commit b721a32346868c17168130df3e6cfeb78eace68b
parent 7b8dc7899b2de2774be7c9c0bdac7d6d4d36bfa1
Author: Oscar Benedito <oscar@oscarbenedito.com>
Date:   Sat,  2 Apr 2022 23:36:17 +0200

Merge tag '1.1'

Diffstat:
MLICENSE | 2+-
MMakefile | 2+-
Mstagit-index.c | 24+++++++++++++++++++++---
Mstagit.c | 43+++++++++++++++++++++++++++++++++----------
Mstyle.css | 47+++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -1,6 +1,6 @@ MIT/X Consortium License -(c) 2015-2021 Hiltjo Posthuma <hiltjo@codemadness.org> +(c) 2015-2022 Hiltjo Posthuma <hiltjo@codemadness.org> (c) 2020-2021 Oscar Benedito <oscar@oscarbenedito.com> Permission is hereby granted, free of charge, to any person obtaining a diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ .POSIX: NAME = stagit -VERSION = 1.0 +VERSION = 1.1 # paths PREFIX = /usr/local diff --git a/stagit-index.c b/stagit-index.c @@ -17,6 +17,16 @@ static char *name = ""; static char owner[255]; static char category[255]; +/* 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); +} + void joinpath(char *buf, size_t bufsiz, const char *path, const char *path2) { @@ -39,8 +49,8 @@ percentencode(FILE *fp, const char *s, size_t len) for (i = 0; *s && i < len; s++, i++) { uc = *s; - /* NOTE: do not encode '/' for paths */ - if (uc < '/' || uc >= 127 || (uc >= ':' && uc <= '@') || + /* NOTE: do not encode '/' for paths or ",-." */ + if (uc < ',' || uc >= 127 || (uc >= ':' && uc <= '@') || uc == '[' || uc == ']') { putc('%', fp); putc(tab[(uc >> 4) & 0x0f], fp); @@ -175,7 +185,11 @@ main(int argc, char *argv[]) return 1; } + /* do not search outside the git repository: + GIT_CONFIG_LEVEL_APP is the highest level currently */ git_libgit2_init(); + for (i = 1; i <= GIT_CONFIG_LEVEL_APP; i++) + git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, i, ""); #ifdef __OpenBSD__ if (pledge("stdio rpath", NULL) == -1) @@ -226,6 +240,7 @@ main(int argc, char *argv[]) tmp = strlen(description); if (tmp > 0 && description[tmp-1] == '\n') description[tmp-1] = '\0'; + checkfileerror(fp, "description", 'r'); fclose(fp); } @@ -239,8 +254,9 @@ main(int argc, char *argv[]) if (fp) { if (!fgets(owner, sizeof(owner), fp)) owner[0] = '\0'; - owner[strcspn(owner, "\n")] = '\0'; + checkfileerror(fp, "owner", 'r'); fclose(fp); + owner[strcspn(owner, "\n")] = '\0'; } writelog(stdout); } @@ -250,5 +266,7 @@ main(int argc, char *argv[]) git_repository_free(repo); git_libgit2_shutdown(); + checkfileerror(stdout, "<stdout>", 'w'); + return ret; } diff --git a/stagit.c b/stagit.c @@ -82,6 +82,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); +} + void joinpath(char *buf, size_t bufsiz, const char *path, const char *path2) { @@ -372,8 +382,8 @@ percentencode(FILE *fp, const char *s, size_t len) for (i = 0; *s && i < len; s++, i++) { uc = *s; - /* NOTE: do not encode '/' for paths */ - if (uc < '/' || uc >= 127 || (uc >= ':' && uc <= '@') || + /* NOTE: do not encode '/' for paths or ",-." */ + if (uc < ',' || uc >= 127 || (uc >= ':' && uc <= '@') || uc == '[' || uc == ']') { putc('%', fp); putc(tab[(uc >> 4) & 0x0f], fp); @@ -835,6 +845,7 @@ writelog(FILE *fp, const git_oid *oid) printshowfile(fpfile, ci); fputs("</pre>\n", fpfile); writefooter(fpfile); + checkfileerror(fpfile, path, 'w'); fclose(fpfile); } err: @@ -1007,14 +1018,13 @@ writeblob(git_object *obj, const char *fpath, const char *rpath, const char *fil fprintf(fp, " (%zuB)", filesize); fprintf(fp, " - <a href=\"%s%s\">raw</a></p><hr/>", relpath, rpath); - if (git_blob_is_binary((git_blob *)obj)) { + if (git_blob_is_binary((git_blob *)obj)) fputs("<p>Binary file.</p>\n", fp); - } else { + else lc = writeblobhtml(fp, (git_blob *)obj); - if (ferror(fp)) - err(1, "fwrite"); - } + writefooter(fp); + checkfileerror(fp, fpath, 'w'); fclose(fp); relpath = oldrelpath; @@ -1321,7 +1331,11 @@ main(int argc, char *argv[]) if (!realpath(repodir, repodirabs)) err(1, "realpath"); + /* do not search outside the git repository: + GIT_CONFIG_LEVEL_APP is the highest level currently */ git_libgit2_init(); + for (i = 1; i <= GIT_CONFIG_LEVEL_APP; i++) + git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, i, ""); #ifdef __OpenBSD__ if (unveil(repodir, "r") == -1) @@ -1373,6 +1387,7 @@ main(int argc, char *argv[]) if (fpread) { if (!fgets(description, sizeof(description), fpread)) description[0] = '\0'; + checkfileerror(fpread, path, 'r'); fclose(fpread); } @@ -1385,8 +1400,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 CONTRIBUTING */ @@ -1478,13 +1494,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) @@ -1493,6 +1511,7 @@ main(int argc, char *argv[]) fputs("</tbody></table>", fp); writefooter(fp); + checkfileerror(fp, "log.html", 'w'); fclose(fp); /* files for HEAD */ @@ -1501,6 +1520,7 @@ main(int argc, char *argv[]) if (head) writefiles(fp, head); writefooter(fp); + checkfileerror(fp, "files.html", 'w'); fclose(fp); /* summary page with branches and tags */ @@ -1508,16 +1528,19 @@ main(int argc, char *argv[]) writeheader(fp, "Refs"); writerefs(fp); writefooter(fp); + checkfileerror(fp, "refs.html", '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 */ diff --git a/style.css b/style.css @@ -208,4 +208,51 @@ pre a.d:hover { #index .repo td:first-child { padding-left: 1.5em; + +@media (prefers-color-scheme: dark) { + body { + background-color: #000; + color: #bdbdbd; + } + hr { + border-color: #222; + } + a { + color: #56c8ff; + } + a:target { + background-color: #222; + } + .desc { + color: #aaa; + } + #blob a { + color: #555; + } + #blob a:target { + color: #eee; + } + #blob a:hover { + color: #56c8ff; + } + pre a.h { + color: #00cdcd; + } + .A, + span.i, + pre a.i { + color: #00cd00; + } + .D, + span.d, + pre a.d { + color: #cd0000; + } + #branches tr:hover td, + #tags tr:hover td, + #index tr:hover td, + #log tr:hover td, + #files tr:hover td { + background-color: #111; + } }