iChanged Bitreich stagit-gopher to gemini protocol - stagit-gemini - Stagit for gemini protocol Openbsd Err thinkerwim.openbsd.amsterdam 70 hgit clone git://thinkerwim.org/stagit-gemini.git URL:git://thinkerwim.org/stagit-gemini.git thinkerwim.org 70 1Log /git/stagit-gemini/log.gph thinkerwim.org 70 1Files /git/stagit-gemini/files.gph thinkerwim.org 70 1Refs /git/stagit-gemini/refs.gph thinkerwim.org 70 1README /git/stagit-gemini/file/README.gph thinkerwim.org 70 1LICENSE /git/stagit-gemini/file/LICENSE.gph thinkerwim.org 70 i--- Err thinkerwim.openbsd.amsterdam 70 1commit b961d515cd77c6f8326d4c7e3f635f6a00fe50bf /git/stagit-gemini/commit/b961d515cd77c6f8326d4c7e3f635f6a00fe50bf.gph thinkerwim.org 70 1parent d8c4c2c3aa23b1237f15fc3ab539419c2368989e /git/stagit-gemini/commit/d8c4c2c3aa23b1237f15fc3ab539419c2368989e.gph thinkerwim.org 70 hAuthor: Wim Stockman URL:mailto:wim@thinkerwim.org thinkerwim.org 70 iDate: Wed, 8 Mar 2023 21:52:34 +0100 Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 iChanged Bitreich stagit-gopher to gemini protocol Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 iDiffstat: Err thinkerwim.openbsd.amsterdam 70 i M Makefile | 22 +++++++++++----------- Err thinkerwim.openbsd.amsterdam 70 i M README | 24 ++++++++++++------------ Err thinkerwim.openbsd.amsterdam 70 i M example_create.sh | 14 +++++++------- Err thinkerwim.openbsd.amsterdam 70 i M example_post-receive.sh | 16 ++++++++-------- Err thinkerwim.openbsd.amsterdam 70 i A file | 8 ++++++++ Err thinkerwim.openbsd.amsterdam 70 i A stagit-gemini-index.1 | 43 ++++++++++++++++++++++++++++++ Err thinkerwim.openbsd.amsterdam 70 i A stagit-gemini-index.c | 310 +++++++++++++++++++++++++++++++ Err thinkerwim.openbsd.amsterdam 70 i A stagit-gemini.1 | 119 +++++++++++++++++++++++++++++++ Err thinkerwim.openbsd.amsterdam 70 i A stagit-gemini.c | 1475 ++++++++++++++++++++++++++++++ Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i9 files changed, 1993 insertions(+), 38 deletions(-) Err thinkerwim.openbsd.amsterdam 70 i--- Err thinkerwim.openbsd.amsterdam 70 1diff --git a/Makefile b/Makefile /git/stagit-gemini/file/Makefile.gph thinkerwim.org 70 i@@ -1,6 +1,6 @@ Err thinkerwim.openbsd.amsterdam 70 i .POSIX: Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i-NAME = stagit-gopher Err thinkerwim.openbsd.amsterdam 70 i+NAME = stagit-gemini Err thinkerwim.openbsd.amsterdam 70 i VERSION = 1.2 Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i # paths Err thinkerwim.openbsd.amsterdam 70 i@@ -21,17 +21,17 @@ STAGIT_CPPFLAGS = -D_XOPEN_SOURCE=700 -D_DEFAULT_SOURCE -D_BSD_SOURCE Err thinkerwim.openbsd.amsterdam 70 i #STAGIT_CFLAGS += -DGIT_OPT_SET_OWNER_VALIDATION=-1 Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i SRC = \ Err thinkerwim.openbsd.amsterdam 70 i- stagit-gopher.c\ Err thinkerwim.openbsd.amsterdam 70 i- stagit-gopher-index.c Err thinkerwim.openbsd.amsterdam 70 i+ stagit-gemini.c\ Err thinkerwim.openbsd.amsterdam 70 i+ stagit-gemini-index.c Err thinkerwim.openbsd.amsterdam 70 i COMPATSRC = \ Err thinkerwim.openbsd.amsterdam 70 i reallocarray.c\ Err thinkerwim.openbsd.amsterdam 70 i strlcpy.c Err thinkerwim.openbsd.amsterdam 70 i BIN = \ Err thinkerwim.openbsd.amsterdam 70 i- stagit-gopher\ Err thinkerwim.openbsd.amsterdam 70 i- stagit-gopher-index Err thinkerwim.openbsd.amsterdam 70 i+ stagit-gemini\ Err thinkerwim.openbsd.amsterdam 70 i+ stagit-gemini-index Err thinkerwim.openbsd.amsterdam 70 i MAN1 = \ Err thinkerwim.openbsd.amsterdam 70 i- stagit-gopher.1\ Err thinkerwim.openbsd.amsterdam 70 i- stagit-gopher-index.1 Err thinkerwim.openbsd.amsterdam 70 i+ stagit-gemini.1\ Err thinkerwim.openbsd.amsterdam 70 i+ stagit-gemini-index.1 Err thinkerwim.openbsd.amsterdam 70 i DOC = \ Err thinkerwim.openbsd.amsterdam 70 i LICENSE\ Err thinkerwim.openbsd.amsterdam 70 i README Err thinkerwim.openbsd.amsterdam 70 i@@ -65,11 +65,11 @@ dist: Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i ${OBJ}: ${HDR} Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i-stagit-gopher: stagit-gopher.o ${COMPATOBJ} Err thinkerwim.openbsd.amsterdam 70 i- ${CC} -o $@ stagit-gopher.o ${COMPATOBJ} ${STAGIT_LDFLAGS} Err thinkerwim.openbsd.amsterdam 70 i+stagit-gemini: stagit-gemini.o ${COMPATOBJ} Err thinkerwim.openbsd.amsterdam 70 i+ ${CC} -o $@ stagit-gemini.o ${COMPATOBJ} ${STAGIT_LDFLAGS} Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i-stagit-gopher-index: stagit-gopher-index.o ${COMPATOBJ} Err thinkerwim.openbsd.amsterdam 70 i- ${CC} -o $@ stagit-gopher-index.o ${COMPATOBJ} ${STAGIT_LDFLAGS} Err thinkerwim.openbsd.amsterdam 70 i+stagit-gemini-index: stagit-gemini-index.o ${COMPATOBJ} Err thinkerwim.openbsd.amsterdam 70 i+ ${CC} -o $@ stagit-gemini-index.o ${COMPATOBJ} ${STAGIT_LDFLAGS} Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i clean: Err thinkerwim.openbsd.amsterdam 70 i rm -f ${BIN} ${OBJ} ${NAME}-${VERSION}.tar.gz Err thinkerwim.openbsd.amsterdam 70 1diff --git a/README b/README /git/stagit-gemini/file/README.gph thinkerwim.org 70 i@@ -1,9 +1,9 @@ Err thinkerwim.openbsd.amsterdam 70 i-stagit-gopher Err thinkerwim.openbsd.amsterdam 70 i+stagit-gemini Err thinkerwim.openbsd.amsterdam 70 i ------------- Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i-static git page generator for gopher. Err thinkerwim.openbsd.amsterdam 70 i+static git page generator for gemini. Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i-This generates pages in the geomyidae .gph file format: Err thinkerwim.openbsd.amsterdam 70 i+This generates pages in the geomyidae .gmi file format: Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i http://git.r-36.net/geomyidae Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i@@ -13,17 +13,17 @@ Usage Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i Make files per repository: Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i- $ mkdir -p gphroot/gphrepo1 && cd gphroot/gphrepo1 Err thinkerwim.openbsd.amsterdam 70 i- $ stagit-gopher path/to/gitrepo1 Err thinkerwim.openbsd.amsterdam 70 i+ $ mkdir -p gmiroot/gmirepo1 && cd gmiroot/gmirepo1 Err thinkerwim.openbsd.amsterdam 70 i+ $ stagit-gemini path/to/gitrepo1 Err thinkerwim.openbsd.amsterdam 70 i repeat for other repositories Err thinkerwim.openbsd.amsterdam 70 i $ ... Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i Make index file for repositories: Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i- $ cd gphroot Err thinkerwim.openbsd.amsterdam 70 i- $ stagit-gopher-index path/to/gitrepo1 \ Err thinkerwim.openbsd.amsterdam 70 i+ $ cd gmiroot Err thinkerwim.openbsd.amsterdam 70 i+ $ stagit-gemini-index path/to/gitrepo1 \ Err thinkerwim.openbsd.amsterdam 70 i path/to/gitrepo2 \ Err thinkerwim.openbsd.amsterdam 70 i- path/to/gitrepo3 > index.gph Err thinkerwim.openbsd.amsterdam 70 i+ path/to/gitrepo3 > index.gmi Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i Build and install Err thinkerwim.openbsd.amsterdam 70 i@@ -39,14 +39,14 @@ Dependencies Err thinkerwim.openbsd.amsterdam 70 i - C compiler (C99). Err thinkerwim.openbsd.amsterdam 70 i - libc (tested with OpenBSD, FreeBSD, NetBSD, Linux: glibc and musl). Err thinkerwim.openbsd.amsterdam 70 i - libgit2 (v0.22+). Err thinkerwim.openbsd.amsterdam 70 i-- geomyidae (for .gph file serving). Err thinkerwim.openbsd.amsterdam 70 i+- geomyidae (for .gmi file serving). Err thinkerwim.openbsd.amsterdam 70 i - POSIX make (optional). Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i Documentation Err thinkerwim.openbsd.amsterdam 70 i ------------- Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i-See man pages: stagit-gopher(1) and stagit-gopher-index(1). Err thinkerwim.openbsd.amsterdam 70 i+See man pages: stagit-gemini(1) and stagit-gemini-index(1). Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i Building a static binary Err thinkerwim.openbsd.amsterdam 70 i@@ -113,7 +113,7 @@ git post-receive hook (repo/.git/hooks/post-receive): Err thinkerwim.openbsd.amsterdam 70 i Create .tar.gz archives by tag Err thinkerwim.openbsd.amsterdam 70 i ------------------------------ Err thinkerwim.openbsd.amsterdam 70 i #!/bin/sh Err thinkerwim.openbsd.amsterdam 70 i- name="stagit-gopher" Err thinkerwim.openbsd.amsterdam 70 i+ name="stagit-gemini" Err thinkerwim.openbsd.amsterdam 70 i mkdir -p archives Err thinkerwim.openbsd.amsterdam 70 i git tag -l | while read -r t; do Err thinkerwim.openbsd.amsterdam 70 i f="archives/${name}-$(echo "${t}" | tr '/' '_').tar.gz" Err thinkerwim.openbsd.amsterdam 70 i@@ -138,7 +138,7 @@ Features Err thinkerwim.openbsd.amsterdam 70 i - Detect submodules (.gitmodules file) from HEAD and link it as a page. Err thinkerwim.openbsd.amsterdam 70 i - Atom feed of the commit log (atom.xml). Err thinkerwim.openbsd.amsterdam 70 i - Atom feed of the tags/refs (tags.xml). Err thinkerwim.openbsd.amsterdam 70 i-- Make index page for multiple repositories with stagit-gopher-index. Err thinkerwim.openbsd.amsterdam 70 i+- Make index page for multiple repositories with stagit-gemini-index. Err thinkerwim.openbsd.amsterdam 70 i - After generating the pages (relatively slow) serving the files is very fast, Err thinkerwim.openbsd.amsterdam 70 i simple and requires little resources (because the content is static), only Err thinkerwim.openbsd.amsterdam 70 i a geomyidae Gopher server is required. Err thinkerwim.openbsd.amsterdam 70 1diff --git a/example_create.sh b/example_create.sh /git/stagit-gemini/file/example_create.sh.gph thinkerwim.org 70 i@@ -8,20 +8,20 @@ Err thinkerwim.openbsd.amsterdam 70 i # - write description in "description" file. Err thinkerwim.openbsd.amsterdam 70 i # Err thinkerwim.openbsd.amsterdam 70 i # Usage: Err thinkerwim.openbsd.amsterdam 70 i-# - mkdir -p gphdir && cd gphdir Err thinkerwim.openbsd.amsterdam 70 i+# - mkdir -p gmidir && cd gmidir Err thinkerwim.openbsd.amsterdam 70 i # - sh example_create.sh Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i # path must be absolute. Err thinkerwim.openbsd.amsterdam 70 i reposdir="/var/scm/git" Err thinkerwim.openbsd.amsterdam 70 i-gopherdir="/var/gopher" Err thinkerwim.openbsd.amsterdam 70 i+geminidir="/var/gemini" Err thinkerwim.openbsd.amsterdam 70 i stagitdir="/scm" Err thinkerwim.openbsd.amsterdam 70 i-destdir="${gopherdir}/${stagitdir}" Err thinkerwim.openbsd.amsterdam 70 i+destdir="${geminidir}/${stagitdir}" Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i # remove /'s at the end. Err thinkerwim.openbsd.amsterdam 70 i stagitdir=$(printf "%s" "${stagitdir}" | sed 's@[/]*$@@g') Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i # make index. Err thinkerwim.openbsd.amsterdam 70 i-stagit-gopher-index -b "${stagitdir}" "${reposdir}/"*/ > "${destdir}/index.gph" Err thinkerwim.openbsd.amsterdam 70 i+stagit-gemini-index -b "${stagitdir}" "${reposdir}/"*/ > "${destdir}/index.gmi" Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i # make files per repo. Err thinkerwim.openbsd.amsterdam 70 i for dir in "${reposdir}/"*/; do Err thinkerwim.openbsd.amsterdam 70 i@@ -32,11 +32,11 @@ for dir in "${reposdir}/"*/; do Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i mkdir -p "${destdir}/${d}" Err thinkerwim.openbsd.amsterdam 70 i cd "${destdir}/${d}" || continue Err thinkerwim.openbsd.amsterdam 70 i- stagit-gopher -b "${stagitdir}/${d}" -c ".cache" \ Err thinkerwim.openbsd.amsterdam 70 i- -u "gopher://codemadness.org/1/git/$d/" "${reposdir}/${r}" Err thinkerwim.openbsd.amsterdam 70 i+ stagit-gemini -b "${stagitdir}/${d}" -c ".cache" \ Err thinkerwim.openbsd.amsterdam 70 i+ -u "gemini://codemadness.org/1/git/$d/" "${reposdir}/${r}" Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i # symlinks Err thinkerwim.openbsd.amsterdam 70 i- ln -sf log.gph index.gph Err thinkerwim.openbsd.amsterdam 70 i+ ln -sf log.gmi index.gmi Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i echo "done" Err thinkerwim.openbsd.amsterdam 70 i done Err thinkerwim.openbsd.amsterdam 70 1diff --git a/example_post-receive.sh b/example_post-receive.sh /git/stagit-gemini/file/example_post-receive.sh.gph thinkerwim.org 70 i@@ -21,10 +21,10 @@ fi Err thinkerwim.openbsd.amsterdam 70 i # paths must be absolute. Err thinkerwim.openbsd.amsterdam 70 i reposdir="/home/src/src" Err thinkerwim.openbsd.amsterdam 70 i dir="${reposdir}/${name}" Err thinkerwim.openbsd.amsterdam 70 i-gopherdir="/home/www/gopher" Err thinkerwim.openbsd.amsterdam 70 i+geminidir="/home/www/gemini" Err thinkerwim.openbsd.amsterdam 70 i stagitdir="/" Err thinkerwim.openbsd.amsterdam 70 i-destdir="${gopherdir}/${stagitdir}" Err thinkerwim.openbsd.amsterdam 70 i-cachefile=".gphcache" Err thinkerwim.openbsd.amsterdam 70 i+destdir="${geminidir}/${stagitdir}" Err thinkerwim.openbsd.amsterdam 70 i+cachefile=".gmicache" Err thinkerwim.openbsd.amsterdam 70 i # /config Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i if ! test -d "${dir}"; then Err thinkerwim.openbsd.amsterdam 70 i@@ -49,7 +49,7 @@ done Err thinkerwim.openbsd.amsterdam 70 i # strip .git suffix. Err thinkerwim.openbsd.amsterdam 70 i r=$(basename "${name}") Err thinkerwim.openbsd.amsterdam 70 i d=$(basename "${name}" ".git") Err thinkerwim.openbsd.amsterdam 70 i-printf "[%s] stagit .gph pages... " "${d}" Err thinkerwim.openbsd.amsterdam 70 i+printf "[%s] stagit .gmi pages... " "${d}" Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i mkdir -p "${destdir}/${d}" Err thinkerwim.openbsd.amsterdam 70 i cd "${destdir}/${d}" || exit 1 Err thinkerwim.openbsd.amsterdam 70 i@@ -64,12 +64,12 @@ fi Err thinkerwim.openbsd.amsterdam 70 i stagitdir=$(printf "%s" "${stagitdir}" | sed 's@[/]*$@@g') Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i # make index. Err thinkerwim.openbsd.amsterdam 70 i-stagit-gopher-index -b "${stagitdir}" "${reposdir}/"*/ > "${destdir}/index.gph" Err thinkerwim.openbsd.amsterdam 70 i+stagit-gemini-index -b "${stagitdir}" "${reposdir}/"*/ > "${destdir}/index.gmi" Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i # make pages. Err thinkerwim.openbsd.amsterdam 70 i-stagit-gopher -b "${stagitdir}/${d}" -c "${cachefile}" \ Err thinkerwim.openbsd.amsterdam 70 i- -u "gopher://codemadness.org/1/git/$d/" "${reposdir}/${r}" Err thinkerwim.openbsd.amsterdam 70 i+stagit-gemini -b "${stagitdir}/${d}" -c "${cachefile}" \ Err thinkerwim.openbsd.amsterdam 70 i+ -u "gemini://codemadness.org/1/git/$d/" "${reposdir}/${r}" Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i-ln -sf log.gph index.gph Err thinkerwim.openbsd.amsterdam 70 i+ln -sf log.gmi index.gmi Err thinkerwim.openbsd.amsterdam 70 i Err thinkerwim.openbsd.amsterdam 70 i echo "done" Err thinkerwim.openbsd.amsterdam 70 1diff --git a/file b/file /git/stagit-gemini/file/file.gph thinkerwim.org 70 i@@ -0,0 +1,8 @@ Err thinkerwim.openbsd.amsterdam 70 i+mv stagit-gemini stagit-gemini Err thinkerwim.openbsd.amsterdam 70 i+mv stagit-gemini-index stagit-gemini-index Err thinkerwim.openbsd.amsterdam 70 i+mv stagit-gemini-index.1 stagit-gemini-index.1 Err thinkerwim.openbsd.amsterdam 70 i+mv stagit-gemini-index.c stagit-gemini-index.c Err thinkerwim.openbsd.amsterdam 70 i+mv stagit-gemini-index.o stagit-gemini-index.o Err thinkerwim.openbsd.amsterdam 70 i+mv stagit-gemini.1 stagit-gemini.1 Err thinkerwim.openbsd.amsterdam 70 i+mv stagit-gemini.c stagit-gemini.c Err thinkerwim.openbsd.amsterdam 70 i+mv stagit-gemini.o stagit-gemini.o Err thinkerwim.openbsd.amsterdam 70 1diff --git a/stagit-gemini-index.1 b/stagit-gemini-index.1 /git/stagit-gemini/file/stagit-gemini-index.1.gph thinkerwim.org 70 i@@ -0,0 +1,43 @@ Err thinkerwim.openbsd.amsterdam 70 i+.Dd August 2, 2021 Err thinkerwim.openbsd.amsterdam 70 i+.Dt STAGIT-GOPHER-INDEX 1 Err thinkerwim.openbsd.amsterdam 70 i+.Os Err thinkerwim.openbsd.amsterdam 70 i+.Sh NAME Err thinkerwim.openbsd.amsterdam 70 i+.Nm stagit-gemini-index Err thinkerwim.openbsd.amsterdam 70 i+.Nd static git Gopher index generator Err thinkerwim.openbsd.amsterdam 70 i+.Sh SYNOPSIS Err thinkerwim.openbsd.amsterdam 70 i+.Nm Err thinkerwim.openbsd.amsterdam 70 i+.Op Fl b Ar baseprefix Err thinkerwim.openbsd.amsterdam 70 i+.Op Ar repodir... Err thinkerwim.openbsd.amsterdam 70 i+.Sh DESCRIPTION Err thinkerwim.openbsd.amsterdam 70 i+.Nm Err thinkerwim.openbsd.amsterdam 70 i+will create a Gopher index for the repositories specified and writes Err thinkerwim.openbsd.amsterdam 70 i+the Gopher data to stdout. Err thinkerwim.openbsd.amsterdam 70 i+The repos in the index are in the same order as the arguments Err thinkerwim.openbsd.amsterdam 70 i+.Ar repodir Err thinkerwim.openbsd.amsterdam 70 i+specified. Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+The options are as follows: Err thinkerwim.openbsd.amsterdam 70 i+.Bl -tag -width Ds Err thinkerwim.openbsd.amsterdam 70 i+.It Fl b Ar baseprefix Err thinkerwim.openbsd.amsterdam 70 i+Use base prefix as the root. Err thinkerwim.openbsd.amsterdam 70 i+By default this is "/". Err thinkerwim.openbsd.amsterdam 70 i+.El Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+The basename of the directory is used as the repository name. Err thinkerwim.openbsd.amsterdam 70 i+The suffix ".git" is removed from the basename, this suffix is commonly used Err thinkerwim.openbsd.amsterdam 70 i+for "bare" repos. Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+The content of the follow files specifies the meta data for each repository: Err thinkerwim.openbsd.amsterdam 70 i+.Bl -tag -width Ds Err thinkerwim.openbsd.amsterdam 70 i+.It .git/description or description (bare repos). Err thinkerwim.openbsd.amsterdam 70 i+description Err thinkerwim.openbsd.amsterdam 70 i+.El Err thinkerwim.openbsd.amsterdam 70 i+.Sh EXAMPLES Err thinkerwim.openbsd.amsterdam 70 i+.Bd -literal Err thinkerwim.openbsd.amsterdam 70 i+cd gmiroot Err thinkerwim.openbsd.amsterdam 70 i+stagit-gemini-index path/to/gitrepo1 path/to/gitrepo2 > index.gmi Err thinkerwim.openbsd.amsterdam 70 i+.Ed Err thinkerwim.openbsd.amsterdam 70 i+.Sh SEE ALSO Err thinkerwim.openbsd.amsterdam 70 i+.Xr stagit-gemini 1 Err thinkerwim.openbsd.amsterdam 70 i+.Sh AUTHORS Err thinkerwim.openbsd.amsterdam 70 i+.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org Err thinkerwim.openbsd.amsterdam 70 1diff --git a/stagit-gemini-index.c b/stagit-gemini-index.c /git/stagit-gemini/file/stagit-gemini-index.c.gph thinkerwim.org 70 i@@ -0,0 +1,310 @@ Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+#define PAD_TRUNCATE_SYMBOL "\xe2\x80\xa6" /* symbol: "ellipsis" */ Err thinkerwim.openbsd.amsterdam 70 i+#define UTF_INVALID_SYMBOL "\xef\xbf\xbd" /* symbol: "replacement" */ Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+static git_repository *repo; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+static const char *relpath = ""; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+static char description[255] = "Repositories"; Err thinkerwim.openbsd.amsterdam 70 i+static char *name = ""; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Handle read or write errors for a FILE * stream */ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+checkfileerror(FILE *fp, const char *name, int mode) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ if (mode == 'r' && ferror(fp)) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "read error: %s", name); Err thinkerwim.openbsd.amsterdam 70 i+ else if (mode == 'w' && (fflush(fp) || ferror(fp))) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "write error: %s", name); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Format `len' columns of characters. If string is shorter pad the rest Err thinkerwim.openbsd.amsterdam 70 i+ * with characters `pad`. */ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+utf8pad(char *buf, size_t bufsiz, const char *s, size_t len, int pad) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ wchar_t wc; Err thinkerwim.openbsd.amsterdam 70 i+ size_t col = 0, i, slen, siz = 0; Err thinkerwim.openbsd.amsterdam 70 i+ int inc, rl, w; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ if (!len) { Err thinkerwim.openbsd.amsterdam 70 i+ buf[0] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ slen = strlen(s); Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < slen; i += inc) { Err thinkerwim.openbsd.amsterdam 70 i+ inc = 1; /* next byte */ Err thinkerwim.openbsd.amsterdam 70 i+ if ((unsigned char)s[i] < 32) Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ rl = mbtowc(&wc, &s[i], slen - i < 4 ? slen - i : 4); Err thinkerwim.openbsd.amsterdam 70 i+ inc = rl; Err thinkerwim.openbsd.amsterdam 70 i+ if (rl < 0) { Err thinkerwim.openbsd.amsterdam 70 i+ mbtowc(NULL, NULL, 0); /* reset state */ Err thinkerwim.openbsd.amsterdam 70 i+ inc = 1; /* invalid, seek next byte */ Err thinkerwim.openbsd.amsterdam 70 i+ w = 1; /* replacement char is one width */ Err thinkerwim.openbsd.amsterdam 70 i+ } else if ((w = wcwidth(wc)) == -1) { Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (col + w > len || (col + w == len && s[i + inc])) { Err thinkerwim.openbsd.amsterdam 70 i+ if (siz + 4 >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ memcpy(&buf[siz], PAD_TRUNCATE_SYMBOL, sizeof(PAD_TRUNCATE_SYMBOL) - 1); Err thinkerwim.openbsd.amsterdam 70 i+ siz += sizeof(PAD_TRUNCATE_SYMBOL) - 1; Err thinkerwim.openbsd.amsterdam 70 i+ buf[siz] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ col++; Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ } else if (rl < 0) { Err thinkerwim.openbsd.amsterdam 70 i+ if (siz + 4 >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ memcpy(&buf[siz], UTF_INVALID_SYMBOL, sizeof(UTF_INVALID_SYMBOL) - 1); Err thinkerwim.openbsd.amsterdam 70 i+ siz += sizeof(UTF_INVALID_SYMBOL) - 1; Err thinkerwim.openbsd.amsterdam 70 i+ buf[siz] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ col++; Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (siz + inc + 1 >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ memcpy(&buf[siz], &s[i], inc); Err thinkerwim.openbsd.amsterdam 70 i+ siz += inc; Err thinkerwim.openbsd.amsterdam 70 i+ buf[siz] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ col += w; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ len -= col; Err thinkerwim.openbsd.amsterdam 70 i+ if (siz + len + 1 >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ memset(&buf[siz], pad, len); Err thinkerwim.openbsd.amsterdam 70 i+ siz += len; Err thinkerwim.openbsd.amsterdam 70 i+ buf[siz] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Escape characters in text in geomyidae .gmi format, Err thinkerwim.openbsd.amsterdam 70 i+ newlines are ignored */ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+gmitext(FILE *fp, const char *s, size_t len) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ size_t i; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; *s && i < len; s++, i++) { Err thinkerwim.openbsd.amsterdam 70 i+ switch (*s) { Err thinkerwim.openbsd.amsterdam 70 i+ case '\r': /* ignore CR */ Err thinkerwim.openbsd.amsterdam 70 i+ case '\n': /* ignore LF */ Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ default: Err thinkerwim.openbsd.amsterdam 70 i+ putc(*s, fp); Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Escape characters in links in geomyidae .gmi format */ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+gmilink(FILE *fp, const char *s, size_t len) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ size_t i; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; *s && i < len; s++, i++) { Err thinkerwim.openbsd.amsterdam 70 i+ switch (*s) { Err thinkerwim.openbsd.amsterdam 70 i+ case '\r': /* ignore CR */ Err thinkerwim.openbsd.amsterdam 70 i+ case '\n': /* ignore LF */ Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ default: Err thinkerwim.openbsd.amsterdam 70 i+ putc(*s, fp); Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+joinpath(char *buf, size_t bufsiz, const char *path, const char *path2) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ int r; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ r = snprintf(buf, bufsiz, "%s%s%s", Err thinkerwim.openbsd.amsterdam 70 i+ path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2); Err thinkerwim.openbsd.amsterdam 70 i+ if (r < 0 || (size_t)r >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "path truncated: '%s%s%s'", Err thinkerwim.openbsd.amsterdam 70 i+ path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+printtimeshort(FILE *fp, const git_time *intime) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct tm *intm; Err thinkerwim.openbsd.amsterdam 70 i+ time_t t; Err thinkerwim.openbsd.amsterdam 70 i+ char out[32]; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ t = (time_t)intime->time; Err thinkerwim.openbsd.amsterdam 70 i+ if (!(intm = gmtime(&t))) Err thinkerwim.openbsd.amsterdam 70 i+ return; Err thinkerwim.openbsd.amsterdam 70 i+ strftime(out, sizeof(out), "%Y-%m-%d %H:%M", intm); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(out, fp); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+writeheader(FILE *fp) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ if (description[0]) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs(description, fp); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%-20.20s ", "Name"); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%-39.39s ", "Description"); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%s\n", "Last commit"); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+writelog(FILE *fp) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ git_commit *commit = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ const git_signature *author; Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk *w = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_oid id; Err thinkerwim.openbsd.amsterdam 70 i+ char *stripped_name = NULL, *p; Err thinkerwim.openbsd.amsterdam 70 i+ char buf[1024]; Err thinkerwim.openbsd.amsterdam 70 i+ int ret = 0; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_new(&w, repo); Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_push_head(w); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (git_revwalk_next(&id, w) || Err thinkerwim.openbsd.amsterdam 70 i+ git_commit_lookup(&commit, repo, &id)) { Err thinkerwim.openbsd.amsterdam 70 i+ ret = -1; Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ author = git_commit_author(commit); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* strip .git suffix */ Err thinkerwim.openbsd.amsterdam 70 i+ if (!(stripped_name = strdup(name))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "strdup"); Err thinkerwim.openbsd.amsterdam 70 i+ if ((p = strrchr(stripped_name, '.'))) Err thinkerwim.openbsd.amsterdam 70 i+ if (!strcmp(p, ".git")) Err thinkerwim.openbsd.amsterdam 70 i+ *p = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/%s/log.gmi ", relpath, stripped_name); Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), stripped_name, 20, ' '); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, buf, strlen(buf)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), description, 39, ' '); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, buf, strlen(buf)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ if (author) Err thinkerwim.openbsd.amsterdam 70 i+ printtimeshort(fp, &(author->when)); Err thinkerwim.openbsd.amsterdam 70 i+ fputc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_commit_free(commit); Err thinkerwim.openbsd.amsterdam 70 i+err: Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_free(w); Err thinkerwim.openbsd.amsterdam 70 i+ free(stripped_name); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return ret; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+usage(const char *argv0) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(stderr, "usage: %s [-b baseprefix] [repodir...]\n", argv0); Err thinkerwim.openbsd.amsterdam 70 i+ exit(1); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+main(int argc, char *argv[]) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ FILE *fp; Err thinkerwim.openbsd.amsterdam 70 i+ char path[PATH_MAX], repodirabs[PATH_MAX + 1]; Err thinkerwim.openbsd.amsterdam 70 i+ const char *repodir = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ int i, r, ret = 0; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ setlocale(LC_CTYPE, ""); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* do not search outside the git repository: Err thinkerwim.openbsd.amsterdam 70 i+ GIT_CONFIG_LEVEL_APP is the highest level currently */ Err thinkerwim.openbsd.amsterdam 70 i+ git_libgit2_init(); Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 1; i <= GIT_CONFIG_LEVEL_APP; i++) Err thinkerwim.openbsd.amsterdam 70 i+ git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, i, ""); Err thinkerwim.openbsd.amsterdam 70 i+ /* do not require the git repository to be owned by the current user */ Err thinkerwim.openbsd.amsterdam 70 i+ git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+#ifdef __OpenBSD__ Err thinkerwim.openbsd.amsterdam 70 i+ if (pledge("stdio rpath", NULL) == -1) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "pledge"); Err thinkerwim.openbsd.amsterdam 70 i+#endif Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 1, r = 0; i < argc; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (argv[i][0] == '-') { Err thinkerwim.openbsd.amsterdam 70 i+ if (argv[i][1] != 'b' || i + 1 >= argc) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ relpath = argv[++i]; Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (r++ == 0) Err thinkerwim.openbsd.amsterdam 70 i+ writeheader(stdout); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ repodir = argv[i]; Err thinkerwim.openbsd.amsterdam 70 i+ if (!realpath(repodir, repodirabs)) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "realpath"); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (git_repository_open_ext(&repo, repodir, Err thinkerwim.openbsd.amsterdam 70 i+ GIT_REPOSITORY_OPEN_NO_SEARCH, NULL)) { Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(stderr, "%s: cannot open repository\n", argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ ret = 1; Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* use directory name as name */ Err thinkerwim.openbsd.amsterdam 70 i+ if ((name = strrchr(repodirabs, '/'))) Err thinkerwim.openbsd.amsterdam 70 i+ name++; Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ name = ""; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* read description or .git/description */ Err thinkerwim.openbsd.amsterdam 70 i+ joinpath(path, sizeof(path), repodir, "description"); Err thinkerwim.openbsd.amsterdam 70 i+ if (!(fp = fopen(path, "r"))) { Err thinkerwim.openbsd.amsterdam 70 i+ joinpath(path, sizeof(path), repodir, ".git/description"); Err thinkerwim.openbsd.amsterdam 70 i+ fp = fopen(path, "r"); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ description[0] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ if (fp) { Err thinkerwim.openbsd.amsterdam 70 i+ if (fgets(description, sizeof(description), fp)) Err thinkerwim.openbsd.amsterdam 70 i+ description[strcspn(description, "\t\r\n")] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ description[0] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fp, "description", 'r'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ writelog(stdout); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (!repodir) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* cleanup */ Err thinkerwim.openbsd.amsterdam 70 i+ git_repository_free(repo); Err thinkerwim.openbsd.amsterdam 70 i+ git_libgit2_shutdown(); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(stdout, "", 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return ret; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 1diff --git a/stagit-gemini.1 b/stagit-gemini.1 /git/stagit-gemini/file/stagit-gemini.1.gph thinkerwim.org 70 i@@ -0,0 +1,119 @@ Err thinkerwim.openbsd.amsterdam 70 i+.Dd August 2, 2021 Err thinkerwim.openbsd.amsterdam 70 i+.Dt STAGIT-GOPHER 1 Err thinkerwim.openbsd.amsterdam 70 i+.Os Err thinkerwim.openbsd.amsterdam 70 i+.Sh NAME Err thinkerwim.openbsd.amsterdam 70 i+.Nm stagit-gemini Err thinkerwim.openbsd.amsterdam 70 i+.Nd static git Gopher index generator Err thinkerwim.openbsd.amsterdam 70 i+.Sh SYNOPSIS Err thinkerwim.openbsd.amsterdam 70 i+.Nm Err thinkerwim.openbsd.amsterdam 70 i+.Op Fl b Ar baseprefix Err thinkerwim.openbsd.amsterdam 70 i+.Op Fl c Ar cachefile Err thinkerwim.openbsd.amsterdam 70 i+.Op Fl l Ar commits Err thinkerwim.openbsd.amsterdam 70 i+.Op Fl u Ar baseurl Err thinkerwim.openbsd.amsterdam 70 i+.Ar repodir Err thinkerwim.openbsd.amsterdam 70 i+.Sh DESCRIPTION Err thinkerwim.openbsd.amsterdam 70 i+.Nm Err thinkerwim.openbsd.amsterdam 70 i+writes Gopher indexes for the repository Err thinkerwim.openbsd.amsterdam 70 i+.Ar repodir Err thinkerwim.openbsd.amsterdam 70 i+to the current directory. Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+The options are as follows: Err thinkerwim.openbsd.amsterdam 70 i+.Bl -tag -width Ds Err thinkerwim.openbsd.amsterdam 70 i+.It Fl b Ar baseprefix Err thinkerwim.openbsd.amsterdam 70 i+Use base prefix as the root. Err thinkerwim.openbsd.amsterdam 70 i+By default this is "". Err thinkerwim.openbsd.amsterdam 70 i+.It Fl c Ar cachefile Err thinkerwim.openbsd.amsterdam 70 i+Cache the entries of the log index up to the point of Err thinkerwim.openbsd.amsterdam 70 i+the last commit. Err thinkerwim.openbsd.amsterdam 70 i+The Err thinkerwim.openbsd.amsterdam 70 i+.Ar cachefile Err thinkerwim.openbsd.amsterdam 70 i+will store the last commit id and the entries in the Gopher index. Err thinkerwim.openbsd.amsterdam 70 i+It is up to the user to make sure the state of the Err thinkerwim.openbsd.amsterdam 70 i+.Ar cachefile Err thinkerwim.openbsd.amsterdam 70 i+is in sync with the history of the repository. Err thinkerwim.openbsd.amsterdam 70 i+.It Fl l Ar commits Err thinkerwim.openbsd.amsterdam 70 i+Write a maximum number of Err thinkerwim.openbsd.amsterdam 70 i+.Ar commits Err thinkerwim.openbsd.amsterdam 70 i+to the log.gmi file only. Err thinkerwim.openbsd.amsterdam 70 i+However the commit files are written as usual. Err thinkerwim.openbsd.amsterdam 70 i+.It Fl u Ar baseurl Err thinkerwim.openbsd.amsterdam 70 i+Base URL to make links in the Atom feeds absolute. Err thinkerwim.openbsd.amsterdam 70 i+Does not use the prefix from the -b option. Err thinkerwim.openbsd.amsterdam 70 i+It should include the gemini type. Err thinkerwim.openbsd.amsterdam 70 i+For example: "gemini://codemadness.org/1/git/stagit-gemini/". Err thinkerwim.openbsd.amsterdam 70 i+.El Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+The options Err thinkerwim.openbsd.amsterdam 70 i+.Fl c Err thinkerwim.openbsd.amsterdam 70 i+and Err thinkerwim.openbsd.amsterdam 70 i+.Fl l Err thinkerwim.openbsd.amsterdam 70 i+cannot be used at the same time. Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+The following files will be written: Err thinkerwim.openbsd.amsterdam 70 i+.Bl -tag -width Ds Err thinkerwim.openbsd.amsterdam 70 i+.It atom.xml Err thinkerwim.openbsd.amsterdam 70 i+Atom XML feed of the last 100 commits. Err thinkerwim.openbsd.amsterdam 70 i+.It tags.xml Err thinkerwim.openbsd.amsterdam 70 i+Atom XML feed of the tags. Err thinkerwim.openbsd.amsterdam 70 i+.It files.gmi Err thinkerwim.openbsd.amsterdam 70 i+List of files in the latest tree, linking to the file. Err thinkerwim.openbsd.amsterdam 70 i+.It log.gmi Err thinkerwim.openbsd.amsterdam 70 i+List of commits in reverse chronological applied commit order, each commit Err thinkerwim.openbsd.amsterdam 70 i+links to a page with a diffstat and diff of the commit. Err thinkerwim.openbsd.amsterdam 70 i+.It refs.gmi Err thinkerwim.openbsd.amsterdam 70 i+Lists references of the repository such as branches and tags. Err thinkerwim.openbsd.amsterdam 70 i+.El Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+For each entry in HEAD a file will be written in the format: Err thinkerwim.openbsd.amsterdam 70 i+file/filepath.gmi. Err thinkerwim.openbsd.amsterdam 70 i+This file will contain the textual data of the file prefixed by line numbers. Err thinkerwim.openbsd.amsterdam 70 i+The file will have the string "Binary file" if the data is considered to be Err thinkerwim.openbsd.amsterdam 70 i+non-textual. Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+For each commit a file will be written in the format: Err thinkerwim.openbsd.amsterdam 70 i+commit/commitid.gmi. Err thinkerwim.openbsd.amsterdam 70 i+This file will contain the diffstat and diff of the commit. Err thinkerwim.openbsd.amsterdam 70 i+It will write the string "Binary files differ" if the data is considered to Err thinkerwim.openbsd.amsterdam 70 i+be non-textual. Err thinkerwim.openbsd.amsterdam 70 i+Too large diffs will be suppressed and a string Err thinkerwim.openbsd.amsterdam 70 i+"Diff is too large, output suppressed" will be written. Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+When a Gopher commit file exists it won't be overwritten again, note that if Err thinkerwim.openbsd.amsterdam 70 i+you've changed Err thinkerwim.openbsd.amsterdam 70 i+.Nm Err thinkerwim.openbsd.amsterdam 70 i+or changed one of the metadata files of the repository it is recommended to Err thinkerwim.openbsd.amsterdam 70 i+recreate all the output files because it will contain old data. Err thinkerwim.openbsd.amsterdam 70 i+To do this remove the output directory and Err thinkerwim.openbsd.amsterdam 70 i+.Ar cachefile , Err thinkerwim.openbsd.amsterdam 70 i+then recreate the files. Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+The basename of the directory is used as the repository name. Err thinkerwim.openbsd.amsterdam 70 i+The suffix ".git" is removed from the basename, this suffix is commonly used Err thinkerwim.openbsd.amsterdam 70 i+for "bare" repos. Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+The content of the follow files specifies the metadata for each repository: Err thinkerwim.openbsd.amsterdam 70 i+.Bl -tag -width Ds Err thinkerwim.openbsd.amsterdam 70 i+.It .git/description or description (bare repo). Err thinkerwim.openbsd.amsterdam 70 i+description Err thinkerwim.openbsd.amsterdam 70 i+.It .git/url or url (bare repo). Err thinkerwim.openbsd.amsterdam 70 i+primary clone URL of the repository, for example: Err thinkerwim.openbsd.amsterdam 70 i+git://git.codemadness.org/stagit Err thinkerwim.openbsd.amsterdam 70 i+.El Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+When a README or LICENSE file exists in HEAD or a .gitmodules submodules file Err thinkerwim.openbsd.amsterdam 70 i+exists in HEAD a direct link in the index is made. Err thinkerwim.openbsd.amsterdam 70 i+.Sh EXIT STATUS Err thinkerwim.openbsd.amsterdam 70 i+.Ex -std Err thinkerwim.openbsd.amsterdam 70 i+.Sh EXAMPLES Err thinkerwim.openbsd.amsterdam 70 i+.Bd -literal Err thinkerwim.openbsd.amsterdam 70 i+mkdir -p gmiroot/gmirepo1 && cd gmiroot/gmirepo1 Err thinkerwim.openbsd.amsterdam 70 i+stagit-gemini path/to/gitrepo1 Err thinkerwim.openbsd.amsterdam 70 i+# repeat for other repositories. Err thinkerwim.openbsd.amsterdam 70 i+.Ed Err thinkerwim.openbsd.amsterdam 70 i+.Pp Err thinkerwim.openbsd.amsterdam 70 i+To update the gmi files when the repository is changed a git post-receive hook Err thinkerwim.openbsd.amsterdam 70 i+can be used, see the file example_post-receive.sh for an example. Err thinkerwim.openbsd.amsterdam 70 i+.Sh SEE ALSO Err thinkerwim.openbsd.amsterdam 70 i+.Xr stagit-gemini-index 1 Err thinkerwim.openbsd.amsterdam 70 i+.Sh AUTHORS Err thinkerwim.openbsd.amsterdam 70 i+.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org Err thinkerwim.openbsd.amsterdam 70 1diff --git a/stagit-gemini.c b/stagit-gemini.c /git/stagit-gemini/file/stagit-gemini.c.gph thinkerwim.org 70 i@@ -0,0 +1,1475 @@ Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+#include Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+#include "compat.h" Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+#define LEN(s) (sizeof(s)/sizeof(*s)) Err thinkerwim.openbsd.amsterdam 70 i+#define PAD_TRUNCATE_SYMBOL "\xe2\x80\xa6" /* symbol: "ellipsis" */ Err thinkerwim.openbsd.amsterdam 70 i+#define UTF_INVALID_SYMBOL "\xef\xbf\xbd" /* symbol: "replacement" */ Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+struct deltainfo { Err thinkerwim.openbsd.amsterdam 70 i+ git_patch *patch; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ size_t addcount; Err thinkerwim.openbsd.amsterdam 70 i+ size_t delcount; Err thinkerwim.openbsd.amsterdam 70 i+}; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+struct commitinfo { Err thinkerwim.openbsd.amsterdam 70 i+ const git_oid *id; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ char oid[GIT_OID_HEXSZ + 1]; Err thinkerwim.openbsd.amsterdam 70 i+ char parentoid[GIT_OID_HEXSZ + 1]; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ const git_signature *author; Err thinkerwim.openbsd.amsterdam 70 i+ const git_signature *committer; Err thinkerwim.openbsd.amsterdam 70 i+ const char *summary; Err thinkerwim.openbsd.amsterdam 70 i+ const char *msg; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_diff *diff; Err thinkerwim.openbsd.amsterdam 70 i+ git_commit *commit; Err thinkerwim.openbsd.amsterdam 70 i+ git_commit *parent; Err thinkerwim.openbsd.amsterdam 70 i+ git_tree *commit_tree; Err thinkerwim.openbsd.amsterdam 70 i+ git_tree *parent_tree; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ size_t addcount; Err thinkerwim.openbsd.amsterdam 70 i+ size_t delcount; Err thinkerwim.openbsd.amsterdam 70 i+ size_t filecount; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ struct deltainfo **deltas; Err thinkerwim.openbsd.amsterdam 70 i+ size_t ndeltas; Err thinkerwim.openbsd.amsterdam 70 i+}; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* reference and associated data for sorting */ Err thinkerwim.openbsd.amsterdam 70 i+struct referenceinfo { Err thinkerwim.openbsd.amsterdam 70 i+ struct git_reference *ref; Err thinkerwim.openbsd.amsterdam 70 i+ struct commitinfo *ci; Err thinkerwim.openbsd.amsterdam 70 i+}; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+static git_repository *repo; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+static const char *baseurl = ""; /* base URL to make absolute RSS/Atom URI */ Err thinkerwim.openbsd.amsterdam 70 i+static const char *relpath = ""; Err thinkerwim.openbsd.amsterdam 70 i+static const char *repodir; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+static char *name = ""; Err thinkerwim.openbsd.amsterdam 70 i+static char *strippedname = ""; Err thinkerwim.openbsd.amsterdam 70 i+static char description[255]; Err thinkerwim.openbsd.amsterdam 70 i+static char cloneurl[1024]; Err thinkerwim.openbsd.amsterdam 70 i+static char *submodules; Err thinkerwim.openbsd.amsterdam 70 i+static char *licensefiles[] = { "HEAD:LICENSE", "HEAD:LICENSE.md", "HEAD:COPYING" }; Err thinkerwim.openbsd.amsterdam 70 i+static char *license; Err thinkerwim.openbsd.amsterdam 70 i+static char *readmefiles[] = { "HEAD:README", "HEAD:README.md" }; Err thinkerwim.openbsd.amsterdam 70 i+static char *readme; Err thinkerwim.openbsd.amsterdam 70 i+static long long nlogcommits = -1; /* -1 indicates not used */ Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* cache */ Err thinkerwim.openbsd.amsterdam 70 i+static git_oid lastoid; Err thinkerwim.openbsd.amsterdam 70 i+static char lastoidstr[GIT_OID_HEXSZ + 2]; /* id + newline + NUL byte */ Err thinkerwim.openbsd.amsterdam 70 i+static FILE *rcachefp, *wcachefp; Err thinkerwim.openbsd.amsterdam 70 i+static const char *cachefile; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Handle read or write errors for a FILE * stream */ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+checkfileerror(FILE *fp, const char *name, int mode) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ if (mode == 'r' && ferror(fp)) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "read error: %s", name); Err thinkerwim.openbsd.amsterdam 70 i+ else if (mode == 'w' && (fflush(fp) || ferror(fp))) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "write error: %s", name); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Format `len' columns of characters. If string is shorter pad the rest Err thinkerwim.openbsd.amsterdam 70 i+ * with characters `pad`. */ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+utf8pad(char *buf, size_t bufsiz, const char *s, size_t len, int pad) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ wchar_t wc; Err thinkerwim.openbsd.amsterdam 70 i+ size_t col = 0, i, slen, siz = 0; Err thinkerwim.openbsd.amsterdam 70 i+ int inc, rl, w; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ if (!len) { Err thinkerwim.openbsd.amsterdam 70 i+ buf[0] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ slen = strlen(s); Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < slen; i += inc) { Err thinkerwim.openbsd.amsterdam 70 i+ inc = 1; /* next byte */ Err thinkerwim.openbsd.amsterdam 70 i+ if ((unsigned char)s[i] < 32) Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ rl = mbtowc(&wc, &s[i], slen - i < 4 ? slen - i : 4); Err thinkerwim.openbsd.amsterdam 70 i+ inc = rl; Err thinkerwim.openbsd.amsterdam 70 i+ if (rl < 0) { Err thinkerwim.openbsd.amsterdam 70 i+ mbtowc(NULL, NULL, 0); /* reset state */ Err thinkerwim.openbsd.amsterdam 70 i+ inc = 1; /* invalid, seek next byte */ Err thinkerwim.openbsd.amsterdam 70 i+ w = 1; /* replacement char is one width */ Err thinkerwim.openbsd.amsterdam 70 i+ } else if ((w = wcwidth(wc)) == -1) { Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (col + w > len || (col + w == len && s[i + inc])) { Err thinkerwim.openbsd.amsterdam 70 i+ if (siz + 4 >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ memcpy(&buf[siz], PAD_TRUNCATE_SYMBOL, sizeof(PAD_TRUNCATE_SYMBOL) - 1); Err thinkerwim.openbsd.amsterdam 70 i+ siz += sizeof(PAD_TRUNCATE_SYMBOL) - 1; Err thinkerwim.openbsd.amsterdam 70 i+ buf[siz] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ col++; Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ } else if (rl < 0) { Err thinkerwim.openbsd.amsterdam 70 i+ if (siz + 4 >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ memcpy(&buf[siz], UTF_INVALID_SYMBOL, sizeof(UTF_INVALID_SYMBOL) - 1); Err thinkerwim.openbsd.amsterdam 70 i+ siz += sizeof(UTF_INVALID_SYMBOL) - 1; Err thinkerwim.openbsd.amsterdam 70 i+ buf[siz] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ col++; Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (siz + inc + 1 >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ memcpy(&buf[siz], &s[i], inc); Err thinkerwim.openbsd.amsterdam 70 i+ siz += inc; Err thinkerwim.openbsd.amsterdam 70 i+ buf[siz] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ col += w; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ len -= col; Err thinkerwim.openbsd.amsterdam 70 i+ if (siz + len + 1 >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ memset(&buf[siz], pad, len); Err thinkerwim.openbsd.amsterdam 70 i+ siz += len; Err thinkerwim.openbsd.amsterdam 70 i+ buf[siz] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+joinpath(char *buf, size_t bufsiz, const char *path, const char *path2) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ int r; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ r = snprintf(buf, bufsiz, "%s%s%s", Err thinkerwim.openbsd.amsterdam 70 i+ path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2); Err thinkerwim.openbsd.amsterdam 70 i+ if (r < 0 || (size_t)r >= bufsiz) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "path truncated: '%s%s%s'", Err thinkerwim.openbsd.amsterdam 70 i+ path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+deltainfo_free(struct deltainfo *di) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ if (!di) Err thinkerwim.openbsd.amsterdam 70 i+ return; Err thinkerwim.openbsd.amsterdam 70 i+ git_patch_free(di->patch); Err thinkerwim.openbsd.amsterdam 70 i+ memset(di, 0, sizeof(*di)); Err thinkerwim.openbsd.amsterdam 70 i+ free(di); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+commitinfo_getstats(struct commitinfo *ci) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct deltainfo *di; Err thinkerwim.openbsd.amsterdam 70 i+ git_diff_options opts; Err thinkerwim.openbsd.amsterdam 70 i+ git_diff_find_options fopts; Err thinkerwim.openbsd.amsterdam 70 i+ const git_diff_delta *delta; Err thinkerwim.openbsd.amsterdam 70 i+ const git_diff_hunk *hunk; Err thinkerwim.openbsd.amsterdam 70 i+ const git_diff_line *line; Err thinkerwim.openbsd.amsterdam 70 i+ git_patch *patch = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ size_t ndeltas, nhunks, nhunklines; Err thinkerwim.openbsd.amsterdam 70 i+ size_t i, j, k; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (git_tree_lookup(&(ci->commit_tree), repo, git_commit_tree_id(ci->commit))) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_commit_parent(&(ci->parent), ci->commit, 0)) { Err thinkerwim.openbsd.amsterdam 70 i+ if (git_tree_lookup(&(ci->parent_tree), repo, git_commit_tree_id(ci->parent))) { Err thinkerwim.openbsd.amsterdam 70 i+ ci->parent = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ ci->parent_tree = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION); Err thinkerwim.openbsd.amsterdam 70 i+ opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH | Err thinkerwim.openbsd.amsterdam 70 i+ GIT_DIFF_IGNORE_SUBMODULES | Err thinkerwim.openbsd.amsterdam 70 i+ GIT_DIFF_INCLUDE_TYPECHANGE; Err thinkerwim.openbsd.amsterdam 70 i+ if (git_diff_tree_to_tree(&(ci->diff), repo, ci->parent_tree, ci->commit_tree, &opts)) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (git_diff_find_init_options(&fopts, GIT_DIFF_FIND_OPTIONS_VERSION)) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ /* find renames and copies, exact matches (no heuristic) for renames. */ Err thinkerwim.openbsd.amsterdam 70 i+ fopts.flags |= GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES | Err thinkerwim.openbsd.amsterdam 70 i+ GIT_DIFF_FIND_EXACT_MATCH_ONLY; Err thinkerwim.openbsd.amsterdam 70 i+ if (git_diff_find_similar(ci->diff, &fopts)) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ ndeltas = git_diff_num_deltas(ci->diff); Err thinkerwim.openbsd.amsterdam 70 i+ if (ndeltas && !(ci->deltas = calloc(ndeltas, sizeof(struct deltainfo *)))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "calloc"); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < ndeltas; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (git_patch_from_diff(&patch, ci->diff, i)) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!(di = calloc(1, sizeof(struct deltainfo)))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "calloc"); Err thinkerwim.openbsd.amsterdam 70 i+ di->patch = patch; Err thinkerwim.openbsd.amsterdam 70 i+ ci->deltas[i] = di; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ delta = git_patch_get_delta(patch); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* skip stats for binary data */ Err thinkerwim.openbsd.amsterdam 70 i+ if (delta->flags & GIT_DIFF_FLAG_BINARY) Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ nhunks = git_patch_num_hunks(patch); Err thinkerwim.openbsd.amsterdam 70 i+ for (j = 0; j < nhunks; j++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (git_patch_get_hunk(&hunk, &nhunklines, patch, j)) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ for (k = 0; ; k++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (git_patch_get_line_in_hunk(&line, patch, j, k)) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ if (line->old_lineno == -1) { Err thinkerwim.openbsd.amsterdam 70 i+ di->addcount++; Err thinkerwim.openbsd.amsterdam 70 i+ ci->addcount++; Err thinkerwim.openbsd.amsterdam 70 i+ } else if (line->new_lineno == -1) { Err thinkerwim.openbsd.amsterdam 70 i+ di->delcount++; Err thinkerwim.openbsd.amsterdam 70 i+ ci->delcount++; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ ci->ndeltas = i; Err thinkerwim.openbsd.amsterdam 70 i+ ci->filecount = i; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+err: Err thinkerwim.openbsd.amsterdam 70 i+ git_diff_free(ci->diff); Err thinkerwim.openbsd.amsterdam 70 i+ ci->diff = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_tree_free(ci->commit_tree); Err thinkerwim.openbsd.amsterdam 70 i+ ci->commit_tree = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_tree_free(ci->parent_tree); Err thinkerwim.openbsd.amsterdam 70 i+ ci->parent_tree = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_commit_free(ci->parent); Err thinkerwim.openbsd.amsterdam 70 i+ ci->parent = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->deltas) Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < ci->ndeltas; i++) Err thinkerwim.openbsd.amsterdam 70 i+ deltainfo_free(ci->deltas[i]); Err thinkerwim.openbsd.amsterdam 70 i+ free(ci->deltas); Err thinkerwim.openbsd.amsterdam 70 i+ ci->deltas = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ ci->ndeltas = 0; Err thinkerwim.openbsd.amsterdam 70 i+ ci->addcount = 0; Err thinkerwim.openbsd.amsterdam 70 i+ ci->delcount = 0; Err thinkerwim.openbsd.amsterdam 70 i+ ci->filecount = 0; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+commitinfo_free(struct commitinfo *ci) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ size_t i; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!ci) Err thinkerwim.openbsd.amsterdam 70 i+ return; Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->deltas) Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < ci->ndeltas; i++) Err thinkerwim.openbsd.amsterdam 70 i+ deltainfo_free(ci->deltas[i]); Err thinkerwim.openbsd.amsterdam 70 i+ free(ci->deltas); Err thinkerwim.openbsd.amsterdam 70 i+ git_diff_free(ci->diff); Err thinkerwim.openbsd.amsterdam 70 i+ git_tree_free(ci->commit_tree); Err thinkerwim.openbsd.amsterdam 70 i+ git_tree_free(ci->parent_tree); Err thinkerwim.openbsd.amsterdam 70 i+ git_commit_free(ci->commit); Err thinkerwim.openbsd.amsterdam 70 i+ git_commit_free(ci->parent); Err thinkerwim.openbsd.amsterdam 70 i+ memset(ci, 0, sizeof(*ci)); Err thinkerwim.openbsd.amsterdam 70 i+ free(ci); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+struct commitinfo * Err thinkerwim.openbsd.amsterdam 70 i+commitinfo_getbyoid(const git_oid *id) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct commitinfo *ci; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!(ci = calloc(1, sizeof(struct commitinfo)))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "calloc"); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (git_commit_lookup(&(ci->commit), repo, id)) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ ci->id = id; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_oid_tostr(ci->oid, sizeof(ci->oid), git_commit_id(ci->commit)); Err thinkerwim.openbsd.amsterdam 70 i+ git_oid_tostr(ci->parentoid, sizeof(ci->parentoid), git_commit_parent_id(ci->commit, 0)); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ ci->author = git_commit_author(ci->commit); Err thinkerwim.openbsd.amsterdam 70 i+ ci->committer = git_commit_committer(ci->commit); Err thinkerwim.openbsd.amsterdam 70 i+ ci->summary = git_commit_summary(ci->commit); Err thinkerwim.openbsd.amsterdam 70 i+ ci->msg = git_commit_message(ci->commit); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return ci; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+err: Err thinkerwim.openbsd.amsterdam 70 i+ commitinfo_free(ci); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return NULL; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+refs_cmp(const void *v1, const void *v2) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ const struct referenceinfo *r1 = v1, *r2 = v2; Err thinkerwim.openbsd.amsterdam 70 i+ time_t t1, t2; Err thinkerwim.openbsd.amsterdam 70 i+ int r; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if ((r = git_reference_is_tag(r1->ref) - git_reference_is_tag(r2->ref))) Err thinkerwim.openbsd.amsterdam 70 i+ return r; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ t1 = r1->ci->author ? r1->ci->author->when.time : 0; Err thinkerwim.openbsd.amsterdam 70 i+ t2 = r2->ci->author ? r2->ci->author->when.time : 0; Err thinkerwim.openbsd.amsterdam 70 i+ if ((r = t1 > t2 ? -1 : (t1 == t2 ? 0 : 1))) Err thinkerwim.openbsd.amsterdam 70 i+ return r; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return strcmp(git_reference_shorthand(r1->ref), Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_shorthand(r2->ref)); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+getrefs(struct referenceinfo **pris, size_t *prefcount) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct referenceinfo *ris = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ struct commitinfo *ci = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_iterator *it = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ const git_oid *id = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_object *obj = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_reference *dref = NULL, *r, *ref = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ size_t i, refcount; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ *pris = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ *prefcount = 0; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (git_reference_iterator_new(&it, repo)) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (refcount = 0; !git_reference_next(&ref, it); ) { Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_reference_is_branch(ref) && !git_reference_is_tag(ref)) { Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_free(ref); Err thinkerwim.openbsd.amsterdam 70 i+ ref = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ switch (git_reference_type(ref)) { Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_REF_SYMBOLIC: Err thinkerwim.openbsd.amsterdam 70 i+ if (git_reference_resolve(&dref, ref)) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ r = dref; Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_REF_OID: Err thinkerwim.openbsd.amsterdam 70 i+ r = ref; Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ default: Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_reference_target(r) || Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_peel(&obj, r, GIT_OBJ_ANY)) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ if (!(id = git_object_id(obj))) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ if (!(ci = commitinfo_getbyoid(id))) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!(ris = reallocarray(ris, refcount + 1, sizeof(*ris)))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "realloc"); Err thinkerwim.openbsd.amsterdam 70 i+ ris[refcount].ci = ci; Err thinkerwim.openbsd.amsterdam 70 i+ ris[refcount].ref = r; Err thinkerwim.openbsd.amsterdam 70 i+ refcount++; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ obj = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_free(dref); Err thinkerwim.openbsd.amsterdam 70 i+ dref = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_iterator_free(it); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* sort by type, date then shorthand name */ Err thinkerwim.openbsd.amsterdam 70 i+ qsort(ris, refcount, sizeof(*ris), refs_cmp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ *pris = ris; Err thinkerwim.openbsd.amsterdam 70 i+ *prefcount = refcount; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+err: Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_free(dref); Err thinkerwim.openbsd.amsterdam 70 i+ commitinfo_free(ci); Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < refcount; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ commitinfo_free(ris[i].ci); Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_free(ris[i].ref); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ free(ris); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+FILE * Err thinkerwim.openbsd.amsterdam 70 i+efopen(const char *filename, const char *flags) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ FILE *fp; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!(fp = fopen(filename, flags))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "fopen: '%s'", filename); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return fp; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Escape characters below as HTML 2.0 / XML 1.0. */ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+xmlencode(FILE *fp, const char *s, size_t len) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ size_t i; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; *s && i < len; s++, i++) { Err thinkerwim.openbsd.amsterdam 70 i+ switch(*s) { Err thinkerwim.openbsd.amsterdam 70 i+ case '<': fputs("<", fp); break; Err thinkerwim.openbsd.amsterdam 70 i+ case '>': fputs(">", fp); break; Err thinkerwim.openbsd.amsterdam 70 i+ case '\'': fputs("'", fp); break; Err thinkerwim.openbsd.amsterdam 70 i+ case '&': fputs("&", fp); break; Err thinkerwim.openbsd.amsterdam 70 i+ case '"': fputs(""", fp); break; Err thinkerwim.openbsd.amsterdam 70 i+ default: putc(*s, fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Escape characters in text in geomyidae .gmi format, with newlines */ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+gmitextnl(FILE *fp, const char *s, size_t len) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ size_t i, n = 0; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; s[i] && i < len; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ switch (s[i]) { Err thinkerwim.openbsd.amsterdam 70 i+ case '\r': break; Err thinkerwim.openbsd.amsterdam 70 i+ default: fputc(s[i], fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ n = (s[i] != '\n'); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Escape characters in text in geomyidae .gmi format, Err thinkerwim.openbsd.amsterdam 70 i+ newlines are ignored */ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+gmitext(FILE *fp, const char *s, size_t len) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ size_t i; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; *s && i < len; s++, i++) { Err thinkerwim.openbsd.amsterdam 70 i+ switch (*s) { Err thinkerwim.openbsd.amsterdam 70 i+ case '\r': /* ignore CR */ Err thinkerwim.openbsd.amsterdam 70 i+ case '\n': /* ignore LF */ Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ default: Err thinkerwim.openbsd.amsterdam 70 i+ putc(*s, fp); Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+/* Escape characters in links in geomyidae .gmi format */ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+gmilink(FILE *fp, const char *s, size_t len) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ size_t i; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; *s && i < len; s++, i++) { Err thinkerwim.openbsd.amsterdam 70 i+ switch (*s) { Err thinkerwim.openbsd.amsterdam 70 i+ case '\r': /* ignore CR */ Err thinkerwim.openbsd.amsterdam 70 i+ case '\n': /* ignore LF */ Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ default: Err thinkerwim.openbsd.amsterdam 70 i+ putc(*s, fp); Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+mkdirp(const char *path) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ char tmp[PATH_MAX], *p; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (strlcpy(tmp, path, sizeof(tmp)) >= sizeof(tmp)) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "path truncated: '%s'", path); Err thinkerwim.openbsd.amsterdam 70 i+ for (p = tmp + (tmp[0] == '/'); *p; p++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (*p != '/') Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ *p = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ *p = '/'; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+printtimez(FILE *fp, const git_time *intime) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct tm *intm; Err thinkerwim.openbsd.amsterdam 70 i+ time_t t; Err thinkerwim.openbsd.amsterdam 70 i+ char out[32]; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ t = (time_t)intime->time; Err thinkerwim.openbsd.amsterdam 70 i+ if (!(intm = gmtime(&t))) Err thinkerwim.openbsd.amsterdam 70 i+ return; Err thinkerwim.openbsd.amsterdam 70 i+ strftime(out, sizeof(out), "%Y-%m-%dT%H:%M:%SZ", intm); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(out, fp); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+printtime(FILE *fp, const git_time *intime) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct tm *intm; Err thinkerwim.openbsd.amsterdam 70 i+ time_t t; Err thinkerwim.openbsd.amsterdam 70 i+ char out[32]; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ t = (time_t)intime->time + (intime->offset * 60); Err thinkerwim.openbsd.amsterdam 70 i+ if (!(intm = gmtime(&t))) Err thinkerwim.openbsd.amsterdam 70 i+ return; Err thinkerwim.openbsd.amsterdam 70 i+ strftime(out, sizeof(out), "%a, %e %b %Y %H:%M:%S", intm); Err thinkerwim.openbsd.amsterdam 70 i+ if (intime->offset < 0) Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%s -%02d%02d", out, Err thinkerwim.openbsd.amsterdam 70 i+ -(intime->offset) / 60, -(intime->offset) % 60); Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%s +%02d%02d", out, Err thinkerwim.openbsd.amsterdam 70 i+ intime->offset / 60, intime->offset % 60); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+printtimeshort(FILE *fp, const git_time *intime) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct tm *intm; Err thinkerwim.openbsd.amsterdam 70 i+ time_t t; Err thinkerwim.openbsd.amsterdam 70 i+ char out[32]; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ t = (time_t)intime->time; Err thinkerwim.openbsd.amsterdam 70 i+ if (!(intm = gmtime(&t))) Err thinkerwim.openbsd.amsterdam 70 i+ return; Err thinkerwim.openbsd.amsterdam 70 i+ strftime(out, sizeof(out), "%Y-%m-%d %H:%M", intm); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(out, fp); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+writeheader(FILE *fp, const char *title) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ gmitext(fp, title, strlen(title)); Err thinkerwim.openbsd.amsterdam 70 i+ if (title[0] && strippedname[0]) Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" - ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmitext(fp, strippedname, strlen(strippedname)); Err thinkerwim.openbsd.amsterdam 70 i+ if (description[0]) Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" - ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmitext(fp, description, strlen(description)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ if (cloneurl[0]) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("=> ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, cloneurl, strlen(cloneurl)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" git clone: ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, cloneurl, strlen(cloneurl)); Err thinkerwim.openbsd.amsterdam 70 i+ fputc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/log.gmi Log\n", relpath); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/files.gmi Files\n", relpath); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/refs.gmi Refs\n", relpath); Err thinkerwim.openbsd.amsterdam 70 i+ if (submodules) Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/file/%s.gmi Submodules\n", Err thinkerwim.openbsd.amsterdam 70 i+ relpath, submodules); Err thinkerwim.openbsd.amsterdam 70 i+ if (readme) Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/file/%s.gmi README\n", Err thinkerwim.openbsd.amsterdam 70 i+ relpath, readme); Err thinkerwim.openbsd.amsterdam 70 i+ if (license) Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/file/%s.gmi LICENSE\n", Err thinkerwim.openbsd.amsterdam 70 i+ relpath, license); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("---\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+writefooter(FILE *fp) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n\ngenerated w/ stagit-gemini\n\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+size_t Err thinkerwim.openbsd.amsterdam 70 i+writeblobgmi(FILE *fp, const git_blob *blob) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ size_t n = 0, i, j, len, prev; Err thinkerwim.openbsd.amsterdam 70 i+ const char *nfmt = "%6zu "; Err thinkerwim.openbsd.amsterdam 70 i+ const char *s = git_blob_rawcontent(blob); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ len = git_blob_rawsize(blob); Err thinkerwim.openbsd.amsterdam 70 i+ if (len > 0) { Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0, prev = 0; i < len; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (s[i] != '\n') Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ n++; Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, nfmt, n, n, n); Err thinkerwim.openbsd.amsterdam 70 i+ for (j = prev; j <= i && s[j]; j++) { Err thinkerwim.openbsd.amsterdam 70 i+ switch (s[j]) { Err thinkerwim.openbsd.amsterdam 70 i+ case '\r': break; Err thinkerwim.openbsd.amsterdam 70 i+ default: putc(s[j], fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ prev = i + 1; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ /* trailing data */ Err thinkerwim.openbsd.amsterdam 70 i+ if ((len - prev) > 0) { Err thinkerwim.openbsd.amsterdam 70 i+ n++; Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, nfmt, n, n, n); Err thinkerwim.openbsd.amsterdam 70 i+ for (j = prev; j < len - prev && s[j]; j++) { Err thinkerwim.openbsd.amsterdam 70 i+ switch (s[j]) { Err thinkerwim.openbsd.amsterdam 70 i+ case '\r': break; Err thinkerwim.openbsd.amsterdam 70 i+ case '\t': fputs(" ", fp); break; Err thinkerwim.openbsd.amsterdam 70 i+ default: putc(s[j], fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return n; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+printcommit(FILE *fp, struct commitinfo *ci) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/commit/%s.gmi commit %s\n", Err thinkerwim.openbsd.amsterdam 70 i+ relpath, ci->oid, ci->oid); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->parentoid[0]) Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/commit/%s.gmi parent %s\n", Err thinkerwim.openbsd.amsterdam 70 i+ relpath, ci->parentoid, ci->parentoid); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->author) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" Author: ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, ci->author->name, strlen(ci->author->name)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" <", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, ci->author->email, strlen(ci->author->email)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(">\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("Date: ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ printtime(fp, &(ci->author->when)); Err thinkerwim.openbsd.amsterdam 70 i+ putc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->msg) { Err thinkerwim.openbsd.amsterdam 70 i+ putc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmitextnl(fp, ci->msg, strlen(ci->msg)); Err thinkerwim.openbsd.amsterdam 70 i+ putc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+printshowfile(FILE *fp, struct commitinfo *ci) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ const git_diff_delta *delta; Err thinkerwim.openbsd.amsterdam 70 i+ const git_diff_hunk *hunk; Err thinkerwim.openbsd.amsterdam 70 i+ const git_diff_line *line; Err thinkerwim.openbsd.amsterdam 70 i+ git_patch *patch; Err thinkerwim.openbsd.amsterdam 70 i+ size_t nhunks, nhunklines, changed, add, del, total, i, j, k; Err thinkerwim.openbsd.amsterdam 70 i+ char buf[256], filename[256], linestr[32]; Err thinkerwim.openbsd.amsterdam 70 i+ int c; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ printcommit(fp, ci); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!ci->deltas) Err thinkerwim.openbsd.amsterdam 70 i+ return; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->filecount > 1000 || Err thinkerwim.openbsd.amsterdam 70 i+ ci->ndeltas > 1000 || Err thinkerwim.openbsd.amsterdam 70 i+ ci->addcount > 100000 || Err thinkerwim.openbsd.amsterdam 70 i+ ci->delcount > 100000) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\nDiff is too large, output suppressed.\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ return; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* diff stat */ Err thinkerwim.openbsd.amsterdam 70 i+ fputs("Diffstat:\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < ci->ndeltas; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ delta = git_patch_get_delta(ci->deltas[i]->patch); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ switch (delta->status) { Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_DELTA_ADDED: c = 'A'; break; Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_DELTA_COPIED: c = 'C'; break; Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_DELTA_DELETED: c = 'D'; break; Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_DELTA_MODIFIED: c = 'M'; break; Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_DELTA_RENAMED: c = 'R'; break; Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_DELTA_TYPECHANGE: c = 'T'; break; Err thinkerwim.openbsd.amsterdam 70 i+ default: c = ' '; break; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (strcmp(delta->old_file.path, delta->new_file.path)) { Err thinkerwim.openbsd.amsterdam 70 i+ snprintf(filename, sizeof(filename), "%s -> %s", Err thinkerwim.openbsd.amsterdam 70 i+ delta->old_file.path, delta->new_file.path); Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), filename, 35, ' '); Err thinkerwim.openbsd.amsterdam 70 i+ } else { Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), delta->old_file.path, 35, ' '); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, " %c ", c); Err thinkerwim.openbsd.amsterdam 70 i+ gmitext(fp, buf, strlen(buf)); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ add = ci->deltas[i]->addcount; Err thinkerwim.openbsd.amsterdam 70 i+ del = ci->deltas[i]->delcount; Err thinkerwim.openbsd.amsterdam 70 i+ changed = add + del; Err thinkerwim.openbsd.amsterdam 70 i+ total = sizeof(linestr) - 2; Err thinkerwim.openbsd.amsterdam 70 i+ if (changed > total) { Err thinkerwim.openbsd.amsterdam 70 i+ if (add) Err thinkerwim.openbsd.amsterdam 70 i+ add = ((float)total / changed * add) + 1; Err thinkerwim.openbsd.amsterdam 70 i+ if (del) Err thinkerwim.openbsd.amsterdam 70 i+ del = ((float)total / changed * del) + 1; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ memset(&linestr, '+', add); Err thinkerwim.openbsd.amsterdam 70 i+ memset(&linestr[add], '-', del); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, " | %7zu ", Err thinkerwim.openbsd.amsterdam 70 i+ ci->deltas[i]->addcount + ci->deltas[i]->delcount); Err thinkerwim.openbsd.amsterdam 70 i+ fwrite(&linestr, 1, add, fp); Err thinkerwim.openbsd.amsterdam 70 i+ fwrite(&linestr[add], 1, del, fp); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "\n%zu file%s changed, %zu insertion%s(+), %zu deletion%s(-)\n", Err thinkerwim.openbsd.amsterdam 70 i+ ci->filecount, ci->filecount == 1 ? "" : "s", Err thinkerwim.openbsd.amsterdam 70 i+ ci->addcount, ci->addcount == 1 ? "" : "s", Err thinkerwim.openbsd.amsterdam 70 i+ ci->delcount, ci->delcount == 1 ? "" : "s"); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fputs("---\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < ci->ndeltas; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ patch = ci->deltas[i]->patch; Err thinkerwim.openbsd.amsterdam 70 i+ delta = git_patch_get_delta(patch); Err thinkerwim.openbsd.amsterdam 70 i+ /* NOTE: only links to new path */ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/file/", relpath); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, delta->new_file.path, strlen(delta->new_file.path)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(".gmi diff --git a/", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, delta->old_file.path, strlen(delta->old_file.path)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" b/", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, delta->new_file.path, strlen(delta->new_file.path)); Err thinkerwim.openbsd.amsterdam 70 i+ fputc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* check binary data */ Err thinkerwim.openbsd.amsterdam 70 i+ if (delta->flags & GIT_DIFF_FLAG_BINARY) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("Binary files differ.\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ nhunks = git_patch_num_hunks(patch); Err thinkerwim.openbsd.amsterdam 70 i+ for (j = 0; j < nhunks; j++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (git_patch_get_hunk(&hunk, &nhunklines, patch, j)) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (hunk->header_len > 0 && hunk->header[0] == '[') Err thinkerwim.openbsd.amsterdam 70 i+ fputc('t', fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmitext(fp, hunk->header, hunk->header_len); Err thinkerwim.openbsd.amsterdam 70 i+ putc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (k = 0; ; k++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (git_patch_get_line_in_hunk(&line, patch, j, k)) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ if (line->old_lineno == -1) Err thinkerwim.openbsd.amsterdam 70 i+ fputs("+", fp); Err thinkerwim.openbsd.amsterdam 70 i+ else if (line->new_lineno == -1) Err thinkerwim.openbsd.amsterdam 70 i+ fputs("-", fp); Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmitext(fp, line->content, line->content_len); Err thinkerwim.openbsd.amsterdam 70 i+ putc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+writelogline(FILE *fp, struct commitinfo *ci) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ char buf[256]; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/commit/%s.gmi ", relpath, ci->oid); Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->author) Err thinkerwim.openbsd.amsterdam 70 i+ printtimeshort(fp, &(ci->author->when)); Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), ci->summary ? ci->summary : "", 40, ' '); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, buf, strlen(buf)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), ci->author ? ci->author->name : "", 19, '\0'); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, buf, strlen(buf)); Err thinkerwim.openbsd.amsterdam 70 i+ fputc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+writelog(FILE *fp, const git_oid *oid) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct commitinfo *ci; Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk *w = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_oid id; Err thinkerwim.openbsd.amsterdam 70 i+ char path[PATH_MAX], oidstr[GIT_OID_HEXSZ + 1]; Err thinkerwim.openbsd.amsterdam 70 i+ FILE *fpfile; Err thinkerwim.openbsd.amsterdam 70 i+ size_t remcommits = 0; Err thinkerwim.openbsd.amsterdam 70 i+ int r; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_new(&w, repo); Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_push(w, oid); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ while (!git_revwalk_next(&id, w)) { Err thinkerwim.openbsd.amsterdam 70 i+ if (cachefile && !memcmp(&id, &lastoid, sizeof(id))) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_oid_tostr(oidstr, sizeof(oidstr), &id); Err thinkerwim.openbsd.amsterdam 70 i+ r = snprintf(path, sizeof(path), "commit/%s.gmi", oidstr); Err thinkerwim.openbsd.amsterdam 70 i+ if (r < 0 || (size_t)r >= sizeof(path)) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "path truncated: 'commit/%s.gmi'", oidstr); Err thinkerwim.openbsd.amsterdam 70 i+ r = access(path, F_OK); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* optimization: if there are no log lines to write and Err thinkerwim.openbsd.amsterdam 70 i+ the commit file already exists: skip the diffstat */ Err thinkerwim.openbsd.amsterdam 70 i+ if (!nlogcommits) { Err thinkerwim.openbsd.amsterdam 70 i+ remcommits++; Err thinkerwim.openbsd.amsterdam 70 i+ if (!r) Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!(ci = commitinfo_getbyoid(&id))) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (nlogcommits != 0) { Err thinkerwim.openbsd.amsterdam 70 i+ writelogline(fp, ci); Err thinkerwim.openbsd.amsterdam 70 i+ if (nlogcommits > 0) Err thinkerwim.openbsd.amsterdam 70 i+ nlogcommits--; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (cachefile) Err thinkerwim.openbsd.amsterdam 70 i+ writelogline(wcachefp, ci); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* check if file exists if so skip it */ Err thinkerwim.openbsd.amsterdam 70 i+ if (r) { Err thinkerwim.openbsd.amsterdam 70 i+ /* lookup stats: only required here for gemini */ Err thinkerwim.openbsd.amsterdam 70 i+ if (commitinfo_getstats(ci) == -1) Err thinkerwim.openbsd.amsterdam 70 i+ goto err; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fpfile = efopen(path, "w"); Err thinkerwim.openbsd.amsterdam 70 i+ writeheader(fpfile, ci->summary); Err thinkerwim.openbsd.amsterdam 70 i+ printshowfile(fpfile, ci); Err thinkerwim.openbsd.amsterdam 70 i+ writefooter(fpfile); Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fpfile, path, 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fpfile); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+err: Err thinkerwim.openbsd.amsterdam 70 i+ commitinfo_free(ci); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_free(w); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (nlogcommits == 0 && remcommits != 0) { Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%16.16s " Err thinkerwim.openbsd.amsterdam 70 i+ "%zu more commits remaining, fetch the repository\n", Err thinkerwim.openbsd.amsterdam 70 i+ "", remcommits); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+printcommitatom(FILE *fp, struct commitinfo *ci, const char *tag) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%s\n", ci->oid); Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->author) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("", fp); Err thinkerwim.openbsd.amsterdam 70 i+ printtimez(fp, &(ci->author->when)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->committer) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("", fp); Err thinkerwim.openbsd.amsterdam 70 i+ printtimez(fp, &(ci->committer->when)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->summary) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("", fp); Err thinkerwim.openbsd.amsterdam 70 i+ if (tag && tag[0]) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("[", fp); Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, tag, strlen(tag)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("] ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, ci->summary, strlen(ci->summary)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "\n", Err thinkerwim.openbsd.amsterdam 70 i+ baseurl, ci->oid); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->author) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, ci->author->name, strlen(ci->author->name)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, ci->author->email, strlen(ci->author->email)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fputs("", fp); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "commit %s\n", ci->oid); Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->parentoid[0]) Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "parent %s\n", ci->parentoid); Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->author) { Err thinkerwim.openbsd.amsterdam 70 i+ fputs("Author: ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, ci->author->name, strlen(ci->author->name)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" <", fp); Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, ci->author->email, strlen(ci->author->email)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(">\nDate: ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ printtime(fp, &(ci->author->when)); Err thinkerwim.openbsd.amsterdam 70 i+ putc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->msg) { Err thinkerwim.openbsd.amsterdam 70 i+ putc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, ci->msg, strlen(ci->msg)); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n\n\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+writeatom(FILE *fp, int all) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct referenceinfo *ris = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ size_t refcount = 0; Err thinkerwim.openbsd.amsterdam 70 i+ struct commitinfo *ci; Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk *w = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_oid id; Err thinkerwim.openbsd.amsterdam 70 i+ size_t i, m = 100; /* last 'm' commits */ Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n" Err thinkerwim.openbsd.amsterdam 70 i+ "\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, strippedname, strlen(strippedname)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(", branch HEAD\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ xmlencode(fp, description, strlen(description)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* all commits or only tags? */ Err thinkerwim.openbsd.amsterdam 70 i+ if (all) { Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_new(&w, repo); Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_push_head(w); Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < m && !git_revwalk_next(&id, w); i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (!(ci = commitinfo_getbyoid(&id))) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ printcommitatom(fp, ci, ""); Err thinkerwim.openbsd.amsterdam 70 i+ commitinfo_free(ci); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ git_revwalk_free(w); Err thinkerwim.openbsd.amsterdam 70 i+ } else if (getrefs(&ris, &refcount) != -1) { Err thinkerwim.openbsd.amsterdam 70 i+ /* references: tags */ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < refcount; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (git_reference_is_tag(ris[i].ref)) Err thinkerwim.openbsd.amsterdam 70 i+ printcommitatom(fp, ris[i].ci, Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_shorthand(ris[i].ref)); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ commitinfo_free(ris[i].ci); Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_free(ris[i].ref); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ free(ris); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+size_t Err thinkerwim.openbsd.amsterdam 70 i+writeblob(git_object *obj, const char *fpath, const char *filename, size_t filesize) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ char tmp[PATH_MAX] = "", *d; Err thinkerwim.openbsd.amsterdam 70 i+ size_t lc = 0; Err thinkerwim.openbsd.amsterdam 70 i+ FILE *fp; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (strlcpy(tmp, fpath, sizeof(tmp)) >= sizeof(tmp)) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "path truncated: '%s'", fpath); Err thinkerwim.openbsd.amsterdam 70 i+ if (!(d = dirname(tmp))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "dirname"); Err thinkerwim.openbsd.amsterdam 70 i+ if (mkdirp(d)) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fp = efopen(fpath, "w"); Err thinkerwim.openbsd.amsterdam 70 i+ writeheader(fp, filename); Err thinkerwim.openbsd.amsterdam 70 i+ if (filename[0] == '[') Err thinkerwim.openbsd.amsterdam 70 i+ fputs("[|", fp); Err thinkerwim.openbsd.amsterdam 70 i+ gmitext(fp, filename, strlen(filename)); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, " (%zuB)\n", filesize); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("---\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (git_blob_is_binary((git_blob *)obj)) Err thinkerwim.openbsd.amsterdam 70 i+ fputs("Binary file.\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ lc = writeblobgmi(fp, (git_blob *)obj); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ writefooter(fp); Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fp, fpath, 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return lc; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+const char * Err thinkerwim.openbsd.amsterdam 70 i+filemode(git_filemode_t m) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ static char mode[11]; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ memset(mode, '-', sizeof(mode) - 1); Err thinkerwim.openbsd.amsterdam 70 i+ mode[10] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (S_ISREG(m)) Err thinkerwim.openbsd.amsterdam 70 i+ mode[0] = '-'; Err thinkerwim.openbsd.amsterdam 70 i+ else if (S_ISBLK(m)) Err thinkerwim.openbsd.amsterdam 70 i+ mode[0] = 'b'; Err thinkerwim.openbsd.amsterdam 70 i+ else if (S_ISCHR(m)) Err thinkerwim.openbsd.amsterdam 70 i+ mode[0] = 'c'; Err thinkerwim.openbsd.amsterdam 70 i+ else if (S_ISDIR(m)) Err thinkerwim.openbsd.amsterdam 70 i+ mode[0] = 'd'; Err thinkerwim.openbsd.amsterdam 70 i+ else if (S_ISFIFO(m)) Err thinkerwim.openbsd.amsterdam 70 i+ mode[0] = 'p'; Err thinkerwim.openbsd.amsterdam 70 i+ else if (S_ISLNK(m)) Err thinkerwim.openbsd.amsterdam 70 i+ mode[0] = 'l'; Err thinkerwim.openbsd.amsterdam 70 i+ else if (S_ISSOCK(m)) Err thinkerwim.openbsd.amsterdam 70 i+ mode[0] = 's'; Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ mode[0] = '?'; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IRUSR) mode[1] = 'r'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IWUSR) mode[2] = 'w'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IXUSR) mode[3] = 'x'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IRGRP) mode[4] = 'r'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IWGRP) mode[5] = 'w'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IXGRP) mode[6] = 'x'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IROTH) mode[7] = 'r'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IWOTH) mode[8] = 'w'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_IXOTH) mode[9] = 'x'; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_ISUID) mode[3] = (mode[3] == 'x') ? 's' : 'S'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_ISGID) mode[6] = (mode[6] == 'x') ? 's' : 'S'; Err thinkerwim.openbsd.amsterdam 70 i+ if (m & S_ISVTX) mode[9] = (mode[9] == 'x') ? 't' : 'T'; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return mode; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+writefilestree(FILE *fp, git_tree *tree, const char *path) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ const git_tree_entry *entry = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_object *obj = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ const char *entryname; Err thinkerwim.openbsd.amsterdam 70 i+ char buf[256], filepath[PATH_MAX], entrypath[PATH_MAX], oid[8]; Err thinkerwim.openbsd.amsterdam 70 i+ size_t count, i, lc, filesize; Err thinkerwim.openbsd.amsterdam 70 i+ int r, ret; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ count = git_tree_entrycount(tree); Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < count; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (!(entry = git_tree_entry_byindex(tree, i)) || Err thinkerwim.openbsd.amsterdam 70 i+ !(entryname = git_tree_entry_name(entry))) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ joinpath(entrypath, sizeof(entrypath), path, entryname); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ r = snprintf(filepath, sizeof(filepath), "file/%s.gmi", Err thinkerwim.openbsd.amsterdam 70 i+ entrypath); Err thinkerwim.openbsd.amsterdam 70 i+ if (r < 0 || (size_t)r >= sizeof(filepath)) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "path truncated: 'file/%s.gmi'", entrypath); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_tree_entry_to_object(&obj, repo, entry)) { Err thinkerwim.openbsd.amsterdam 70 i+ switch (git_object_type(obj)) { Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_OBJ_BLOB: Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ case GIT_OBJ_TREE: Err thinkerwim.openbsd.amsterdam 70 i+ /* NOTE: recurses */ Err thinkerwim.openbsd.amsterdam 70 i+ ret = writefilestree(fp, (git_tree *)obj, Err thinkerwim.openbsd.amsterdam 70 i+ entrypath); Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ if (ret) Err thinkerwim.openbsd.amsterdam 70 i+ return ret; Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ default: Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ continue; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ filesize = git_blob_rawsize((git_blob *)obj); Err thinkerwim.openbsd.amsterdam 70 i+ lc = writeblob(obj, filepath, entryname, filesize); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/", relpath); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, filepath, strlen(filepath)); Err thinkerwim.openbsd.amsterdam 70 i+ fputc(' ', fp); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(filemode(git_tree_entry_filemode(entry)), fp); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), entrypath, 50, ' '); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, buf, strlen(buf)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ if (lc > 0) Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%7zuL", lc); Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%7zuB", filesize); Err thinkerwim.openbsd.amsterdam 70 i+ fputc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ } else if (git_tree_entry_type(entry) == GIT_OBJ_COMMIT) { Err thinkerwim.openbsd.amsterdam 70 i+ /* commit object in tree is a submodule */ Err thinkerwim.openbsd.amsterdam 70 i+ git_oid_tostr(oid, sizeof(oid), git_tree_entry_id(entry)); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, oid, strlen(oid)); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "=> %s/file/.gitmodules.gmi ", relpath); Err thinkerwim.openbsd.amsterdam 70 i+ fputs("m--------- ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fputc('\n', fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* NOTE: linecount omitted */ Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+writefiles(FILE *fp, const git_oid *id) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ git_tree *tree = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ git_commit *commit = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ int ret = -1; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%-10.10s ", "Mode"); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%-50.50s ", "Name"); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%8.8s\n", "Size"); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_commit_lookup(&commit, repo, id) && Err thinkerwim.openbsd.amsterdam 70 i+ !git_commit_tree(&tree, commit)) Err thinkerwim.openbsd.amsterdam 70 i+ ret = writefilestree(fp, tree, ""); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ git_commit_free(commit); Err thinkerwim.openbsd.amsterdam 70 i+ git_tree_free(tree); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return ret; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+writerefs(FILE *fp) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ struct referenceinfo *ris = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ struct commitinfo *ci; Err thinkerwim.openbsd.amsterdam 70 i+ size_t count, i, j, refcount; Err thinkerwim.openbsd.amsterdam 70 i+ const char *titles[] = { "Branches", "Tags" }; Err thinkerwim.openbsd.amsterdam 70 i+ const char *s; Err thinkerwim.openbsd.amsterdam 70 i+ char buf[256]; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (getrefs(&ris, &refcount) == -1) Err thinkerwim.openbsd.amsterdam 70 i+ return -1; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0, j = 0, count = 0; i < refcount; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (j == 0 && git_reference_is_tag(ris[i].ref)) { Err thinkerwim.openbsd.amsterdam 70 i+ /* table footer */ Err thinkerwim.openbsd.amsterdam 70 i+ if (count) Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ count = 0; Err thinkerwim.openbsd.amsterdam 70 i+ j = 1; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* print header if it has an entry (first). */ Err thinkerwim.openbsd.amsterdam 70 i+ if (++count == 1) { Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%s\n", titles[j]); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, " %-32.32s", "Name"); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, " %-16.16s", "Last commit date"); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, " %s\n", "Author"); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ ci = ris[i].ci; Err thinkerwim.openbsd.amsterdam 70 i+ s = git_reference_shorthand(ris[i].ref); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), s, 32, ' '); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, buf, strlen(buf)); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->author) Err thinkerwim.openbsd.amsterdam 70 i+ printtimeshort(fp, &(ci->author->when)); Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ fputs(" ", fp); Err thinkerwim.openbsd.amsterdam 70 i+ if (ci->author) { Err thinkerwim.openbsd.amsterdam 70 i+ utf8pad(buf, sizeof(buf), ci->author->name, 25, '\0'); Err thinkerwim.openbsd.amsterdam 70 i+ gmilink(fp, buf, strlen(buf)); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ /* table footer */ Err thinkerwim.openbsd.amsterdam 70 i+ if (count) Err thinkerwim.openbsd.amsterdam 70 i+ fputs("\n", fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < refcount; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ commitinfo_free(ris[i].ci); Err thinkerwim.openbsd.amsterdam 70 i+ git_reference_free(ris[i].ref); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ free(ris); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+void Err thinkerwim.openbsd.amsterdam 70 i+usage(char *argv0) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(stderr, "usage: %s [-b baseprefix] [-c cachefile | -l commits] " Err thinkerwim.openbsd.amsterdam 70 i+ "[-u baseurl] repodir\n", argv0); Err thinkerwim.openbsd.amsterdam 70 i+ exit(1); Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+int Err thinkerwim.openbsd.amsterdam 70 i+main(int argc, char *argv[]) Err thinkerwim.openbsd.amsterdam 70 i+{ Err thinkerwim.openbsd.amsterdam 70 i+ git_object *obj = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ const git_oid *head = NULL; Err thinkerwim.openbsd.amsterdam 70 i+ mode_t mask; Err thinkerwim.openbsd.amsterdam 70 i+ FILE *fp, *fpread; Err thinkerwim.openbsd.amsterdam 70 i+ char path[PATH_MAX], repodirabs[PATH_MAX + 1], *p; Err thinkerwim.openbsd.amsterdam 70 i+ char tmppath[64] = "cache.XXXXXXXXXXXX", buf[BUFSIZ]; Err thinkerwim.openbsd.amsterdam 70 i+ size_t n; Err thinkerwim.openbsd.amsterdam 70 i+ int i, fd; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ setlocale(LC_CTYPE, ""); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 1; i < argc; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (argv[i][0] != '-') { Err thinkerwim.openbsd.amsterdam 70 i+ if (repodir) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ repodir = argv[i]; Err thinkerwim.openbsd.amsterdam 70 i+ } else if (argv[i][1] == 'b') { Err thinkerwim.openbsd.amsterdam 70 i+ if (i + 1 >= argc) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ relpath = argv[++i]; Err thinkerwim.openbsd.amsterdam 70 i+ } else if (argv[i][1] == 'c') { Err thinkerwim.openbsd.amsterdam 70 i+ if (nlogcommits > 0 || i + 1 >= argc) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ cachefile = argv[++i]; Err thinkerwim.openbsd.amsterdam 70 i+ } else if (argv[i][1] == 'l') { Err thinkerwim.openbsd.amsterdam 70 i+ if (cachefile || i + 1 >= argc) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ errno = 0; Err thinkerwim.openbsd.amsterdam 70 i+ nlogcommits = strtoll(argv[++i], &p, 10); Err thinkerwim.openbsd.amsterdam 70 i+ if (argv[i][0] == '\0' || *p != '\0' || Err thinkerwim.openbsd.amsterdam 70 i+ nlogcommits <= 0 || errno) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ } else if (argv[i][1] == 'u') { Err thinkerwim.openbsd.amsterdam 70 i+ if (i + 1 >= argc) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ baseurl = argv[++i]; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (!repodir) Err thinkerwim.openbsd.amsterdam 70 i+ usage(argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!realpath(repodir, repodirabs)) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "realpath"); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* do not search outside the git repository: Err thinkerwim.openbsd.amsterdam 70 i+ GIT_CONFIG_LEVEL_APP is the highest level currently */ Err thinkerwim.openbsd.amsterdam 70 i+ git_libgit2_init(); Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 1; i <= GIT_CONFIG_LEVEL_APP; i++) Err thinkerwim.openbsd.amsterdam 70 i+ git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, i, ""); Err thinkerwim.openbsd.amsterdam 70 i+ /* do not require the git repository to be owned by the current user */ Err thinkerwim.openbsd.amsterdam 70 i+ git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+#ifdef __OpenBSD__ Err thinkerwim.openbsd.amsterdam 70 i+ if (unveil(repodir, "r") == -1) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "unveil: %s", repodir); Err thinkerwim.openbsd.amsterdam 70 i+ if (unveil(".", "rwc") == -1) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "unveil: ."); Err thinkerwim.openbsd.amsterdam 70 i+ if (cachefile && unveil(cachefile, "rwc") == -1) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "unveil: %s", cachefile); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (cachefile) { Err thinkerwim.openbsd.amsterdam 70 i+ if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "pledge"); Err thinkerwim.openbsd.amsterdam 70 i+ } else { Err thinkerwim.openbsd.amsterdam 70 i+ if (pledge("stdio rpath wpath cpath", NULL) == -1) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "pledge"); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+#endif Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (git_repository_open_ext(&repo, repodir, Err thinkerwim.openbsd.amsterdam 70 i+ GIT_REPOSITORY_OPEN_NO_SEARCH, NULL) < 0) { Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(stderr, "%s: cannot open repository\n", argv[0]); Err thinkerwim.openbsd.amsterdam 70 i+ return 1; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* find HEAD */ Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_revparse_single(&obj, repo, "HEAD")) Err thinkerwim.openbsd.amsterdam 70 i+ head = git_object_id(obj); Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* use directory name as name */ Err thinkerwim.openbsd.amsterdam 70 i+ if ((name = strrchr(repodirabs, '/'))) Err thinkerwim.openbsd.amsterdam 70 i+ name++; Err thinkerwim.openbsd.amsterdam 70 i+ else Err thinkerwim.openbsd.amsterdam 70 i+ name = ""; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* strip .git suffix */ Err thinkerwim.openbsd.amsterdam 70 i+ if (!(strippedname = strdup(name))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "strdup"); Err thinkerwim.openbsd.amsterdam 70 i+ if ((p = strrchr(strippedname, '.'))) Err thinkerwim.openbsd.amsterdam 70 i+ if (!strcmp(p, ".git")) Err thinkerwim.openbsd.amsterdam 70 i+ *p = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* read description or .git/description */ Err thinkerwim.openbsd.amsterdam 70 i+ joinpath(path, sizeof(path), repodir, "description"); Err thinkerwim.openbsd.amsterdam 70 i+ if (!(fpread = fopen(path, "r"))) { Err thinkerwim.openbsd.amsterdam 70 i+ joinpath(path, sizeof(path), repodir, ".git/description"); Err thinkerwim.openbsd.amsterdam 70 i+ fpread = fopen(path, "r"); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (fpread) { Err thinkerwim.openbsd.amsterdam 70 i+ if (!fgets(description, sizeof(description), fpread)) Err thinkerwim.openbsd.amsterdam 70 i+ description[0] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fpread, path, 'r'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fpread); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* read url or .git/url */ Err thinkerwim.openbsd.amsterdam 70 i+ joinpath(path, sizeof(path), repodir, "url"); Err thinkerwim.openbsd.amsterdam 70 i+ if (!(fpread = fopen(path, "r"))) { Err thinkerwim.openbsd.amsterdam 70 i+ joinpath(path, sizeof(path), repodir, ".git/url"); Err thinkerwim.openbsd.amsterdam 70 i+ fpread = fopen(path, "r"); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ if (fpread) { Err thinkerwim.openbsd.amsterdam 70 i+ if (!fgets(cloneurl, sizeof(cloneurl), fpread)) Err thinkerwim.openbsd.amsterdam 70 i+ cloneurl[0] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fpread, path, 'r'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fpread); Err thinkerwim.openbsd.amsterdam 70 i+ cloneurl[strcspn(cloneurl, "\n")] = '\0'; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* check LICENSE */ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < LEN(licensefiles) && !license; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_revparse_single(&obj, repo, licensefiles[i]) && Err thinkerwim.openbsd.amsterdam 70 i+ git_object_type(obj) == GIT_OBJ_BLOB) Err thinkerwim.openbsd.amsterdam 70 i+ license = licensefiles[i] + strlen("HEAD:"); Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* check README */ Err thinkerwim.openbsd.amsterdam 70 i+ for (i = 0; i < LEN(readmefiles) && !readme; i++) { Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_revparse_single(&obj, repo, readmefiles[i]) && Err thinkerwim.openbsd.amsterdam 70 i+ git_object_type(obj) == GIT_OBJ_BLOB) Err thinkerwim.openbsd.amsterdam 70 i+ readme = readmefiles[i] + strlen("HEAD:"); Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (!git_revparse_single(&obj, repo, "HEAD:.gitmodules") && Err thinkerwim.openbsd.amsterdam 70 i+ git_object_type(obj) == GIT_OBJ_BLOB) Err thinkerwim.openbsd.amsterdam 70 i+ submodules = ".gitmodules"; Err thinkerwim.openbsd.amsterdam 70 i+ git_object_free(obj); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* log for HEAD */ Err thinkerwim.openbsd.amsterdam 70 i+ fp = efopen("log.gmi", "w"); Err thinkerwim.openbsd.amsterdam 70 i+ mkdir("commit", S_IRWXU | S_IRWXG | S_IRWXO); Err thinkerwim.openbsd.amsterdam 70 i+ writeheader(fp, "Log"); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%-16.16s ", "Date"); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%-40.40s ", "Commit message"); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "%s\n", "Author"); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (cachefile && head) { Err thinkerwim.openbsd.amsterdam 70 i+ /* read from cache file (does not need to exist) */ Err thinkerwim.openbsd.amsterdam 70 i+ if ((rcachefp = fopen(cachefile, "r"))) { Err thinkerwim.openbsd.amsterdam 70 i+ if (!fgets(lastoidstr, sizeof(lastoidstr), rcachefp)) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "%s: no object id", cachefile); Err thinkerwim.openbsd.amsterdam 70 i+ if (git_oid_fromstr(&lastoid, lastoidstr)) Err thinkerwim.openbsd.amsterdam 70 i+ errx(1, "%s: invalid object id", cachefile); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* write log to (temporary) cache */ Err thinkerwim.openbsd.amsterdam 70 i+ if ((fd = mkstemp(tmppath)) == -1) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "mkstemp"); Err thinkerwim.openbsd.amsterdam 70 i+ if (!(wcachefp = fdopen(fd, "w"))) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "fdopen: '%s'", tmppath); Err thinkerwim.openbsd.amsterdam 70 i+ /* write last commit id (HEAD) */ Err thinkerwim.openbsd.amsterdam 70 i+ git_oid_tostr(buf, sizeof(buf), head); Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(wcachefp, "%s\n", buf); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ writelog(fp, head); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ if (rcachefp) { Err thinkerwim.openbsd.amsterdam 70 i+ /* append previous log to log.gmi and the new cache */ Err thinkerwim.openbsd.amsterdam 70 i+ while (!feof(rcachefp)) { Err thinkerwim.openbsd.amsterdam 70 i+ n = fread(buf, 1, sizeof(buf), rcachefp); Err thinkerwim.openbsd.amsterdam 70 i+ if (ferror(rcachefp)) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ if (fwrite(buf, 1, n, fp) != n || Err thinkerwim.openbsd.amsterdam 70 i+ fwrite(buf, 1, n, wcachefp) != n) Err thinkerwim.openbsd.amsterdam 70 i+ break; Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(rcachefp, cachefile, 'r'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(rcachefp); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(wcachefp, tmppath, 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(wcachefp); Err thinkerwim.openbsd.amsterdam 70 i+ } else { Err thinkerwim.openbsd.amsterdam 70 i+ if (head) Err thinkerwim.openbsd.amsterdam 70 i+ writelog(fp, head); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ fprintf(fp, "\n=> %s/atom.xml Atom Feed\n", relpath); Err thinkerwim.openbsd.amsterdam 70 i+ writefooter(fp); Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fp, "log.gmi", 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* files for HEAD */ Err thinkerwim.openbsd.amsterdam 70 i+ fp = efopen("files.gmi", "w"); Err thinkerwim.openbsd.amsterdam 70 i+ writeheader(fp, "Files"); Err thinkerwim.openbsd.amsterdam 70 i+ if (head) Err thinkerwim.openbsd.amsterdam 70 i+ writefiles(fp, head); Err thinkerwim.openbsd.amsterdam 70 i+ writefooter(fp); Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fp, "files.gmi", 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* summary page with branches and tags */ Err thinkerwim.openbsd.amsterdam 70 i+ fp = efopen("refs.gmi", "w"); Err thinkerwim.openbsd.amsterdam 70 i+ writeheader(fp, "Refs"); Err thinkerwim.openbsd.amsterdam 70 i+ writerefs(fp); Err thinkerwim.openbsd.amsterdam 70 i+ writefooter(fp); Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fp, "refs.gmi", 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* Atom feed */ Err thinkerwim.openbsd.amsterdam 70 i+ fp = efopen("atom.xml", "w"); Err thinkerwim.openbsd.amsterdam 70 i+ writeatom(fp, 1); Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fp, "atom.xml", 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* Atom feed for tags / releases */ Err thinkerwim.openbsd.amsterdam 70 i+ fp = efopen("tags.xml", "w"); Err thinkerwim.openbsd.amsterdam 70 i+ writeatom(fp, 0); Err thinkerwim.openbsd.amsterdam 70 i+ checkfileerror(fp, "tags.xml", 'w'); Err thinkerwim.openbsd.amsterdam 70 i+ fclose(fp); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* rename new cache file on success */ Err thinkerwim.openbsd.amsterdam 70 i+ if (cachefile && head) { Err thinkerwim.openbsd.amsterdam 70 i+ if (rename(tmppath, cachefile)) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "rename: '%s' to '%s'", tmppath, cachefile); Err thinkerwim.openbsd.amsterdam 70 i+ umask((mask = umask(0))); Err thinkerwim.openbsd.amsterdam 70 i+ if (chmod(cachefile, Err thinkerwim.openbsd.amsterdam 70 i+ (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) & ~mask)) Err thinkerwim.openbsd.amsterdam 70 i+ err(1, "chmod: '%s'", cachefile); Err thinkerwim.openbsd.amsterdam 70 i+ } Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ /* cleanup */ Err thinkerwim.openbsd.amsterdam 70 i+ git_repository_free(repo); Err thinkerwim.openbsd.amsterdam 70 i+ git_libgit2_shutdown(); Err thinkerwim.openbsd.amsterdam 70 i+ Err thinkerwim.openbsd.amsterdam 70 i+ return 0; Err thinkerwim.openbsd.amsterdam 70 i+} Err thinkerwim.openbsd.amsterdam 70 .