commit 3efa22d3fda2611902ccbadd3b53caf7569fc033
parent e951fe209d38932b1d7596fee7bb07c158ce4b75
Author: gearsix <gearsix@tuta.io>
Date: Sun, 5 Mar 2023 12:05:14 +0000
1.2 Squashed commit of the following:
commit 37f2b1165a709e27d810624359b14acb487028fe
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Aug 16 13:17:00 2022 +0200
prefix usage with the common prefix "usage: "
commit 02c00248d8134c69758557a78e3c632ac77ae687
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Aug 7 10:10:16 2022 +0200
bump version to 1.2
commit 174ea5d6fee240ec5df3afabfea1c5ce1319e3ea
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Jul 26 23:50:40 2022 +0200
Makefile: add workaround for distros still using older libgit2 versions
Noticed on Void Linux, Debian, etc.
commit 289045115432562f5fb4ddc721bd9008e8df4ad5
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri May 27 21:29:14 2022 +0200
Revert "remain compatible with slightly older libgit versions for now"
This reverts commit 70541c5e2cbdc141ba94e76899aba5f07047cecf.
Reported by Anton:
The last commit[1] is not correct as GIT_OPT_SET_OWNER_VALIDATION is not
a preprocessor directive but rather an enum. Causing the branch to never
be entered.
commit 70541c5e2cbdc141ba94e76899aba5f07047cecf
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue May 24 14:07:27 2022 +0200
remain compatible with slightly older libgit versions for now
commit 1357ad5181f80a99fe9c436af134e947ec7f4d29
Author: Anton Lindqvist <anton@basename.se>
Date: Tue May 24 10:58:37 2022 +0200
Allow git to run on an other user repository
Reported by Anton:
"Recent versions of libgit2 broke stagit for me due to the added opt-out
GIT_OPT_SET_OWNER_VALIDATION configuration knob. My repositories are owned by
root:vcs and I run stagit as another user which happens to be in vcs group but
not the owner of the repository. Disabling the validation makes stagit work as
expected again."
Some notes:
When using regular git it also provides a knob. This is due to a security
concern in some cases, which is not applicable to stagit.
git log somerepo
fatal: unsafe repository ('somerepo' is owned by someone else)
To add an exception for this directory, call:
git config --global --add safe.directory somerepo
See also / related:
- https://github.blog/2022-04-12-git-security-vulnerability-announced/
commit a8a5e9c3b37e133d26fe3ea5cd361281d7a56c85
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat Apr 2 17:35:47 2022 +0200
bump version to 1.1
commit d0e36eb6abce72c587dd53dcabc35120c3cf3a81
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat Mar 19 12:22:43 2022 +0100
improve stream read and write error handling
commit 7c419a8bac26e491206953bf2646ac634296b160
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Mar 15 16:58:32 2022 +0100
add dark mode support for the example stylesheet
commit 037d2c70531b879ced2f013e3d75e95c1b29553b
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Mon Jan 3 12:22:40 2022 +0100
bump LICENSE year
commit 4d19863b062ac469fe09dec014976ba3b8677fb0
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Mon Jan 3 12:21:12 2022 +0100
libgit2 config opts: set the search to an empty path
Otherwise this would search outside the unveiled paths and cause an unveil
violation.
Reported by Anton Lindqvist, thanks!
commit df2a31c67a7b6ca782121248f650526a4fbe08d2
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Dec 14 20:51:02 2021 +0100
do not percent-encode: ',' or '-' or '.' it looks ugly
commit cd5814fdedba47b03d42833019e6753b2a20b6ef
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Nov 30 18:13:20 2021 +0100
bump version to 1.0
commit 67e5e6c5e74117b478c150480c282a03543fe887
Author: Quentin Rameau <quinq@fifth.space>
Date: Tue Nov 16 18:17:45 2021 +0100
Print the number of remaining commits
commit 5f78d89d591ad26b902947288625b90528954372
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Nov 16 14:24:30 2021 +0100
ignore '\r' in writing the blob aswell
Follow-up on commit 295e4b8cb95114bb74b582c7332bc4c171f36dd3 which changed it
for diffs.
commit 6eeefd208743b0b2edbd7330dea36eea5b1099b7
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Nov 16 14:16:46 2021 +0100
percent encode characters in path names
Paths could contain characters like # (fragment), '?', control-characters, etc.
commit 961cf0f9d86e1e043d80398e4a71d218c28123a0
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Nov 16 11:44:23 2021 +0100
encode the name, it could contain XML entities
Like ", which would unquote the attribute value. Crazy but true.
commit 1b6a24c893866a604d9b7bc425f9b23706f39912
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue Aug 3 19:22:50 2021 +0200
man pages: add EXAMPLES section
commit 61be8f532818ac1c8d16e418d6e3124d10f82bd6
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat Jul 31 01:09:45 2021 +0200
small typo fixes and url -> URL
commit 57f84d0fd12d6466122dc8a2190e7e284f5668d7
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Thu May 27 12:41:43 2021 +0200
bump version to 0.9.6
commit 45394004a3455f76a2eef42d6f36c250f5e9a9ac
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue May 18 11:42:41 2021 +0200
man page: codemadness is the primary server. make logo brandless (not 2f30)
commit ddc581bd9088d0b3503606993eb8ed9dbeb44347
Author: Quentin Rameau <quinq@fifth.space>
Date: Tue May 18 10:38:54 2021 +0200
README: improve a bit the usage examples
commit c827ab1b1dee13e512f8ae24aa824879d547d0db
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Wed May 5 19:15:58 2021 +0200
do not simplify the history by first-parent
Reference:
https://libgit2.org/libgit2/#HEAD/group/revwalk/git_revwalk_simplify_first_parent
Noticed on merge commits on:
https://git.simple-cc.org/scc/
Reported by quinq, thanks!
commit 727e02be6c6aaafd929341963465bf6e1ff2947d
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Thu Mar 25 18:17:34 2021 +0100
tiny comment change
commit 295e4b8cb95114bb74b582c7332bc4c171f36dd3
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Thu Mar 25 18:13:13 2021 +0100
add function to print a single line, ignoring \r and \n
This can happen when there is no newline at end of file in the diff which is
served by libgit2 as:
"\n\ No newline at end of file\n".
commit 995f7d5c5d8e396b06e70b1497ac96df63ffec36
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri Mar 19 11:29:53 2021 +0100
add meta viewport on stagit-index too
Patch by Oscar Benedito, thanks!
commit f46405850133e43dcae95e0a41b74bcca7b10027
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Mar 14 16:23:58 2021 +0100
bump version to 0.9.5
commit c4d5fecc40e51ab4667315bd11dabd2023e357f3
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri Mar 5 12:47:08 2021 +0100
LICENSE: update
commit 5ced189f1993fc17ae683f0a542218db7be7267b
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri Mar 5 12:44:48 2021 +0100
change STAGIT_BASEURL to an -u option and also update the example script
commit 7968c0bc9c0172bd654e1f87d8194aef7fb69865
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri Mar 5 11:51:21 2021 +0100
add $STAGIT_BASEURL environment variable to make Atom links absolute
With feedback from adc, thanks!
commit d1c528fb5ad81c876f07a69e1b759764f69cb9de
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri Mar 5 11:50:16 2021 +0100
README: mention tags.xml feature
commit 722f8364601d2b6ee2439b42cd75750f6aac90ed
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat Jan 9 14:59:53 2021 +0100
micro-optimization: fputc (function) -> putc (macro/inline function)
commit 5044ddeea3c77fea97daa62d51593d73b0e08413
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri Jan 8 14:32:33 2021 +0100
LICENSE: bump year
commit e1c0aebde443979a524a944027b81f84f4323ff3
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat Nov 28 12:28:05 2020 +0100
fix warning with libgit2 v0.99+, remain compatible with older versions
git_blob_rawsize now returns with git_object_size_t (unsigned). This was
git_off_t (signed).
In my current version 1.1.0:
types.h:typedef uint64_t git_object_size_t;
v0.28.5:
https://libgit2.org/libgit2/#v0.28.5/group/blob/git_blob_rawsize
changed from v0.99 onwards:
https://libgit2.org/libgit2/#v0.99.0/group/blob/git_blob_rawsize
Fix: use size_t to remain compatible (with a possible warning in older
versions), since git_object_size_t is a new defined type.
This assumes size_t is atleast uint32_t / uint64_t size.
Adapted from a patch by Augustin Fabre <augustin@augfab.fr>, thanks!
commit 66df204c440de3b0cf3442d3a0c719016cdcf9c6
Author: Oscar Benedito <oscar@oscarbenedito.com>
Date: Mon Nov 16 23:24:32 2020 +0100
add abbreviated commit hash to submodule file
commit a63645a5ea4e60523c0024f69c627f586b601d82
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Nov 15 21:11:46 2020 +0100
add meta viewport for scaling on mobile
Patch by Augustin Fabre <augustin@augfab.fr>
commit ae41add24a87027343e3a6f7eea19f3902af4a12
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Nov 15 21:11:10 2020 +0100
style.css: improve contrast
https://webaim.org/resources/contrastchecker/?fcolor=555555&bcolor=FFFFFF
Patch by Augustin Fabre <augustin@augfab.fr> and adapted.
commit fc5ef41165df39d6def252e5230a63cc6839bfc1
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Nov 15 20:59:34 2020 +0100
use size_t to count lines
commit 4f60446c011b45e862540c97b684c62fd8dc3c60
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Nov 15 20:58:58 2020 +0100
avoid shadowed `name' global variable
by Augustin Fabre <augustin@augfab.fr>
commit 9467f347a2224ac95b96ef5c74d50a4e2aad5241
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Nov 15 20:58:41 2020 +0100
refs_cmp: remove unneeded cast
commit 3e7865f8f9ef87f622a7a94e7ae70355753ee66a
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Nov 15 20:58:02 2020 +0100
use LEN() macros for arrays
from Augustin Fabre <augustin@augfab.fr>
commit 75555cd99ee4d5df765f7dd6f0d09f2f925be725
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Mon Aug 17 16:09:33 2020 +0200
bump version to 0.9.4
commit 5334f3e0009bb7d5835c3bad60db507bfd146930
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Mon Aug 10 16:09:46 2020 +0200
fix a small memleak in writeatom()
non-tag references were not freed.
commit dc0709f6f4f7e256e27272cb0b8611715caf1f3b
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat Aug 8 20:01:05 2020 +0200
stagit-index: remove unveil support for argv
This can reach the unveil argument limits and it is not a good case for using
unveil.
commit 174a763058f9a90831ab5a2aeb1c9bfbecdabf48
Author: kst <nil@krj.st>
Date: Wed Aug 5 22:11:18 2020 +0000
fix submodule lookup in bare repos
git_submodule_lookup does not work without a working tree [1], so the
current approach fails to recognize any submodules in bare repos.
Instead, notice that
$ git ls-tree HEAD
lists any submodules as commit objects regardless of a working tree.
This is the only instance commit object is used in a tree, so we will
use this to check for submodules.
[1]: https://github.com/libgit2/libgit2/pull/4305/files
commit f05e6b0fcb3b874180970d06ebcde05fb5aea470
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Mon Jul 20 14:15:12 2020 +0200
regression: do not show unset or empty tags
commit d80a163acd47df2bd9ab145be6b249814aa9eceb
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Jul 19 16:41:10 2020 +0200
refactor get reference, add another feed for tags/releases
A separate Atom feed is helpful to ports maintainers to monitor new
tags/releases.
commit 693c06448972f049d74addbd4942365cd37d92e4
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun Jul 19 14:07:54 2020 +0200
sort branches and tags by time (descending)
In general version tags are done in chronological order, so this will have a
better sorting for tagged (versioned) releases.
Request from Caltlgin Stsodaat and others, thanks!
Diffstat:
M | LICENSE | | | 2 | +- |
M | Makefile | | | 6 | +++++- |
M | stagit-index.c | | | 45 | ++++++++++++++++++++++++++++++++++++++++++--- |
M | stagit.c | | | 111 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
M | style.css | | | 48 | ++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 179 insertions(+), 33 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>
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/Makefile b/Makefile
@@ -1,7 +1,7 @@
.POSIX:
NAME = stagit
-VERSION = 0.9.6
+VERSION = 1.2
# paths
PREFIX = /usr/local
@@ -16,6 +16,10 @@ STAGIT_CFLAGS = ${LIBGIT_INC} ${CFLAGS}
STAGIT_LDFLAGS = ${LIBGIT_LIB} ${LDFLAGS}
STAGIT_CPPFLAGS = -D_XOPEN_SOURCE=700 -D_DEFAULT_SOURCE -D_BSD_SOURCE
+# Uncomment to enable workaround for older libgit2 which don't support this
+# option. This workaround will be removed in the future *pinky promise*.
+#STAGIT_CFLAGS += -DGIT_OPT_SET_OWNER_VALIDATION=-1
+
SRC = \
stagit.c\
stagit-index.c
diff --git a/stagit-index.c b/stagit-index.c
@@ -20,6 +20,16 @@ static char *name = "gearsix";
static char *contact = "gearsix@tuta.io";
static char owner[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)
{
@@ -32,6 +42,28 @@ joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2);
}
+/* Percent-encode, see RFC3986 section 2.1. */
+void
+percentencode(FILE *fp, const char *s, size_t len)
+{
+ static char tab[] = "0123456789ABCDEF";
+ unsigned char uc;
+ size_t i;
+
+ for (i = 0; *s && i < len; s++, i++) {
+ uc = *s;
+ /* NOTE: do not encode '/' for paths or ",-." */
+ if (uc < ',' || uc >= 127 || (uc >= ':' && uc <= '@') ||
+ uc == '[' || uc == ']') {
+ putc('%', fp);
+ putc(tab[(uc >> 4) & 0x0f], fp);
+ putc(tab[uc & 0x0f], fp);
+ } else {
+ putc(uc, fp);
+ }
+ }
+}
+
/* Escape characters below as HTML 2.0 / XML 1.0. */
void
xmlencode(FILE *fp, const char *s, size_t len)
@@ -125,7 +157,7 @@ writelog(FILE *fp)
*p = '\0';
fputs("<tr><td><a href=\"", fp);
- xmlencode(fp, stripped_name, strlen(stripped_name));
+ percentencode(fp, stripped_name, strlen(stripped_name));
fputs("/log.html\">", fp);
xmlencode(fp, stripped_name, strlen(stripped_name));
fputs("</a></td><td>", fp);
@@ -227,11 +259,17 @@ main(int argc, char *argv[])
binary = argv[0];
if (argc < 2) {
- fprintf(stderr, "%s [repodir...]\n", argv[0]);
+ fprintf(stderr, "usage: %s [repodir...]\n", argv[0]);
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, "");
+ /* do not require the git repository to be owned by the current user */
+ git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0);
#ifdef __OpenBSD__
if (pledge("stdio rpath", NULL) == -1)
@@ -240,7 +278,6 @@ main(int argc, char *argv[])
writeheader(stdout);
- fputs("<details open><summary><b>orignal</b></summary>", stdout);
writebodyhead(stdout);
for (i = 1; i < argc; i++) {
ret = writebody(stdout, argv[i], 0);
@@ -265,5 +302,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
@@ -73,7 +73,7 @@ static char *licensefiles[] = { "HEAD:LICENSE", "HEAD:LICENSE.md", "HEAD:COPYING
static char *license;
static char *readmefiles[] = { "HEAD:README", "HEAD:README.md" };
static char *readme;
-static long long nlogcommits = -1; /* < 0 indicates not used */
+static long long nlogcommits = -1; /* -1 indicates not used */
/* cache */
static git_oid lastoid;
@@ -81,6 +81,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)
{
@@ -361,6 +371,28 @@ efopen(const char *filename, const char *flags)
return fp;
}
+/* Percent-encode, see RFC3986 section 2.1. */
+void
+percentencode(FILE *fp, const char *s, size_t len)
+{
+ static char tab[] = "0123456789ABCDEF";
+ unsigned char uc;
+ size_t i;
+
+ for (i = 0; *s && i < len; s++, i++) {
+ uc = *s;
+ /* NOTE: do not encode '/' for paths or ",-." */
+ if (uc < ',' || uc >= 127 || (uc >= ':' && uc <= '@') ||
+ uc == '[' || uc == ']') {
+ putc('%', fp);
+ putc(tab[(uc >> 4) & 0x0f], fp);
+ putc(tab[uc & 0x0f], fp);
+ } else {
+ putc(uc, fp);
+ }
+ }
+}
+
/* Escape characters below as HTML 2.0 / XML 1.0. */
void
xmlencode(FILE *fp, const char *s, size_t len)
@@ -490,6 +522,7 @@ writeheader(FILE *fp, const char *title)
fputs("</head>\n<body>\n<table><tr><td id=\"logo\">", fp);
fprintf(fp, "<a href=\"../%s\"><img src=\"%slogo.png\" alt=\"\" width=\"50\" height=\"50\" /></a>",
relpath, rootpath);
+
fputs("</td><td><h1>", fp);
xmlencode(fp, strippedname, strlen(strippedname));
fputs("</h1><span class=\"desc\">", fp);
@@ -498,7 +531,7 @@ writeheader(FILE *fp, const char *title)
fputs("</span></td></tr>", fp);
if (cloneurl[0]) {
fputs("<tr class=\"url\"><td></td><td>git clone <a href=\"", fp);
- xmlencode(fp, cloneurl, strlen(cloneurl));
+ xmlencode(fp, cloneurl, strlen(cloneurl)); /* not percent-encoded */
fputs("\">", fp);
xmlencode(fp, cloneurl, strlen(cloneurl));
fputs("</a></td></tr>", fp);
@@ -542,14 +575,15 @@ writeblobhtml(FILE *fp, const git_blob *blob)
continue;
n++;
fprintf(fp, nfmt, n, n, n);
- xmlencode(fp, &s[prev], i - prev + 1);
+ xmlencodeline(fp, &s[prev], i - prev + 1);
+ putc('\n', fp);
prev = i + 1;
}
/* trailing data */
if ((len - prev) > 0) {
n++;
fprintf(fp, nfmt, n, n, n);
- xmlencode(fp, &s[prev], len - prev);
+ xmlencodeline(fp, &s[prev], len - prev);
}
}
@@ -572,7 +606,7 @@ printcommit(FILE *fp, struct commitinfo *ci)
fputs("<b>Author:</b> ", fp);
xmlencode(fp, ci->author->name, strlen(ci->author->name));
fputs(" <<a href=\"mailto:", fp);
- xmlencode(fp, ci->author->email, strlen(ci->author->email));
+ xmlencode(fp, ci->author->email, strlen(ci->author->email)); /* not percent-encoded */
fputs("\">", fp);
xmlencode(fp, ci->author->email, strlen(ci->author->email));
fputs("</a>>\n<b>Date:</b> ", fp);
@@ -667,11 +701,11 @@ printshowfile(FILE *fp, struct commitinfo *ci)
patch = ci->deltas[i]->patch;
delta = git_patch_get_delta(patch);
fprintf(fp, "<b>diff --git a/<a id=\"h%zu\" href=\"%sfile/", i, relpath);
- xmlencode(fp, delta->old_file.path, strlen(delta->old_file.path));
+ percentencode(fp, delta->old_file.path, strlen(delta->old_file.path));
fputs(".html\">", fp);
xmlencode(fp, delta->old_file.path, strlen(delta->old_file.path));
fprintf(fp, "</a> b/<a href=\"%sfile/", relpath);
- xmlencode(fp, delta->new_file.path, strlen(delta->new_file.path));
+ percentencode(fp, delta->new_file.path, strlen(delta->new_file.path));
fprintf(fp, ".html\">");
xmlencode(fp, delta->new_file.path, strlen(delta->new_file.path));
fprintf(fp, "</a></b>\n");
@@ -743,6 +777,7 @@ writelog(FILE *fp, const git_oid *oid)
git_oid id;
char path[PATH_MAX], oidstr[GIT_OID_HEXSZ + 1];
FILE *fpfile;
+ size_t remcommits = 0;
int r;
git_revwalk_new(&w, repo);
@@ -762,8 +797,11 @@ writelog(FILE *fp, const git_oid *oid)
/* optimization: if there are no log lines to write and
the commit file already exists: skip the diffstat */
- if (!nlogcommits && !r)
- continue;
+ if (!nlogcommits) {
+ remcommits++;
+ if (!r)
+ continue;
+ }
if (!(ci = commitinfo_getbyoid(&id)))
break;
@@ -771,15 +809,10 @@ writelog(FILE *fp, const git_oid *oid)
if (commitinfo_getstats(ci) == -1)
goto err;
- if (nlogcommits < 0) {
- writelogline(fp, ci);
- } else if (nlogcommits > 0) {
+ if (nlogcommits != 0) {
writelogline(fp, ci);
- nlogcommits--;
- if (!nlogcommits && ci->parentoid[0])
- fputs("<tr><td></td><td colspan=\"5\">"
- "More commits remaining [...]</td>"
- "</tr>\n", fp);
+ if (nlogcommits > 0)
+ nlogcommits--;
}
if (cachefile)
@@ -794,6 +827,7 @@ writelog(FILE *fp, const git_oid *oid)
printshowfile(fpfile, ci);
fputs("</pre>\n", fpfile);
writefooter(fpfile);
+ checkfileerror(fpfile, path, 'w');
fclose(fpfile);
}
err:
@@ -801,6 +835,12 @@ err:
}
git_revwalk_free(w);
+ if (nlogcommits == 0 && remcommits != 0) {
+ fprintf(fp, "<tr><td></td><td colspan=\"5\">"
+ "%zu more commits remaining, fetch the repository"
+ "</td></tr>\n", remcommits);
+ }
+
relpath = "";
return 0;
@@ -938,14 +978,13 @@ writeblob(git_object *obj, const char *fpath, const char *filename, size_t files
fprintf(fp, " (%zuB)", filesize);
fputs("</p><hr/>", fp);
- 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 = "";
@@ -1040,7 +1079,7 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
fputs("<tr><td>", fp);
fputs(filemode(git_tree_entry_filemode(entry)), fp);
fprintf(fp, "</td><td><a href=\"%s", relpath);
- xmlencode(fp, filepath, strlen(filepath));
+ percentencode(fp, filepath, strlen(filepath));
fputs("\">", fp);
xmlencode(fp, entrypath, strlen(entrypath));
fputs("</a></td><td class=\"num\" align=\"right\">", fp);
@@ -1155,7 +1194,7 @@ writeindex(FILE *fp)
void
usage(char *argv0)
{
- fprintf(stderr, "%s [-c cachefile | -l commits] "
+ fprintf(stderr, "usage: %s [-c cachefile | -l commits] "
"[-u baseurl] repodir\n", argv0);
exit(1);
}
@@ -1202,7 +1241,13 @@ 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, "");
+ /* do not require the git repository to be owned by the current user */
+ git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0);
#ifdef __OpenBSD__
if (unveil(repodir, "r") == -1)
@@ -1254,6 +1299,7 @@ main(int argc, char *argv[])
if (fpread) {
if (!fgets(description, sizeof(description), fpread))
description[0] = '\0';
+ checkfileerror(fpread, path, 'r');
fclose(fpread);
}
@@ -1277,8 +1323,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 */
@@ -1338,13 +1385,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)
@@ -1353,6 +1402,7 @@ main(int argc, char *argv[])
fputs("</tbody></table>", fp);
writefooter(fp);
+ checkfileerror(fp, "log.html", 'w');
fclose(fp);
/* files for HEAD */
@@ -1361,6 +1411,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 */
@@ -1368,21 +1419,25 @@ 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);
- /* index page */
+ /* index redirect page */
fp = efopen("index.html", "w");
writeindex(fp);
+ checkfileerror(fp, "index.html", 'w');
fclose(fp);
/* rename new cache file on success */
diff --git a/style.css b/style.css
@@ -104,3 +104,51 @@ pre a.i:hover,
pre a.d:hover {
text-decoration: none;
}
+
+@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;
+ }
+}