Commit Diff


commit - 1c2f8577ce1acf4b16371f61fe9a4cc2e53b7869
commit + 161663e7ebf5aa10caf7b4048f013d5e45db5fe3
blob - 041e66818e8cd0f84a1d59fe60801962e8f611b4
blob + b578672d782d8d87cbe3a28d2d4097c83da33166
--- gotwebd/config.c
+++ gotwebd/config.c
@@ -35,6 +35,7 @@
 #include <errno.h>
 
 #include "got_opentemp.h"
+#include "got_reference.h"
 
 #include "got_compat.h"
 
blob - a2a198890cf78469d183c3223cdce1833f9e6be9
blob + a86029ab9bdf600070dee0af486d4a0f7f5e7e5a
--- gotwebd/fcgi.c
+++ gotwebd/fcgi.c
@@ -35,6 +35,7 @@
 #include <unistd.h>
 
 #include "got_error.h"
+#include "got_reference.h"
 
 #include "proc.h"
 #include "gotwebd.h"
blob - eadd7523213b9ccbb04392c1f1ce4381ff218fc6
blob + 647e83fe8caab03ac1c04ff0f1433a7d6da154ce
--- gotwebd/gotweb.c
+++ gotwebd/gotweb.c
@@ -84,7 +84,7 @@ static const struct got_error *gotweb_parse_querystrin
     char *);
 static const struct got_error *gotweb_assign_querystring(struct querystring **,
     char *, char *);
-static const struct got_error *gotweb_render_index(struct request *);
+static int gotweb_render_index(struct template *);
 static const struct got_error *gotweb_init_repo_dir(struct repo_dir **,
     const char *);
 static const struct got_error *gotweb_load_got_path(struct request *c,
@@ -143,17 +143,12 @@ void
 gotweb_process_request(struct request *c)
 {
 	const struct got_error *error = NULL, *error2 = NULL;
-	struct got_blob_object *blob = NULL;
 	struct server *srv = NULL;
 	struct querystring *qs = NULL;
 	struct repo_dir *repo_dir = NULL;
-	struct got_reflist_head refs;
-	FILE *fp = NULL;
 	uint8_t err[] = "gotwebd experienced an error: ";
-	int r, html = 0, fd = -1;
+	int r, html = 0;
 
-	TAILQ_INIT(&refs);
-
 	/* init the transport */
 	error = gotweb_init_transport(&c->t);
 	if (error) {
@@ -216,7 +211,8 @@ gotweb_process_request(struct request *c)
 		if (error)
 			goto done;
 
-		error2 = got_open_blob_for_output(&blob, &fd, &binary, c);
+		error2 = got_open_blob_for_output(&c->t->blob, &c->t->fd,
+		    &binary, c);
 		if (error2)
 			goto render;
 
@@ -229,12 +225,12 @@ gotweb_process_request(struct request *c)
 			goto done;
 
 		for (;;) {
-			error = got_object_blob_read_block(&len, blob);
+			error = got_object_blob_read_block(&len, c->t->blob);
 			if (error)
 				goto done;
 			if (len == 0)
 				break;
-			buf = got_object_blob_get_read_buf(blob);
+			buf = got_object_blob_get_read_buf(c->t->blob);
 			if (fcgi_gen_binary_response(c, buf, len) == -1)
 				goto done;
 		}
@@ -258,7 +254,8 @@ gotweb_process_request(struct request *c)
 		if (error)
 			goto done;
 
-		error2 = got_open_blob_for_output(&blob, &fd, &binary, c);
+		error2 = got_open_blob_for_output(&c->t->blob, &c->t->fd,
+		    &binary, c);
 		if (error2)
 			goto render;
 		if (binary) {
@@ -287,9 +284,6 @@ render:
 	if (gotweb_reply(c, 200, "text/html", NULL) == -1)
 		goto done;
 	html = 1;
-
-	if (gotweb_render_header(c->tp) == -1)
-		goto err;
 
 	if (error2) {
 		error = error2;
@@ -303,15 +297,15 @@ render:
 			log_warnx("%s: %s", __func__, error->msg);
 			goto err;
 		}
-		if (gotweb_render_blame(c->tp) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_blame) == -1)
 			goto done;
 		break;
 	case BLOB:
-		if (gotweb_render_blob(c->tp, blob) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_blob) == -1)
 			goto err;
 		break;
 	case BRIEFS:
-		if (gotweb_render_briefs(c->tp) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_briefs) == -1)
 			goto err;
 		break;
 	case COMMITS:
@@ -320,7 +314,7 @@ render:
 			log_warnx("%s: %s", __func__, error->msg);
 			goto err;
 		}
-		if (gotweb_render_commits(c->tp) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_commits) == -1)
 			goto err;
 		break;
 	case DIFF:
@@ -329,23 +323,28 @@ render:
 			log_warnx("%s: %s", __func__, error->msg);
 			goto err;
 		}
-		error = got_open_diff_for_output(&fp, &fd, c);
+		error = got_open_diff_for_output(&c->t->fp, &c->t->fd, c);
 		if (error) {
 			log_warnx("%s: %s", __func__, error->msg);
 			goto err;
 		}
-		if (gotweb_render_diff(c->tp, fp) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_diff) == -1)
 			goto err;
 		break;
 	case INDEX:
-		error = gotweb_render_index(c);
-		if (error) {
-			log_warnx("%s: %s", __func__, error->msg);
+		c->t->nrepos = scandir(srv->repos_path, &c->t->repos, NULL,
+		    alphasort);
+		if (c->t->nrepos == -1) {
+			c->t->repos = NULL;
+			error = got_error_from_errno2("scandir",
+			    srv->repos_path);
 			goto err;
 		}
+		if (gotweb_render_page(c->tp, gotweb_render_index) == -1)
+			goto err;
 		break;
 	case SUMMARY:
-		error = got_ref_list(&refs, c->t->repo, "refs/heads",
+		error = got_ref_list(&c->t->refs, c->t->repo, "refs/heads",
 		    got_ref_cmp_by_name, NULL);
 		if (error) {
 			log_warnx("%s: got_ref_list: %s", __func__,
@@ -360,7 +359,7 @@ render:
 			goto err;
 		}
 		qs->action = SUMMARY;
-		if (gotweb_render_summary(c->tp, &refs) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_summary) == -1)
 			goto done;
 		break;
 	case TAG:
@@ -374,7 +373,7 @@ render:
 			    "bad commit id");
 			goto err;
 		}
-		if (gotweb_render_tag(c->tp) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_tag) == -1)
 			goto done;
 		break;
 	case TAGS:
@@ -383,7 +382,7 @@ render:
 			log_warnx("%s: %s", __func__, error->msg);
 			goto err;
 		}
-		if (gotweb_render_tags(c->tp) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_tags) == -1)
 			goto done;
 		break;
 	case TREE:
@@ -392,7 +391,7 @@ render:
 			log_warnx("%s: %s", __func__, error->msg);
 			goto err;
 		}
-		if (gotweb_render_tree(c->tp) == -1)
+		if (gotweb_render_page(c->tp, gotweb_render_tree) == -1)
 			goto err;
 		break;
 	case ERR:
@@ -420,21 +419,7 @@ err:
 	if (html && fcgi_printf(c, "</div>\n") == -1)
 		return;
 done:
-	if (blob)
-		got_object_blob_close(blob);
-	if (fp) {
-		error = got_gotweb_flushfile(fp, fd);
-		if (error)
-			log_warnx("%s: got_gotweb_flushfile failure: %s",
-			    __func__, error->msg);
-		fd = -1;
-	}
-	if (fd != -1)
-		close(fd);
-	if (html && srv != NULL)
-		gotweb_render_footer(c->tp);
-
-	got_ref_list_free(&refs);
+	return;
 }
 
 struct server *
@@ -473,6 +458,7 @@ gotweb_init_transport(struct transport **t)
 
 	TAILQ_INIT(&(*t)->repo_commits);
 	TAILQ_INIT(&(*t)->repo_tags);
+	TAILQ_INIT(&(*t)->refs);
 
 	(*t)->repo = NULL;
 	(*t)->repo_dir = NULL;
@@ -481,6 +467,8 @@ gotweb_init_transport(struct transport **t)
 	(*t)->prev_id = NULL;
 	(*t)->next_disp = 0;
 	(*t)->prev_disp = 0;
+
+	(*t)->fd = -1;
 
 	return error;
 }
@@ -769,9 +757,12 @@ gotweb_free_repo_dir(struct repo_dir *repo_dir)
 void
 gotweb_free_transport(struct transport *t)
 {
+	const struct got_error *err;
 	struct repo_commit *rc = NULL, *trc = NULL;
 	struct repo_tag *rt = NULL, *trt = NULL;
+	int i;
 
+	got_ref_list_free(&t->refs);
 	TAILQ_FOREACH_SAFE(rc, &t->repo_commits, entry, trc) {
 		TAILQ_REMOVE(&t->repo_commits, rc, entry);
 		gotweb_free_repo_commit(rc);
@@ -785,6 +776,22 @@ gotweb_free_transport(struct transport *t)
 	free(t->more_id);
 	free(t->next_id);
 	free(t->prev_id);
+	if (t->blob)
+		got_object_blob_close(t->blob);
+	if (t->fp) {
+		err = got_gotweb_flushfile(t->fp, t->fd);
+		if (err)
+			log_warnx("%s: got_gotweb_flushfile failure: %s",
+			    __func__, err->msg);
+		t->fd = -1;
+	}
+	if (t->fd != -1)
+		close(t->fd);
+	if (t->repos) {
+		for (i = 0; i < t->nrepos; ++i)
+			free(t->repos[i]);
+		free(t->repos);
+	}
 	free(t);
 }
 
@@ -847,30 +854,24 @@ gotweb_get_navs(struct request *c, struct gotweb_url *
 	}
 }
 
-static const struct got_error *
-gotweb_render_index(struct request *c)
+static int
+gotweb_render_index(struct template *tp)
 {
 	const struct got_error *error = NULL;
+	struct request *c = tp->tp_arg;
 	struct server *srv = c->srv;
 	struct transport *t = c->t;
 	struct querystring *qs = t->qs;
 	struct repo_dir *repo_dir = NULL;
-	struct dirent **sd_dent = NULL;
-	unsigned int d_cnt, d_i, d_disp = 0;
+	struct dirent **sd_dent = t->repos;
+	unsigned int d_i, d_disp = 0;
 	unsigned int d_skipped = 0;
-	int type;
+	int type, r;
 
-	d_cnt = scandir(srv->repos_path, &sd_dent, NULL, alphasort);
-	if (d_cnt == -1) {
-		sd_dent = NULL;
-		error = got_error_from_errno2("scandir", srv->repos_path);
-		goto done;
-	}
-
 	if (gotweb_render_repo_table_hdr(c->tp) == -1)
-		goto done;
+		return -1;
 
-	for (d_i = 0; d_i < d_cnt; d_i++) {
+	for (d_i = 0; d_i < t->nrepos; d_i++) {
 		if (srv->max_repos > 0 && t->prev_disp == srv->max_repos)
 			break;
 
@@ -883,7 +884,7 @@ gotweb_render_index(struct request *c)
 		error = got_path_dirent_type(&type, srv->repos_path,
 		    sd_dent[d_i]);
 		if (error)
-			goto done;
+			continue;
 		if (type != DT_DIR) {
 			d_skipped++;
 			continue;
@@ -897,50 +898,45 @@ gotweb_render_index(struct request *c)
 
 		error = gotweb_init_repo_dir(&repo_dir, sd_dent[d_i]->d_name);
 		if (error)
-			goto done;
+			continue;
 
 		error = gotweb_load_got_path(c, repo_dir);
-		if (error && error->code == GOT_ERR_NOT_GIT_REPO) {
-			error = NULL;
+		if (error && error->code == GOT_ERR_LONELY_PACKIDX) {
+			if (error->code != GOT_ERR_NOT_GIT_REPO)
+				log_warnx("%s: %s: %s", __func__,
+				    sd_dent[d_i]->d_name, error->msg);
 			gotweb_free_repo_dir(repo_dir);
 			repo_dir = NULL;
 			d_skipped++;
 			continue;
 		}
-		if (error && error->code != GOT_ERR_LONELY_PACKIDX)
-			goto done;
 
 		d_disp++;
 		t->prev_disp++;
 
-		if (gotweb_render_repo_fragment(c->tp, repo_dir) == -1)
-			goto done;
-
+		r = gotweb_render_repo_fragment(c->tp, repo_dir);
 		gotweb_free_repo_dir(repo_dir);
-		repo_dir = NULL;
+		if (r == -1)
+			return -1;
+
 		t->next_disp++;
 		if (d_disp == srv->max_repos_display)
 			break;
 	}
-	t->repos_total = d_cnt - d_skipped;
+	t->repos_total = t->nrepos - d_skipped;
 
 	if (srv->max_repos_display == 0)
-		goto done;
+		return 0;
 	if (srv->max_repos > 0 && srv->max_repos < srv->max_repos_display)
-		goto done;
+		return 0;
 	if (t->repos_total <= srv->max_repos ||
 	    t->repos_total <= srv->max_repos_display)
-		goto done;
+		return 0;
 
 	if (gotweb_render_navs(c->tp) == -1)
-		goto done;
-done:
-	if (sd_dent) {
-		for (d_i = 0; d_i < d_cnt; d_i++)
-			free(sd_dent[d_i]);
-		free(sd_dent);
-	}
-	return error;
+		return -1;
+
+	return 0;
 }
 
 static inline int
blob - 970fd2dec57e85de37318509346f66e8c7ef0cd2
blob + 4008d67067b944faa3ad59182834a089c26c923d
--- gotwebd/gotwebd.c
+++ gotwebd/gotwebd.c
@@ -40,6 +40,7 @@
 
 #include "got_compat.h"
 #include "got_opentemp.h"
+#include "got_reference.h"
 
 #include "proc.h"
 #include "gotwebd.h"
blob - 53749ebdda49e3367abdc4bd1723ef3b976c75ea
blob + 32ff7b9956d2a4af5dc1eff9cdef560e8457cd2f
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
@@ -188,6 +188,7 @@ struct got_repository;
 struct transport {
 	TAILQ_HEAD(repo_commits_head, repo_commit)	 repo_commits;
 	TAILQ_HEAD(repo_tags_head, repo_tag)		 repo_tags;
+	struct got_reflist_head	 refs;
 	struct got_repository	*repo;
 	struct repo_dir		*repo_dir;
 	struct querystring	*qs;
@@ -198,6 +199,11 @@ struct transport {
 	unsigned int		 next_disp;
 	unsigned int		 prev_disp;
 	unsigned int		 tag_count;
+	struct got_blob_object	*blob;
+	int			 fd;
+	FILE			*fp;
+	struct dirent		**repos;
+	int			 nrepos;
 };
 
 enum socket_priv_fds {
@@ -465,20 +471,19 @@ void gotweb_process_request(struct request *);
 void gotweb_free_transport(struct transport *);
 
 /* pages.tmpl */
-int	gotweb_render_header(struct template *);
-int	gotweb_render_footer(struct template *);
+int	gotweb_render_page(struct template *, int (*)(struct template *));
 int	gotweb_render_repo_table_hdr(struct template *);
 int	gotweb_render_repo_fragment(struct template *, struct repo_dir *);
 int	gotweb_render_briefs(struct template *);
 int	gotweb_render_navs(struct template *);
 int	gotweb_render_commits(struct template *);
-int	gotweb_render_blob(struct template *, struct got_blob_object *);
+int	gotweb_render_blob(struct template *);
 int	gotweb_render_tree(struct template *);
 int	gotweb_render_tags(struct template *);
 int	gotweb_render_tag(struct template *);
-int	gotweb_render_diff(struct template *, FILE *);
+int	gotweb_render_diff(struct template *);
 int	gotweb_render_branches(struct template *, struct got_reflist_head *);
-int	gotweb_render_summary(struct template *, struct got_reflist_head *);
+int	gotweb_render_summary(struct template *);
 int	gotweb_render_blame(struct template *);
 int	gotweb_render_rss(struct template *);
 
blob - 6b6301601460ed9f36bca0237892906c6761b5a4
blob + d092e3fbcc837ec5abd7684b0cb9de5e0562319c
--- gotwebd/pages.tmpl
+++ gotwebd/pages.tmpl
@@ -54,7 +54,8 @@ static inline int rss_author(struct template *, char *
 
 !}
 
-{{ define gotweb_render_header(struct template *tp) }}
+{{ define gotweb_render_page(struct template *tp,
+    int (*body)(struct template *)) }}
 {!
 	struct request		*c = tp->tp_arg;
 	struct server		*srv = c->srv;
@@ -110,13 +111,7 @@ static inline int rss_author(struct template *, char *
         </div>
       </div>
       <div id="content">
-{{ end }}
-
-{{ define gotweb_render_footer(struct template *tp) }}
-{!
-	struct request		*c = tp->tp_arg;
-	struct server		*srv = c->srv;
-!}
+        {{ render body(tp) }}
         <div id="site_owner_wrapper">
           <div id="site_owner">
             {{ if srv->show_site_owner }}
@@ -433,11 +428,11 @@ static inline int rss_author(struct template *, char *
 </div>
 {{ end }}
 
-{{ define gotweb_render_blob(struct template *tp,
-    struct got_blob_object *blob) }}
+{{ define gotweb_render_blob(struct template *tp) }}
 {!
 	struct request		*c = tp->tp_arg;
 	struct transport	*t = c->t;
+	struct got_blob_object	*blob = t->blob;
 	struct repo_commit	*rc = TAILQ_FIRST(&t->repo_commits);
 !}
 <div id="blob_title_wrapper">
@@ -711,10 +706,11 @@ static inline int rss_author(struct template *, char *
 </div>
 {{ end }}
 
-{{ define gotweb_render_diff(struct template *tp, FILE *fp) }}
+{{ define gotweb_render_diff(struct template *tp) }}
 {!
 	struct request		*c = tp->tp_arg;
 	struct transport	*t = c->t;
+	FILE			*fp = t->fp;
 	struct repo_commit	*rc = TAILQ_FIRST(&t->repo_commits);
 	char			*line = NULL;
 	size_t			 linesize = 0;
@@ -851,12 +847,12 @@ static inline int rss_author(struct template *, char *
 </div>
 {{ end }}
 
-{{ define gotweb_render_summary(struct template *tp,
-    struct got_reflist_head *refs) }}
+{{ define gotweb_render_summary(struct template *tp) }}
 {!
 	struct request		*c = tp->tp_arg;
 	struct server		*srv = c->srv;
 	struct transport	*t = c->t;
+	struct got_reflist_head	*refs = &t->refs;
 !}
 <div id="summary_wrapper">
   {{ if srv->show_repo_description }}
blob - 2861d081090b8314fc0a8fa65e6ab4aa4694b13a
blob + 2ce12171af2de27dad4d389dbbf8f9ea81cdb1ba
--- gotwebd/parse.y
+++ gotwebd/parse.y
@@ -47,10 +47,12 @@
 #include <string.h>
 #include <syslog.h>
 #include <unistd.h>
+
+#include "got_sockaddr.h"
+#include "got_reference.h"
 
 #include "proc.h"
 #include "gotwebd.h"
-#include "got_sockaddr.h"
 
 TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
 static struct file {
blob - c70fe81742e688cd82a6449ebb48174fdc111dc1
blob + eacbdc8fa8acb1d85aef92bdaf14ba95977a69b1
--- gotwebd/sockets.c
+++ gotwebd/sockets.c
@@ -51,6 +51,7 @@
 
 #include "got_error.h"
 #include "got_opentemp.h"
+#include "got_reference.h"
 #include "got_repository.h"
 
 #include "proc.h"