Blame


1 56324ebe 2022-07-14 thomas /*
2 56324ebe 2022-07-14 thomas * Copyright (c) 2016, 2019, 2020-2022 Tracey Emery <tracey@traceyemery.net>
3 56324ebe 2022-07-14 thomas * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
4 56324ebe 2022-07-14 thomas * Copyright (c) 2013 David Gwynne <dlg@openbsd.org>
5 56324ebe 2022-07-14 thomas * Copyright (c) 2013 Florian Obser <florian@openbsd.org>
6 56324ebe 2022-07-14 thomas *
7 56324ebe 2022-07-14 thomas * Permission to use, copy, modify, and distribute this software for any
8 56324ebe 2022-07-14 thomas * purpose with or without fee is hereby granted, provided that the above
9 56324ebe 2022-07-14 thomas * copyright notice and this permission notice appear in all copies.
10 56324ebe 2022-07-14 thomas *
11 56324ebe 2022-07-14 thomas * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 56324ebe 2022-07-14 thomas * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 56324ebe 2022-07-14 thomas * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 56324ebe 2022-07-14 thomas * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 56324ebe 2022-07-14 thomas * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 56324ebe 2022-07-14 thomas * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 56324ebe 2022-07-14 thomas * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 56324ebe 2022-07-14 thomas */
19 56324ebe 2022-07-14 thomas
20 56324ebe 2022-07-14 thomas #include <net/if.h>
21 56324ebe 2022-07-14 thomas #include <netinet/in.h>
22 56324ebe 2022-07-14 thomas #include <sys/stat.h>
23 56324ebe 2022-07-14 thomas #include <sys/types.h>
24 56324ebe 2022-07-14 thomas
25 56324ebe 2022-07-14 thomas #include <dirent.h>
26 56324ebe 2022-07-14 thomas #include <errno.h>
27 56324ebe 2022-07-14 thomas #include <event.h>
28 56324ebe 2022-07-14 thomas #include <stdio.h>
29 56324ebe 2022-07-14 thomas #include <stdlib.h>
30 56324ebe 2022-07-14 thomas #include <string.h>
31 56324ebe 2022-07-14 thomas #include <unistd.h>
32 56324ebe 2022-07-14 thomas
33 56324ebe 2022-07-14 thomas #include "got_error.h"
34 56324ebe 2022-07-14 thomas #include "got_object.h"
35 56324ebe 2022-07-14 thomas #include "got_reference.h"
36 56324ebe 2022-07-14 thomas #include "got_repository.h"
37 56324ebe 2022-07-14 thomas #include "got_path.h"
38 56324ebe 2022-07-14 thomas #include "got_cancel.h"
39 56324ebe 2022-07-14 thomas #include "got_worktree.h"
40 56324ebe 2022-07-14 thomas #include "got_diff.h"
41 56324ebe 2022-07-14 thomas #include "got_commit_graph.h"
42 56324ebe 2022-07-14 thomas #include "got_blame.h"
43 56324ebe 2022-07-14 thomas #include "got_privsep.h"
44 56324ebe 2022-07-14 thomas
45 56324ebe 2022-07-14 thomas #include "proc.h"
46 56324ebe 2022-07-14 thomas #include "gotwebd.h"
47 56324ebe 2022-07-14 thomas
48 d7cad54e 2022-07-14 thomas #include "got_compat.h"
49 d7cad54e 2022-07-14 thomas
50 56324ebe 2022-07-14 thomas enum gotweb_ref_tm {
51 56324ebe 2022-07-14 thomas TM_DIFF,
52 56324ebe 2022-07-14 thomas TM_LONG,
53 56324ebe 2022-07-14 thomas };
54 56324ebe 2022-07-14 thomas
55 56324ebe 2022-07-14 thomas static const struct querystring_keys querystring_keys[] = {
56 56324ebe 2022-07-14 thomas { "action", ACTION },
57 56324ebe 2022-07-14 thomas { "commit", COMMIT },
58 56324ebe 2022-07-14 thomas { "file", RFILE },
59 56324ebe 2022-07-14 thomas { "folder", FOLDER },
60 56324ebe 2022-07-14 thomas { "headref", HEADREF },
61 56324ebe 2022-07-14 thomas { "index_page", INDEX_PAGE },
62 56324ebe 2022-07-14 thomas { "path", PATH },
63 56324ebe 2022-07-14 thomas { "page", PAGE },
64 56324ebe 2022-07-14 thomas };
65 56324ebe 2022-07-14 thomas
66 56324ebe 2022-07-14 thomas static const struct action_keys action_keys[] = {
67 56324ebe 2022-07-14 thomas { "blame", BLAME },
68 56324ebe 2022-07-14 thomas { "blob", BLOB },
69 56324ebe 2022-07-14 thomas { "briefs", BRIEFS },
70 56324ebe 2022-07-14 thomas { "commits", COMMITS },
71 56324ebe 2022-07-14 thomas { "diff", DIFF },
72 56324ebe 2022-07-14 thomas { "error", ERR },
73 56324ebe 2022-07-14 thomas { "index", INDEX },
74 56324ebe 2022-07-14 thomas { "summary", SUMMARY },
75 56324ebe 2022-07-14 thomas { "tag", TAG },
76 56324ebe 2022-07-14 thomas { "tags", TAGS },
77 56324ebe 2022-07-14 thomas { "tree", TREE },
78 56324ebe 2022-07-14 thomas };
79 56324ebe 2022-07-14 thomas
80 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_init_querystring(struct querystring **);
81 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_parse_querystring(struct querystring **,
82 56324ebe 2022-07-14 thomas char *);
83 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_assign_querystring(struct querystring **,
84 56324ebe 2022-07-14 thomas char *, char *);
85 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_header(struct request *);
86 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_footer(struct request *);
87 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_index(struct request *);
88 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_init_repo_dir(struct repo_dir **,
89 56324ebe 2022-07-14 thomas const char *);
90 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_load_got_path(struct request *c,
91 56324ebe 2022-07-14 thomas struct repo_dir *);
92 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_get_repo_description(char **,
93 56324ebe 2022-07-14 thomas struct server *, char *);
94 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_get_clone_url(char **, struct server *,
95 56324ebe 2022-07-14 thomas char *);
96 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_navs(struct request *);
97 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_blame(struct request *);
98 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_briefs(struct request *);
99 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_commits(struct request *);
100 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_diff(struct request *);
101 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_summary(struct request *);
102 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_tag(struct request *);
103 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_tags(struct request *);
104 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_tree(struct request *);
105 56324ebe 2022-07-14 thomas static const struct got_error *gotweb_render_branches(struct request *);
106 56324ebe 2022-07-14 thomas
107 56324ebe 2022-07-14 thomas static void gotweb_free_querystring(struct querystring *);
108 56324ebe 2022-07-14 thomas static void gotweb_free_repo_dir(struct repo_dir *);
109 56324ebe 2022-07-14 thomas
110 56324ebe 2022-07-14 thomas struct server *gotweb_get_server(uint8_t *, uint8_t *, uint8_t *);
111 56324ebe 2022-07-14 thomas
112 56324ebe 2022-07-14 thomas void
113 56324ebe 2022-07-14 thomas gotweb_process_request(struct request *c)
114 56324ebe 2022-07-14 thomas {
115 56324ebe 2022-07-14 thomas const struct got_error *error = NULL, *error2 = NULL;
116 56324ebe 2022-07-14 thomas struct server *srv = NULL;
117 56324ebe 2022-07-14 thomas struct querystring *qs = NULL;
118 56324ebe 2022-07-14 thomas struct repo_dir *repo_dir = NULL;
119 56324ebe 2022-07-14 thomas uint8_t err[] = "gotwebd experienced an error: ";
120 56324ebe 2022-07-14 thomas int html = 0;
121 56324ebe 2022-07-14 thomas
122 56324ebe 2022-07-14 thomas /* init the transport */
123 56324ebe 2022-07-14 thomas error = gotweb_init_transport(&c->t);
124 56324ebe 2022-07-14 thomas if (error) {
125 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
126 56324ebe 2022-07-14 thomas goto err;
127 56324ebe 2022-07-14 thomas }
128 56324ebe 2022-07-14 thomas /* don't process any further if client disconnected */
129 56324ebe 2022-07-14 thomas if (c->sock->client_status == CLIENT_DISCONNECT)
130 56324ebe 2022-07-14 thomas return;
131 56324ebe 2022-07-14 thomas /* get the gotwebd server */
132 56324ebe 2022-07-14 thomas srv = gotweb_get_server(c->server_name, c->document_root, c->http_host);
133 56324ebe 2022-07-14 thomas if (srv == NULL) {
134 56324ebe 2022-07-14 thomas log_warnx("%s: error server is NULL", __func__);
135 56324ebe 2022-07-14 thomas goto err;
136 56324ebe 2022-07-14 thomas }
137 56324ebe 2022-07-14 thomas c->srv = srv;
138 56324ebe 2022-07-14 thomas /* parse our querystring */
139 56324ebe 2022-07-14 thomas error = gotweb_init_querystring(&qs);
140 56324ebe 2022-07-14 thomas if (error) {
141 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
142 56324ebe 2022-07-14 thomas goto err;
143 56324ebe 2022-07-14 thomas }
144 56324ebe 2022-07-14 thomas c->t->qs = qs;
145 56324ebe 2022-07-14 thomas error = gotweb_parse_querystring(&qs, c->querystring);
146 56324ebe 2022-07-14 thomas if (error) {
147 56324ebe 2022-07-14 thomas gotweb_free_querystring(qs);
148 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
149 56324ebe 2022-07-14 thomas goto err;
150 56324ebe 2022-07-14 thomas }
151 56324ebe 2022-07-14 thomas
152 56324ebe 2022-07-14 thomas /*
153 56324ebe 2022-07-14 thomas * certain actions require a commit id in the querystring. this stops
154 56324ebe 2022-07-14 thomas * bad actors from exploiting this by manually manipulating the
155 56324ebe 2022-07-14 thomas * querystring.
156 56324ebe 2022-07-14 thomas */
157 56324ebe 2022-07-14 thomas
158 56324ebe 2022-07-14 thomas if (qs->commit == NULL && (qs->action == BLAME || qs->action == BLOB ||
159 56324ebe 2022-07-14 thomas qs->action == DIFF)) {
160 56324ebe 2022-07-14 thomas error2 = got_error(GOT_ERR_QUERYSTRING);
161 56324ebe 2022-07-14 thomas goto render;
162 56324ebe 2022-07-14 thomas }
163 56324ebe 2022-07-14 thomas
164 56324ebe 2022-07-14 thomas if (qs->action != INDEX) {
165 56324ebe 2022-07-14 thomas error = gotweb_init_repo_dir(&repo_dir, qs->path);
166 56324ebe 2022-07-14 thomas if (error)
167 56324ebe 2022-07-14 thomas goto done;
168 56324ebe 2022-07-14 thomas error = gotweb_load_got_path(c, repo_dir);
169 56324ebe 2022-07-14 thomas c->t->repo_dir = repo_dir;
170 56324ebe 2022-07-14 thomas if (error && error->code != GOT_ERR_LONELY_PACKIDX)
171 56324ebe 2022-07-14 thomas goto err;
172 56324ebe 2022-07-14 thomas }
173 56324ebe 2022-07-14 thomas
174 56324ebe 2022-07-14 thomas /* render top of page */
175 56324ebe 2022-07-14 thomas if (qs != NULL && qs->action == BLOB) {
176 56324ebe 2022-07-14 thomas error = got_get_repo_commits(c, 1);
177 56324ebe 2022-07-14 thomas if (error)
178 56324ebe 2022-07-14 thomas goto done;
179 56324ebe 2022-07-14 thomas error = gotweb_render_content_type(c, "text/plain");
180 56324ebe 2022-07-14 thomas if (error) {
181 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
182 56324ebe 2022-07-14 thomas goto err;
183 56324ebe 2022-07-14 thomas }
184 56324ebe 2022-07-14 thomas error = got_output_file_blob(c);
185 56324ebe 2022-07-14 thomas if (error) {
186 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
187 56324ebe 2022-07-14 thomas goto err;
188 56324ebe 2022-07-14 thomas }
189 56324ebe 2022-07-14 thomas goto done;
190 56324ebe 2022-07-14 thomas } else {
191 56324ebe 2022-07-14 thomas render:
192 56324ebe 2022-07-14 thomas error = gotweb_render_content_type(c, "text/html");
193 56324ebe 2022-07-14 thomas if (error) {
194 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
195 56324ebe 2022-07-14 thomas goto err;
196 56324ebe 2022-07-14 thomas }
197 56324ebe 2022-07-14 thomas html = 1;
198 56324ebe 2022-07-14 thomas }
199 56324ebe 2022-07-14 thomas
200 56324ebe 2022-07-14 thomas error = gotweb_render_header(c);
201 56324ebe 2022-07-14 thomas if (error) {
202 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
203 56324ebe 2022-07-14 thomas goto err;
204 56324ebe 2022-07-14 thomas }
205 56324ebe 2022-07-14 thomas
206 56324ebe 2022-07-14 thomas if (error2) {
207 56324ebe 2022-07-14 thomas error = error2;
208 56324ebe 2022-07-14 thomas goto err;
209 56324ebe 2022-07-14 thomas }
210 56324ebe 2022-07-14 thomas
211 56324ebe 2022-07-14 thomas switch(qs->action) {
212 56324ebe 2022-07-14 thomas case BLAME:
213 56324ebe 2022-07-14 thomas error = gotweb_render_blame(c);
214 56324ebe 2022-07-14 thomas if (error) {
215 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
216 56324ebe 2022-07-14 thomas goto err;
217 56324ebe 2022-07-14 thomas }
218 56324ebe 2022-07-14 thomas break;
219 56324ebe 2022-07-14 thomas case BRIEFS:
220 56324ebe 2022-07-14 thomas error = gotweb_render_briefs(c);
221 56324ebe 2022-07-14 thomas if (error) {
222 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
223 56324ebe 2022-07-14 thomas goto err;
224 56324ebe 2022-07-14 thomas }
225 56324ebe 2022-07-14 thomas break;
226 56324ebe 2022-07-14 thomas case COMMITS:
227 56324ebe 2022-07-14 thomas error = gotweb_render_commits(c);
228 56324ebe 2022-07-14 thomas if (error) {
229 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
230 56324ebe 2022-07-14 thomas goto err;
231 56324ebe 2022-07-14 thomas }
232 56324ebe 2022-07-14 thomas break;
233 56324ebe 2022-07-14 thomas case DIFF:
234 56324ebe 2022-07-14 thomas error = gotweb_render_diff(c);
235 56324ebe 2022-07-14 thomas if (error) {
236 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
237 56324ebe 2022-07-14 thomas goto err;
238 56324ebe 2022-07-14 thomas }
239 56324ebe 2022-07-14 thomas break;
240 56324ebe 2022-07-14 thomas case INDEX:
241 56324ebe 2022-07-14 thomas error = gotweb_render_index(c);
242 56324ebe 2022-07-14 thomas if (error) {
243 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
244 56324ebe 2022-07-14 thomas goto err;
245 56324ebe 2022-07-14 thomas }
246 56324ebe 2022-07-14 thomas break;
247 56324ebe 2022-07-14 thomas case SUMMARY:
248 56324ebe 2022-07-14 thomas error = gotweb_render_summary(c);
249 56324ebe 2022-07-14 thomas if (error) {
250 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
251 56324ebe 2022-07-14 thomas goto err;
252 56324ebe 2022-07-14 thomas }
253 56324ebe 2022-07-14 thomas break;
254 56324ebe 2022-07-14 thomas case TAG:
255 56324ebe 2022-07-14 thomas error = gotweb_render_tag(c);
256 56324ebe 2022-07-14 thomas if (error) {
257 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
258 56324ebe 2022-07-14 thomas goto err;
259 56324ebe 2022-07-14 thomas }
260 56324ebe 2022-07-14 thomas break;
261 56324ebe 2022-07-14 thomas case TAGS:
262 56324ebe 2022-07-14 thomas error = gotweb_render_tags(c);
263 56324ebe 2022-07-14 thomas if (error) {
264 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
265 56324ebe 2022-07-14 thomas goto err;
266 56324ebe 2022-07-14 thomas }
267 56324ebe 2022-07-14 thomas break;
268 56324ebe 2022-07-14 thomas case TREE:
269 56324ebe 2022-07-14 thomas error = gotweb_render_tree(c);
270 56324ebe 2022-07-14 thomas if (error) {
271 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
272 56324ebe 2022-07-14 thomas goto err;
273 56324ebe 2022-07-14 thomas }
274 56324ebe 2022-07-14 thomas break;
275 56324ebe 2022-07-14 thomas case ERR:
276 56324ebe 2022-07-14 thomas default:
277 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='err_content'>") == -1)
278 56324ebe 2022-07-14 thomas goto err;
279 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "Error: Bad Querystring\n") == -1)
280 56324ebe 2022-07-14 thomas goto err;
281 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
282 56324ebe 2022-07-14 thomas goto err;
283 56324ebe 2022-07-14 thomas break;
284 56324ebe 2022-07-14 thomas }
285 56324ebe 2022-07-14 thomas
286 56324ebe 2022-07-14 thomas goto done;
287 56324ebe 2022-07-14 thomas err:
288 56324ebe 2022-07-14 thomas if (html && fcgi_gen_response(c, "<div id='err_content'>") == -1)
289 56324ebe 2022-07-14 thomas return;
290 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, err) == -1)
291 56324ebe 2022-07-14 thomas return;
292 56324ebe 2022-07-14 thomas if (error) {
293 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, (uint8_t *)error->msg) == -1)
294 56324ebe 2022-07-14 thomas return;
295 56324ebe 2022-07-14 thomas } else {
296 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "see daemon logs for details") == -1)
297 56324ebe 2022-07-14 thomas return;
298 56324ebe 2022-07-14 thomas }
299 56324ebe 2022-07-14 thomas if (html && fcgi_gen_response(c, "</div>\n") == -1)
300 56324ebe 2022-07-14 thomas return;
301 56324ebe 2022-07-14 thomas done:
302 56324ebe 2022-07-14 thomas if (c->t->repo != NULL && qs->action != INDEX)
303 56324ebe 2022-07-14 thomas got_repo_close(c->t->repo);
304 56324ebe 2022-07-14 thomas if (html && srv != NULL)
305 56324ebe 2022-07-14 thomas gotweb_render_footer(c);
306 56324ebe 2022-07-14 thomas }
307 56324ebe 2022-07-14 thomas
308 56324ebe 2022-07-14 thomas struct server *
309 56324ebe 2022-07-14 thomas gotweb_get_server(uint8_t *server_name, uint8_t *document_root,
310 56324ebe 2022-07-14 thomas uint8_t *subdomain)
311 56324ebe 2022-07-14 thomas {
312 56324ebe 2022-07-14 thomas struct server *srv = NULL;
313 56324ebe 2022-07-14 thomas
314 56324ebe 2022-07-14 thomas /* check against document_root first */
315 56324ebe 2022-07-14 thomas if (strlen(server_name) > 0)
316 56324ebe 2022-07-14 thomas TAILQ_FOREACH(srv, gotwebd_env->servers, entry)
317 56324ebe 2022-07-14 thomas if (strcmp(srv->name, server_name) == 0)
318 56324ebe 2022-07-14 thomas goto done;
319 56324ebe 2022-07-14 thomas
320 56324ebe 2022-07-14 thomas /* check against document_root second */
321 56324ebe 2022-07-14 thomas if (strlen(document_root) > 0)
322 56324ebe 2022-07-14 thomas TAILQ_FOREACH(srv, gotwebd_env->servers, entry)
323 56324ebe 2022-07-14 thomas if (strcmp(srv->name, document_root) == 0)
324 56324ebe 2022-07-14 thomas goto done;
325 56324ebe 2022-07-14 thomas
326 56324ebe 2022-07-14 thomas /* check against subdomain third */
327 56324ebe 2022-07-14 thomas if (strlen(subdomain) > 0)
328 56324ebe 2022-07-14 thomas TAILQ_FOREACH(srv, gotwebd_env->servers, entry)
329 56324ebe 2022-07-14 thomas if (strcmp(srv->name, subdomain) == 0)
330 56324ebe 2022-07-14 thomas goto done;
331 56324ebe 2022-07-14 thomas
332 56324ebe 2022-07-14 thomas /* if those fail, send first server */
333 56324ebe 2022-07-14 thomas TAILQ_FOREACH(srv, gotwebd_env->servers, entry)
334 56324ebe 2022-07-14 thomas if (srv != NULL)
335 56324ebe 2022-07-14 thomas break;
336 56324ebe 2022-07-14 thomas done:
337 56324ebe 2022-07-14 thomas return srv;
338 56324ebe 2022-07-14 thomas };
339 56324ebe 2022-07-14 thomas
340 56324ebe 2022-07-14 thomas const struct got_error *
341 56324ebe 2022-07-14 thomas gotweb_init_transport(struct transport **t)
342 56324ebe 2022-07-14 thomas {
343 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
344 56324ebe 2022-07-14 thomas
345 56324ebe 2022-07-14 thomas *t = calloc(1, sizeof(**t));
346 56324ebe 2022-07-14 thomas if (*t == NULL)
347 56324ebe 2022-07-14 thomas return got_error_from_errno2("%s: calloc", __func__);
348 56324ebe 2022-07-14 thomas
349 56324ebe 2022-07-14 thomas TAILQ_INIT(&(*t)->repo_commits);
350 56324ebe 2022-07-14 thomas TAILQ_INIT(&(*t)->repo_tags);
351 56324ebe 2022-07-14 thomas
352 56324ebe 2022-07-14 thomas (*t)->repo = NULL;
353 56324ebe 2022-07-14 thomas (*t)->repo_dir = NULL;
354 56324ebe 2022-07-14 thomas (*t)->qs = NULL;
355 56324ebe 2022-07-14 thomas (*t)->next_id = NULL;
356 56324ebe 2022-07-14 thomas (*t)->prev_id = NULL;
357 56324ebe 2022-07-14 thomas (*t)->next_disp = 0;
358 56324ebe 2022-07-14 thomas (*t)->prev_disp = 0;
359 56324ebe 2022-07-14 thomas
360 56324ebe 2022-07-14 thomas return error;
361 56324ebe 2022-07-14 thomas }
362 56324ebe 2022-07-14 thomas
363 56324ebe 2022-07-14 thomas static const struct got_error *
364 56324ebe 2022-07-14 thomas gotweb_init_querystring(struct querystring **qs)
365 56324ebe 2022-07-14 thomas {
366 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
367 56324ebe 2022-07-14 thomas
368 56324ebe 2022-07-14 thomas *qs = calloc(1, sizeof(**qs));
369 56324ebe 2022-07-14 thomas if (*qs == NULL)
370 56324ebe 2022-07-14 thomas return got_error_from_errno2("%s: calloc", __func__);
371 56324ebe 2022-07-14 thomas
372 56324ebe 2022-07-14 thomas (*qs)->action = INDEX;
373 56324ebe 2022-07-14 thomas (*qs)->commit = NULL;
374 56324ebe 2022-07-14 thomas (*qs)->file = NULL;
375 56324ebe 2022-07-14 thomas (*qs)->folder = NULL;
376 56324ebe 2022-07-14 thomas (*qs)->headref = strdup("HEAD");
377 56324ebe 2022-07-14 thomas if ((*qs)->headref == NULL) {
378 56324ebe 2022-07-14 thomas return got_error_from_errno2("%s: strdup", __func__);
379 56324ebe 2022-07-14 thomas }
380 56324ebe 2022-07-14 thomas (*qs)->index_page = 0;
381 56324ebe 2022-07-14 thomas (*qs)->index_page_str = NULL;
382 56324ebe 2022-07-14 thomas (*qs)->path = NULL;
383 56324ebe 2022-07-14 thomas
384 56324ebe 2022-07-14 thomas return error;
385 56324ebe 2022-07-14 thomas }
386 56324ebe 2022-07-14 thomas
387 56324ebe 2022-07-14 thomas static const struct got_error *
388 56324ebe 2022-07-14 thomas gotweb_parse_querystring(struct querystring **qs, char *qst)
389 56324ebe 2022-07-14 thomas {
390 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
391 56324ebe 2022-07-14 thomas char *tok1 = NULL, *tok1_pair = NULL, *tok1_end = NULL;
392 56324ebe 2022-07-14 thomas char *tok2 = NULL, *tok2_pair = NULL, *tok2_end = NULL;
393 56324ebe 2022-07-14 thomas
394 56324ebe 2022-07-14 thomas if (qst == NULL)
395 56324ebe 2022-07-14 thomas return error;
396 56324ebe 2022-07-14 thomas
397 56324ebe 2022-07-14 thomas tok1 = strdup(qst);
398 56324ebe 2022-07-14 thomas if (tok1 == NULL)
399 56324ebe 2022-07-14 thomas return got_error_from_errno2("%s: strdup", __func__);
400 56324ebe 2022-07-14 thomas
401 56324ebe 2022-07-14 thomas tok1_pair = tok1;
402 56324ebe 2022-07-14 thomas tok1_end = tok1;
403 56324ebe 2022-07-14 thomas
404 56324ebe 2022-07-14 thomas while (tok1_pair != NULL) {
405 56324ebe 2022-07-14 thomas strsep(&tok1_end, "&");
406 56324ebe 2022-07-14 thomas
407 56324ebe 2022-07-14 thomas tok2 = strdup(tok1_pair);
408 56324ebe 2022-07-14 thomas if (tok2 == NULL) {
409 56324ebe 2022-07-14 thomas free(tok1);
410 56324ebe 2022-07-14 thomas return got_error_from_errno2("%s: strdup", __func__);
411 56324ebe 2022-07-14 thomas }
412 56324ebe 2022-07-14 thomas
413 56324ebe 2022-07-14 thomas tok2_pair = tok2;
414 56324ebe 2022-07-14 thomas tok2_end = tok2;
415 56324ebe 2022-07-14 thomas
416 56324ebe 2022-07-14 thomas while (tok2_pair != NULL) {
417 56324ebe 2022-07-14 thomas strsep(&tok2_end, "=");
418 56324ebe 2022-07-14 thomas if (tok2_end) {
419 56324ebe 2022-07-14 thomas error = gotweb_assign_querystring(qs, tok2_pair,
420 56324ebe 2022-07-14 thomas tok2_end);
421 56324ebe 2022-07-14 thomas if (error)
422 56324ebe 2022-07-14 thomas goto err;
423 56324ebe 2022-07-14 thomas }
424 56324ebe 2022-07-14 thomas tok2_pair = tok2_end;
425 56324ebe 2022-07-14 thomas }
426 56324ebe 2022-07-14 thomas free(tok2);
427 56324ebe 2022-07-14 thomas tok1_pair = tok1_end;
428 56324ebe 2022-07-14 thomas }
429 56324ebe 2022-07-14 thomas free(tok1);
430 56324ebe 2022-07-14 thomas return error;
431 56324ebe 2022-07-14 thomas err:
432 56324ebe 2022-07-14 thomas free(tok2);
433 56324ebe 2022-07-14 thomas free(tok1);
434 56324ebe 2022-07-14 thomas return error;
435 56324ebe 2022-07-14 thomas }
436 56324ebe 2022-07-14 thomas
437 56324ebe 2022-07-14 thomas static const struct got_error *
438 56324ebe 2022-07-14 thomas gotweb_assign_querystring(struct querystring **qs, char *key, char *value)
439 56324ebe 2022-07-14 thomas {
440 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
441 56324ebe 2022-07-14 thomas const char *errstr;
442 56324ebe 2022-07-14 thomas int a_cnt, el_cnt;
443 56324ebe 2022-07-14 thomas
444 56324ebe 2022-07-14 thomas for (el_cnt = 0; el_cnt < QSELEM__MAX; el_cnt++) {
445 56324ebe 2022-07-14 thomas if (strcmp(key, querystring_keys[el_cnt].name) != 0)
446 56324ebe 2022-07-14 thomas continue;
447 56324ebe 2022-07-14 thomas
448 56324ebe 2022-07-14 thomas switch (querystring_keys[el_cnt].element) {
449 56324ebe 2022-07-14 thomas case ACTION:
450 56324ebe 2022-07-14 thomas for (a_cnt = 0; a_cnt < ACTIONS__MAX; a_cnt++) {
451 56324ebe 2022-07-14 thomas if (strcmp(value, action_keys[a_cnt].name) != 0)
452 56324ebe 2022-07-14 thomas continue;
453 56324ebe 2022-07-14 thomas else if (strcmp(value,
454 56324ebe 2022-07-14 thomas action_keys[a_cnt].name) == 0){
455 56324ebe 2022-07-14 thomas (*qs)->action =
456 56324ebe 2022-07-14 thomas action_keys[a_cnt].action;
457 56324ebe 2022-07-14 thomas goto qa_found;
458 56324ebe 2022-07-14 thomas }
459 56324ebe 2022-07-14 thomas }
460 56324ebe 2022-07-14 thomas (*qs)->action = ERR;
461 56324ebe 2022-07-14 thomas qa_found:
462 56324ebe 2022-07-14 thomas break;
463 56324ebe 2022-07-14 thomas case COMMIT:
464 56324ebe 2022-07-14 thomas (*qs)->commit = strdup(value);
465 56324ebe 2022-07-14 thomas if ((*qs)->commit == NULL) {
466 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: strdup",
467 56324ebe 2022-07-14 thomas __func__);
468 56324ebe 2022-07-14 thomas goto done;
469 56324ebe 2022-07-14 thomas }
470 56324ebe 2022-07-14 thomas break;
471 56324ebe 2022-07-14 thomas case RFILE:
472 56324ebe 2022-07-14 thomas (*qs)->file = strdup(value);
473 56324ebe 2022-07-14 thomas if ((*qs)->file == NULL) {
474 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: strdup",
475 56324ebe 2022-07-14 thomas __func__);
476 56324ebe 2022-07-14 thomas goto done;
477 56324ebe 2022-07-14 thomas }
478 56324ebe 2022-07-14 thomas break;
479 56324ebe 2022-07-14 thomas case FOLDER:
480 56324ebe 2022-07-14 thomas (*qs)->folder = strdup(value);
481 56324ebe 2022-07-14 thomas if ((*qs)->folder == NULL) {
482 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: strdup",
483 56324ebe 2022-07-14 thomas __func__);
484 56324ebe 2022-07-14 thomas goto done;
485 56324ebe 2022-07-14 thomas }
486 56324ebe 2022-07-14 thomas break;
487 56324ebe 2022-07-14 thomas case HEADREF:
488 56324ebe 2022-07-14 thomas (*qs)->headref = strdup(value);
489 56324ebe 2022-07-14 thomas if ((*qs)->headref == NULL) {
490 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: strdup",
491 56324ebe 2022-07-14 thomas __func__);
492 56324ebe 2022-07-14 thomas goto done;
493 56324ebe 2022-07-14 thomas }
494 56324ebe 2022-07-14 thomas break;
495 56324ebe 2022-07-14 thomas case INDEX_PAGE:
496 56324ebe 2022-07-14 thomas if (strlen(value) == 0)
497 56324ebe 2022-07-14 thomas break;
498 56324ebe 2022-07-14 thomas (*qs)->index_page_str = strdup(value);
499 56324ebe 2022-07-14 thomas if ((*qs)->index_page_str == NULL) {
500 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: strdup",
501 56324ebe 2022-07-14 thomas __func__);
502 56324ebe 2022-07-14 thomas goto done;
503 56324ebe 2022-07-14 thomas }
504 56324ebe 2022-07-14 thomas (*qs)->index_page = strtonum(value, INT64_MIN,
505 56324ebe 2022-07-14 thomas INT64_MAX, &errstr);
506 56324ebe 2022-07-14 thomas if (errstr) {
507 56324ebe 2022-07-14 thomas error = got_error_from_errno3("%s: strtonum %s",
508 56324ebe 2022-07-14 thomas __func__, errstr);
509 56324ebe 2022-07-14 thomas goto done;
510 56324ebe 2022-07-14 thomas }
511 56324ebe 2022-07-14 thomas if ((*qs)->index_page < 0) {
512 56324ebe 2022-07-14 thomas (*qs)->index_page = 0;
513 56324ebe 2022-07-14 thomas sprintf((*qs)->index_page_str, "%d", 0);
514 56324ebe 2022-07-14 thomas }
515 56324ebe 2022-07-14 thomas break;
516 56324ebe 2022-07-14 thomas case PATH:
517 56324ebe 2022-07-14 thomas (*qs)->path = strdup(value);
518 56324ebe 2022-07-14 thomas if ((*qs)->path == NULL) {
519 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: strdup",
520 56324ebe 2022-07-14 thomas __func__);
521 56324ebe 2022-07-14 thomas goto done;
522 56324ebe 2022-07-14 thomas }
523 56324ebe 2022-07-14 thomas break;
524 56324ebe 2022-07-14 thomas case PAGE:
525 56324ebe 2022-07-14 thomas if (strlen(value) == 0)
526 56324ebe 2022-07-14 thomas break;
527 56324ebe 2022-07-14 thomas (*qs)->page_str = strdup(value);
528 56324ebe 2022-07-14 thomas if ((*qs)->page_str == NULL) {
529 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: strdup",
530 56324ebe 2022-07-14 thomas __func__);
531 56324ebe 2022-07-14 thomas goto done;
532 56324ebe 2022-07-14 thomas }
533 56324ebe 2022-07-14 thomas (*qs)->page = strtonum(value, INT64_MIN,
534 56324ebe 2022-07-14 thomas INT64_MAX, &errstr);
535 56324ebe 2022-07-14 thomas if (errstr) {
536 56324ebe 2022-07-14 thomas error = got_error_from_errno3("%s: strtonum %s",
537 56324ebe 2022-07-14 thomas __func__, errstr);
538 56324ebe 2022-07-14 thomas goto done;
539 56324ebe 2022-07-14 thomas }
540 56324ebe 2022-07-14 thomas if ((*qs)->page < 0) {
541 56324ebe 2022-07-14 thomas (*qs)->page = 0;
542 56324ebe 2022-07-14 thomas sprintf((*qs)->page_str, "%d", 0);
543 56324ebe 2022-07-14 thomas }
544 56324ebe 2022-07-14 thomas break;
545 56324ebe 2022-07-14 thomas default:
546 56324ebe 2022-07-14 thomas break;
547 56324ebe 2022-07-14 thomas }
548 56324ebe 2022-07-14 thomas }
549 56324ebe 2022-07-14 thomas done:
550 56324ebe 2022-07-14 thomas return error;
551 56324ebe 2022-07-14 thomas }
552 56324ebe 2022-07-14 thomas
553 56324ebe 2022-07-14 thomas void
554 56324ebe 2022-07-14 thomas gotweb_free_repo_tag(struct repo_tag *rt)
555 56324ebe 2022-07-14 thomas {
556 56324ebe 2022-07-14 thomas if (rt != NULL) {
557 56324ebe 2022-07-14 thomas free(rt->commit_msg);
558 56324ebe 2022-07-14 thomas free(rt->commit_id);
559 56324ebe 2022-07-14 thomas free(rt->tagger);
560 56324ebe 2022-07-14 thomas }
561 56324ebe 2022-07-14 thomas free(rt);
562 56324ebe 2022-07-14 thomas }
563 56324ebe 2022-07-14 thomas
564 56324ebe 2022-07-14 thomas void
565 56324ebe 2022-07-14 thomas gotweb_free_repo_commit(struct repo_commit *rc)
566 56324ebe 2022-07-14 thomas {
567 56324ebe 2022-07-14 thomas if (rc != NULL) {
568 56324ebe 2022-07-14 thomas free(rc->path);
569 56324ebe 2022-07-14 thomas free(rc->refs_str);
570 56324ebe 2022-07-14 thomas free(rc->commit_id);
571 56324ebe 2022-07-14 thomas free(rc->parent_id);
572 56324ebe 2022-07-14 thomas free(rc->tree_id);
573 56324ebe 2022-07-14 thomas free(rc->author);
574 56324ebe 2022-07-14 thomas free(rc->committer);
575 56324ebe 2022-07-14 thomas free(rc->commit_msg);
576 56324ebe 2022-07-14 thomas }
577 56324ebe 2022-07-14 thomas free(rc);
578 56324ebe 2022-07-14 thomas }
579 56324ebe 2022-07-14 thomas
580 56324ebe 2022-07-14 thomas static void
581 56324ebe 2022-07-14 thomas gotweb_free_querystring(struct querystring *qs)
582 56324ebe 2022-07-14 thomas {
583 56324ebe 2022-07-14 thomas if (qs != NULL) {
584 56324ebe 2022-07-14 thomas free(qs->commit);
585 56324ebe 2022-07-14 thomas free(qs->file);
586 56324ebe 2022-07-14 thomas free(qs->folder);
587 56324ebe 2022-07-14 thomas free(qs->headref);
588 56324ebe 2022-07-14 thomas free(qs->index_page_str);
589 56324ebe 2022-07-14 thomas free(qs->path);
590 56324ebe 2022-07-14 thomas free(qs->page_str);
591 56324ebe 2022-07-14 thomas }
592 56324ebe 2022-07-14 thomas free(qs);
593 56324ebe 2022-07-14 thomas }
594 56324ebe 2022-07-14 thomas
595 56324ebe 2022-07-14 thomas static void
596 56324ebe 2022-07-14 thomas gotweb_free_repo_dir(struct repo_dir *repo_dir)
597 56324ebe 2022-07-14 thomas {
598 56324ebe 2022-07-14 thomas if (repo_dir != NULL) {
599 56324ebe 2022-07-14 thomas free(repo_dir->name);
600 56324ebe 2022-07-14 thomas free(repo_dir->owner);
601 56324ebe 2022-07-14 thomas free(repo_dir->description);
602 56324ebe 2022-07-14 thomas free(repo_dir->url);
603 56324ebe 2022-07-14 thomas free(repo_dir->age);
604 56324ebe 2022-07-14 thomas free(repo_dir->path);
605 56324ebe 2022-07-14 thomas }
606 56324ebe 2022-07-14 thomas free(repo_dir);
607 56324ebe 2022-07-14 thomas }
608 56324ebe 2022-07-14 thomas
609 56324ebe 2022-07-14 thomas void
610 56324ebe 2022-07-14 thomas gotweb_free_transport(struct transport *t)
611 56324ebe 2022-07-14 thomas {
612 56324ebe 2022-07-14 thomas struct repo_commit *rc = NULL, *trc = NULL;
613 56324ebe 2022-07-14 thomas struct repo_tag *rt = NULL, *trt = NULL;
614 56324ebe 2022-07-14 thomas
615 56324ebe 2022-07-14 thomas TAILQ_FOREACH_SAFE(rc, &t->repo_commits, entry, trc) {
616 56324ebe 2022-07-14 thomas TAILQ_REMOVE(&t->repo_commits, rc, entry);
617 56324ebe 2022-07-14 thomas gotweb_free_repo_commit(rc);
618 56324ebe 2022-07-14 thomas }
619 56324ebe 2022-07-14 thomas TAILQ_FOREACH_SAFE(rt, &t->repo_tags, entry, trt) {
620 56324ebe 2022-07-14 thomas TAILQ_REMOVE(&t->repo_tags, rt, entry);
621 56324ebe 2022-07-14 thomas gotweb_free_repo_tag(rt);
622 56324ebe 2022-07-14 thomas }
623 56324ebe 2022-07-14 thomas gotweb_free_repo_dir(t->repo_dir);
624 56324ebe 2022-07-14 thomas gotweb_free_querystring(t->qs);
625 56324ebe 2022-07-14 thomas if (t != NULL) {
626 56324ebe 2022-07-14 thomas free(t->next_id);
627 56324ebe 2022-07-14 thomas free(t->prev_id);
628 56324ebe 2022-07-14 thomas }
629 56324ebe 2022-07-14 thomas free(t);
630 56324ebe 2022-07-14 thomas }
631 56324ebe 2022-07-14 thomas
632 56324ebe 2022-07-14 thomas const struct got_error *
633 56324ebe 2022-07-14 thomas gotweb_render_content_type(struct request *c, const uint8_t *type)
634 56324ebe 2022-07-14 thomas {
635 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
636 56324ebe 2022-07-14 thomas char *h = NULL;
637 56324ebe 2022-07-14 thomas
638 56324ebe 2022-07-14 thomas if (asprintf(&h, "Content-type: %s\r\n\r\n", type) == -1) {
639 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
640 56324ebe 2022-07-14 thomas goto done;
641 56324ebe 2022-07-14 thomas }
642 56324ebe 2022-07-14 thomas
643 56324ebe 2022-07-14 thomas fcgi_gen_response(c, h);
644 56324ebe 2022-07-14 thomas done:
645 56324ebe 2022-07-14 thomas free(h);
646 56324ebe 2022-07-14 thomas
647 56324ebe 2022-07-14 thomas return error;
648 56324ebe 2022-07-14 thomas }
649 56324ebe 2022-07-14 thomas
650 56324ebe 2022-07-14 thomas const struct got_error *
651 56324ebe 2022-07-14 thomas gotweb_render_content_type_file(struct request *c, const uint8_t *type,
652 56324ebe 2022-07-14 thomas char *file)
653 56324ebe 2022-07-14 thomas {
654 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
655 56324ebe 2022-07-14 thomas char *h = NULL;
656 56324ebe 2022-07-14 thomas
657 56324ebe 2022-07-14 thomas if (asprintf(&h, "Content-type: %s\r\n"
658 56324ebe 2022-07-14 thomas "Content-disposition: attachment; filename=%s\r\n\r\n",
659 56324ebe 2022-07-14 thomas type, file) == -1) {
660 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
661 56324ebe 2022-07-14 thomas goto done;
662 56324ebe 2022-07-14 thomas }
663 56324ebe 2022-07-14 thomas
664 56324ebe 2022-07-14 thomas fcgi_gen_response(c, h);
665 56324ebe 2022-07-14 thomas done:
666 56324ebe 2022-07-14 thomas free(h);
667 56324ebe 2022-07-14 thomas
668 56324ebe 2022-07-14 thomas return error;
669 56324ebe 2022-07-14 thomas }
670 56324ebe 2022-07-14 thomas
671 56324ebe 2022-07-14 thomas static const struct got_error *
672 56324ebe 2022-07-14 thomas gotweb_render_header(struct request *c)
673 56324ebe 2022-07-14 thomas {
674 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
675 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
676 56324ebe 2022-07-14 thomas struct querystring *qs = c->t->qs;
677 56324ebe 2022-07-14 thomas char *title = NULL, *droot = NULL, *css = NULL, *gotlink = NULL;
678 56324ebe 2022-07-14 thomas char *gotimg = NULL, *sitelink = NULL, *summlink = NULL;
679 56324ebe 2022-07-14 thomas
680 56324ebe 2022-07-14 thomas if (strlen(c->document_root) > 0) {
681 56324ebe 2022-07-14 thomas if (asprintf(&droot, "/%s/", c->document_root) == -1) {
682 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
683 56324ebe 2022-07-14 thomas goto done;
684 56324ebe 2022-07-14 thomas }
685 56324ebe 2022-07-14 thomas } else {
686 56324ebe 2022-07-14 thomas if (asprintf(&droot, "/") == -1) {
687 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
688 56324ebe 2022-07-14 thomas goto done;
689 56324ebe 2022-07-14 thomas }
690 56324ebe 2022-07-14 thomas }
691 56324ebe 2022-07-14 thomas
692 56324ebe 2022-07-14 thomas if (asprintf(&title, "<title>%s</title>\n", srv->site_name) == -1) {
693 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
694 56324ebe 2022-07-14 thomas goto done;
695 56324ebe 2022-07-14 thomas }
696 56324ebe 2022-07-14 thomas if (asprintf(&css,
697 56324ebe 2022-07-14 thomas "<link rel='stylesheet' type='text/css' href='%s%s'/>\n",
698 56324ebe 2022-07-14 thomas droot, srv->custom_css) == -1) {
699 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
700 56324ebe 2022-07-14 thomas goto done;
701 56324ebe 2022-07-14 thomas }
702 56324ebe 2022-07-14 thomas if (asprintf(&gotlink, "<a href='%s' target='_sotd'>",
703 56324ebe 2022-07-14 thomas srv->logo_url) == -1) {
704 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
705 56324ebe 2022-07-14 thomas goto done;
706 56324ebe 2022-07-14 thomas }
707 56324ebe 2022-07-14 thomas if (asprintf(&gotimg, "<img src='%s%s' alt='logo' id='logo'/></a>",
708 56324ebe 2022-07-14 thomas droot, srv->logo) == -1) {
709 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
710 56324ebe 2022-07-14 thomas goto done;
711 56324ebe 2022-07-14 thomas }
712 56324ebe 2022-07-14 thomas if (asprintf(&sitelink, "<a href='/%s?index_page=%d' "
713 56324ebe 2022-07-14 thomas "alt='sitelink'>%s</a>", c->document_root, qs->index_page,
714 56324ebe 2022-07-14 thomas srv->site_link) == -1) {
715 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
716 56324ebe 2022-07-14 thomas goto done;
717 56324ebe 2022-07-14 thomas }
718 56324ebe 2022-07-14 thomas if (asprintf(&summlink, "<a href='/%s?index_page=%d&path=%s"
719 56324ebe 2022-07-14 thomas "&action=summary' alt='summlink'>%s</a>", c->document_root,
720 56324ebe 2022-07-14 thomas qs->index_page, qs->path, qs->path) == -1) {
721 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf", __func__);
722 56324ebe 2022-07-14 thomas goto done;
723 56324ebe 2022-07-14 thomas }
724 56324ebe 2022-07-14 thomas
725 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<!DOCTYPE html>\n<head>\n") == -1)
726 56324ebe 2022-07-14 thomas goto done;
727 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, title) == -1)
728 56324ebe 2022-07-14 thomas goto done;
729 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<meta name='viewport' "
730 56324ebe 2022-07-14 thomas "content='initial-scale=.75, user-scalable=yes'/>\n") == -1)
731 56324ebe 2022-07-14 thomas goto done;
732 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<meta charset='utf-8'/>\n") == -1)
733 56324ebe 2022-07-14 thomas goto done;
734 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<meta name='msapplication-TileColor' "
735 56324ebe 2022-07-14 thomas "content='#da532c'/>\n") == -1)
736 56324ebe 2022-07-14 thomas goto done;
737 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
738 56324ebe 2022-07-14 thomas "<meta name='theme-color' content='#ffffff'/>\n") == -1)
739 56324ebe 2022-07-14 thomas goto done;
740 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<link rel='apple-touch-icon' sizes='180x180' "
741 56324ebe 2022-07-14 thomas "href='/apple-touch-icon.png'/>\n") == -1)
742 56324ebe 2022-07-14 thomas goto done;
743 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
744 56324ebe 2022-07-14 thomas "<link rel='icon' type='image/png' sizes='32x32' "
745 56324ebe 2022-07-14 thomas "href='/favicon-32x32.png'/>\n") == -1)
746 56324ebe 2022-07-14 thomas goto done;
747 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<link rel='icon' type='image/png' "
748 56324ebe 2022-07-14 thomas "sizes='16x16' href='/favicon-16x16.png'/>\n") == -1)
749 56324ebe 2022-07-14 thomas goto done;
750 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<link rel='manifest' "
751 56324ebe 2022-07-14 thomas "href='/site.webmanifest'/>\n") == -1)
752 56324ebe 2022-07-14 thomas goto done;
753 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<link rel='mask-icon' "
754 56324ebe 2022-07-14 thomas "href='/safari-pinned-tab.svg'/>\n") == -1)
755 56324ebe 2022-07-14 thomas goto done;
756 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, css) == -1)
757 56324ebe 2022-07-14 thomas goto done;
758 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</head>\n<body>\n<div id='gw_body'>\n") == -1)
759 56324ebe 2022-07-14 thomas goto done;
760 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
761 56324ebe 2022-07-14 thomas "<div id='header'>\n<div id='got_link'>") == -1)
762 56324ebe 2022-07-14 thomas goto done;
763 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, gotlink) == -1)
764 56324ebe 2022-07-14 thomas goto done;
765 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, gotimg) == -1)
766 56324ebe 2022-07-14 thomas goto done;
767 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n</div>\n") == -1)
768 56324ebe 2022-07-14 thomas goto done;
769 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
770 56324ebe 2022-07-14 thomas "<div id='site_path'>\n<div id='site_link'>") == -1)
771 56324ebe 2022-07-14 thomas goto done;
772 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, sitelink) == -1)
773 56324ebe 2022-07-14 thomas goto done;
774 56324ebe 2022-07-14 thomas if (qs != NULL) {
775 56324ebe 2022-07-14 thomas if (qs->path != NULL) {
776 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " / ") == -1)
777 56324ebe 2022-07-14 thomas goto done;
778 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, summlink) == -1)
779 56324ebe 2022-07-14 thomas goto done;
780 56324ebe 2022-07-14 thomas }
781 56324ebe 2022-07-14 thomas if (qs->action != INDEX) {
782 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " / ") == -1)
783 56324ebe 2022-07-14 thomas goto done;
784 56324ebe 2022-07-14 thomas switch(qs->action) {
785 56324ebe 2022-07-14 thomas case(BLAME):
786 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "blame") == -1)
787 56324ebe 2022-07-14 thomas goto done;
788 56324ebe 2022-07-14 thomas break;
789 56324ebe 2022-07-14 thomas case(BRIEFS):
790 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "briefs") == -1)
791 56324ebe 2022-07-14 thomas goto done;
792 56324ebe 2022-07-14 thomas break;
793 56324ebe 2022-07-14 thomas case(COMMITS):
794 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "commits") == -1)
795 56324ebe 2022-07-14 thomas goto done;
796 56324ebe 2022-07-14 thomas break;
797 56324ebe 2022-07-14 thomas case(DIFF):
798 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "diff") == -1)
799 56324ebe 2022-07-14 thomas goto done;
800 56324ebe 2022-07-14 thomas break;
801 56324ebe 2022-07-14 thomas case(SUMMARY):
802 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "summary") == -1)
803 56324ebe 2022-07-14 thomas goto done;
804 56324ebe 2022-07-14 thomas break;
805 56324ebe 2022-07-14 thomas case(TAG):
806 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "tag") == -1)
807 56324ebe 2022-07-14 thomas goto done;
808 56324ebe 2022-07-14 thomas break;
809 56324ebe 2022-07-14 thomas case(TAGS):
810 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "tags") == -1)
811 56324ebe 2022-07-14 thomas goto done;
812 56324ebe 2022-07-14 thomas break;
813 56324ebe 2022-07-14 thomas case(TREE):
814 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "tree") == -1)
815 56324ebe 2022-07-14 thomas goto done;
816 56324ebe 2022-07-14 thomas break;
817 56324ebe 2022-07-14 thomas default:
818 56324ebe 2022-07-14 thomas break;
819 56324ebe 2022-07-14 thomas }
820 56324ebe 2022-07-14 thomas }
821 56324ebe 2022-07-14 thomas
822 56324ebe 2022-07-14 thomas }
823 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n</div>\n<div id='content'>\n");
824 56324ebe 2022-07-14 thomas done:
825 56324ebe 2022-07-14 thomas free(title);
826 56324ebe 2022-07-14 thomas free(droot);
827 56324ebe 2022-07-14 thomas free(css);
828 56324ebe 2022-07-14 thomas free(gotlink);
829 56324ebe 2022-07-14 thomas free(gotimg);
830 56324ebe 2022-07-14 thomas free(sitelink);
831 56324ebe 2022-07-14 thomas free(summlink);
832 56324ebe 2022-07-14 thomas
833 56324ebe 2022-07-14 thomas return error;
834 56324ebe 2022-07-14 thomas }
835 56324ebe 2022-07-14 thomas
836 56324ebe 2022-07-14 thomas static const struct got_error *
837 56324ebe 2022-07-14 thomas gotweb_render_footer(struct request *c)
838 56324ebe 2022-07-14 thomas {
839 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
840 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
841 56324ebe 2022-07-14 thomas char *siteowner = NULL;
842 56324ebe 2022-07-14 thomas
843 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='site_owner_wrapper'>\n") == -1)
844 56324ebe 2022-07-14 thomas goto done;
845 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='site_owner'>") == -1)
846 56324ebe 2022-07-14 thomas goto done;
847 56324ebe 2022-07-14 thomas if (srv->show_site_owner) {
848 56324ebe 2022-07-14 thomas error = gotweb_escape_html(&siteowner, srv->site_owner);
849 56324ebe 2022-07-14 thomas if (error)
850 56324ebe 2022-07-14 thomas goto done;
851 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, siteowner) == -1)
852 56324ebe 2022-07-14 thomas goto done;
853 56324ebe 2022-07-14 thomas } else
854 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&nbsp;") == -1)
855 56324ebe 2022-07-14 thomas goto done;
856 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n</div>\n</div>\n</body>\n</html>");
857 56324ebe 2022-07-14 thomas done:
858 56324ebe 2022-07-14 thomas free(siteowner);
859 56324ebe 2022-07-14 thomas
860 56324ebe 2022-07-14 thomas return error;
861 56324ebe 2022-07-14 thomas }
862 56324ebe 2022-07-14 thomas
863 56324ebe 2022-07-14 thomas static const struct got_error *
864 56324ebe 2022-07-14 thomas gotweb_render_navs(struct request *c)
865 56324ebe 2022-07-14 thomas {
866 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
867 56324ebe 2022-07-14 thomas struct transport *t = c->t;
868 56324ebe 2022-07-14 thomas struct querystring *qs = t->qs;
869 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
870 56324ebe 2022-07-14 thomas char *nhref = NULL, *phref = NULL;
871 56324ebe 2022-07-14 thomas int disp = 0;
872 56324ebe 2022-07-14 thomas
873 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='np_wrapper'>\n") == -1)
874 56324ebe 2022-07-14 thomas goto done;
875 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='nav_prev'>") == -1)
876 56324ebe 2022-07-14 thomas goto done;
877 56324ebe 2022-07-14 thomas
878 56324ebe 2022-07-14 thomas switch(qs->action) {
879 56324ebe 2022-07-14 thomas case INDEX:
880 56324ebe 2022-07-14 thomas if (qs->index_page > 0) {
881 56324ebe 2022-07-14 thomas if (asprintf(&phref, "index_page=%d",
882 56324ebe 2022-07-14 thomas qs->index_page - 1) == -1) {
883 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf",
884 56324ebe 2022-07-14 thomas __func__);
885 56324ebe 2022-07-14 thomas goto done;
886 56324ebe 2022-07-14 thomas }
887 56324ebe 2022-07-14 thomas disp = 1;
888 56324ebe 2022-07-14 thomas }
889 56324ebe 2022-07-14 thomas break;
890 56324ebe 2022-07-14 thomas case BRIEFS:
891 56324ebe 2022-07-14 thomas if (t->prev_id && qs->commit != NULL &&
892 56324ebe 2022-07-14 thomas strcmp(qs->commit, t->prev_id) != 0) {
893 56324ebe 2022-07-14 thomas if (asprintf(&phref, "index_page=%d&path=%s&page=%d"
894 56324ebe 2022-07-14 thomas "&action=briefs&commit=%s&headref=%s",
895 56324ebe 2022-07-14 thomas qs->index_page, qs->path, qs->page - 1, t->prev_id,
896 56324ebe 2022-07-14 thomas qs->headref) == -1) {
897 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf",
898 56324ebe 2022-07-14 thomas __func__);
899 56324ebe 2022-07-14 thomas goto done;
900 56324ebe 2022-07-14 thomas }
901 56324ebe 2022-07-14 thomas disp = 1;
902 56324ebe 2022-07-14 thomas }
903 56324ebe 2022-07-14 thomas break;
904 56324ebe 2022-07-14 thomas case COMMITS:
905 56324ebe 2022-07-14 thomas if (t->prev_id && qs->commit != NULL &&
906 56324ebe 2022-07-14 thomas strcmp(qs->commit, t->prev_id) != 0) {
907 56324ebe 2022-07-14 thomas if (asprintf(&phref, "index_page=%d&path=%s&page=%d"
908 56324ebe 2022-07-14 thomas "&action=commits&commit=%s&headref=%s&folder=%s"
909 56324ebe 2022-07-14 thomas "&file=%s",
910 56324ebe 2022-07-14 thomas qs->index_page, qs->path, qs->page - 1, t->prev_id,
911 56324ebe 2022-07-14 thomas qs->headref, qs->folder ? qs->folder : "",
912 56324ebe 2022-07-14 thomas qs->file ? qs->file : "") == -1) {
913 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf",
914 56324ebe 2022-07-14 thomas __func__);
915 56324ebe 2022-07-14 thomas goto done;
916 56324ebe 2022-07-14 thomas }
917 56324ebe 2022-07-14 thomas disp = 1;
918 56324ebe 2022-07-14 thomas }
919 56324ebe 2022-07-14 thomas break;
920 56324ebe 2022-07-14 thomas case TAGS:
921 56324ebe 2022-07-14 thomas if (t->prev_id && qs->commit != NULL &&
922 56324ebe 2022-07-14 thomas strcmp(qs->commit, t->prev_id) != 0) {
923 56324ebe 2022-07-14 thomas if (asprintf(&phref, "index_page=%d&path=%s&page=%d"
924 56324ebe 2022-07-14 thomas "&action=tags&commit=%s&headref=%s",
925 56324ebe 2022-07-14 thomas qs->index_page, qs->path, qs->page - 1, t->prev_id,
926 56324ebe 2022-07-14 thomas qs->headref) == -1) {
927 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf",
928 56324ebe 2022-07-14 thomas __func__);
929 56324ebe 2022-07-14 thomas goto done;
930 56324ebe 2022-07-14 thomas }
931 56324ebe 2022-07-14 thomas disp = 1;
932 56324ebe 2022-07-14 thomas }
933 56324ebe 2022-07-14 thomas break;
934 56324ebe 2022-07-14 thomas default:
935 56324ebe 2022-07-14 thomas disp = 0;
936 56324ebe 2022-07-14 thomas break;
937 56324ebe 2022-07-14 thomas }
938 56324ebe 2022-07-14 thomas
939 56324ebe 2022-07-14 thomas if (disp) {
940 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?") == -1)
941 56324ebe 2022-07-14 thomas goto done;
942 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, phref) == -1)
943 56324ebe 2022-07-14 thomas goto done;
944 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>Previous</a>") == -1)
945 56324ebe 2022-07-14 thomas goto done;
946 56324ebe 2022-07-14 thomas }
947 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
948 56324ebe 2022-07-14 thomas goto done;
949 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='nav_next'>") == -1)
950 56324ebe 2022-07-14 thomas goto done;
951 56324ebe 2022-07-14 thomas
952 56324ebe 2022-07-14 thomas disp = 0;
953 56324ebe 2022-07-14 thomas
954 56324ebe 2022-07-14 thomas switch(qs->action) {
955 56324ebe 2022-07-14 thomas case INDEX:
956 56324ebe 2022-07-14 thomas if (t->next_disp == srv->max_repos_display &&
957 56324ebe 2022-07-14 thomas t->repos_total != (qs->index_page + 1) *
958 56324ebe 2022-07-14 thomas srv->max_repos_display) {
959 56324ebe 2022-07-14 thomas if (asprintf(&nhref, "index_page=%d",
960 56324ebe 2022-07-14 thomas qs->index_page + 1) == -1) {
961 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf",
962 56324ebe 2022-07-14 thomas __func__);
963 56324ebe 2022-07-14 thomas goto done;
964 56324ebe 2022-07-14 thomas }
965 56324ebe 2022-07-14 thomas disp = 1;
966 56324ebe 2022-07-14 thomas }
967 56324ebe 2022-07-14 thomas break;
968 56324ebe 2022-07-14 thomas case BRIEFS:
969 56324ebe 2022-07-14 thomas if (t->next_id) {
970 56324ebe 2022-07-14 thomas if (asprintf(&nhref, "index_page=%d&path=%s&page=%d"
971 56324ebe 2022-07-14 thomas "&action=briefs&commit=%s&headref=%s",
972 56324ebe 2022-07-14 thomas qs->index_page, qs->path, qs->page + 1, t->next_id,
973 56324ebe 2022-07-14 thomas qs->headref) == -1) {
974 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf",
975 56324ebe 2022-07-14 thomas __func__);
976 56324ebe 2022-07-14 thomas goto done;
977 56324ebe 2022-07-14 thomas }
978 56324ebe 2022-07-14 thomas disp = 1;
979 56324ebe 2022-07-14 thomas }
980 56324ebe 2022-07-14 thomas break;
981 56324ebe 2022-07-14 thomas case COMMITS:
982 56324ebe 2022-07-14 thomas if (t->next_id) {
983 56324ebe 2022-07-14 thomas if (asprintf(&nhref, "index_page=%d&path=%s&page=%d"
984 56324ebe 2022-07-14 thomas "&action=commits&commit=%s&headref=%s&folder=%s"
985 56324ebe 2022-07-14 thomas "&file=%s",
986 56324ebe 2022-07-14 thomas qs->index_page, qs->path, qs->page + 1, t->next_id,
987 56324ebe 2022-07-14 thomas qs->headref, qs->folder ? qs->folder : "",
988 56324ebe 2022-07-14 thomas qs->file ? qs->file : "") == -1) {
989 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf",
990 56324ebe 2022-07-14 thomas __func__);
991 56324ebe 2022-07-14 thomas goto done;
992 56324ebe 2022-07-14 thomas }
993 56324ebe 2022-07-14 thomas disp = 1;
994 56324ebe 2022-07-14 thomas }
995 56324ebe 2022-07-14 thomas break;
996 56324ebe 2022-07-14 thomas case TAGS:
997 56324ebe 2022-07-14 thomas if (t->next_id) {
998 56324ebe 2022-07-14 thomas if (asprintf(&nhref, "index_page=%d&path=%s&page=%d"
999 56324ebe 2022-07-14 thomas "&action=tags&commit=%s&headref=%s",
1000 56324ebe 2022-07-14 thomas qs->index_page, qs->path, qs->page + 1, t->next_id,
1001 56324ebe 2022-07-14 thomas qs->headref) == -1) {
1002 56324ebe 2022-07-14 thomas error = got_error_from_errno2("%s: asprintf",
1003 56324ebe 2022-07-14 thomas __func__);
1004 56324ebe 2022-07-14 thomas goto done;
1005 56324ebe 2022-07-14 thomas }
1006 56324ebe 2022-07-14 thomas disp = 1;
1007 56324ebe 2022-07-14 thomas }
1008 56324ebe 2022-07-14 thomas break;
1009 56324ebe 2022-07-14 thomas default:
1010 56324ebe 2022-07-14 thomas disp = 0;
1011 56324ebe 2022-07-14 thomas break;
1012 56324ebe 2022-07-14 thomas }
1013 56324ebe 2022-07-14 thomas if (disp) {
1014 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?") == -1)
1015 56324ebe 2022-07-14 thomas goto done;
1016 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, nhref) == -1)
1017 56324ebe 2022-07-14 thomas goto done;
1018 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>Next</a>") == -1)
1019 56324ebe 2022-07-14 thomas goto done;
1020 56324ebe 2022-07-14 thomas }
1021 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1022 56324ebe 2022-07-14 thomas done:
1023 56324ebe 2022-07-14 thomas free(t->next_id);
1024 56324ebe 2022-07-14 thomas t->next_id = NULL;
1025 56324ebe 2022-07-14 thomas free(t->prev_id);
1026 56324ebe 2022-07-14 thomas t->prev_id = NULL;
1027 56324ebe 2022-07-14 thomas free(phref);
1028 56324ebe 2022-07-14 thomas free(nhref);
1029 56324ebe 2022-07-14 thomas return error;
1030 56324ebe 2022-07-14 thomas }
1031 56324ebe 2022-07-14 thomas
1032 56324ebe 2022-07-14 thomas static const struct got_error *
1033 56324ebe 2022-07-14 thomas gotweb_render_index(struct request *c)
1034 56324ebe 2022-07-14 thomas {
1035 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
1036 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
1037 56324ebe 2022-07-14 thomas struct transport *t = c->t;
1038 56324ebe 2022-07-14 thomas struct querystring *qs = t->qs;
1039 56324ebe 2022-07-14 thomas struct repo_dir *repo_dir = NULL;
1040 56324ebe 2022-07-14 thomas DIR *d;
1041 56324ebe 2022-07-14 thomas struct dirent **sd_dent;
1042 56324ebe 2022-07-14 thomas char *c_path = NULL;
1043 56324ebe 2022-07-14 thomas struct stat st;
1044 56324ebe 2022-07-14 thomas unsigned int d_cnt, d_i, d_disp = 0;
1045 56324ebe 2022-07-14 thomas
1046 56324ebe 2022-07-14 thomas d = opendir(srv->repos_path);
1047 56324ebe 2022-07-14 thomas if (d == NULL) {
1048 56324ebe 2022-07-14 thomas error = got_error_from_errno2("opendir", srv->repos_path);
1049 56324ebe 2022-07-14 thomas return error;
1050 56324ebe 2022-07-14 thomas }
1051 56324ebe 2022-07-14 thomas
1052 56324ebe 2022-07-14 thomas d_cnt = scandir(srv->repos_path, &sd_dent, NULL, alphasort);
1053 56324ebe 2022-07-14 thomas if (d_cnt == -1) {
1054 56324ebe 2022-07-14 thomas error = got_error_from_errno2("scandir", srv->repos_path);
1055 56324ebe 2022-07-14 thomas goto done;
1056 56324ebe 2022-07-14 thomas }
1057 56324ebe 2022-07-14 thomas
1058 56324ebe 2022-07-14 thomas /* get total count of repos */
1059 56324ebe 2022-07-14 thomas for (d_i = 0; d_i < d_cnt; d_i++) {
1060 56324ebe 2022-07-14 thomas if (strcmp(sd_dent[d_i]->d_name, ".") == 0 ||
1061 56324ebe 2022-07-14 thomas strcmp(sd_dent[d_i]->d_name, "..") == 0)
1062 56324ebe 2022-07-14 thomas continue;
1063 56324ebe 2022-07-14 thomas
1064 56324ebe 2022-07-14 thomas if (asprintf(&c_path, "%s/%s", srv->repos_path,
1065 56324ebe 2022-07-14 thomas sd_dent[d_i]->d_name) == -1) {
1066 56324ebe 2022-07-14 thomas error = got_error_from_errno("asprintf");
1067 56324ebe 2022-07-14 thomas return error;
1068 56324ebe 2022-07-14 thomas }
1069 56324ebe 2022-07-14 thomas
1070 56324ebe 2022-07-14 thomas if (lstat(c_path, &st) == 0 && S_ISDIR(st.st_mode) &&
1071 56324ebe 2022-07-14 thomas !got_path_dir_is_empty(c_path))
1072 56324ebe 2022-07-14 thomas t->repos_total++;
1073 56324ebe 2022-07-14 thomas free(c_path);
1074 56324ebe 2022-07-14 thomas c_path = NULL;
1075 56324ebe 2022-07-14 thomas }
1076 56324ebe 2022-07-14 thomas
1077 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='index_header'>\n") == -1)
1078 56324ebe 2022-07-14 thomas goto done;
1079 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1080 56324ebe 2022-07-14 thomas "<div id='index_header_project'>Project</div>\n") == -1)
1081 56324ebe 2022-07-14 thomas goto done;
1082 56324ebe 2022-07-14 thomas if (srv->show_repo_description)
1083 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='index_header_description'>"
1084 56324ebe 2022-07-14 thomas "Description</div>\n") == -1)
1085 56324ebe 2022-07-14 thomas goto done;
1086 56324ebe 2022-07-14 thomas if (srv->show_repo_owner)
1087 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='index_header_owner'>"
1088 56324ebe 2022-07-14 thomas "Owner</div>\n") == -1)
1089 56324ebe 2022-07-14 thomas goto done;
1090 56324ebe 2022-07-14 thomas if (srv->show_repo_age)
1091 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='index_header_age'>"
1092 56324ebe 2022-07-14 thomas "Last Change</div>\n") == -1)
1093 56324ebe 2022-07-14 thomas goto done;
1094 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1095 56324ebe 2022-07-14 thomas goto done;
1096 56324ebe 2022-07-14 thomas
1097 56324ebe 2022-07-14 thomas for (d_i = 0; d_i < d_cnt; d_i++) {
1098 56324ebe 2022-07-14 thomas if (srv->max_repos > 0 && (d_i - 2) == srv->max_repos)
1099 56324ebe 2022-07-14 thomas break; /* account for parent and self */
1100 56324ebe 2022-07-14 thomas
1101 56324ebe 2022-07-14 thomas if (strcmp(sd_dent[d_i]->d_name, ".") == 0 ||
1102 56324ebe 2022-07-14 thomas strcmp(sd_dent[d_i]->d_name, "..") == 0)
1103 56324ebe 2022-07-14 thomas continue;
1104 56324ebe 2022-07-14 thomas
1105 56324ebe 2022-07-14 thomas if (qs->index_page > 0 && (qs->index_page *
1106 56324ebe 2022-07-14 thomas srv->max_repos_display) > t->prev_disp) {
1107 56324ebe 2022-07-14 thomas t->prev_disp++;
1108 56324ebe 2022-07-14 thomas continue;
1109 56324ebe 2022-07-14 thomas }
1110 56324ebe 2022-07-14 thomas
1111 56324ebe 2022-07-14 thomas error = gotweb_init_repo_dir(&repo_dir, sd_dent[d_i]->d_name);
1112 56324ebe 2022-07-14 thomas if (error)
1113 56324ebe 2022-07-14 thomas goto done;
1114 56324ebe 2022-07-14 thomas
1115 56324ebe 2022-07-14 thomas error = gotweb_load_got_path(c, repo_dir);
1116 56324ebe 2022-07-14 thomas if (error && error->code == GOT_ERR_NOT_GIT_REPO) {
1117 56324ebe 2022-07-14 thomas error = NULL;
1118 56324ebe 2022-07-14 thomas continue;
1119 56324ebe 2022-07-14 thomas }
1120 56324ebe 2022-07-14 thomas else if (error && error->code != GOT_ERR_LONELY_PACKIDX)
1121 56324ebe 2022-07-14 thomas goto done;
1122 56324ebe 2022-07-14 thomas
1123 56324ebe 2022-07-14 thomas if (lstat(repo_dir->path, &st) == 0 &&
1124 56324ebe 2022-07-14 thomas S_ISDIR(st.st_mode) &&
1125 56324ebe 2022-07-14 thomas !got_path_dir_is_empty(repo_dir->path))
1126 56324ebe 2022-07-14 thomas goto render;
1127 56324ebe 2022-07-14 thomas else {
1128 56324ebe 2022-07-14 thomas gotweb_free_repo_dir(repo_dir);
1129 56324ebe 2022-07-14 thomas repo_dir = NULL;
1130 56324ebe 2022-07-14 thomas continue;
1131 56324ebe 2022-07-14 thomas }
1132 56324ebe 2022-07-14 thomas render:
1133 56324ebe 2022-07-14 thomas d_disp++;
1134 56324ebe 2022-07-14 thomas t->prev_disp++;
1135 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='index_wrapper'>\n") == -1)
1136 56324ebe 2022-07-14 thomas goto done;
1137 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='index_project'>") == -1)
1138 56324ebe 2022-07-14 thomas goto done;
1139 56324ebe 2022-07-14 thomas
1140 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1141 56324ebe 2022-07-14 thomas goto done;
1142 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1143 56324ebe 2022-07-14 thomas goto done;
1144 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1145 56324ebe 2022-07-14 thomas goto done;
1146 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1147 56324ebe 2022-07-14 thomas goto done;
1148 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=summary'>") == -1)
1149 56324ebe 2022-07-14 thomas goto done;
1150 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1151 56324ebe 2022-07-14 thomas goto done;
1152 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1153 56324ebe 2022-07-14 thomas goto done;
1154 56324ebe 2022-07-14 thomas
1155 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1156 56324ebe 2022-07-14 thomas goto done;
1157 56324ebe 2022-07-14 thomas
1158 56324ebe 2022-07-14 thomas if (srv->show_repo_description) {
1159 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1160 56324ebe 2022-07-14 thomas "<div id='index_project_description'>\n") == -1)
1161 56324ebe 2022-07-14 thomas goto done;
1162 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->description) == -1)
1163 56324ebe 2022-07-14 thomas goto done;
1164 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1165 56324ebe 2022-07-14 thomas goto done;
1166 56324ebe 2022-07-14 thomas }
1167 56324ebe 2022-07-14 thomas
1168 56324ebe 2022-07-14 thomas if (srv->show_repo_owner) {
1169 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1170 56324ebe 2022-07-14 thomas "<div id='index_project_owner'>") == -1)
1171 56324ebe 2022-07-14 thomas goto done;
1172 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->owner) == -1)
1173 56324ebe 2022-07-14 thomas goto done;
1174 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1175 56324ebe 2022-07-14 thomas goto done;
1176 56324ebe 2022-07-14 thomas }
1177 56324ebe 2022-07-14 thomas
1178 56324ebe 2022-07-14 thomas if (srv->show_repo_age) {
1179 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1180 56324ebe 2022-07-14 thomas "<div id='index_project_age'>") == -1)
1181 56324ebe 2022-07-14 thomas goto done;
1182 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->age) == -1)
1183 56324ebe 2022-07-14 thomas goto done;
1184 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1185 56324ebe 2022-07-14 thomas goto done;
1186 56324ebe 2022-07-14 thomas }
1187 56324ebe 2022-07-14 thomas
1188 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs_wrapper'>") == -1)
1189 56324ebe 2022-07-14 thomas goto done;
1190 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs'>") == -1)
1191 56324ebe 2022-07-14 thomas goto done;;
1192 56324ebe 2022-07-14 thomas
1193 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1194 56324ebe 2022-07-14 thomas goto done;
1195 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1196 56324ebe 2022-07-14 thomas goto done;
1197 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1198 56324ebe 2022-07-14 thomas goto done;
1199 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1200 56324ebe 2022-07-14 thomas goto done;
1201 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=summary'>") == -1)
1202 56324ebe 2022-07-14 thomas goto done;
1203 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "summary") == -1)
1204 56324ebe 2022-07-14 thomas goto done;
1205 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a> | ") == -1)
1206 56324ebe 2022-07-14 thomas goto done;
1207 56324ebe 2022-07-14 thomas
1208 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1209 56324ebe 2022-07-14 thomas goto done;
1210 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1211 56324ebe 2022-07-14 thomas goto done;
1212 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1213 56324ebe 2022-07-14 thomas goto done;
1214 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1215 56324ebe 2022-07-14 thomas goto done;
1216 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=briefs'>") == -1)
1217 56324ebe 2022-07-14 thomas goto done;
1218 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "commit briefs") == -1)
1219 56324ebe 2022-07-14 thomas goto done;
1220 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a> | ") == -1)
1221 56324ebe 2022-07-14 thomas goto done;
1222 56324ebe 2022-07-14 thomas
1223 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1224 56324ebe 2022-07-14 thomas goto done;
1225 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1226 56324ebe 2022-07-14 thomas goto done;
1227 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1228 56324ebe 2022-07-14 thomas goto done;
1229 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1230 56324ebe 2022-07-14 thomas goto done;
1231 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=commits'>") == -1)
1232 56324ebe 2022-07-14 thomas goto done;
1233 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "commits") == -1)
1234 56324ebe 2022-07-14 thomas goto done;
1235 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a> | ") == -1)
1236 56324ebe 2022-07-14 thomas goto done;
1237 56324ebe 2022-07-14 thomas
1238 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1239 56324ebe 2022-07-14 thomas goto done;
1240 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1241 56324ebe 2022-07-14 thomas goto done;
1242 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1243 56324ebe 2022-07-14 thomas goto done;
1244 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1245 56324ebe 2022-07-14 thomas goto done;
1246 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=tags'>") == -1)
1247 56324ebe 2022-07-14 thomas goto done;
1248 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "tags") == -1)
1249 56324ebe 2022-07-14 thomas goto done;
1250 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a> | ") == -1)
1251 56324ebe 2022-07-14 thomas goto done;
1252 56324ebe 2022-07-14 thomas
1253 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1254 56324ebe 2022-07-14 thomas goto done;
1255 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1256 56324ebe 2022-07-14 thomas goto done;
1257 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1258 56324ebe 2022-07-14 thomas goto done;
1259 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1260 56324ebe 2022-07-14 thomas goto done;
1261 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=tree'>") == -1)
1262 56324ebe 2022-07-14 thomas goto done;
1263 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "tree") == -1)
1264 56324ebe 2022-07-14 thomas goto done;
1265 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1266 56324ebe 2022-07-14 thomas goto done;
1267 56324ebe 2022-07-14 thomas
1268 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>") == -1)
1269 56324ebe 2022-07-14 thomas goto done;
1270 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1271 56324ebe 2022-07-14 thomas "<div id='dotted_line'></div>\n") == -1)
1272 56324ebe 2022-07-14 thomas goto done;
1273 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1274 56324ebe 2022-07-14 thomas goto done;
1275 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1276 56324ebe 2022-07-14 thomas goto done;
1277 56324ebe 2022-07-14 thomas
1278 56324ebe 2022-07-14 thomas gotweb_free_repo_dir(repo_dir);
1279 56324ebe 2022-07-14 thomas repo_dir = NULL;
1280 56324ebe 2022-07-14 thomas error = got_repo_close(t->repo);
1281 56324ebe 2022-07-14 thomas if (error)
1282 56324ebe 2022-07-14 thomas goto done;
1283 56324ebe 2022-07-14 thomas t->next_disp++;
1284 56324ebe 2022-07-14 thomas if (d_disp == srv->max_repos_display)
1285 56324ebe 2022-07-14 thomas break;
1286 56324ebe 2022-07-14 thomas }
1287 56324ebe 2022-07-14 thomas if (srv->max_repos_display == 0)
1288 56324ebe 2022-07-14 thomas goto div;
1289 56324ebe 2022-07-14 thomas if (srv->max_repos > 0 && srv->max_repos < srv->max_repos_display)
1290 56324ebe 2022-07-14 thomas goto div;
1291 56324ebe 2022-07-14 thomas if (t->repos_total <= srv->max_repos ||
1292 56324ebe 2022-07-14 thomas t->repos_total <= srv->max_repos_display)
1293 56324ebe 2022-07-14 thomas goto div;
1294 56324ebe 2022-07-14 thomas
1295 56324ebe 2022-07-14 thomas error = gotweb_render_navs(c);
1296 56324ebe 2022-07-14 thomas if (error)
1297 56324ebe 2022-07-14 thomas goto done;
1298 56324ebe 2022-07-14 thomas div:
1299 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1300 56324ebe 2022-07-14 thomas done:
1301 56324ebe 2022-07-14 thomas if (d != NULL && closedir(d) == EOF && error == NULL)
1302 56324ebe 2022-07-14 thomas error = got_error_from_errno("closedir");
1303 56324ebe 2022-07-14 thomas return error;
1304 56324ebe 2022-07-14 thomas }
1305 56324ebe 2022-07-14 thomas
1306 56324ebe 2022-07-14 thomas static const struct got_error *
1307 56324ebe 2022-07-14 thomas gotweb_render_blame(struct request *c)
1308 56324ebe 2022-07-14 thomas {
1309 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
1310 56324ebe 2022-07-14 thomas struct transport *t = c->t;
1311 56324ebe 2022-07-14 thomas struct repo_commit *rc = NULL;
1312 56324ebe 2022-07-14 thomas char *age = NULL;
1313 56324ebe 2022-07-14 thomas
1314 56324ebe 2022-07-14 thomas error = got_get_repo_commits(c, 1);
1315 56324ebe 2022-07-14 thomas if (error)
1316 56324ebe 2022-07-14 thomas return error;
1317 56324ebe 2022-07-14 thomas
1318 56324ebe 2022-07-14 thomas rc = TAILQ_FIRST(&t->repo_commits);
1319 56324ebe 2022-07-14 thomas
1320 56324ebe 2022-07-14 thomas error = gotweb_get_time_str(&age, rc->committer_time, TM_LONG);
1321 56324ebe 2022-07-14 thomas if (error)
1322 56324ebe 2022-07-14 thomas goto done;
1323 56324ebe 2022-07-14 thomas
1324 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='blame_title_wrapper'>\n") == -1)
1325 56324ebe 2022-07-14 thomas goto done;
1326 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='blame_title'>Blame</div>\n") == -1)
1327 56324ebe 2022-07-14 thomas goto done;
1328 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1329 56324ebe 2022-07-14 thomas goto done;
1330 56324ebe 2022-07-14 thomas
1331 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='blame_content'>\n") == -1)
1332 56324ebe 2022-07-14 thomas goto done;
1333 56324ebe 2022-07-14 thomas
1334 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='blame_header_wrapper'>\n") == -1)
1335 56324ebe 2022-07-14 thomas goto done;
1336 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='blame_header'>\n") == -1)
1337 56324ebe 2022-07-14 thomas goto done;
1338 56324ebe 2022-07-14 thomas
1339 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age_title'>Date:"
1340 56324ebe 2022-07-14 thomas "</div>\n") == -1)
1341 56324ebe 2022-07-14 thomas goto done;
1342 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age'>") == -1)
1343 56324ebe 2022-07-14 thomas goto done;
1344 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, age ? age : "") == -1)
1345 56324ebe 2022-07-14 thomas goto done;
1346 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1347 56324ebe 2022-07-14 thomas goto done;
1348 56324ebe 2022-07-14 thomas
1349 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_msg_title'>Message:"
1350 56324ebe 2022-07-14 thomas "</div>\n") == -1)
1351 56324ebe 2022-07-14 thomas goto done;
1352 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_msg'>") == -1)
1353 56324ebe 2022-07-14 thomas goto done;
1354 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_msg) == -1)
1355 56324ebe 2022-07-14 thomas goto done;
1356 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1357 56324ebe 2022-07-14 thomas goto done;
1358 56324ebe 2022-07-14 thomas
1359 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1360 56324ebe 2022-07-14 thomas goto done;
1361 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1362 56324ebe 2022-07-14 thomas goto done;
1363 56324ebe 2022-07-14 thomas
1364 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='dotted_line'></div>\n") == -1)
1365 56324ebe 2022-07-14 thomas goto done;
1366 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='blame'>\n") == -1)
1367 56324ebe 2022-07-14 thomas goto done;
1368 56324ebe 2022-07-14 thomas
1369 56324ebe 2022-07-14 thomas error = got_output_file_blame(c);
1370 56324ebe 2022-07-14 thomas if (error)
1371 56324ebe 2022-07-14 thomas goto done;
1372 56324ebe 2022-07-14 thomas
1373 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1374 56324ebe 2022-07-14 thomas done:
1375 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1376 56324ebe 2022-07-14 thomas return error;
1377 56324ebe 2022-07-14 thomas }
1378 56324ebe 2022-07-14 thomas
1379 56324ebe 2022-07-14 thomas static const struct got_error *
1380 56324ebe 2022-07-14 thomas gotweb_render_briefs(struct request *c)
1381 56324ebe 2022-07-14 thomas {
1382 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
1383 56324ebe 2022-07-14 thomas struct repo_commit *rc = NULL;
1384 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
1385 56324ebe 2022-07-14 thomas struct transport *t = c->t;
1386 56324ebe 2022-07-14 thomas struct querystring *qs = t->qs;
1387 56324ebe 2022-07-14 thomas struct repo_dir *repo_dir = t->repo_dir;
1388 56324ebe 2022-07-14 thomas char *smallerthan, *newline;
1389 56324ebe 2022-07-14 thomas char *age = NULL;
1390 56324ebe 2022-07-14 thomas
1391 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='briefs_title_wrapper'>\n") == -1)
1392 56324ebe 2022-07-14 thomas goto done;
1393 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1394 56324ebe 2022-07-14 thomas "<div id='briefs_title'>Commit Briefs</div>\n") == -1)
1395 56324ebe 2022-07-14 thomas goto done;
1396 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1397 56324ebe 2022-07-14 thomas goto done;
1398 56324ebe 2022-07-14 thomas
1399 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='briefs_content'>\n") == -1)
1400 56324ebe 2022-07-14 thomas goto done;
1401 56324ebe 2022-07-14 thomas
1402 56324ebe 2022-07-14 thomas if (qs->action == SUMMARY) {
1403 56324ebe 2022-07-14 thomas qs->action = BRIEFS;
1404 56324ebe 2022-07-14 thomas error = got_get_repo_commits(c, D_MAXSLCOMMDISP);
1405 56324ebe 2022-07-14 thomas } else
1406 56324ebe 2022-07-14 thomas error = got_get_repo_commits(c, srv->max_commits_display);
1407 56324ebe 2022-07-14 thomas if (error)
1408 56324ebe 2022-07-14 thomas goto done;
1409 56324ebe 2022-07-14 thomas
1410 56324ebe 2022-07-14 thomas TAILQ_FOREACH(rc, &t->repo_commits, entry) {
1411 56324ebe 2022-07-14 thomas error = gotweb_get_time_str(&age, rc->committer_time, TM_DIFF);
1412 56324ebe 2022-07-14 thomas if (error)
1413 56324ebe 2022-07-14 thomas goto done;
1414 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='briefs_age'>") == -1)
1415 56324ebe 2022-07-14 thomas goto done;
1416 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, age ? age : "") == -1)
1417 56324ebe 2022-07-14 thomas goto done;
1418 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1419 56324ebe 2022-07-14 thomas goto done;
1420 56324ebe 2022-07-14 thomas
1421 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='briefs_author'>") == -1)
1422 56324ebe 2022-07-14 thomas goto done;
1423 56324ebe 2022-07-14 thomas smallerthan = strchr(rc->author, '<');
1424 56324ebe 2022-07-14 thomas if (smallerthan)
1425 56324ebe 2022-07-14 thomas *smallerthan = '\0';
1426 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->author) == -1)
1427 56324ebe 2022-07-14 thomas goto done;
1428 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1429 56324ebe 2022-07-14 thomas goto done;
1430 56324ebe 2022-07-14 thomas
1431 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='briefs_log'>") == -1)
1432 56324ebe 2022-07-14 thomas goto done;
1433 56324ebe 2022-07-14 thomas newline = strchr(rc->commit_msg, '\n');
1434 56324ebe 2022-07-14 thomas if (newline)
1435 56324ebe 2022-07-14 thomas *newline = '\0';
1436 56324ebe 2022-07-14 thomas
1437 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1438 56324ebe 2022-07-14 thomas goto done;
1439 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1440 56324ebe 2022-07-14 thomas goto done;
1441 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1442 56324ebe 2022-07-14 thomas goto done;
1443 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1444 56324ebe 2022-07-14 thomas goto done;
1445 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=diff&commit=") == -1)
1446 56324ebe 2022-07-14 thomas goto done;
1447 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_id) == -1)
1448 56324ebe 2022-07-14 thomas goto done;
1449 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&headref=") == -1)
1450 56324ebe 2022-07-14 thomas goto done;
1451 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->headref) == -1)
1452 56324ebe 2022-07-14 thomas goto done;
1453 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1454 56324ebe 2022-07-14 thomas goto done;
1455 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_msg) == -1)
1456 56324ebe 2022-07-14 thomas goto done;
1457 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1458 56324ebe 2022-07-14 thomas goto done;
1459 56324ebe 2022-07-14 thomas if (rc->refs_str) {
1460 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1461 56324ebe 2022-07-14 thomas " <span id='refs_str'>(") == -1)
1462 56324ebe 2022-07-14 thomas goto done;
1463 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->refs_str) == -1)
1464 56324ebe 2022-07-14 thomas goto done;
1465 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, ")</span>") == -1)
1466 56324ebe 2022-07-14 thomas goto done;
1467 56324ebe 2022-07-14 thomas }
1468 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1469 56324ebe 2022-07-14 thomas goto done;
1470 56324ebe 2022-07-14 thomas
1471 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs_wrapper'>\n") == -1)
1472 56324ebe 2022-07-14 thomas goto done;
1473 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs'>") == -1)
1474 56324ebe 2022-07-14 thomas goto done;
1475 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1476 56324ebe 2022-07-14 thomas goto done;
1477 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1478 56324ebe 2022-07-14 thomas goto done;
1479 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1480 56324ebe 2022-07-14 thomas goto done;
1481 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1482 56324ebe 2022-07-14 thomas goto done;
1483 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=diff&commit=") == -1)
1484 56324ebe 2022-07-14 thomas goto done;
1485 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_id) == -1)
1486 56324ebe 2022-07-14 thomas goto done;
1487 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&headref=") == -1)
1488 56324ebe 2022-07-14 thomas goto done;
1489 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->headref) == -1)
1490 56324ebe 2022-07-14 thomas goto done;
1491 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1492 56324ebe 2022-07-14 thomas goto done;
1493 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "diff") == -1)
1494 56324ebe 2022-07-14 thomas goto done;
1495 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1496 56324ebe 2022-07-14 thomas goto done;
1497 56324ebe 2022-07-14 thomas
1498 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " | ") == -1)
1499 56324ebe 2022-07-14 thomas goto done;
1500 56324ebe 2022-07-14 thomas
1501 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1502 56324ebe 2022-07-14 thomas goto done;
1503 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1504 56324ebe 2022-07-14 thomas goto done;
1505 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1506 56324ebe 2022-07-14 thomas goto done;
1507 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1508 56324ebe 2022-07-14 thomas goto done;
1509 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=tree&commit=") == -1)
1510 56324ebe 2022-07-14 thomas goto done;
1511 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_id) == -1)
1512 56324ebe 2022-07-14 thomas goto done;
1513 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&headref=") == -1)
1514 56324ebe 2022-07-14 thomas goto done;
1515 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->headref) == -1)
1516 56324ebe 2022-07-14 thomas goto done;
1517 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1518 56324ebe 2022-07-14 thomas goto done;
1519 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "tree") == -1)
1520 56324ebe 2022-07-14 thomas goto done;
1521 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1522 56324ebe 2022-07-14 thomas goto done;
1523 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1524 56324ebe 2022-07-14 thomas goto done;
1525 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1526 56324ebe 2022-07-14 thomas goto done;
1527 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1528 56324ebe 2022-07-14 thomas "<div id='dotted_line'></div>\n") == -1)
1529 56324ebe 2022-07-14 thomas goto done;
1530 56324ebe 2022-07-14 thomas
1531 56324ebe 2022-07-14 thomas free(age);
1532 56324ebe 2022-07-14 thomas age = NULL;
1533 56324ebe 2022-07-14 thomas }
1534 56324ebe 2022-07-14 thomas
1535 56324ebe 2022-07-14 thomas if (t->next_id || t->prev_id) {
1536 56324ebe 2022-07-14 thomas error = gotweb_render_navs(c);
1537 56324ebe 2022-07-14 thomas if (error)
1538 56324ebe 2022-07-14 thomas goto done;
1539 56324ebe 2022-07-14 thomas }
1540 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1541 56324ebe 2022-07-14 thomas done:
1542 56324ebe 2022-07-14 thomas free(age);
1543 56324ebe 2022-07-14 thomas return error;
1544 56324ebe 2022-07-14 thomas }
1545 56324ebe 2022-07-14 thomas
1546 56324ebe 2022-07-14 thomas static const struct got_error *
1547 56324ebe 2022-07-14 thomas gotweb_render_commits(struct request *c)
1548 56324ebe 2022-07-14 thomas {
1549 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
1550 56324ebe 2022-07-14 thomas struct repo_commit *rc = NULL;
1551 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
1552 56324ebe 2022-07-14 thomas struct transport *t = c->t;
1553 56324ebe 2022-07-14 thomas struct querystring *qs = t->qs;
1554 56324ebe 2022-07-14 thomas struct repo_dir *repo_dir = t->repo_dir;
1555 56324ebe 2022-07-14 thomas char *age = NULL, *author = NULL;
1556 56324ebe 2022-07-14 thomas /* int commit_found = 0; */
1557 56324ebe 2022-07-14 thomas
1558 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='commits_title_wrapper'>\n") == -1)
1559 56324ebe 2022-07-14 thomas goto done;
1560 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1561 56324ebe 2022-07-14 thomas "<div id='commits_title'>Commits</div>\n") == -1)
1562 56324ebe 2022-07-14 thomas goto done;
1563 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1564 56324ebe 2022-07-14 thomas goto done;
1565 56324ebe 2022-07-14 thomas
1566 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='commits_content'>\n") == -1)
1567 56324ebe 2022-07-14 thomas goto done;
1568 56324ebe 2022-07-14 thomas
1569 56324ebe 2022-07-14 thomas error = got_get_repo_commits(c, srv->max_commits_display);
1570 56324ebe 2022-07-14 thomas if (error)
1571 56324ebe 2022-07-14 thomas goto done;
1572 56324ebe 2022-07-14 thomas
1573 56324ebe 2022-07-14 thomas TAILQ_FOREACH(rc, &t->repo_commits, entry) {
1574 56324ebe 2022-07-14 thomas error = gotweb_get_time_str(&age, rc->committer_time, TM_LONG);
1575 56324ebe 2022-07-14 thomas if (error)
1576 56324ebe 2022-07-14 thomas goto done;
1577 56324ebe 2022-07-14 thomas error = gotweb_escape_html(&author, rc->author);
1578 56324ebe 2022-07-14 thomas if (error)
1579 56324ebe 2022-07-14 thomas goto done;
1580 56324ebe 2022-07-14 thomas
1581 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1582 56324ebe 2022-07-14 thomas "<div id='commits_header_wrapper'>\n") == -1)
1583 56324ebe 2022-07-14 thomas goto done;
1584 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='commits_header'>\n") == -1)
1585 56324ebe 2022-07-14 thomas goto done;
1586 56324ebe 2022-07-14 thomas
1587 56324ebe 2022-07-14 thomas
1588 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_title'>Commit:"
1589 56324ebe 2022-07-14 thomas "</div>\n") == -1)
1590 56324ebe 2022-07-14 thomas goto done;
1591 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit'>") == -1)
1592 56324ebe 2022-07-14 thomas goto done;
1593 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_id) == -1)
1594 56324ebe 2022-07-14 thomas goto done;
1595 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1596 56324ebe 2022-07-14 thomas goto done;
1597 56324ebe 2022-07-14 thomas
1598 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_author_title'>Author:"
1599 56324ebe 2022-07-14 thomas "</div>\n") == -1)
1600 56324ebe 2022-07-14 thomas goto done;
1601 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_author'>") == -1)
1602 56324ebe 2022-07-14 thomas goto done;
1603 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, author ? author : "") == -1)
1604 56324ebe 2022-07-14 thomas goto done;
1605 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1606 56324ebe 2022-07-14 thomas goto done;
1607 56324ebe 2022-07-14 thomas
1608 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age_title'>Date:"
1609 56324ebe 2022-07-14 thomas "</div>\n") == -1)
1610 56324ebe 2022-07-14 thomas goto done;
1611 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age'>") == -1)
1612 56324ebe 2022-07-14 thomas goto done;
1613 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, age ? age : "") == -1)
1614 56324ebe 2022-07-14 thomas goto done;
1615 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1616 56324ebe 2022-07-14 thomas goto done;
1617 56324ebe 2022-07-14 thomas
1618 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1619 56324ebe 2022-07-14 thomas goto done;
1620 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1621 56324ebe 2022-07-14 thomas goto done;
1622 56324ebe 2022-07-14 thomas
1623 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1624 56324ebe 2022-07-14 thomas "<div id='dotted_line'></div>\n") == -1)
1625 56324ebe 2022-07-14 thomas goto done;
1626 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='commit'>\n") == -1)
1627 56324ebe 2022-07-14 thomas goto done;
1628 56324ebe 2022-07-14 thomas
1629 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_msg) == -1)
1630 56324ebe 2022-07-14 thomas goto done;
1631 56324ebe 2022-07-14 thomas
1632 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1633 56324ebe 2022-07-14 thomas goto done;
1634 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1635 56324ebe 2022-07-14 thomas goto done;
1636 56324ebe 2022-07-14 thomas
1637 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs_wrapper'>\n") == -1)
1638 56324ebe 2022-07-14 thomas goto done;
1639 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs'>") == -1)
1640 56324ebe 2022-07-14 thomas goto done;
1641 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1642 56324ebe 2022-07-14 thomas goto done;
1643 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1644 56324ebe 2022-07-14 thomas goto done;
1645 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1646 56324ebe 2022-07-14 thomas goto done;
1647 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1648 56324ebe 2022-07-14 thomas goto done;
1649 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=diff&commit=") == -1)
1650 56324ebe 2022-07-14 thomas goto done;
1651 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_id) == -1)
1652 56324ebe 2022-07-14 thomas goto done;
1653 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1654 56324ebe 2022-07-14 thomas goto done;
1655 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "diff") == -1)
1656 56324ebe 2022-07-14 thomas goto done;
1657 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1658 56324ebe 2022-07-14 thomas goto done;
1659 56324ebe 2022-07-14 thomas
1660 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " | ") == -1)
1661 56324ebe 2022-07-14 thomas goto done;
1662 56324ebe 2022-07-14 thomas
1663 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1664 56324ebe 2022-07-14 thomas goto done;
1665 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1666 56324ebe 2022-07-14 thomas goto done;
1667 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1668 56324ebe 2022-07-14 thomas goto done;
1669 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
1670 56324ebe 2022-07-14 thomas goto done;
1671 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=tree&commit=") == -1)
1672 56324ebe 2022-07-14 thomas goto done;
1673 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_id) == -1)
1674 56324ebe 2022-07-14 thomas goto done;
1675 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1676 56324ebe 2022-07-14 thomas goto done;
1677 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "tree") == -1)
1678 56324ebe 2022-07-14 thomas goto done;
1679 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1680 56324ebe 2022-07-14 thomas goto done;
1681 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1682 56324ebe 2022-07-14 thomas goto done;
1683 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1684 56324ebe 2022-07-14 thomas goto done;
1685 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1686 56324ebe 2022-07-14 thomas "<div id='dotted_line'></div>\n") == -1)
1687 56324ebe 2022-07-14 thomas goto done;
1688 56324ebe 2022-07-14 thomas free(age);
1689 56324ebe 2022-07-14 thomas age = NULL;
1690 56324ebe 2022-07-14 thomas free(author);
1691 56324ebe 2022-07-14 thomas author = NULL;
1692 56324ebe 2022-07-14 thomas }
1693 56324ebe 2022-07-14 thomas
1694 56324ebe 2022-07-14 thomas if (t->next_id || t->prev_id) {
1695 56324ebe 2022-07-14 thomas error = gotweb_render_navs(c);
1696 56324ebe 2022-07-14 thomas if (error)
1697 56324ebe 2022-07-14 thomas goto done;
1698 56324ebe 2022-07-14 thomas }
1699 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1700 56324ebe 2022-07-14 thomas goto done;
1701 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1702 56324ebe 2022-07-14 thomas done:
1703 56324ebe 2022-07-14 thomas free(age);
1704 56324ebe 2022-07-14 thomas return error;
1705 56324ebe 2022-07-14 thomas }
1706 56324ebe 2022-07-14 thomas
1707 56324ebe 2022-07-14 thomas static const struct got_error *
1708 56324ebe 2022-07-14 thomas gotweb_render_branches(struct request *c)
1709 56324ebe 2022-07-14 thomas {
1710 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
1711 56324ebe 2022-07-14 thomas struct got_reflist_head refs;
1712 56324ebe 2022-07-14 thomas struct got_reflist_entry *re;
1713 56324ebe 2022-07-14 thomas struct transport *t = c->t;
1714 56324ebe 2022-07-14 thomas struct querystring *qs = t->qs;
1715 56324ebe 2022-07-14 thomas struct got_repository *repo = t->repo;
1716 56324ebe 2022-07-14 thomas char *age = NULL;
1717 56324ebe 2022-07-14 thomas
1718 56324ebe 2022-07-14 thomas TAILQ_INIT(&refs);
1719 56324ebe 2022-07-14 thomas
1720 56324ebe 2022-07-14 thomas error = got_ref_list(&refs, repo, "refs/heads",
1721 56324ebe 2022-07-14 thomas got_ref_cmp_by_name, NULL);
1722 56324ebe 2022-07-14 thomas if (error)
1723 56324ebe 2022-07-14 thomas goto done;
1724 56324ebe 2022-07-14 thomas
1725 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='branches_title_wrapper'>\n") == -1)
1726 56324ebe 2022-07-14 thomas goto done;
1727 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1728 56324ebe 2022-07-14 thomas "<div id='branches_title'>Branches</div>\n") == -1)
1729 56324ebe 2022-07-14 thomas goto done;
1730 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1731 56324ebe 2022-07-14 thomas goto done;
1732 56324ebe 2022-07-14 thomas
1733 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='branches_content'>\n") == -1)
1734 56324ebe 2022-07-14 thomas goto done;
1735 56324ebe 2022-07-14 thomas
1736 56324ebe 2022-07-14 thomas TAILQ_FOREACH(re, &refs, entry) {
1737 56324ebe 2022-07-14 thomas char *refname = NULL;
1738 56324ebe 2022-07-14 thomas
1739 56324ebe 2022-07-14 thomas if (got_ref_is_symbolic(re->ref))
1740 56324ebe 2022-07-14 thomas continue;
1741 56324ebe 2022-07-14 thomas
1742 56324ebe 2022-07-14 thomas refname = strdup(got_ref_get_name(re->ref));
1743 56324ebe 2022-07-14 thomas if (refname == NULL) {
1744 56324ebe 2022-07-14 thomas error = got_error_from_errno("strdup");
1745 56324ebe 2022-07-14 thomas goto done;
1746 56324ebe 2022-07-14 thomas }
1747 56324ebe 2022-07-14 thomas if (strncmp(refname, "refs/heads/", 11) != 0)
1748 56324ebe 2022-07-14 thomas continue;
1749 56324ebe 2022-07-14 thomas
1750 56324ebe 2022-07-14 thomas error = got_get_repo_age(&age, c, qs->path, refname,
1751 56324ebe 2022-07-14 thomas TM_DIFF);
1752 56324ebe 2022-07-14 thomas if (error)
1753 56324ebe 2022-07-14 thomas goto done;
1754 56324ebe 2022-07-14 thomas
1755 56324ebe 2022-07-14 thomas if (strncmp(refname, "refs/heads/", 11) == 0)
1756 56324ebe 2022-07-14 thomas refname += 11;
1757 56324ebe 2022-07-14 thomas
1758 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='branches_wrapper'>") == -1)
1759 56324ebe 2022-07-14 thomas goto done;
1760 56324ebe 2022-07-14 thomas
1761 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='branches_age'>") == -1)
1762 56324ebe 2022-07-14 thomas goto done;
1763 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, age ? age : "") == -1)
1764 56324ebe 2022-07-14 thomas goto done;
1765 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1766 56324ebe 2022-07-14 thomas goto done;
1767 56324ebe 2022-07-14 thomas
1768 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='branches_space'>") == -1)
1769 56324ebe 2022-07-14 thomas goto done;
1770 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&nbsp;") == -1)
1771 56324ebe 2022-07-14 thomas goto done;
1772 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1773 56324ebe 2022-07-14 thomas goto done;
1774 56324ebe 2022-07-14 thomas
1775 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='branch'>") == -1)
1776 56324ebe 2022-07-14 thomas goto done;
1777 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1778 56324ebe 2022-07-14 thomas goto done;
1779 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1780 56324ebe 2022-07-14 thomas goto done;
1781 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1782 56324ebe 2022-07-14 thomas goto done;
1783 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->path) == -1)
1784 56324ebe 2022-07-14 thomas goto done;
1785 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=summary&headref=") == -1)
1786 56324ebe 2022-07-14 thomas goto done;
1787 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, refname) == -1)
1788 56324ebe 2022-07-14 thomas goto done;
1789 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1790 56324ebe 2022-07-14 thomas goto done;
1791 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, refname) == -1)
1792 56324ebe 2022-07-14 thomas goto done;
1793 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1794 56324ebe 2022-07-14 thomas goto done;
1795 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1796 56324ebe 2022-07-14 thomas goto done;
1797 56324ebe 2022-07-14 thomas
1798 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs_wrapper'>\n") == -1)
1799 56324ebe 2022-07-14 thomas goto done;
1800 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs'>") == -1)
1801 56324ebe 2022-07-14 thomas goto done;
1802 56324ebe 2022-07-14 thomas
1803 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1804 56324ebe 2022-07-14 thomas goto done;
1805 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1806 56324ebe 2022-07-14 thomas goto done;
1807 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1808 56324ebe 2022-07-14 thomas goto done;
1809 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->path) == -1)
1810 56324ebe 2022-07-14 thomas goto done;
1811 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=summary&headref=") == -1)
1812 56324ebe 2022-07-14 thomas goto done;
1813 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, refname) == -1)
1814 56324ebe 2022-07-14 thomas goto done;
1815 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1816 56324ebe 2022-07-14 thomas goto done;
1817 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "summary") == -1)
1818 56324ebe 2022-07-14 thomas goto done;
1819 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1820 56324ebe 2022-07-14 thomas goto done;
1821 56324ebe 2022-07-14 thomas
1822 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " | ") == -1)
1823 56324ebe 2022-07-14 thomas goto done;
1824 56324ebe 2022-07-14 thomas
1825 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1826 56324ebe 2022-07-14 thomas goto done;
1827 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1828 56324ebe 2022-07-14 thomas goto done;
1829 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1830 56324ebe 2022-07-14 thomas goto done;
1831 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->path) == -1)
1832 56324ebe 2022-07-14 thomas goto done;
1833 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=briefs&headref=") == -1)
1834 56324ebe 2022-07-14 thomas goto done;
1835 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, refname) == -1)
1836 56324ebe 2022-07-14 thomas goto done;
1837 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1838 56324ebe 2022-07-14 thomas goto done;
1839 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "commit briefs") == -1)
1840 56324ebe 2022-07-14 thomas goto done;
1841 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1842 56324ebe 2022-07-14 thomas goto done;
1843 56324ebe 2022-07-14 thomas
1844 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " | ") == -1)
1845 56324ebe 2022-07-14 thomas goto done;
1846 56324ebe 2022-07-14 thomas
1847 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
1848 56324ebe 2022-07-14 thomas goto done;
1849 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
1850 56324ebe 2022-07-14 thomas goto done;
1851 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
1852 56324ebe 2022-07-14 thomas goto done;
1853 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->path) == -1)
1854 56324ebe 2022-07-14 thomas goto done;
1855 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=commits&headref=") == -1)
1856 56324ebe 2022-07-14 thomas goto done;
1857 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, refname) == -1)
1858 56324ebe 2022-07-14 thomas goto done;
1859 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
1860 56324ebe 2022-07-14 thomas goto done;
1861 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "commits") == -1)
1862 56324ebe 2022-07-14 thomas goto done;
1863 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
1864 56324ebe 2022-07-14 thomas goto done;
1865 56324ebe 2022-07-14 thomas
1866 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1867 56324ebe 2022-07-14 thomas goto done;
1868 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1869 56324ebe 2022-07-14 thomas goto done;
1870 56324ebe 2022-07-14 thomas
1871 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1872 56324ebe 2022-07-14 thomas "<div id='dotted_line'></div>\n") == -1)
1873 56324ebe 2022-07-14 thomas goto done;
1874 56324ebe 2022-07-14 thomas
1875 56324ebe 2022-07-14 thomas free(age);
1876 56324ebe 2022-07-14 thomas age = NULL;
1877 56324ebe 2022-07-14 thomas
1878 56324ebe 2022-07-14 thomas }
1879 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1880 56324ebe 2022-07-14 thomas done:
1881 56324ebe 2022-07-14 thomas return error;
1882 56324ebe 2022-07-14 thomas }
1883 56324ebe 2022-07-14 thomas
1884 56324ebe 2022-07-14 thomas static const struct got_error *
1885 56324ebe 2022-07-14 thomas gotweb_render_tree(struct request *c)
1886 56324ebe 2022-07-14 thomas {
1887 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
1888 56324ebe 2022-07-14 thomas struct transport *t = c->t;
1889 56324ebe 2022-07-14 thomas struct repo_commit *rc = NULL;
1890 56324ebe 2022-07-14 thomas char *age = NULL;
1891 56324ebe 2022-07-14 thomas
1892 56324ebe 2022-07-14 thomas error = got_get_repo_commits(c, 1);
1893 56324ebe 2022-07-14 thomas if (error)
1894 56324ebe 2022-07-14 thomas return error;
1895 56324ebe 2022-07-14 thomas
1896 56324ebe 2022-07-14 thomas rc = TAILQ_FIRST(&t->repo_commits);
1897 56324ebe 2022-07-14 thomas
1898 56324ebe 2022-07-14 thomas error = gotweb_get_time_str(&age, rc->committer_time, TM_LONG);
1899 56324ebe 2022-07-14 thomas if (error)
1900 56324ebe 2022-07-14 thomas goto done;
1901 56324ebe 2022-07-14 thomas
1902 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tree_title_wrapper'>\n") == -1)
1903 56324ebe 2022-07-14 thomas goto done;
1904 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tree_title'>Tree</div>\n") == -1)
1905 56324ebe 2022-07-14 thomas goto done;
1906 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1907 56324ebe 2022-07-14 thomas goto done;
1908 56324ebe 2022-07-14 thomas
1909 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tree_content'>\n") == -1)
1910 56324ebe 2022-07-14 thomas goto done;
1911 56324ebe 2022-07-14 thomas
1912 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tree_header_wrapper'>\n") == -1)
1913 56324ebe 2022-07-14 thomas goto done;
1914 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tree_header'>\n") == -1)
1915 56324ebe 2022-07-14 thomas goto done;
1916 56324ebe 2022-07-14 thomas
1917 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_tree_title'>Tree:"
1918 56324ebe 2022-07-14 thomas "</div>\n") == -1)
1919 56324ebe 2022-07-14 thomas goto done;
1920 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_tree'>") == -1)
1921 56324ebe 2022-07-14 thomas goto done;
1922 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->tree_id) == -1)
1923 56324ebe 2022-07-14 thomas goto done;
1924 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1925 56324ebe 2022-07-14 thomas goto done;
1926 56324ebe 2022-07-14 thomas
1927 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age_title'>Date:"
1928 56324ebe 2022-07-14 thomas "</div>\n") == -1)
1929 56324ebe 2022-07-14 thomas goto done;
1930 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age'>") == -1)
1931 56324ebe 2022-07-14 thomas goto done;
1932 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, age ? age : "") == -1)
1933 56324ebe 2022-07-14 thomas goto done;
1934 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1935 56324ebe 2022-07-14 thomas goto done;
1936 56324ebe 2022-07-14 thomas
1937 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_msg_title'>Message:"
1938 56324ebe 2022-07-14 thomas "</div>\n") == -1)
1939 56324ebe 2022-07-14 thomas goto done;
1940 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_msg'>") == -1)
1941 56324ebe 2022-07-14 thomas goto done;
1942 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_msg) == -1)
1943 56324ebe 2022-07-14 thomas goto done;
1944 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1945 56324ebe 2022-07-14 thomas goto done;
1946 56324ebe 2022-07-14 thomas
1947 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1948 56324ebe 2022-07-14 thomas goto done;
1949 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1950 56324ebe 2022-07-14 thomas goto done;
1951 56324ebe 2022-07-14 thomas
1952 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='dotted_line'></div>\n") == -1)
1953 56324ebe 2022-07-14 thomas goto done;
1954 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tree'>\n") == -1)
1955 56324ebe 2022-07-14 thomas goto done;
1956 56324ebe 2022-07-14 thomas
1957 56324ebe 2022-07-14 thomas error = got_output_repo_tree(c);
1958 56324ebe 2022-07-14 thomas if (error)
1959 56324ebe 2022-07-14 thomas goto done;
1960 56324ebe 2022-07-14 thomas
1961 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1962 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
1963 56324ebe 2022-07-14 thomas done:
1964 56324ebe 2022-07-14 thomas return error;
1965 56324ebe 2022-07-14 thomas }
1966 56324ebe 2022-07-14 thomas
1967 56324ebe 2022-07-14 thomas static const struct got_error *
1968 56324ebe 2022-07-14 thomas gotweb_render_diff(struct request *c)
1969 56324ebe 2022-07-14 thomas {
1970 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
1971 56324ebe 2022-07-14 thomas struct transport *t = c->t;
1972 56324ebe 2022-07-14 thomas struct repo_commit *rc = NULL;
1973 56324ebe 2022-07-14 thomas char *age = NULL, *author = NULL;
1974 56324ebe 2022-07-14 thomas
1975 56324ebe 2022-07-14 thomas error = got_get_repo_commits(c, 1);
1976 56324ebe 2022-07-14 thomas if (error)
1977 56324ebe 2022-07-14 thomas return error;
1978 56324ebe 2022-07-14 thomas
1979 56324ebe 2022-07-14 thomas rc = TAILQ_FIRST(&t->repo_commits);
1980 56324ebe 2022-07-14 thomas
1981 56324ebe 2022-07-14 thomas error = gotweb_get_time_str(&age, rc->committer_time, TM_LONG);
1982 56324ebe 2022-07-14 thomas if (error)
1983 56324ebe 2022-07-14 thomas goto done;
1984 56324ebe 2022-07-14 thomas error = gotweb_escape_html(&author, rc->author);
1985 56324ebe 2022-07-14 thomas if (error)
1986 56324ebe 2022-07-14 thomas goto done;
1987 56324ebe 2022-07-14 thomas
1988 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='diff_title_wrapper'>\n") == -1)
1989 56324ebe 2022-07-14 thomas goto done;
1990 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
1991 56324ebe 2022-07-14 thomas "<div id='diff_title'>Commit Diff</div>\n") == -1)
1992 56324ebe 2022-07-14 thomas goto done;
1993 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
1994 56324ebe 2022-07-14 thomas goto done;
1995 56324ebe 2022-07-14 thomas
1996 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='diff_content'>\n") == -1)
1997 56324ebe 2022-07-14 thomas goto done;
1998 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='diff_header_wrapper'>\n") == -1)
1999 56324ebe 2022-07-14 thomas goto done;
2000 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='diff_header'>\n") == -1)
2001 56324ebe 2022-07-14 thomas goto done;
2002 56324ebe 2022-07-14 thomas
2003 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_diff_title'>Diff:"
2004 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2005 56324ebe 2022-07-14 thomas goto done;
2006 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_diff'>") == -1)
2007 56324ebe 2022-07-14 thomas goto done;
2008 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->parent_id) == -1)
2009 56324ebe 2022-07-14 thomas goto done;
2010 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<br />") == -1)
2011 56324ebe 2022-07-14 thomas goto done;
2012 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_id) == -1)
2013 56324ebe 2022-07-14 thomas goto done;
2014 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2015 56324ebe 2022-07-14 thomas goto done;
2016 56324ebe 2022-07-14 thomas
2017 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_title'>Commit:"
2018 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2019 56324ebe 2022-07-14 thomas goto done;
2020 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit'>") == -1)
2021 56324ebe 2022-07-14 thomas goto done;
2022 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_id) == -1)
2023 56324ebe 2022-07-14 thomas goto done;
2024 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2025 56324ebe 2022-07-14 thomas goto done;
2026 56324ebe 2022-07-14 thomas
2027 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_tree_title'>Tree:"
2028 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2029 56324ebe 2022-07-14 thomas goto done;
2030 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_tree'>") == -1)
2031 56324ebe 2022-07-14 thomas goto done;
2032 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->tree_id) == -1)
2033 56324ebe 2022-07-14 thomas goto done;
2034 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2035 56324ebe 2022-07-14 thomas goto done;
2036 56324ebe 2022-07-14 thomas
2037 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_author_title'>Author:"
2038 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2039 56324ebe 2022-07-14 thomas goto done;
2040 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_author'>") == -1)
2041 56324ebe 2022-07-14 thomas goto done;
2042 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, author ? author : "") == -1)
2043 56324ebe 2022-07-14 thomas goto done;
2044 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2045 56324ebe 2022-07-14 thomas goto done;
2046 56324ebe 2022-07-14 thomas
2047 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age_title'>Date:"
2048 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2049 56324ebe 2022-07-14 thomas goto done;
2050 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age'>") == -1)
2051 56324ebe 2022-07-14 thomas goto done;
2052 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, age ? age : "") == -1)
2053 56324ebe 2022-07-14 thomas goto done;
2054 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2055 56324ebe 2022-07-14 thomas goto done;
2056 56324ebe 2022-07-14 thomas
2057 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_msg_title'>Message:"
2058 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2059 56324ebe 2022-07-14 thomas goto done;
2060 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_msg'>") == -1)
2061 56324ebe 2022-07-14 thomas goto done;
2062 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rc->commit_msg) == -1)
2063 56324ebe 2022-07-14 thomas goto done;
2064 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2065 56324ebe 2022-07-14 thomas goto done;
2066 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2067 56324ebe 2022-07-14 thomas goto done;
2068 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2069 56324ebe 2022-07-14 thomas goto done;
2070 56324ebe 2022-07-14 thomas
2071 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='dotted_line'></div>\n") == -1)
2072 56324ebe 2022-07-14 thomas goto done;
2073 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='diff'>\n") == -1)
2074 56324ebe 2022-07-14 thomas goto done;
2075 56324ebe 2022-07-14 thomas
2076 56324ebe 2022-07-14 thomas error = got_output_repo_diff(c);
2077 56324ebe 2022-07-14 thomas if (error)
2078 56324ebe 2022-07-14 thomas goto done;
2079 56324ebe 2022-07-14 thomas
2080 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
2081 56324ebe 2022-07-14 thomas done:
2082 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
2083 56324ebe 2022-07-14 thomas free(age);
2084 56324ebe 2022-07-14 thomas free(author);
2085 56324ebe 2022-07-14 thomas return error;
2086 56324ebe 2022-07-14 thomas }
2087 56324ebe 2022-07-14 thomas
2088 56324ebe 2022-07-14 thomas static const struct got_error *
2089 56324ebe 2022-07-14 thomas gotweb_render_summary(struct request *c)
2090 56324ebe 2022-07-14 thomas {
2091 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
2092 56324ebe 2022-07-14 thomas struct transport *t = c->t;
2093 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
2094 56324ebe 2022-07-14 thomas
2095 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='summary_wrapper'>\n") == -1)
2096 56324ebe 2022-07-14 thomas goto done;
2097 56324ebe 2022-07-14 thomas
2098 56324ebe 2022-07-14 thomas if (!srv->show_repo_description)
2099 56324ebe 2022-07-14 thomas goto owner;
2100 56324ebe 2022-07-14 thomas
2101 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='description_title'>"
2102 56324ebe 2022-07-14 thomas "Description:</div>\n") == -1)
2103 56324ebe 2022-07-14 thomas goto done;
2104 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='description'>") == -1)
2105 56324ebe 2022-07-14 thomas goto done;
2106 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, t->repo_dir->description) == -1)
2107 56324ebe 2022-07-14 thomas goto done;
2108 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2109 56324ebe 2022-07-14 thomas goto done;
2110 56324ebe 2022-07-14 thomas owner:
2111 56324ebe 2022-07-14 thomas if (!srv->show_repo_owner)
2112 56324ebe 2022-07-14 thomas goto last_change;
2113 56324ebe 2022-07-14 thomas
2114 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='repo_owner_title'>"
2115 56324ebe 2022-07-14 thomas "Owner:</div>\n") == -1)
2116 56324ebe 2022-07-14 thomas goto done;
2117 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='repo_owner'>") == -1)
2118 56324ebe 2022-07-14 thomas goto done;
2119 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, t->repo_dir->owner) == -1)
2120 56324ebe 2022-07-14 thomas goto done;
2121 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2122 56324ebe 2022-07-14 thomas goto done;
2123 56324ebe 2022-07-14 thomas last_change:
2124 56324ebe 2022-07-14 thomas if (!srv->show_repo_age)
2125 56324ebe 2022-07-14 thomas goto clone_url;
2126 56324ebe 2022-07-14 thomas
2127 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='last_change_title'>"
2128 56324ebe 2022-07-14 thomas "Last Change:</div>\n") == -1)
2129 56324ebe 2022-07-14 thomas goto done;
2130 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='last_change'>") == -1)
2131 56324ebe 2022-07-14 thomas goto done;
2132 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, t->repo_dir->age) == -1)
2133 56324ebe 2022-07-14 thomas goto done;
2134 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2135 56324ebe 2022-07-14 thomas goto done;
2136 56324ebe 2022-07-14 thomas clone_url:
2137 56324ebe 2022-07-14 thomas if (!srv->show_repo_cloneurl)
2138 56324ebe 2022-07-14 thomas goto content;
2139 56324ebe 2022-07-14 thomas
2140 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='cloneurl_title'>"
2141 56324ebe 2022-07-14 thomas "Clone URL:</div>\n") == -1)
2142 56324ebe 2022-07-14 thomas goto done;
2143 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='cloneurl'>") == -1)
2144 56324ebe 2022-07-14 thomas goto done;
2145 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, t->repo_dir->url) == -1)
2146 56324ebe 2022-07-14 thomas goto done;
2147 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2148 56324ebe 2022-07-14 thomas goto done;
2149 56324ebe 2022-07-14 thomas content:
2150 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2151 56324ebe 2022-07-14 thomas goto done;
2152 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2153 56324ebe 2022-07-14 thomas goto done;
2154 56324ebe 2022-07-14 thomas
2155 56324ebe 2022-07-14 thomas error = gotweb_render_briefs(c);
2156 56324ebe 2022-07-14 thomas if (error) {
2157 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
2158 56324ebe 2022-07-14 thomas goto done;
2159 56324ebe 2022-07-14 thomas }
2160 56324ebe 2022-07-14 thomas
2161 56324ebe 2022-07-14 thomas error = gotweb_render_tags(c);
2162 56324ebe 2022-07-14 thomas if (error) {
2163 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
2164 56324ebe 2022-07-14 thomas goto done;
2165 56324ebe 2022-07-14 thomas }
2166 56324ebe 2022-07-14 thomas
2167 56324ebe 2022-07-14 thomas error = gotweb_render_branches(c);
2168 56324ebe 2022-07-14 thomas if (error)
2169 56324ebe 2022-07-14 thomas log_warnx("%s: %s", __func__, error->msg);
2170 56324ebe 2022-07-14 thomas done:
2171 56324ebe 2022-07-14 thomas return error;
2172 56324ebe 2022-07-14 thomas }
2173 56324ebe 2022-07-14 thomas
2174 56324ebe 2022-07-14 thomas static const struct got_error *
2175 56324ebe 2022-07-14 thomas gotweb_render_tag(struct request *c)
2176 56324ebe 2022-07-14 thomas {
2177 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
2178 56324ebe 2022-07-14 thomas struct repo_tag *rt = NULL;
2179 56324ebe 2022-07-14 thomas struct transport *t = c->t;
2180 56324ebe 2022-07-14 thomas char *age = NULL, *author = NULL;
2181 56324ebe 2022-07-14 thomas
2182 56324ebe 2022-07-14 thomas error = got_get_repo_tags(c, 1);
2183 56324ebe 2022-07-14 thomas if (error)
2184 56324ebe 2022-07-14 thomas goto done;
2185 56324ebe 2022-07-14 thomas
2186 56324ebe 2022-07-14 thomas if (t->tag_count == 0) {
2187 56324ebe 2022-07-14 thomas error = got_error_set_errno(GOT_ERR_BAD_OBJ_ID,
2188 56324ebe 2022-07-14 thomas "bad commit id");
2189 56324ebe 2022-07-14 thomas goto done;
2190 56324ebe 2022-07-14 thomas }
2191 56324ebe 2022-07-14 thomas
2192 56324ebe 2022-07-14 thomas rt = TAILQ_LAST(&t->repo_tags, repo_tags_head);
2193 56324ebe 2022-07-14 thomas
2194 56324ebe 2022-07-14 thomas error = gotweb_get_time_str(&age, rt->tagger_time, TM_LONG);
2195 56324ebe 2022-07-14 thomas if (error)
2196 56324ebe 2022-07-14 thomas goto done;
2197 56324ebe 2022-07-14 thomas error = gotweb_escape_html(&author, rt->tagger);
2198 56324ebe 2022-07-14 thomas if (error)
2199 56324ebe 2022-07-14 thomas goto done;
2200 56324ebe 2022-07-14 thomas
2201 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tags_title_wrapper'>\n") == -1)
2202 56324ebe 2022-07-14 thomas goto done;
2203 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tags_title'>Tag</div>\n") == -1)
2204 56324ebe 2022-07-14 thomas goto done;
2205 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2206 56324ebe 2022-07-14 thomas goto done;
2207 56324ebe 2022-07-14 thomas
2208 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tags_content'>\n") == -1)
2209 56324ebe 2022-07-14 thomas goto done;
2210 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tag_header_wrapper'>\n") == -1)
2211 56324ebe 2022-07-14 thomas goto done;
2212 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tag_header'>\n") == -1)
2213 56324ebe 2022-07-14 thomas goto done;
2214 56324ebe 2022-07-14 thomas
2215 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_title'>Commit:"
2216 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2217 56324ebe 2022-07-14 thomas goto done;
2218 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit'>") == -1)
2219 56324ebe 2022-07-14 thomas goto done;
2220 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->commit_id) == -1)
2221 56324ebe 2022-07-14 thomas goto done;
2222 56324ebe 2022-07-14 thomas
2223 56324ebe 2022-07-14 thomas if (strncmp(rt->tag_name, "refs/", 5) == 0)
2224 56324ebe 2022-07-14 thomas rt->tag_name += 5;
2225 56324ebe 2022-07-14 thomas
2226 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " <span id='refs_str'>(") == -1)
2227 56324ebe 2022-07-14 thomas goto done;
2228 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->tag_name) == -1)
2229 56324ebe 2022-07-14 thomas goto done;
2230 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, ")</span>") == -1)
2231 56324ebe 2022-07-14 thomas goto done;
2232 56324ebe 2022-07-14 thomas
2233 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2234 56324ebe 2022-07-14 thomas goto done;
2235 56324ebe 2022-07-14 thomas
2236 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_author_title'>Tagger:"
2237 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2238 56324ebe 2022-07-14 thomas goto done;
2239 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_author'>") == -1)
2240 56324ebe 2022-07-14 thomas goto done;
2241 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, author ? author : "") == -1)
2242 56324ebe 2022-07-14 thomas goto done;
2243 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2244 56324ebe 2022-07-14 thomas goto done;
2245 56324ebe 2022-07-14 thomas
2246 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age_title'>Date:"
2247 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2248 56324ebe 2022-07-14 thomas goto done;
2249 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_age'>") == -1)
2250 56324ebe 2022-07-14 thomas goto done;
2251 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, age ? age : "") == -1)
2252 56324ebe 2022-07-14 thomas goto done;
2253 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2254 56324ebe 2022-07-14 thomas goto done;
2255 56324ebe 2022-07-14 thomas
2256 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_msg_title'>Message:"
2257 56324ebe 2022-07-14 thomas "</div>\n") == -1)
2258 56324ebe 2022-07-14 thomas goto done;
2259 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='header_commit_msg'>") == -1)
2260 56324ebe 2022-07-14 thomas goto done;
2261 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->commit_msg) == -1)
2262 56324ebe 2022-07-14 thomas goto done;
2263 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2264 56324ebe 2022-07-14 thomas goto done;
2265 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2266 56324ebe 2022-07-14 thomas goto done;
2267 56324ebe 2022-07-14 thomas
2268 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='dotted_line'></div>\n") == -1)
2269 56324ebe 2022-07-14 thomas goto done;
2270 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tag_commit'>\n") == -1)
2271 56324ebe 2022-07-14 thomas goto done;
2272 56324ebe 2022-07-14 thomas
2273 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->tag_commit) == -1)
2274 56324ebe 2022-07-14 thomas goto done;
2275 56324ebe 2022-07-14 thomas
2276 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2277 56324ebe 2022-07-14 thomas goto done;
2278 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
2279 56324ebe 2022-07-14 thomas done:
2280 56324ebe 2022-07-14 thomas free(age);
2281 56324ebe 2022-07-14 thomas free(author);
2282 56324ebe 2022-07-14 thomas return error;
2283 56324ebe 2022-07-14 thomas }
2284 56324ebe 2022-07-14 thomas
2285 56324ebe 2022-07-14 thomas static const struct got_error *
2286 56324ebe 2022-07-14 thomas gotweb_render_tags(struct request *c)
2287 56324ebe 2022-07-14 thomas {
2288 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
2289 56324ebe 2022-07-14 thomas struct repo_tag *rt = NULL;
2290 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
2291 56324ebe 2022-07-14 thomas struct transport *t = c->t;
2292 56324ebe 2022-07-14 thomas struct querystring *qs = t->qs;
2293 56324ebe 2022-07-14 thomas struct repo_dir *repo_dir = t->repo_dir;
2294 56324ebe 2022-07-14 thomas char *newline;
2295 56324ebe 2022-07-14 thomas char *age = NULL;
2296 56324ebe 2022-07-14 thomas int commit_found = 0;
2297 56324ebe 2022-07-14 thomas
2298 56324ebe 2022-07-14 thomas if (qs->action == BRIEFS) {
2299 56324ebe 2022-07-14 thomas qs->action = TAGS;
2300 56324ebe 2022-07-14 thomas error = got_get_repo_tags(c, D_MAXSLCOMMDISP);
2301 56324ebe 2022-07-14 thomas } else
2302 56324ebe 2022-07-14 thomas error = got_get_repo_tags(c, srv->max_commits_display);
2303 56324ebe 2022-07-14 thomas if (error)
2304 56324ebe 2022-07-14 thomas goto done;
2305 56324ebe 2022-07-14 thomas
2306 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tags_title_wrapper'>\n") == -1)
2307 56324ebe 2022-07-14 thomas goto done;
2308 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
2309 56324ebe 2022-07-14 thomas "<div id='tags_title'>Tags</div>\n") == -1)
2310 56324ebe 2022-07-14 thomas goto done;
2311 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2312 56324ebe 2022-07-14 thomas goto done;
2313 56324ebe 2022-07-14 thomas
2314 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tags_content'>\n") == -1)
2315 56324ebe 2022-07-14 thomas goto done;
2316 56324ebe 2022-07-14 thomas
2317 56324ebe 2022-07-14 thomas if (t->tag_count == 0) {
2318 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='err_content'>") == -1)
2319 56324ebe 2022-07-14 thomas goto done;
2320 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
2321 56324ebe 2022-07-14 thomas "This repository contains no tags\n") == -1)
2322 56324ebe 2022-07-14 thomas goto done;
2323 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2324 56324ebe 2022-07-14 thomas goto done;
2325 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2326 56324ebe 2022-07-14 thomas goto done;
2327 56324ebe 2022-07-14 thomas }
2328 56324ebe 2022-07-14 thomas
2329 56324ebe 2022-07-14 thomas TAILQ_FOREACH(rt, &t->repo_tags, entry) {
2330 56324ebe 2022-07-14 thomas if (commit_found == 0 && qs->commit != NULL) {
2331 56324ebe 2022-07-14 thomas if (strcmp(qs->commit, rt->commit_id) != 0)
2332 56324ebe 2022-07-14 thomas continue;
2333 56324ebe 2022-07-14 thomas else
2334 56324ebe 2022-07-14 thomas commit_found = 1;
2335 56324ebe 2022-07-14 thomas }
2336 56324ebe 2022-07-14 thomas error = gotweb_get_time_str(&age, rt->tagger_time, TM_DIFF);
2337 56324ebe 2022-07-14 thomas if (error)
2338 56324ebe 2022-07-14 thomas goto done;
2339 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tag_age'>") == -1)
2340 56324ebe 2022-07-14 thomas goto done;
2341 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, age ? age : "") == -1)
2342 56324ebe 2022-07-14 thomas goto done;
2343 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2344 56324ebe 2022-07-14 thomas goto done;
2345 56324ebe 2022-07-14 thomas
2346 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tag'>") == -1)
2347 56324ebe 2022-07-14 thomas goto done;
2348 56324ebe 2022-07-14 thomas if (strncmp(rt->tag_name, "refs/tags/", 10) == 0)
2349 56324ebe 2022-07-14 thomas rt->tag_name += 10;
2350 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->tag_name) == -1)
2351 56324ebe 2022-07-14 thomas goto done;
2352 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2353 56324ebe 2022-07-14 thomas goto done;
2354 56324ebe 2022-07-14 thomas
2355 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='tags_log'>") == -1)
2356 56324ebe 2022-07-14 thomas goto done;
2357 56324ebe 2022-07-14 thomas if (rt->tag_commit != NULL) {
2358 56324ebe 2022-07-14 thomas newline = strchr(rt->tag_commit, '\n');
2359 56324ebe 2022-07-14 thomas if (newline)
2360 56324ebe 2022-07-14 thomas *newline = '\0';
2361 56324ebe 2022-07-14 thomas }
2362 56324ebe 2022-07-14 thomas
2363 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
2364 56324ebe 2022-07-14 thomas goto done;
2365 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
2366 56324ebe 2022-07-14 thomas goto done;
2367 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
2368 56324ebe 2022-07-14 thomas goto done;
2369 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
2370 56324ebe 2022-07-14 thomas goto done;
2371 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=tag&commit=") == -1)
2372 56324ebe 2022-07-14 thomas goto done;
2373 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->commit_id) == -1)
2374 56324ebe 2022-07-14 thomas goto done;
2375 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
2376 56324ebe 2022-07-14 thomas goto done;
2377 56324ebe 2022-07-14 thomas if (rt->tag_commit != NULL &&
2378 56324ebe 2022-07-14 thomas fcgi_gen_response(c, rt->tag_commit) == -1)
2379 56324ebe 2022-07-14 thomas goto done;
2380 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
2381 56324ebe 2022-07-14 thomas goto done;
2382 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2383 56324ebe 2022-07-14 thomas goto done;
2384 56324ebe 2022-07-14 thomas
2385 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs_wrapper'>\n") == -1)
2386 56324ebe 2022-07-14 thomas goto done;
2387 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<div id='navs'>") == -1)
2388 56324ebe 2022-07-14 thomas goto done;
2389 56324ebe 2022-07-14 thomas
2390 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
2391 56324ebe 2022-07-14 thomas goto done;
2392 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
2393 56324ebe 2022-07-14 thomas goto done;
2394 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
2395 56324ebe 2022-07-14 thomas goto done;
2396 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
2397 56324ebe 2022-07-14 thomas goto done;
2398 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=tag&commit=") == -1)
2399 56324ebe 2022-07-14 thomas goto done;
2400 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->commit_id) == -1)
2401 56324ebe 2022-07-14 thomas goto done;
2402 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
2403 56324ebe 2022-07-14 thomas goto done;
2404 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "tag") == -1)
2405 56324ebe 2022-07-14 thomas goto done;
2406 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
2407 56324ebe 2022-07-14 thomas goto done;
2408 56324ebe 2022-07-14 thomas
2409 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " | ") == -1)
2410 56324ebe 2022-07-14 thomas goto done;
2411 56324ebe 2022-07-14 thomas
2412 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
2413 56324ebe 2022-07-14 thomas goto done;
2414 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
2415 56324ebe 2022-07-14 thomas goto done;
2416 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
2417 56324ebe 2022-07-14 thomas goto done;
2418 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
2419 56324ebe 2022-07-14 thomas goto done;
2420 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=briefs&commit=") == -1)
2421 56324ebe 2022-07-14 thomas goto done;
2422 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->commit_id) == -1)
2423 56324ebe 2022-07-14 thomas goto done;
2424 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
2425 56324ebe 2022-07-14 thomas goto done;
2426 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "commit briefs") == -1)
2427 56324ebe 2022-07-14 thomas goto done;
2428 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
2429 56324ebe 2022-07-14 thomas goto done;
2430 56324ebe 2022-07-14 thomas
2431 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, " | ") == -1)
2432 56324ebe 2022-07-14 thomas goto done;
2433 56324ebe 2022-07-14 thomas
2434 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "<a href='?index_page=") == -1)
2435 56324ebe 2022-07-14 thomas goto done;
2436 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, qs->index_page_str) == -1)
2437 56324ebe 2022-07-14 thomas goto done;
2438 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&path=") == -1)
2439 56324ebe 2022-07-14 thomas goto done;
2440 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, repo_dir->name) == -1)
2441 56324ebe 2022-07-14 thomas goto done;
2442 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "&action=commits&commit=") == -1)
2443 56324ebe 2022-07-14 thomas goto done;
2444 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, rt->commit_id) == -1)
2445 56324ebe 2022-07-14 thomas goto done;
2446 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "'>") == -1)
2447 56324ebe 2022-07-14 thomas goto done;
2448 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "commits") == -1)
2449 56324ebe 2022-07-14 thomas goto done;
2450 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</a>") == -1)
2451 56324ebe 2022-07-14 thomas goto done;
2452 56324ebe 2022-07-14 thomas
2453 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2454 56324ebe 2022-07-14 thomas goto done;
2455 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c, "</div>\n") == -1)
2456 56324ebe 2022-07-14 thomas goto done;
2457 56324ebe 2022-07-14 thomas if (fcgi_gen_response(c,
2458 56324ebe 2022-07-14 thomas "<div id='dotted_line'></div>\n") == -1)
2459 56324ebe 2022-07-14 thomas goto done;
2460 56324ebe 2022-07-14 thomas
2461 56324ebe 2022-07-14 thomas free(age);
2462 56324ebe 2022-07-14 thomas age = NULL;
2463 56324ebe 2022-07-14 thomas }
2464 56324ebe 2022-07-14 thomas if (t->next_id || t->prev_id) {
2465 56324ebe 2022-07-14 thomas error = gotweb_render_navs(c);
2466 56324ebe 2022-07-14 thomas if (error)
2467 56324ebe 2022-07-14 thomas goto done;
2468 56324ebe 2022-07-14 thomas }
2469 56324ebe 2022-07-14 thomas fcgi_gen_response(c, "</div>\n");
2470 56324ebe 2022-07-14 thomas done:
2471 56324ebe 2022-07-14 thomas free(age);
2472 56324ebe 2022-07-14 thomas return error;
2473 56324ebe 2022-07-14 thomas }
2474 56324ebe 2022-07-14 thomas
2475 56324ebe 2022-07-14 thomas const struct got_error *
2476 56324ebe 2022-07-14 thomas gotweb_escape_html(char **escaped_html, const char *orig_html)
2477 56324ebe 2022-07-14 thomas {
2478 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
2479 56324ebe 2022-07-14 thomas struct escape_pair {
2480 56324ebe 2022-07-14 thomas char c;
2481 56324ebe 2022-07-14 thomas const char *s;
2482 56324ebe 2022-07-14 thomas } esc[] = {
2483 56324ebe 2022-07-14 thomas { '>', "&gt;" },
2484 56324ebe 2022-07-14 thomas { '<', "&lt;" },
2485 56324ebe 2022-07-14 thomas { '&', "&amp;" },
2486 56324ebe 2022-07-14 thomas { '"', "&quot;" },
2487 56324ebe 2022-07-14 thomas { '\'', "&apos;" },
2488 56324ebe 2022-07-14 thomas { '\n', "<br />" },
2489 56324ebe 2022-07-14 thomas };
2490 56324ebe 2022-07-14 thomas size_t orig_len, len;
2491 56324ebe 2022-07-14 thomas int i, j, x;
2492 56324ebe 2022-07-14 thomas
2493 56324ebe 2022-07-14 thomas orig_len = strlen(orig_html);
2494 56324ebe 2022-07-14 thomas len = orig_len;
2495 56324ebe 2022-07-14 thomas for (i = 0; i < orig_len; i++) {
2496 56324ebe 2022-07-14 thomas for (j = 0; j < nitems(esc); j++) {
2497 56324ebe 2022-07-14 thomas if (orig_html[i] != esc[j].c)
2498 56324ebe 2022-07-14 thomas continue;
2499 56324ebe 2022-07-14 thomas len += strlen(esc[j].s) - 1 /* escaped char */;
2500 56324ebe 2022-07-14 thomas }
2501 56324ebe 2022-07-14 thomas }
2502 56324ebe 2022-07-14 thomas
2503 56324ebe 2022-07-14 thomas *escaped_html = calloc(len + 1 /* NUL */, sizeof(**escaped_html));
2504 56324ebe 2022-07-14 thomas if (*escaped_html == NULL)
2505 56324ebe 2022-07-14 thomas return got_error_from_errno("calloc");
2506 56324ebe 2022-07-14 thomas
2507 56324ebe 2022-07-14 thomas x = 0;
2508 56324ebe 2022-07-14 thomas for (i = 0; i < orig_len; i++) {
2509 56324ebe 2022-07-14 thomas int escaped = 0;
2510 56324ebe 2022-07-14 thomas for (j = 0; j < nitems(esc); j++) {
2511 56324ebe 2022-07-14 thomas if (orig_html[i] != esc[j].c)
2512 56324ebe 2022-07-14 thomas continue;
2513 56324ebe 2022-07-14 thomas
2514 56324ebe 2022-07-14 thomas if (strlcat(*escaped_html, esc[j].s, len + 1)
2515 56324ebe 2022-07-14 thomas >= len + 1) {
2516 56324ebe 2022-07-14 thomas error = got_error(GOT_ERR_NO_SPACE);
2517 56324ebe 2022-07-14 thomas goto done;
2518 56324ebe 2022-07-14 thomas }
2519 56324ebe 2022-07-14 thomas x += strlen(esc[j].s);
2520 56324ebe 2022-07-14 thomas escaped = 1;
2521 56324ebe 2022-07-14 thomas break;
2522 56324ebe 2022-07-14 thomas }
2523 56324ebe 2022-07-14 thomas if (!escaped) {
2524 56324ebe 2022-07-14 thomas (*escaped_html)[x] = orig_html[i];
2525 56324ebe 2022-07-14 thomas x++;
2526 56324ebe 2022-07-14 thomas }
2527 56324ebe 2022-07-14 thomas }
2528 56324ebe 2022-07-14 thomas done:
2529 56324ebe 2022-07-14 thomas if (error) {
2530 56324ebe 2022-07-14 thomas free(*escaped_html);
2531 56324ebe 2022-07-14 thomas *escaped_html = NULL;
2532 56324ebe 2022-07-14 thomas } else {
2533 56324ebe 2022-07-14 thomas (*escaped_html)[x] = '\0';
2534 56324ebe 2022-07-14 thomas }
2535 56324ebe 2022-07-14 thomas
2536 56324ebe 2022-07-14 thomas return error;
2537 56324ebe 2022-07-14 thomas }
2538 56324ebe 2022-07-14 thomas
2539 56324ebe 2022-07-14 thomas static const struct got_error *
2540 56324ebe 2022-07-14 thomas gotweb_load_got_path(struct request *c, struct repo_dir *repo_dir)
2541 56324ebe 2022-07-14 thomas {
2542 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
2543 56324ebe 2022-07-14 thomas struct socket *sock = c->sock;
2544 56324ebe 2022-07-14 thomas struct server *srv = c->srv;
2545 56324ebe 2022-07-14 thomas struct transport *t = c->t;
2546 56324ebe 2022-07-14 thomas DIR *dt;
2547 56324ebe 2022-07-14 thomas char *dir_test;
2548 56324ebe 2022-07-14 thomas int opened = 0;
2549 56324ebe 2022-07-14 thomas
2550 56324ebe 2022-07-14 thomas if (asprintf(&dir_test, "%s/%s/%s", srv->repos_path, repo_dir->name,
2551 56324ebe 2022-07-14 thomas GOTWEB_GIT_DIR) == -1)
2552 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2553 56324ebe 2022-07-14 thomas
2554 56324ebe 2022-07-14 thomas dt = opendir(dir_test);
2555 56324ebe 2022-07-14 thomas if (dt == NULL) {
2556 56324ebe 2022-07-14 thomas free(dir_test);
2557 56324ebe 2022-07-14 thomas } else {
2558 56324ebe 2022-07-14 thomas repo_dir->path = strdup(dir_test);
2559 56324ebe 2022-07-14 thomas if (repo_dir->path == NULL) {
2560 56324ebe 2022-07-14 thomas opened = 1;
2561 56324ebe 2022-07-14 thomas error = got_error_from_errno("strdup");
2562 56324ebe 2022-07-14 thomas goto err;
2563 56324ebe 2022-07-14 thomas }
2564 56324ebe 2022-07-14 thomas opened = 1;
2565 56324ebe 2022-07-14 thomas goto done;
2566 56324ebe 2022-07-14 thomas }
2567 56324ebe 2022-07-14 thomas
2568 56324ebe 2022-07-14 thomas if (asprintf(&dir_test, "%s/%s/%s", srv->repos_path, repo_dir->name,
2569 56324ebe 2022-07-14 thomas GOTWEB_GOT_DIR) == -1) {
2570 56324ebe 2022-07-14 thomas dir_test = NULL;
2571 56324ebe 2022-07-14 thomas error = got_error_from_errno("asprintf");
2572 56324ebe 2022-07-14 thomas goto err;
2573 56324ebe 2022-07-14 thomas }
2574 56324ebe 2022-07-14 thomas
2575 56324ebe 2022-07-14 thomas dt = opendir(dir_test);
2576 56324ebe 2022-07-14 thomas if (dt == NULL)
2577 56324ebe 2022-07-14 thomas free(dir_test);
2578 56324ebe 2022-07-14 thomas else {
2579 56324ebe 2022-07-14 thomas opened = 1;
2580 56324ebe 2022-07-14 thomas error = got_error(GOT_ERR_NOT_GIT_REPO);
2581 56324ebe 2022-07-14 thomas goto err;
2582 56324ebe 2022-07-14 thomas }
2583 56324ebe 2022-07-14 thomas
2584 56324ebe 2022-07-14 thomas if (asprintf(&dir_test, "%s/%s", srv->repos_path,
2585 56324ebe 2022-07-14 thomas repo_dir->name) == -1) {
2586 56324ebe 2022-07-14 thomas error = got_error_from_errno("asprintf");
2587 56324ebe 2022-07-14 thomas dir_test = NULL;
2588 56324ebe 2022-07-14 thomas goto err;
2589 56324ebe 2022-07-14 thomas }
2590 56324ebe 2022-07-14 thomas
2591 56324ebe 2022-07-14 thomas repo_dir->path = strdup(dir_test);
2592 56324ebe 2022-07-14 thomas if (repo_dir->path == NULL) {
2593 56324ebe 2022-07-14 thomas opened = 1;
2594 56324ebe 2022-07-14 thomas error = got_error_from_errno("strdup");
2595 56324ebe 2022-07-14 thomas goto err;
2596 56324ebe 2022-07-14 thomas }
2597 56324ebe 2022-07-14 thomas
2598 56324ebe 2022-07-14 thomas dt = opendir(dir_test);
2599 56324ebe 2022-07-14 thomas if (dt == NULL) {
2600 56324ebe 2022-07-14 thomas error = got_error_path(repo_dir->name, GOT_ERR_NOT_GIT_REPO);
2601 56324ebe 2022-07-14 thomas goto err;
2602 56324ebe 2022-07-14 thomas } else
2603 56324ebe 2022-07-14 thomas opened = 1;
2604 56324ebe 2022-07-14 thomas done:
2605 56324ebe 2022-07-14 thomas error = got_repo_open(&t->repo, repo_dir->path, NULL, sock->pack_fds);
2606 56324ebe 2022-07-14 thomas if (error)
2607 56324ebe 2022-07-14 thomas goto err;
2608 56324ebe 2022-07-14 thomas error = gotweb_get_repo_description(&repo_dir->description, srv,
2609 56324ebe 2022-07-14 thomas repo_dir->path);
2610 56324ebe 2022-07-14 thomas if (error)
2611 56324ebe 2022-07-14 thomas goto err;
2612 56324ebe 2022-07-14 thomas error = got_get_repo_owner(&repo_dir->owner, c, repo_dir->path);
2613 56324ebe 2022-07-14 thomas if (error)
2614 56324ebe 2022-07-14 thomas goto err;
2615 56324ebe 2022-07-14 thomas error = got_get_repo_age(&repo_dir->age, c, repo_dir->path,
2616 56324ebe 2022-07-14 thomas NULL, TM_DIFF);
2617 56324ebe 2022-07-14 thomas if (error)
2618 56324ebe 2022-07-14 thomas goto err;
2619 56324ebe 2022-07-14 thomas error = gotweb_get_clone_url(&repo_dir->url, srv, repo_dir->path);
2620 56324ebe 2022-07-14 thomas err:
2621 56324ebe 2022-07-14 thomas free(dir_test);
2622 56324ebe 2022-07-14 thomas if (opened)
2623 56324ebe 2022-07-14 thomas if (dt != NULL && closedir(dt) == EOF && error == NULL)
2624 56324ebe 2022-07-14 thomas error = got_error_from_errno("closedir");
2625 56324ebe 2022-07-14 thomas return error;
2626 56324ebe 2022-07-14 thomas }
2627 56324ebe 2022-07-14 thomas
2628 56324ebe 2022-07-14 thomas static const struct got_error *
2629 56324ebe 2022-07-14 thomas gotweb_init_repo_dir(struct repo_dir **repo_dir, const char *dir)
2630 56324ebe 2022-07-14 thomas {
2631 56324ebe 2022-07-14 thomas const struct got_error *error;
2632 56324ebe 2022-07-14 thomas
2633 56324ebe 2022-07-14 thomas *repo_dir = calloc(1, sizeof(**repo_dir));
2634 56324ebe 2022-07-14 thomas if (*repo_dir == NULL)
2635 56324ebe 2022-07-14 thomas return got_error_from_errno("calloc");
2636 56324ebe 2022-07-14 thomas
2637 56324ebe 2022-07-14 thomas if (asprintf(&(*repo_dir)->name, "%s", dir) == -1) {
2638 56324ebe 2022-07-14 thomas error = got_error_from_errno("asprintf");
2639 56324ebe 2022-07-14 thomas free(*repo_dir);
2640 56324ebe 2022-07-14 thomas *repo_dir = NULL;
2641 56324ebe 2022-07-14 thomas return error;
2642 56324ebe 2022-07-14 thomas }
2643 56324ebe 2022-07-14 thomas (*repo_dir)->owner = NULL;
2644 56324ebe 2022-07-14 thomas (*repo_dir)->description = NULL;
2645 56324ebe 2022-07-14 thomas (*repo_dir)->url = NULL;
2646 56324ebe 2022-07-14 thomas (*repo_dir)->age = NULL;
2647 56324ebe 2022-07-14 thomas (*repo_dir)->path = NULL;
2648 56324ebe 2022-07-14 thomas
2649 56324ebe 2022-07-14 thomas return NULL;
2650 56324ebe 2022-07-14 thomas }
2651 56324ebe 2022-07-14 thomas
2652 56324ebe 2022-07-14 thomas static const struct got_error *
2653 56324ebe 2022-07-14 thomas gotweb_get_repo_description(char **description, struct server *srv, char *dir)
2654 56324ebe 2022-07-14 thomas {
2655 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
2656 56324ebe 2022-07-14 thomas FILE *f = NULL;
2657 56324ebe 2022-07-14 thomas char *d_file = NULL;
2658 56324ebe 2022-07-14 thomas unsigned int len;
2659 56324ebe 2022-07-14 thomas size_t n;
2660 56324ebe 2022-07-14 thomas
2661 56324ebe 2022-07-14 thomas *description = NULL;
2662 56324ebe 2022-07-14 thomas if (srv->show_repo_description == 0)
2663 56324ebe 2022-07-14 thomas return NULL;
2664 56324ebe 2022-07-14 thomas
2665 56324ebe 2022-07-14 thomas if (asprintf(&d_file, "%s/description", dir) == -1)
2666 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2667 56324ebe 2022-07-14 thomas
2668 56324ebe 2022-07-14 thomas f = fopen(d_file, "r");
2669 56324ebe 2022-07-14 thomas if (f == NULL) {
2670 56324ebe 2022-07-14 thomas if (errno == ENOENT || errno == EACCES)
2671 56324ebe 2022-07-14 thomas return NULL;
2672 56324ebe 2022-07-14 thomas error = got_error_from_errno2("fopen", d_file);
2673 56324ebe 2022-07-14 thomas goto done;
2674 56324ebe 2022-07-14 thomas }
2675 56324ebe 2022-07-14 thomas
2676 56324ebe 2022-07-14 thomas if (fseek(f, 0, SEEK_END) == -1) {
2677 56324ebe 2022-07-14 thomas error = got_ferror(f, GOT_ERR_IO);
2678 56324ebe 2022-07-14 thomas goto done;
2679 56324ebe 2022-07-14 thomas }
2680 56324ebe 2022-07-14 thomas len = ftell(f);
2681 56324ebe 2022-07-14 thomas if (len == -1) {
2682 56324ebe 2022-07-14 thomas error = got_ferror(f, GOT_ERR_IO);
2683 56324ebe 2022-07-14 thomas goto done;
2684 56324ebe 2022-07-14 thomas }
2685 56324ebe 2022-07-14 thomas
2686 56324ebe 2022-07-14 thomas if (len == 0)
2687 56324ebe 2022-07-14 thomas goto done;
2688 56324ebe 2022-07-14 thomas
2689 56324ebe 2022-07-14 thomas if (fseek(f, 0, SEEK_SET) == -1) {
2690 56324ebe 2022-07-14 thomas error = got_ferror(f, GOT_ERR_IO);
2691 56324ebe 2022-07-14 thomas goto done;
2692 56324ebe 2022-07-14 thomas }
2693 56324ebe 2022-07-14 thomas *description = calloc(len + 1, sizeof(**description));
2694 56324ebe 2022-07-14 thomas if (*description == NULL) {
2695 56324ebe 2022-07-14 thomas error = got_error_from_errno("calloc");
2696 56324ebe 2022-07-14 thomas goto done;
2697 56324ebe 2022-07-14 thomas }
2698 56324ebe 2022-07-14 thomas
2699 56324ebe 2022-07-14 thomas n = fread(*description, 1, len, f);
2700 56324ebe 2022-07-14 thomas if (n == 0 && ferror(f))
2701 56324ebe 2022-07-14 thomas error = got_ferror(f, GOT_ERR_IO);
2702 56324ebe 2022-07-14 thomas done:
2703 56324ebe 2022-07-14 thomas if (f != NULL && fclose(f) == EOF && error == NULL)
2704 56324ebe 2022-07-14 thomas error = got_error_from_errno("fclose");
2705 56324ebe 2022-07-14 thomas free(d_file);
2706 56324ebe 2022-07-14 thomas return error;
2707 56324ebe 2022-07-14 thomas }
2708 56324ebe 2022-07-14 thomas
2709 56324ebe 2022-07-14 thomas static const struct got_error *
2710 56324ebe 2022-07-14 thomas gotweb_get_clone_url(char **url, struct server *srv, char *dir)
2711 56324ebe 2022-07-14 thomas {
2712 56324ebe 2022-07-14 thomas const struct got_error *error = NULL;
2713 56324ebe 2022-07-14 thomas FILE *f;
2714 56324ebe 2022-07-14 thomas char *d_file = NULL;
2715 56324ebe 2022-07-14 thomas unsigned int len;
2716 56324ebe 2022-07-14 thomas size_t n;
2717 56324ebe 2022-07-14 thomas
2718 56324ebe 2022-07-14 thomas *url = NULL;
2719 56324ebe 2022-07-14 thomas
2720 56324ebe 2022-07-14 thomas if (srv->show_repo_cloneurl == 0)
2721 56324ebe 2022-07-14 thomas return NULL;
2722 56324ebe 2022-07-14 thomas
2723 56324ebe 2022-07-14 thomas if (asprintf(&d_file, "%s/cloneurl", dir) == -1)
2724 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2725 56324ebe 2022-07-14 thomas
2726 56324ebe 2022-07-14 thomas f = fopen(d_file, "r");
2727 56324ebe 2022-07-14 thomas if (f == NULL) {
2728 56324ebe 2022-07-14 thomas if (errno != ENOENT && errno != EACCES)
2729 56324ebe 2022-07-14 thomas error = got_error_from_errno2("fopen", d_file);
2730 56324ebe 2022-07-14 thomas goto done;
2731 56324ebe 2022-07-14 thomas }
2732 56324ebe 2022-07-14 thomas
2733 56324ebe 2022-07-14 thomas if (fseek(f, 0, SEEK_END) == -1) {
2734 56324ebe 2022-07-14 thomas error = got_ferror(f, GOT_ERR_IO);
2735 56324ebe 2022-07-14 thomas goto done;
2736 56324ebe 2022-07-14 thomas }
2737 56324ebe 2022-07-14 thomas len = ftell(f);
2738 56324ebe 2022-07-14 thomas if (len == -1) {
2739 56324ebe 2022-07-14 thomas error = got_ferror(f, GOT_ERR_IO);
2740 56324ebe 2022-07-14 thomas goto done;
2741 56324ebe 2022-07-14 thomas }
2742 56324ebe 2022-07-14 thomas if (len == 0)
2743 56324ebe 2022-07-14 thomas goto done;
2744 56324ebe 2022-07-14 thomas
2745 56324ebe 2022-07-14 thomas if (fseek(f, 0, SEEK_SET) == -1) {
2746 56324ebe 2022-07-14 thomas error = got_ferror(f, GOT_ERR_IO);
2747 56324ebe 2022-07-14 thomas goto done;
2748 56324ebe 2022-07-14 thomas }
2749 56324ebe 2022-07-14 thomas
2750 56324ebe 2022-07-14 thomas *url = calloc(len + 1, sizeof(**url));
2751 56324ebe 2022-07-14 thomas if (*url == NULL) {
2752 56324ebe 2022-07-14 thomas error = got_error_from_errno("calloc");
2753 56324ebe 2022-07-14 thomas goto done;
2754 56324ebe 2022-07-14 thomas }
2755 56324ebe 2022-07-14 thomas
2756 56324ebe 2022-07-14 thomas n = fread(*url, 1, len, f);
2757 56324ebe 2022-07-14 thomas if (n == 0 && ferror(f))
2758 56324ebe 2022-07-14 thomas error = got_ferror(f, GOT_ERR_IO);
2759 56324ebe 2022-07-14 thomas done:
2760 56324ebe 2022-07-14 thomas if (f != NULL && fclose(f) == EOF && error == NULL)
2761 56324ebe 2022-07-14 thomas error = got_error_from_errno("fclose");
2762 56324ebe 2022-07-14 thomas free(d_file);
2763 56324ebe 2022-07-14 thomas return error;
2764 56324ebe 2022-07-14 thomas }
2765 56324ebe 2022-07-14 thomas
2766 56324ebe 2022-07-14 thomas const struct got_error *
2767 56324ebe 2022-07-14 thomas gotweb_get_time_str(char **repo_age, time_t committer_time, int ref_tm)
2768 56324ebe 2022-07-14 thomas {
2769 56324ebe 2022-07-14 thomas struct tm tm;
2770 56324ebe 2022-07-14 thomas time_t diff_time;
2771 56324ebe 2022-07-14 thomas const char *years = "years ago", *months = "months ago";
2772 56324ebe 2022-07-14 thomas const char *weeks = "weeks ago", *days = "days ago";
2773 56324ebe 2022-07-14 thomas const char *hours = "hours ago", *minutes = "minutes ago";
2774 56324ebe 2022-07-14 thomas const char *seconds = "seconds ago", *now = "right now";
2775 56324ebe 2022-07-14 thomas char *s;
2776 56324ebe 2022-07-14 thomas char datebuf[29];
2777 56324ebe 2022-07-14 thomas
2778 56324ebe 2022-07-14 thomas *repo_age = NULL;
2779 56324ebe 2022-07-14 thomas
2780 56324ebe 2022-07-14 thomas switch (ref_tm) {
2781 56324ebe 2022-07-14 thomas case TM_DIFF:
2782 56324ebe 2022-07-14 thomas diff_time = time(NULL) - committer_time;
2783 56324ebe 2022-07-14 thomas if (diff_time > 60 * 60 * 24 * 365 * 2) {
2784 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%lld %s",
2785 56324ebe 2022-07-14 thomas (diff_time / 60 / 60 / 24 / 365), years) == -1)
2786 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2787 56324ebe 2022-07-14 thomas } else if (diff_time > 60 * 60 * 24 * (365 / 12) * 2) {
2788 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%lld %s",
2789 56324ebe 2022-07-14 thomas (diff_time / 60 / 60 / 24 / (365 / 12)),
2790 56324ebe 2022-07-14 thomas months) == -1)
2791 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2792 56324ebe 2022-07-14 thomas } else if (diff_time > 60 * 60 * 24 * 7 * 2) {
2793 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%lld %s",
2794 56324ebe 2022-07-14 thomas (diff_time / 60 / 60 / 24 / 7), weeks) == -1)
2795 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2796 56324ebe 2022-07-14 thomas } else if (diff_time > 60 * 60 * 24 * 2) {
2797 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%lld %s",
2798 56324ebe 2022-07-14 thomas (diff_time / 60 / 60 / 24), days) == -1)
2799 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2800 56324ebe 2022-07-14 thomas } else if (diff_time > 60 * 60 * 2) {
2801 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%lld %s",
2802 56324ebe 2022-07-14 thomas (diff_time / 60 / 60), hours) == -1)
2803 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2804 56324ebe 2022-07-14 thomas } else if (diff_time > 60 * 2) {
2805 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%lld %s", (diff_time / 60),
2806 56324ebe 2022-07-14 thomas minutes) == -1)
2807 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2808 56324ebe 2022-07-14 thomas } else if (diff_time > 2) {
2809 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%lld %s", diff_time,
2810 56324ebe 2022-07-14 thomas seconds) == -1)
2811 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2812 56324ebe 2022-07-14 thomas } else {
2813 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%s", now) == -1)
2814 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2815 56324ebe 2022-07-14 thomas }
2816 56324ebe 2022-07-14 thomas break;
2817 56324ebe 2022-07-14 thomas case TM_LONG:
2818 56324ebe 2022-07-14 thomas if (gmtime_r(&committer_time, &tm) == NULL)
2819 56324ebe 2022-07-14 thomas return got_error_from_errno("gmtime_r");
2820 56324ebe 2022-07-14 thomas
2821 56324ebe 2022-07-14 thomas s = asctime_r(&tm, datebuf);
2822 56324ebe 2022-07-14 thomas if (s == NULL)
2823 56324ebe 2022-07-14 thomas return got_error_from_errno("asctime_r");
2824 56324ebe 2022-07-14 thomas
2825 56324ebe 2022-07-14 thomas if (asprintf(repo_age, "%s UTC", datebuf) == -1)
2826 56324ebe 2022-07-14 thomas return got_error_from_errno("asprintf");
2827 56324ebe 2022-07-14 thomas break;
2828 56324ebe 2022-07-14 thomas }
2829 56324ebe 2022-07-14 thomas return NULL;
2830 d7cad54e 2022-07-14 thomas }