stagit-gopher

[fork] gopher git frontend
Log | Files | Refs | README | LICENSE

commit 32abbb35ebc5d73d7767c9f4a209ea94ae1f2e23
parent 4dcaa7f51f39d3cba5b7aaa91ef97d9921c15308
Author: hhvn <dev@hhvn.uk>
Date:   Sun, 15 May 2022 21:12:53 +0100

Merge some stuff from git://codemadness.org/stagit-gopher

Diffstat:
MLICENSE | 2+-
MREADME | 16+++++++++++-----
Mmakefile | 2+-
Mstagit-gopher-index.c | 13+++++++++++++
Mstagit-gopher.c | 35+++++++++++++++++++++++++++--------
5 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -2,7 +2,7 @@ MIT/X Consortium License (c) 2015-2022 Hiltjo Posthuma <hiltjo@codemadness.org> (c) 2015-2016 Dimitris Papastamos <sin@2f30.org> -(c) 2020-2021 Hayden Hamilton <dev@hhvn.uk> +(c) 2020-2022 hhvn <dev@hhvn.uk> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/README b/README @@ -13,12 +13,17 @@ Usage Make files per repository: - $ mkdir -p gphdir && cd gphdir - $ stagit-gopher path-to-repo + $ mkdir -p gphroot/gphrepo1 && cd gphroot/gphrepo1 + $ stagit-gopher path/to/gitrepo1 + repeat for other repositories + $ ... Make index file for repositories: - $ stagit-gopher-index repodir1 repodir2 repodir3 > index.gph + $ cd gphroot + $ stagit-gopher-index path/to/gitrepo1 \ + path/to/gitrepo2 \ + path/to/gitrepo3 > index.gph Build and install @@ -66,7 +71,7 @@ make make install -Set clone url for a directory of repos +Set clone URL for a directory of repos -------------------------------------- #!/bin/sh cd "$dir" @@ -131,7 +136,8 @@ Features - Show references: local branches and tags. - Detect README and LICENSE file from HEAD and link it as a page. - Detect submodules (.gitmodules file) from HEAD and link it as a page. -- Atom feed log (atom.xml). +- Atom feed of the commit log (atom.xml). +- Atom feed of the tags/refs (tags.xml). - Make index page for multiple repositories with stagit-gopher-index. - After generating the pages (relatively slow) serving the files is very fast, simple and requires little resources (because the content is static), only diff --git a/makefile b/makefile @@ -1,7 +1,7 @@ .POSIX: NAME = stagit-gopher -VERSION = 0.9.4 +VERSION = 1.1 # paths PREFIX = /usr/local diff --git a/stagit-gopher-index.c b/stagit-gopher-index.c @@ -20,6 +20,16 @@ static const char *relpath = ""; static char description[255] = "Repositories"; static char *name = ""; +/* Handle read or write errors for a FILE * stream */ +void +checkfileerror(FILE *fp, const char *name, int mode) +{ + if (mode == 'r' && ferror(fp)) + errx(1, "read error: %s", name); + else if (mode == 'w' && (fflush(fp) || ferror(fp))) + errx(1, "write error: %s", name); +} + /* Format `len' columns of characters. If string is shorter pad the rest * with characters `pad`. */ int @@ -288,6 +298,7 @@ main(int argc, char *argv[]) description[strcspn(description, "\t\r\n")] = '\0'; else description[0] = '\0'; + checkfileerror(fp, "description", 'r'); fclose(fp); } @@ -302,5 +313,7 @@ main(int argc, char *argv[]) git_repository_free(repo); git_libgit2_shutdown(); + checkfileerror(stdout, "<stdout>", 'w'); + return ret; } diff --git a/stagit-gopher.c b/stagit-gopher.c @@ -83,6 +83,16 @@ static char lastoidstr[GIT_OID_HEXSZ + 2]; /* id + newline + NUL byte */ static FILE *rcachefp, *wcachefp; static const char *cachefile; +/* Handle read or write errors for a FILE * stream */ +void +checkfileerror(FILE *fp, const char *name, int mode) +{ + if (mode == 'r' && ferror(fp)) + errx(1, "read error: %s", name); + else if (mode == 'w' && (fflush(fp) || ferror(fp))) + errx(1, "write error: %s", name); +} + /* Format `len' columns of characters. If string is shorter pad the rest * with characters `pad`. */ int @@ -876,6 +886,7 @@ writelog(FILE *fp, const git_oid *oid) writeheader(fpfile, ci->summary); printshowfile(fpfile, ci); writefooter(fpfile); + checkfileerror(fpfile, path, 'w'); fclose(fpfile); } err: @@ -1015,14 +1026,13 @@ writeblob(git_object *obj, const char *fpath, const char *filename, size_t files fprintf(fp, " (%zuB)\n", filesize); fputs("---\n", fp); - if (git_blob_is_binary((git_blob *)obj)) { + if (git_blob_is_binary((git_blob *)obj)) fputs("Binary file.\n", fp); - } else { + else lc = writeblobgph(fp, (git_blob *)obj); - if (ferror(fp)) - err(1, "fwrite"); - } + writefooter(fp); + checkfileerror(fp, fpath, 'w'); fclose(fp); return lc; @@ -1334,6 +1344,7 @@ main(int argc, char *argv[]) if (fpread) { if (!fgets(description, sizeof(description), fpread)) description[0] = '\0'; + checkfileerror(fpread, path, 'r'); fclose(fpread); } @@ -1346,8 +1357,9 @@ main(int argc, char *argv[]) if (fpread) { if (!fgets(cloneurl, sizeof(cloneurl), fpread)) cloneurl[0] = '\0'; - cloneurl[strcspn(cloneurl, "\n")] = '\0'; + checkfileerror(fpread, path, 'r'); fclose(fpread); + cloneurl[strcspn(cloneurl, "\n")] = '\0'; } /* check LICENSE */ @@ -1405,13 +1417,15 @@ main(int argc, char *argv[]) while (!feof(rcachefp)) { n = fread(buf, 1, sizeof(buf), rcachefp); if (ferror(rcachefp)) - err(1, "fread"); + break; if (fwrite(buf, 1, n, fp) != n || fwrite(buf, 1, n, wcachefp) != n) - err(1, "fwrite"); + break; } + checkfileerror(rcachefp, cachefile, 'r'); fclose(rcachefp); } + checkfileerror(wcachefp, tmppath, 'w'); fclose(wcachefp); } else { if (head) @@ -1421,6 +1435,7 @@ main(int argc, char *argv[]) fprintf(fp, "[0|Atom feed|%s/atom.xml|server|port]\n", relpath); fprintf(fp, "[0|Atom feed (tags)|%s/tags.xml|server|port]\n", relpath); writefooter(fp); + checkfileerror(fp, "log.gph", 'w'); fclose(fp); /* files for HEAD */ @@ -1429,6 +1444,7 @@ main(int argc, char *argv[]) if (head) writefiles(fp, head); writefooter(fp); + checkfileerror(fp, "files.gph", 'w'); fclose(fp); /* summary page with branches and tags */ @@ -1436,16 +1452,19 @@ main(int argc, char *argv[]) writeheader(fp, "Refs"); writerefs(fp); writefooter(fp); + checkfileerror(fp, "refs.gph", 'w'); fclose(fp); /* Atom feed */ fp = efopen("atom.xml", "w"); writeatom(fp, 1); + checkfileerror(fp, "atom.xml", 'w'); fclose(fp); /* Atom feed for tags / releases */ fp = efopen("tags.xml", "w"); writeatom(fp, 0); + checkfileerror(fp, "tags.xml", 'w'); fclose(fp); /* rename new cache file on success */