stagit

static git page generator  https://git.ce9e.org
git clone https://git.ce9e.org/stagit.git

commit
7be949c4d6a99242c78e0b5d51cd030ae39992e8
parent
62879d957130b0e9c5851d2818d6f0d9cc28195a
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2025-12-05 06:20
lint

Diffstat

M src/stagit.c.in 354 ++++++++++++++++++++++++++++---------------------------------
M src/strlcpy.c 17 ++++++++---------

2 files changed, 173 insertions, 198 deletions


diff --git a/src/stagit.c.in b/src/stagit.c.in

@@ -59,92 +59,88 @@ static char *reponame = "";
   59    59 static char description[255];
   60    60 static char url[255];
   61    61 
   62    -1 void
   63    -1 joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
   64    -1 {
   -1    62 void joinpath(char *buf, size_t bufsiz, const char *path, const char *path2) {
   65    63 	int r;
   66    64 
   67    65 	r = snprintf(buf, bufsiz, "%s%s%s",
   68    66 		path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2);
   69    -1 	if (r < 0 || (size_t)r >= bufsiz)
   -1    67 	if (r < 0 || (size_t)r >= bufsiz) {
   70    68 		errx(1, "path truncated: '%s%s%s'",
   71    69 			path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2);
   -1    70 	}
   72    71 }
   73    72 
   74    -1 int
   75    -1 mkdirp(const char *path)
   76    -1 {
   -1    73 int mkdirp(const char *path) {
   77    74 	char tmp[PATH_MAX], *p;
   78    75 
   79    -1 	if (strlcpy(tmp, path, sizeof(tmp)) >= sizeof(tmp))
   -1    76 	if (strlcpy(tmp, path, sizeof(tmp)) >= sizeof(tmp)) {
   80    77 		errx(1, "path truncated: '%s'", path);
   -1    78 	}
   81    79 	for (p = tmp + (tmp[0] == '/'); *p; p++) {
   82    -1 		if (*p != '/')
   -1    80 		if (*p != '/') {
   83    81 			continue;
   -1    82 		}
   84    83 		*p = '\0';
   85    -1 		if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST)
   -1    84 		if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) {
   86    85 			return -1;
   -1    86 		}
   87    87 		*p = '/';
   88    88 	}
   89    -1 	if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST)
   -1    89 	if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) {
   90    90 		return -1;
   -1    91 	}
   91    92 	return 0;
   92    93 }
   93    94 
   94    -1 FILE *
   95    -1 efopen(const char *name, const char *flags)
   96    -1 {
   -1    95 FILE *efopen(const char *name, const char *flags) {
   97    96 	FILE *fp;
   98    -1 
   99    -1 	if (!(fp = fopen(name, flags)))
  100    -1 		err(1, "fopen: '%s'", name);
  101    -1 
   -1    97 	if (!(fp = fopen(name, flags))) {
   -1    98 		err(EXIT_FAILURE, "fopen: '%s'", name);
   -1    99 	}
  102   100 	return fp;
  103   101 }
  104   102 
  105    -1 void
  106    -1 deltainfo_free(struct deltainfo *di)
  107    -1 {
  108    -1 	if (!di)
   -1   103 void deltainfo_free(struct deltainfo *di) {
   -1   104 	if (!di) {
  109   105 		return;
   -1   106 	}
  110   107 	git_patch_free(di->patch);
  111   108 	memset(di, 0, sizeof(*di));
  112   109 	free(di);
  113   110 }
  114   111 
  115    -1 void
  116    -1 commitstats_free(struct commitstats *cs)
  117    -1 {
   -1   112 void commitstats_free(struct commitstats *cs) {
  118   113 	size_t i;
  119    -1 	if (!cs)
   -1   114 	if (!cs) {
  120   115 		return;
  121    -1 	for (i = 0; i < cs->ndeltas; i++)
   -1   116 	}
   -1   117 	for (i = 0; i < cs->ndeltas; i++) {
  122   118 		deltainfo_free(cs->deltas[i]);
   -1   119 	}
  123   120 	free(cs->deltas);
  124   121 	memset(cs, 0, sizeof(*cs));
  125   122 	free(cs);
  126   123 }
  127   124 
  128    -1 void
  129    -1 commitinfo_free(struct commitinfo *ci)
  130    -1 {
  131    -1 	if (!ci)
   -1   125 void commitinfo_free(struct commitinfo *ci) {
   -1   126 	if (!ci) {
  132   127 		return;
   -1   128 	}
  133   129 	git_commit_free(ci->commit);
  134   130 	memset(ci, 0, sizeof(*ci));
  135   131 	free(ci);
  136   132 }
  137   133 
  138    -1 struct commitinfo *
  139    -1 commitinfo_getbyoid(const git_oid *id)
  140    -1 {
   -1   134 struct commitinfo *commitinfo_getbyoid(const git_oid *id) {
  141   135 	struct commitinfo *ci;
  142   136 
  143    -1 	if (!(ci = calloc(1, sizeof(struct commitinfo))))
   -1   137 	if (!(ci = calloc(1, sizeof(struct commitinfo)))) {
  144   138 		err(1, "calloc");
   -1   139 	}
  145   140 
  146    -1 	if (git_commit_lookup(&(ci->commit), repo, id))
   -1   141 	if (git_commit_lookup(&(ci->commit), repo, id)) {
  147   142 		goto err;
   -1   143 	}
  148   144 
  149   145 	git_oid_tostr(ci->oid, sizeof(ci->oid), git_commit_id(ci->commit));
  150   146 	git_oid_tostr(ci->parentoid, sizeof(ci->parentoid), git_commit_parent_id(ci->commit, 0));
@@ -161,17 +157,16 @@ err:
  161   157 	return NULL;
  162   158 }
  163   159 
  164    -1 int
  165    -1 git_commit_get_diff(git_diff **diff, git_commit *commit)
  166    -1 {
   -1   160 int git_commit_get_diff(git_diff **diff, git_commit *commit) {
  167   161 	git_commit *parent;
  168   162 	git_tree *commit_tree;
  169   163 	git_tree *parent_tree;
  170   164 	git_diff_options opts;
  171   165 	git_diff_find_options fopts;
  172   166 
  173    -1 	if (git_tree_lookup(&commit_tree, repo, git_commit_tree_id(commit)))
   -1   167 	if (git_tree_lookup(&commit_tree, repo, git_commit_tree_id(commit))) {
  174   168 		goto err;
   -1   169 	}
  175   170 	if (git_commit_parent(&parent, commit, 0)) {
  176   171 		parent = NULL;
  177   172 	}
@@ -179,18 +174,21 @@ git_commit_get_diff(git_diff **diff, git_commit *commit)
  179   174 		parent_tree = NULL;
  180   175 	}
  181   176 
  182    -1 	if (git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION))
   -1   177 	if (git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION)) {
  183   178 		goto err;
   -1   179 	}
  184   180 	opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH | GIT_DIFF_INCLUDE_TYPECHANGE;
  185    -1 	if (git_diff_tree_to_tree(diff, repo, parent_tree, commit_tree, &opts))
   -1   181 	if (git_diff_tree_to_tree(diff, repo, parent_tree, commit_tree, &opts)) {
  186   182 		goto err;
   -1   183 	}
  187   184 
  188   185 	git_tree_free(commit_tree);
  189   186 	git_tree_free(parent_tree);
  190   187 	git_commit_free(parent);
  191   188 
  192    -1 	if (git_diff_find_init_options(&fopts, GIT_DIFF_FIND_OPTIONS_VERSION))
   -1   189 	if (git_diff_find_init_options(&fopts, GIT_DIFF_FIND_OPTIONS_VERSION)) {
  193   190 		goto err;
   -1   191 	}
  194   192 	fopts.flags |= GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
  195   193 	if (git_diff_find_similar(*diff, &fopts)) {
  196   194 		git_diff_free(*diff);
@@ -206,9 +204,7 @@ err:
  206   204 	return -1;
  207   205 }
  208   206 
  209    -1 struct commitstats *
  210    -1 commitinfo_getstats(git_diff *diff)
  211    -1 {
   -1   207 struct commitstats *commitinfo_getstats(git_diff *diff) {
  212   208 	struct commitstats *cs;
  213   209 	struct deltainfo *di;
  214   210 	const git_diff_delta *delta;
@@ -217,35 +213,42 @@ commitinfo_getstats(git_diff *diff)
  217   213 	git_patch *patch = NULL;
  218   214 	size_t ndeltas, nhunks, nhunklines, i, j, k;
  219   215 
  220    -1 	if (!(cs = calloc(1, sizeof(struct commitstats))))
   -1   216 	if (!(cs = calloc(1, sizeof(struct commitstats)))) {
  221   217 		err(1, "calloc");
   -1   218 	}
  222   219 
  223   220 	ndeltas = git_diff_num_deltas(diff);
  224    -1 	if (ndeltas && !(cs->deltas = calloc(ndeltas, sizeof(struct deltainfo *))))
   -1   221 	if (ndeltas && !(cs->deltas = calloc(ndeltas, sizeof(struct deltainfo *)))) {
  225   222 		err(1, "calloc");
   -1   223 	}
  226   224 
  227   225 	for (i = 0; i < ndeltas; i++) {
  228    -1 		if (git_patch_from_diff(&patch, diff, i))
   -1   226 		if (git_patch_from_diff(&patch, diff, i)) {
  229   227 			break;
   -1   228 		}
  230   229 
  231    -1 		if (!(di = calloc(1, sizeof(struct deltainfo))))
   -1   230 		if (!(di = calloc(1, sizeof(struct deltainfo)))) {
  232   231 			err(1, "calloc");
   -1   232 		}
  233   233 		di->patch = patch;
  234   234 		cs->deltas[i] = di;
  235   235 
  236   236 		delta = git_patch_get_delta(patch);
  237   237 
  238   238 		/* skip stats for binary data */
  239    -1 		if (delta->flags & GIT_DIFF_FLAG_BINARY)
   -1   239 		if (delta->flags & GIT_DIFF_FLAG_BINARY) {
  240   240 			continue;
   -1   241 		}
  241   242 
  242   243 		nhunks = git_patch_num_hunks(patch);
  243   244 		for (j = 0; j < nhunks; j++) {
  244    -1 			if (git_patch_get_hunk(&hunk, &nhunklines, patch, j))
   -1   245 			if (git_patch_get_hunk(&hunk, &nhunklines, patch, j)) {
  245   246 				break;
   -1   247 			}
  246   248 			for (k = 0; ; k++) {
  247    -1 				if (git_patch_get_line_in_hunk(&line, patch, j, k))
   -1   249 				if (git_patch_get_line_in_hunk(&line, patch, j, k)) {
  248   250 					break;
   -1   251 				}
  249   252 				if (line->old_lineno == -1) {
  250   253 					di->addcount++;
  251   254 					cs->addcount++;
@@ -261,9 +264,7 @@ commitinfo_getstats(git_diff *diff)
  261   264 	return cs;
  262   265 }
  263   266 
  264    -1 void
  265    -1 xmlencode(FILE *fp, const char *s, size_t len)
  266    -1 {
   -1   267 void xmlencode(FILE *fp, const char *s, size_t len) {
  267   268 	size_t i;
  268   269 
  269   270 	for (i = 0; *s && i < len; s++, i++) {
@@ -278,37 +279,33 @@ xmlencode(FILE *fp, const char *s, size_t len)
  278   279 	}
  279   280 }
  280   281 
  281    -1 void
  282    -1 printtimez(FILE *fp, const git_time *intime)
  283    -1 {
   -1   282 void printtimez(FILE *fp, const git_time *intime) {
  284   283 	struct tm *intm;
  285   284 	time_t t;
  286   285 	char out[32];
  287   286 
  288   287 	t = (time_t)intime->time;
  289    -1 	if (!(intm = gmtime(&t)))
   -1   288 	if (!(intm = gmtime(&t))) {
  290   289 		return;
   -1   290 	}
  291   291 	strftime(out, sizeof(out), "%Y-%m-%dT%H:%M:%SZ", intm);
  292   292 	fputs(out, fp);
  293   293 }
  294   294 
  295    -1 void
  296    -1 printtimeshort(FILE *fp, const git_time *intime)
  297    -1 {
   -1   295 void printtimeshort(FILE *fp, const git_time *intime) {
  298   296 	struct tm *intm;
  299   297 	time_t t;
  300   298 	char out[32];
  301   299 
  302   300 	t = (time_t)intime->time;
  303    -1 	if (!(intm = gmtime(&t)))
   -1   301 	if (!(intm = gmtime(&t))) {
  304   302 		return;
   -1   303 	}
  305   304 	strftime(out, sizeof(out), "%Y-%m-%d %H:%M", intm);
  306   305 	fputs(out, fp);
  307   306 }
  308   307 
  309    -1 void
  310    -1 write_header(FILE *fp, const char *title, const char *relpath)
  311    -1 {
   -1   308 void write_header(FILE *fp, const char *title, const char *relpath) {
  312   309 	T("<!DOCTYPE html>\n");
  313   310 	T("<html>\n");
  314   311 	T("<head>\n");
@@ -322,22 +319,26 @@ write_header(FILE *fp, const char *title, const char *relpath)
  322   319 		T(" - {title}");
  323   320 	}
  324   321 	T("</title>\n");
  325    -1 	if (favicon[0])
   -1   322 	if (favicon[0]) {
  326   323 		T("<link rel=\"icon\" type=\"image/png\" href=\"{favicon:%s}\" />\n");
   -1   324 	}
  327   325 	T("<link rel=\"alternate\" type=\"application/atom+xml\" title=\"{reponame} Feed\" href=\"{relpath:%s}atom.xml\" />\n");
  328    -1 	if (stylesheet[0])
   -1   326 	if (stylesheet[0]) {
  329   327 		T("<link rel=\"stylesheet\" type=\"text/css\" href=\"{stylesheet:%s}\" />\n");
   -1   328 	}
  330   329 	T("</head>\n");
  331   330 	T("<body>\n");
  332   331 	T("<header>\n");
  333    -1 	if (logo[0])
   -1   332 	if (logo[0]) {
  334   333 		T("<a href=\"{relpath:%s}..\"><img src=\"{logo:%s}\" alt=\"\" width=\"32\" height=\"32\" /></a>");
   -1   334 	}
  335   335 	T("<div>\n");
  336   336 	T("<h1>{reponame}</h1>");
  337   337 	if (description[0] || url[0]) {
  338   338 		T("<div class=\"desc\">{description}");
  339    -1 		if (description[0] && url[0])
   -1   339 		if (description[0] && url[0]) {
  340   340 			T("&nbsp; ");
   -1   341 		}
  341   342 		if (url[0]) {
  342   343 			T("<a href=\"{url}\">{url}</a>");
  343   344 		}
@@ -356,15 +357,11 @@ write_header(FILE *fp, const char *title, const char *relpath)
  356   357 	T("<main id=\"content\">\n");
  357   358 }
  358   359 
  359    -1 void
  360    -1 write_footer(FILE *fp)
  361    -1 {
   -1   360 void write_footer(FILE *fp) {
  362   361 	T("</main>\n</body>\n</html>\n");
  363   362 }
  364   363 
  365    -1 void
  366    -1 write_readme(FILE *fp, const git_blob *blob)
  367    -1 {
   -1   364 void write_readme(FILE *fp, const git_blob *blob) {
  368   365 	const void *raw = git_blob_rawcontent(blob);
  369   366 	git_off_t len = git_blob_rawsize(blob);
  370   367 
@@ -381,9 +378,7 @@ write_readme(FILE *fp, const git_blob *blob)
  381   378 #endif
  382   379 }
  383   380 
  384    -1 void
  385    -1 write_commit_statline(FILE *fp, struct deltainfo *di, size_t i)
  386    -1 {
   -1   381 void write_commit_statline(FILE *fp, struct deltainfo *di, size_t i) {
  387   382 	char c;
  388   383 	int total;
  389   384 	size_t j;
@@ -413,19 +408,19 @@ write_commit_statline(FILE *fp, struct deltainfo *di, size_t i)
  413   408 	total = di->addcount + di->delcount;
  414   409 	T("<td class=\"num\">{total:%i}</td>\n");
  415   410 	T("<td><span class=\"i\">");
  416    -1 	for (j = 0; j < di->addcount && j * total < di->addcount * 60; j++)
   -1   411 	for (j = 0; j < di->addcount && j * total < di->addcount * 60; j++) {
  417   412 		fputc('+', fp);
   -1   413 	}
  418   414 	T("</span><span class=\"d\">");
  419    -1 	for (j = 0; j < di->delcount && j * total < di->delcount * 60; j++)
   -1   415 	for (j = 0; j < di->delcount && j * total < di->delcount * 60; j++) {
  420   416 		fputc('-', fp);
   -1   417 	}
  421   418 	T("</span></td>");
  422   419 
  423   420 	T("</tr>\n");
  424   421 }
  425   422 
  426    -1 void
  427    -1 write_commit_file(FILE *fp, struct deltainfo *di, size_t i)
  428    -1 {
   -1   423 void write_commit_file(FILE *fp, struct deltainfo *di, size_t i) {
  429   424 	const git_diff_delta *delta;
  430   425 	const git_diff_hunk *hunk;
  431   426 	const git_diff_line *line;
@@ -446,19 +441,22 @@ write_commit_file(FILE *fp, struct deltainfo *di, size_t i)
  446   441 		return;
  447   442 	}
  448   443 
  449    -1 	if (nhunks == 0)
   -1   444 	if (nhunks == 0) {
  450   445 		return;
   -1   446 	}
  451   447 
  452   448 	T("<pre class=\"diff\">\n");
  453   449 	for (j = 0; j < nhunks; j++) {
  454    -1 		if (git_patch_get_hunk(&hunk, &nhunklines, di->patch, j))
   -1   450 		if (git_patch_get_hunk(&hunk, &nhunklines, di->patch, j)) {
  455   451 			break;
   -1   452 		}
  456   453 		T("<a href=\"#h{i:%zu}-{j:%zu}\" id=\"h{i:%zu}-{j:%zu}\" class=\"h\">");
  457   454 		T("{hunk->header:hunk->header_len - 1}");
  458   455 		T("</a>\n");
  459   456 		for (k = 0; k < nhunklines; k++) {
  460    -1 			if (git_patch_get_line_in_hunk(&line, di->patch, j, k))
   -1   457 			if (git_patch_get_line_in_hunk(&line, di->patch, j, k)) {
  461   458 				break;
   -1   459 			}
  462   460 			tag = line->old_lineno == -1 ? "ins" : line->new_lineno == -1 ? "del" : "span";
  463   461 			T("<{tag:%s} class=\"line\" id=\"h{i:%zu}-{j:%zu}-{k:%zu}\">");
  464   462 			T("<a href=\"#h{i:%zu}-{j:%zu}-{k:%zu}\" tabindex=\"-1\">{line->old_lineno:%5i} {line->new_lineno:%5i}</a> ");
@@ -469,16 +467,15 @@ write_commit_file(FILE *fp, struct deltainfo *di, size_t i)
  469   467 	T("</pre>\n");
  470   468 }
  471   469 
  472    -1 void
  473    -1 write_commit(FILE *fp, struct commitinfo *ci, git_diff *diff)
  474    -1 {
   -1   470 void write_commit(FILE *fp, struct commitinfo *ci, git_diff *diff) {
  475   471 	size_t i;
  476   472 	struct commitstats *cs = commitinfo_getstats(diff);
  477   473 
  478   474 	T("<dl>\n");
  479   475 	T("<dt>commit</dt><dd><a href=\"\">{ci->oid:%s}</a></dd>\n");
  480    -1 	if (ci->parentoid[0])
   -1   476 	if (ci->parentoid[0]) {
  481   477 		T("<dt>parent</dt><dd><a href=\"{ci->parentoid:%s}.html\">{ci->parentoid:%s}</a></dd>\n");
   -1   478 	}
  482   479 	if (ci->author) {
  483   480 		T("<dt>Author</dt><dd>{ci->author->name} ");
  484   481 		T("&lt;<a href=\"mailto:{ci->author->email}\">{ci->author->email}</a>&gt;");
@@ -491,14 +488,15 @@ write_commit(FILE *fp, struct commitinfo *ci, git_diff *diff)
  491   488 		T("<pre>{ci->msg}</pre>\n");
  492   489 	}
  493   490 
  494    -1 	if (!cs->deltas)
   -1   491 	if (!cs->deltas) {
  495   492 		goto err;
   -1   493 	}
  496   494 
  497   495 	if (
  498    -1 			cs->ndeltas > 1000 ||
  499    -1 			cs->addcount > 100000 ||
  500    -1 			cs->delcount > 100000
  501    -1 		) {
   -1   496 			cs->ndeltas > 1000
   -1   497 			|| cs->addcount > 100000
   -1   498 			|| cs->delcount > 100000
   -1   499 	) {
  502   500 		T("Diff is too large, output suppressed.\n");
  503   501 		goto err;
  504   502 	}
@@ -522,17 +520,13 @@ err:
  522   520 	commitstats_free(cs);
  523   521 }
  524   522 
  525    -1 void
  526    -1 write_diff(FILE *fp, git_diff *diff)
  527    -1 {
   -1   523 void write_diff(FILE *fp, git_diff *diff) {
  528   524 	git_buf buf = GIT_BUF_INIT;
  529   525 	git_diff_to_buf(&buf, diff, GIT_DIFF_FORMAT_PATCH);
  530   526 	fprintf(fp, "%s", buf.ptr);
  531   527 }
  532   528 
  533    -1 void
  534    -1 write_log_header(FILE *fp)
  535    -1 {
   -1   529 void write_log_header(FILE *fp) {
  536   530 	T("<table id=\"log\">\n");
  537   531 	T("<thead>\n");
  538   532 	T("<tr><th>Date</th><th class=\"text\">Commit message</th><th>Author</th></tr>\n");
@@ -540,9 +534,7 @@ write_log_header(FILE *fp)
  540   534 	T("<tbody>\n");
  541   535 }
  542   536 
  543    -1 void
  544    -1 write_log_line(FILE *fp, struct commitinfo *ci)
  545    -1 {
   -1   537 void write_log_line(FILE *fp, struct commitinfo *ci) {
  546   538 	T("<tr><td>");
  547   539 	if (ci->author) {
  548   540 		T("<a href=\"commit/{ci->oid:%s}.html\">");
@@ -550,32 +542,28 @@ write_log_line(FILE *fp, struct commitinfo *ci)
  550   542 		T("</a>");
  551   543 	}
  552   544 	T("</td><td class=\"text\">");
  553    -1 	if (ci->summary)
   -1   545 	if (ci->summary) {
  554   546 		T("{ci->summary}");
   -1   547 	}
  555   548 	T("</td><td>");
  556    -1 	if (ci->author)
   -1   549 	if (ci->author) {
  557   550 		T("{ci->author->name}");
   -1   551 	}
  558   552 	T("</td></tr>\n");
  559   553 }
  560   554 
  561    -1 void
  562    -1 write_log_footer(FILE *fp)
  563    -1 {
   -1   555 void write_log_footer(FILE *fp) {
  564   556 	T("</tbody>\n</table>\n");
  565   557 }
  566   558 
  567    -1 void
  568    -1 write_atom_header(FILE *fp)
  569    -1 {
   -1   559 void write_atom_header(FILE *fp) {
  570   560 	T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
  571   561 	T("<feed xmlns=\"http://www.w3.org/2005/Atom\">\n");
  572   562 	T("<title>{reponame}, branch HEAD</title>\n");
  573   563 	T("<subtitle>{description}</subtitle>\n");
  574   564 }
  575   565 
  576    -1 void
  577    -1 write_atom_entry(FILE *fp, struct commitinfo *ci)
  578    -1 {
   -1   566 void write_atom_entry(FILE *fp, struct commitinfo *ci) {
  579   567 	T("<entry>\n");
  580   568 
  581   569 	T("<id>{ci->oid:%s}</id>\n");
@@ -607,28 +595,27 @@ write_atom_entry(FILE *fp, struct commitinfo *ci)
  607   595 	T("</entry>\n");
  608   596 }
  609   597 
  610    -1 void
  611    -1 write_atom_footer(FILE *fp)
  612    -1 {
   -1   598 void write_atom_footer(FILE *fp) {
  613   599 	T("</feed>\n");
  614   600 }
  615   601 
  616    -1 void
  617    -1 copy_blob(git_object *obj, const char *fpath)
  618    -1 {
   -1   602 void copy_blob(git_object *obj, const char *fpath) {
  619   603 	char tmp[PATH_MAX] = "";
  620   604 	char *d;
  621   605 	git_off_t len;
  622   606 	const void *raw;
  623   607 	FILE *fp;
  624   608 
  625    -1 	if (strlcpy(tmp, fpath, sizeof(tmp)) >= sizeof(tmp))
   -1   609 	if (strlcpy(tmp, fpath, sizeof(tmp)) >= sizeof(tmp)) {
  626   610 		errx(1, "path truncated: '%s'", fpath);
   -1   611 	}
  627   612 
  628    -1 	if (!(d = dirname(tmp)))
  629    -1 		err(1, "dirname");
  630    -1 	if (mkdirp(d))
   -1   613 	if (!(d = dirname(tmp))) {
   -1   614 		err(EXIT_FAILURE, "dirname");
   -1   615 	}
   -1   616 	if (mkdirp(d)) {
  631   617 		return;
   -1   618 	}
  632   619 
  633   620 	fp = efopen(fpath, "w");
  634   621 	len = git_blob_rawsize((git_blob *)obj);
@@ -637,9 +624,7 @@ copy_blob(git_object *obj, const char *fpath)
  637   624 	fclose(fp);
  638   625 }
  639   626 
  640    -1 void
  641    -1 write_files_header(FILE *fp)
  642    -1 {
   -1   627 void write_files_header(FILE *fp) {
  643   628 	T("<table id=\"files\">\n");
  644   629 	T("<thead>\n");
  645   630 	T("<tr><th>Name</th><th class=\"num\">Size</th></tr>\n");
@@ -647,28 +632,22 @@ write_files_header(FILE *fp)
  647   632 	T("<tbody>\n");
  648   633 }
  649   634 
  650    -1 void
  651    -1 write_files_line(FILE *fp, char *entrypath, char *filepath, uintmax_t size)
  652    -1 {
   -1   635 void write_files_line(FILE *fp, char *entrypath, char *filepath, uintmax_t size) {
  653   636 	T("<tr><td><a href=\"{filepath}\">{entrypath}</a></td><td class=\"num\">{size:%ju}B</td></tr>\n");
  654   637 }
  655   638 
  656    -1 void
  657    -1 write_files_footer(FILE *fp)
  658    -1 {
   -1   639 void write_files_footer(FILE *fp) {
  659   640 	T("</tbody>\n</table>\n");
  660   641 }
  661   642 
  662    -1 void
  663    -1 process_readme(FILE *fp)
  664    -1 {
   -1   643 void process_readme(FILE *fp) {
  665   644 	int i;
  666   645 	git_object *obj = NULL;
  667   646 
  668   647 	for (i = 0; i < sizeof(readmefiles) / sizeof(*readmefiles); i++) {
  669   648 		if (
  670    -1 			!git_revparse_single(&obj, repo, readmefiles[i]) &&
  671    -1 			git_object_type(obj) == GIT_OBJ_BLOB
   -1   649 			!git_revparse_single(&obj, repo, readmefiles[i])
   -1   650 			&& git_object_type(obj) == GIT_OBJ_BLOB
  672   651 		) {
  673   652 			write_readme(fp, (git_blob *)obj);
  674   653 			break;
@@ -677,9 +656,7 @@ process_readme(FILE *fp)
  677   656 	}
  678   657 }
  679   658 
  680    -1 int
  681    -1 _process_files(FILE *fp, git_tree *tree, const char *path)
  682    -1 {
   -1   659 int _process_files(FILE *fp, git_tree *tree, const char *path) {
  683   660 	const git_tree_entry *entry = NULL;
  684   661 	git_object *obj = NULL;
  685   662 	git_off_t filesize;
@@ -691,8 +668,8 @@ _process_files(FILE *fp, git_tree *tree, const char *path)
  691   668 	count = git_tree_entrycount(tree);
  692   669 	for (i = 0; i < count; i++) {
  693   670 		if (
  694    -1 			!(entry = git_tree_entry_byindex(tree, i)) ||
  695    -1 			!(entryname = git_tree_entry_name(entry))
   -1   671 			!(entry = git_tree_entry_byindex(tree, i))
   -1   672 			|| !(entryname = git_tree_entry_name(entry))
  696   673 		)
  697   674 			return -1;
  698   675 		joinpath(entrypath, sizeof(entrypath), path, entryname);
@@ -706,8 +683,9 @@ _process_files(FILE *fp, git_tree *tree, const char *path)
  706   683 				/* NOTE: recurses */
  707   684 				ret = _process_files(fp, (git_tree *)obj, entrypath);
  708   685 				git_object_free(obj);
  709    -1 				if (ret)
   -1   686 				if (ret) {
  710   687 					return ret;
   -1   688 				}
  711   689 				continue;
  712   690 			default:
  713   691 				git_object_free(obj);
@@ -726,9 +704,7 @@ _process_files(FILE *fp, git_tree *tree, const char *path)
  726   704 	return 0;
  727   705 }
  728   706 
  729    -1 int
  730    -1 process_files(FILE *fp)
  731    -1 {
   -1   707 int process_files(FILE *fp) {
  732   708 	git_tree *tree = NULL;
  733   709 	git_commit *commit = NULL;
  734   710 	git_object *obj = NULL;
@@ -736,16 +712,18 @@ process_files(FILE *fp)
  736   712 	int ret = -1;
  737   713 
  738   714 	/* find HEAD */
  739    -1 	if (!git_revparse_single(&obj, repo, "HEAD"))
   -1   715 	if (!git_revparse_single(&obj, repo, "HEAD")) {
  740   716 		head = git_object_id(obj);
   -1   717 	}
  741   718 	git_object_free(obj);
  742   719 	if (!head) {
  743   720 		fprintf(stderr, "no HEAD found\n");
  744   721 		return 1;
  745   722 	}
  746   723 
  747    -1 	if (!git_commit_lookup(&commit, repo, head) && !git_commit_tree(&tree, commit))
   -1   724 	if (!git_commit_lookup(&commit, repo, head) && !git_commit_tree(&tree, commit)) {
  748   725 		ret = _process_files(fp, tree, "");
   -1   726 	}
  749   727 
  750   728 	git_commit_free(commit);
  751   729 	git_tree_free(tree);
@@ -753,9 +731,7 @@ process_files(FILE *fp)
  753   731 	return ret;
  754   732 }
  755   733 
  756    -1 void
  757    -1 process_commits(FILE *fp_log, FILE *fp_atom, size_t m)
  758    -1 {
   -1   734 void process_commits(FILE *fp_log, FILE *fp_atom, size_t m) {
  759   735 	struct commitinfo *ci;
  760   736 	git_revwalk *w = NULL;
  761   737 	git_oid id;
@@ -771,11 +747,12 @@ process_commits(FILE *fp_log, FILE *fp_atom, size_t m)
  771   747 			fputs("<tr><td colspan=\"3\">More commits remaining&hellip;</td></tr>\n", fp_log);
  772   748 			break;
  773   749 		}
  774    -1 		if (!(ci = commitinfo_getbyoid(&id)))
   -1   750 		if (!(ci = commitinfo_getbyoid(&id))) {
  775   751 			break;
  776    -1 
  777    -1 		if (git_commit_get_diff(&diff, ci->commit))
   -1   752 		}
   -1   753 		if (git_commit_get_diff(&diff, ci->commit)) {
  778   754 			break;
   -1   755 		}
  779   756 
  780   757 		write_log_line(fp_log, ci);
  781   758 		write_atom_entry(fp_atom, ci);
@@ -806,79 +783,78 @@ process_commits(FILE *fp_log, FILE *fp_atom, size_t m)
  806   783 	git_revwalk_free(w);
  807   784 }
  808   785 
  809    -1 void
  810    -1 usage(char *argv0)
  811    -1 {
   -1   786 void usage(char *argv0) {
  812   787 	fprintf(stderr, "%s repodir\n", argv0);
  813   788 	exit(1);
  814   789 }
  815   790 
  816    -1 void
  817    -1 get_repo_name(const char *path)
  818    -1 {
   -1   791 void get_repo_name(const char *path) {
  819   792 	char *p;
  820   793 
  821    -1 	if (!realpath(repodir, repodirabs))
  822    -1 		err(1, "realpath");
   -1   794 	if (!realpath(repodir, repodirabs)) {
   -1   795 		err(EXIT_FAILURE, "realpath");
   -1   796 	}
  823   797 
  824   798 	if (!(reponame = strrchr(repodirabs, '/'))) {
  825   799 		fprintf(stderr, "could not use directory name\n");
  826   800 		return;
  827   801 	}
  828   802 	reponame++;
  829    -1 	if ((p = strrchr(reponame, '.')))
  830    -1 		if (!strcmp(p, ".git"))
   -1   803 	if ((p = strrchr(reponame, '.'))) {
   -1   804 		if (!strcmp(p, ".git")) {
  831   805 			*p = '\0';
   -1   806 		}
   -1   807 	}
  832   808 }
  833   809 
  834    -1 void
  835    -1 get_metadata(void)
  836    -1 {
   -1   810 void get_metadata(void) {
  837   811 	char path[PATH_MAX];
  838   812 	FILE *fpread;
  839   813 
  840   814 	joinpath(path, sizeof(path), repodir, "description");
  841   815 	if ((fpread = fopen(path, "r"))) {
  842    -1 		if (!fgets(description, sizeof(description), fpread))
   -1   816 		if (!fgets(description, sizeof(description), fpread)) {
  843   817 			description[0] = '\0';
   -1   818 		}
  844   819 		fclose(fpread);
  845   820 	}
  846   821 
  847   822 	joinpath(path, sizeof(path), repodir, "url");
  848   823 	if ((fpread = fopen(path, "r"))) {
  849    -1 		if (!fgets(url, sizeof(url), fpread))
   -1   824 		if (!fgets(url, sizeof(url), fpread)) {
  850   825 			url[0] = '\0';
   -1   826 		}
  851   827 		fclose(fpread);
  852   828 	}
  853   829 }
  854   830 
  855    -1 int
  856    -1 main(int argc, char *argv[])
  857    -1 {
   -1   831 int main(int argc, char *argv[]) {
  858   832 	static FILE *fp_index, *fp_log, *fp_atom;
  859   833 
  860    -1 	if (argc == 2)
   -1   834 	if (argc == 2) {
  861   835 		repodir = argv[1];
  862    -1 	else
   -1   836 	} else {
  863   837 		usage(argv[0]);
   -1   838 	}
  864   839 
  865   840 	git_libgit2_init();
  866   841 
  867   842 #ifdef __OpenBSD__
  868    -1 	if (unveil(repodir, "r") == -1)
  869    -1 		err(1, "unveil: %s", repodir);
  870    -1 	if (unveil(".", "rwc") == -1)
  871    -1 		err(1, "unveil: .");
   -1   843 	if (unveil(repodir, "r") == -1) {
   -1   844 		err(EXIT_FAILURE, "unveil: %s", repodir);
   -1   845 	}
   -1   846 	if (unveil(".", "rwc") == -1) {
   -1   847 		err(EXIT_FAILURE, "unveil: .");
   -1   848 	}
  872   849 
  873    -1 	if (pledge("stdio rpath wpath cpath", NULL) == -1)
  874    -1 		err(1, "pledge");
   -1   850 	if (pledge("stdio rpath wpath cpath", NULL) == -1) {
   -1   851 		err(EXIT_FAILURE, "pledge");
   -1   852 	}
  875   853 #endif
  876   854 
  877    -1 	if (git_repository_open_ext(
  878    -1 		&repo, repodir, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL
  879    -1 	) < 0) {
   -1   855 	if (git_repository_open_ext(&repo, repodir, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL) < 0) {
  880   856 		fprintf(stderr, "%s: cannot open repository\n", argv[0]);
  881    -1 		return 1;
   -1   857 		return EXIT_FAILURE;
  882   858 	}
  883   859 
  884   860 	get_repo_name(repodir);
@@ -915,5 +891,5 @@ main(int argc, char *argv[])
  915   891 	git_repository_free(repo);
  916   892 	git_libgit2_shutdown();
  917   893 
  918    -1 	return 0;
   -1   894 	return EXIT_SUCCESS;
  919   895 }

diff --git a/src/strlcpy.c b/src/strlcpy.c

@@ -24,27 +24,26 @@
   24    24  * chars will be copied.  Always NUL terminates (unless dsize == 0).
   25    25  * Returns strlen(src); if retval >= dsize, truncation occurred.
   26    26  */
   27    -1 size_t
   28    -1 strlcpy(char *dst, const char *src, size_t dsize)
   29    -1 {
   -1    27 size_t strlcpy(char *dst, const char *src, size_t dsize) {
   30    28 	const char *osrc = src;
   31    29 	size_t nleft = dsize;
   32    30 
   33    31 	/* Copy as many bytes as will fit. */
   34    32 	if (nleft != 0) {
   35    33 		while (--nleft != 0) {
   36    -1 			if ((*dst++ = *src++) == '\0')
   -1    34 			if ((*dst++ = *src++) == '\0') {
   37    35 				break;
   -1    36 			}
   38    37 		}
   39    38 	}
   40    39 
   41    40 	/* Not enough room in dst, add NUL and traverse rest of src. */
   42    41 	if (nleft == 0) {
   43    -1 		if (dsize != 0)
   44    -1 			*dst = '\0';		/* NUL-terminate dst */
   45    -1 		while (*src++)
   46    -1 			;
   -1    42 		if (dsize != 0) {
   -1    43 			*dst = '\0';  /* NUL-terminate dst */
   -1    44 		}
   -1    45 		while (*src++) {}
   47    46 	}
   48    47 
   49    -1 	return(src - osrc - 1);	/* count does not include NUL */
   -1    48 	return(src - osrc - 1);  /* count does not include NUL */
   50    49 }