Blame


1 2c251c14 2020-01-15 tracey /*
2 9460dac0 2020-01-15 tracey * Copyright (c) 2019, 2020 Tracey Emery <tracey@traceyemery.net>
3 2c251c14 2020-01-15 tracey * Copyright (c) 2018, 2019 Stefan Sperling <stsp@openbsd.org>
4 2c251c14 2020-01-15 tracey *
5 2c251c14 2020-01-15 tracey * Permission to use, copy, modify, and distribute this software for any
6 2c251c14 2020-01-15 tracey * purpose with or without fee is hereby granted, provided that the above
7 2c251c14 2020-01-15 tracey * copyright notice and this permission notice appear in all copies.
8 2c251c14 2020-01-15 tracey *
9 2c251c14 2020-01-15 tracey * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 2c251c14 2020-01-15 tracey * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 2c251c14 2020-01-15 tracey * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 2c251c14 2020-01-15 tracey * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 2c251c14 2020-01-15 tracey * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 2c251c14 2020-01-15 tracey * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 2c251c14 2020-01-15 tracey * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 2c251c14 2020-01-15 tracey */
17 2c251c14 2020-01-15 tracey
18 2c251c14 2020-01-15 tracey #include <sys/queue.h>
19 2c251c14 2020-01-15 tracey #include <sys/stat.h>
20 2c251c14 2020-01-15 tracey #include <sys/types.h>
21 2c251c14 2020-01-15 tracey
22 017d6da3 2020-01-29 tracey #include <ctype.h>
23 2c251c14 2020-01-15 tracey #include <dirent.h>
24 2c251c14 2020-01-15 tracey #include <err.h>
25 c25c2314 2020-01-28 stsp #include <errno.h>
26 474370cb 2020-01-15 tracey #include <regex.h>
27 2c251c14 2020-01-15 tracey #include <stdarg.h>
28 2c251c14 2020-01-15 tracey #include <stdint.h>
29 2c251c14 2020-01-15 tracey #include <stdio.h>
30 2c251c14 2020-01-15 tracey #include <stdlib.h>
31 2c251c14 2020-01-15 tracey #include <string.h>
32 2c251c14 2020-01-15 tracey #include <unistd.h>
33 2c251c14 2020-01-15 tracey
34 c34ec417 2020-06-22 tracey #include <got_error.h>
35 2c251c14 2020-01-15 tracey #include <got_object.h>
36 2c251c14 2020-01-15 tracey #include <got_reference.h>
37 2c251c14 2020-01-15 tracey #include <got_repository.h>
38 2c251c14 2020-01-15 tracey #include <got_path.h>
39 2c251c14 2020-01-15 tracey #include <got_cancel.h>
40 2c251c14 2020-01-15 tracey #include <got_worktree.h>
41 2c251c14 2020-01-15 tracey #include <got_diff.h>
42 2c251c14 2020-01-15 tracey #include <got_commit_graph.h>
43 2c251c14 2020-01-15 tracey #include <got_blame.h>
44 2c251c14 2020-01-15 tracey #include <got_privsep.h>
45 2c251c14 2020-01-15 tracey #include <got_opentemp.h>
46 2c251c14 2020-01-15 tracey
47 2c251c14 2020-01-15 tracey #include <kcgi.h>
48 2c251c14 2020-01-15 tracey #include <kcgihtml.h>
49 2c251c14 2020-01-15 tracey
50 2c251c14 2020-01-15 tracey #include "gotweb.h"
51 2c251c14 2020-01-15 tracey
52 2c251c14 2020-01-15 tracey #ifndef nitems
53 2c251c14 2020-01-15 tracey #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
54 2c251c14 2020-01-15 tracey #endif
55 2c251c14 2020-01-15 tracey
56 54415d85 2020-01-15 tracey struct gw_trans {
57 f2f46662 2020-01-23 tracey TAILQ_HEAD(headers, gw_header) gw_headers;
58 f2f46662 2020-01-23 tracey TAILQ_HEAD(dirs, gw_dir) gw_dirs;
59 deac617c 2020-02-14 tracey struct got_repository *repo;
60 46b9c89b 2020-01-15 tracey struct gw_dir *gw_dir;
61 c34ec417 2020-06-22 tracey struct gotweb_config *gw_conf;
62 2c251c14 2020-01-15 tracey struct ktemplate *gw_tmpl;
63 2c251c14 2020-01-15 tracey struct khtmlreq *gw_html_req;
64 2c251c14 2020-01-15 tracey struct kreq *gw_req;
65 f1200fe3 2020-02-13 tracey const struct got_error *error;
66 f652ec0c 2020-02-13 stsp const char *repo_name;
67 2c251c14 2020-01-15 tracey char *repo_path;
68 56997cd3 2020-02-14 tracey char *commit_id;
69 55e46400 2020-02-18 tracey char *next_id;
70 55e46400 2020-02-18 tracey char *next_prev_id;
71 55e46400 2020-02-18 tracey char *prev_id;
72 55e46400 2020-02-18 tracey char *prev_prev_id;
73 4d6abe2b 2020-02-13 stsp const char *repo_file;
74 ec46ccd7 2020-01-15 tracey char *repo_folder;
75 742ba378 2020-02-14 stsp const char *headref;
76 2c251c14 2020-01-15 tracey unsigned int action;
77 2c251c14 2020-01-15 tracey unsigned int page;
78 2c251c14 2020-01-15 tracey unsigned int repos_total;
79 387a29ba 2020-01-15 tracey enum kmime mime;
80 2c251c14 2020-01-15 tracey };
81 2c251c14 2020-01-15 tracey
82 f2f46662 2020-01-23 tracey struct gw_header {
83 f2f46662 2020-01-23 tracey TAILQ_ENTRY(gw_header) entry;
84 f2f46662 2020-01-23 tracey struct got_reflist_head refs;
85 f2f46662 2020-01-23 tracey char *path;
86 f2f46662 2020-01-23 tracey
87 f2f46662 2020-01-23 tracey char *refs_str;
88 f2f46662 2020-01-23 tracey char *commit_id; /* id_str1 */
89 f2f46662 2020-01-23 tracey char *parent_id; /* id_str2 */
90 f2f46662 2020-01-23 tracey char *tree_id;
91 4e8d6e3e 2020-02-14 tracey char *author;
92 4e8d6e3e 2020-02-14 tracey char *committer;
93 f2f46662 2020-01-23 tracey char *commit_msg;
94 f2f46662 2020-01-23 tracey time_t committer_time;
95 2c251c14 2020-01-15 tracey };
96 2c251c14 2020-01-15 tracey
97 2c251c14 2020-01-15 tracey struct gw_dir {
98 2c251c14 2020-01-15 tracey TAILQ_ENTRY(gw_dir) entry;
99 2c251c14 2020-01-15 tracey char *name;
100 2c251c14 2020-01-15 tracey char *owner;
101 2c251c14 2020-01-15 tracey char *description;
102 2c251c14 2020-01-15 tracey char *url;
103 2c251c14 2020-01-15 tracey char *age;
104 2c251c14 2020-01-15 tracey char *path;
105 2c251c14 2020-01-15 tracey };
106 2c251c14 2020-01-15 tracey
107 f2f46662 2020-01-23 tracey enum gw_key {
108 f2f46662 2020-01-23 tracey KEY_ACTION,
109 f2f46662 2020-01-23 tracey KEY_COMMIT_ID,
110 f2f46662 2020-01-23 tracey KEY_FILE,
111 f2f46662 2020-01-23 tracey KEY_FOLDER,
112 f2f46662 2020-01-23 tracey KEY_HEADREF,
113 f2f46662 2020-01-23 tracey KEY_PAGE,
114 f2f46662 2020-01-23 tracey KEY_PATH,
115 55e46400 2020-02-18 tracey KEY_PREV_ID,
116 55e46400 2020-02-18 tracey KEY_PREV_PREV_ID,
117 f2f46662 2020-01-23 tracey KEY__ZMAX
118 f2f46662 2020-01-23 tracey };
119 f2f46662 2020-01-23 tracey
120 54415d85 2020-01-15 tracey enum gw_tmpl {
121 f2f46662 2020-01-23 tracey TEMPL_CONTENT,
122 2c251c14 2020-01-15 tracey TEMPL_HEAD,
123 2c251c14 2020-01-15 tracey TEMPL_HEADER,
124 f2f46662 2020-01-23 tracey TEMPL_SEARCH,
125 2c251c14 2020-01-15 tracey TEMPL_SITEPATH,
126 2c251c14 2020-01-15 tracey TEMPL_SITEOWNER,
127 2c251c14 2020-01-15 tracey TEMPL_TITLE,
128 2c251c14 2020-01-15 tracey TEMPL__MAX
129 2c251c14 2020-01-15 tracey };
130 2c251c14 2020-01-15 tracey
131 54415d85 2020-01-15 tracey enum gw_ref_tm {
132 387a29ba 2020-01-15 tracey TM_DIFF,
133 387a29ba 2020-01-15 tracey TM_LONG,
134 387a29ba 2020-01-15 tracey };
135 387a29ba 2020-01-15 tracey
136 ff4bb25f 2020-02-19 tracey enum gw_tags_type {
137 87f9ebf5 2020-01-15 tracey TAGBRIEF,
138 87f9ebf5 2020-01-15 tracey TAGFULL,
139 87f9ebf5 2020-01-15 tracey };
140 87f9ebf5 2020-01-15 tracey
141 54415d85 2020-01-15 tracey static const char *const gw_templs[TEMPL__MAX] = {
142 f2f46662 2020-01-23 tracey "content",
143 2c251c14 2020-01-15 tracey "head",
144 2c251c14 2020-01-15 tracey "header",
145 f2f46662 2020-01-23 tracey "search",
146 2c251c14 2020-01-15 tracey "sitepath",
147 2c251c14 2020-01-15 tracey "siteowner",
148 2c251c14 2020-01-15 tracey "title",
149 2c251c14 2020-01-15 tracey };
150 2c251c14 2020-01-15 tracey
151 ec46ccd7 2020-01-15 tracey static const struct kvalid gw_keys[KEY__ZMAX] = {
152 2c251c14 2020-01-15 tracey { kvalid_stringne, "action" },
153 2c251c14 2020-01-15 tracey { kvalid_stringne, "commit" },
154 2c251c14 2020-01-15 tracey { kvalid_stringne, "file" },
155 ec46ccd7 2020-01-15 tracey { kvalid_stringne, "folder" },
156 8087c3c5 2020-01-15 tracey { kvalid_stringne, "headref" },
157 ec46ccd7 2020-01-15 tracey { kvalid_int, "page" },
158 ec46ccd7 2020-01-15 tracey { kvalid_stringne, "path" },
159 55e46400 2020-02-18 tracey { kvalid_stringne, "prev" },
160 55e46400 2020-02-18 tracey { kvalid_stringne, "prev_prev" },
161 2c251c14 2020-01-15 tracey };
162 2c251c14 2020-01-15 tracey
163 f2f46662 2020-01-23 tracey static struct gw_header *gw_init_header(void);
164 2c251c14 2020-01-15 tracey
165 b0a1bc86 2020-02-14 stsp static void gw_free_header(struct gw_header *);
166 00f13350 2020-02-10 tracey
167 00f13350 2020-02-10 tracey static int gw_template(size_t, void *);
168 00f13350 2020-02-10 tracey
169 f1200fe3 2020-02-13 tracey static const struct got_error *gw_error(struct gw_trans *);
170 f1200fe3 2020-02-13 tracey static const struct got_error *gw_init_gw_dir(struct gw_dir **, const char *);
171 185ba3ba 2020-02-04 tracey static const struct got_error *gw_get_repo_description(char **,
172 185ba3ba 2020-02-04 tracey struct gw_trans *, char *);
173 9a1cc63f 2020-02-03 stsp static const struct got_error *gw_get_repo_owner(char **, struct gw_trans *,
174 2c251c14 2020-01-15 tracey char *);
175 55ccf528 2020-02-03 stsp static const struct got_error *gw_get_time_str(char **, time_t, int);
176 d126c1b7 2020-01-29 stsp static const struct got_error *gw_get_repo_age(char **, struct gw_trans *,
177 2011c142 2020-02-14 stsp char *, const char *, int);
178 84de9106 2020-12-26 stsp static const struct got_error *gw_output_file_blame(struct gw_trans *,
179 84de9106 2020-12-26 stsp struct gw_header *);
180 84de9106 2020-12-26 stsp static const struct got_error *gw_output_blob_buf(struct gw_trans *,
181 84de9106 2020-12-26 stsp struct gw_header *);
182 84de9106 2020-12-26 stsp static const struct got_error *gw_output_repo_tree(struct gw_trans *,
183 84de9106 2020-12-26 stsp struct gw_header *);
184 38b240fb 2020-02-06 tracey static const struct got_error *gw_output_diff(struct gw_trans *,
185 f2f46662 2020-01-23 tracey struct gw_header *);
186 38b240fb 2020-02-06 tracey static const struct got_error *gw_output_repo_tags(struct gw_trans *,
187 4ff7391f 2020-01-28 tracey struct gw_header *, int, int);
188 9eed6f10 2020-02-08 tracey static const struct got_error *gw_output_repo_heads(struct gw_trans *);
189 4ae179a2 2020-02-08 tracey static const struct got_error *gw_output_site_link(struct gw_trans *);
190 185ba3ba 2020-02-04 tracey static const struct got_error *gw_get_clone_url(char **, struct gw_trans *,
191 185ba3ba 2020-02-04 tracey char *);
192 f7cc9480 2020-02-05 tracey static const struct got_error *gw_colordiff_line(struct gw_trans *, char *);
193 2c251c14 2020-01-15 tracey
194 21a55cc7 2020-02-04 tracey static const struct got_error *gw_gen_commit_header(struct gw_trans *, char *,
195 21a55cc7 2020-02-04 tracey char*);
196 f7cc9480 2020-02-05 tracey static const struct got_error *gw_gen_diff_header(struct gw_trans *, char *,
197 f7cc9480 2020-02-05 tracey char*);
198 21a55cc7 2020-02-04 tracey static const struct got_error *gw_gen_author_header(struct gw_trans *,
199 21a55cc7 2020-02-04 tracey const char *);
200 21a55cc7 2020-02-04 tracey static const struct got_error *gw_gen_age_header(struct gw_trans *,
201 21a55cc7 2020-02-04 tracey const char *);
202 21a55cc7 2020-02-04 tracey static const struct got_error *gw_gen_committer_header(struct gw_trans *,
203 21a55cc7 2020-02-04 tracey const char *);
204 f7cc9480 2020-02-05 tracey static const struct got_error *gw_gen_commit_msg_header(struct gw_trans*,
205 f7cc9480 2020-02-05 tracey char *);
206 f7cc9480 2020-02-05 tracey static const struct got_error *gw_gen_tree_header(struct gw_trans *, char *);
207 00f13350 2020-02-10 tracey static const struct got_error *gw_display_open(struct gw_trans *, enum khttp,
208 2c251c14 2020-01-15 tracey enum kmime);
209 00f13350 2020-02-10 tracey static const struct got_error *gw_display_index(struct gw_trans *);
210 00f13350 2020-02-10 tracey static const struct got_error *gw_get_header(struct gw_trans *,
211 f2f46662 2020-01-23 tracey struct gw_header *, int);
212 00f13350 2020-02-10 tracey static const struct got_error *gw_get_commits(struct gw_trans *,
213 3c245a0e 2020-02-14 tracey struct gw_header *, int,
214 3c245a0e 2020-02-14 tracey struct got_object_id *);
215 00f13350 2020-02-10 tracey static const struct got_error *gw_get_commit(struct gw_trans *,
216 4e8d6e3e 2020-02-14 tracey struct gw_header *,
217 4e8d6e3e 2020-02-14 tracey struct got_commit_object *,
218 3c245a0e 2020-02-14 tracey struct got_object_id *);
219 d4159696 2020-02-13 stsp static const struct got_error *gw_apply_unveil(const char *);
220 00f13350 2020-02-10 tracey static const struct got_error *gw_blame_cb(void *, int, int,
221 ec46ccd7 2020-01-15 tracey struct got_object_id *);
222 00f13350 2020-02-10 tracey static const struct got_error *gw_load_got_paths(struct gw_trans *);
223 00f13350 2020-02-10 tracey static const struct got_error *gw_load_got_path(struct gw_trans *,
224 2c251c14 2020-01-15 tracey struct gw_dir *);
225 00f13350 2020-02-10 tracey static const struct got_error *gw_parse_querystring(struct gw_trans *);
226 00f13350 2020-02-10 tracey static const struct got_error *gw_blame(struct gw_trans *);
227 00f13350 2020-02-10 tracey static const struct got_error *gw_blob(struct gw_trans *);
228 00f13350 2020-02-10 tracey static const struct got_error *gw_diff(struct gw_trans *);
229 00f13350 2020-02-10 tracey static const struct got_error *gw_index(struct gw_trans *);
230 00f13350 2020-02-10 tracey static const struct got_error *gw_commits(struct gw_trans *);
231 00f13350 2020-02-10 tracey static const struct got_error *gw_briefs(struct gw_trans *);
232 00f13350 2020-02-10 tracey static const struct got_error *gw_summary(struct gw_trans *);
233 00f13350 2020-02-10 tracey static const struct got_error *gw_tree(struct gw_trans *);
234 00f13350 2020-02-10 tracey static const struct got_error *gw_tag(struct gw_trans *);
235 ff4bb25f 2020-02-19 tracey static const struct got_error *gw_tags(struct gw_trans *);
236 2c251c14 2020-01-15 tracey
237 2c251c14 2020-01-15 tracey struct gw_query_action {
238 2c251c14 2020-01-15 tracey unsigned int func_id;
239 2c251c14 2020-01-15 tracey const char *func_name;
240 54415d85 2020-01-15 tracey const struct got_error *(*func_main)(struct gw_trans *);
241 2c251c14 2020-01-15 tracey char *template;
242 2c251c14 2020-01-15 tracey };
243 2c251c14 2020-01-15 tracey
244 2c251c14 2020-01-15 tracey enum gw_query_actions {
245 2c251c14 2020-01-15 tracey GW_BLAME,
246 e46f587c 2020-01-29 tracey GW_BLOB,
247 f2f46662 2020-01-23 tracey GW_BRIEFS,
248 f2f46662 2020-01-23 tracey GW_COMMITS,
249 f2f46662 2020-01-23 tracey GW_DIFF,
250 2c251c14 2020-01-15 tracey GW_ERR,
251 2c251c14 2020-01-15 tracey GW_INDEX,
252 2c251c14 2020-01-15 tracey GW_SUMMARY,
253 4ff7391f 2020-01-28 tracey GW_TAG,
254 ff4bb25f 2020-02-19 tracey GW_TAGS,
255 b772de24 2020-01-15 tracey GW_TREE,
256 2c251c14 2020-01-15 tracey };
257 2c251c14 2020-01-15 tracey
258 2c251c14 2020-01-15 tracey static struct gw_query_action gw_query_funcs[] = {
259 f2f46662 2020-01-23 tracey { GW_BLAME, "blame", gw_blame, "gw_tmpl/blame.tmpl" },
260 017d6da3 2020-01-29 tracey { GW_BLOB, "blob", NULL, NULL },
261 f2f46662 2020-01-23 tracey { GW_BRIEFS, "briefs", gw_briefs, "gw_tmpl/briefs.tmpl" },
262 f2f46662 2020-01-23 tracey { GW_COMMITS, "commits", gw_commits, "gw_tmpl/commit.tmpl" },
263 f2f46662 2020-01-23 tracey { GW_DIFF, "diff", gw_diff, "gw_tmpl/diff.tmpl" },
264 f1200fe3 2020-02-13 tracey { GW_ERR, "error", gw_error, "gw_tmpl/err.tmpl" },
265 f2f46662 2020-01-23 tracey { GW_INDEX, "index", gw_index, "gw_tmpl/index.tmpl" },
266 f2f46662 2020-01-23 tracey { GW_SUMMARY, "summary", gw_summary, "gw_tmpl/summry.tmpl" },
267 4ff7391f 2020-01-28 tracey { GW_TAG, "tag", gw_tag, "gw_tmpl/tag.tmpl" },
268 ff4bb25f 2020-02-19 tracey { GW_TAGS, "tags", gw_tags, "gw_tmpl/tags.tmpl" },
269 f2f46662 2020-01-23 tracey { GW_TREE, "tree", gw_tree, "gw_tmpl/tree.tmpl" },
270 2c251c14 2020-01-15 tracey };
271 5d1296de 2020-02-13 stsp
272 5d1296de 2020-02-13 stsp static const char *
273 5d1296de 2020-02-13 stsp gw_get_action_name(struct gw_trans *gw_trans)
274 5d1296de 2020-02-13 stsp {
275 5d1296de 2020-02-13 stsp return gw_query_funcs[gw_trans->action].func_name;
276 5d1296de 2020-02-13 stsp }
277 c25c2314 2020-01-28 stsp
278 c25c2314 2020-01-28 stsp static const struct got_error *
279 c25c2314 2020-01-28 stsp gw_kcgi_error(enum kcgi_err kerr)
280 c25c2314 2020-01-28 stsp {
281 c25c2314 2020-01-28 stsp if (kerr == KCGI_OK)
282 c25c2314 2020-01-28 stsp return NULL;
283 c25c2314 2020-01-28 stsp
284 c25c2314 2020-01-28 stsp if (kerr == KCGI_EXIT || kerr == KCGI_HUP)
285 c25c2314 2020-01-28 stsp return got_error(GOT_ERR_CANCELLED);
286 c25c2314 2020-01-28 stsp
287 c25c2314 2020-01-28 stsp if (kerr == KCGI_ENOMEM)
288 f7cc9480 2020-02-05 tracey return got_error_set_errno(ENOMEM,
289 7afec891 2020-02-06 stsp kcgi_strerror(kerr));
290 2c251c14 2020-01-15 tracey
291 c25c2314 2020-01-28 stsp if (kerr == KCGI_ENFILE)
292 f7cc9480 2020-02-05 tracey return got_error_set_errno(ENFILE,
293 7afec891 2020-02-06 stsp kcgi_strerror(kerr));
294 c25c2314 2020-01-28 stsp
295 c25c2314 2020-01-28 stsp if (kerr == KCGI_EAGAIN)
296 f7cc9480 2020-02-05 tracey return got_error_set_errno(EAGAIN,
297 7afec891 2020-02-06 stsp kcgi_strerror(kerr));
298 c25c2314 2020-01-28 stsp
299 c25c2314 2020-01-28 stsp if (kerr == KCGI_FORM)
300 f7cc9480 2020-02-05 tracey return got_error_msg(GOT_ERR_IO,
301 7afec891 2020-02-06 stsp kcgi_strerror(kerr));
302 c25c2314 2020-01-28 stsp
303 7afec891 2020-02-06 stsp return got_error_from_errno(kcgi_strerror(kerr));
304 c25c2314 2020-01-28 stsp }
305 c25c2314 2020-01-28 stsp
306 2c251c14 2020-01-15 tracey static const struct got_error *
307 d4159696 2020-02-13 stsp gw_apply_unveil(const char *repo_path)
308 2c251c14 2020-01-15 tracey {
309 2c251c14 2020-01-15 tracey const struct got_error *err;
310 2c251c14 2020-01-15 tracey
311 245c7240 2021-06-17 stsp #ifdef PROFILE
312 245c7240 2021-06-17 stsp if (unveil("gmon.out", "rwc") != 0)
313 245c7240 2021-06-17 stsp return got_error_from_errno2("unveil", "gmon.out");
314 245c7240 2021-06-17 stsp #endif
315 2c251c14 2020-01-15 tracey if (repo_path && unveil(repo_path, "r") != 0)
316 2c251c14 2020-01-15 tracey return got_error_from_errno2("unveil", repo_path);
317 2c251c14 2020-01-15 tracey
318 bb63914a 2020-02-17 stsp if (unveil(GOT_TMPDIR_STR, "rwc") != 0)
319 bb63914a 2020-02-17 stsp return got_error_from_errno2("unveil", GOT_TMPDIR_STR);
320 2c251c14 2020-01-15 tracey
321 2c251c14 2020-01-15 tracey err = got_privsep_unveil_exec_helpers();
322 2c251c14 2020-01-15 tracey if (err != NULL)
323 2c251c14 2020-01-15 tracey return err;
324 2c251c14 2020-01-15 tracey
325 2c251c14 2020-01-15 tracey if (unveil(NULL, NULL) != 0)
326 2c251c14 2020-01-15 tracey return got_error_from_errno("unveil");
327 65b95fb2 2020-01-15 tracey
328 32cd4d18 2020-02-03 stsp return NULL;
329 5894d523 2020-02-03 stsp }
330 5894d523 2020-02-03 stsp
331 5894d523 2020-02-03 stsp static int
332 e0857cfe 2020-02-06 tracey isbinary(const uint8_t *buf, size_t n)
333 5894d523 2020-02-03 stsp {
334 e0857cfe 2020-02-06 tracey size_t i;
335 e0857cfe 2020-02-06 tracey
336 e0857cfe 2020-02-06 tracey for (i = 0; i < n; i++)
337 e0857cfe 2020-02-06 tracey if (buf[i] == 0)
338 e0857cfe 2020-02-06 tracey return 1;
339 e0857cfe 2020-02-06 tracey return 0;
340 32cd4d18 2020-02-03 stsp }
341 5894d523 2020-02-03 stsp
342 32cd4d18 2020-02-03 stsp static const struct got_error *
343 54415d85 2020-01-15 tracey gw_blame(struct gw_trans *gw_trans)
344 2c251c14 2020-01-15 tracey {
345 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
346 f2f46662 2020-01-23 tracey struct gw_header *header = NULL;
347 78a9dab5 2020-02-07 tracey char *age = NULL;
348 1b33afc0 2020-02-14 tracey enum kcgi_err kerr = KCGI_OK;
349 2c251c14 2020-01-15 tracey
350 6bee13de 2020-01-16 tracey if (pledge("stdio rpath wpath cpath proc exec sendfd unveil",
351 f2f46662 2020-01-23 tracey NULL) == -1)
352 f2f46662 2020-01-23 tracey return got_error_from_errno("pledge");
353 6bee13de 2020-01-16 tracey
354 f2f46662 2020-01-23 tracey if ((header = gw_init_header()) == NULL)
355 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
356 f2f46662 2020-01-23 tracey
357 d4159696 2020-02-13 stsp error = gw_apply_unveil(gw_trans->gw_dir->path);
358 ec46ccd7 2020-01-15 tracey if (error)
359 5ddf0079 2020-01-29 stsp goto done;
360 ec46ccd7 2020-01-15 tracey
361 1b33afc0 2020-02-14 tracey /* check querystring */
362 1b33afc0 2020-02-14 tracey if (gw_trans->repo_file == NULL) {
363 1b33afc0 2020-02-14 tracey error = got_error_msg(GOT_ERR_QUERYSTRING,
364 1b33afc0 2020-02-14 tracey "file required in querystring");
365 1b33afc0 2020-02-14 tracey goto done;
366 1b33afc0 2020-02-14 tracey }
367 1b33afc0 2020-02-14 tracey if (gw_trans->commit_id == NULL) {
368 1b33afc0 2020-02-14 tracey error = got_error_msg(GOT_ERR_QUERYSTRING,
369 1b33afc0 2020-02-14 tracey "commit required in querystring");
370 1b33afc0 2020-02-14 tracey goto done;
371 1b33afc0 2020-02-14 tracey }
372 1b33afc0 2020-02-14 tracey
373 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header, 1);
374 f2f46662 2020-01-23 tracey if (error)
375 5ddf0079 2020-01-29 stsp goto done;
376 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
377 9a9d12ca 2020-02-06 tracey "blame_header_wrapper", KATTR__MAX);
378 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
379 9a9d12ca 2020-02-06 tracey goto done;
380 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
381 9a9d12ca 2020-02-06 tracey "blame_header", KATTR__MAX);
382 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
383 9a9d12ca 2020-02-06 tracey goto done;
384 9a9d12ca 2020-02-06 tracey error = gw_get_time_str(&age, header->committer_time,
385 9a9d12ca 2020-02-06 tracey TM_LONG);
386 a81f3554 2020-02-03 stsp if (error)
387 a81f3554 2020-02-03 stsp goto done;
388 9a9d12ca 2020-02-06 tracey error = gw_gen_age_header(gw_trans, age ?age : "");
389 55ccf528 2020-02-03 stsp if (error)
390 55ccf528 2020-02-03 stsp goto done;
391 9a9d12ca 2020-02-06 tracey error = gw_gen_commit_msg_header(gw_trans, header->commit_msg);
392 9a9d12ca 2020-02-06 tracey if (error)
393 6d9fc692 2020-01-28 stsp goto done;
394 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
395 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
396 6d9fc692 2020-01-28 stsp goto done;
397 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
398 9a9d12ca 2020-02-06 tracey "dotted_line", KATTR__MAX);
399 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
400 9a9d12ca 2020-02-06 tracey goto done;
401 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
402 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
403 9a9d12ca 2020-02-06 tracey goto done;
404 9a9d12ca 2020-02-06 tracey
405 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
406 9a9d12ca 2020-02-06 tracey "blame", KATTR__MAX);
407 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
408 9a9d12ca 2020-02-06 tracey goto done;
409 84de9106 2020-12-26 stsp error = gw_output_file_blame(gw_trans, header);
410 9a9d12ca 2020-02-06 tracey if (error)
411 9a9d12ca 2020-02-06 tracey goto done;
412 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
413 6d9fc692 2020-01-28 stsp done:
414 b0a1bc86 2020-02-14 stsp gw_free_header(header);
415 9a9d12ca 2020-02-06 tracey if (error == NULL && kerr != KCGI_OK)
416 9a9d12ca 2020-02-06 tracey error = gw_kcgi_error(kerr);
417 2c251c14 2020-01-15 tracey return error;
418 2c251c14 2020-01-15 tracey }
419 2c251c14 2020-01-15 tracey
420 2c251c14 2020-01-15 tracey static const struct got_error *
421 e46f587c 2020-01-29 tracey gw_blob(struct gw_trans *gw_trans)
422 e46f587c 2020-01-29 tracey {
423 3b7fdcf4 2020-02-14 tracey const struct got_error *error = NULL, *err = NULL;
424 e46f587c 2020-01-29 tracey struct gw_header *header = NULL;
425 3b7fdcf4 2020-02-14 tracey enum kcgi_err kerr = KCGI_OK;
426 e46f587c 2020-01-29 tracey
427 e46f587c 2020-01-29 tracey if (pledge("stdio rpath wpath cpath proc exec sendfd unveil",
428 e46f587c 2020-01-29 tracey NULL) == -1)
429 e46f587c 2020-01-29 tracey return got_error_from_errno("pledge");
430 e46f587c 2020-01-29 tracey
431 e46f587c 2020-01-29 tracey if ((header = gw_init_header()) == NULL)
432 e46f587c 2020-01-29 tracey return got_error_from_errno("malloc");
433 e46f587c 2020-01-29 tracey
434 d4159696 2020-02-13 stsp error = gw_apply_unveil(gw_trans->gw_dir->path);
435 e46f587c 2020-01-29 tracey if (error)
436 e46f587c 2020-01-29 tracey goto done;
437 e46f587c 2020-01-29 tracey
438 3b7fdcf4 2020-02-14 tracey /* check querystring */
439 3b7fdcf4 2020-02-14 tracey if (gw_trans->repo_file == NULL) {
440 3b7fdcf4 2020-02-14 tracey error = got_error_msg(GOT_ERR_QUERYSTRING,
441 3b7fdcf4 2020-02-14 tracey "file required in querystring");
442 3b7fdcf4 2020-02-14 tracey goto done;
443 3b7fdcf4 2020-02-14 tracey }
444 3b7fdcf4 2020-02-14 tracey if (gw_trans->commit_id == NULL) {
445 3b7fdcf4 2020-02-14 tracey error = got_error_msg(GOT_ERR_QUERYSTRING,
446 3b7fdcf4 2020-02-14 tracey "commit required in querystring");
447 3b7fdcf4 2020-02-14 tracey goto done;
448 3b7fdcf4 2020-02-14 tracey }
449 e46f587c 2020-01-29 tracey error = gw_get_header(gw_trans, header, 1);
450 e46f587c 2020-01-29 tracey if (error)
451 e46f587c 2020-01-29 tracey goto done;
452 e46f587c 2020-01-29 tracey
453 84de9106 2020-12-26 stsp error = gw_output_blob_buf(gw_trans, header);
454 e46f587c 2020-01-29 tracey done:
455 3b7fdcf4 2020-02-14 tracey
456 3b7fdcf4 2020-02-14 tracey if (error) {
457 3b7fdcf4 2020-02-14 tracey gw_trans->mime = KMIME_TEXT_PLAIN;
458 3b7fdcf4 2020-02-14 tracey err = gw_display_index(gw_trans);
459 3b7fdcf4 2020-02-14 tracey if (err) {
460 3b7fdcf4 2020-02-14 tracey error = err;
461 3b7fdcf4 2020-02-14 tracey goto errored;
462 3b7fdcf4 2020-02-14 tracey }
463 3b7fdcf4 2020-02-14 tracey kerr = khttp_puts(gw_trans->gw_req, error->msg);
464 3b7fdcf4 2020-02-14 tracey }
465 3b7fdcf4 2020-02-14 tracey errored:
466 b0a1bc86 2020-02-14 stsp gw_free_header(header);
467 3b7fdcf4 2020-02-14 tracey if (error == NULL && kerr != KCGI_OK)
468 3b7fdcf4 2020-02-14 tracey error = gw_kcgi_error(kerr);
469 e46f587c 2020-01-29 tracey return error;
470 e46f587c 2020-01-29 tracey }
471 e46f587c 2020-01-29 tracey
472 e46f587c 2020-01-29 tracey static const struct got_error *
473 f2f46662 2020-01-23 tracey gw_diff(struct gw_trans *gw_trans)
474 2c251c14 2020-01-15 tracey {
475 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
476 f2f46662 2020-01-23 tracey struct gw_header *header = NULL;
477 78a9dab5 2020-02-07 tracey char *age = NULL;
478 f7cc9480 2020-02-05 tracey enum kcgi_err kerr = KCGI_OK;
479 2c251c14 2020-01-15 tracey
480 f2f46662 2020-01-23 tracey if (pledge("stdio rpath wpath cpath proc exec sendfd unveil",
481 f2f46662 2020-01-23 tracey NULL) == -1)
482 f2f46662 2020-01-23 tracey return got_error_from_errno("pledge");
483 6bee13de 2020-01-16 tracey
484 ae36ed87 2020-01-28 stsp if ((header = gw_init_header()) == NULL)
485 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
486 f2f46662 2020-01-23 tracey
487 d4159696 2020-02-13 stsp error = gw_apply_unveil(gw_trans->gw_dir->path);
488 8087c3c5 2020-01-15 tracey if (error)
489 390d412c 2020-01-28 stsp goto done;
490 8087c3c5 2020-01-15 tracey
491 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header, 1);
492 f2f46662 2020-01-23 tracey if (error)
493 55ccf528 2020-02-03 stsp goto done;
494 f7cc9480 2020-02-05 tracey
495 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
496 f7cc9480 2020-02-05 tracey "diff_header_wrapper", KATTR__MAX);
497 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
498 f7cc9480 2020-02-05 tracey goto done;
499 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
500 f7cc9480 2020-02-05 tracey "diff_header", KATTR__MAX);
501 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
502 f7cc9480 2020-02-05 tracey goto done;
503 f7cc9480 2020-02-05 tracey error = gw_gen_diff_header(gw_trans, header->parent_id,
504 f7cc9480 2020-02-05 tracey header->commit_id);
505 f7cc9480 2020-02-05 tracey if (error)
506 f7cc9480 2020-02-05 tracey goto done;
507 f7cc9480 2020-02-05 tracey error = gw_gen_commit_header(gw_trans, header->commit_id,
508 f7cc9480 2020-02-05 tracey header->refs_str);
509 f7cc9480 2020-02-05 tracey if (error)
510 f7cc9480 2020-02-05 tracey goto done;
511 f7cc9480 2020-02-05 tracey error = gw_gen_tree_header(gw_trans, header->tree_id);
512 f7cc9480 2020-02-05 tracey if (error)
513 f7cc9480 2020-02-05 tracey goto done;
514 f7cc9480 2020-02-05 tracey error = gw_gen_author_header(gw_trans, header->author);
515 f7cc9480 2020-02-05 tracey if (error)
516 f7cc9480 2020-02-05 tracey goto done;
517 f7cc9480 2020-02-05 tracey error = gw_gen_committer_header(gw_trans, header->author);
518 f7cc9480 2020-02-05 tracey if (error)
519 f7cc9480 2020-02-05 tracey goto done;
520 f7cc9480 2020-02-05 tracey error = gw_get_time_str(&age, header->committer_time,
521 f7cc9480 2020-02-05 tracey TM_LONG);
522 f7cc9480 2020-02-05 tracey if (error)
523 f7cc9480 2020-02-05 tracey goto done;
524 f7cc9480 2020-02-05 tracey error = gw_gen_age_header(gw_trans, age ?age : "");
525 070fee27 2020-02-03 stsp if (error)
526 070fee27 2020-02-03 stsp goto done;
527 f7cc9480 2020-02-05 tracey error = gw_gen_commit_msg_header(gw_trans, header->commit_msg);
528 f7cc9480 2020-02-05 tracey if (error)
529 390d412c 2020-01-28 stsp goto done;
530 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
531 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
532 390d412c 2020-01-28 stsp goto done;
533 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
534 f7cc9480 2020-02-05 tracey "dotted_line", KATTR__MAX);
535 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
536 f7cc9480 2020-02-05 tracey goto done;
537 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
538 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
539 f7cc9480 2020-02-05 tracey goto done;
540 87f9ebf5 2020-01-15 tracey
541 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
542 f7cc9480 2020-02-05 tracey "diff", KATTR__MAX);
543 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
544 f7cc9480 2020-02-05 tracey goto done;
545 38b240fb 2020-02-06 tracey error = gw_output_diff(gw_trans, header);
546 f7cc9480 2020-02-05 tracey if (error)
547 f7cc9480 2020-02-05 tracey goto done;
548 f7cc9480 2020-02-05 tracey
549 b4fba448 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
550 390d412c 2020-01-28 stsp done:
551 b0a1bc86 2020-02-14 stsp gw_free_header(header);
552 55ccf528 2020-02-03 stsp free(age);
553 f7cc9480 2020-02-05 tracey if (error == NULL && kerr != KCGI_OK)
554 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
555 2204c934 2020-01-15 tracey return error;
556 2204c934 2020-01-15 tracey }
557 2204c934 2020-01-15 tracey
558 2204c934 2020-01-15 tracey static const struct got_error *
559 54415d85 2020-01-15 tracey gw_index(struct gw_trans *gw_trans)
560 2c251c14 2020-01-15 tracey {
561 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
562 46b9c89b 2020-01-15 tracey struct gw_dir *gw_dir = NULL;
563 b3f1f953 2020-02-09 tracey char *href_next = NULL, *href_prev = NULL, *href_summary = NULL;
564 b3f1f953 2020-02-09 tracey char *href_briefs = NULL, *href_commits = NULL, *href_tree = NULL;
565 ff4bb25f 2020-02-19 tracey char *href_tags = NULL;
566 387a29ba 2020-01-15 tracey unsigned int prev_disp = 0, next_disp = 1, dir_c = 0;
567 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
568 2c251c14 2020-01-15 tracey
569 6bee13de 2020-01-16 tracey if (pledge("stdio rpath proc exec sendfd unveil",
570 6bee13de 2020-01-16 tracey NULL) == -1) {
571 6bee13de 2020-01-16 tracey error = got_error_from_errno("pledge");
572 6bee13de 2020-01-16 tracey return error;
573 6bee13de 2020-01-16 tracey }
574 6bee13de 2020-01-16 tracey
575 d4159696 2020-02-13 stsp error = gw_apply_unveil(gw_trans->gw_conf->got_repos_path);
576 46b9c89b 2020-01-15 tracey if (error)
577 46b9c89b 2020-01-15 tracey return error;
578 46b9c89b 2020-01-15 tracey
579 2c251c14 2020-01-15 tracey error = gw_load_got_paths(gw_trans);
580 46b9c89b 2020-01-15 tracey if (error)
581 2c251c14 2020-01-15 tracey return error;
582 2c251c14 2020-01-15 tracey
583 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
584 b3f1f953 2020-02-09 tracey "index_header", KATTR__MAX);
585 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
586 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
587 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
588 b3f1f953 2020-02-09 tracey "index_header_project", KATTR__MAX);
589 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
590 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
591 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Project");
592 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
593 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
594 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
595 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
596 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
597 2c251c14 2020-01-15 tracey
598 b3f1f953 2020-02-09 tracey if (gw_trans->gw_conf->got_show_repo_description) {
599 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
600 b3f1f953 2020-02-09 tracey "index_header_description", KATTR__MAX);
601 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
602 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
603 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Description");
604 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
605 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
606 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
607 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
608 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
609 b3f1f953 2020-02-09 tracey }
610 b3f1f953 2020-02-09 tracey
611 b3f1f953 2020-02-09 tracey if (gw_trans->gw_conf->got_show_repo_owner) {
612 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
613 b3f1f953 2020-02-09 tracey "index_header_owner", KATTR__MAX);
614 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
615 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
616 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Owner");
617 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
618 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
619 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
620 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
621 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
622 b3f1f953 2020-02-09 tracey }
623 b3f1f953 2020-02-09 tracey
624 b3f1f953 2020-02-09 tracey if (gw_trans->gw_conf->got_show_repo_age) {
625 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
626 b3f1f953 2020-02-09 tracey "index_header_age", KATTR__MAX);
627 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
628 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
629 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Last Change");
630 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
631 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
632 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
633 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
634 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
635 b3f1f953 2020-02-09 tracey }
636 b3f1f953 2020-02-09 tracey
637 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
638 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
639 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
640 b3f1f953 2020-02-09 tracey
641 b3f1f953 2020-02-09 tracey if (TAILQ_EMPTY(&gw_trans->gw_dirs)) {
642 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
643 b3f1f953 2020-02-09 tracey "index_wrapper", KATTR__MAX);
644 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
645 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
646 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(gw_trans->gw_html_req,
647 32b9f7ed 2020-04-14 tracey "No repositories found in %s",
648 b3f1f953 2020-02-09 tracey gw_trans->gw_conf->got_repos_path);
649 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
650 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
651 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
652 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
653 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
654 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
655 b3f1f953 2020-02-09 tracey "dotted_line", KATTR__MAX);
656 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
657 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
658 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
659 b3f1f953 2020-02-09 tracey if (kerr != KCGI_OK)
660 b3f1f953 2020-02-09 tracey return gw_kcgi_error(kerr);
661 c25c2314 2020-01-28 stsp return error;
662 bce5dac1 2020-01-28 stsp }
663 bce5dac1 2020-01-28 stsp
664 46b9c89b 2020-01-15 tracey TAILQ_FOREACH(gw_dir, &gw_trans->gw_dirs, entry)
665 2c251c14 2020-01-15 tracey dir_c++;
666 2c251c14 2020-01-15 tracey
667 46b9c89b 2020-01-15 tracey TAILQ_FOREACH(gw_dir, &gw_trans->gw_dirs, entry) {
668 2c251c14 2020-01-15 tracey if (gw_trans->page > 0 && (gw_trans->page *
669 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_max_repos_display) > prev_disp) {
670 2c251c14 2020-01-15 tracey prev_disp++;
671 2c251c14 2020-01-15 tracey continue;
672 2c251c14 2020-01-15 tracey }
673 2c251c14 2020-01-15 tracey
674 2c251c14 2020-01-15 tracey prev_disp++;
675 f2f46662 2020-01-23 tracey
676 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
677 b3f1f953 2020-02-09 tracey "index_wrapper", KATTR__MAX);
678 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
679 a02d5f81 2020-02-13 stsp goto done;
680 b3f1f953 2020-02-09 tracey
681 2796ac23 2020-04-14 tracey href_summary = khttp_urlpart(NULL, NULL, "gotweb", "path",
682 2796ac23 2020-04-14 tracey gw_dir->name, "action", "summary", NULL);
683 19ff7638 2020-04-14 tracey if (href_summary == NULL) {
684 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
685 19ff7638 2020-04-14 tracey goto done;
686 19ff7638 2020-04-14 tracey }
687 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
688 b3f1f953 2020-02-09 tracey "index_project", KATTR__MAX);
689 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
690 b3f1f953 2020-02-09 tracey goto done;
691 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
692 b3f1f953 2020-02-09 tracey href_summary, KATTR__MAX);
693 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
694 b3f1f953 2020-02-09 tracey goto done;
695 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, gw_dir->name);
696 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
697 b3f1f953 2020-02-09 tracey goto done;
698 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
699 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
700 b3f1f953 2020-02-09 tracey goto done;
701 b3f1f953 2020-02-09 tracey if (gw_trans->gw_conf->got_show_repo_description) {
702 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
703 b3f1f953 2020-02-09 tracey KATTR_ID, "index_project_description", KATTR__MAX);
704 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
705 b3f1f953 2020-02-09 tracey goto done;
706 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req,
707 b3f1f953 2020-02-09 tracey gw_dir->description ? gw_dir->description : "");
708 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
709 b3f1f953 2020-02-09 tracey goto done;
710 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
711 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
712 b3f1f953 2020-02-09 tracey goto done;
713 b3f1f953 2020-02-09 tracey }
714 b3f1f953 2020-02-09 tracey if (gw_trans->gw_conf->got_show_repo_owner) {
715 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
716 b3f1f953 2020-02-09 tracey KATTR_ID, "index_project_owner", KATTR__MAX);
717 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
718 b3f1f953 2020-02-09 tracey goto done;
719 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req,
720 b3f1f953 2020-02-09 tracey gw_dir->owner ? gw_dir->owner : "");
721 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
722 b3f1f953 2020-02-09 tracey goto done;
723 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
724 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
725 b3f1f953 2020-02-09 tracey goto done;
726 b3f1f953 2020-02-09 tracey }
727 b3f1f953 2020-02-09 tracey if (gw_trans->gw_conf->got_show_repo_age) {
728 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
729 b3f1f953 2020-02-09 tracey KATTR_ID, "index_project_age", KATTR__MAX);
730 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
731 b3f1f953 2020-02-09 tracey goto done;
732 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req,
733 b3f1f953 2020-02-09 tracey gw_dir->age ? gw_dir->age : "");
734 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
735 b3f1f953 2020-02-09 tracey goto done;
736 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
737 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
738 b3f1f953 2020-02-09 tracey goto done;
739 b3f1f953 2020-02-09 tracey }
740 b3f1f953 2020-02-09 tracey
741 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
742 b3f1f953 2020-02-09 tracey "navs_wrapper", KATTR__MAX);
743 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
744 b3f1f953 2020-02-09 tracey goto done;
745 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
746 b3f1f953 2020-02-09 tracey "navs", KATTR__MAX);
747 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
748 b3f1f953 2020-02-09 tracey goto done;
749 b3f1f953 2020-02-09 tracey
750 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
751 b3f1f953 2020-02-09 tracey href_summary, KATTR__MAX);
752 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
753 b3f1f953 2020-02-09 tracey goto done;
754 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, "summary");
755 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
756 b3f1f953 2020-02-09 tracey goto done;
757 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
758 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
759 b3f1f953 2020-02-09 tracey goto done;
760 2c251c14 2020-01-15 tracey
761 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
762 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
763 b3f1f953 2020-02-09 tracey goto done;
764 b3f1f953 2020-02-09 tracey
765 2796ac23 2020-04-14 tracey href_briefs = khttp_urlpart(NULL, NULL, "gotweb", "path",
766 2796ac23 2020-04-14 tracey gw_dir->name, "action", "briefs", NULL);
767 19ff7638 2020-04-14 tracey if (href_briefs == NULL) {
768 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
769 19ff7638 2020-04-14 tracey goto done;
770 19ff7638 2020-04-14 tracey }
771 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
772 b3f1f953 2020-02-09 tracey href_briefs, KATTR__MAX);
773 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
774 b3f1f953 2020-02-09 tracey goto done;
775 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, "commit briefs");
776 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
777 b3f1f953 2020-02-09 tracey goto done;
778 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
779 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
780 b3f1f953 2020-02-09 tracey error = gw_kcgi_error(kerr);
781 b3f1f953 2020-02-09 tracey
782 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
783 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
784 b3f1f953 2020-02-09 tracey goto done;
785 b3f1f953 2020-02-09 tracey
786 2796ac23 2020-04-14 tracey href_commits = khttp_urlpart(NULL, NULL, "gotweb", "path",
787 2796ac23 2020-04-14 tracey gw_dir->name, "action", "commits", NULL);
788 19ff7638 2020-04-14 tracey if (href_commits == NULL) {
789 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
790 19ff7638 2020-04-14 tracey goto done;
791 19ff7638 2020-04-14 tracey }
792 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
793 b3f1f953 2020-02-09 tracey href_commits, KATTR__MAX);
794 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
795 b3f1f953 2020-02-09 tracey goto done;
796 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, "commits");
797 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
798 b3f1f953 2020-02-09 tracey goto done;
799 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
800 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
801 b3f1f953 2020-02-09 tracey goto done;
802 b3f1f953 2020-02-09 tracey
803 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
804 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
805 b3f1f953 2020-02-09 tracey goto done;
806 b3f1f953 2020-02-09 tracey
807 2796ac23 2020-04-14 tracey href_tags = khttp_urlpart(NULL, NULL, "gotweb", "path",
808 2796ac23 2020-04-14 tracey gw_dir->name, "action", "tags", NULL);
809 19ff7638 2020-04-14 tracey if (href_tags == NULL) {
810 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
811 19ff7638 2020-04-14 tracey goto done;
812 19ff7638 2020-04-14 tracey }
813 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
814 ff4bb25f 2020-02-19 tracey href_tags, KATTR__MAX);
815 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
816 ff4bb25f 2020-02-19 tracey goto done;
817 ff4bb25f 2020-02-19 tracey kerr = khtml_puts(gw_trans->gw_html_req, "tags");
818 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
819 ff4bb25f 2020-02-19 tracey goto done;
820 ff4bb25f 2020-02-19 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
821 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
822 ff4bb25f 2020-02-19 tracey goto done;
823 ff4bb25f 2020-02-19 tracey
824 ff4bb25f 2020-02-19 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
825 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
826 ff4bb25f 2020-02-19 tracey goto done;
827 ff4bb25f 2020-02-19 tracey
828 2796ac23 2020-04-14 tracey href_tree = khttp_urlpart(NULL, NULL, "gotweb", "path",
829 2796ac23 2020-04-14 tracey gw_dir->name, "action", "tree", NULL);
830 19ff7638 2020-04-14 tracey if (href_tree == NULL) {
831 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
832 19ff7638 2020-04-14 tracey goto done;
833 19ff7638 2020-04-14 tracey }
834 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
835 b3f1f953 2020-02-09 tracey href_tree, KATTR__MAX);
836 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
837 b3f1f953 2020-02-09 tracey goto done;
838 b3f1f953 2020-02-09 tracey kerr = khtml_puts(gw_trans->gw_html_req, "tree");
839 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
840 b3f1f953 2020-02-09 tracey goto done;
841 b3f1f953 2020-02-09 tracey
842 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 4);
843 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
844 b3f1f953 2020-02-09 tracey goto done;
845 b3f1f953 2020-02-09 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
846 b3f1f953 2020-02-09 tracey "dotted_line", KATTR__MAX);
847 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
848 b3f1f953 2020-02-09 tracey goto done;
849 b3f1f953 2020-02-09 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
850 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
851 b3f1f953 2020-02-09 tracey goto done;
852 b3f1f953 2020-02-09 tracey
853 b3f1f953 2020-02-09 tracey free(href_summary);
854 b3f1f953 2020-02-09 tracey href_summary = NULL;
855 b3f1f953 2020-02-09 tracey free(href_briefs);
856 b3f1f953 2020-02-09 tracey href_briefs = NULL;
857 b3f1f953 2020-02-09 tracey free(href_commits);
858 b3f1f953 2020-02-09 tracey href_commits = NULL;
859 ff4bb25f 2020-02-19 tracey free(href_tags);
860 ff4bb25f 2020-02-19 tracey href_tags = NULL;
861 b3f1f953 2020-02-09 tracey free(href_tree);
862 b3f1f953 2020-02-09 tracey href_tree = NULL;
863 b3f1f953 2020-02-09 tracey
864 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_max_repos_display == 0)
865 2c251c14 2020-01-15 tracey continue;
866 2c251c14 2020-01-15 tracey
867 75f21c89 2020-02-18 tracey if ((next_disp == gw_trans->gw_conf->got_max_repos_display) ||
868 75f21c89 2020-02-18 tracey ((gw_trans->gw_conf->got_max_repos_display > 0) &&
869 2c251c14 2020-01-15 tracey (gw_trans->page > 0) &&
870 2c251c14 2020-01-15 tracey (next_disp == gw_trans->gw_conf->got_max_repos_display ||
871 75f21c89 2020-02-18 tracey prev_disp == gw_trans->repos_total))) {
872 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
873 63ee0dca 2020-02-08 tracey KATTR_ID, "np_wrapper", KATTR__MAX);
874 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
875 b3f1f953 2020-02-09 tracey goto done;
876 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
877 63ee0dca 2020-02-08 tracey KATTR_ID, "nav_prev", KATTR__MAX);
878 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
879 b3f1f953 2020-02-09 tracey goto done;
880 c25c2314 2020-01-28 stsp }
881 2c251c14 2020-01-15 tracey
882 2c251c14 2020-01-15 tracey if ((gw_trans->gw_conf->got_max_repos_display > 0) &&
883 2c251c14 2020-01-15 tracey (gw_trans->page > 0) &&
884 2c251c14 2020-01-15 tracey (next_disp == gw_trans->gw_conf->got_max_repos_display ||
885 2c251c14 2020-01-15 tracey prev_disp == gw_trans->repos_total)) {
886 2796ac23 2020-04-14 tracey href_prev = khttp_urlpartx(NULL, NULL, "gotweb", "page",
887 2796ac23 2020-04-14 tracey KATTRX_INT, (int64_t)(gw_trans->page - 1), NULL);
888 19ff7638 2020-04-14 tracey if (href_prev == NULL) {
889 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpartx");
890 19ff7638 2020-04-14 tracey goto done;
891 19ff7638 2020-04-14 tracey }
892 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
893 63ee0dca 2020-02-08 tracey KATTR_HREF, href_prev, KATTR__MAX);
894 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
895 565d9dcb 2020-02-09 tracey goto done;
896 63ee0dca 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Previous");
897 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
898 b3f1f953 2020-02-09 tracey goto done;
899 63ee0dca 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
900 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
901 b3f1f953 2020-02-09 tracey goto done;
902 2c251c14 2020-01-15 tracey }
903 2c251c14 2020-01-15 tracey
904 63ee0dca 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
905 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
906 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
907 2c251c14 2020-01-15 tracey
908 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_max_repos_display > 0 &&
909 2c251c14 2020-01-15 tracey next_disp == gw_trans->gw_conf->got_max_repos_display &&
910 2c251c14 2020-01-15 tracey dir_c != (gw_trans->page + 1) *
911 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_max_repos_display) {
912 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
913 63ee0dca 2020-02-08 tracey KATTR_ID, "nav_next", KATTR__MAX);
914 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
915 b3f1f953 2020-02-09 tracey goto done;
916 2796ac23 2020-04-14 tracey href_next = khttp_urlpartx(NULL, NULL, "gotweb", "page",
917 2796ac23 2020-04-14 tracey KATTRX_INT, (int64_t)(gw_trans->page + 1), NULL);
918 19ff7638 2020-04-14 tracey if (href_next == NULL) {
919 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpartx");
920 19ff7638 2020-04-14 tracey goto done;
921 19ff7638 2020-04-14 tracey }
922 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
923 63ee0dca 2020-02-08 tracey KATTR_HREF, href_next, KATTR__MAX);
924 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
925 b3f1f953 2020-02-09 tracey goto done;
926 63ee0dca 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Next");
927 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
928 b3f1f953 2020-02-09 tracey goto done;
929 63ee0dca 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
930 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
931 b3f1f953 2020-02-09 tracey goto done;
932 2c251c14 2020-01-15 tracey next_disp = 0;
933 2c251c14 2020-01-15 tracey break;
934 2c251c14 2020-01-15 tracey }
935 2c251c14 2020-01-15 tracey
936 2c251c14 2020-01-15 tracey if ((gw_trans->gw_conf->got_max_repos_display > 0) &&
937 2c251c14 2020-01-15 tracey (gw_trans->page > 0) &&
938 2c251c14 2020-01-15 tracey (next_disp == gw_trans->gw_conf->got_max_repos_display ||
939 c25c2314 2020-01-28 stsp prev_disp == gw_trans->repos_total)) {
940 63ee0dca 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
941 565d9dcb 2020-02-09 tracey if (kerr != KCGI_OK)
942 b3f1f953 2020-02-09 tracey goto done;
943 c25c2314 2020-01-28 stsp }
944 2c251c14 2020-01-15 tracey next_disp++;
945 2c251c14 2020-01-15 tracey }
946 b3f1f953 2020-02-09 tracey done:
947 00f13350 2020-02-10 tracey free(href_prev);
948 00f13350 2020-02-10 tracey free(href_next);
949 b3f1f953 2020-02-09 tracey free(href_summary);
950 b3f1f953 2020-02-09 tracey free(href_briefs);
951 b3f1f953 2020-02-09 tracey free(href_commits);
952 ff4bb25f 2020-02-19 tracey free(href_tags);
953 b3f1f953 2020-02-09 tracey free(href_tree);
954 565d9dcb 2020-02-09 tracey if (error == NULL && kerr != KCGI_OK)
955 565d9dcb 2020-02-09 tracey error = gw_kcgi_error(kerr);
956 2c251c14 2020-01-15 tracey return error;
957 2c251c14 2020-01-15 tracey }
958 2c251c14 2020-01-15 tracey
959 2c251c14 2020-01-15 tracey static const struct got_error *
960 f2f46662 2020-01-23 tracey gw_commits(struct gw_trans *gw_trans)
961 2c251c14 2020-01-15 tracey {
962 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
963 f2f46662 2020-01-23 tracey struct gw_header *header = NULL, *n_header = NULL;
964 038dfa29 2020-04-14 tracey char *age = NULL, *href_diff = NULL, *href_tree = NULL;
965 55e46400 2020-02-18 tracey char *href_prev = NULL, *href_next = NULL;
966 21a55cc7 2020-02-04 tracey enum kcgi_err kerr = KCGI_OK;
967 6bee13de 2020-01-16 tracey
968 ae36ed87 2020-01-28 stsp if ((header = gw_init_header()) == NULL)
969 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
970 f2f46662 2020-01-23 tracey
971 6bee13de 2020-01-16 tracey if (pledge("stdio rpath proc exec sendfd unveil",
972 6bee13de 2020-01-16 tracey NULL) == -1) {
973 6bee13de 2020-01-16 tracey error = got_error_from_errno("pledge");
974 5ddf0079 2020-01-29 stsp goto done;
975 6bee13de 2020-01-16 tracey }
976 8087c3c5 2020-01-15 tracey
977 d4159696 2020-02-13 stsp error = gw_apply_unveil(gw_trans->gw_dir->path);
978 8087c3c5 2020-01-15 tracey if (error)
979 5ddf0079 2020-01-29 stsp goto done;
980 2c251c14 2020-01-15 tracey
981 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header,
982 f2f46662 2020-01-23 tracey gw_trans->gw_conf->got_max_commits_display);
983 18da9978 2020-01-29 stsp if (error)
984 18da9978 2020-01-29 stsp goto done;
985 4ceb8155 2020-01-15 tracey
986 f2f46662 2020-01-23 tracey TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry) {
987 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
988 21a55cc7 2020-02-04 tracey "commits_line_wrapper", KATTR__MAX);
989 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
990 18da9978 2020-01-29 stsp goto done;
991 21a55cc7 2020-02-04 tracey error = gw_gen_commit_header(gw_trans, n_header->commit_id,
992 21a55cc7 2020-02-04 tracey n_header->refs_str);
993 f7cc9480 2020-02-05 tracey if (error)
994 f7cc9480 2020-02-05 tracey goto done;
995 21a55cc7 2020-02-04 tracey error = gw_gen_author_header(gw_trans, n_header->author);
996 21a55cc7 2020-02-04 tracey if (error)
997 21a55cc7 2020-02-04 tracey goto done;
998 21a55cc7 2020-02-04 tracey error = gw_gen_committer_header(gw_trans, n_header->author);
999 21a55cc7 2020-02-04 tracey if (error)
1000 21a55cc7 2020-02-04 tracey goto done;
1001 55ccf528 2020-02-03 stsp error = gw_get_time_str(&age, n_header->committer_time,
1002 55ccf528 2020-02-03 stsp TM_LONG);
1003 55ccf528 2020-02-03 stsp if (error)
1004 55ccf528 2020-02-03 stsp goto done;
1005 21a55cc7 2020-02-04 tracey error = gw_gen_age_header(gw_trans, age ?age : "");
1006 21a55cc7 2020-02-04 tracey if (error)
1007 55ccf528 2020-02-03 stsp goto done;
1008 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
1009 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1010 21a55cc7 2020-02-04 tracey goto done;
1011 21a55cc7 2020-02-04 tracey
1012 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1013 21a55cc7 2020-02-04 tracey "dotted_line", KATTR__MAX);
1014 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1015 21a55cc7 2020-02-04 tracey goto done;
1016 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1017 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1018 21a55cc7 2020-02-04 tracey goto done;
1019 21a55cc7 2020-02-04 tracey
1020 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1021 21a55cc7 2020-02-04 tracey "commit", KATTR__MAX);
1022 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1023 21a55cc7 2020-02-04 tracey goto done;
1024 78a9dab5 2020-02-07 tracey kerr = khttp_puts(gw_trans->gw_req, n_header->commit_msg);
1025 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1026 21a55cc7 2020-02-04 tracey goto done;
1027 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1028 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1029 21a55cc7 2020-02-04 tracey goto done;
1030 21a55cc7 2020-02-04 tracey
1031 038dfa29 2020-04-14 tracey href_diff = khttp_urlpart(NULL, NULL, "gotweb", "path",
1032 038dfa29 2020-04-14 tracey gw_trans->repo_name, "action", "diff", "commit",
1033 038dfa29 2020-04-14 tracey n_header->commit_id, NULL);
1034 19ff7638 2020-04-14 tracey if (href_diff == NULL) {
1035 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
1036 19ff7638 2020-04-14 tracey goto done;
1037 19ff7638 2020-04-14 tracey }
1038 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1039 21a55cc7 2020-02-04 tracey KATTR_ID, "navs_wrapper", KATTR__MAX);
1040 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1041 21a55cc7 2020-02-04 tracey goto done;
1042 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1043 21a55cc7 2020-02-04 tracey KATTR_ID, "navs", KATTR__MAX);
1044 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1045 21a55cc7 2020-02-04 tracey goto done;
1046 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1047 21a55cc7 2020-02-04 tracey KATTR_HREF, href_diff, KATTR__MAX);
1048 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1049 21a55cc7 2020-02-04 tracey goto done;
1050 21a55cc7 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, "diff");
1051 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1052 21a55cc7 2020-02-04 tracey goto done;
1053 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1054 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1055 21a55cc7 2020-02-04 tracey goto done;
1056 21a55cc7 2020-02-04 tracey
1057 21a55cc7 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
1058 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1059 21a55cc7 2020-02-04 tracey goto done;
1060 21a55cc7 2020-02-04 tracey
1061 038dfa29 2020-04-14 tracey href_tree = khttp_urlpart(NULL, NULL, "gotweb", "path",
1062 038dfa29 2020-04-14 tracey gw_trans->repo_name, "action", "tree", "commit",
1063 19ff7638 2020-04-14 tracey n_header->commit_id, NULL);
1064 19ff7638 2020-04-14 tracey if (href_tree == NULL) {
1065 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
1066 19ff7638 2020-04-14 tracey goto done;
1067 19ff7638 2020-04-14 tracey }
1068 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1069 038dfa29 2020-04-14 tracey KATTR_HREF, href_tree, KATTR__MAX);
1070 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1071 21a55cc7 2020-02-04 tracey goto done;
1072 21a55cc7 2020-02-04 tracey khtml_puts(gw_trans->gw_html_req, "tree");
1073 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1074 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1075 21a55cc7 2020-02-04 tracey goto done;
1076 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1077 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1078 21a55cc7 2020-02-04 tracey goto done;
1079 21a55cc7 2020-02-04 tracey
1080 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1081 21a55cc7 2020-02-04 tracey "solid_line", KATTR__MAX);
1082 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1083 21a55cc7 2020-02-04 tracey goto done;
1084 b4fba448 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
1085 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1086 21a55cc7 2020-02-04 tracey goto done;
1087 21a55cc7 2020-02-04 tracey
1088 55ccf528 2020-02-03 stsp free(age);
1089 55ccf528 2020-02-03 stsp age = NULL;
1090 55e46400 2020-02-18 tracey }
1091 55e46400 2020-02-18 tracey
1092 55e46400 2020-02-18 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1093 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1094 55e46400 2020-02-18 tracey KATTR_ID, "np_wrapper", KATTR__MAX);
1095 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1096 55e46400 2020-02-18 tracey goto done;
1097 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1098 55e46400 2020-02-18 tracey KATTR_ID, "nav_prev", KATTR__MAX);
1099 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1100 55e46400 2020-02-18 tracey goto done;
1101 f2f46662 2020-01-23 tracey }
1102 55e46400 2020-02-18 tracey
1103 bf4484a3 2020-02-18 tracey if (gw_trans->page > 0 && gw_trans->prev_id) {
1104 038dfa29 2020-04-14 tracey href_prev = khttp_urlpartx(NULL, NULL, "gotweb", "path",
1105 038dfa29 2020-04-14 tracey KATTRX_STRING, gw_trans->repo_name, "page",
1106 038dfa29 2020-04-14 tracey KATTRX_INT, (int64_t) (gw_trans->page - 1), "action",
1107 038dfa29 2020-04-14 tracey KATTRX_STRING, "commits", "commit", KATTRX_STRING,
1108 038dfa29 2020-04-14 tracey gw_trans->prev_id ? gw_trans->prev_id : "", "prev",
1109 038dfa29 2020-04-14 tracey KATTRX_STRING, gw_trans->prev_prev_id ?
1110 038dfa29 2020-04-14 tracey gw_trans->prev_prev_id : "", NULL);
1111 19ff7638 2020-04-14 tracey if (href_prev == NULL) {
1112 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpartx");
1113 19ff7638 2020-04-14 tracey goto done;
1114 19ff7638 2020-04-14 tracey }
1115 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1116 55e46400 2020-02-18 tracey KATTR_HREF, href_prev, KATTR__MAX);
1117 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1118 55e46400 2020-02-18 tracey goto done;
1119 55e46400 2020-02-18 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Previous");
1120 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1121 55e46400 2020-02-18 tracey goto done;
1122 55e46400 2020-02-18 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1123 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1124 55e46400 2020-02-18 tracey goto done;
1125 55e46400 2020-02-18 tracey }
1126 55e46400 2020-02-18 tracey
1127 55e46400 2020-02-18 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1128 55e46400 2020-02-18 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1129 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1130 55e46400 2020-02-18 tracey return gw_kcgi_error(kerr);
1131 55e46400 2020-02-18 tracey }
1132 55e46400 2020-02-18 tracey
1133 55e46400 2020-02-18 tracey if (gw_trans->next_id) {
1134 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1135 55e46400 2020-02-18 tracey KATTR_ID, "nav_next", KATTR__MAX);
1136 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1137 55e46400 2020-02-18 tracey goto done;
1138 038dfa29 2020-04-14 tracey href_next = khttp_urlpartx(NULL, NULL, "gotweb", "path",
1139 038dfa29 2020-04-14 tracey KATTRX_STRING, gw_trans->repo_name, "page",
1140 038dfa29 2020-04-14 tracey KATTRX_INT, (int64_t) (gw_trans->page + 1), "action",
1141 038dfa29 2020-04-14 tracey KATTRX_STRING, "commits", "commit", KATTRX_STRING,
1142 038dfa29 2020-04-14 tracey gw_trans->next_id, "prev", KATTRX_STRING,
1143 55e46400 2020-02-18 tracey gw_trans->next_prev_id ? gw_trans->next_prev_id : "",
1144 038dfa29 2020-04-14 tracey "prev_prev", KATTRX_STRING, gw_trans->prev_prev_id ?
1145 19ff7638 2020-04-14 tracey gw_trans->prev_prev_id : "", NULL);
1146 19ff7638 2020-04-14 tracey if (href_next == NULL) {
1147 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpartx");
1148 19ff7638 2020-04-14 tracey goto done;
1149 19ff7638 2020-04-14 tracey }
1150 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1151 55e46400 2020-02-18 tracey KATTR_HREF, href_next, KATTR__MAX);
1152 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1153 55e46400 2020-02-18 tracey goto done;
1154 55e46400 2020-02-18 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Next");
1155 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1156 55e46400 2020-02-18 tracey goto done;
1157 55e46400 2020-02-18 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
1158 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1159 55e46400 2020-02-18 tracey goto done;
1160 55e46400 2020-02-18 tracey }
1161 55e46400 2020-02-18 tracey
1162 55e46400 2020-02-18 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1163 55e46400 2020-02-18 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
1164 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1165 55e46400 2020-02-18 tracey goto done;
1166 55e46400 2020-02-18 tracey }
1167 18da9978 2020-01-29 stsp done:
1168 b0a1bc86 2020-02-14 stsp gw_free_header(header);
1169 f2f46662 2020-01-23 tracey TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry)
1170 b0a1bc86 2020-02-14 stsp gw_free_header(n_header);
1171 55ccf528 2020-02-03 stsp free(age);
1172 55e46400 2020-02-18 tracey free(href_next);
1173 55e46400 2020-02-18 tracey free(href_prev);
1174 21a55cc7 2020-02-04 tracey free(href_diff);
1175 038dfa29 2020-04-14 tracey free(href_tree);
1176 21a55cc7 2020-02-04 tracey if (error == NULL && kerr != KCGI_OK)
1177 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
1178 2c251c14 2020-01-15 tracey return error;
1179 2c251c14 2020-01-15 tracey }
1180 2c251c14 2020-01-15 tracey
1181 2c251c14 2020-01-15 tracey static const struct got_error *
1182 f2f46662 2020-01-23 tracey gw_briefs(struct gw_trans *gw_trans)
1183 2c251c14 2020-01-15 tracey {
1184 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
1185 bd275801 2020-02-03 tracey struct gw_header *header = NULL, *n_header = NULL;
1186 9ba68833 2020-04-14 tracey char *age = NULL, *href_diff = NULL, *href_tree = NULL;
1187 55e46400 2020-02-18 tracey char *href_prev = NULL, *href_next = NULL;
1188 bd275801 2020-02-03 tracey char *newline, *smallerthan;
1189 ef72fe2c 2020-02-04 stsp enum kcgi_err kerr = KCGI_OK;
1190 17a96b9f 2020-01-15 tracey
1191 ae36ed87 2020-01-28 stsp if ((header = gw_init_header()) == NULL)
1192 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
1193 f2f46662 2020-01-23 tracey
1194 6bee13de 2020-01-16 tracey if (pledge("stdio rpath proc exec sendfd unveil",
1195 6bee13de 2020-01-16 tracey NULL) == -1) {
1196 6bee13de 2020-01-16 tracey error = got_error_from_errno("pledge");
1197 5ddf0079 2020-01-29 stsp goto done;
1198 6bee13de 2020-01-16 tracey }
1199 6bee13de 2020-01-16 tracey
1200 85993e64 2020-02-17 tracey if (gw_trans->action != GW_SUMMARY) {
1201 85993e64 2020-02-17 tracey error = gw_apply_unveil(gw_trans->gw_dir->path);
1202 85993e64 2020-02-17 tracey if (error)
1203 85993e64 2020-02-17 tracey goto done;
1204 85993e64 2020-02-17 tracey }
1205 9d84e7dd 2020-01-15 tracey
1206 f2f46662 2020-01-23 tracey if (gw_trans->action == GW_SUMMARY)
1207 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header, D_MAXSLCOMMDISP);
1208 f2f46662 2020-01-23 tracey else
1209 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header,
1210 f2f46662 2020-01-23 tracey gw_trans->gw_conf->got_max_commits_display);
1211 c25c2314 2020-01-28 stsp if (error)
1212 0e00e8f4 2020-01-29 stsp goto done;
1213 c25c2314 2020-01-28 stsp
1214 f2f46662 2020-01-23 tracey TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry) {
1215 bd275801 2020-02-03 tracey error = gw_get_time_str(&age, n_header->committer_time,
1216 bd275801 2020-02-03 tracey TM_DIFF);
1217 bd275801 2020-02-03 tracey if (error)
1218 bd275801 2020-02-03 tracey goto done;
1219 bd275801 2020-02-03 tracey
1220 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1221 bd275801 2020-02-03 tracey KATTR_ID, "briefs_wrapper", KATTR__MAX);
1222 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1223 bd275801 2020-02-03 tracey goto done;
1224 bd275801 2020-02-03 tracey
1225 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1226 bd275801 2020-02-03 tracey KATTR_ID, "briefs_age", KATTR__MAX);
1227 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1228 bd275801 2020-02-03 tracey goto done;
1229 53e81e48 2020-02-13 tracey kerr = khtml_puts(gw_trans->gw_html_req, age ? age : "");
1230 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1231 bd275801 2020-02-03 tracey goto done;
1232 bd275801 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1233 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1234 bd275801 2020-02-03 tracey goto done;
1235 bd275801 2020-02-03 tracey
1236 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1237 bd275801 2020-02-03 tracey KATTR_ID, "briefs_author", KATTR__MAX);
1238 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1239 bd275801 2020-02-03 tracey goto done;
1240 bd275801 2020-02-03 tracey smallerthan = strchr(n_header->author, '<');
1241 bd275801 2020-02-03 tracey if (smallerthan)
1242 bd275801 2020-02-03 tracey *smallerthan = '\0';
1243 bd275801 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, n_header->author);
1244 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1245 bd275801 2020-02-03 tracey goto done;
1246 bd275801 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1247 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1248 bd275801 2020-02-03 tracey goto done;
1249 bd275801 2020-02-03 tracey
1250 9ba68833 2020-04-14 tracey href_diff = khttp_urlpart(NULL, NULL, "gotweb", "path",
1251 9ba68833 2020-04-14 tracey gw_trans->repo_name, "action", "diff", "commit",
1252 9ba68833 2020-04-14 tracey n_header->commit_id, NULL);
1253 19ff7638 2020-04-14 tracey if (href_diff == NULL) {
1254 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
1255 19ff7638 2020-04-14 tracey goto done;
1256 19ff7638 2020-04-14 tracey }
1257 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1258 bd275801 2020-02-03 tracey KATTR_ID, "briefs_log", KATTR__MAX);
1259 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1260 bd275801 2020-02-03 tracey goto done;
1261 f2f46662 2020-01-23 tracey newline = strchr(n_header->commit_msg, '\n');
1262 f2f46662 2020-01-23 tracey if (newline)
1263 f2f46662 2020-01-23 tracey *newline = '\0';
1264 52f8346c 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1265 52f8346c 2020-02-03 tracey KATTR_HREF, href_diff, KATTR__MAX);
1266 52f8346c 2020-02-03 tracey if (kerr != KCGI_OK)
1267 52f8346c 2020-02-03 tracey goto done;
1268 bd275801 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, n_header->commit_msg);
1269 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1270 55ccf528 2020-02-03 stsp goto done;
1271 bf93a5c0 2020-02-15 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1272 bf93a5c0 2020-02-15 tracey if (kerr != KCGI_OK)
1273 bf93a5c0 2020-02-15 tracey goto done;
1274 bf93a5c0 2020-02-15 tracey
1275 bf93a5c0 2020-02-15 tracey if (n_header->refs_str) {
1276 bf93a5c0 2020-02-15 tracey kerr = khtml_puts(gw_trans->gw_html_req, " ");
1277 bf93a5c0 2020-02-15 tracey if (kerr != KCGI_OK)
1278 bf93a5c0 2020-02-15 tracey goto done;
1279 bf93a5c0 2020-02-15 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_SPAN,
1280 bf93a5c0 2020-02-15 tracey KATTR_ID, "refs_str", KATTR__MAX);
1281 bf93a5c0 2020-02-15 tracey if (kerr != KCGI_OK)
1282 bf93a5c0 2020-02-15 tracey goto done;
1283 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(gw_trans->gw_html_req, "(%s)",
1284 bf93a5c0 2020-02-15 tracey n_header->refs_str);
1285 bf93a5c0 2020-02-15 tracey if (kerr != KCGI_OK)
1286 bf93a5c0 2020-02-15 tracey goto done;
1287 bf93a5c0 2020-02-15 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1288 bf93a5c0 2020-02-15 tracey if (kerr != KCGI_OK)
1289 bf93a5c0 2020-02-15 tracey goto done;
1290 bf93a5c0 2020-02-15 tracey }
1291 bf93a5c0 2020-02-15 tracey
1292 bf93a5c0 2020-02-15 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1293 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1294 bd275801 2020-02-03 tracey goto done;
1295 bd275801 2020-02-03 tracey
1296 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1297 bd275801 2020-02-03 tracey KATTR_ID, "navs_wrapper", KATTR__MAX);
1298 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1299 bd275801 2020-02-03 tracey goto done;
1300 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1301 bd275801 2020-02-03 tracey KATTR_ID, "navs", KATTR__MAX);
1302 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1303 bd275801 2020-02-03 tracey goto done;
1304 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1305 bd275801 2020-02-03 tracey KATTR_HREF, href_diff, KATTR__MAX);
1306 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1307 070fee27 2020-02-03 stsp goto done;
1308 bd275801 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, "diff");
1309 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1310 bd275801 2020-02-03 tracey goto done;
1311 bd275801 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1312 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1313 bd275801 2020-02-03 tracey goto done;
1314 bd275801 2020-02-03 tracey
1315 bd275801 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
1316 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1317 bd275801 2020-02-03 tracey goto done;
1318 bd275801 2020-02-03 tracey
1319 9ba68833 2020-04-14 tracey href_tree = khttp_urlpart(NULL, NULL, "gotweb", "path",
1320 9ba68833 2020-04-14 tracey gw_trans->repo_name, "action", "tree", "commit",
1321 9ba68833 2020-04-14 tracey n_header->commit_id, NULL);
1322 19ff7638 2020-04-14 tracey if (href_tree == NULL) {
1323 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
1324 19ff7638 2020-04-14 tracey goto done;
1325 19ff7638 2020-04-14 tracey }
1326 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1327 9ba68833 2020-04-14 tracey KATTR_HREF, href_tree, KATTR__MAX);
1328 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1329 bd275801 2020-02-03 tracey goto done;
1330 bd275801 2020-02-03 tracey khtml_puts(gw_trans->gw_html_req, "tree");
1331 bd275801 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1332 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1333 bd275801 2020-02-03 tracey goto done;
1334 bd275801 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1335 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1336 bd275801 2020-02-03 tracey goto done;
1337 bd275801 2020-02-03 tracey
1338 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1339 bd275801 2020-02-03 tracey KATTR_ID, "dotted_line", KATTR__MAX);
1340 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1341 bd275801 2020-02-03 tracey goto done;
1342 bd275801 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
1343 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
1344 bd275801 2020-02-03 tracey goto done;
1345 bd275801 2020-02-03 tracey
1346 55ccf528 2020-02-03 stsp free(age);
1347 55ccf528 2020-02-03 stsp age = NULL;
1348 bd275801 2020-02-03 tracey free(href_diff);
1349 bd275801 2020-02-03 tracey href_diff = NULL;
1350 9ba68833 2020-04-14 tracey free(href_tree);
1351 9ba68833 2020-04-14 tracey href_tree = NULL;
1352 55e46400 2020-02-18 tracey }
1353 55e46400 2020-02-18 tracey
1354 55e46400 2020-02-18 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1355 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1356 55e46400 2020-02-18 tracey KATTR_ID, "np_wrapper", KATTR__MAX);
1357 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1358 55e46400 2020-02-18 tracey goto done;
1359 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1360 55e46400 2020-02-18 tracey KATTR_ID, "nav_prev", KATTR__MAX);
1361 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1362 55e46400 2020-02-18 tracey goto done;
1363 55e46400 2020-02-18 tracey }
1364 55e46400 2020-02-18 tracey
1365 bf4484a3 2020-02-18 tracey if (gw_trans->page > 0 && gw_trans->prev_id) {
1366 9ba68833 2020-04-14 tracey href_prev = khttp_urlpartx(NULL, NULL, "gotweb", "path",
1367 9ba68833 2020-04-14 tracey KATTRX_STRING, gw_trans->repo_name, "page",
1368 9ba68833 2020-04-14 tracey KATTRX_INT, (int64_t) (gw_trans->page - 1), "action",
1369 9ba68833 2020-04-14 tracey KATTRX_STRING, "briefs", "commit", KATTRX_STRING,
1370 9ba68833 2020-04-14 tracey gw_trans->prev_id ? gw_trans->prev_id : "", "prev",
1371 9ba68833 2020-04-14 tracey KATTRX_STRING, gw_trans->prev_prev_id ?
1372 9ba68833 2020-04-14 tracey gw_trans->prev_prev_id : "", NULL);
1373 19ff7638 2020-04-14 tracey if (href_prev == NULL) {
1374 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpartx");
1375 19ff7638 2020-04-14 tracey goto done;
1376 19ff7638 2020-04-14 tracey }
1377 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1378 55e46400 2020-02-18 tracey KATTR_HREF, href_prev, KATTR__MAX);
1379 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1380 55e46400 2020-02-18 tracey goto done;
1381 55e46400 2020-02-18 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Previous");
1382 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1383 55e46400 2020-02-18 tracey goto done;
1384 55e46400 2020-02-18 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1385 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1386 55e46400 2020-02-18 tracey goto done;
1387 9d84e7dd 2020-01-15 tracey }
1388 55e46400 2020-02-18 tracey
1389 55e46400 2020-02-18 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1390 55e46400 2020-02-18 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1391 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1392 55e46400 2020-02-18 tracey return gw_kcgi_error(kerr);
1393 55e46400 2020-02-18 tracey }
1394 55e46400 2020-02-18 tracey
1395 55e46400 2020-02-18 tracey if (gw_trans->next_id) {
1396 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1397 55e46400 2020-02-18 tracey KATTR_ID, "nav_next", KATTR__MAX);
1398 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1399 55e46400 2020-02-18 tracey goto done;
1400 9ba68833 2020-04-14 tracey
1401 9ba68833 2020-04-14 tracey href_next = khttp_urlpartx(NULL, NULL, "gotweb", "path",
1402 9ba68833 2020-04-14 tracey KATTRX_STRING, gw_trans->repo_name, "page",
1403 9ba68833 2020-04-14 tracey KATTRX_INT, (int64_t) (gw_trans->page + 1), "action",
1404 9ba68833 2020-04-14 tracey KATTRX_STRING, "briefs", "commit", KATTRX_STRING,
1405 9ba68833 2020-04-14 tracey gw_trans->next_id, "prev", KATTRX_STRING,
1406 55e46400 2020-02-18 tracey gw_trans->next_prev_id ? gw_trans->next_prev_id : "",
1407 9ba68833 2020-04-14 tracey "prev_prev", KATTRX_STRING, gw_trans->prev_id ?
1408 19ff7638 2020-04-14 tracey gw_trans->prev_id : "", NULL);
1409 19ff7638 2020-04-14 tracey if (href_next == NULL) {
1410 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpartx");
1411 19ff7638 2020-04-14 tracey goto done;
1412 19ff7638 2020-04-14 tracey }
1413 55e46400 2020-02-18 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1414 55e46400 2020-02-18 tracey KATTR_HREF, href_next, KATTR__MAX);
1415 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1416 55e46400 2020-02-18 tracey goto done;
1417 55e46400 2020-02-18 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Next");
1418 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1419 55e46400 2020-02-18 tracey goto done;
1420 55e46400 2020-02-18 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
1421 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1422 55e46400 2020-02-18 tracey goto done;
1423 55e46400 2020-02-18 tracey }
1424 55e46400 2020-02-18 tracey
1425 55e46400 2020-02-18 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1426 55e46400 2020-02-18 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
1427 55e46400 2020-02-18 tracey if (kerr != KCGI_OK)
1428 55e46400 2020-02-18 tracey goto done;
1429 55e46400 2020-02-18 tracey }
1430 0e00e8f4 2020-01-29 stsp done:
1431 b0a1bc86 2020-02-14 stsp gw_free_header(header);
1432 f2f46662 2020-01-23 tracey TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry)
1433 b0a1bc86 2020-02-14 stsp gw_free_header(n_header);
1434 55ccf528 2020-02-03 stsp free(age);
1435 55e46400 2020-02-18 tracey free(href_next);
1436 55e46400 2020-02-18 tracey free(href_prev);
1437 bd275801 2020-02-03 tracey free(href_diff);
1438 9ba68833 2020-04-14 tracey free(href_tree);
1439 ef72fe2c 2020-02-04 stsp if (error == NULL && kerr != KCGI_OK)
1440 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
1441 2c251c14 2020-01-15 tracey return error;
1442 2c251c14 2020-01-15 tracey }
1443 2c251c14 2020-01-15 tracey
1444 2c251c14 2020-01-15 tracey static const struct got_error *
1445 54415d85 2020-01-15 tracey gw_summary(struct gw_trans *gw_trans)
1446 387a29ba 2020-01-15 tracey {
1447 387a29ba 2020-01-15 tracey const struct got_error *error = NULL;
1448 9eed6f10 2020-02-08 tracey char *age = NULL;
1449 21a55cc7 2020-02-04 tracey enum kcgi_err kerr = KCGI_OK;
1450 387a29ba 2020-01-15 tracey
1451 f4df82f9 2020-01-29 stsp if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
1452 f4df82f9 2020-01-29 stsp return got_error_from_errno("pledge");
1453 6bee13de 2020-01-16 tracey
1454 85993e64 2020-02-17 tracey error = gw_apply_unveil(gw_trans->gw_dir->path);
1455 85993e64 2020-02-17 tracey if (error)
1456 85993e64 2020-02-17 tracey goto done;
1457 46b9c89b 2020-01-15 tracey
1458 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1459 783ec107 2020-02-03 tracey "summary_wrapper", KATTR__MAX);
1460 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
1461 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
1462 c25c2314 2020-01-28 stsp
1463 783ec107 2020-02-03 tracey if (gw_trans->gw_conf->got_show_repo_description &&
1464 783ec107 2020-02-03 tracey gw_trans->gw_dir->description != NULL &&
1465 783ec107 2020-02-03 tracey (strcmp(gw_trans->gw_dir->description, "") != 0)) {
1466 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1467 783ec107 2020-02-03 tracey KATTR_ID, "description_title", KATTR__MAX);
1468 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1469 783ec107 2020-02-03 tracey goto done;
1470 783ec107 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Description: ");
1471 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1472 783ec107 2020-02-03 tracey goto done;
1473 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1474 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1475 783ec107 2020-02-03 tracey goto done;
1476 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1477 783ec107 2020-02-03 tracey KATTR_ID, "description", KATTR__MAX);
1478 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1479 783ec107 2020-02-03 tracey goto done;
1480 783ec107 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req,
1481 783ec107 2020-02-03 tracey gw_trans->gw_dir->description);
1482 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1483 783ec107 2020-02-03 tracey goto done;
1484 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1485 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1486 783ec107 2020-02-03 tracey goto done;
1487 46b9c89b 2020-01-15 tracey }
1488 46b9c89b 2020-01-15 tracey
1489 9a1cc63f 2020-02-03 stsp if (gw_trans->gw_conf->got_show_repo_owner &&
1490 a942aa37 2020-02-10 tracey gw_trans->gw_dir->owner != NULL &&
1491 a942aa37 2020-02-10 tracey (strcmp(gw_trans->gw_dir->owner, "") != 0)) {
1492 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1493 783ec107 2020-02-03 tracey KATTR_ID, "repo_owner_title", KATTR__MAX);
1494 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1495 9a1cc63f 2020-02-03 stsp goto done;
1496 783ec107 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Owner: ");
1497 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1498 9a1cc63f 2020-02-03 stsp goto done;
1499 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1500 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1501 783ec107 2020-02-03 tracey goto done;
1502 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1503 783ec107 2020-02-03 tracey KATTR_ID, "repo_owner", KATTR__MAX);
1504 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1505 783ec107 2020-02-03 tracey goto done;
1506 783ec107 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req,
1507 62d463ca 2020-10-20 naddy gw_trans->gw_dir->owner);
1508 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1509 783ec107 2020-02-03 tracey goto done;
1510 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1511 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1512 783ec107 2020-02-03 tracey goto done;
1513 46b9c89b 2020-01-15 tracey }
1514 46b9c89b 2020-01-15 tracey
1515 46b9c89b 2020-01-15 tracey if (gw_trans->gw_conf->got_show_repo_age) {
1516 d126c1b7 2020-01-29 stsp error = gw_get_repo_age(&age, gw_trans, gw_trans->gw_dir->path,
1517 2011c142 2020-02-14 stsp NULL, TM_LONG);
1518 d126c1b7 2020-01-29 stsp if (error)
1519 20f34652 2020-01-29 stsp goto done;
1520 55ccf528 2020-02-03 stsp if (age != NULL) {
1521 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1522 783ec107 2020-02-03 tracey KATTR_ID, "last_change_title", KATTR__MAX);
1523 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1524 20f34652 2020-01-29 stsp goto done;
1525 783ec107 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req,
1526 783ec107 2020-02-03 tracey "Last Change: ");
1527 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1528 20f34652 2020-01-29 stsp goto done;
1529 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1530 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1531 20f34652 2020-01-29 stsp goto done;
1532 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1533 783ec107 2020-02-03 tracey KATTR_ID, "last_change", KATTR__MAX);
1534 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1535 20f34652 2020-01-29 stsp goto done;
1536 783ec107 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, age);
1537 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1538 783ec107 2020-02-03 tracey goto done;
1539 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1540 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1541 783ec107 2020-02-03 tracey goto done;
1542 46b9c89b 2020-01-15 tracey }
1543 46b9c89b 2020-01-15 tracey }
1544 783ec107 2020-02-03 tracey
1545 783ec107 2020-02-03 tracey if (gw_trans->gw_conf->got_show_repo_cloneurl &&
1546 783ec107 2020-02-03 tracey gw_trans->gw_dir->url != NULL &&
1547 783ec107 2020-02-03 tracey (strcmp(gw_trans->gw_dir->url, "") != 0)) {
1548 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1549 783ec107 2020-02-03 tracey KATTR_ID, "cloneurl_title", KATTR__MAX);
1550 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1551 783ec107 2020-02-03 tracey goto done;
1552 783ec107 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Clone URL: ");
1553 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1554 783ec107 2020-02-03 tracey goto done;
1555 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1556 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1557 783ec107 2020-02-03 tracey goto done;
1558 783ec107 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1559 783ec107 2020-02-03 tracey KATTR_ID, "cloneurl", KATTR__MAX);
1560 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1561 783ec107 2020-02-03 tracey goto done;
1562 783ec107 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, gw_trans->gw_dir->url);
1563 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1564 21a55cc7 2020-02-04 tracey goto done;
1565 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1566 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1567 783ec107 2020-02-03 tracey goto done;
1568 783ec107 2020-02-03 tracey }
1569 783ec107 2020-02-03 tracey
1570 783ec107 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1571 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1572 bd275801 2020-02-03 tracey goto done;
1573 bd275801 2020-02-03 tracey
1574 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1575 bd275801 2020-02-03 tracey "briefs_title_wrapper", KATTR__MAX);
1576 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1577 bd275801 2020-02-03 tracey goto done;
1578 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1579 bd275801 2020-02-03 tracey "briefs_title", KATTR__MAX);
1580 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1581 20f34652 2020-01-29 stsp goto done;
1582 bd275801 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Commit Briefs");
1583 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1584 bd275801 2020-02-03 tracey goto done;
1585 bd275801 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
1586 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
1587 bd275801 2020-02-03 tracey goto done;
1588 f2f46662 2020-01-23 tracey error = gw_briefs(gw_trans);
1589 f2f46662 2020-01-23 tracey if (error)
1590 20f34652 2020-01-29 stsp goto done;
1591 f2f46662 2020-01-23 tracey
1592 ff4bb25f 2020-02-19 tracey error = gw_tags(gw_trans);
1593 6eccd105 2020-02-03 stsp if (error)
1594 6eccd105 2020-02-03 stsp goto done;
1595 8d4d2453 2020-01-15 tracey
1596 9eed6f10 2020-02-08 tracey error = gw_output_repo_heads(gw_trans);
1597 20f34652 2020-01-29 stsp done:
1598 20f34652 2020-01-29 stsp free(age);
1599 f7cc9480 2020-02-05 tracey if (error == NULL && kerr != KCGI_OK)
1600 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
1601 2204c934 2020-01-15 tracey return error;
1602 2204c934 2020-01-15 tracey }
1603 2204c934 2020-01-15 tracey
1604 2204c934 2020-01-15 tracey static const struct got_error *
1605 f2f46662 2020-01-23 tracey gw_tree(struct gw_trans *gw_trans)
1606 b772de24 2020-01-15 tracey {
1607 b772de24 2020-01-15 tracey const struct got_error *error = NULL;
1608 f2f46662 2020-01-23 tracey struct gw_header *header = NULL;
1609 f2f46662 2020-01-23 tracey char *tree = NULL, *tree_html = NULL, *tree_html_disp = NULL;
1610 53e81e48 2020-02-13 tracey char *age = NULL;
1611 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
1612 6bee13de 2020-01-16 tracey
1613 f2f46662 2020-01-23 tracey if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
1614 f2f46662 2020-01-23 tracey return got_error_from_errno("pledge");
1615 b772de24 2020-01-15 tracey
1616 ae36ed87 2020-01-28 stsp if ((header = gw_init_header()) == NULL)
1617 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
1618 f2f46662 2020-01-23 tracey
1619 d4159696 2020-02-13 stsp error = gw_apply_unveil(gw_trans->gw_dir->path);
1620 b772de24 2020-01-15 tracey if (error)
1621 5ddf0079 2020-01-29 stsp goto done;
1622 b772de24 2020-01-15 tracey
1623 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header, 1);
1624 f2f46662 2020-01-23 tracey if (error)
1625 42281175 2020-01-29 stsp goto done;
1626 b772de24 2020-01-15 tracey
1627 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1628 626b25b6 2020-02-06 tracey "tree_header_wrapper", KATTR__MAX);
1629 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
1630 55ccf528 2020-02-03 stsp goto done;
1631 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1632 626b25b6 2020-02-06 tracey "tree_header", KATTR__MAX);
1633 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
1634 55ccf528 2020-02-03 stsp goto done;
1635 626b25b6 2020-02-06 tracey error = gw_gen_tree_header(gw_trans, header->tree_id);
1636 626b25b6 2020-02-06 tracey if (error)
1637 626b25b6 2020-02-06 tracey goto done;
1638 626b25b6 2020-02-06 tracey error = gw_get_time_str(&age, header->committer_time,
1639 626b25b6 2020-02-06 tracey TM_LONG);
1640 626b25b6 2020-02-06 tracey if (error)
1641 626b25b6 2020-02-06 tracey goto done;
1642 626b25b6 2020-02-06 tracey error = gw_gen_age_header(gw_trans, age ?age : "");
1643 070fee27 2020-02-03 stsp if (error)
1644 070fee27 2020-02-03 stsp goto done;
1645 626b25b6 2020-02-06 tracey error = gw_gen_commit_msg_header(gw_trans, header->commit_msg);
1646 626b25b6 2020-02-06 tracey if (error)
1647 42281175 2020-01-29 stsp goto done;
1648 626b25b6 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
1649 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
1650 42281175 2020-01-29 stsp goto done;
1651 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1652 626b25b6 2020-02-06 tracey "dotted_line", KATTR__MAX);
1653 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
1654 626b25b6 2020-02-06 tracey goto done;
1655 626b25b6 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1656 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
1657 626b25b6 2020-02-06 tracey goto done;
1658 626b25b6 2020-02-06 tracey
1659 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1660 626b25b6 2020-02-06 tracey "tree", KATTR__MAX);
1661 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
1662 626b25b6 2020-02-06 tracey goto done;
1663 84de9106 2020-12-26 stsp error = gw_output_repo_tree(gw_trans, header);
1664 626b25b6 2020-02-06 tracey if (error)
1665 626b25b6 2020-02-06 tracey goto done;
1666 626b25b6 2020-02-06 tracey
1667 626b25b6 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1668 4ff7391f 2020-01-28 tracey done:
1669 b0a1bc86 2020-02-14 stsp gw_free_header(header);
1670 f2f46662 2020-01-23 tracey free(tree_html_disp);
1671 f2f46662 2020-01-23 tracey free(tree_html);
1672 f2f46662 2020-01-23 tracey free(tree);
1673 55ccf528 2020-02-03 stsp free(age);
1674 ff4bb25f 2020-02-19 tracey if (error == NULL && kerr != KCGI_OK)
1675 ff4bb25f 2020-02-19 tracey error = gw_kcgi_error(kerr);
1676 ff4bb25f 2020-02-19 tracey return error;
1677 ff4bb25f 2020-02-19 tracey }
1678 ff4bb25f 2020-02-19 tracey
1679 ff4bb25f 2020-02-19 tracey static const struct got_error *
1680 ff4bb25f 2020-02-19 tracey gw_tags(struct gw_trans *gw_trans)
1681 ff4bb25f 2020-02-19 tracey {
1682 ff4bb25f 2020-02-19 tracey const struct got_error *error = NULL;
1683 ff4bb25f 2020-02-19 tracey struct gw_header *header = NULL;
1684 ff4bb25f 2020-02-19 tracey char *href_next = NULL, *href_prev = NULL;
1685 ff4bb25f 2020-02-19 tracey enum kcgi_err kerr = KCGI_OK;
1686 ff4bb25f 2020-02-19 tracey
1687 ff4bb25f 2020-02-19 tracey if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
1688 ff4bb25f 2020-02-19 tracey return got_error_from_errno("pledge");
1689 ff4bb25f 2020-02-19 tracey
1690 ff4bb25f 2020-02-19 tracey if ((header = gw_init_header()) == NULL)
1691 ff4bb25f 2020-02-19 tracey return got_error_from_errno("malloc");
1692 ff4bb25f 2020-02-19 tracey
1693 ff4bb25f 2020-02-19 tracey if (gw_trans->action != GW_SUMMARY) {
1694 ff4bb25f 2020-02-19 tracey error = gw_apply_unveil(gw_trans->gw_dir->path);
1695 ff4bb25f 2020-02-19 tracey if (error)
1696 ff4bb25f 2020-02-19 tracey goto done;
1697 ff4bb25f 2020-02-19 tracey }
1698 ff4bb25f 2020-02-19 tracey
1699 ff4bb25f 2020-02-19 tracey error = gw_get_header(gw_trans, header, 1);
1700 ff4bb25f 2020-02-19 tracey if (error)
1701 ff4bb25f 2020-02-19 tracey goto done;
1702 ff4bb25f 2020-02-19 tracey
1703 ff4bb25f 2020-02-19 tracey if (gw_trans->action == GW_SUMMARY) {
1704 7b1f04a6 2020-03-11 tracey gw_trans->next_id = NULL;
1705 ff4bb25f 2020-02-19 tracey error = gw_output_repo_tags(gw_trans, header,
1706 ff4bb25f 2020-02-19 tracey D_MAXSLCOMMDISP, TAGBRIEF);
1707 ff4bb25f 2020-02-19 tracey if (error)
1708 ff4bb25f 2020-02-19 tracey goto done;
1709 ff4bb25f 2020-02-19 tracey } else {
1710 ff4bb25f 2020-02-19 tracey error = gw_output_repo_tags(gw_trans, header,
1711 ff4bb25f 2020-02-19 tracey gw_trans->gw_conf->got_max_commits_display, TAGBRIEF);
1712 ff4bb25f 2020-02-19 tracey if (error)
1713 ff4bb25f 2020-02-19 tracey goto done;
1714 ff4bb25f 2020-02-19 tracey }
1715 ff4bb25f 2020-02-19 tracey
1716 ff4bb25f 2020-02-19 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1717 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1718 ff4bb25f 2020-02-19 tracey KATTR_ID, "np_wrapper", KATTR__MAX);
1719 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1720 ff4bb25f 2020-02-19 tracey goto done;
1721 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1722 ff4bb25f 2020-02-19 tracey KATTR_ID, "nav_prev", KATTR__MAX);
1723 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1724 ff4bb25f 2020-02-19 tracey goto done;
1725 ff4bb25f 2020-02-19 tracey }
1726 ff4bb25f 2020-02-19 tracey
1727 ff4bb25f 2020-02-19 tracey if (gw_trans->page > 0 && gw_trans->prev_id) {
1728 f7632464 2020-04-14 tracey href_prev = khttp_urlpartx(NULL, NULL, "gotweb", "path",
1729 f7632464 2020-04-14 tracey KATTRX_STRING, gw_trans->repo_name, "page",
1730 f7632464 2020-04-14 tracey KATTRX_INT, (int64_t) (gw_trans->page - 1), "action",
1731 f7632464 2020-04-14 tracey KATTRX_STRING, "tags", "commit", KATTRX_STRING,
1732 f7632464 2020-04-14 tracey gw_trans->prev_id ? gw_trans->prev_id : "", "prev",
1733 f7632464 2020-04-14 tracey KATTRX_STRING, gw_trans->prev_prev_id ?
1734 f7632464 2020-04-14 tracey gw_trans->prev_prev_id : "", NULL);
1735 19ff7638 2020-04-14 tracey if (href_prev == NULL) {
1736 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpartx");
1737 19ff7638 2020-04-14 tracey goto done;
1738 19ff7638 2020-04-14 tracey }
1739 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1740 ff4bb25f 2020-02-19 tracey KATTR_HREF, href_prev, KATTR__MAX);
1741 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1742 ff4bb25f 2020-02-19 tracey goto done;
1743 ff4bb25f 2020-02-19 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Previous");
1744 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1745 ff4bb25f 2020-02-19 tracey goto done;
1746 ff4bb25f 2020-02-19 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1747 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1748 ff4bb25f 2020-02-19 tracey goto done;
1749 ff4bb25f 2020-02-19 tracey }
1750 ff4bb25f 2020-02-19 tracey
1751 ff4bb25f 2020-02-19 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1752 ff4bb25f 2020-02-19 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1753 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1754 ff4bb25f 2020-02-19 tracey return gw_kcgi_error(kerr);
1755 ff4bb25f 2020-02-19 tracey }
1756 ff4bb25f 2020-02-19 tracey
1757 ff4bb25f 2020-02-19 tracey if (gw_trans->next_id) {
1758 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
1759 ff4bb25f 2020-02-19 tracey KATTR_ID, "nav_next", KATTR__MAX);
1760 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1761 ff4bb25f 2020-02-19 tracey goto done;
1762 f7632464 2020-04-14 tracey href_next = khttp_urlpartx(NULL, NULL, "gotweb", "path",
1763 f7632464 2020-04-14 tracey KATTRX_STRING, gw_trans->repo_name, "page",
1764 f7632464 2020-04-14 tracey KATTRX_INT, (int64_t) (gw_trans->page + 1), "action",
1765 f7632464 2020-04-14 tracey KATTRX_STRING, "tags", "commit", KATTRX_STRING,
1766 f7632464 2020-04-14 tracey gw_trans->next_id, "prev", KATTRX_STRING,
1767 ff4bb25f 2020-02-19 tracey gw_trans->next_prev_id ? gw_trans->next_prev_id : "",
1768 f7632464 2020-04-14 tracey "prev_prev", KATTRX_STRING, gw_trans->prev_id ?
1769 f7632464 2020-04-14 tracey gw_trans->prev_id : "", NULL);
1770 19ff7638 2020-04-14 tracey if (href_next == NULL) {
1771 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpartx");
1772 19ff7638 2020-04-14 tracey goto done;
1773 19ff7638 2020-04-14 tracey }
1774 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
1775 ff4bb25f 2020-02-19 tracey KATTR_HREF, href_next, KATTR__MAX);
1776 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1777 ff4bb25f 2020-02-19 tracey goto done;
1778 ff4bb25f 2020-02-19 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Next");
1779 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1780 ff4bb25f 2020-02-19 tracey goto done;
1781 ff4bb25f 2020-02-19 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
1782 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1783 ff4bb25f 2020-02-19 tracey goto done;
1784 ff4bb25f 2020-02-19 tracey }
1785 ff4bb25f 2020-02-19 tracey
1786 ff4bb25f 2020-02-19 tracey if (gw_trans->next_id || gw_trans->page > 0) {
1787 ff4bb25f 2020-02-19 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
1788 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
1789 ff4bb25f 2020-02-19 tracey goto done;
1790 ff4bb25f 2020-02-19 tracey }
1791 ff4bb25f 2020-02-19 tracey done:
1792 ff4bb25f 2020-02-19 tracey gw_free_header(header);
1793 ff4bb25f 2020-02-19 tracey free(href_next);
1794 ff4bb25f 2020-02-19 tracey free(href_prev);
1795 626b25b6 2020-02-06 tracey if (error == NULL && kerr != KCGI_OK)
1796 626b25b6 2020-02-06 tracey error = gw_kcgi_error(kerr);
1797 4ff7391f 2020-01-28 tracey return error;
1798 4ff7391f 2020-01-28 tracey }
1799 4ff7391f 2020-01-28 tracey
1800 4ff7391f 2020-01-28 tracey static const struct got_error *
1801 4ff7391f 2020-01-28 tracey gw_tag(struct gw_trans *gw_trans)
1802 4ff7391f 2020-01-28 tracey {
1803 4ff7391f 2020-01-28 tracey const struct got_error *error = NULL;
1804 4ff7391f 2020-01-28 tracey struct gw_header *header = NULL;
1805 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
1806 4ff7391f 2020-01-28 tracey
1807 4ff7391f 2020-01-28 tracey if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
1808 4ff7391f 2020-01-28 tracey return got_error_from_errno("pledge");
1809 4ff7391f 2020-01-28 tracey
1810 4ff7391f 2020-01-28 tracey if ((header = gw_init_header()) == NULL)
1811 4ff7391f 2020-01-28 tracey return got_error_from_errno("malloc");
1812 4ff7391f 2020-01-28 tracey
1813 d4159696 2020-02-13 stsp error = gw_apply_unveil(gw_trans->gw_dir->path);
1814 4ff7391f 2020-01-28 tracey if (error)
1815 5ddf0079 2020-01-29 stsp goto done;
1816 4ff7391f 2020-01-28 tracey
1817 9f33591a 2020-02-14 tracey if (gw_trans->commit_id == NULL) {
1818 9f33591a 2020-02-14 tracey error = got_error_msg(GOT_ERR_QUERYSTRING,
1819 9f33591a 2020-02-14 tracey "commit required in querystring");
1820 9f33591a 2020-02-14 tracey goto done;
1821 9f33591a 2020-02-14 tracey }
1822 9f33591a 2020-02-14 tracey
1823 4ff7391f 2020-01-28 tracey error = gw_get_header(gw_trans, header, 1);
1824 4ff7391f 2020-01-28 tracey if (error)
1825 470cd826 2020-01-29 stsp goto done;
1826 4ff7391f 2020-01-28 tracey
1827 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1828 38b240fb 2020-02-06 tracey "tag_header_wrapper", KATTR__MAX);
1829 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
1830 38b240fb 2020-02-06 tracey goto done;
1831 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1832 38b240fb 2020-02-06 tracey "tag_header", KATTR__MAX);
1833 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
1834 38b240fb 2020-02-06 tracey goto done;
1835 38b240fb 2020-02-06 tracey error = gw_gen_commit_header(gw_trans, header->commit_id,
1836 38b240fb 2020-02-06 tracey header->refs_str);
1837 6eccd105 2020-02-03 stsp if (error)
1838 6eccd105 2020-02-03 stsp goto done;
1839 38b240fb 2020-02-06 tracey error = gw_gen_commit_msg_header(gw_trans, header->commit_msg);
1840 38b240fb 2020-02-06 tracey if (error)
1841 470cd826 2020-01-29 stsp goto done;
1842 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
1843 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
1844 470cd826 2020-01-29 stsp goto done;
1845 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1846 38b240fb 2020-02-06 tracey "dotted_line", KATTR__MAX);
1847 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
1848 38b240fb 2020-02-06 tracey goto done;
1849 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1850 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
1851 38b240fb 2020-02-06 tracey goto done;
1852 4ff7391f 2020-01-28 tracey
1853 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
1854 38b240fb 2020-02-06 tracey "tree", KATTR__MAX);
1855 4ff7391f 2020-01-28 tracey if (kerr != KCGI_OK)
1856 38b240fb 2020-02-06 tracey goto done;
1857 38b240fb 2020-02-06 tracey
1858 38b240fb 2020-02-06 tracey error = gw_output_repo_tags(gw_trans, header, 1, TAGFULL);
1859 38b240fb 2020-02-06 tracey if (error)
1860 38b240fb 2020-02-06 tracey goto done;
1861 38b240fb 2020-02-06 tracey
1862 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
1863 4ff7391f 2020-01-28 tracey done:
1864 b0a1bc86 2020-02-14 stsp gw_free_header(header);
1865 38b240fb 2020-02-06 tracey if (error == NULL && kerr != KCGI_OK)
1866 38b240fb 2020-02-06 tracey error = gw_kcgi_error(kerr);
1867 2c251c14 2020-01-15 tracey return error;
1868 2c251c14 2020-01-15 tracey }
1869 2c251c14 2020-01-15 tracey
1870 2c251c14 2020-01-15 tracey static const struct got_error *
1871 54415d85 2020-01-15 tracey gw_load_got_path(struct gw_trans *gw_trans, struct gw_dir *gw_dir)
1872 2c251c14 2020-01-15 tracey {
1873 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
1874 2c251c14 2020-01-15 tracey DIR *dt;
1875 2c251c14 2020-01-15 tracey char *dir_test;
1876 4ceb8155 2020-01-15 tracey int opened = 0;
1877 2c251c14 2020-01-15 tracey
1878 88d59c36 2020-01-29 stsp if (asprintf(&dir_test, "%s/%s/%s",
1879 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_repos_path, gw_dir->name,
1880 88d59c36 2020-01-29 stsp GOTWEB_GIT_DIR) == -1)
1881 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
1882 2c251c14 2020-01-15 tracey
1883 2c251c14 2020-01-15 tracey dt = opendir(dir_test);
1884 2c251c14 2020-01-15 tracey if (dt == NULL) {
1885 2c251c14 2020-01-15 tracey free(dir_test);
1886 2c251c14 2020-01-15 tracey } else {
1887 d1635ae4 2020-02-13 tracey gw_dir->path = strdup(dir_test);
1888 d1635ae4 2020-02-13 tracey if (gw_dir->path == NULL) {
1889 d1635ae4 2020-02-13 tracey opened = 1;
1890 d1635ae4 2020-02-13 tracey error = got_error_from_errno("strdup");
1891 a942aa37 2020-02-10 tracey goto errored;
1892 d1635ae4 2020-02-13 tracey }
1893 d1635ae4 2020-02-13 tracey opened = 1;
1894 2c251c14 2020-01-15 tracey goto done;
1895 2c251c14 2020-01-15 tracey }
1896 2c251c14 2020-01-15 tracey
1897 88d59c36 2020-01-29 stsp if (asprintf(&dir_test, "%s/%s/%s",
1898 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_repos_path, gw_dir->name,
1899 d81f9039 2020-02-13 stsp GOTWEB_GOT_DIR) == -1) {
1900 d81f9039 2020-02-13 stsp dir_test = NULL;
1901 d81f9039 2020-02-13 stsp error = got_error_from_errno("asprintf");
1902 d81f9039 2020-02-13 stsp goto errored;
1903 d81f9039 2020-02-13 stsp }
1904 2c251c14 2020-01-15 tracey
1905 2c251c14 2020-01-15 tracey dt = opendir(dir_test);
1906 2c251c14 2020-01-15 tracey if (dt == NULL)
1907 2c251c14 2020-01-15 tracey free(dir_test);
1908 2c251c14 2020-01-15 tracey else {
1909 4ceb8155 2020-01-15 tracey opened = 1;
1910 2c251c14 2020-01-15 tracey error = got_error(GOT_ERR_NOT_GIT_REPO);
1911 2c251c14 2020-01-15 tracey goto errored;
1912 2c251c14 2020-01-15 tracey }
1913 2c251c14 2020-01-15 tracey
1914 88d59c36 2020-01-29 stsp if (asprintf(&dir_test, "%s/%s",
1915 d81f9039 2020-02-13 stsp gw_trans->gw_conf->got_repos_path, gw_dir->name) == -1) {
1916 d81f9039 2020-02-13 stsp error = got_error_from_errno("asprintf");
1917 d81f9039 2020-02-13 stsp dir_test = NULL;
1918 d81f9039 2020-02-13 stsp goto errored;
1919 d81f9039 2020-02-13 stsp }
1920 2c251c14 2020-01-15 tracey
1921 d1635ae4 2020-02-13 tracey gw_dir->path = strdup(dir_test);
1922 d1635ae4 2020-02-13 tracey if (gw_dir->path == NULL) {
1923 a942aa37 2020-02-10 tracey opened = 1;
1924 d1635ae4 2020-02-13 tracey error = got_error_from_errno("strdup");
1925 a942aa37 2020-02-10 tracey goto errored;
1926 a942aa37 2020-02-10 tracey }
1927 cc18a904 2020-02-13 tracey
1928 cc18a904 2020-02-13 tracey dt = opendir(dir_test);
1929 cc18a904 2020-02-13 tracey if (dt == NULL) {
1930 d90bcdd6 2020-02-17 stsp error = got_error_path(gw_dir->name, GOT_ERR_NOT_GIT_REPO);
1931 cc18a904 2020-02-13 tracey goto errored;
1932 7ecc73af 2020-02-13 tracey } else
1933 7ecc73af 2020-02-13 tracey opened = 1;
1934 2c251c14 2020-01-15 tracey done:
1935 32cd4d18 2020-02-03 stsp error = gw_get_repo_description(&gw_dir->description, gw_trans,
1936 2c251c14 2020-01-15 tracey gw_dir->path);
1937 32cd4d18 2020-02-03 stsp if (error)
1938 32cd4d18 2020-02-03 stsp goto errored;
1939 9a1cc63f 2020-02-03 stsp error = gw_get_repo_owner(&gw_dir->owner, gw_trans, gw_dir->path);
1940 9a1cc63f 2020-02-03 stsp if (error)
1941 9a1cc63f 2020-02-03 stsp goto errored;
1942 d126c1b7 2020-01-29 stsp error = gw_get_repo_age(&gw_dir->age, gw_trans, gw_dir->path,
1943 2011c142 2020-02-14 stsp NULL, TM_DIFF);
1944 d126c1b7 2020-01-29 stsp if (error)
1945 d126c1b7 2020-01-29 stsp goto errored;
1946 59d3c40e 2020-02-03 stsp error = gw_get_clone_url(&gw_dir->url, gw_trans, gw_dir->path);
1947 2c251c14 2020-01-15 tracey errored:
1948 2c251c14 2020-01-15 tracey free(dir_test);
1949 2c251c14 2020-01-15 tracey if (opened)
1950 795c5bd7 2020-02-17 tracey if (dt && closedir(dt) == -1 && error == NULL)
1951 e227880d 2020-02-17 tracey error = got_error_from_errno("closedir");
1952 2c251c14 2020-01-15 tracey return error;
1953 2c251c14 2020-01-15 tracey }
1954 2c251c14 2020-01-15 tracey
1955 2c251c14 2020-01-15 tracey static const struct got_error *
1956 54415d85 2020-01-15 tracey gw_load_got_paths(struct gw_trans *gw_trans)
1957 2c251c14 2020-01-15 tracey {
1958 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
1959 2c251c14 2020-01-15 tracey DIR *d;
1960 2c251c14 2020-01-15 tracey struct dirent **sd_dent;
1961 2c251c14 2020-01-15 tracey struct gw_dir *gw_dir;
1962 2c251c14 2020-01-15 tracey struct stat st;
1963 2c251c14 2020-01-15 tracey unsigned int d_cnt, d_i;
1964 2c251c14 2020-01-15 tracey
1965 2c251c14 2020-01-15 tracey d = opendir(gw_trans->gw_conf->got_repos_path);
1966 2c251c14 2020-01-15 tracey if (d == NULL) {
1967 2c251c14 2020-01-15 tracey error = got_error_from_errno2("opendir",
1968 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_repos_path);
1969 2c251c14 2020-01-15 tracey return error;
1970 2c251c14 2020-01-15 tracey }
1971 2c251c14 2020-01-15 tracey
1972 2c251c14 2020-01-15 tracey d_cnt = scandir(gw_trans->gw_conf->got_repos_path, &sd_dent, NULL,
1973 2c251c14 2020-01-15 tracey alphasort);
1974 2c251c14 2020-01-15 tracey if (d_cnt == -1) {
1975 2c251c14 2020-01-15 tracey error = got_error_from_errno2("scandir",
1976 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_repos_path);
1977 8182bd34 2020-02-17 tracey goto done;
1978 2c251c14 2020-01-15 tracey }
1979 2c251c14 2020-01-15 tracey
1980 2c251c14 2020-01-15 tracey for (d_i = 0; d_i < d_cnt; d_i++) {
1981 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_max_repos > 0 &&
1982 2c251c14 2020-01-15 tracey (d_i - 2) == gw_trans->gw_conf->got_max_repos)
1983 2c251c14 2020-01-15 tracey break; /* account for parent and self */
1984 2c251c14 2020-01-15 tracey
1985 2c251c14 2020-01-15 tracey if (strcmp(sd_dent[d_i]->d_name, ".") == 0 ||
1986 2c251c14 2020-01-15 tracey strcmp(sd_dent[d_i]->d_name, "..") == 0)
1987 2c251c14 2020-01-15 tracey continue;
1988 2c251c14 2020-01-15 tracey
1989 4619e1f2 2020-02-13 stsp error = gw_init_gw_dir(&gw_dir, sd_dent[d_i]->d_name);
1990 4619e1f2 2020-02-13 stsp if (error)
1991 8182bd34 2020-02-17 tracey goto done;
1992 2c251c14 2020-01-15 tracey
1993 2c251c14 2020-01-15 tracey error = gw_load_got_path(gw_trans, gw_dir);
1994 7bf16821 2020-02-07 stsp if (error && error->code == GOT_ERR_NOT_GIT_REPO) {
1995 7bf16821 2020-02-07 stsp error = NULL;
1996 2c251c14 2020-01-15 tracey continue;
1997 7bf16821 2020-02-07 stsp }
1998 2c251c14 2020-01-15 tracey else if (error)
1999 8182bd34 2020-02-17 tracey goto done;
2000 2c251c14 2020-01-15 tracey
2001 2c251c14 2020-01-15 tracey if (lstat(gw_dir->path, &st) == 0 && S_ISDIR(st.st_mode) &&
2002 2c251c14 2020-01-15 tracey !got_path_dir_is_empty(gw_dir->path)) {
2003 2c251c14 2020-01-15 tracey TAILQ_INSERT_TAIL(&gw_trans->gw_dirs, gw_dir,
2004 2c251c14 2020-01-15 tracey entry);
2005 2c251c14 2020-01-15 tracey gw_trans->repos_total++;
2006 2c251c14 2020-01-15 tracey }
2007 2c251c14 2020-01-15 tracey }
2008 8182bd34 2020-02-17 tracey done:
2009 e227880d 2020-02-17 tracey if (d && closedir(d) == -1 && error == NULL)
2010 e227880d 2020-02-17 tracey error = got_error_from_errno("closedir");
2011 2c251c14 2020-01-15 tracey return error;
2012 2c251c14 2020-01-15 tracey }
2013 2c251c14 2020-01-15 tracey
2014 2c251c14 2020-01-15 tracey static const struct got_error *
2015 54415d85 2020-01-15 tracey gw_parse_querystring(struct gw_trans *gw_trans)
2016 2c251c14 2020-01-15 tracey {
2017 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
2018 2c251c14 2020-01-15 tracey struct kpair *p;
2019 2c251c14 2020-01-15 tracey struct gw_query_action *action = NULL;
2020 2c251c14 2020-01-15 tracey unsigned int i;
2021 2c251c14 2020-01-15 tracey
2022 2c251c14 2020-01-15 tracey if (gw_trans->gw_req->fieldnmap[0]) {
2023 8f214b62 2020-02-17 stsp return got_error(GOT_ERR_QUERYSTRING);
2024 2c251c14 2020-01-15 tracey } else if ((p = gw_trans->gw_req->fieldmap[KEY_PATH])) {
2025 2c251c14 2020-01-15 tracey /* define gw_trans->repo_path */
2026 f652ec0c 2020-02-13 stsp gw_trans->repo_name = p->parsed.s;
2027 2c251c14 2020-01-15 tracey
2028 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->repo_path, "%s/%s",
2029 88d59c36 2020-01-29 stsp gw_trans->gw_conf->got_repos_path, p->parsed.s) == -1)
2030 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
2031 2c251c14 2020-01-15 tracey
2032 2c251c14 2020-01-15 tracey /* get action and set function */
2033 f1200fe3 2020-02-13 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_ACTION])) {
2034 2c251c14 2020-01-15 tracey for (i = 0; i < nitems(gw_query_funcs); i++) {
2035 2c251c14 2020-01-15 tracey action = &gw_query_funcs[i];
2036 f1200fe3 2020-02-13 tracey if (action->func_name == NULL)
2037 2c251c14 2020-01-15 tracey continue;
2038 f1200fe3 2020-02-13 tracey if (strcmp(action->func_name,
2039 f1200fe3 2020-02-13 tracey p->parsed.s) == 0) {
2040 f1200fe3 2020-02-13 tracey gw_trans->action = i;
2041 f1200fe3 2020-02-13 tracey break;
2042 f1200fe3 2020-02-13 tracey }
2043 f1200fe3 2020-02-13 tracey }
2044 6f6f771f 2020-02-13 tracey }
2045 6f6f771f 2020-02-13 tracey if (gw_trans->action == -1) {
2046 6f6f771f 2020-02-13 tracey gw_trans->action = GW_ERR;
2047 8f214b62 2020-02-17 stsp gw_trans->error = got_error_msg(GOT_ERR_QUERYSTRING,
2048 8f214b62 2020-02-17 stsp p != NULL ? "bad action in querystring" :
2049 8f214b62 2020-02-17 stsp "no action in querystring");
2050 cc18a904 2020-02-13 tracey return error;
2051 f1200fe3 2020-02-13 tracey }
2052 ec46ccd7 2020-01-15 tracey
2053 26dc3004 2020-02-13 stsp if ((p = gw_trans->gw_req->fieldmap[KEY_COMMIT_ID])) {
2054 56997cd3 2020-02-14 tracey if (asprintf(&gw_trans->commit_id, "%s",
2055 88d59c36 2020-01-29 stsp p->parsed.s) == -1)
2056 ec46ccd7 2020-01-15 tracey return got_error_from_errno("asprintf");
2057 26dc3004 2020-02-13 stsp }
2058 2c251c14 2020-01-15 tracey
2059 4d6abe2b 2020-02-13 stsp if ((p = gw_trans->gw_req->fieldmap[KEY_FILE]))
2060 4d6abe2b 2020-02-13 stsp gw_trans->repo_file = p->parsed.s;
2061 8087c3c5 2020-01-15 tracey
2062 26dc3004 2020-02-13 stsp if ((p = gw_trans->gw_req->fieldmap[KEY_FOLDER])) {
2063 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->repo_folder, "%s",
2064 55e46400 2020-02-18 tracey p->parsed.s) == -1)
2065 55e46400 2020-02-18 tracey return got_error_from_errno("asprintf");
2066 55e46400 2020-02-18 tracey }
2067 55e46400 2020-02-18 tracey
2068 55e46400 2020-02-18 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_PREV_ID])) {
2069 55e46400 2020-02-18 tracey if (asprintf(&gw_trans->prev_id, "%s",
2070 55e46400 2020-02-18 tracey p->parsed.s) == -1)
2071 55e46400 2020-02-18 tracey return got_error_from_errno("asprintf");
2072 55e46400 2020-02-18 tracey }
2073 55e46400 2020-02-18 tracey
2074 55e46400 2020-02-18 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_PREV_PREV_ID])) {
2075 55e46400 2020-02-18 tracey if (asprintf(&gw_trans->prev_prev_id, "%s",
2076 88d59c36 2020-01-29 stsp p->parsed.s) == -1)
2077 ec46ccd7 2020-01-15 tracey return got_error_from_errno("asprintf");
2078 26dc3004 2020-02-13 stsp }
2079 ec46ccd7 2020-01-15 tracey
2080 742ba378 2020-02-14 stsp if ((p = gw_trans->gw_req->fieldmap[KEY_HEADREF]))
2081 742ba378 2020-02-14 stsp gw_trans->headref = p->parsed.s;
2082 2c251c14 2020-01-15 tracey
2083 4619e1f2 2020-02-13 stsp error = gw_init_gw_dir(&gw_trans->gw_dir, gw_trans->repo_name);
2084 4619e1f2 2020-02-13 stsp if (error)
2085 4619e1f2 2020-02-13 stsp return error;
2086 46b9c89b 2020-01-15 tracey
2087 cc18a904 2020-02-13 tracey gw_trans->error = gw_load_got_path(gw_trans, gw_trans->gw_dir);
2088 2c251c14 2020-01-15 tracey } else
2089 2c251c14 2020-01-15 tracey gw_trans->action = GW_INDEX;
2090 2c251c14 2020-01-15 tracey
2091 2c251c14 2020-01-15 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_PAGE]))
2092 2c251c14 2020-01-15 tracey gw_trans->page = p->parsed.i;
2093 2c251c14 2020-01-15 tracey
2094 2c251c14 2020-01-15 tracey return error;
2095 2c251c14 2020-01-15 tracey }
2096 2c251c14 2020-01-15 tracey
2097 4619e1f2 2020-02-13 stsp static const struct got_error *
2098 f652ec0c 2020-02-13 stsp gw_init_gw_dir(struct gw_dir **gw_dir, const char *dir)
2099 4619e1f2 2020-02-13 stsp {
2100 4619e1f2 2020-02-13 stsp const struct got_error *error;
2101 2c251c14 2020-01-15 tracey
2102 4619e1f2 2020-02-13 stsp *gw_dir = malloc(sizeof(**gw_dir));
2103 4619e1f2 2020-02-13 stsp if (*gw_dir == NULL)
2104 4619e1f2 2020-02-13 stsp return got_error_from_errno("malloc");
2105 2c251c14 2020-01-15 tracey
2106 4619e1f2 2020-02-13 stsp if (asprintf(&(*gw_dir)->name, "%s", dir) == -1) {
2107 4619e1f2 2020-02-13 stsp error = got_error_from_errno("asprintf");
2108 4619e1f2 2020-02-13 stsp free(*gw_dir);
2109 4619e1f2 2020-02-13 stsp *gw_dir = NULL;
2110 e9a8bbf7 2020-05-29 tracey return error;
2111 4619e1f2 2020-02-13 stsp }
2112 2c251c14 2020-01-15 tracey
2113 4619e1f2 2020-02-13 stsp return NULL;
2114 474370cb 2020-01-15 tracey }
2115 474370cb 2020-01-15 tracey
2116 c25c2314 2020-01-28 stsp static const struct got_error *
2117 54415d85 2020-01-15 tracey gw_display_open(struct gw_trans *gw_trans, enum khttp code, enum kmime mime)
2118 2c251c14 2020-01-15 tracey {
2119 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
2120 c25c2314 2020-01-28 stsp
2121 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, kresps[KRESP_ALLOW], "GET");
2122 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
2123 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2124 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, kresps[KRESP_STATUS], "%s",
2125 2c251c14 2020-01-15 tracey khttps[code]);
2126 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
2127 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2128 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, kresps[KRESP_CONTENT_TYPE], "%s",
2129 2c251c14 2020-01-15 tracey kmimetypes[mime]);
2130 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
2131 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2132 017d6da3 2020-01-29 tracey kerr = khttp_head(gw_trans->gw_req, "X-Content-Type-Options",
2133 017d6da3 2020-01-29 tracey "nosniff");
2134 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
2135 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2136 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, "X-Frame-Options", "DENY");
2137 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
2138 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2139 017d6da3 2020-01-29 tracey kerr = khttp_head(gw_trans->gw_req, "X-XSS-Protection",
2140 017d6da3 2020-01-29 tracey "1; mode=block");
2141 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
2142 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2143 c25c2314 2020-01-28 stsp
2144 017d6da3 2020-01-29 tracey if (gw_trans->mime == KMIME_APP_OCTET_STREAM) {
2145 017d6da3 2020-01-29 tracey kerr = khttp_head(gw_trans->gw_req,
2146 017d6da3 2020-01-29 tracey kresps[KRESP_CONTENT_DISPOSITION],
2147 017d6da3 2020-01-29 tracey "attachment; filename=%s", gw_trans->repo_file);
2148 017d6da3 2020-01-29 tracey if (kerr != KCGI_OK)
2149 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2150 017d6da3 2020-01-29 tracey }
2151 017d6da3 2020-01-29 tracey
2152 c25c2314 2020-01-28 stsp kerr = khttp_body(gw_trans->gw_req);
2153 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2154 2c251c14 2020-01-15 tracey }
2155 2c251c14 2020-01-15 tracey
2156 c25c2314 2020-01-28 stsp static const struct got_error *
2157 6d8d8a26 2020-01-29 stsp gw_display_index(struct gw_trans *gw_trans)
2158 2c251c14 2020-01-15 tracey {
2159 4bec7539 2020-01-29 stsp const struct got_error *error;
2160 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
2161 c25c2314 2020-01-28 stsp
2162 cc18a904 2020-02-13 tracey /* catch early querystring errors */
2163 cc18a904 2020-02-13 tracey if (gw_trans->error)
2164 cc18a904 2020-02-13 tracey gw_trans->action = GW_ERR;
2165 cc18a904 2020-02-13 tracey
2166 4bec7539 2020-01-29 stsp error = gw_display_open(gw_trans, KHTTP_200, gw_trans->mime);
2167 4bec7539 2020-01-29 stsp if (error)
2168 4bec7539 2020-01-29 stsp return error;
2169 4bec7539 2020-01-29 stsp
2170 f7cc9480 2020-02-05 tracey kerr = khtml_open(gw_trans->gw_html_req, gw_trans->gw_req, 0);
2171 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2172 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2173 2c251c14 2020-01-15 tracey
2174 017d6da3 2020-01-29 tracey if (gw_trans->action != GW_BLOB) {
2175 017d6da3 2020-01-29 tracey kerr = khttp_template(gw_trans->gw_req, gw_trans->gw_tmpl,
2176 017d6da3 2020-01-29 tracey gw_query_funcs[gw_trans->action].template);
2177 017d6da3 2020-01-29 tracey if (kerr != KCGI_OK) {
2178 017d6da3 2020-01-29 tracey khtml_close(gw_trans->gw_html_req);
2179 2447adad 2020-02-06 stsp return gw_kcgi_error(kerr);
2180 017d6da3 2020-01-29 tracey }
2181 7a9bfbff 2020-01-29 stsp }
2182 2c251c14 2020-01-15 tracey
2183 7a9bfbff 2020-01-29 stsp return gw_kcgi_error(khtml_close(gw_trans->gw_html_req));
2184 2c251c14 2020-01-15 tracey }
2185 2c251c14 2020-01-15 tracey
2186 f1200fe3 2020-02-13 tracey static const struct got_error *
2187 f1200fe3 2020-02-13 tracey gw_error(struct gw_trans *gw_trans)
2188 6d8d8a26 2020-01-29 stsp {
2189 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
2190 6d8d8a26 2020-01-29 stsp
2191 f1200fe3 2020-02-13 tracey kerr = khtml_puts(gw_trans->gw_html_req, gw_trans->error->msg);
2192 f1200fe3 2020-02-13 tracey
2193 f1200fe3 2020-02-13 tracey return gw_kcgi_error(kerr);
2194 6d8d8a26 2020-01-29 stsp }
2195 6d8d8a26 2020-01-29 stsp
2196 2c251c14 2020-01-15 tracey static int
2197 2c251c14 2020-01-15 tracey gw_template(size_t key, void *arg)
2198 2c251c14 2020-01-15 tracey {
2199 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
2200 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
2201 54415d85 2020-01-15 tracey struct gw_trans *gw_trans = arg;
2202 9f6f3943 2020-09-24 tracey char *ati = NULL, *fic32 = NULL, *fic16 = NULL;
2203 9f6f3943 2020-09-24 tracey char *swm = NULL, *spt = NULL, *css = NULL, *logo = NULL;
2204 2c251c14 2020-01-15 tracey
2205 9f6f3943 2020-09-24 tracey if (asprintf(&ati, "%s%s", gw_trans->gw_conf->got_www_path,
2206 9f6f3943 2020-09-24 tracey "/apple-touch-icon.png") == -1)
2207 9f6f3943 2020-09-24 tracey goto err;
2208 9f6f3943 2020-09-24 tracey if (asprintf(&fic32, "%s%s", gw_trans->gw_conf->got_www_path,
2209 62d463ca 2020-10-20 naddy "/favicon-32x32.png") == -1)
2210 9f6f3943 2020-09-24 tracey goto err;
2211 9f6f3943 2020-09-24 tracey if (asprintf(&fic16, "%s%s", gw_trans->gw_conf->got_www_path,
2212 9f6f3943 2020-09-24 tracey "/favicon-16x16.png") == -1)
2213 9f6f3943 2020-09-24 tracey goto err;
2214 9f6f3943 2020-09-24 tracey if (asprintf(&swm, "%s%s", gw_trans->gw_conf->got_www_path,
2215 9f6f3943 2020-09-24 tracey "/site.webmanifest") == -1)
2216 9f6f3943 2020-09-24 tracey goto err;
2217 9f6f3943 2020-09-24 tracey if (asprintf(&spt, "%s%s", gw_trans->gw_conf->got_www_path,
2218 9f6f3943 2020-09-24 tracey "/safari-pinned-tab.svg") == -1)
2219 9f6f3943 2020-09-24 tracey goto err;
2220 9f6f3943 2020-09-24 tracey if (asprintf(&css, "%s%s", gw_trans->gw_conf->got_www_path,
2221 9f6f3943 2020-09-24 tracey "/gotweb.css") == -1)
2222 9f6f3943 2020-09-24 tracey goto err;
2223 9f6f3943 2020-09-24 tracey if (asprintf(&logo, "%s%s%s", gw_trans->gw_conf->got_www_path,
2224 9f6f3943 2020-09-24 tracey gw_trans->gw_conf->got_www_path ? "/" : "",
2225 9f6f3943 2020-09-24 tracey gw_trans->gw_conf->got_logo) == -1)
2226 9f6f3943 2020-09-24 tracey goto err;
2227 9f6f3943 2020-09-24 tracey
2228 2c251c14 2020-01-15 tracey switch (key) {
2229 2c251c14 2020-01-15 tracey case (TEMPL_HEAD):
2230 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_META,
2231 1dcb8908 2020-02-12 tracey KATTR_NAME, "viewport",
2232 1dcb8908 2020-02-12 tracey KATTR_CONTENT, "initial-scale=.75, user-scalable=yes",
2233 aaed5792 2020-02-08 tracey KATTR__MAX);
2234 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
2235 bd275801 2020-02-03 tracey return 0;
2236 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2237 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2238 aaed5792 2020-02-08 tracey return 0;
2239 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_META,
2240 aaed5792 2020-02-08 tracey KATTR_CHARSET, "utf-8",
2241 aaed5792 2020-02-08 tracey KATTR__MAX);
2242 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2243 aaed5792 2020-02-08 tracey return 0;
2244 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2245 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2246 aaed5792 2020-02-08 tracey return 0;
2247 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_META,
2248 aaed5792 2020-02-08 tracey KATTR_NAME, "msapplication-TileColor",
2249 aaed5792 2020-02-08 tracey KATTR_CONTENT, "#da532c", KATTR__MAX);
2250 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2251 aaed5792 2020-02-08 tracey return 0;
2252 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2253 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2254 aaed5792 2020-02-08 tracey return 0;
2255 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_META,
2256 aaed5792 2020-02-08 tracey KATTR_NAME, "theme-color",
2257 aaed5792 2020-02-08 tracey KATTR_CONTENT, "#ffffff", KATTR__MAX);
2258 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2259 aaed5792 2020-02-08 tracey return 0;
2260 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2261 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2262 aaed5792 2020-02-08 tracey return 0;
2263 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_LINK,
2264 aaed5792 2020-02-08 tracey KATTR_REL, "apple-touch-icon", KATTR_SIZES, "180x180",
2265 9f6f3943 2020-09-24 tracey KATTR_HREF, ati, KATTR__MAX);
2266 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2267 aaed5792 2020-02-08 tracey return 0;
2268 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2269 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2270 aaed5792 2020-02-08 tracey return 0;
2271 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_LINK,
2272 aaed5792 2020-02-08 tracey KATTR_REL, "icon", KATTR_TYPE, "image/png", KATTR_SIZES,
2273 9f6f3943 2020-09-24 tracey "32x32", KATTR_HREF, fic32, KATTR__MAX);
2274 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2275 aaed5792 2020-02-08 tracey return 0;
2276 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2277 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2278 aaed5792 2020-02-08 tracey return 0;
2279 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_LINK,
2280 aaed5792 2020-02-08 tracey KATTR_REL, "icon", KATTR_TYPE, "image/png", KATTR_SIZES,
2281 9f6f3943 2020-09-24 tracey "16x16", KATTR_HREF, fic16, KATTR__MAX);
2282 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2283 aaed5792 2020-02-08 tracey return 0;
2284 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2285 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2286 aaed5792 2020-02-08 tracey return 0;
2287 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_LINK,
2288 9f6f3943 2020-09-24 tracey KATTR_REL, "manifest", KATTR_HREF, swm,
2289 aaed5792 2020-02-08 tracey KATTR__MAX);
2290 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2291 aaed5792 2020-02-08 tracey return 0;
2292 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2293 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2294 aaed5792 2020-02-08 tracey return 0;
2295 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_LINK,
2296 aaed5792 2020-02-08 tracey KATTR_REL, "mask-icon", KATTR_HREF,
2297 9f6f3943 2020-09-24 tracey spt, KATTR__MAX);
2298 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2299 aaed5792 2020-02-08 tracey return 0;
2300 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2301 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2302 aaed5792 2020-02-08 tracey return 0;
2303 aaed5792 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_LINK,
2304 aaed5792 2020-02-08 tracey KATTR_REL, "stylesheet", KATTR_TYPE, "text/css",
2305 9f6f3943 2020-09-24 tracey KATTR_HREF, css, KATTR__MAX);
2306 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2307 aaed5792 2020-02-08 tracey return 0;
2308 aaed5792 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2309 aaed5792 2020-02-08 tracey if (kerr != KCGI_OK)
2310 aaed5792 2020-02-08 tracey return 0;
2311 2c251c14 2020-01-15 tracey break;
2312 2c251c14 2020-01-15 tracey case(TEMPL_HEADER):
2313 185ba3ba 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2314 185ba3ba 2020-02-04 tracey KATTR_ID, "got_link", KATTR__MAX);
2315 185ba3ba 2020-02-04 tracey if (kerr != KCGI_OK)
2316 185ba3ba 2020-02-04 tracey return 0;
2317 185ba3ba 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
2318 185ba3ba 2020-02-04 tracey KATTR_HREF, gw_trans->gw_conf->got_logo_url,
2319 185ba3ba 2020-02-04 tracey KATTR_TARGET, "_sotd", KATTR__MAX);
2320 185ba3ba 2020-02-04 tracey if (kerr != KCGI_OK)
2321 185ba3ba 2020-02-04 tracey return 0;
2322 185ba3ba 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_IMG,
2323 9f6f3943 2020-09-24 tracey KATTR_SRC, logo, KATTR__MAX);
2324 9f6f3943 2020-09-24 tracey if (kerr != KCGI_OK)
2325 185ba3ba 2020-02-04 tracey return 0;
2326 185ba3ba 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
2327 9f6f3943 2020-09-24 tracey if (kerr != KCGI_OK)
2328 185ba3ba 2020-02-04 tracey return 0;
2329 2c251c14 2020-01-15 tracey break;
2330 2c251c14 2020-01-15 tracey case (TEMPL_SITEPATH):
2331 4ae179a2 2020-02-08 tracey error = gw_output_site_link(gw_trans);
2332 4ae179a2 2020-02-08 tracey if (error)
2333 4ae179a2 2020-02-08 tracey return 0;
2334 2c251c14 2020-01-15 tracey break;
2335 2c251c14 2020-01-15 tracey case(TEMPL_TITLE):
2336 bd275801 2020-02-03 tracey if (gw_trans->gw_conf->got_site_name != NULL) {
2337 bd275801 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req,
2338 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_site_name);
2339 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
2340 bd275801 2020-02-03 tracey return 0;
2341 bd275801 2020-02-03 tracey }
2342 2c251c14 2020-01-15 tracey break;
2343 2c251c14 2020-01-15 tracey case (TEMPL_SEARCH):
2344 63ee0dca 2020-02-08 tracey break;
2345 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
2346 63ee0dca 2020-02-08 tracey "search", KATTR__MAX);
2347 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
2348 bd275801 2020-02-03 tracey return 0;
2349 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_FORM,
2350 63ee0dca 2020-02-08 tracey KATTR_METHOD, "POST", KATTR__MAX);
2351 63ee0dca 2020-02-08 tracey if (kerr != KCGI_OK)
2352 63ee0dca 2020-02-08 tracey return 0;
2353 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_INPUT, KATTR_ID,
2354 63ee0dca 2020-02-08 tracey "got-search", KATTR_NAME, "got-search", KATTR_SIZE, "15",
2355 63ee0dca 2020-02-08 tracey KATTR_MAXLENGTH, "50", KATTR__MAX);
2356 63ee0dca 2020-02-08 tracey if (kerr != KCGI_OK)
2357 63ee0dca 2020-02-08 tracey return 0;
2358 63ee0dca 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_BUTTON,
2359 63ee0dca 2020-02-08 tracey KATTR__MAX);
2360 63ee0dca 2020-02-08 tracey if (kerr != KCGI_OK)
2361 63ee0dca 2020-02-08 tracey return 0;
2362 63ee0dca 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Search");
2363 63ee0dca 2020-02-08 tracey if (kerr != KCGI_OK)
2364 63ee0dca 2020-02-08 tracey return 0;
2365 63ee0dca 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 4);
2366 63ee0dca 2020-02-08 tracey if (kerr != KCGI_OK)
2367 63ee0dca 2020-02-08 tracey return 0;
2368 2c251c14 2020-01-15 tracey break;
2369 2c251c14 2020-01-15 tracey case(TEMPL_SITEOWNER):
2370 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_site_owner != NULL &&
2371 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_show_site_owner) {
2372 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2373 bd275801 2020-02-03 tracey KATTR_ID, "site_owner_wrapper", KATTR__MAX);
2374 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
2375 070fee27 2020-02-03 stsp return 0;
2376 bd275801 2020-02-03 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2377 bd275801 2020-02-03 tracey KATTR_ID, "site_owner", KATTR__MAX);
2378 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
2379 2c251c14 2020-01-15 tracey return 0;
2380 bd275801 2020-02-03 tracey kerr = khtml_puts(gw_trans->gw_html_req,
2381 bd275801 2020-02-03 tracey gw_trans->gw_conf->got_site_owner);
2382 bd275801 2020-02-03 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
2383 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
2384 bd275801 2020-02-03 tracey return 0;
2385 2c251c14 2020-01-15 tracey }
2386 2c251c14 2020-01-15 tracey break;
2387 2c251c14 2020-01-15 tracey case(TEMPL_CONTENT):
2388 2c251c14 2020-01-15 tracey error = gw_query_funcs[gw_trans->action].func_main(gw_trans);
2389 bd275801 2020-02-03 tracey if (error) {
2390 0d100d0b 2020-02-07 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2391 0d100d0b 2020-02-07 tracey KATTR_ID, "tmpl_err", KATTR__MAX);
2392 0d100d0b 2020-02-07 tracey if (kerr != KCGI_OK)
2393 0d100d0b 2020-02-07 tracey return 0;
2394 f08447b0 2020-04-14 tracey kerr = khttp_printf(gw_trans->gw_req, "Error: %s",
2395 f08447b0 2020-04-14 tracey error->msg);
2396 0d100d0b 2020-02-07 tracey if (kerr != KCGI_OK)
2397 0d100d0b 2020-02-07 tracey return 0;
2398 0d100d0b 2020-02-07 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2399 bd275801 2020-02-03 tracey if (kerr != KCGI_OK)
2400 bd275801 2020-02-03 tracey return 0;
2401 bd275801 2020-02-03 tracey }
2402 2c251c14 2020-01-15 tracey break;
2403 2c251c14 2020-01-15 tracey default:
2404 2c251c14 2020-01-15 tracey return 0;
2405 2c251c14 2020-01-15 tracey }
2406 9f6f3943 2020-09-24 tracey free(ati);
2407 9f6f3943 2020-09-24 tracey free(fic32);
2408 9f6f3943 2020-09-24 tracey free(fic16);
2409 9f6f3943 2020-09-24 tracey free(swm);
2410 9f6f3943 2020-09-24 tracey free(spt);
2411 9f6f3943 2020-09-24 tracey free(css);
2412 9f6f3943 2020-09-24 tracey free(logo);
2413 2c251c14 2020-01-15 tracey return 1;
2414 9f6f3943 2020-09-24 tracey err:
2415 9f6f3943 2020-09-24 tracey free(ati);
2416 9f6f3943 2020-09-24 tracey free(fic32);
2417 9f6f3943 2020-09-24 tracey free(fic16);
2418 9f6f3943 2020-09-24 tracey free(swm);
2419 9f6f3943 2020-09-24 tracey free(spt);
2420 9f6f3943 2020-09-24 tracey free(css);
2421 9f6f3943 2020-09-24 tracey free(logo);
2422 9f6f3943 2020-09-24 tracey return 0;
2423 f2f46662 2020-01-23 tracey }
2424 21a55cc7 2020-02-04 tracey
2425 21a55cc7 2020-02-04 tracey static const struct got_error *
2426 21a55cc7 2020-02-04 tracey gw_gen_commit_header(struct gw_trans *gw_trans, char *str1, char *str2)
2427 21a55cc7 2020-02-04 tracey {
2428 21a55cc7 2020-02-04 tracey const struct got_error *error = NULL;
2429 21a55cc7 2020-02-04 tracey enum kcgi_err kerr = KCGI_OK;
2430 21a55cc7 2020-02-04 tracey
2431 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2432 21a55cc7 2020-02-04 tracey KATTR_ID, "header_commit_title", KATTR__MAX);
2433 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2434 21a55cc7 2020-02-04 tracey goto done;
2435 21a55cc7 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Commit: ");
2436 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2437 21a55cc7 2020-02-04 tracey goto done;
2438 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2439 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2440 21a55cc7 2020-02-04 tracey goto done;
2441 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2442 21a55cc7 2020-02-04 tracey KATTR_ID, "header_commit", KATTR__MAX);
2443 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2444 21a55cc7 2020-02-04 tracey goto done;
2445 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(gw_trans->gw_html_req, "%s ", str1);
2446 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2447 21a55cc7 2020-02-04 tracey goto done;
2448 5c65becf 2020-02-13 tracey if (str2 != NULL) {
2449 bf93a5c0 2020-02-15 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_SPAN,
2450 bf93a5c0 2020-02-15 tracey KATTR_ID, "refs_str", KATTR__MAX);
2451 5c65becf 2020-02-13 tracey if (kerr != KCGI_OK)
2452 5c65becf 2020-02-13 tracey goto done;
2453 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(gw_trans->gw_html_req, "(%s)", str2);
2454 bf93a5c0 2020-02-15 tracey if (kerr != KCGI_OK)
2455 bf93a5c0 2020-02-15 tracey goto done;
2456 bf93a5c0 2020-02-15 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2457 5c65becf 2020-02-13 tracey if (kerr != KCGI_OK)
2458 5c65becf 2020-02-13 tracey goto done;
2459 5c65becf 2020-02-13 tracey }
2460 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2461 21a55cc7 2020-02-04 tracey done:
2462 21a55cc7 2020-02-04 tracey if (error == NULL && kerr != KCGI_OK)
2463 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
2464 21a55cc7 2020-02-04 tracey return error;
2465 21a55cc7 2020-02-04 tracey }
2466 21a55cc7 2020-02-04 tracey
2467 f7cc9480 2020-02-05 tracey static const struct got_error *
2468 f7cc9480 2020-02-05 tracey gw_gen_diff_header(struct gw_trans *gw_trans, char *str1, char *str2)
2469 f2f46662 2020-01-23 tracey {
2470 27192be7 2020-02-04 tracey const struct got_error *error = NULL;
2471 f7cc9480 2020-02-05 tracey enum kcgi_err kerr = KCGI_OK;
2472 f2f46662 2020-01-23 tracey
2473 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2474 f7cc9480 2020-02-05 tracey KATTR_ID, "header_diff_title", KATTR__MAX);
2475 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2476 f7cc9480 2020-02-05 tracey goto done;
2477 f7cc9480 2020-02-05 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Diff: ");
2478 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2479 f7cc9480 2020-02-05 tracey goto done;
2480 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2481 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2482 f7cc9480 2020-02-05 tracey goto done;
2483 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2484 f7cc9480 2020-02-05 tracey KATTR_ID, "header_diff", KATTR__MAX);
2485 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2486 f7cc9480 2020-02-05 tracey goto done;
2487 5c65becf 2020-02-13 tracey if (str1 != NULL) {
2488 5c65becf 2020-02-13 tracey kerr = khtml_puts(gw_trans->gw_html_req, str1);
2489 5c65becf 2020-02-13 tracey if (kerr != KCGI_OK)
2490 5c65becf 2020-02-13 tracey goto done;
2491 5c65becf 2020-02-13 tracey }
2492 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_BR, KATTR__MAX);
2493 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2494 f7cc9480 2020-02-05 tracey goto done;
2495 f7cc9480 2020-02-05 tracey kerr = khtml_puts(gw_trans->gw_html_req, str2);
2496 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2497 f7cc9480 2020-02-05 tracey goto done;
2498 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2499 f7cc9480 2020-02-05 tracey done:
2500 f7cc9480 2020-02-05 tracey if (error == NULL && kerr != KCGI_OK)
2501 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
2502 f7cc9480 2020-02-05 tracey return error;
2503 21a55cc7 2020-02-04 tracey }
2504 21a55cc7 2020-02-04 tracey
2505 21a55cc7 2020-02-04 tracey static const struct got_error *
2506 21a55cc7 2020-02-04 tracey gw_gen_age_header(struct gw_trans *gw_trans, const char *str)
2507 21a55cc7 2020-02-04 tracey {
2508 21a55cc7 2020-02-04 tracey const struct got_error *error = NULL;
2509 21a55cc7 2020-02-04 tracey enum kcgi_err kerr = KCGI_OK;
2510 21a55cc7 2020-02-04 tracey
2511 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2512 21a55cc7 2020-02-04 tracey KATTR_ID, "header_age_title", KATTR__MAX);
2513 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2514 21a55cc7 2020-02-04 tracey goto done;
2515 21a55cc7 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Date: ");
2516 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2517 21a55cc7 2020-02-04 tracey goto done;
2518 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2519 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2520 21a55cc7 2020-02-04 tracey goto done;
2521 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2522 21a55cc7 2020-02-04 tracey KATTR_ID, "header_age", KATTR__MAX);
2523 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2524 21a55cc7 2020-02-04 tracey goto done;
2525 21a55cc7 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, str);
2526 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2527 21a55cc7 2020-02-04 tracey goto done;
2528 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2529 21a55cc7 2020-02-04 tracey done:
2530 21a55cc7 2020-02-04 tracey if (error == NULL && kerr != KCGI_OK)
2531 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
2532 21a55cc7 2020-02-04 tracey return error;
2533 21a55cc7 2020-02-04 tracey }
2534 21a55cc7 2020-02-04 tracey
2535 21a55cc7 2020-02-04 tracey static const struct got_error *
2536 21a55cc7 2020-02-04 tracey gw_gen_author_header(struct gw_trans *gw_trans, const char *str)
2537 21a55cc7 2020-02-04 tracey {
2538 21a55cc7 2020-02-04 tracey const struct got_error *error = NULL;
2539 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
2540 21a55cc7 2020-02-04 tracey
2541 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2542 21a55cc7 2020-02-04 tracey KATTR_ID, "header_author_title", KATTR__MAX);
2543 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2544 21a55cc7 2020-02-04 tracey goto done;
2545 21a55cc7 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Author: ");
2546 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2547 21a55cc7 2020-02-04 tracey goto done;
2548 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2549 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2550 21a55cc7 2020-02-04 tracey goto done;
2551 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2552 21a55cc7 2020-02-04 tracey KATTR_ID, "header_author", KATTR__MAX);
2553 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2554 21a55cc7 2020-02-04 tracey goto done;
2555 21a55cc7 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, str);
2556 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2557 21a55cc7 2020-02-04 tracey goto done;
2558 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2559 21a55cc7 2020-02-04 tracey done:
2560 21a55cc7 2020-02-04 tracey if (error == NULL && kerr != KCGI_OK)
2561 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
2562 21a55cc7 2020-02-04 tracey return error;
2563 f2f46662 2020-01-23 tracey }
2564 f2f46662 2020-01-23 tracey
2565 21a55cc7 2020-02-04 tracey static const struct got_error *
2566 21a55cc7 2020-02-04 tracey gw_gen_committer_header(struct gw_trans *gw_trans, const char *str)
2567 21a55cc7 2020-02-04 tracey {
2568 21a55cc7 2020-02-04 tracey const struct got_error *error = NULL;
2569 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
2570 21a55cc7 2020-02-04 tracey
2571 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2572 21a55cc7 2020-02-04 tracey KATTR_ID, "header_committer_title", KATTR__MAX);
2573 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2574 21a55cc7 2020-02-04 tracey goto done;
2575 87ca24ac 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Committer: ");
2576 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2577 21a55cc7 2020-02-04 tracey goto done;
2578 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2579 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2580 21a55cc7 2020-02-04 tracey goto done;
2581 21a55cc7 2020-02-04 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2582 21a55cc7 2020-02-04 tracey KATTR_ID, "header_committer", KATTR__MAX);
2583 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2584 21a55cc7 2020-02-04 tracey goto done;
2585 21a55cc7 2020-02-04 tracey kerr = khtml_puts(gw_trans->gw_html_req, str);
2586 21a55cc7 2020-02-04 tracey if (kerr != KCGI_OK)
2587 21a55cc7 2020-02-04 tracey goto done;
2588 21a55cc7 2020-02-04 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2589 21a55cc7 2020-02-04 tracey done:
2590 21a55cc7 2020-02-04 tracey if (error == NULL && kerr != KCGI_OK)
2591 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
2592 21a55cc7 2020-02-04 tracey return error;
2593 21a55cc7 2020-02-04 tracey }
2594 21a55cc7 2020-02-04 tracey
2595 f7cc9480 2020-02-05 tracey static const struct got_error *
2596 f7cc9480 2020-02-05 tracey gw_gen_commit_msg_header(struct gw_trans *gw_trans, char *str)
2597 f2f46662 2020-01-23 tracey {
2598 27192be7 2020-02-04 tracey const struct got_error *error = NULL;
2599 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
2600 f2f46662 2020-01-23 tracey
2601 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2602 f7cc9480 2020-02-05 tracey KATTR_ID, "header_commit_msg_title", KATTR__MAX);
2603 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2604 f7cc9480 2020-02-05 tracey goto done;
2605 f7cc9480 2020-02-05 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Message: ");
2606 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2607 f7cc9480 2020-02-05 tracey goto done;
2608 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2609 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2610 f7cc9480 2020-02-05 tracey goto done;
2611 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2612 f7cc9480 2020-02-05 tracey KATTR_ID, "header_commit_msg", KATTR__MAX);
2613 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2614 f7cc9480 2020-02-05 tracey goto done;
2615 f7cc9480 2020-02-05 tracey kerr = khttp_puts(gw_trans->gw_req, str);
2616 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2617 f7cc9480 2020-02-05 tracey goto done;
2618 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2619 f7cc9480 2020-02-05 tracey done:
2620 f7cc9480 2020-02-05 tracey if (error == NULL && kerr != KCGI_OK)
2621 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
2622 f7cc9480 2020-02-05 tracey return error;
2623 f2f46662 2020-01-23 tracey }
2624 f2f46662 2020-01-23 tracey
2625 f7cc9480 2020-02-05 tracey static const struct got_error *
2626 f7cc9480 2020-02-05 tracey gw_gen_tree_header(struct gw_trans *gw_trans, char *str)
2627 f2f46662 2020-01-23 tracey {
2628 f7cc9480 2020-02-05 tracey const struct got_error *error = NULL;
2629 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
2630 f2f46662 2020-01-23 tracey
2631 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2632 f7cc9480 2020-02-05 tracey KATTR_ID, "header_tree_title", KATTR__MAX);
2633 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2634 f7cc9480 2020-02-05 tracey goto done;
2635 f7cc9480 2020-02-05 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Tree: ");
2636 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2637 f7cc9480 2020-02-05 tracey goto done;
2638 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2639 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2640 f7cc9480 2020-02-05 tracey goto done;
2641 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
2642 f7cc9480 2020-02-05 tracey KATTR_ID, "header_tree", KATTR__MAX);
2643 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2644 f7cc9480 2020-02-05 tracey goto done;
2645 f7cc9480 2020-02-05 tracey kerr = khtml_puts(gw_trans->gw_html_req, str);
2646 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2647 f7cc9480 2020-02-05 tracey goto done;
2648 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2649 f7cc9480 2020-02-05 tracey done:
2650 f7cc9480 2020-02-05 tracey if (error == NULL && kerr != KCGI_OK)
2651 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
2652 f7cc9480 2020-02-05 tracey return error;
2653 f2f46662 2020-01-23 tracey }
2654 f2f46662 2020-01-23 tracey
2655 32cd4d18 2020-02-03 stsp static const struct got_error *
2656 32cd4d18 2020-02-03 stsp gw_get_repo_description(char **description, struct gw_trans *gw_trans,
2657 32cd4d18 2020-02-03 stsp char *dir)
2658 2c251c14 2020-01-15 tracey {
2659 32cd4d18 2020-02-03 stsp const struct got_error *error = NULL;
2660 b8b04565 2020-02-02 tracey FILE *f = NULL;
2661 32cd4d18 2020-02-03 stsp char *d_file = NULL;
2662 2c251c14 2020-01-15 tracey unsigned int len;
2663 1ab830c1 2020-02-03 stsp size_t n;
2664 2c251c14 2020-01-15 tracey
2665 32cd4d18 2020-02-03 stsp *description = NULL;
2666 0b20762b 2020-01-29 stsp if (gw_trans->gw_conf->got_show_repo_description == 0)
2667 a942aa37 2020-02-10 tracey return NULL;
2668 2c251c14 2020-01-15 tracey
2669 88d59c36 2020-01-29 stsp if (asprintf(&d_file, "%s/description", dir) == -1)
2670 32cd4d18 2020-02-03 stsp return got_error_from_errno("asprintf");
2671 2c251c14 2020-01-15 tracey
2672 32cd4d18 2020-02-03 stsp f = fopen(d_file, "r");
2673 32cd4d18 2020-02-03 stsp if (f == NULL) {
2674 32cd4d18 2020-02-03 stsp if (errno == ENOENT || errno == EACCES)
2675 a942aa37 2020-02-10 tracey return NULL;
2676 32cd4d18 2020-02-03 stsp error = got_error_from_errno2("fopen", d_file);
2677 32cd4d18 2020-02-03 stsp goto done;
2678 32cd4d18 2020-02-03 stsp }
2679 2c251c14 2020-01-15 tracey
2680 32cd4d18 2020-02-03 stsp if (fseek(f, 0, SEEK_END) == -1) {
2681 32cd4d18 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
2682 32cd4d18 2020-02-03 stsp goto done;
2683 32cd4d18 2020-02-03 stsp }
2684 32cd4d18 2020-02-03 stsp len = ftell(f);
2685 32cd4d18 2020-02-03 stsp if (len == -1) {
2686 32cd4d18 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
2687 32cd4d18 2020-02-03 stsp goto done;
2688 32cd4d18 2020-02-03 stsp }
2689 32cd4d18 2020-02-03 stsp if (fseek(f, 0, SEEK_SET) == -1) {
2690 32cd4d18 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
2691 32cd4d18 2020-02-03 stsp goto done;
2692 32cd4d18 2020-02-03 stsp }
2693 32cd4d18 2020-02-03 stsp *description = calloc(len + 1, sizeof(**description));
2694 32cd4d18 2020-02-03 stsp if (*description == NULL) {
2695 32cd4d18 2020-02-03 stsp error = got_error_from_errno("calloc");
2696 32cd4d18 2020-02-03 stsp goto done;
2697 32cd4d18 2020-02-03 stsp }
2698 32cd4d18 2020-02-03 stsp
2699 32cd4d18 2020-02-03 stsp n = fread(*description, 1, len, f);
2700 1ab830c1 2020-02-03 stsp if (n == 0 && ferror(f))
2701 32cd4d18 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
2702 32cd4d18 2020-02-03 stsp done:
2703 56b63ca4 2021-01-22 stsp if (f != NULL && fclose(f) == EOF && error == NULL)
2704 32cd4d18 2020-02-03 stsp error = got_error_from_errno("fclose");
2705 2c251c14 2020-01-15 tracey free(d_file);
2706 32cd4d18 2020-02-03 stsp return error;
2707 2c251c14 2020-01-15 tracey }
2708 2c251c14 2020-01-15 tracey
2709 55ccf528 2020-02-03 stsp static const struct got_error *
2710 55ccf528 2020-02-03 stsp gw_get_time_str(char **repo_age, time_t committer_time, int ref_tm)
2711 474370cb 2020-01-15 tracey {
2712 474370cb 2020-01-15 tracey struct tm tm;
2713 474370cb 2020-01-15 tracey time_t diff_time;
2714 474370cb 2020-01-15 tracey char *years = "years ago", *months = "months ago";
2715 474370cb 2020-01-15 tracey char *weeks = "weeks ago", *days = "days ago", *hours = "hours ago";
2716 474370cb 2020-01-15 tracey char *minutes = "minutes ago", *seconds = "seconds ago";
2717 474370cb 2020-01-15 tracey char *now = "right now";
2718 55ccf528 2020-02-03 stsp char *s;
2719 6c6c85af 2020-01-15 tracey char datebuf[29];
2720 474370cb 2020-01-15 tracey
2721 55ccf528 2020-02-03 stsp *repo_age = NULL;
2722 55ccf528 2020-02-03 stsp
2723 474370cb 2020-01-15 tracey switch (ref_tm) {
2724 474370cb 2020-01-15 tracey case TM_DIFF:
2725 474370cb 2020-01-15 tracey diff_time = time(NULL) - committer_time;
2726 474370cb 2020-01-15 tracey if (diff_time > 60 * 60 * 24 * 365 * 2) {
2727 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%lld %s",
2728 88d59c36 2020-01-29 stsp (diff_time / 60 / 60 / 24 / 365), years) == -1)
2729 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2730 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 60 * 24 * (365 / 12) * 2) {
2731 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%lld %s",
2732 474370cb 2020-01-15 tracey (diff_time / 60 / 60 / 24 / (365 / 12)),
2733 88d59c36 2020-01-29 stsp months) == -1)
2734 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2735 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 60 * 24 * 7 * 2) {
2736 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%lld %s",
2737 88d59c36 2020-01-29 stsp (diff_time / 60 / 60 / 24 / 7), weeks) == -1)
2738 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2739 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 60 * 24 * 2) {
2740 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%lld %s",
2741 88d59c36 2020-01-29 stsp (diff_time / 60 / 60 / 24), days) == -1)
2742 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2743 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 60 * 2) {
2744 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%lld %s",
2745 88d59c36 2020-01-29 stsp (diff_time / 60 / 60), hours) == -1)
2746 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2747 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 2) {
2748 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%lld %s", (diff_time / 60),
2749 88d59c36 2020-01-29 stsp minutes) == -1)
2750 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2751 474370cb 2020-01-15 tracey } else if (diff_time > 2) {
2752 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%lld %s", diff_time,
2753 88d59c36 2020-01-29 stsp seconds) == -1)
2754 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2755 474370cb 2020-01-15 tracey } else {
2756 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%s", now) == -1)
2757 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2758 474370cb 2020-01-15 tracey }
2759 474370cb 2020-01-15 tracey break;
2760 474370cb 2020-01-15 tracey case TM_LONG:
2761 474370cb 2020-01-15 tracey if (gmtime_r(&committer_time, &tm) == NULL)
2762 55ccf528 2020-02-03 stsp return got_error_from_errno("gmtime_r");
2763 474370cb 2020-01-15 tracey
2764 474370cb 2020-01-15 tracey s = asctime_r(&tm, datebuf);
2765 474370cb 2020-01-15 tracey if (s == NULL)
2766 55ccf528 2020-02-03 stsp return got_error_from_errno("asctime_r");
2767 474370cb 2020-01-15 tracey
2768 55ccf528 2020-02-03 stsp if (asprintf(repo_age, "%s UTC", datebuf) == -1)
2769 55ccf528 2020-02-03 stsp return got_error_from_errno("asprintf");
2770 474370cb 2020-01-15 tracey break;
2771 474370cb 2020-01-15 tracey }
2772 55ccf528 2020-02-03 stsp return NULL;
2773 474370cb 2020-01-15 tracey }
2774 474370cb 2020-01-15 tracey
2775 d126c1b7 2020-01-29 stsp static const struct got_error *
2776 d126c1b7 2020-01-29 stsp gw_get_repo_age(char **repo_age, struct gw_trans *gw_trans, char *dir,
2777 2011c142 2020-02-14 stsp const char *refname, int ref_tm)
2778 2c251c14 2020-01-15 tracey {
2779 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
2780 2c251c14 2020-01-15 tracey struct got_repository *repo = NULL;
2781 2c251c14 2020-01-15 tracey struct got_commit_object *commit = NULL;
2782 2c251c14 2020-01-15 tracey struct got_reflist_head refs;
2783 2c251c14 2020-01-15 tracey struct got_reflist_entry *re;
2784 474370cb 2020-01-15 tracey time_t committer_time = 0, cmp_time = 0;
2785 a0f36e03 2020-01-28 stsp
2786 d126c1b7 2020-01-29 stsp *repo_age = NULL;
2787 d9dff0e5 2020-12-26 stsp TAILQ_INIT(&refs);
2788 387a29ba 2020-01-15 tracey
2789 55ccf528 2020-02-03 stsp if (gw_trans->gw_conf->got_show_repo_age == 0)
2790 d126c1b7 2020-01-29 stsp return NULL;
2791 87f9ebf5 2020-01-15 tracey
2792 deac617c 2020-02-14 tracey if (gw_trans->repo)
2793 deac617c 2020-02-14 tracey repo = gw_trans->repo;
2794 deac617c 2020-02-14 tracey else {
2795 deac617c 2020-02-14 tracey error = got_repo_open(&repo, dir, NULL);
2796 deac617c 2020-02-14 tracey if (error)
2797 deac617c 2020-02-14 tracey return error;
2798 deac617c 2020-02-14 tracey }
2799 2c251c14 2020-01-15 tracey
2800 2011c142 2020-02-14 stsp error = got_ref_list(&refs, repo, "refs/heads",
2801 2011c142 2020-02-14 stsp got_ref_cmp_by_name, NULL);
2802 ec46ccd7 2020-01-15 tracey if (error)
2803 d126c1b7 2020-01-29 stsp goto done;
2804 2c251c14 2020-01-15 tracey
2805 2011c142 2020-02-14 stsp /*
2806 2011c142 2020-02-14 stsp * Find the youngest branch tip in the repository, or the age of
2807 2011c142 2020-02-14 stsp * the a specific branch tip if a name was provided by the caller.
2808 2011c142 2020-02-14 stsp */
2809 d9dff0e5 2020-12-26 stsp TAILQ_FOREACH(re, &refs, entry) {
2810 2011c142 2020-02-14 stsp struct got_object_id *id = NULL;
2811 17d4bf8d 2020-02-14 stsp
2812 2011c142 2020-02-14 stsp if (refname && strcmp(got_ref_get_name(re->ref), refname) != 0)
2813 2011c142 2020-02-14 stsp continue;
2814 4e8d6e3e 2020-02-14 tracey
2815 2011c142 2020-02-14 stsp error = got_ref_resolve(&id, repo, re->ref);
2816 ec46ccd7 2020-01-15 tracey if (error)
2817 d126c1b7 2020-01-29 stsp goto done;
2818 2c251c14 2020-01-15 tracey
2819 2c251c14 2020-01-15 tracey error = got_object_open_as_commit(&commit, repo, id);
2820 2011c142 2020-02-14 stsp free(id);
2821 ec46ccd7 2020-01-15 tracey if (error)
2822 d126c1b7 2020-01-29 stsp goto done;
2823 2c251c14 2020-01-15 tracey
2824 2c251c14 2020-01-15 tracey committer_time =
2825 2c251c14 2020-01-15 tracey got_object_commit_get_committer_time(commit);
2826 2011c142 2020-02-14 stsp got_object_commit_close(commit);
2827 387a29ba 2020-01-15 tracey if (cmp_time < committer_time)
2828 2c251c14 2020-01-15 tracey cmp_time = committer_time;
2829 2011c142 2020-02-14 stsp
2830 2011c142 2020-02-14 stsp if (refname)
2831 2011c142 2020-02-14 stsp break;
2832 2c251c14 2020-01-15 tracey }
2833 2c251c14 2020-01-15 tracey
2834 474370cb 2020-01-15 tracey if (cmp_time != 0) {
2835 2c251c14 2020-01-15 tracey committer_time = cmp_time;
2836 55ccf528 2020-02-03 stsp error = gw_get_time_str(repo_age, committer_time, ref_tm);
2837 d126c1b7 2020-01-29 stsp }
2838 d126c1b7 2020-01-29 stsp done:
2839 2c251c14 2020-01-15 tracey got_ref_list_free(&refs);
2840 1d0f4054 2021-06-17 stsp if (gw_trans->repo == NULL) {
2841 1d0f4054 2021-06-17 stsp const struct got_error *close_err = got_repo_close(repo);
2842 1d0f4054 2021-06-17 stsp if (error == NULL)
2843 1d0f4054 2021-06-17 stsp error = close_err;
2844 1d0f4054 2021-06-17 stsp }
2845 d126c1b7 2020-01-29 stsp return error;
2846 ec46ccd7 2020-01-15 tracey }
2847 ec46ccd7 2020-01-15 tracey
2848 83eb9a68 2020-02-03 stsp static const struct got_error *
2849 38b240fb 2020-02-06 tracey gw_output_diff(struct gw_trans *gw_trans, struct gw_header *header)
2850 ec46ccd7 2020-01-15 tracey {
2851 ec46ccd7 2020-01-15 tracey const struct got_error *error;
2852 ec46ccd7 2020-01-15 tracey FILE *f = NULL;
2853 ec46ccd7 2020-01-15 tracey struct got_object_id *id1 = NULL, *id2 = NULL;
2854 f7cc9480 2020-02-05 tracey char *label1 = NULL, *label2 = NULL, *line = NULL;
2855 05ce9a79 2020-01-24 tracey int obj_type;
2856 f7cc9480 2020-02-05 tracey size_t linesize = 0;
2857 83eb9a68 2020-02-03 stsp ssize_t linelen;
2858 f7cc9480 2020-02-05 tracey enum kcgi_err kerr = KCGI_OK;
2859 ec46ccd7 2020-01-15 tracey
2860 ec46ccd7 2020-01-15 tracey f = got_opentemp();
2861 ec46ccd7 2020-01-15 tracey if (f == NULL)
2862 ec46ccd7 2020-01-15 tracey return NULL;
2863 ec46ccd7 2020-01-15 tracey
2864 5c65becf 2020-02-13 tracey if (header->parent_id != NULL &&
2865 5c65becf 2020-02-13 tracey strncmp(header->parent_id, "/dev/null", 9) != 0) {
2866 05ce9a79 2020-01-24 tracey error = got_repo_match_object_id(&id1, &label1,
2867 84de9106 2020-12-26 stsp header->parent_id, GOT_OBJ_TYPE_ANY,
2868 84de9106 2020-12-26 stsp &header->refs, gw_trans->repo);
2869 05ce9a79 2020-01-24 tracey if (error)
2870 05ce9a79 2020-01-24 tracey goto done;
2871 05ce9a79 2020-01-24 tracey }
2872 ec46ccd7 2020-01-15 tracey
2873 90f16cb8 2020-01-24 tracey error = got_repo_match_object_id(&id2, &label2,
2874 84de9106 2020-12-26 stsp header->commit_id, GOT_OBJ_TYPE_ANY, &header->refs,
2875 84de9106 2020-12-26 stsp gw_trans->repo);
2876 90f16cb8 2020-01-24 tracey if (error)
2877 90f16cb8 2020-01-24 tracey goto done;
2878 ec46ccd7 2020-01-15 tracey
2879 deac617c 2020-02-14 tracey error = got_object_get_type(&obj_type, gw_trans->repo, id2);
2880 90f16cb8 2020-01-24 tracey if (error)
2881 90f16cb8 2020-01-24 tracey goto done;
2882 05ce9a79 2020-01-24 tracey switch (obj_type) {
2883 ec46ccd7 2020-01-15 tracey case GOT_OBJ_TYPE_BLOB:
2884 c9d2b263 2020-11-11 stsp error = got_diff_objects_as_blobs(NULL, NULL, id1, id2,
2885 22c0f09d 2020-11-22 stsp NULL, NULL, 3, 0, 0, gw_trans->repo, f);
2886 ec46ccd7 2020-01-15 tracey break;
2887 ec46ccd7 2020-01-15 tracey case GOT_OBJ_TYPE_TREE:
2888 c9d2b263 2020-11-11 stsp error = got_diff_objects_as_trees(NULL, NULL, id1, id2,
2889 22c0f09d 2020-11-22 stsp "", "", 3, 0, 0, gw_trans->repo, f);
2890 ec46ccd7 2020-01-15 tracey break;
2891 ec46ccd7 2020-01-15 tracey case GOT_OBJ_TYPE_COMMIT:
2892 22c0f09d 2020-11-22 stsp error = got_diff_objects_as_commits(NULL, NULL, id1, id2,
2893 22c0f09d 2020-11-22 stsp 3, 0, 0, gw_trans->repo, f);
2894 ec46ccd7 2020-01-15 tracey break;
2895 ec46ccd7 2020-01-15 tracey default:
2896 ec46ccd7 2020-01-15 tracey error = got_error(GOT_ERR_OBJ_TYPE);
2897 ec46ccd7 2020-01-15 tracey }
2898 b8b04565 2020-02-02 tracey if (error)
2899 b8b04565 2020-02-02 tracey goto done;
2900 b8b04565 2020-02-02 tracey
2901 d4729381 2020-02-03 stsp if (fseek(f, 0, SEEK_SET) == -1) {
2902 d4729381 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
2903 ec46ccd7 2020-01-15 tracey goto done;
2904 d4729381 2020-02-03 stsp }
2905 ec46ccd7 2020-01-15 tracey
2906 83eb9a68 2020-02-03 stsp while ((linelen = getline(&line, &linesize, f)) != -1) {
2907 f7cc9480 2020-02-05 tracey error = gw_colordiff_line(gw_trans, line);
2908 ec46ccd7 2020-01-15 tracey if (error)
2909 b8b04565 2020-02-02 tracey goto done;
2910 f7cc9480 2020-02-05 tracey /* XXX: KHTML_PRETTY breaks this */
2911 f7cc9480 2020-02-05 tracey kerr = khtml_puts(gw_trans->gw_html_req, line);
2912 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2913 83eb9a68 2020-02-03 stsp goto done;
2914 f7cc9480 2020-02-05 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
2915 f7cc9480 2020-02-05 tracey if (kerr != KCGI_OK)
2916 b8b04565 2020-02-02 tracey goto done;
2917 ec46ccd7 2020-01-15 tracey }
2918 f7cc9480 2020-02-05 tracey if (linelen == -1 && ferror(f))
2919 83eb9a68 2020-02-03 stsp error = got_error_from_errno("getline");
2920 ec46ccd7 2020-01-15 tracey done:
2921 56b63ca4 2021-01-22 stsp if (f && fclose(f) == EOF && error == NULL)
2922 d4729381 2020-02-03 stsp error = got_error_from_errno("fclose");
2923 d4729381 2020-02-03 stsp free(line);
2924 ec46ccd7 2020-01-15 tracey free(label1);
2925 ec46ccd7 2020-01-15 tracey free(label2);
2926 ec46ccd7 2020-01-15 tracey free(id1);
2927 ec46ccd7 2020-01-15 tracey free(id2);
2928 ec46ccd7 2020-01-15 tracey
2929 f7cc9480 2020-02-05 tracey if (error == NULL && kerr != KCGI_OK)
2930 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
2931 83eb9a68 2020-02-03 stsp return error;
2932 2c251c14 2020-01-15 tracey }
2933 2c251c14 2020-01-15 tracey
2934 9a1cc63f 2020-02-03 stsp static const struct got_error *
2935 9a1cc63f 2020-02-03 stsp gw_get_repo_owner(char **owner, struct gw_trans *gw_trans, char *dir)
2936 9a1cc63f 2020-02-03 stsp {
2937 1d0f4054 2021-06-17 stsp const struct got_error *error = NULL, *close_err;
2938 9a1cc63f 2020-02-03 stsp struct got_repository *repo;
2939 9a1cc63f 2020-02-03 stsp const char *gitconfig_owner;
2940 2c251c14 2020-01-15 tracey
2941 9a1cc63f 2020-02-03 stsp *owner = NULL;
2942 2c251c14 2020-01-15 tracey
2943 9a1cc63f 2020-02-03 stsp if (gw_trans->gw_conf->got_show_repo_owner == 0)
2944 9a1cc63f 2020-02-03 stsp return NULL;
2945 2c251c14 2020-01-15 tracey
2946 9a1cc63f 2020-02-03 stsp error = got_repo_open(&repo, dir, NULL);
2947 9a1cc63f 2020-02-03 stsp if (error)
2948 9a1cc63f 2020-02-03 stsp return error;
2949 9a1cc63f 2020-02-03 stsp gitconfig_owner = got_repo_get_gitconfig_owner(repo);
2950 d1635ae4 2020-02-13 tracey if (gitconfig_owner) {
2951 d1635ae4 2020-02-13 tracey *owner = strdup(gitconfig_owner);
2952 d1635ae4 2020-02-13 tracey if (*owner == NULL)
2953 d1635ae4 2020-02-13 tracey error = got_error_from_errno("strdup");
2954 d1635ae4 2020-02-13 tracey }
2955 1d0f4054 2021-06-17 stsp close_err = got_repo_close(repo);
2956 1d0f4054 2021-06-17 stsp if (error == NULL)
2957 1d0f4054 2021-06-17 stsp error = close_err;
2958 9a1cc63f 2020-02-03 stsp return error;
2959 2c251c14 2020-01-15 tracey }
2960 2c251c14 2020-01-15 tracey
2961 59d3c40e 2020-02-03 stsp static const struct got_error *
2962 59d3c40e 2020-02-03 stsp gw_get_clone_url(char **url, struct gw_trans *gw_trans, char *dir)
2963 2c251c14 2020-01-15 tracey {
2964 59d3c40e 2020-02-03 stsp const struct got_error *error = NULL;
2965 2c251c14 2020-01-15 tracey FILE *f;
2966 59d3c40e 2020-02-03 stsp char *d_file = NULL;
2967 2c251c14 2020-01-15 tracey unsigned int len;
2968 59d3c40e 2020-02-03 stsp size_t n;
2969 2c251c14 2020-01-15 tracey
2970 59d3c40e 2020-02-03 stsp *url = NULL;
2971 2c251c14 2020-01-15 tracey
2972 59d3c40e 2020-02-03 stsp if (asprintf(&d_file, "%s/cloneurl", dir) == -1)
2973 59d3c40e 2020-02-03 stsp return got_error_from_errno("asprintf");
2974 2c251c14 2020-01-15 tracey
2975 59d3c40e 2020-02-03 stsp f = fopen(d_file, "r");
2976 59d3c40e 2020-02-03 stsp if (f == NULL) {
2977 59d3c40e 2020-02-03 stsp if (errno != ENOENT && errno != EACCES)
2978 59d3c40e 2020-02-03 stsp error = got_error_from_errno2("fopen", d_file);
2979 59d3c40e 2020-02-03 stsp goto done;
2980 59d3c40e 2020-02-03 stsp }
2981 59d3c40e 2020-02-03 stsp
2982 59d3c40e 2020-02-03 stsp if (fseek(f, 0, SEEK_END) == -1) {
2983 59d3c40e 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
2984 59d3c40e 2020-02-03 stsp goto done;
2985 59d3c40e 2020-02-03 stsp }
2986 59d3c40e 2020-02-03 stsp len = ftell(f);
2987 59d3c40e 2020-02-03 stsp if (len == -1) {
2988 59d3c40e 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
2989 59d3c40e 2020-02-03 stsp goto done;
2990 59d3c40e 2020-02-03 stsp }
2991 59d3c40e 2020-02-03 stsp if (fseek(f, 0, SEEK_SET) == -1) {
2992 59d3c40e 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
2993 59d3c40e 2020-02-03 stsp goto done;
2994 59d3c40e 2020-02-03 stsp }
2995 2c251c14 2020-01-15 tracey
2996 59d3c40e 2020-02-03 stsp *url = calloc(len + 1, sizeof(**url));
2997 59d3c40e 2020-02-03 stsp if (*url == NULL) {
2998 59d3c40e 2020-02-03 stsp error = got_error_from_errno("calloc");
2999 59d3c40e 2020-02-03 stsp goto done;
3000 59d3c40e 2020-02-03 stsp }
3001 2c251c14 2020-01-15 tracey
3002 59d3c40e 2020-02-03 stsp n = fread(*url, 1, len, f);
3003 59d3c40e 2020-02-03 stsp if (n == 0 && ferror(f))
3004 59d3c40e 2020-02-03 stsp error = got_ferror(f, GOT_ERR_IO);
3005 59d3c40e 2020-02-03 stsp done:
3006 56b63ca4 2021-01-22 stsp if (f && fclose(f) == EOF && error == NULL)
3007 59d3c40e 2020-02-03 stsp error = got_error_from_errno("fclose");
3008 2c251c14 2020-01-15 tracey free(d_file);
3009 59d3c40e 2020-02-03 stsp return NULL;
3010 8d4d2453 2020-01-15 tracey }
3011 8d4d2453 2020-01-15 tracey
3012 6eccd105 2020-02-03 stsp static const struct got_error *
3013 38b240fb 2020-02-06 tracey gw_output_repo_tags(struct gw_trans *gw_trans, struct gw_header *header,
3014 38b240fb 2020-02-06 tracey int limit, int tag_type)
3015 8d4d2453 2020-01-15 tracey {
3016 87f9ebf5 2020-01-15 tracey const struct got_error *error = NULL;
3017 87f9ebf5 2020-01-15 tracey struct got_reflist_head refs;
3018 87f9ebf5 2020-01-15 tracey struct got_reflist_entry *re;
3019 38b240fb 2020-02-06 tracey char *age = NULL;
3020 ef2c200c 2020-02-07 tracey char *id_str = NULL, *newline, *href_commits = NULL;
3021 38b240fb 2020-02-06 tracey char *tag_commit0 = NULL, *href_tag = NULL, *href_briefs = NULL;
3022 6eccd105 2020-02-03 stsp struct got_tag_object *tag = NULL;
3023 38b240fb 2020-02-06 tracey enum kcgi_err kerr = KCGI_OK;
3024 ff4bb25f 2020-02-19 tracey int summary_header_displayed = 0, start_tag = 0, chk_next = 0;
3025 ff4bb25f 2020-02-19 tracey int prev_set = 0, tag_count = 0;
3026 8d4d2453 2020-01-15 tracey
3027 d9dff0e5 2020-12-26 stsp TAILQ_INIT(&refs);
3028 a0f36e03 2020-01-28 stsp
3029 deac617c 2020-02-14 tracey error = got_ref_list(&refs, gw_trans->repo, "refs/tags",
3030 deac617c 2020-02-14 tracey got_ref_cmp_tags, gw_trans->repo);
3031 ec46ccd7 2020-01-15 tracey if (error)
3032 87f9ebf5 2020-01-15 tracey goto done;
3033 87f9ebf5 2020-01-15 tracey
3034 d9dff0e5 2020-12-26 stsp TAILQ_FOREACH(re, &refs, entry) {
3035 87f9ebf5 2020-01-15 tracey const char *refname;
3036 4ff7391f 2020-01-28 tracey const char *tagger;
3037 6eccd105 2020-02-03 stsp const char *tag_commit;
3038 87f9ebf5 2020-01-15 tracey time_t tagger_time;
3039 87f9ebf5 2020-01-15 tracey struct got_object_id *id;
3040 ef2c200c 2020-02-07 tracey struct got_commit_object *commit = NULL;
3041 87f9ebf5 2020-01-15 tracey
3042 87f9ebf5 2020-01-15 tracey refname = got_ref_get_name(re->ref);
3043 87f9ebf5 2020-01-15 tracey if (strncmp(refname, "refs/tags/", 10) != 0)
3044 87f9ebf5 2020-01-15 tracey continue;
3045 87f9ebf5 2020-01-15 tracey refname += 10;
3046 87f9ebf5 2020-01-15 tracey
3047 deac617c 2020-02-14 tracey error = got_ref_resolve(&id, gw_trans->repo, re->ref);
3048 87f9ebf5 2020-01-15 tracey if (error)
3049 87f9ebf5 2020-01-15 tracey goto done;
3050 38b240fb 2020-02-06 tracey
3051 deac617c 2020-02-14 tracey error = got_object_open_as_tag(&tag, gw_trans->repo, id);
3052 38b240fb 2020-02-06 tracey if (error) {
3053 ef2c200c 2020-02-07 tracey if (error->code != GOT_ERR_OBJ_TYPE) {
3054 ef2c200c 2020-02-07 tracey free(id);
3055 ef2c200c 2020-02-07 tracey goto done;
3056 ef2c200c 2020-02-07 tracey }
3057 ef2c200c 2020-02-07 tracey /* "lightweight" tag */
3058 deac617c 2020-02-14 tracey error = got_object_open_as_commit(&commit,
3059 deac617c 2020-02-14 tracey gw_trans->repo, id);
3060 ef2c200c 2020-02-07 tracey if (error) {
3061 ef2c200c 2020-02-07 tracey free(id);
3062 ef2c200c 2020-02-07 tracey goto done;
3063 ef2c200c 2020-02-07 tracey }
3064 ef2c200c 2020-02-07 tracey tagger = got_object_commit_get_committer(commit);
3065 ef2c200c 2020-02-07 tracey tagger_time =
3066 ef2c200c 2020-02-07 tracey got_object_commit_get_committer_time(commit);
3067 ef2c200c 2020-02-07 tracey error = got_object_id_str(&id_str, id);
3068 ef2c200c 2020-02-07 tracey free(id);
3069 ef2c200c 2020-02-07 tracey } else {
3070 ef2c200c 2020-02-07 tracey free(id);
3071 ef2c200c 2020-02-07 tracey tagger = got_object_tag_get_tagger(tag);
3072 ef2c200c 2020-02-07 tracey tagger_time = got_object_tag_get_tagger_time(tag);
3073 ef2c200c 2020-02-07 tracey error = got_object_id_str(&id_str,
3074 ef2c200c 2020-02-07 tracey got_object_tag_get_object_id(tag));
3075 38b240fb 2020-02-06 tracey }
3076 87f9ebf5 2020-01-15 tracey if (error)
3077 87f9ebf5 2020-01-15 tracey goto done;
3078 87f9ebf5 2020-01-15 tracey
3079 38b240fb 2020-02-06 tracey if (tag_type == TAGFULL && strncmp(id_str, header->commit_id,
3080 38b240fb 2020-02-06 tracey strlen(id_str)) != 0)
3081 38b240fb 2020-02-06 tracey continue;
3082 38b240fb 2020-02-06 tracey
3083 ff4bb25f 2020-02-19 tracey if (tag_type == TAGBRIEF && gw_trans->commit_id &&
3084 ff4bb25f 2020-02-19 tracey start_tag == 0 && strncmp(id_str, header->commit_id,
3085 ff4bb25f 2020-02-19 tracey strlen(id_str)) != 0) {
3086 ff4bb25f 2020-02-19 tracey continue;
3087 ff4bb25f 2020-02-19 tracey } else {
3088 ff4bb25f 2020-02-19 tracey start_tag = 1;
3089 ff4bb25f 2020-02-19 tracey }
3090 ff4bb25f 2020-02-19 tracey
3091 ff4bb25f 2020-02-19 tracey tag_count++;
3092 ff4bb25f 2020-02-19 tracey
3093 ff4bb25f 2020-02-19 tracey if (prev_set == 0 && start_tag == 1) {
3094 ff4bb25f 2020-02-19 tracey gw_trans->next_prev_id = strdup(id_str);
3095 ff4bb25f 2020-02-19 tracey if (gw_trans->next_prev_id == NULL) {
3096 ff4bb25f 2020-02-19 tracey error = got_error_from_errno("strdup");
3097 ff4bb25f 2020-02-19 tracey goto done;
3098 ff4bb25f 2020-02-19 tracey }
3099 ff4bb25f 2020-02-19 tracey prev_set = 1;
3100 ff4bb25f 2020-02-19 tracey }
3101 ff4bb25f 2020-02-19 tracey
3102 ff4bb25f 2020-02-19 tracey if (chk_next) {
3103 ff4bb25f 2020-02-19 tracey gw_trans->next_id = strdup(id_str);
3104 ff4bb25f 2020-02-19 tracey if (gw_trans->next_id == NULL)
3105 ff4bb25f 2020-02-19 tracey error = got_error_from_errno("strdup");
3106 ff4bb25f 2020-02-19 tracey goto done;
3107 ff4bb25f 2020-02-19 tracey }
3108 ff4bb25f 2020-02-19 tracey
3109 ef2c200c 2020-02-07 tracey if (commit) {
3110 ef2c200c 2020-02-07 tracey error = got_object_commit_get_logmsg(&tag_commit0,
3111 ef2c200c 2020-02-07 tracey commit);
3112 ef2c200c 2020-02-07 tracey if (error)
3113 ef2c200c 2020-02-07 tracey goto done;
3114 ef2c200c 2020-02-07 tracey got_object_commit_close(commit);
3115 ef2c200c 2020-02-07 tracey } else {
3116 ef2c200c 2020-02-07 tracey tag_commit0 = strdup(got_object_tag_get_message(tag));
3117 ef2c200c 2020-02-07 tracey if (tag_commit0 == NULL) {
3118 ef2c200c 2020-02-07 tracey error = got_error_from_errno("strdup");
3119 ef2c200c 2020-02-07 tracey goto done;
3120 ef2c200c 2020-02-07 tracey }
3121 87f9ebf5 2020-01-15 tracey }
3122 87f9ebf5 2020-01-15 tracey
3123 f2f46662 2020-01-23 tracey tag_commit = tag_commit0;
3124 f2f46662 2020-01-23 tracey while (*tag_commit == '\n')
3125 f2f46662 2020-01-23 tracey tag_commit++;
3126 87f9ebf5 2020-01-15 tracey
3127 87f9ebf5 2020-01-15 tracey switch (tag_type) {
3128 87f9ebf5 2020-01-15 tracey case TAGBRIEF:
3129 f2f46662 2020-01-23 tracey newline = strchr(tag_commit, '\n');
3130 87f9ebf5 2020-01-15 tracey if (newline)
3131 87f9ebf5 2020-01-15 tracey *newline = '\0';
3132 87f9ebf5 2020-01-15 tracey
3133 38b240fb 2020-02-06 tracey if (summary_header_displayed == 0) {
3134 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req,
3135 38b240fb 2020-02-06 tracey KELEM_DIV, KATTR_ID,
3136 38b240fb 2020-02-06 tracey "summary_tags_title_wrapper", KATTR__MAX);
3137 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3138 38b240fb 2020-02-06 tracey goto done;
3139 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req,
3140 38b240fb 2020-02-06 tracey KELEM_DIV, KATTR_ID,
3141 38b240fb 2020-02-06 tracey "summary_tags_title", KATTR__MAX);
3142 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3143 38b240fb 2020-02-06 tracey goto done;
3144 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req,
3145 38b240fb 2020-02-06 tracey "Tags");
3146 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3147 38b240fb 2020-02-06 tracey goto done;
3148 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req,
3149 38b240fb 2020-02-06 tracey 2);
3150 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3151 38b240fb 2020-02-06 tracey goto done;
3152 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req,
3153 38b240fb 2020-02-06 tracey KELEM_DIV, KATTR_ID,
3154 38b240fb 2020-02-06 tracey "summary_tags_content", KATTR__MAX);
3155 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3156 38b240fb 2020-02-06 tracey goto done;
3157 38b240fb 2020-02-06 tracey summary_header_displayed = 1;
3158 38b240fb 2020-02-06 tracey }
3159 38b240fb 2020-02-06 tracey
3160 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3161 ff4bb25f 2020-02-19 tracey KATTR_ID, "tag_wrapper", KATTR__MAX);
3162 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3163 38b240fb 2020-02-06 tracey goto done;
3164 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3165 ff4bb25f 2020-02-19 tracey KATTR_ID, "tag_age", KATTR__MAX);
3166 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3167 38b240fb 2020-02-06 tracey goto done;
3168 55ccf528 2020-02-03 stsp error = gw_get_time_str(&age, tagger_time, TM_DIFF);
3169 55ccf528 2020-02-03 stsp if (error)
3170 87f9ebf5 2020-01-15 tracey goto done;
3171 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req,
3172 38b240fb 2020-02-06 tracey age ? age : "");
3173 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3174 38b240fb 2020-02-06 tracey goto done;
3175 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3176 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3177 38b240fb 2020-02-06 tracey goto done;
3178 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3179 ff4bb25f 2020-02-19 tracey KATTR_ID, "tag", KATTR__MAX);
3180 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3181 38b240fb 2020-02-06 tracey goto done;
3182 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, refname);
3183 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3184 38b240fb 2020-02-06 tracey goto done;
3185 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3186 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3187 38b240fb 2020-02-06 tracey goto done;
3188 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3189 ff4bb25f 2020-02-19 tracey KATTR_ID, "tag_name", KATTR__MAX);
3190 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3191 dad0fde4 2020-02-06 tracey goto done;
3192 12003b6a 2020-04-14 tracey
3193 12003b6a 2020-04-14 tracey href_tag = khttp_urlpart(NULL, NULL, "gotweb", "path",
3194 12003b6a 2020-04-14 tracey gw_trans->repo_name, "action", "tag", "commit",
3195 12003b6a 2020-04-14 tracey id_str, NULL);
3196 19ff7638 2020-04-14 tracey if (href_tag == NULL) {
3197 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
3198 19ff7638 2020-04-14 tracey goto done;
3199 19ff7638 2020-04-14 tracey }
3200 056e30c8 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
3201 056e30c8 2020-02-06 tracey KATTR_HREF, href_tag, KATTR__MAX);
3202 056e30c8 2020-02-06 tracey if (kerr != KCGI_OK)
3203 056e30c8 2020-02-06 tracey goto done;
3204 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, tag_commit);
3205 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3206 38b240fb 2020-02-06 tracey goto done;
3207 dad0fde4 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
3208 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3209 38b240fb 2020-02-06 tracey goto done;
3210 87f9ebf5 2020-01-15 tracey
3211 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3212 38b240fb 2020-02-06 tracey KATTR_ID, "navs_wrapper", KATTR__MAX);
3213 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3214 38b240fb 2020-02-06 tracey goto done;
3215 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3216 38b240fb 2020-02-06 tracey KATTR_ID, "navs", KATTR__MAX);
3217 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3218 38b240fb 2020-02-06 tracey goto done;
3219 38b240fb 2020-02-06 tracey
3220 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
3221 38b240fb 2020-02-06 tracey KATTR_HREF, href_tag, KATTR__MAX);
3222 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3223 38b240fb 2020-02-06 tracey goto done;
3224 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, "tag");
3225 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3226 38b240fb 2020-02-06 tracey goto done;
3227 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3228 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3229 38b240fb 2020-02-06 tracey goto done;
3230 87f9ebf5 2020-01-15 tracey
3231 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
3232 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3233 87f9ebf5 2020-01-15 tracey goto done;
3234 12003b6a 2020-04-14 tracey
3235 12003b6a 2020-04-14 tracey href_briefs = khttp_urlpart(NULL, NULL, "gotweb",
3236 12003b6a 2020-04-14 tracey "path", gw_trans->repo_name, "action", "briefs",
3237 12003b6a 2020-04-14 tracey "commit", id_str, NULL);
3238 19ff7638 2020-04-14 tracey if (href_briefs == NULL) {
3239 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
3240 19ff7638 2020-04-14 tracey goto done;
3241 19ff7638 2020-04-14 tracey }
3242 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
3243 38b240fb 2020-02-06 tracey KATTR_HREF, href_briefs, KATTR__MAX);
3244 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3245 38b240fb 2020-02-06 tracey goto done;
3246 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req,
3247 38b240fb 2020-02-06 tracey "commit briefs");
3248 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3249 38b240fb 2020-02-06 tracey goto done;
3250 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3251 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3252 38b240fb 2020-02-06 tracey goto done;
3253 87f9ebf5 2020-01-15 tracey
3254 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
3255 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3256 38b240fb 2020-02-06 tracey goto done;
3257 38b240fb 2020-02-06 tracey
3258 12003b6a 2020-04-14 tracey href_commits = khttp_urlpart(NULL, NULL, "gotweb",
3259 12003b6a 2020-04-14 tracey "path", gw_trans->repo_name, "action", "commits",
3260 12003b6a 2020-04-14 tracey "commit", id_str, NULL);
3261 19ff7638 2020-04-14 tracey if (href_commits == NULL) {
3262 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
3263 19ff7638 2020-04-14 tracey goto done;
3264 19ff7638 2020-04-14 tracey }
3265 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
3266 38b240fb 2020-02-06 tracey KATTR_HREF, href_commits, KATTR__MAX);
3267 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3268 38b240fb 2020-02-06 tracey goto done;
3269 32b9f7ed 2020-04-14 tracey kerr = khtml_puts(gw_trans->gw_html_req, "commits");
3270 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3271 38b240fb 2020-02-06 tracey goto done;
3272 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
3273 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3274 38b240fb 2020-02-06 tracey goto done;
3275 38b240fb 2020-02-06 tracey
3276 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3277 38b240fb 2020-02-06 tracey KATTR_ID, "dotted_line", KATTR__MAX);
3278 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3279 38b240fb 2020-02-06 tracey goto done;
3280 ef2c200c 2020-02-07 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
3281 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3282 38b240fb 2020-02-06 tracey goto done;
3283 87f9ebf5 2020-01-15 tracey break;
3284 87f9ebf5 2020-01-15 tracey case TAGFULL:
3285 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3286 38b240fb 2020-02-06 tracey KATTR_ID, "tag_info_date_title", KATTR__MAX);
3287 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3288 38b240fb 2020-02-06 tracey goto done;
3289 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Tag Date:");
3290 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3291 38b240fb 2020-02-06 tracey goto done;
3292 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3293 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3294 38b240fb 2020-02-06 tracey goto done;
3295 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3296 38b240fb 2020-02-06 tracey KATTR_ID, "tag_info_date", KATTR__MAX);
3297 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3298 38b240fb 2020-02-06 tracey goto done;
3299 55ccf528 2020-02-03 stsp error = gw_get_time_str(&age, tagger_time, TM_LONG);
3300 55ccf528 2020-02-03 stsp if (error)
3301 4ff7391f 2020-01-28 tracey goto done;
3302 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req,
3303 38b240fb 2020-02-06 tracey age ? age : "");
3304 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3305 070fee27 2020-02-03 stsp goto done;
3306 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3307 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3308 38b240fb 2020-02-06 tracey goto done;
3309 38b240fb 2020-02-06 tracey
3310 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3311 38b240fb 2020-02-06 tracey KATTR_ID, "tag_info_tagger_title", KATTR__MAX);
3312 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3313 38b240fb 2020-02-06 tracey goto done;
3314 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Tagger:");
3315 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3316 38b240fb 2020-02-06 tracey goto done;
3317 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3318 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3319 38b240fb 2020-02-06 tracey goto done;
3320 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3321 38b240fb 2020-02-06 tracey KATTR_ID, "tag_info_date", KATTR__MAX);
3322 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3323 38b240fb 2020-02-06 tracey goto done;
3324 38b240fb 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, tagger);
3325 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3326 38b240fb 2020-02-06 tracey goto done;
3327 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3328 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3329 38b240fb 2020-02-06 tracey goto done;
3330 38b240fb 2020-02-06 tracey
3331 38b240fb 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
3332 38b240fb 2020-02-06 tracey KATTR_ID, "tag_info", KATTR__MAX);
3333 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3334 38b240fb 2020-02-06 tracey goto done;
3335 78a9dab5 2020-02-07 tracey kerr = khttp_puts(gw_trans->gw_req, tag_commit);
3336 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3337 4ff7391f 2020-01-28 tracey goto done;
3338 87f9ebf5 2020-01-15 tracey break;
3339 87f9ebf5 2020-01-15 tracey default:
3340 87f9ebf5 2020-01-15 tracey break;
3341 87f9ebf5 2020-01-15 tracey }
3342 38b240fb 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
3343 38b240fb 2020-02-06 tracey if (kerr != KCGI_OK)
3344 6eccd105 2020-02-03 stsp goto done;
3345 87ca24ac 2020-02-04 tracey
3346 6eccd105 2020-02-03 stsp if (limit && --limit == 0)
3347 ff4bb25f 2020-02-19 tracey chk_next = 1;
3348 87f9ebf5 2020-01-15 tracey
3349 ef2c200c 2020-02-07 tracey if (tag)
3350 ef2c200c 2020-02-07 tracey got_object_tag_close(tag);
3351 6eccd105 2020-02-03 stsp tag = NULL;
3352 6c6c85af 2020-01-15 tracey free(id_str);
3353 6eccd105 2020-02-03 stsp id_str = NULL;
3354 6c6c85af 2020-01-15 tracey free(age);
3355 55ccf528 2020-02-03 stsp age = NULL;
3356 f2f46662 2020-01-23 tracey free(tag_commit0);
3357 6eccd105 2020-02-03 stsp tag_commit0 = NULL;
3358 38b240fb 2020-02-06 tracey free(href_tag);
3359 38b240fb 2020-02-06 tracey href_tag = NULL;
3360 38b240fb 2020-02-06 tracey free(href_briefs);
3361 38b240fb 2020-02-06 tracey href_briefs = NULL;
3362 38b240fb 2020-02-06 tracey free(href_commits);
3363 38b240fb 2020-02-06 tracey href_commits = NULL;
3364 ff4bb25f 2020-02-19 tracey }
3365 ff4bb25f 2020-02-19 tracey if (tag_count == 0) {
3366 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3367 ff4bb25f 2020-02-19 tracey "summary_tags_title_wrapper", KATTR__MAX);
3368 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
3369 ff4bb25f 2020-02-19 tracey goto done;
3370 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3371 ff4bb25f 2020-02-19 tracey "summary_tags_title", KATTR__MAX);
3372 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
3373 ff4bb25f 2020-02-19 tracey goto done;
3374 ff4bb25f 2020-02-19 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Tags");
3375 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
3376 ff4bb25f 2020-02-19 tracey goto done;
3377 ff4bb25f 2020-02-19 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
3378 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
3379 ff4bb25f 2020-02-19 tracey goto done;
3380 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3381 ff4bb25f 2020-02-19 tracey "summary_tags_content", KATTR__MAX);
3382 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
3383 ff4bb25f 2020-02-19 tracey goto done;
3384 ff4bb25f 2020-02-19 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3385 ff4bb25f 2020-02-19 tracey "tags_info", KATTR__MAX);
3386 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
3387 ff4bb25f 2020-02-19 tracey goto done;
3388 ff4bb25f 2020-02-19 tracey kerr = khttp_puts(gw_trans->gw_req,
3389 ff4bb25f 2020-02-19 tracey "There are no tags for this repo.");
3390 ff4bb25f 2020-02-19 tracey if (kerr != KCGI_OK)
3391 ff4bb25f 2020-02-19 tracey goto done;
3392 ff4bb25f 2020-02-19 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
3393 6c6c85af 2020-01-15 tracey }
3394 87f9ebf5 2020-01-15 tracey done:
3395 6eccd105 2020-02-03 stsp if (tag)
3396 6eccd105 2020-02-03 stsp got_object_tag_close(tag);
3397 6eccd105 2020-02-03 stsp free(id_str);
3398 55ccf528 2020-02-03 stsp free(age);
3399 6eccd105 2020-02-03 stsp free(tag_commit0);
3400 38b240fb 2020-02-06 tracey free(href_tag);
3401 38b240fb 2020-02-06 tracey free(href_briefs);
3402 38b240fb 2020-02-06 tracey free(href_commits);
3403 6eccd105 2020-02-03 stsp got_ref_list_free(&refs);
3404 38b240fb 2020-02-06 tracey if (error == NULL && kerr != KCGI_OK)
3405 38b240fb 2020-02-06 tracey error = gw_kcgi_error(kerr);
3406 6eccd105 2020-02-03 stsp return error;
3407 f2f46662 2020-01-23 tracey }
3408 f2f46662 2020-01-23 tracey
3409 f2f46662 2020-01-23 tracey static void
3410 b0a1bc86 2020-02-14 stsp gw_free_header(struct gw_header *header)
3411 f2f46662 2020-01-23 tracey {
3412 f2f46662 2020-01-23 tracey free(header->path);
3413 4e8d6e3e 2020-02-14 tracey free(header->author);
3414 4e8d6e3e 2020-02-14 tracey free(header->committer);
3415 f2f46662 2020-01-23 tracey free(header->refs_str);
3416 f2f46662 2020-01-23 tracey free(header->commit_id);
3417 f2f46662 2020-01-23 tracey free(header->parent_id);
3418 f2f46662 2020-01-23 tracey free(header->tree_id);
3419 f2f46662 2020-01-23 tracey free(header->commit_msg);
3420 f2f46662 2020-01-23 tracey }
3421 f2f46662 2020-01-23 tracey
3422 f2f46662 2020-01-23 tracey static struct gw_header *
3423 f2f46662 2020-01-23 tracey gw_init_header()
3424 f2f46662 2020-01-23 tracey {
3425 f2f46662 2020-01-23 tracey struct gw_header *header;
3426 f2f46662 2020-01-23 tracey
3427 ae36ed87 2020-01-28 stsp header = malloc(sizeof(*header));
3428 ae36ed87 2020-01-28 stsp if (header == NULL)
3429 f2f46662 2020-01-23 tracey return NULL;
3430 f2f46662 2020-01-23 tracey
3431 f2f46662 2020-01-23 tracey header->path = NULL;
3432 d9dff0e5 2020-12-26 stsp TAILQ_INIT(&header->refs);
3433 5c65becf 2020-02-13 tracey
3434 5c65becf 2020-02-13 tracey header->refs_str = NULL;
3435 5c65becf 2020-02-13 tracey header->commit_id = NULL;
3436 f9315db0 2020-02-14 tracey header->committer = NULL;
3437 f9315db0 2020-02-14 tracey header->author = NULL;
3438 5c65becf 2020-02-13 tracey header->parent_id = NULL;
3439 5c65becf 2020-02-13 tracey header->tree_id = NULL;
3440 5c65becf 2020-02-13 tracey header->commit_msg = NULL;
3441 f2f46662 2020-01-23 tracey
3442 f2f46662 2020-01-23 tracey return header;
3443 f2f46662 2020-01-23 tracey }
3444 f2f46662 2020-01-23 tracey
3445 f2f46662 2020-01-23 tracey static const struct got_error *
3446 f2f46662 2020-01-23 tracey gw_get_commits(struct gw_trans * gw_trans, struct gw_header *header,
3447 3c245a0e 2020-02-14 tracey int limit, struct got_object_id *id)
3448 f2f46662 2020-01-23 tracey {
3449 f2f46662 2020-01-23 tracey const struct got_error *error = NULL;
3450 f2f46662 2020-01-23 tracey struct got_commit_graph *graph = NULL;
3451 4e8d6e3e 2020-02-14 tracey struct got_commit_object *commit = NULL;
3452 55e46400 2020-02-18 tracey int chk_next = 0, chk_multi = 0, prev_set = 0;
3453 f2f46662 2020-01-23 tracey
3454 f2f46662 2020-01-23 tracey error = got_commit_graph_open(&graph, header->path, 0);
3455 f2f46662 2020-01-23 tracey if (error)
3456 00f13350 2020-02-10 tracey return error;
3457 f2f46662 2020-01-23 tracey
3458 deac617c 2020-02-14 tracey error = got_commit_graph_iter_start(graph, id, gw_trans->repo, NULL,
3459 3c245a0e 2020-02-14 tracey NULL);
3460 f2f46662 2020-01-23 tracey if (error)
3461 f2f46662 2020-01-23 tracey goto done;
3462 f2f46662 2020-01-23 tracey
3463 f2f46662 2020-01-23 tracey for (;;) {
3464 deac617c 2020-02-14 tracey error = got_commit_graph_iter_next(&id, graph, gw_trans->repo,
3465 3c245a0e 2020-02-14 tracey NULL, NULL);
3466 f2f46662 2020-01-23 tracey if (error) {
3467 f2f46662 2020-01-23 tracey if (error->code == GOT_ERR_ITER_COMPLETED)
3468 f2f46662 2020-01-23 tracey error = NULL;
3469 f2f46662 2020-01-23 tracey goto done;
3470 f2f46662 2020-01-23 tracey }
3471 3c245a0e 2020-02-14 tracey if (id == NULL)
3472 f2f46662 2020-01-23 tracey goto done;
3473 f2f46662 2020-01-23 tracey
3474 deac617c 2020-02-14 tracey error = got_object_open_as_commit(&commit, gw_trans->repo, id);
3475 4e8d6e3e 2020-02-14 tracey if (error)
3476 4e8d6e3e 2020-02-14 tracey goto done;
3477 bf4484a3 2020-02-18 tracey if (limit == 1 && chk_multi == 0 &&
3478 bf4484a3 2020-02-18 tracey gw_trans->gw_conf->got_max_commits_display != 1) {
3479 3c245a0e 2020-02-14 tracey error = gw_get_commit(gw_trans, header, commit, id);
3480 4e8d6e3e 2020-02-14 tracey if (error)
3481 4e8d6e3e 2020-02-14 tracey goto done;
3482 4e8d6e3e 2020-02-14 tracey } else {
3483 55e46400 2020-02-18 tracey chk_multi = 1;
3484 f2f46662 2020-01-23 tracey struct gw_header *n_header = NULL;
3485 5147ab56 2020-01-29 stsp if ((n_header = gw_init_header()) == NULL) {
3486 f2f46662 2020-01-23 tracey error = got_error_from_errno("malloc");
3487 a942aa37 2020-02-10 tracey goto done;
3488 d1635ae4 2020-02-13 tracey }
3489 bf93a5c0 2020-02-15 tracey error = got_ref_list(&n_header->refs, gw_trans->repo,
3490 bf93a5c0 2020-02-15 tracey NULL, got_ref_cmp_by_name, NULL);
3491 bf93a5c0 2020-02-15 tracey if (error)
3492 bf93a5c0 2020-02-15 tracey goto done;
3493 bf93a5c0 2020-02-15 tracey
3494 3c245a0e 2020-02-14 tracey error = gw_get_commit(gw_trans, n_header, commit, id);
3495 4e8d6e3e 2020-02-14 tracey if (error)
3496 d1635ae4 2020-02-13 tracey goto done;
3497 bc8c6114 2020-02-17 tracey got_ref_list_free(&n_header->refs);
3498 55e46400 2020-02-18 tracey
3499 55e46400 2020-02-18 tracey /*
3500 55e46400 2020-02-18 tracey * we have a commit_id now, so copy it to next_prev_id
3501 55e46400 2020-02-18 tracey * for navigation through gw_briefs and gw_commits
3502 55e46400 2020-02-18 tracey */
3503 55e46400 2020-02-18 tracey if (gw_trans->next_prev_id == NULL && prev_set == 0 &&
3504 55e46400 2020-02-18 tracey (gw_trans->action == GW_BRIEFS ||
3505 55e46400 2020-02-18 tracey gw_trans->action == GW_COMMITS ||
3506 55e46400 2020-02-18 tracey gw_trans->action == GW_SUMMARY)) {
3507 55e46400 2020-02-18 tracey prev_set = 1;
3508 55e46400 2020-02-18 tracey gw_trans->next_prev_id =
3509 55e46400 2020-02-18 tracey strdup(n_header->commit_id);
3510 55e46400 2020-02-18 tracey if (gw_trans->next_prev_id == NULL) {
3511 55e46400 2020-02-18 tracey error = got_error_from_errno("strdup");
3512 55e46400 2020-02-18 tracey goto done;
3513 55e46400 2020-02-18 tracey }
3514 55e46400 2020-02-18 tracey }
3515 55e46400 2020-02-18 tracey
3516 55e46400 2020-02-18 tracey /*
3517 55e46400 2020-02-18 tracey * check for one more commit before breaking,
3518 55e46400 2020-02-18 tracey * so we know whether to navicate through gw_briefs
3519 55e46400 2020-02-18 tracey * gw_commits and gw_summary
3520 55e46400 2020-02-18 tracey */
3521 55e46400 2020-02-18 tracey if (chk_next && (gw_trans->action == GW_BRIEFS||
3522 55e46400 2020-02-18 tracey gw_trans->action == GW_COMMITS ||
3523 55e46400 2020-02-18 tracey gw_trans->action == GW_SUMMARY)) {
3524 55e46400 2020-02-18 tracey gw_trans->next_id = strdup(n_header->commit_id);
3525 55e46400 2020-02-18 tracey if (gw_trans->next_id == NULL)
3526 55e46400 2020-02-18 tracey error = got_error_from_errno("strdup");
3527 55e46400 2020-02-18 tracey goto done;
3528 55e46400 2020-02-18 tracey }
3529 55e46400 2020-02-18 tracey
3530 f2f46662 2020-01-23 tracey TAILQ_INSERT_TAIL(&gw_trans->gw_headers, n_header,
3531 f2f46662 2020-01-23 tracey entry);
3532 f2f46662 2020-01-23 tracey }
3533 55e46400 2020-02-18 tracey if (error || (limit && --limit == 0)) {
3534 55e46400 2020-02-18 tracey if (chk_multi == 0)
3535 55e46400 2020-02-18 tracey break;
3536 55e46400 2020-02-18 tracey chk_next = 1;
3537 55e46400 2020-02-18 tracey }
3538 f2f46662 2020-01-23 tracey }
3539 f2f46662 2020-01-23 tracey done:
3540 4e8d6e3e 2020-02-14 tracey if (commit != NULL)
3541 4e8d6e3e 2020-02-14 tracey got_object_commit_close(commit);
3542 f2f46662 2020-01-23 tracey if (graph)
3543 f2f46662 2020-01-23 tracey got_commit_graph_close(graph);
3544 f2f46662 2020-01-23 tracey return error;
3545 f2f46662 2020-01-23 tracey }
3546 f2f46662 2020-01-23 tracey
3547 f2f46662 2020-01-23 tracey static const struct got_error *
3548 4e8d6e3e 2020-02-14 tracey gw_get_commit(struct gw_trans *gw_trans, struct gw_header *header,
3549 4e8d6e3e 2020-02-14 tracey struct got_commit_object *commit, struct got_object_id *id)
3550 f2f46662 2020-01-23 tracey {
3551 f2f46662 2020-01-23 tracey const struct got_error *error = NULL;
3552 f2f46662 2020-01-23 tracey struct got_reflist_entry *re;
3553 f2f46662 2020-01-23 tracey struct got_object_id *id2 = NULL;
3554 f2f46662 2020-01-23 tracey struct got_object_qid *parent_id;
3555 a81394a7 2020-02-13 stsp char *commit_msg = NULL, *commit_msg0;
3556 f2f46662 2020-01-23 tracey
3557 f2f46662 2020-01-23 tracey /*print commit*/
3558 d9dff0e5 2020-12-26 stsp TAILQ_FOREACH(re, &header->refs, entry) {
3559 f2f46662 2020-01-23 tracey char *s;
3560 f2f46662 2020-01-23 tracey const char *name;
3561 f2f46662 2020-01-23 tracey struct got_tag_object *tag = NULL;
3562 3721d310 2020-09-23 stsp struct got_object_id *ref_id;
3563 f2f46662 2020-01-23 tracey int cmp;
3564 f2f46662 2020-01-23 tracey
3565 eb4f3ad3 2020-02-14 stsp if (got_ref_is_symbolic(re->ref))
3566 f2f46662 2020-01-23 tracey continue;
3567 eb4f3ad3 2020-02-14 stsp
3568 eb4f3ad3 2020-02-14 stsp name = got_ref_get_name(re->ref);
3569 f2f46662 2020-01-23 tracey if (strncmp(name, "refs/", 5) == 0)
3570 f2f46662 2020-01-23 tracey name += 5;
3571 f2f46662 2020-01-23 tracey if (strncmp(name, "got/", 4) == 0)
3572 f2f46662 2020-01-23 tracey continue;
3573 f2f46662 2020-01-23 tracey if (strncmp(name, "heads/", 6) == 0)
3574 f2f46662 2020-01-23 tracey name += 6;
3575 abdd569e 2020-09-23 stsp if (strncmp(name, "remotes/", 8) == 0) {
3576 f2f46662 2020-01-23 tracey name += 8;
3577 abdd569e 2020-09-23 stsp s = strstr(name, "/" GOT_REF_HEAD);
3578 abdd569e 2020-09-23 stsp if (s != NULL && s[strlen(s)] == '\0')
3579 abdd569e 2020-09-23 stsp continue;
3580 abdd569e 2020-09-23 stsp }
3581 3721d310 2020-09-23 stsp error = got_ref_resolve(&ref_id, gw_trans->repo, re->ref);
3582 3721d310 2020-09-23 stsp if (error)
3583 3721d310 2020-09-23 stsp return error;
3584 f2f46662 2020-01-23 tracey if (strncmp(name, "tags/", 5) == 0) {
3585 deac617c 2020-02-14 tracey error = got_object_open_as_tag(&tag, gw_trans->repo,
3586 3721d310 2020-09-23 stsp ref_id);
3587 f2f46662 2020-01-23 tracey if (error) {
3588 3721d310 2020-09-23 stsp if (error->code != GOT_ERR_OBJ_TYPE) {
3589 3721d310 2020-09-23 stsp free(ref_id);
3590 f2f46662 2020-01-23 tracey continue;
3591 3721d310 2020-09-23 stsp }
3592 f2f46662 2020-01-23 tracey /*
3593 f2f46662 2020-01-23 tracey * Ref points at something other
3594 f2f46662 2020-01-23 tracey * than a tag.
3595 f2f46662 2020-01-23 tracey */
3596 f2f46662 2020-01-23 tracey error = NULL;
3597 f2f46662 2020-01-23 tracey tag = NULL;
3598 f2f46662 2020-01-23 tracey }
3599 f2f46662 2020-01-23 tracey }
3600 f2f46662 2020-01-23 tracey cmp = got_object_id_cmp(tag ?
3601 3721d310 2020-09-23 stsp got_object_tag_get_object_id(tag) : ref_id, id);
3602 3721d310 2020-09-23 stsp free(ref_id);
3603 f2f46662 2020-01-23 tracey if (tag)
3604 f2f46662 2020-01-23 tracey got_object_tag_close(tag);
3605 f2f46662 2020-01-23 tracey if (cmp != 0)
3606 f2f46662 2020-01-23 tracey continue;
3607 a81394a7 2020-02-13 stsp s = header->refs_str;
3608 a81394a7 2020-02-13 stsp if (asprintf(&header->refs_str, "%s%s%s", s ? s : "",
3609 88d59c36 2020-01-29 stsp s ? ", " : "", name) == -1) {
3610 f2f46662 2020-01-23 tracey error = got_error_from_errno("asprintf");
3611 f2f46662 2020-01-23 tracey free(s);
3612 a81394a7 2020-02-13 stsp header->refs_str = NULL;
3613 f2f46662 2020-01-23 tracey return error;
3614 f2f46662 2020-01-23 tracey }
3615 f2f46662 2020-01-23 tracey free(s);
3616 f2f46662 2020-01-23 tracey }
3617 f1200fe3 2020-02-13 tracey
3618 4e8d6e3e 2020-02-14 tracey error = got_object_id_str(&header->commit_id, id);
3619 f2f46662 2020-01-23 tracey if (error)
3620 f2f46662 2020-01-23 tracey return error;
3621 f2f46662 2020-01-23 tracey
3622 f2f46662 2020-01-23 tracey error = got_object_id_str(&header->tree_id,
3623 4e8d6e3e 2020-02-14 tracey got_object_commit_get_tree_id(commit));
3624 f2f46662 2020-01-23 tracey if (error)
3625 f2f46662 2020-01-23 tracey return error;
3626 f2f46662 2020-01-23 tracey
3627 f2f46662 2020-01-23 tracey if (gw_trans->action == GW_DIFF) {
3628 f2f46662 2020-01-23 tracey parent_id = SIMPLEQ_FIRST(
3629 4e8d6e3e 2020-02-14 tracey got_object_commit_get_parent_ids(commit));
3630 f2f46662 2020-01-23 tracey if (parent_id != NULL) {
3631 f2f46662 2020-01-23 tracey id2 = got_object_id_dup(parent_id->id);
3632 f2f46662 2020-01-23 tracey free (parent_id);
3633 f2f46662 2020-01-23 tracey error = got_object_id_str(&header->parent_id, id2);
3634 f2f46662 2020-01-23 tracey if (error)
3635 f2f46662 2020-01-23 tracey return error;
3636 f2f46662 2020-01-23 tracey free(id2);
3637 a942aa37 2020-02-10 tracey } else {
3638 d1635ae4 2020-02-13 tracey header->parent_id = strdup("/dev/null");
3639 d1635ae4 2020-02-13 tracey if (header->parent_id == NULL) {
3640 d1635ae4 2020-02-13 tracey error = got_error_from_errno("strdup");
3641 a942aa37 2020-02-10 tracey return error;
3642 d1635ae4 2020-02-13 tracey }
3643 d1635ae4 2020-02-13 tracey }
3644 a942aa37 2020-02-10 tracey }
3645 f2f46662 2020-01-23 tracey
3646 f2f46662 2020-01-23 tracey header->committer_time =
3647 4e8d6e3e 2020-02-14 tracey got_object_commit_get_committer_time(commit);
3648 1177268c 2020-01-28 tracey
3649 d1635ae4 2020-02-13 tracey header->author =
3650 4e8d6e3e 2020-02-14 tracey strdup(got_object_commit_get_author(commit));
3651 4e8d6e3e 2020-02-14 tracey if (header->author == NULL) {
3652 4e8d6e3e 2020-02-14 tracey error = got_error_from_errno("strdup");
3653 4e8d6e3e 2020-02-14 tracey return error;
3654 4e8d6e3e 2020-02-14 tracey }
3655 d1635ae4 2020-02-13 tracey header->committer =
3656 4e8d6e3e 2020-02-14 tracey strdup(got_object_commit_get_committer(commit));
3657 4e8d6e3e 2020-02-14 tracey if (header->committer == NULL) {
3658 4e8d6e3e 2020-02-14 tracey error = got_error_from_errno("strdup");
3659 a942aa37 2020-02-10 tracey return error;
3660 4e8d6e3e 2020-02-14 tracey }
3661 4e8d6e3e 2020-02-14 tracey error = got_object_commit_get_logmsg(&commit_msg0, commit);
3662 f2f46662 2020-01-23 tracey if (error)
3663 f2f46662 2020-01-23 tracey return error;
3664 f2f46662 2020-01-23 tracey
3665 f2f46662 2020-01-23 tracey commit_msg = commit_msg0;
3666 f2f46662 2020-01-23 tracey while (*commit_msg == '\n')
3667 f2f46662 2020-01-23 tracey commit_msg++;
3668 f2f46662 2020-01-23 tracey
3669 d1635ae4 2020-02-13 tracey header->commit_msg = strdup(commit_msg);
3670 d1635ae4 2020-02-13 tracey if (header->commit_msg == NULL)
3671 d1635ae4 2020-02-13 tracey error = got_error_from_errno("strdup");
3672 f2f46662 2020-01-23 tracey free(commit_msg0);
3673 f2f46662 2020-01-23 tracey return error;
3674 f2f46662 2020-01-23 tracey }
3675 f2f46662 2020-01-23 tracey
3676 f2f46662 2020-01-23 tracey static const struct got_error *
3677 f2f46662 2020-01-23 tracey gw_get_header(struct gw_trans *gw_trans, struct gw_header *header, int limit)
3678 f2f46662 2020-01-23 tracey {
3679 f2f46662 2020-01-23 tracey const struct got_error *error = NULL;
3680 f2f46662 2020-01-23 tracey char *in_repo_path = NULL;
3681 3c245a0e 2020-02-14 tracey struct got_object_id *id = NULL;
3682 f2f46662 2020-01-23 tracey
3683 deac617c 2020-02-14 tracey error = got_repo_open(&gw_trans->repo, gw_trans->repo_path, NULL);
3684 f2f46662 2020-01-23 tracey if (error)
3685 f2f46662 2020-01-23 tracey return error;
3686 f2f46662 2020-01-23 tracey
3687 56997cd3 2020-02-14 tracey if (gw_trans->commit_id == NULL) {
3688 f2f46662 2020-01-23 tracey struct got_reference *head_ref;
3689 deac617c 2020-02-14 tracey error = got_ref_open(&head_ref, gw_trans->repo,
3690 f2f46662 2020-01-23 tracey gw_trans->headref, 0);
3691 f2f46662 2020-01-23 tracey if (error)
3692 f2f46662 2020-01-23 tracey return error;
3693 f2f46662 2020-01-23 tracey
3694 deac617c 2020-02-14 tracey error = got_ref_resolve(&id, gw_trans->repo, head_ref);
3695 f2f46662 2020-01-23 tracey got_ref_close(head_ref);
3696 f2f46662 2020-01-23 tracey if (error)
3697 f2f46662 2020-01-23 tracey return error;
3698 f2f46662 2020-01-23 tracey } else {
3699 f2f46662 2020-01-23 tracey struct got_reference *ref;
3700 55e46400 2020-02-18 tracey
3701 56997cd3 2020-02-14 tracey error = got_ref_open(&ref, gw_trans->repo,
3702 56997cd3 2020-02-14 tracey gw_trans->commit_id, 0);
3703 f2f46662 2020-01-23 tracey if (error == NULL) {
3704 f2f46662 2020-01-23 tracey int obj_type;
3705 deac617c 2020-02-14 tracey error = got_ref_resolve(&id, gw_trans->repo, ref);
3706 f2f46662 2020-01-23 tracey got_ref_close(ref);
3707 f2f46662 2020-01-23 tracey if (error)
3708 f2f46662 2020-01-23 tracey return error;
3709 deac617c 2020-02-14 tracey error = got_object_get_type(&obj_type, gw_trans->repo,
3710 3c245a0e 2020-02-14 tracey id);
3711 f2f46662 2020-01-23 tracey if (error)
3712 4e8d6e3e 2020-02-14 tracey goto done;
3713 f2f46662 2020-01-23 tracey if (obj_type == GOT_OBJ_TYPE_TAG) {
3714 f2f46662 2020-01-23 tracey struct got_tag_object *tag;
3715 f2f46662 2020-01-23 tracey error = got_object_open_as_tag(&tag,
3716 deac617c 2020-02-14 tracey gw_trans->repo, id);
3717 f2f46662 2020-01-23 tracey if (error)
3718 4e8d6e3e 2020-02-14 tracey goto done;
3719 f2f46662 2020-01-23 tracey if (got_object_tag_get_object_type(tag) !=
3720 f2f46662 2020-01-23 tracey GOT_OBJ_TYPE_COMMIT) {
3721 f2f46662 2020-01-23 tracey got_object_tag_close(tag);
3722 f2f46662 2020-01-23 tracey error = got_error(GOT_ERR_OBJ_TYPE);
3723 4e8d6e3e 2020-02-14 tracey goto done;
3724 f2f46662 2020-01-23 tracey }
3725 3c245a0e 2020-02-14 tracey free(id);
3726 3c245a0e 2020-02-14 tracey id = got_object_id_dup(
3727 f2f46662 2020-01-23 tracey got_object_tag_get_object_id(tag));
3728 3c245a0e 2020-02-14 tracey if (id == NULL)
3729 f2f46662 2020-01-23 tracey error = got_error_from_errno(
3730 f2f46662 2020-01-23 tracey "got_object_id_dup");
3731 f2f46662 2020-01-23 tracey got_object_tag_close(tag);
3732 f2f46662 2020-01-23 tracey if (error)
3733 4e8d6e3e 2020-02-14 tracey goto done;
3734 f2f46662 2020-01-23 tracey } else if (obj_type != GOT_OBJ_TYPE_COMMIT) {
3735 f2f46662 2020-01-23 tracey error = got_error(GOT_ERR_OBJ_TYPE);
3736 4e8d6e3e 2020-02-14 tracey goto done;
3737 f2f46662 2020-01-23 tracey }
3738 f2f46662 2020-01-23 tracey }
3739 3c245a0e 2020-02-14 tracey error = got_repo_match_object_id_prefix(&id,
3740 56997cd3 2020-02-14 tracey gw_trans->commit_id, GOT_OBJ_TYPE_COMMIT,
3741 deac617c 2020-02-14 tracey gw_trans->repo);
3742 122f3af5 2020-02-14 stsp if (error)
3743 4e8d6e3e 2020-02-14 tracey goto done;
3744 f2f46662 2020-01-23 tracey }
3745 f2f46662 2020-01-23 tracey
3746 deac617c 2020-02-14 tracey error = got_repo_map_path(&in_repo_path, gw_trans->repo,
3747 8b4e047e 2020-11-15 stsp gw_trans->repo_path);
3748 f2f46662 2020-01-23 tracey if (error)
3749 4e8d6e3e 2020-02-14 tracey goto done;
3750 f2f46662 2020-01-23 tracey
3751 f2f46662 2020-01-23 tracey if (in_repo_path) {
3752 d1635ae4 2020-02-13 tracey header->path = strdup(in_repo_path);
3753 d1635ae4 2020-02-13 tracey if (header->path == NULL) {
3754 d1635ae4 2020-02-13 tracey error = got_error_from_errno("strdup");
3755 4e8d6e3e 2020-02-14 tracey goto done;
3756 a942aa37 2020-02-10 tracey }
3757 f2f46662 2020-01-23 tracey }
3758 f2f46662 2020-01-23 tracey
3759 deac617c 2020-02-14 tracey error = got_ref_list(&header->refs, gw_trans->repo, NULL,
3760 f2f46662 2020-01-23 tracey got_ref_cmp_by_name, NULL);
3761 f2f46662 2020-01-23 tracey if (error)
3762 4e8d6e3e 2020-02-14 tracey goto done;
3763 f2f46662 2020-01-23 tracey
3764 3c245a0e 2020-02-14 tracey error = gw_get_commits(gw_trans, header, limit, id);
3765 4e8d6e3e 2020-02-14 tracey done:
3766 4e8d6e3e 2020-02-14 tracey got_ref_list_free(&header->refs);
3767 3c245a0e 2020-02-14 tracey free(id);
3768 4e8d6e3e 2020-02-14 tracey free(in_repo_path);
3769 f2f46662 2020-01-23 tracey return error;
3770 ec46ccd7 2020-01-15 tracey }
3771 ec46ccd7 2020-01-15 tracey
3772 ec46ccd7 2020-01-15 tracey struct blame_line {
3773 ec46ccd7 2020-01-15 tracey int annotated;
3774 ec46ccd7 2020-01-15 tracey char *id_str;
3775 ec46ccd7 2020-01-15 tracey char *committer;
3776 ec46ccd7 2020-01-15 tracey char datebuf[11]; /* YYYY-MM-DD + NUL */
3777 ec46ccd7 2020-01-15 tracey };
3778 ec46ccd7 2020-01-15 tracey
3779 147269d5 2020-01-15 tracey struct gw_blame_cb_args {
3780 ec46ccd7 2020-01-15 tracey struct blame_line *lines;
3781 ec46ccd7 2020-01-15 tracey int nlines;
3782 ec46ccd7 2020-01-15 tracey int nlines_prec;
3783 ec46ccd7 2020-01-15 tracey int lineno_cur;
3784 ec46ccd7 2020-01-15 tracey off_t *line_offsets;
3785 ec46ccd7 2020-01-15 tracey FILE *f;
3786 ec46ccd7 2020-01-15 tracey struct got_repository *repo;
3787 54415d85 2020-01-15 tracey struct gw_trans *gw_trans;
3788 ec46ccd7 2020-01-15 tracey };
3789 ec46ccd7 2020-01-15 tracey
3790 ec46ccd7 2020-01-15 tracey static const struct got_error *
3791 147269d5 2020-01-15 tracey gw_blame_cb(void *arg, int nlines, int lineno, struct got_object_id *id)
3792 ec46ccd7 2020-01-15 tracey {
3793 ec46ccd7 2020-01-15 tracey const struct got_error *err = NULL;
3794 147269d5 2020-01-15 tracey struct gw_blame_cb_args *a = arg;
3795 ec46ccd7 2020-01-15 tracey struct blame_line *bline;
3796 ec46ccd7 2020-01-15 tracey char *line = NULL;
3797 9a9d12ca 2020-02-06 tracey size_t linesize = 0;
3798 ec46ccd7 2020-01-15 tracey struct got_commit_object *commit = NULL;
3799 ec46ccd7 2020-01-15 tracey off_t offset;
3800 ec46ccd7 2020-01-15 tracey struct tm tm;
3801 ec46ccd7 2020-01-15 tracey time_t committer_time;
3802 9a9d12ca 2020-02-06 tracey enum kcgi_err kerr = KCGI_OK;
3803 ec46ccd7 2020-01-15 tracey
3804 ec46ccd7 2020-01-15 tracey if (nlines != a->nlines ||
3805 ec46ccd7 2020-01-15 tracey (lineno != -1 && lineno < 1) || lineno > a->nlines)
3806 ec46ccd7 2020-01-15 tracey return got_error(GOT_ERR_RANGE);
3807 ec46ccd7 2020-01-15 tracey
3808 ec46ccd7 2020-01-15 tracey if (lineno == -1)
3809 ec46ccd7 2020-01-15 tracey return NULL; /* no change in this commit */
3810 ec46ccd7 2020-01-15 tracey
3811 ec46ccd7 2020-01-15 tracey /* Annotate this line. */
3812 ec46ccd7 2020-01-15 tracey bline = &a->lines[lineno - 1];
3813 ec46ccd7 2020-01-15 tracey if (bline->annotated)
3814 ec46ccd7 2020-01-15 tracey return NULL;
3815 ec46ccd7 2020-01-15 tracey err = got_object_id_str(&bline->id_str, id);
3816 ec46ccd7 2020-01-15 tracey if (err)
3817 ec46ccd7 2020-01-15 tracey return err;
3818 ec46ccd7 2020-01-15 tracey
3819 ec46ccd7 2020-01-15 tracey err = got_object_open_as_commit(&commit, a->repo, id);
3820 ec46ccd7 2020-01-15 tracey if (err)
3821 ec46ccd7 2020-01-15 tracey goto done;
3822 ec46ccd7 2020-01-15 tracey
3823 d1635ae4 2020-02-13 tracey bline->committer = strdup(got_object_commit_get_committer(commit));
3824 d1635ae4 2020-02-13 tracey if (bline->committer == NULL) {
3825 d1635ae4 2020-02-13 tracey err = got_error_from_errno("strdup");
3826 ec46ccd7 2020-01-15 tracey goto done;
3827 d1635ae4 2020-02-13 tracey }
3828 ec46ccd7 2020-01-15 tracey
3829 ec46ccd7 2020-01-15 tracey committer_time = got_object_commit_get_committer_time(commit);
3830 ec46ccd7 2020-01-15 tracey if (localtime_r(&committer_time, &tm) == NULL)
3831 ec46ccd7 2020-01-15 tracey return got_error_from_errno("localtime_r");
3832 ec46ccd7 2020-01-15 tracey if (strftime(bline->datebuf, sizeof(bline->datebuf), "%G-%m-%d",
3833 ec6d1a36 2021-03-21 jrick &tm) == 0) {
3834 ec46ccd7 2020-01-15 tracey err = got_error(GOT_ERR_NO_SPACE);
3835 ec46ccd7 2020-01-15 tracey goto done;
3836 ec46ccd7 2020-01-15 tracey }
3837 ec46ccd7 2020-01-15 tracey bline->annotated = 1;
3838 ec46ccd7 2020-01-15 tracey
3839 ec46ccd7 2020-01-15 tracey /* Print lines annotated so far. */
3840 ec46ccd7 2020-01-15 tracey bline = &a->lines[a->lineno_cur - 1];
3841 ec46ccd7 2020-01-15 tracey if (!bline->annotated)
3842 ec46ccd7 2020-01-15 tracey goto done;
3843 ec46ccd7 2020-01-15 tracey
3844 ec46ccd7 2020-01-15 tracey offset = a->line_offsets[a->lineno_cur - 1];
3845 ec46ccd7 2020-01-15 tracey if (fseeko(a->f, offset, SEEK_SET) == -1) {
3846 ec46ccd7 2020-01-15 tracey err = got_error_from_errno("fseeko");
3847 ec46ccd7 2020-01-15 tracey goto done;
3848 ec46ccd7 2020-01-15 tracey }
3849 ec46ccd7 2020-01-15 tracey
3850 ec46ccd7 2020-01-15 tracey while (bline->annotated) {
3851 9a9d12ca 2020-02-06 tracey char *smallerthan, *at, *nl, *committer;
3852 32b9f7ed 2020-04-14 tracey char *href_diff = NULL;
3853 ec46ccd7 2020-01-15 tracey size_t len;
3854 ec46ccd7 2020-01-15 tracey
3855 ec46ccd7 2020-01-15 tracey if (getline(&line, &linesize, a->f) == -1) {
3856 ec46ccd7 2020-01-15 tracey if (ferror(a->f))
3857 ec46ccd7 2020-01-15 tracey err = got_error_from_errno("getline");
3858 ec46ccd7 2020-01-15 tracey break;
3859 ec46ccd7 2020-01-15 tracey }
3860 ec46ccd7 2020-01-15 tracey
3861 ec46ccd7 2020-01-15 tracey committer = bline->committer;
3862 ec46ccd7 2020-01-15 tracey smallerthan = strchr(committer, '<');
3863 ec46ccd7 2020-01-15 tracey if (smallerthan && smallerthan[1] != '\0')
3864 ec46ccd7 2020-01-15 tracey committer = smallerthan + 1;
3865 ec46ccd7 2020-01-15 tracey at = strchr(committer, '@');
3866 ec46ccd7 2020-01-15 tracey if (at)
3867 ec46ccd7 2020-01-15 tracey *at = '\0';
3868 ec46ccd7 2020-01-15 tracey len = strlen(committer);
3869 ec46ccd7 2020-01-15 tracey if (len >= 9)
3870 ec46ccd7 2020-01-15 tracey committer[8] = '\0';
3871 ec46ccd7 2020-01-15 tracey
3872 ec46ccd7 2020-01-15 tracey nl = strchr(line, '\n');
3873 ec46ccd7 2020-01-15 tracey if (nl)
3874 ec46ccd7 2020-01-15 tracey *nl = '\0';
3875 0311ce2d 2020-01-15 tracey
3876 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(a->gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3877 9a9d12ca 2020-02-06 tracey "blame_wrapper", KATTR__MAX);
3878 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3879 9a9d12ca 2020-02-06 tracey goto err;
3880 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(a->gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3881 9a9d12ca 2020-02-06 tracey "blame_number", KATTR__MAX);
3882 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3883 9a9d12ca 2020-02-06 tracey goto err;
3884 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(a->gw_trans->gw_html_req, "%.*d",
3885 32b9f7ed 2020-04-14 tracey a->nlines_prec, a->lineno_cur);
3886 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3887 9a9d12ca 2020-02-06 tracey goto err;
3888 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(a->gw_trans->gw_html_req, 1);
3889 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3890 9a9d12ca 2020-02-06 tracey goto err;
3891 9a9d12ca 2020-02-06 tracey
3892 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(a->gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3893 9a9d12ca 2020-02-06 tracey "blame_hash", KATTR__MAX);
3894 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3895 9a9d12ca 2020-02-06 tracey goto err;
3896 1b33afc0 2020-02-14 tracey
3897 ebc6542a 2020-04-14 tracey href_diff = khttp_urlpart(NULL, NULL, "gotweb", "path",
3898 ebc6542a 2020-04-14 tracey a->gw_trans->repo_name, "action", "diff", "commit",
3899 ebc6542a 2020-04-14 tracey bline->id_str, NULL);
3900 19ff7638 2020-04-14 tracey if (href_diff == NULL) {
3901 19ff7638 2020-04-14 tracey err = got_error_from_errno("khttp_urlpart");
3902 19ff7638 2020-04-14 tracey goto done;
3903 19ff7638 2020-04-14 tracey }
3904 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(a->gw_trans->gw_html_req, KELEM_A,
3905 9a9d12ca 2020-02-06 tracey KATTR_HREF, href_diff, KATTR__MAX);
3906 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3907 9a9d12ca 2020-02-06 tracey goto done;
3908 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(a->gw_trans->gw_html_req, "%.8s",
3909 32b9f7ed 2020-04-14 tracey bline->id_str);
3910 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3911 9a9d12ca 2020-02-06 tracey goto err;
3912 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(a->gw_trans->gw_html_req, 2);
3913 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3914 9a9d12ca 2020-02-06 tracey goto err;
3915 2e676fc5 2020-01-15 tracey
3916 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(a->gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3917 9a9d12ca 2020-02-06 tracey "blame_date", KATTR__MAX);
3918 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3919 9a9d12ca 2020-02-06 tracey goto err;
3920 9a9d12ca 2020-02-06 tracey kerr = khtml_puts(a->gw_trans->gw_html_req, bline->datebuf);
3921 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3922 9a9d12ca 2020-02-06 tracey goto err;
3923 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(a->gw_trans->gw_html_req, 1);
3924 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3925 9a9d12ca 2020-02-06 tracey goto err;
3926 9a9d12ca 2020-02-06 tracey
3927 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(a->gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3928 9a9d12ca 2020-02-06 tracey "blame_author", KATTR__MAX);
3929 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3930 9a9d12ca 2020-02-06 tracey goto err;
3931 9a9d12ca 2020-02-06 tracey kerr = khtml_puts(a->gw_trans->gw_html_req, committer);
3932 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3933 9a9d12ca 2020-02-06 tracey goto err;
3934 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(a->gw_trans->gw_html_req, 1);
3935 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3936 9a9d12ca 2020-02-06 tracey goto err;
3937 9a9d12ca 2020-02-06 tracey
3938 9a9d12ca 2020-02-06 tracey kerr = khtml_attr(a->gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
3939 9a9d12ca 2020-02-06 tracey "blame_code", KATTR__MAX);
3940 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3941 9a9d12ca 2020-02-06 tracey goto err;
3942 9a9d12ca 2020-02-06 tracey kerr = khtml_puts(a->gw_trans->gw_html_req, line);
3943 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3944 9a9d12ca 2020-02-06 tracey goto err;
3945 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(a->gw_trans->gw_html_req, 1);
3946 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3947 9a9d12ca 2020-02-06 tracey goto err;
3948 9a9d12ca 2020-02-06 tracey
3949 9a9d12ca 2020-02-06 tracey kerr = khtml_closeelem(a->gw_trans->gw_html_req, 1);
3950 9a9d12ca 2020-02-06 tracey if (kerr != KCGI_OK)
3951 9a9d12ca 2020-02-06 tracey goto err;
3952 9a9d12ca 2020-02-06 tracey
3953 9a9d12ca 2020-02-06 tracey a->lineno_cur++;
3954 ec46ccd7 2020-01-15 tracey bline = &a->lines[a->lineno_cur - 1];
3955 de6bdba4 2020-01-31 tracey err:
3956 9a9d12ca 2020-02-06 tracey free(href_diff);
3957 ec46ccd7 2020-01-15 tracey }
3958 ec46ccd7 2020-01-15 tracey done:
3959 ec46ccd7 2020-01-15 tracey if (commit)
3960 ec46ccd7 2020-01-15 tracey got_object_commit_close(commit);
3961 ec46ccd7 2020-01-15 tracey free(line);
3962 9a9d12ca 2020-02-06 tracey if (err == NULL && kerr != KCGI_OK)
3963 9a9d12ca 2020-02-06 tracey err = gw_kcgi_error(kerr);
3964 ec46ccd7 2020-01-15 tracey return err;
3965 872742ce 2020-02-01 stsp }
3966 872742ce 2020-02-01 stsp
3967 a81f3554 2020-02-03 stsp static const struct got_error *
3968 84de9106 2020-12-26 stsp gw_output_file_blame(struct gw_trans *gw_trans, struct gw_header *header)
3969 bcbc97d8 2020-01-15 tracey {
3970 bcbc97d8 2020-01-15 tracey const struct got_error *error = NULL;
3971 ec46ccd7 2020-01-15 tracey struct got_object_id *obj_id = NULL;
3972 ec46ccd7 2020-01-15 tracey struct got_object_id *commit_id = NULL;
3973 ec46ccd7 2020-01-15 tracey struct got_blob_object *blob = NULL;
3974 a81f3554 2020-02-03 stsp char *path = NULL, *in_repo_path = NULL;
3975 147269d5 2020-01-15 tracey struct gw_blame_cb_args bca;
3976 119bf4ed 2020-01-15 tracey int i, obj_type;
3977 be659d10 2020-11-18 stsp off_t filesize;
3978 ec46ccd7 2020-01-15 tracey
3979 a81f3554 2020-02-03 stsp if (asprintf(&path, "%s%s%s",
3980 a81f3554 2020-02-03 stsp gw_trans->repo_folder ? gw_trans->repo_folder : "",
3981 4fd4726a 2020-02-03 stsp gw_trans->repo_folder ? "/" : "",
3982 a81f3554 2020-02-03 stsp gw_trans->repo_file) == -1) {
3983 2e676fc5 2020-01-15 tracey error = got_error_from_errno("asprintf");
3984 2e676fc5 2020-01-15 tracey goto done;
3985 2e676fc5 2020-01-15 tracey }
3986 2e676fc5 2020-01-15 tracey
3987 8b4e047e 2020-11-15 stsp error = got_repo_map_path(&in_repo_path, gw_trans->repo, path);
3988 ec46ccd7 2020-01-15 tracey if (error)
3989 ec46ccd7 2020-01-15 tracey goto done;
3990 ec46ccd7 2020-01-15 tracey
3991 56997cd3 2020-02-14 tracey error = got_repo_match_object_id(&commit_id, NULL, gw_trans->commit_id,
3992 84de9106 2020-12-26 stsp GOT_OBJ_TYPE_COMMIT, &header->refs, gw_trans->repo);
3993 ec46ccd7 2020-01-15 tracey if (error)
3994 ec46ccd7 2020-01-15 tracey goto done;
3995 ec46ccd7 2020-01-15 tracey
3996 deac617c 2020-02-14 tracey error = got_object_id_by_path(&obj_id, gw_trans->repo, commit_id,
3997 deac617c 2020-02-14 tracey in_repo_path);
3998 ec46ccd7 2020-01-15 tracey if (error)
3999 ec46ccd7 2020-01-15 tracey goto done;
4000 2e676fc5 2020-01-15 tracey
4001 ec46ccd7 2020-01-15 tracey if (obj_id == NULL) {
4002 ec46ccd7 2020-01-15 tracey error = got_error(GOT_ERR_NO_OBJ);
4003 ec46ccd7 2020-01-15 tracey goto done;
4004 ec46ccd7 2020-01-15 tracey }
4005 ec46ccd7 2020-01-15 tracey
4006 deac617c 2020-02-14 tracey error = got_object_get_type(&obj_type, gw_trans->repo, obj_id);
4007 ec46ccd7 2020-01-15 tracey if (error)
4008 ec46ccd7 2020-01-15 tracey goto done;
4009 ec46ccd7 2020-01-15 tracey
4010 ec46ccd7 2020-01-15 tracey if (obj_type != GOT_OBJ_TYPE_BLOB) {
4011 ec46ccd7 2020-01-15 tracey error = got_error(GOT_ERR_OBJ_TYPE);
4012 ec46ccd7 2020-01-15 tracey goto done;
4013 ec46ccd7 2020-01-15 tracey }
4014 ec46ccd7 2020-01-15 tracey
4015 deac617c 2020-02-14 tracey error = got_object_open_as_blob(&blob, gw_trans->repo, obj_id, 8192);
4016 ec46ccd7 2020-01-15 tracey if (error)
4017 ec46ccd7 2020-01-15 tracey goto done;
4018 ec46ccd7 2020-01-15 tracey
4019 ec46ccd7 2020-01-15 tracey bca.f = got_opentemp();
4020 ec46ccd7 2020-01-15 tracey if (bca.f == NULL) {
4021 ec46ccd7 2020-01-15 tracey error = got_error_from_errno("got_opentemp");
4022 ec46ccd7 2020-01-15 tracey goto done;
4023 ec46ccd7 2020-01-15 tracey }
4024 ec46ccd7 2020-01-15 tracey error = got_object_blob_dump_to_file(&filesize, &bca.nlines,
4025 ec46ccd7 2020-01-15 tracey &bca.line_offsets, bca.f, blob);
4026 ec46ccd7 2020-01-15 tracey if (error || bca.nlines == 0)
4027 ec46ccd7 2020-01-15 tracey goto done;
4028 a81f3554 2020-02-03 stsp
4029 ec46ccd7 2020-01-15 tracey /* Don't include \n at EOF in the blame line count. */
4030 ec46ccd7 2020-01-15 tracey if (bca.line_offsets[bca.nlines - 1] == filesize)
4031 ec46ccd7 2020-01-15 tracey bca.nlines--;
4032 ec46ccd7 2020-01-15 tracey
4033 ec46ccd7 2020-01-15 tracey bca.lines = calloc(bca.nlines, sizeof(*bca.lines));
4034 ec46ccd7 2020-01-15 tracey if (bca.lines == NULL) {
4035 ec46ccd7 2020-01-15 tracey error = got_error_from_errno("calloc");
4036 ec46ccd7 2020-01-15 tracey goto done;
4037 ec46ccd7 2020-01-15 tracey }
4038 ec46ccd7 2020-01-15 tracey bca.lineno_cur = 1;
4039 ec46ccd7 2020-01-15 tracey bca.nlines_prec = 0;
4040 ec46ccd7 2020-01-15 tracey i = bca.nlines;
4041 ec46ccd7 2020-01-15 tracey while (i > 0) {
4042 ec46ccd7 2020-01-15 tracey i /= 10;
4043 ec46ccd7 2020-01-15 tracey bca.nlines_prec++;
4044 ec46ccd7 2020-01-15 tracey }
4045 deac617c 2020-02-14 tracey bca.repo = gw_trans->repo;
4046 2e676fc5 2020-01-15 tracey bca.gw_trans = gw_trans;
4047 ec46ccd7 2020-01-15 tracey
4048 deac617c 2020-02-14 tracey error = got_blame(in_repo_path, commit_id, gw_trans->repo, gw_blame_cb,
4049 deac617c 2020-02-14 tracey &bca, NULL, NULL);
4050 ec46ccd7 2020-01-15 tracey done:
4051 2e676fc5 2020-01-15 tracey free(in_repo_path);
4052 2e676fc5 2020-01-15 tracey free(commit_id);
4053 2e676fc5 2020-01-15 tracey free(obj_id);
4054 2e676fc5 2020-01-15 tracey free(path);
4055 2e676fc5 2020-01-15 tracey
4056 1b33afc0 2020-02-14 tracey if (blob) {
4057 1b33afc0 2020-02-14 tracey free(bca.line_offsets);
4058 1b33afc0 2020-02-14 tracey for (i = 0; i < bca.nlines; i++) {
4059 1b33afc0 2020-02-14 tracey struct blame_line *bline = &bca.lines[i];
4060 1b33afc0 2020-02-14 tracey free(bline->id_str);
4061 1b33afc0 2020-02-14 tracey free(bline->committer);
4062 1b33afc0 2020-02-14 tracey }
4063 1b33afc0 2020-02-14 tracey free(bca.lines);
4064 1b33afc0 2020-02-14 tracey if (bca.f && fclose(bca.f) == EOF && error == NULL)
4065 1b33afc0 2020-02-14 tracey error = got_error_from_errno("fclose");
4066 2e676fc5 2020-01-15 tracey }
4067 4fd4726a 2020-02-03 stsp if (blob)
4068 4fd4726a 2020-02-03 stsp got_object_blob_close(blob);
4069 4fd4726a 2020-02-03 stsp return error;
4070 4fd4726a 2020-02-03 stsp }
4071 4fd4726a 2020-02-03 stsp
4072 4fd4726a 2020-02-03 stsp static const struct got_error *
4073 84de9106 2020-12-26 stsp gw_output_blob_buf(struct gw_trans *gw_trans, struct gw_header *header)
4074 4fd4726a 2020-02-03 stsp {
4075 4fd4726a 2020-02-03 stsp const struct got_error *error = NULL;
4076 4fd4726a 2020-02-03 stsp struct got_object_id *obj_id = NULL;
4077 4fd4726a 2020-02-03 stsp struct got_object_id *commit_id = NULL;
4078 4fd4726a 2020-02-03 stsp struct got_blob_object *blob = NULL;
4079 4fd4726a 2020-02-03 stsp char *path = NULL, *in_repo_path = NULL;
4080 e0857cfe 2020-02-06 tracey int obj_type, set_mime = 0;
4081 e0857cfe 2020-02-06 tracey size_t len, hdrlen;
4082 e0857cfe 2020-02-06 tracey const uint8_t *buf;
4083 e0857cfe 2020-02-06 tracey enum kcgi_err kerr = KCGI_OK;
4084 4fd4726a 2020-02-03 stsp
4085 4fd4726a 2020-02-03 stsp if (asprintf(&path, "%s%s%s",
4086 4fd4726a 2020-02-03 stsp gw_trans->repo_folder ? gw_trans->repo_folder : "",
4087 4fd4726a 2020-02-03 stsp gw_trans->repo_folder ? "/" : "",
4088 4fd4726a 2020-02-03 stsp gw_trans->repo_file) == -1) {
4089 4fd4726a 2020-02-03 stsp error = got_error_from_errno("asprintf");
4090 4fd4726a 2020-02-03 stsp goto done;
4091 4fd4726a 2020-02-03 stsp }
4092 4fd4726a 2020-02-03 stsp
4093 8b4e047e 2020-11-15 stsp error = got_repo_map_path(&in_repo_path, gw_trans->repo, path);
4094 4fd4726a 2020-02-03 stsp if (error)
4095 4fd4726a 2020-02-03 stsp goto done;
4096 4fd4726a 2020-02-03 stsp
4097 56997cd3 2020-02-14 tracey error = got_repo_match_object_id(&commit_id, NULL, gw_trans->commit_id,
4098 84de9106 2020-12-26 stsp GOT_OBJ_TYPE_COMMIT, &header->refs, gw_trans->repo);
4099 4fd4726a 2020-02-03 stsp if (error)
4100 4fd4726a 2020-02-03 stsp goto done;
4101 4fd4726a 2020-02-03 stsp
4102 deac617c 2020-02-14 tracey error = got_object_id_by_path(&obj_id, gw_trans->repo, commit_id,
4103 deac617c 2020-02-14 tracey in_repo_path);
4104 4fd4726a 2020-02-03 stsp if (error)
4105 4fd4726a 2020-02-03 stsp goto done;
4106 4fd4726a 2020-02-03 stsp
4107 4fd4726a 2020-02-03 stsp if (obj_id == NULL) {
4108 4fd4726a 2020-02-03 stsp error = got_error(GOT_ERR_NO_OBJ);
4109 4fd4726a 2020-02-03 stsp goto done;
4110 4fd4726a 2020-02-03 stsp }
4111 4fd4726a 2020-02-03 stsp
4112 deac617c 2020-02-14 tracey error = got_object_get_type(&obj_type, gw_trans->repo, obj_id);
4113 4fd4726a 2020-02-03 stsp if (error)
4114 4fd4726a 2020-02-03 stsp goto done;
4115 4fd4726a 2020-02-03 stsp
4116 4fd4726a 2020-02-03 stsp if (obj_type != GOT_OBJ_TYPE_BLOB) {
4117 4fd4726a 2020-02-03 stsp error = got_error(GOT_ERR_OBJ_TYPE);
4118 4fd4726a 2020-02-03 stsp goto done;
4119 4fd4726a 2020-02-03 stsp }
4120 4fd4726a 2020-02-03 stsp
4121 deac617c 2020-02-14 tracey error = got_object_open_as_blob(&blob, gw_trans->repo, obj_id, 8192);
4122 4fd4726a 2020-02-03 stsp if (error)
4123 4fd4726a 2020-02-03 stsp goto done;
4124 4fd4726a 2020-02-03 stsp
4125 e0857cfe 2020-02-06 tracey hdrlen = got_object_blob_get_hdrlen(blob);
4126 e0857cfe 2020-02-06 tracey do {
4127 e0857cfe 2020-02-06 tracey error = got_object_blob_read_block(&len, blob);
4128 e0857cfe 2020-02-06 tracey if (error)
4129 e0857cfe 2020-02-06 tracey goto done;
4130 e0857cfe 2020-02-06 tracey buf = got_object_blob_get_read_buf(blob);
4131 4fd4726a 2020-02-03 stsp
4132 e0857cfe 2020-02-06 tracey /*
4133 e0857cfe 2020-02-06 tracey * Skip blob object header first time around,
4134 e0857cfe 2020-02-06 tracey * which also contains a zero byte.
4135 e0857cfe 2020-02-06 tracey */
4136 e0857cfe 2020-02-06 tracey buf += hdrlen;
4137 e0857cfe 2020-02-06 tracey if (set_mime == 0) {
4138 e0857cfe 2020-02-06 tracey if (isbinary(buf, len - hdrlen))
4139 e0857cfe 2020-02-06 tracey gw_trans->mime = KMIME_APP_OCTET_STREAM;
4140 e0857cfe 2020-02-06 tracey else
4141 e0857cfe 2020-02-06 tracey gw_trans->mime = KMIME_TEXT_PLAIN;
4142 e0857cfe 2020-02-06 tracey set_mime = 1;
4143 e0857cfe 2020-02-06 tracey error = gw_display_index(gw_trans);
4144 e0857cfe 2020-02-06 tracey if (error)
4145 e0857cfe 2020-02-06 tracey goto done;
4146 e0857cfe 2020-02-06 tracey }
4147 3b7fdcf4 2020-02-14 tracey kerr = khttp_write(gw_trans->gw_req, buf, len - hdrlen);
4148 c56af3fd 2020-02-17 stsp if (kerr != KCGI_OK)
4149 c56af3fd 2020-02-17 stsp goto done;
4150 e0857cfe 2020-02-06 tracey hdrlen = 0;
4151 e0857cfe 2020-02-06 tracey } while (len != 0);
4152 4fd4726a 2020-02-03 stsp done:
4153 4fd4726a 2020-02-03 stsp free(in_repo_path);
4154 4fd4726a 2020-02-03 stsp free(commit_id);
4155 4fd4726a 2020-02-03 stsp free(obj_id);
4156 4fd4726a 2020-02-03 stsp free(path);
4157 e46f587c 2020-01-29 tracey if (blob)
4158 a81f3554 2020-02-03 stsp got_object_blob_close(blob);
4159 e0857cfe 2020-02-06 tracey if (error == NULL && kerr != KCGI_OK)
4160 e0857cfe 2020-02-06 tracey error = gw_kcgi_error(kerr);
4161 a81f3554 2020-02-03 stsp return error;
4162 ec46ccd7 2020-01-15 tracey }
4163 ec46ccd7 2020-01-15 tracey
4164 84bf4df2 2020-02-03 stsp static const struct got_error *
4165 84de9106 2020-12-26 stsp gw_output_repo_tree(struct gw_trans *gw_trans, struct gw_header *header)
4166 ec46ccd7 2020-01-15 tracey {
4167 ec46ccd7 2020-01-15 tracey const struct got_error *error = NULL;
4168 bcbc97d8 2020-01-15 tracey struct got_object_id *tree_id = NULL, *commit_id = NULL;
4169 bcbc97d8 2020-01-15 tracey struct got_tree_object *tree = NULL;
4170 626b25b6 2020-02-06 tracey char *path = NULL, *in_repo_path = NULL;
4171 84bf4df2 2020-02-03 stsp char *id_str = NULL;
4172 84bf4df2 2020-02-03 stsp char *build_folder = NULL;
4173 626b25b6 2020-02-06 tracey char *href_blob = NULL, *href_blame = NULL;
4174 84bf4df2 2020-02-03 stsp const char *class = NULL;
4175 c3bcdfd5 2020-01-29 tracey int nentries, i, class_flip = 0;
4176 626b25b6 2020-02-06 tracey enum kcgi_err kerr = KCGI_OK;
4177 8d4d2453 2020-01-15 tracey
4178 a942aa37 2020-02-10 tracey if (gw_trans->repo_folder != NULL) {
4179 d1635ae4 2020-02-13 tracey path = strdup(gw_trans->repo_folder);
4180 d1635ae4 2020-02-13 tracey if (path == NULL) {
4181 d1635ae4 2020-02-13 tracey error = got_error_from_errno("strdup");
4182 a942aa37 2020-02-10 tracey goto done;
4183 d1635ae4 2020-02-13 tracey }
4184 a942aa37 2020-02-10 tracey } else {
4185 deac617c 2020-02-14 tracey error = got_repo_map_path(&in_repo_path, gw_trans->repo,
4186 8b4e047e 2020-11-15 stsp gw_trans->repo_path);
4187 84bf4df2 2020-02-03 stsp if (error)
4188 84bf4df2 2020-02-03 stsp goto done;
4189 bcbc97d8 2020-01-15 tracey free(path);
4190 bcbc97d8 2020-01-15 tracey path = in_repo_path;
4191 bcbc97d8 2020-01-15 tracey }
4192 bcbc97d8 2020-01-15 tracey
4193 56997cd3 2020-02-14 tracey if (gw_trans->commit_id == NULL) {
4194 ec46ccd7 2020-01-15 tracey struct got_reference *head_ref;
4195 deac617c 2020-02-14 tracey error = got_ref_open(&head_ref, gw_trans->repo,
4196 deac617c 2020-02-14 tracey gw_trans->headref, 0);
4197 ec46ccd7 2020-01-15 tracey if (error)
4198 ec46ccd7 2020-01-15 tracey goto done;
4199 deac617c 2020-02-14 tracey error = got_ref_resolve(&commit_id, gw_trans->repo, head_ref);
4200 84bf4df2 2020-02-03 stsp if (error)
4201 84bf4df2 2020-02-03 stsp goto done;
4202 ec46ccd7 2020-01-15 tracey got_ref_close(head_ref);
4203 56997cd3 2020-02-14 tracey /*
4204 56997cd3 2020-02-14 tracey * gw_trans->commit_id was not parsed from the querystring
4205 56997cd3 2020-02-14 tracey * we hit this code path from gw_index, where we don't know the
4206 56997cd3 2020-02-14 tracey * commit values for the tree link yet, so set
4207 56997cd3 2020-02-14 tracey * gw_trans->commit_id here to continue further into the tree
4208 56997cd3 2020-02-14 tracey */
4209 56997cd3 2020-02-14 tracey error = got_object_id_str(&gw_trans->commit_id, commit_id);
4210 56997cd3 2020-02-14 tracey if (error)
4211 56997cd3 2020-02-14 tracey goto done;
4212 ec46ccd7 2020-01-15 tracey
4213 84bf4df2 2020-02-03 stsp } else {
4214 f2f46662 2020-01-23 tracey error = got_repo_match_object_id(&commit_id, NULL,
4215 84de9106 2020-12-26 stsp gw_trans->commit_id, GOT_OBJ_TYPE_COMMIT, &header->refs,
4216 56997cd3 2020-02-14 tracey gw_trans->repo);
4217 84bf4df2 2020-02-03 stsp if (error)
4218 84bf4df2 2020-02-03 stsp goto done;
4219 84bf4df2 2020-02-03 stsp }
4220 f2f46662 2020-01-23 tracey
4221 56997cd3 2020-02-14 tracey error = got_object_id_by_path(&tree_id, gw_trans->repo, commit_id,
4222 56997cd3 2020-02-14 tracey path);
4223 bcbc97d8 2020-01-15 tracey if (error)
4224 bcbc97d8 2020-01-15 tracey goto done;
4225 bcbc97d8 2020-01-15 tracey
4226 deac617c 2020-02-14 tracey error = got_object_open_as_tree(&tree, gw_trans->repo, tree_id);
4227 bcbc97d8 2020-01-15 tracey if (error)
4228 bcbc97d8 2020-01-15 tracey goto done;
4229 bcbc97d8 2020-01-15 tracey
4230 bcbc97d8 2020-01-15 tracey nentries = got_object_tree_get_nentries(tree);
4231 bcbc97d8 2020-01-15 tracey for (i = 0; i < nentries; i++) {
4232 bcbc97d8 2020-01-15 tracey struct got_tree_entry *te;
4233 ec46ccd7 2020-01-15 tracey const char *modestr = "";
4234 84bf4df2 2020-02-03 stsp mode_t mode;
4235 bcbc97d8 2020-01-15 tracey
4236 bcbc97d8 2020-01-15 tracey te = got_object_tree_get_entry(tree, i);
4237 bcbc97d8 2020-01-15 tracey
4238 bcbc97d8 2020-01-15 tracey error = got_object_id_str(&id_str, got_tree_entry_get_id(te));
4239 bcbc97d8 2020-01-15 tracey if (error)
4240 bcbc97d8 2020-01-15 tracey goto done;
4241 bcbc97d8 2020-01-15 tracey
4242 84bf4df2 2020-02-03 stsp mode = got_tree_entry_get_mode(te);
4243 bcbc97d8 2020-01-15 tracey if (got_object_tree_entry_is_submodule(te))
4244 bcbc97d8 2020-01-15 tracey modestr = "$";
4245 bcbc97d8 2020-01-15 tracey else if (S_ISLNK(mode))
4246 bcbc97d8 2020-01-15 tracey modestr = "@";
4247 bcbc97d8 2020-01-15 tracey else if (S_ISDIR(mode))
4248 bcbc97d8 2020-01-15 tracey modestr = "/";
4249 bcbc97d8 2020-01-15 tracey else if (mode & S_IXUSR)
4250 bcbc97d8 2020-01-15 tracey modestr = "*";
4251 c3bcdfd5 2020-01-29 tracey
4252 c3bcdfd5 2020-01-29 tracey if (class_flip == 0) {
4253 84bf4df2 2020-02-03 stsp class = "back_lightgray";
4254 c3bcdfd5 2020-01-29 tracey class_flip = 1;
4255 c3bcdfd5 2020-01-29 tracey } else {
4256 84bf4df2 2020-02-03 stsp class = "back_white";
4257 c3bcdfd5 2020-01-29 tracey class_flip = 0;
4258 c3bcdfd5 2020-01-29 tracey }
4259 bcbc97d8 2020-01-15 tracey
4260 84bf4df2 2020-02-03 stsp if (S_ISDIR(mode)) {
4261 a5594e37 2020-02-05 tracey if (asprintf(&build_folder, "%s/%s",
4262 84bf4df2 2020-02-03 stsp gw_trans->repo_folder ? gw_trans->repo_folder : "",
4263 84bf4df2 2020-02-03 stsp got_tree_entry_get_name(te)) == -1) {
4264 53e81e48 2020-02-13 tracey error = got_error_from_errno("asprintf");
4265 84bf4df2 2020-02-03 stsp goto done;
4266 ec46ccd7 2020-01-15 tracey }
4267 626b25b6 2020-02-06 tracey
4268 c6eb96ac 2020-04-14 tracey href_blob = khttp_urlpart(NULL, NULL, "gotweb", "path",
4269 c6eb96ac 2020-04-14 tracey gw_trans->repo_name, "action",
4270 c6eb96ac 2020-04-14 tracey gw_get_action_name(gw_trans), "commit",
4271 c6eb96ac 2020-04-14 tracey gw_trans->commit_id, "folder", build_folder, NULL);
4272 19ff7638 2020-04-14 tracey if (href_blob == NULL) {
4273 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
4274 19ff7638 2020-04-14 tracey goto done;
4275 19ff7638 2020-04-14 tracey }
4276 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4277 626b25b6 2020-02-06 tracey KATTR_ID, "tree_wrapper", KATTR__MAX);
4278 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4279 626b25b6 2020-02-06 tracey goto done;
4280 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4281 626b25b6 2020-02-06 tracey KATTR_ID, "tree_line", KATTR_CLASS, class,
4282 626b25b6 2020-02-06 tracey KATTR__MAX);
4283 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4284 626b25b6 2020-02-06 tracey goto done;
4285 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
4286 626b25b6 2020-02-06 tracey KATTR_HREF, href_blob, KATTR_CLASS,
4287 626b25b6 2020-02-06 tracey "diff_directory", KATTR__MAX);
4288 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4289 626b25b6 2020-02-06 tracey goto done;
4290 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(gw_trans->gw_html_req, "%s%s",
4291 32b9f7ed 2020-04-14 tracey got_tree_entry_get_name(te), modestr);
4292 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4293 626b25b6 2020-02-06 tracey goto done;
4294 626b25b6 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
4295 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4296 626b25b6 2020-02-06 tracey goto done;
4297 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4298 626b25b6 2020-02-06 tracey KATTR_ID, "tree_line_blank", KATTR_CLASS, class,
4299 626b25b6 2020-02-06 tracey KATTR__MAX);
4300 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4301 84bf4df2 2020-02-03 stsp goto done;
4302 626b25b6 2020-02-06 tracey kerr = khtml_entity(gw_trans->gw_html_req,
4303 626b25b6 2020-02-06 tracey KENTITY_nbsp);
4304 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4305 626b25b6 2020-02-06 tracey goto done;
4306 626b25b6 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
4307 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4308 626b25b6 2020-02-06 tracey goto done;
4309 ec46ccd7 2020-01-15 tracey } else {
4310 c6eb96ac 2020-04-14 tracey href_blob = khttp_urlpart(NULL, NULL, "gotweb", "path",
4311 c6eb96ac 2020-04-14 tracey gw_trans->repo_name, "action", "blob", "commit",
4312 c6eb96ac 2020-04-14 tracey gw_trans->commit_id, "file",
4313 c6eb96ac 2020-04-14 tracey got_tree_entry_get_name(te), "folder",
4314 c6eb96ac 2020-04-14 tracey gw_trans->repo_folder ? gw_trans->repo_folder : "",
4315 c6eb96ac 2020-04-14 tracey NULL);
4316 19ff7638 2020-04-14 tracey if (href_blob == NULL) {
4317 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
4318 19ff7638 2020-04-14 tracey goto done;
4319 19ff7638 2020-04-14 tracey }
4320 c6eb96ac 2020-04-14 tracey href_blame = khttp_urlpart(NULL, NULL, "gotweb", "path",
4321 c6eb96ac 2020-04-14 tracey gw_trans->repo_name, "action", "blame", "commit",
4322 c6eb96ac 2020-04-14 tracey gw_trans->commit_id, "file",
4323 c6eb96ac 2020-04-14 tracey got_tree_entry_get_name(te), "folder",
4324 c6eb96ac 2020-04-14 tracey gw_trans->repo_folder ? gw_trans->repo_folder : "",
4325 c6eb96ac 2020-04-14 tracey NULL);
4326 19ff7638 2020-04-14 tracey if (href_blame == NULL) {
4327 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
4328 19ff7638 2020-04-14 tracey goto done;
4329 19ff7638 2020-04-14 tracey }
4330 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4331 626b25b6 2020-02-06 tracey KATTR_ID, "tree_wrapper", KATTR__MAX);
4332 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4333 626b25b6 2020-02-06 tracey goto done;
4334 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4335 626b25b6 2020-02-06 tracey KATTR_ID, "tree_line", KATTR_CLASS, class,
4336 626b25b6 2020-02-06 tracey KATTR__MAX);
4337 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4338 626b25b6 2020-02-06 tracey goto done;
4339 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
4340 626b25b6 2020-02-06 tracey KATTR_HREF, href_blob, KATTR__MAX);
4341 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4342 626b25b6 2020-02-06 tracey goto done;
4343 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(gw_trans->gw_html_req, "%s%s",
4344 32b9f7ed 2020-04-14 tracey got_tree_entry_get_name(te), modestr);
4345 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4346 626b25b6 2020-02-06 tracey goto done;
4347 626b25b6 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
4348 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4349 626b25b6 2020-02-06 tracey goto done;
4350 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4351 626b25b6 2020-02-06 tracey KATTR_ID, "tree_line_navs", KATTR_CLASS, class,
4352 626b25b6 2020-02-06 tracey KATTR__MAX);
4353 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4354 626b25b6 2020-02-06 tracey goto done;
4355 ec46ccd7 2020-01-15 tracey
4356 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
4357 626b25b6 2020-02-06 tracey KATTR_HREF, href_blob, KATTR__MAX);
4358 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4359 626b25b6 2020-02-06 tracey goto done;
4360 626b25b6 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, "blob");
4361 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4362 626b25b6 2020-02-06 tracey goto done;
4363 626b25b6 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
4364 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4365 626b25b6 2020-02-06 tracey goto done;
4366 626b25b6 2020-02-06 tracey
4367 626b25b6 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
4368 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4369 626b25b6 2020-02-06 tracey goto done;
4370 626b25b6 2020-02-06 tracey
4371 626b25b6 2020-02-06 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A,
4372 626b25b6 2020-02-06 tracey KATTR_HREF, href_blame, KATTR__MAX);
4373 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4374 626b25b6 2020-02-06 tracey goto done;
4375 626b25b6 2020-02-06 tracey kerr = khtml_puts(gw_trans->gw_html_req, "blame");
4376 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4377 626b25b6 2020-02-06 tracey goto done;
4378 626b25b6 2020-02-06 tracey
4379 626b25b6 2020-02-06 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
4380 626b25b6 2020-02-06 tracey if (kerr != KCGI_OK)
4381 626b25b6 2020-02-06 tracey goto done;
4382 626b25b6 2020-02-06 tracey }
4383 bcbc97d8 2020-01-15 tracey free(id_str);
4384 84bf4df2 2020-02-03 stsp id_str = NULL;
4385 626b25b6 2020-02-06 tracey free(href_blob);
4386 626b25b6 2020-02-06 tracey href_blob = NULL;
4387 84bf4df2 2020-02-03 stsp free(build_folder);
4388 84bf4df2 2020-02-03 stsp build_folder = NULL;
4389 bcbc97d8 2020-01-15 tracey }
4390 bcbc97d8 2020-01-15 tracey done:
4391 bcbc97d8 2020-01-15 tracey if (tree)
4392 bcbc97d8 2020-01-15 tracey got_object_tree_close(tree);
4393 84bf4df2 2020-02-03 stsp free(id_str);
4394 626b25b6 2020-02-06 tracey free(href_blob);
4395 626b25b6 2020-02-06 tracey free(href_blame);
4396 2e676fc5 2020-01-15 tracey free(in_repo_path);
4397 bcbc97d8 2020-01-15 tracey free(tree_id);
4398 84bf4df2 2020-02-03 stsp free(build_folder);
4399 626b25b6 2020-02-06 tracey if (error == NULL && kerr != KCGI_OK)
4400 626b25b6 2020-02-06 tracey error = gw_kcgi_error(kerr);
4401 84bf4df2 2020-02-03 stsp return error;
4402 bcbc97d8 2020-01-15 tracey }
4403 bcbc97d8 2020-01-15 tracey
4404 51d4a92d 2020-02-03 tracey static const struct got_error *
4405 9eed6f10 2020-02-08 tracey gw_output_repo_heads(struct gw_trans *gw_trans)
4406 8d4d2453 2020-01-15 tracey {
4407 87f9ebf5 2020-01-15 tracey const struct got_error *error = NULL;
4408 87f9ebf5 2020-01-15 tracey struct got_reflist_head refs;
4409 87f9ebf5 2020-01-15 tracey struct got_reflist_entry *re;
4410 9eed6f10 2020-02-08 tracey char *age = NULL, *href_summary = NULL, *href_briefs = NULL;
4411 9eed6f10 2020-02-08 tracey char *href_commits = NULL;
4412 9eed6f10 2020-02-08 tracey enum kcgi_err kerr = KCGI_OK;
4413 51d4a92d 2020-02-03 tracey
4414 d9dff0e5 2020-12-26 stsp TAILQ_INIT(&refs);
4415 87f9ebf5 2020-01-15 tracey
4416 deac617c 2020-02-14 tracey error = got_ref_list(&refs, gw_trans->repo, "refs/heads",
4417 deac617c 2020-02-14 tracey got_ref_cmp_by_name, NULL);
4418 87f9ebf5 2020-01-15 tracey if (error)
4419 87f9ebf5 2020-01-15 tracey goto done;
4420 87f9ebf5 2020-01-15 tracey
4421 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4422 9eed6f10 2020-02-08 tracey KATTR_ID, "summary_heads_title_wrapper", KATTR__MAX);
4423 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4424 9eed6f10 2020-02-08 tracey goto done;
4425 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4426 9eed6f10 2020-02-08 tracey KATTR_ID, "summary_heads_title", KATTR__MAX);
4427 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4428 9eed6f10 2020-02-08 tracey goto done;
4429 9eed6f10 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, "Heads");
4430 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4431 9eed6f10 2020-02-08 tracey goto done;
4432 9eed6f10 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
4433 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4434 9eed6f10 2020-02-08 tracey goto done;
4435 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4436 9eed6f10 2020-02-08 tracey KATTR_ID, "summary_heads_content", KATTR__MAX);
4437 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4438 9eed6f10 2020-02-08 tracey goto done;
4439 9eed6f10 2020-02-08 tracey
4440 d9dff0e5 2020-12-26 stsp TAILQ_FOREACH(re, &refs, entry) {
4441 7eb2c8df 2020-02-14 stsp const char *refname;
4442 87f9ebf5 2020-01-15 tracey
4443 eb4f3ad3 2020-02-14 stsp if (got_ref_is_symbolic(re->ref))
4444 eb4f3ad3 2020-02-14 stsp continue;
4445 eb4f3ad3 2020-02-14 stsp
4446 7eb2c8df 2020-02-14 stsp refname = got_ref_get_name(re->ref);
4447 7eb2c8df 2020-02-14 stsp if (strncmp(refname, "refs/heads/", 11) != 0)
4448 87f9ebf5 2020-01-15 tracey continue;
4449 87f9ebf5 2020-01-15 tracey
4450 017d6da3 2020-01-29 tracey error = gw_get_repo_age(&age, gw_trans, gw_trans->gw_dir->path,
4451 017d6da3 2020-01-29 tracey refname, TM_DIFF);
4452 d126c1b7 2020-01-29 stsp if (error)
4453 d126c1b7 2020-01-29 stsp goto done;
4454 87f9ebf5 2020-01-15 tracey
4455 9eed6f10 2020-02-08 tracey if (strncmp(refname, "refs/heads/", 11) == 0)
4456 9eed6f10 2020-02-08 tracey refname += 11;
4457 9eed6f10 2020-02-08 tracey
4458 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4459 9eed6f10 2020-02-08 tracey KATTR_ID, "heads_wrapper", KATTR__MAX);
4460 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4461 9eed6f10 2020-02-08 tracey goto done;
4462 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4463 9eed6f10 2020-02-08 tracey KATTR_ID, "heads_age", KATTR__MAX);
4464 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4465 9eed6f10 2020-02-08 tracey goto done;
4466 9eed6f10 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, age ? age : "");
4467 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4468 9eed6f10 2020-02-08 tracey goto done;
4469 9eed6f10 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
4470 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4471 9eed6f10 2020-02-08 tracey goto done;
4472 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4473 9eed6f10 2020-02-08 tracey KATTR_ID, "heads_space", KATTR__MAX);
4474 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4475 9eed6f10 2020-02-08 tracey goto done;
4476 9eed6f10 2020-02-08 tracey kerr = khtml_entity(gw_trans->gw_html_req, KENTITY_nbsp);
4477 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4478 9eed6f10 2020-02-08 tracey goto done;
4479 9eed6f10 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
4480 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4481 9eed6f10 2020-02-08 tracey goto done;
4482 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV,
4483 9eed6f10 2020-02-08 tracey KATTR_ID, "head", KATTR__MAX);
4484 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4485 9eed6f10 2020-02-08 tracey goto done;
4486 e6789209 2020-04-14 tracey
4487 e6789209 2020-04-14 tracey href_summary = khttp_urlpart(NULL, NULL, "gotweb", "path",
4488 e6789209 2020-04-14 tracey gw_trans->repo_name, "action", "summary", "headref",
4489 19ff7638 2020-04-14 tracey refname, NULL);
4490 19ff7638 2020-04-14 tracey if (href_summary == NULL) {
4491 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
4492 19ff7638 2020-04-14 tracey goto done;
4493 19ff7638 2020-04-14 tracey }
4494 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
4495 9eed6f10 2020-02-08 tracey href_summary, KATTR__MAX);
4496 9eed6f10 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, refname);
4497 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4498 9eed6f10 2020-02-08 tracey goto done;
4499 9eed6f10 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
4500 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4501 9eed6f10 2020-02-08 tracey goto done;
4502 87f9ebf5 2020-01-15 tracey
4503 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
4504 9eed6f10 2020-02-08 tracey "navs_wrapper", KATTR__MAX);
4505 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4506 9eed6f10 2020-02-08 tracey goto done;
4507 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
4508 9eed6f10 2020-02-08 tracey "navs", KATTR__MAX);
4509 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4510 9eed6f10 2020-02-08 tracey goto done;
4511 87f9ebf5 2020-01-15 tracey
4512 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
4513 9eed6f10 2020-02-08 tracey href_summary, KATTR__MAX);
4514 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4515 9eed6f10 2020-02-08 tracey goto done;
4516 9eed6f10 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, "summary");
4517 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4518 9eed6f10 2020-02-08 tracey goto done;
4519 9eed6f10 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
4520 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4521 9eed6f10 2020-02-08 tracey goto done;
4522 9eed6f10 2020-02-08 tracey
4523 9eed6f10 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
4524 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4525 87f9ebf5 2020-01-15 tracey goto done;
4526 e6789209 2020-04-14 tracey
4527 e6789209 2020-04-14 tracey href_briefs = khttp_urlpart(NULL, NULL, "gotweb", "path",
4528 e6789209 2020-04-14 tracey gw_trans->repo_name, "action", "briefs", "headref",
4529 e6789209 2020-04-14 tracey refname, NULL);
4530 19ff7638 2020-04-14 tracey if (href_briefs == NULL) {
4531 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
4532 19ff7638 2020-04-14 tracey goto done;
4533 19ff7638 2020-04-14 tracey }
4534 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
4535 9eed6f10 2020-02-08 tracey href_briefs, KATTR__MAX);
4536 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4537 9eed6f10 2020-02-08 tracey goto done;
4538 9eed6f10 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, "commit briefs");
4539 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4540 9eed6f10 2020-02-08 tracey goto done;
4541 9eed6f10 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
4542 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4543 9eed6f10 2020-02-08 tracey goto done;
4544 87f9ebf5 2020-01-15 tracey
4545 9eed6f10 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, " | ");
4546 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4547 9eed6f10 2020-02-08 tracey goto done;
4548 87f9ebf5 2020-01-15 tracey
4549 e6789209 2020-04-14 tracey href_commits = khttp_urlpart(NULL, NULL, "gotweb", "path",
4550 e6789209 2020-04-14 tracey gw_trans->repo_name, "action", "commits", "headref",
4551 19ff7638 2020-04-14 tracey refname, NULL);
4552 19ff7638 2020-04-14 tracey if (href_commits == NULL) {
4553 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
4554 19ff7638 2020-04-14 tracey goto done;
4555 19ff7638 2020-04-14 tracey }
4556 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
4557 9eed6f10 2020-02-08 tracey href_commits, KATTR__MAX);
4558 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4559 9eed6f10 2020-02-08 tracey goto done;
4560 9eed6f10 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, "commits");
4561 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4562 9eed6f10 2020-02-08 tracey goto done;
4563 9eed6f10 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 3);
4564 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4565 9eed6f10 2020-02-08 tracey goto done;
4566 87f9ebf5 2020-01-15 tracey
4567 9eed6f10 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
4568 9eed6f10 2020-02-08 tracey "dotted_line", KATTR__MAX);
4569 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4570 9eed6f10 2020-02-08 tracey goto done;
4571 9eed6f10 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 2);
4572 9eed6f10 2020-02-08 tracey if (kerr != KCGI_OK)
4573 9eed6f10 2020-02-08 tracey goto done;
4574 9eed6f10 2020-02-08 tracey free(href_summary);
4575 9eed6f10 2020-02-08 tracey href_summary = NULL;
4576 9eed6f10 2020-02-08 tracey free(href_briefs);
4577 9eed6f10 2020-02-08 tracey href_briefs = NULL;
4578 9eed6f10 2020-02-08 tracey free(href_commits);
4579 9eed6f10 2020-02-08 tracey href_commits = NULL;
4580 6c6c85af 2020-01-15 tracey }
4581 87f9ebf5 2020-01-15 tracey done:
4582 87f9ebf5 2020-01-15 tracey got_ref_list_free(&refs);
4583 9eed6f10 2020-02-08 tracey free(href_summary);
4584 9eed6f10 2020-02-08 tracey free(href_briefs);
4585 9eed6f10 2020-02-08 tracey free(href_commits);
4586 51d4a92d 2020-02-03 tracey return error;
4587 8d4d2453 2020-01-15 tracey }
4588 8d4d2453 2020-01-15 tracey
4589 4ae179a2 2020-02-08 tracey static const struct got_error *
4590 4ae179a2 2020-02-08 tracey gw_output_site_link(struct gw_trans *gw_trans)
4591 2c251c14 2020-01-15 tracey {
4592 4ae179a2 2020-02-08 tracey const struct got_error *error = NULL;
4593 4ae179a2 2020-02-08 tracey char *href_summary = NULL;
4594 4ae179a2 2020-02-08 tracey enum kcgi_err kerr = KCGI_OK;
4595 2c251c14 2020-01-15 tracey
4596 4ae179a2 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
4597 4ae179a2 2020-02-08 tracey "site_link", KATTR__MAX);
4598 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4599 4ae179a2 2020-02-08 tracey goto done;
4600 4ae179a2 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF, GOTWEB,
4601 4ae179a2 2020-02-08 tracey KATTR__MAX);
4602 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4603 4ae179a2 2020-02-08 tracey goto done;
4604 4ae179a2 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req,
4605 62d463ca 2020-10-20 naddy gw_trans->gw_conf->got_site_link);
4606 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4607 4ae179a2 2020-02-08 tracey goto done;
4608 4ae179a2 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
4609 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4610 4ae179a2 2020-02-08 tracey goto done;
4611 2c251c14 2020-01-15 tracey
4612 4ae179a2 2020-02-08 tracey if (gw_trans->repo_name != NULL) {
4613 4ae179a2 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, " / ");
4614 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4615 4ae179a2 2020-02-08 tracey goto done;
4616 6918c609 2020-04-14 tracey
4617 6918c609 2020-04-14 tracey href_summary = khttp_urlpart(NULL, NULL, "gotweb", "path",
4618 19ff7638 2020-04-14 tracey gw_trans->repo_name, "action", "summary", NULL);
4619 19ff7638 2020-04-14 tracey if (href_summary == NULL) {
4620 19ff7638 2020-04-14 tracey error = got_error_from_errno("khttp_urlpart");
4621 19ff7638 2020-04-14 tracey goto done;
4622 19ff7638 2020-04-14 tracey }
4623 4ae179a2 2020-02-08 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_A, KATTR_HREF,
4624 4ae179a2 2020-02-08 tracey href_summary, KATTR__MAX);
4625 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4626 4ae179a2 2020-02-08 tracey goto done;
4627 4ae179a2 2020-02-08 tracey kerr = khtml_puts(gw_trans->gw_html_req, gw_trans->repo_name);
4628 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4629 4ae179a2 2020-02-08 tracey goto done;
4630 4ae179a2 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
4631 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4632 4ae179a2 2020-02-08 tracey goto done;
4633 32b9f7ed 2020-04-14 tracey kerr = khtml_printf(gw_trans->gw_html_req, " / %s",
4634 5d1296de 2020-02-13 stsp gw_get_action_name(gw_trans));
4635 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4636 4ae179a2 2020-02-08 tracey goto done;
4637 eb89db64 2020-02-03 stsp }
4638 2c251c14 2020-01-15 tracey
4639 4ae179a2 2020-02-08 tracey kerr = khtml_closeelem(gw_trans->gw_html_req, 1);
4640 4ae179a2 2020-02-08 tracey if (kerr != KCGI_OK)
4641 4ae179a2 2020-02-08 tracey goto done;
4642 4ae179a2 2020-02-08 tracey done:
4643 4ae179a2 2020-02-08 tracey free(href_summary);
4644 6918c609 2020-04-14 tracey if (error == NULL && kerr != KCGI_OK)
4645 6918c609 2020-04-14 tracey error = gw_kcgi_error(kerr);
4646 4ae179a2 2020-02-08 tracey return error;
4647 2c251c14 2020-01-15 tracey }
4648 2c251c14 2020-01-15 tracey
4649 83eb9a68 2020-02-03 stsp static const struct got_error *
4650 f7cc9480 2020-02-05 tracey gw_colordiff_line(struct gw_trans *gw_trans, char *buf)
4651 ec46ccd7 2020-01-15 tracey {
4652 ec46ccd7 2020-01-15 tracey const struct got_error *error = NULL;
4653 f7cc9480 2020-02-05 tracey char *color = NULL;
4654 f7cc9480 2020-02-05 tracey enum kcgi_err kerr = KCGI_OK;
4655 83eb9a68 2020-02-03 stsp
4656 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "-", 1) == 0)
4657 ec46ccd7 2020-01-15 tracey color = "diff_minus";
4658 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "+", 1) == 0)
4659 ec46ccd7 2020-01-15 tracey color = "diff_plus";
4660 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "@@", 2) == 0)
4661 ec46ccd7 2020-01-15 tracey color = "diff_chunk_header";
4662 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "@@", 2) == 0)
4663 ec46ccd7 2020-01-15 tracey color = "diff_chunk_header";
4664 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "commit +", 8) == 0)
4665 ec46ccd7 2020-01-15 tracey color = "diff_meta";
4666 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "commit -", 8) == 0)
4667 ec46ccd7 2020-01-15 tracey color = "diff_meta";
4668 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "blob +", 6) == 0)
4669 ec46ccd7 2020-01-15 tracey color = "diff_meta";
4670 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "blob -", 6) == 0)
4671 ec46ccd7 2020-01-15 tracey color = "diff_meta";
4672 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "file +", 6) == 0)
4673 ec46ccd7 2020-01-15 tracey color = "diff_meta";
4674 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "file -", 6) == 0)
4675 ec46ccd7 2020-01-15 tracey color = "diff_meta";
4676 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "from:", 5) == 0)
4677 ec46ccd7 2020-01-15 tracey color = "diff_author";
4678 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "via:", 4) == 0)
4679 ec46ccd7 2020-01-15 tracey color = "diff_author";
4680 83eb9a68 2020-02-03 stsp else if (strncmp(buf, "date:", 5) == 0)
4681 ec46ccd7 2020-01-15 tracey color = "diff_date";
4682 f7cc9480 2020-02-05 tracey kerr = khtml_attr(gw_trans->gw_html_req, KELEM_DIV, KATTR_ID,
4683 f7cc9480 2020-02-05 tracey "diff_line", KATTR_CLASS, color ? color : "", KATTR__MAX);
4684 f7cc9480 2020-02-05 tracey if (error == NULL && kerr != KCGI_OK)
4685 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
4686 070fee27 2020-02-03 stsp return error;
4687 2c251c14 2020-01-15 tracey }
4688 2c251c14 2020-01-15 tracey
4689 2c251c14 2020-01-15 tracey int
4690 c08369d7 2020-01-15 tracey main(int argc, char *argv[])
4691 2c251c14 2020-01-15 tracey {
4692 6648f956 2021-04-26 tracey const struct got_error *error = NULL, *error2 = NULL;
4693 54415d85 2020-01-15 tracey struct gw_trans *gw_trans;
4694 2c251c14 2020-01-15 tracey struct gw_dir *dir = NULL, *tdir;
4695 2c251c14 2020-01-15 tracey const char *page = "index";
4696 795c10a4 2020-02-20 tracey enum kcgi_err kerr = KCGI_OK;
4697 2c251c14 2020-01-15 tracey
4698 54415d85 2020-01-15 tracey if ((gw_trans = malloc(sizeof(struct gw_trans))) == NULL)
4699 2c251c14 2020-01-15 tracey errx(1, "malloc");
4700 2c251c14 2020-01-15 tracey
4701 2c251c14 2020-01-15 tracey if ((gw_trans->gw_req = malloc(sizeof(struct kreq))) == NULL)
4702 2c251c14 2020-01-15 tracey errx(1, "malloc");
4703 2c251c14 2020-01-15 tracey
4704 2c251c14 2020-01-15 tracey if ((gw_trans->gw_html_req = malloc(sizeof(struct khtmlreq))) == NULL)
4705 2c251c14 2020-01-15 tracey errx(1, "malloc");
4706 2c251c14 2020-01-15 tracey
4707 2c251c14 2020-01-15 tracey if ((gw_trans->gw_tmpl = malloc(sizeof(struct ktemplate))) == NULL)
4708 2c251c14 2020-01-15 tracey errx(1, "malloc");
4709 2c251c14 2020-01-15 tracey
4710 c25c2314 2020-01-28 stsp kerr = khttp_parse(gw_trans->gw_req, gw_keys, KEY__ZMAX, &page, 1, 0);
4711 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK) {
4712 2447adad 2020-02-06 stsp error = gw_kcgi_error(kerr);
4713 c119608e 2020-01-28 stsp goto done;
4714 46b9c89b 2020-01-15 tracey }
4715 46b9c89b 2020-01-15 tracey
4716 2c251c14 2020-01-15 tracey TAILQ_INIT(&gw_trans->gw_dirs);
4717 f2f46662 2020-01-23 tracey TAILQ_INIT(&gw_trans->gw_headers);
4718 2c251c14 2020-01-15 tracey
4719 f1200fe3 2020-02-13 tracey gw_trans->action = -1;
4720 2c251c14 2020-01-15 tracey gw_trans->page = 0;
4721 2c251c14 2020-01-15 tracey gw_trans->repos_total = 0;
4722 2c251c14 2020-01-15 tracey gw_trans->repo_path = NULL;
4723 56997cd3 2020-02-14 tracey gw_trans->commit_id = NULL;
4724 55e46400 2020-02-18 tracey gw_trans->next_id = NULL;
4725 55e46400 2020-02-18 tracey gw_trans->next_prev_id = NULL;
4726 55e46400 2020-02-18 tracey gw_trans->prev_id = NULL;
4727 55e46400 2020-02-18 tracey gw_trans->prev_prev_id = NULL;
4728 742ba378 2020-02-14 stsp gw_trans->headref = GOT_REF_HEAD;
4729 2c251c14 2020-01-15 tracey gw_trans->mime = KMIME_TEXT_HTML;
4730 54415d85 2020-01-15 tracey gw_trans->gw_tmpl->key = gw_templs;
4731 2c251c14 2020-01-15 tracey gw_trans->gw_tmpl->keysz = TEMPL__MAX;
4732 2c251c14 2020-01-15 tracey gw_trans->gw_tmpl->arg = gw_trans;
4733 2c251c14 2020-01-15 tracey gw_trans->gw_tmpl->cb = gw_template;
4734 c34ec417 2020-06-22 tracey
4735 c34ec417 2020-06-22 tracey error = parse_gotweb_config(&gw_trans->gw_conf, GOTWEB_CONF);
4736 c119608e 2020-01-28 stsp if (error)
4737 2c251c14 2020-01-15 tracey goto done;
4738 2c251c14 2020-01-15 tracey
4739 2c251c14 2020-01-15 tracey error = gw_parse_querystring(gw_trans);
4740 2c251c14 2020-01-15 tracey if (error)
4741 c119608e 2020-01-28 stsp goto done;
4742 2c251c14 2020-01-15 tracey
4743 017d6da3 2020-01-29 tracey if (gw_trans->action == GW_BLOB)
4744 017d6da3 2020-01-29 tracey error = gw_blob(gw_trans);
4745 017d6da3 2020-01-29 tracey else
4746 017d6da3 2020-01-29 tracey error = gw_display_index(gw_trans);
4747 2c251c14 2020-01-15 tracey done:
4748 1d0f4054 2021-06-17 stsp if (gw_trans->repo) {
4749 1d0f4054 2021-06-17 stsp const struct got_error *close_err;
4750 1d0f4054 2021-06-17 stsp close_err = got_repo_close(gw_trans->repo);
4751 1d0f4054 2021-06-17 stsp if (error == NULL)
4752 1d0f4054 2021-06-17 stsp error = close_err;
4753 1d0f4054 2021-06-17 stsp }
4754 6648f956 2021-04-26 tracey if (error) {
4755 6648f956 2021-04-26 tracey gw_trans->error = error;
4756 6648f956 2021-04-26 tracey gw_trans->action = GW_ERR;
4757 6648f956 2021-04-26 tracey error2 = gw_display_open(gw_trans, KHTTP_200, gw_trans->mime);
4758 6648f956 2021-04-26 tracey if (error2)
4759 6648f956 2021-04-26 tracey goto cleanup; /* we can't display an error page */
4760 6648f956 2021-04-26 tracey kerr = khtml_open(gw_trans->gw_html_req, gw_trans->gw_req, 0);
4761 6648f956 2021-04-26 tracey if (kerr != KCGI_OK)
4762 6648f956 2021-04-26 tracey goto cleanup; /* we can't display an error page */
4763 6648f956 2021-04-26 tracey kerr = khttp_template(gw_trans->gw_req, gw_trans->gw_tmpl,
4764 6648f956 2021-04-26 tracey gw_query_funcs[gw_trans->action].template);
4765 6648f956 2021-04-26 tracey if (kerr != KCGI_OK) {
4766 6648f956 2021-04-26 tracey khtml_close(gw_trans->gw_html_req);
4767 6648f956 2021-04-26 tracey goto cleanup; /* we can't display an error page */
4768 6648f956 2021-04-26 tracey }
4769 6648f956 2021-04-26 tracey }
4770 6648f956 2021-04-26 tracey
4771 6648f956 2021-04-26 tracey cleanup:
4772 a5a8a332 2020-11-09 tracey free(gw_trans->gw_conf->got_repos_path);
4773 a5a8a332 2020-11-09 tracey free(gw_trans->gw_conf->got_www_path);
4774 a5a8a332 2020-11-09 tracey free(gw_trans->gw_conf->got_site_name);
4775 a5a8a332 2020-11-09 tracey free(gw_trans->gw_conf->got_site_owner);
4776 a5a8a332 2020-11-09 tracey free(gw_trans->gw_conf->got_site_link);
4777 a5a8a332 2020-11-09 tracey free(gw_trans->gw_conf->got_logo);
4778 a5a8a332 2020-11-09 tracey free(gw_trans->gw_conf->got_logo_url);
4779 a5a8a332 2020-11-09 tracey free(gw_trans->gw_conf);
4780 a5a8a332 2020-11-09 tracey free(gw_trans->commit_id);
4781 a5a8a332 2020-11-09 tracey free(gw_trans->next_id);
4782 a5a8a332 2020-11-09 tracey free(gw_trans->next_prev_id);
4783 a5a8a332 2020-11-09 tracey free(gw_trans->prev_id);
4784 a5a8a332 2020-11-09 tracey free(gw_trans->prev_prev_id);
4785 a5a8a332 2020-11-09 tracey free(gw_trans->repo_path);
4786 a5a8a332 2020-11-09 tracey TAILQ_FOREACH_SAFE(dir, &gw_trans->gw_dirs, entry, tdir) {
4787 a5a8a332 2020-11-09 tracey free(dir->name);
4788 a5a8a332 2020-11-09 tracey free(dir->description);
4789 a5a8a332 2020-11-09 tracey free(dir->age);
4790 a5a8a332 2020-11-09 tracey free(dir->url);
4791 a5a8a332 2020-11-09 tracey free(dir->path);
4792 a5a8a332 2020-11-09 tracey free(dir);
4793 2c251c14 2020-01-15 tracey }
4794 2c251c14 2020-01-15 tracey
4795 2c251c14 2020-01-15 tracey khttp_free(gw_trans->gw_req);
4796 d56b34ca 2020-01-29 stsp return 0;
4797 2c251c14 2020-01-15 tracey }