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