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 2c251c14 2020-01-15 tracey #include <dirent.h>
23 2c251c14 2020-01-15 tracey #include <err.h>
24 c25c2314 2020-01-28 stsp #include <errno.h>
25 474370cb 2020-01-15 tracey #include <regex.h>
26 2c251c14 2020-01-15 tracey #include <stdarg.h>
27 2c251c14 2020-01-15 tracey #include <stdint.h>
28 2c251c14 2020-01-15 tracey #include <stdio.h>
29 2c251c14 2020-01-15 tracey #include <stdlib.h>
30 2c251c14 2020-01-15 tracey #include <string.h>
31 2c251c14 2020-01-15 tracey #include <unistd.h>
32 2c251c14 2020-01-15 tracey
33 2c251c14 2020-01-15 tracey #include <got_object.h>
34 2c251c14 2020-01-15 tracey #include <got_reference.h>
35 2c251c14 2020-01-15 tracey #include <got_repository.h>
36 2c251c14 2020-01-15 tracey #include <got_path.h>
37 2c251c14 2020-01-15 tracey #include <got_cancel.h>
38 2c251c14 2020-01-15 tracey #include <got_worktree.h>
39 2c251c14 2020-01-15 tracey #include <got_diff.h>
40 2c251c14 2020-01-15 tracey #include <got_commit_graph.h>
41 2c251c14 2020-01-15 tracey #include <got_blame.h>
42 2c251c14 2020-01-15 tracey #include <got_privsep.h>
43 2c251c14 2020-01-15 tracey #include <got_opentemp.h>
44 2c251c14 2020-01-15 tracey
45 2c251c14 2020-01-15 tracey #include <kcgi.h>
46 2c251c14 2020-01-15 tracey #include <kcgihtml.h>
47 2c251c14 2020-01-15 tracey
48 474370cb 2020-01-15 tracey #include "buf.h"
49 2c251c14 2020-01-15 tracey #include "gotweb.h"
50 2c251c14 2020-01-15 tracey #include "gotweb_ui.h"
51 2c251c14 2020-01-15 tracey
52 2c251c14 2020-01-15 tracey #ifndef nitems
53 2c251c14 2020-01-15 tracey #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
54 2c251c14 2020-01-15 tracey #endif
55 2c251c14 2020-01-15 tracey
56 54415d85 2020-01-15 tracey struct gw_trans {
57 f2f46662 2020-01-23 tracey TAILQ_HEAD(headers, gw_header) gw_headers;
58 f2f46662 2020-01-23 tracey TAILQ_HEAD(dirs, gw_dir) gw_dirs;
59 46b9c89b 2020-01-15 tracey struct gw_dir *gw_dir;
60 2c251c14 2020-01-15 tracey struct gotweb_conf *gw_conf;
61 2c251c14 2020-01-15 tracey struct ktemplate *gw_tmpl;
62 2c251c14 2020-01-15 tracey struct khtmlreq *gw_html_req;
63 2c251c14 2020-01-15 tracey struct kreq *gw_req;
64 2c251c14 2020-01-15 tracey char *repo_name;
65 2c251c14 2020-01-15 tracey char *repo_path;
66 2c251c14 2020-01-15 tracey char *commit;
67 2c251c14 2020-01-15 tracey char *repo_file;
68 ec46ccd7 2020-01-15 tracey char *repo_folder;
69 2c251c14 2020-01-15 tracey char *action_name;
70 8087c3c5 2020-01-15 tracey char *headref;
71 2c251c14 2020-01-15 tracey unsigned int action;
72 2c251c14 2020-01-15 tracey unsigned int page;
73 2c251c14 2020-01-15 tracey unsigned int repos_total;
74 387a29ba 2020-01-15 tracey enum kmime mime;
75 2c251c14 2020-01-15 tracey };
76 2c251c14 2020-01-15 tracey
77 f2f46662 2020-01-23 tracey struct gw_header {
78 f2f46662 2020-01-23 tracey TAILQ_ENTRY(gw_header) entry;
79 f2f46662 2020-01-23 tracey struct got_repository *repo;
80 f2f46662 2020-01-23 tracey struct got_reflist_head refs;
81 f2f46662 2020-01-23 tracey struct got_commit_object *commit;
82 f2f46662 2020-01-23 tracey struct got_object_id *id;
83 f2f46662 2020-01-23 tracey char *path;
84 f2f46662 2020-01-23 tracey
85 f2f46662 2020-01-23 tracey char *refs_str;
86 f2f46662 2020-01-23 tracey char *commit_id; /* id_str1 */
87 f2f46662 2020-01-23 tracey char *parent_id; /* id_str2 */
88 f2f46662 2020-01-23 tracey char *tree_id;
89 f2f46662 2020-01-23 tracey char *author;
90 f2f46662 2020-01-23 tracey char *committer;
91 f2f46662 2020-01-23 tracey char *commit_msg;
92 f2f46662 2020-01-23 tracey time_t committer_time;
93 2c251c14 2020-01-15 tracey };
94 2c251c14 2020-01-15 tracey
95 2c251c14 2020-01-15 tracey struct gw_dir {
96 2c251c14 2020-01-15 tracey TAILQ_ENTRY(gw_dir) entry;
97 2c251c14 2020-01-15 tracey char *name;
98 2c251c14 2020-01-15 tracey char *owner;
99 2c251c14 2020-01-15 tracey char *description;
100 2c251c14 2020-01-15 tracey char *url;
101 2c251c14 2020-01-15 tracey char *age;
102 2c251c14 2020-01-15 tracey char *path;
103 2c251c14 2020-01-15 tracey };
104 2c251c14 2020-01-15 tracey
105 f2f46662 2020-01-23 tracey enum gw_key {
106 f2f46662 2020-01-23 tracey KEY_ACTION,
107 f2f46662 2020-01-23 tracey KEY_COMMIT_ID,
108 f2f46662 2020-01-23 tracey KEY_FILE,
109 f2f46662 2020-01-23 tracey KEY_FOLDER,
110 f2f46662 2020-01-23 tracey KEY_HEADREF,
111 f2f46662 2020-01-23 tracey KEY_PAGE,
112 f2f46662 2020-01-23 tracey KEY_PATH,
113 f2f46662 2020-01-23 tracey KEY__ZMAX
114 f2f46662 2020-01-23 tracey };
115 f2f46662 2020-01-23 tracey
116 54415d85 2020-01-15 tracey enum gw_tmpl {
117 f2f46662 2020-01-23 tracey TEMPL_CONTENT,
118 2c251c14 2020-01-15 tracey TEMPL_HEAD,
119 2c251c14 2020-01-15 tracey TEMPL_HEADER,
120 f2f46662 2020-01-23 tracey TEMPL_SEARCH,
121 2c251c14 2020-01-15 tracey TEMPL_SITEPATH,
122 2c251c14 2020-01-15 tracey TEMPL_SITEOWNER,
123 2c251c14 2020-01-15 tracey TEMPL_TITLE,
124 2c251c14 2020-01-15 tracey TEMPL__MAX
125 2c251c14 2020-01-15 tracey };
126 2c251c14 2020-01-15 tracey
127 54415d85 2020-01-15 tracey enum gw_ref_tm {
128 387a29ba 2020-01-15 tracey TM_DIFF,
129 387a29ba 2020-01-15 tracey TM_LONG,
130 387a29ba 2020-01-15 tracey };
131 387a29ba 2020-01-15 tracey
132 54415d85 2020-01-15 tracey enum gw_tags {
133 87f9ebf5 2020-01-15 tracey TAGBRIEF,
134 87f9ebf5 2020-01-15 tracey TAGFULL,
135 87f9ebf5 2020-01-15 tracey };
136 87f9ebf5 2020-01-15 tracey
137 54415d85 2020-01-15 tracey static const char *const gw_templs[TEMPL__MAX] = {
138 f2f46662 2020-01-23 tracey "content",
139 2c251c14 2020-01-15 tracey "head",
140 2c251c14 2020-01-15 tracey "header",
141 f2f46662 2020-01-23 tracey "search",
142 2c251c14 2020-01-15 tracey "sitepath",
143 2c251c14 2020-01-15 tracey "siteowner",
144 2c251c14 2020-01-15 tracey "title",
145 2c251c14 2020-01-15 tracey };
146 2c251c14 2020-01-15 tracey
147 ec46ccd7 2020-01-15 tracey static const struct kvalid gw_keys[KEY__ZMAX] = {
148 2c251c14 2020-01-15 tracey { kvalid_stringne, "action" },
149 2c251c14 2020-01-15 tracey { kvalid_stringne, "commit" },
150 2c251c14 2020-01-15 tracey { kvalid_stringne, "file" },
151 ec46ccd7 2020-01-15 tracey { kvalid_stringne, "folder" },
152 8087c3c5 2020-01-15 tracey { kvalid_stringne, "headref" },
153 ec46ccd7 2020-01-15 tracey { kvalid_int, "page" },
154 ec46ccd7 2020-01-15 tracey { kvalid_stringne, "path" },
155 2c251c14 2020-01-15 tracey };
156 2c251c14 2020-01-15 tracey
157 2c251c14 2020-01-15 tracey static struct gw_dir *gw_init_gw_dir(char *);
158 f2f46662 2020-01-23 tracey static struct gw_header *gw_init_header(void);
159 2c251c14 2020-01-15 tracey
160 54415d85 2020-01-15 tracey static char *gw_get_repo_description(struct gw_trans *,
161 2c251c14 2020-01-15 tracey char *);
162 54415d85 2020-01-15 tracey static char *gw_get_repo_owner(struct gw_trans *,
163 2c251c14 2020-01-15 tracey char *);
164 474370cb 2020-01-15 tracey static char *gw_get_time_str(time_t, int);
165 d126c1b7 2020-01-29 stsp static const struct got_error *gw_get_repo_age(char **, struct gw_trans *,
166 387a29ba 2020-01-15 tracey char *, char *, int);
167 e46f587c 2020-01-29 tracey static char *gw_get_file_blame_blob(struct gw_trans *);
168 f2f46662 2020-01-23 tracey static char *gw_get_repo_tree(struct gw_trans *);
169 f2f46662 2020-01-23 tracey static char *gw_get_diff(struct gw_trans *,
170 f2f46662 2020-01-23 tracey struct gw_header *);
171 4ff7391f 2020-01-28 tracey static char *gw_get_repo_tags(struct gw_trans *,
172 4ff7391f 2020-01-28 tracey struct gw_header *, int, int);
173 54415d85 2020-01-15 tracey static char *gw_get_repo_heads(struct gw_trans *);
174 54415d85 2020-01-15 tracey static char *gw_get_clone_url(struct gw_trans *, char *);
175 54415d85 2020-01-15 tracey static char *gw_get_got_link(struct gw_trans *);
176 54415d85 2020-01-15 tracey static char *gw_get_site_link(struct gw_trans *);
177 2c251c14 2020-01-15 tracey static char *gw_html_escape(const char *);
178 d0ea9c5b 2020-01-15 tracey static char *gw_colordiff_line(char *);
179 2c251c14 2020-01-15 tracey
180 f2f46662 2020-01-23 tracey static char *gw_gen_commit_header(char *, char*);
181 f2f46662 2020-01-23 tracey static char *gw_gen_diff_header(char *, char*);
182 f2f46662 2020-01-23 tracey static char *gw_gen_author_header(char *);
183 f2f46662 2020-01-23 tracey static char *gw_gen_committer_header(char *);
184 f2f46662 2020-01-23 tracey static char *gw_gen_age_header(char *);
185 f2f46662 2020-01-23 tracey static char *gw_gen_commit_msg_header(char *);
186 f2f46662 2020-01-23 tracey static char *gw_gen_tree_header(char *);
187 f2f46662 2020-01-23 tracey
188 f2f46662 2020-01-23 tracey static void gw_free_headers(struct gw_header *);
189 c25c2314 2020-01-28 stsp static const struct got_error* gw_display_open(struct gw_trans *, enum khttp,
190 2c251c14 2020-01-15 tracey enum kmime);
191 6d8d8a26 2020-01-29 stsp static const struct got_error* gw_display_index(struct gw_trans *);
192 6d8d8a26 2020-01-29 stsp static void gw_display_error(struct gw_trans *,
193 2c251c14 2020-01-15 tracey const struct got_error *);
194 2c251c14 2020-01-15 tracey
195 2c251c14 2020-01-15 tracey static int gw_template(size_t, void *);
196 2c251c14 2020-01-15 tracey
197 f2f46662 2020-01-23 tracey static const struct got_error* gw_get_header(struct gw_trans *,
198 f2f46662 2020-01-23 tracey struct gw_header *, int);
199 f2f46662 2020-01-23 tracey static const struct got_error* gw_get_commits(struct gw_trans *,
200 f2f46662 2020-01-23 tracey struct gw_header *, int);
201 f2f46662 2020-01-23 tracey static const struct got_error* gw_get_commit(struct gw_trans *,
202 f2f46662 2020-01-23 tracey struct gw_header *);
203 54415d85 2020-01-15 tracey static const struct got_error* gw_apply_unveil(const char *, const char *);
204 147269d5 2020-01-15 tracey static const struct got_error* gw_blame_cb(void *, int, int,
205 ec46ccd7 2020-01-15 tracey struct got_object_id *);
206 54415d85 2020-01-15 tracey static const struct got_error* gw_load_got_paths(struct gw_trans *);
207 54415d85 2020-01-15 tracey static const struct got_error* gw_load_got_path(struct gw_trans *,
208 2c251c14 2020-01-15 tracey struct gw_dir *);
209 54415d85 2020-01-15 tracey static const struct got_error* gw_parse_querystring(struct gw_trans *);
210 2c251c14 2020-01-15 tracey
211 54415d85 2020-01-15 tracey static const struct got_error* gw_blame(struct gw_trans *);
212 e46f587c 2020-01-29 tracey static const struct got_error* gw_blob(struct gw_trans *);
213 f2f46662 2020-01-23 tracey static const struct got_error* gw_diff(struct gw_trans *);
214 54415d85 2020-01-15 tracey static const struct got_error* gw_index(struct gw_trans *);
215 f2f46662 2020-01-23 tracey static const struct got_error* gw_commits(struct gw_trans *);
216 f2f46662 2020-01-23 tracey static const struct got_error* gw_briefs(struct gw_trans *);
217 54415d85 2020-01-15 tracey static const struct got_error* gw_summary(struct gw_trans *);
218 54415d85 2020-01-15 tracey static const struct got_error* gw_tree(struct gw_trans *);
219 4ff7391f 2020-01-28 tracey static const struct got_error* gw_tag(struct gw_trans *);
220 2c251c14 2020-01-15 tracey
221 2c251c14 2020-01-15 tracey struct gw_query_action {
222 2c251c14 2020-01-15 tracey unsigned int func_id;
223 2c251c14 2020-01-15 tracey const char *func_name;
224 54415d85 2020-01-15 tracey const struct got_error *(*func_main)(struct gw_trans *);
225 2c251c14 2020-01-15 tracey char *template;
226 2c251c14 2020-01-15 tracey };
227 2c251c14 2020-01-15 tracey
228 2c251c14 2020-01-15 tracey enum gw_query_actions {
229 2c251c14 2020-01-15 tracey GW_BLAME,
230 e46f587c 2020-01-29 tracey GW_BLOB,
231 f2f46662 2020-01-23 tracey GW_BRIEFS,
232 f2f46662 2020-01-23 tracey GW_COMMITS,
233 f2f46662 2020-01-23 tracey GW_DIFF,
234 2c251c14 2020-01-15 tracey GW_ERR,
235 2c251c14 2020-01-15 tracey GW_INDEX,
236 2c251c14 2020-01-15 tracey GW_SUMMARY,
237 4ff7391f 2020-01-28 tracey GW_TAG,
238 b772de24 2020-01-15 tracey GW_TREE,
239 2c251c14 2020-01-15 tracey };
240 2c251c14 2020-01-15 tracey
241 2c251c14 2020-01-15 tracey static struct gw_query_action gw_query_funcs[] = {
242 f2f46662 2020-01-23 tracey { GW_BLAME, "blame", gw_blame, "gw_tmpl/blame.tmpl" },
243 e46f587c 2020-01-29 tracey { GW_BLOB, "blob", gw_blob, "gw_tmpl/blob.tmpl" },
244 f2f46662 2020-01-23 tracey { GW_BRIEFS, "briefs", gw_briefs, "gw_tmpl/briefs.tmpl" },
245 f2f46662 2020-01-23 tracey { GW_COMMITS, "commits", gw_commits, "gw_tmpl/commit.tmpl" },
246 f2f46662 2020-01-23 tracey { GW_DIFF, "diff", gw_diff, "gw_tmpl/diff.tmpl" },
247 f2f46662 2020-01-23 tracey { GW_ERR, NULL, NULL, "gw_tmpl/err.tmpl" },
248 f2f46662 2020-01-23 tracey { GW_INDEX, "index", gw_index, "gw_tmpl/index.tmpl" },
249 f2f46662 2020-01-23 tracey { GW_SUMMARY, "summary", gw_summary, "gw_tmpl/summry.tmpl" },
250 4ff7391f 2020-01-28 tracey { GW_TAG, "tag", gw_tag, "gw_tmpl/tag.tmpl" },
251 f2f46662 2020-01-23 tracey { GW_TREE, "tree", gw_tree, "gw_tmpl/tree.tmpl" },
252 2c251c14 2020-01-15 tracey };
253 c25c2314 2020-01-28 stsp
254 c25c2314 2020-01-28 stsp static const struct got_error *
255 c25c2314 2020-01-28 stsp gw_kcgi_error(enum kcgi_err kerr)
256 c25c2314 2020-01-28 stsp {
257 c25c2314 2020-01-28 stsp if (kerr == KCGI_OK)
258 c25c2314 2020-01-28 stsp return NULL;
259 c25c2314 2020-01-28 stsp
260 c25c2314 2020-01-28 stsp if (kerr == KCGI_EXIT || kerr == KCGI_HUP)
261 c25c2314 2020-01-28 stsp return got_error(GOT_ERR_CANCELLED);
262 c25c2314 2020-01-28 stsp
263 c25c2314 2020-01-28 stsp if (kerr == KCGI_ENOMEM)
264 c25c2314 2020-01-28 stsp return got_error_set_errno(ENOMEM, kcgi_strerror(kerr));
265 2c251c14 2020-01-15 tracey
266 c25c2314 2020-01-28 stsp if (kerr == KCGI_ENFILE)
267 c25c2314 2020-01-28 stsp return got_error_set_errno(ENFILE, kcgi_strerror(kerr));
268 c25c2314 2020-01-28 stsp
269 c25c2314 2020-01-28 stsp if (kerr == KCGI_EAGAIN)
270 c25c2314 2020-01-28 stsp return got_error_set_errno(EAGAIN, kcgi_strerror(kerr));
271 c25c2314 2020-01-28 stsp
272 c25c2314 2020-01-28 stsp if (kerr == KCGI_FORM)
273 c25c2314 2020-01-28 stsp return got_error_msg(GOT_ERR_IO, kcgi_strerror(kerr));
274 c25c2314 2020-01-28 stsp
275 c25c2314 2020-01-28 stsp return got_error_from_errno(kcgi_strerror(kerr));
276 c25c2314 2020-01-28 stsp }
277 c25c2314 2020-01-28 stsp
278 2c251c14 2020-01-15 tracey static const struct got_error *
279 54415d85 2020-01-15 tracey gw_apply_unveil(const char *repo_path, const char *repo_file)
280 2c251c14 2020-01-15 tracey {
281 2c251c14 2020-01-15 tracey const struct got_error *err;
282 2c251c14 2020-01-15 tracey
283 2c251c14 2020-01-15 tracey if (repo_path && repo_file) {
284 2c251c14 2020-01-15 tracey char *full_path;
285 88d59c36 2020-01-29 stsp if (asprintf(&full_path, "%s/%s", repo_path, repo_file) == -1)
286 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf unveil");
287 2c251c14 2020-01-15 tracey if (unveil(full_path, "r") != 0)
288 2c251c14 2020-01-15 tracey return got_error_from_errno2("unveil", full_path);
289 2c251c14 2020-01-15 tracey }
290 2c251c14 2020-01-15 tracey
291 2c251c14 2020-01-15 tracey if (repo_path && unveil(repo_path, "r") != 0)
292 2c251c14 2020-01-15 tracey return got_error_from_errno2("unveil", repo_path);
293 2c251c14 2020-01-15 tracey
294 2c251c14 2020-01-15 tracey if (unveil("/tmp", "rwc") != 0)
295 2c251c14 2020-01-15 tracey return got_error_from_errno2("unveil", "/tmp");
296 2c251c14 2020-01-15 tracey
297 2c251c14 2020-01-15 tracey err = got_privsep_unveil_exec_helpers();
298 2c251c14 2020-01-15 tracey if (err != NULL)
299 2c251c14 2020-01-15 tracey return err;
300 2c251c14 2020-01-15 tracey
301 2c251c14 2020-01-15 tracey if (unveil(NULL, NULL) != 0)
302 2c251c14 2020-01-15 tracey return got_error_from_errno("unveil");
303 2c251c14 2020-01-15 tracey
304 2c251c14 2020-01-15 tracey return NULL;
305 87f9ebf5 2020-01-15 tracey }
306 65b95fb2 2020-01-15 tracey
307 2c251c14 2020-01-15 tracey static const struct got_error *
308 54415d85 2020-01-15 tracey gw_blame(struct gw_trans *gw_trans)
309 2c251c14 2020-01-15 tracey {
310 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
311 f2f46662 2020-01-23 tracey struct gw_header *header = NULL;
312 f2f46662 2020-01-23 tracey char *blame = NULL, *blame_html = NULL, *blame_html_disp = NULL;
313 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
314 2c251c14 2020-01-15 tracey
315 6bee13de 2020-01-16 tracey if (pledge("stdio rpath wpath cpath proc exec sendfd unveil",
316 f2f46662 2020-01-23 tracey NULL) == -1)
317 f2f46662 2020-01-23 tracey return got_error_from_errno("pledge");
318 6bee13de 2020-01-16 tracey
319 f2f46662 2020-01-23 tracey if ((header = gw_init_header()) == NULL)
320 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
321 f2f46662 2020-01-23 tracey
322 54415d85 2020-01-15 tracey error = gw_apply_unveil(gw_trans->gw_dir->path, NULL);
323 ec46ccd7 2020-01-15 tracey if (error)
324 5ddf0079 2020-01-29 stsp goto done;
325 ec46ccd7 2020-01-15 tracey
326 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header, 1);
327 f2f46662 2020-01-23 tracey if (error)
328 5ddf0079 2020-01-29 stsp goto done;
329 ec46ccd7 2020-01-15 tracey
330 e46f587c 2020-01-29 tracey blame_html = gw_get_file_blame_blob(gw_trans);
331 f2f46662 2020-01-23 tracey
332 6d9fc692 2020-01-28 stsp if (blame_html == NULL) {
333 f2f46662 2020-01-23 tracey blame_html = strdup("");
334 5ddf0079 2020-01-29 stsp if (blame_html == NULL) {
335 5ddf0079 2020-01-29 stsp error = got_error_from_errno("strdup");
336 5ddf0079 2020-01-29 stsp goto done;
337 5ddf0079 2020-01-29 stsp }
338 6d9fc692 2020-01-28 stsp }
339 f2f46662 2020-01-23 tracey
340 88d59c36 2020-01-29 stsp if (asprintf(&blame_html_disp, blame_header,
341 f2f46662 2020-01-23 tracey gw_gen_age_header(gw_get_time_str(header->committer_time, TM_LONG)),
342 f2f46662 2020-01-23 tracey gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)),
343 88d59c36 2020-01-29 stsp blame_html) == -1) {
344 6d9fc692 2020-01-28 stsp error = got_error_from_errno("asprintf");
345 6d9fc692 2020-01-28 stsp goto done;
346 6d9fc692 2020-01-28 stsp }
347 f2f46662 2020-01-23 tracey
348 6d9fc692 2020-01-28 stsp if (asprintf(&blame, blame_wrapper, blame_html_disp) == -1) {
349 6d9fc692 2020-01-28 stsp error = got_error_from_errno("asprintf");
350 6d9fc692 2020-01-28 stsp goto done;
351 6d9fc692 2020-01-28 stsp }
352 f2f46662 2020-01-23 tracey
353 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, blame);
354 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
355 c25c2314 2020-01-28 stsp error = gw_kcgi_error(kerr);
356 6d9fc692 2020-01-28 stsp done:
357 f2f46662 2020-01-23 tracey got_ref_list_free(&header->refs);
358 f2f46662 2020-01-23 tracey gw_free_headers(header);
359 f2f46662 2020-01-23 tracey free(blame_html_disp);
360 f2f46662 2020-01-23 tracey free(blame_html);
361 f2f46662 2020-01-23 tracey free(blame);
362 2c251c14 2020-01-15 tracey return error;
363 2c251c14 2020-01-15 tracey }
364 2c251c14 2020-01-15 tracey
365 2c251c14 2020-01-15 tracey static const struct got_error *
366 e46f587c 2020-01-29 tracey gw_blob(struct gw_trans *gw_trans)
367 e46f587c 2020-01-29 tracey {
368 e46f587c 2020-01-29 tracey const struct got_error *error = NULL;
369 e46f587c 2020-01-29 tracey struct gw_header *header = NULL;
370 b27da801 2020-01-29 tracey char *blob = NULL;
371 e46f587c 2020-01-29 tracey enum kcgi_err kerr;
372 e46f587c 2020-01-29 tracey
373 e46f587c 2020-01-29 tracey if (pledge("stdio rpath wpath cpath proc exec sendfd unveil",
374 e46f587c 2020-01-29 tracey NULL) == -1)
375 e46f587c 2020-01-29 tracey return got_error_from_errno("pledge");
376 e46f587c 2020-01-29 tracey
377 e46f587c 2020-01-29 tracey if ((header = gw_init_header()) == NULL)
378 e46f587c 2020-01-29 tracey return got_error_from_errno("malloc");
379 e46f587c 2020-01-29 tracey
380 e46f587c 2020-01-29 tracey error = gw_apply_unveil(gw_trans->gw_dir->path, NULL);
381 e46f587c 2020-01-29 tracey if (error)
382 e46f587c 2020-01-29 tracey goto done;
383 e46f587c 2020-01-29 tracey
384 e46f587c 2020-01-29 tracey error = gw_get_header(gw_trans, header, 1);
385 e46f587c 2020-01-29 tracey if (error)
386 e46f587c 2020-01-29 tracey goto done;
387 e46f587c 2020-01-29 tracey
388 b27da801 2020-01-29 tracey blob = gw_get_file_blame_blob(gw_trans);
389 e46f587c 2020-01-29 tracey
390 b27da801 2020-01-29 tracey if (blob == NULL) {
391 b27da801 2020-01-29 tracey blob = strdup("");
392 b27da801 2020-01-29 tracey if (blob == NULL) {
393 e46f587c 2020-01-29 tracey error = got_error_from_errno("strdup");
394 e46f587c 2020-01-29 tracey goto done;
395 e46f587c 2020-01-29 tracey }
396 e46f587c 2020-01-29 tracey }
397 e46f587c 2020-01-29 tracey
398 e46f587c 2020-01-29 tracey kerr = khttp_puts(gw_trans->gw_req, blob);
399 e46f587c 2020-01-29 tracey if (kerr != KCGI_OK)
400 e46f587c 2020-01-29 tracey error = gw_kcgi_error(kerr);
401 e46f587c 2020-01-29 tracey done:
402 e46f587c 2020-01-29 tracey got_ref_list_free(&header->refs);
403 e46f587c 2020-01-29 tracey gw_free_headers(header);
404 e46f587c 2020-01-29 tracey free(blob);
405 e46f587c 2020-01-29 tracey return error;
406 e46f587c 2020-01-29 tracey }
407 e46f587c 2020-01-29 tracey
408 e46f587c 2020-01-29 tracey static const struct got_error *
409 f2f46662 2020-01-23 tracey gw_diff(struct gw_trans *gw_trans)
410 2c251c14 2020-01-15 tracey {
411 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
412 f2f46662 2020-01-23 tracey struct gw_header *header = NULL;
413 f2f46662 2020-01-23 tracey char *diff = NULL, *diff_html = NULL, *diff_html_disp = NULL;
414 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
415 2c251c14 2020-01-15 tracey
416 f2f46662 2020-01-23 tracey if (pledge("stdio rpath wpath cpath proc exec sendfd unveil",
417 f2f46662 2020-01-23 tracey NULL) == -1)
418 f2f46662 2020-01-23 tracey return got_error_from_errno("pledge");
419 6bee13de 2020-01-16 tracey
420 ae36ed87 2020-01-28 stsp if ((header = gw_init_header()) == NULL)
421 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
422 f2f46662 2020-01-23 tracey
423 54415d85 2020-01-15 tracey error = gw_apply_unveil(gw_trans->gw_dir->path, NULL);
424 8087c3c5 2020-01-15 tracey if (error)
425 390d412c 2020-01-28 stsp goto done;
426 8087c3c5 2020-01-15 tracey
427 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header, 1);
428 f2f46662 2020-01-23 tracey if (error)
429 390d412c 2020-01-28 stsp goto done;
430 2c251c14 2020-01-15 tracey
431 f2f46662 2020-01-23 tracey diff_html = gw_get_diff(gw_trans, header);
432 6bee13de 2020-01-16 tracey
433 390d412c 2020-01-28 stsp if (diff_html == NULL) {
434 f2f46662 2020-01-23 tracey diff_html = strdup("");
435 390d412c 2020-01-28 stsp if (diff_html == NULL) {
436 390d412c 2020-01-28 stsp error = got_error_from_errno("strdup");
437 390d412c 2020-01-28 stsp goto done;
438 390d412c 2020-01-28 stsp }
439 390d412c 2020-01-28 stsp }
440 87f9ebf5 2020-01-15 tracey
441 390d412c 2020-01-28 stsp if (asprintf(&diff_html_disp, diff_header,
442 2ac037ec 2020-01-24 tracey gw_gen_diff_header(header->parent_id, header->commit_id),
443 f2f46662 2020-01-23 tracey gw_gen_commit_header(header->commit_id, header->refs_str),
444 f2f46662 2020-01-23 tracey gw_gen_tree_header(header->tree_id),
445 f2f46662 2020-01-23 tracey gw_gen_author_header(header->author),
446 f2f46662 2020-01-23 tracey gw_gen_committer_header(header->committer),
447 f2f46662 2020-01-23 tracey gw_gen_age_header(gw_get_time_str(header->committer_time, TM_LONG)),
448 f2f46662 2020-01-23 tracey gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)),
449 390d412c 2020-01-28 stsp diff_html) == -1) {
450 390d412c 2020-01-28 stsp error = got_error_from_errno("asprintf");
451 390d412c 2020-01-28 stsp goto done;
452 390d412c 2020-01-28 stsp }
453 2204c934 2020-01-15 tracey
454 390d412c 2020-01-28 stsp if (asprintf(&diff, diff_wrapper, diff_html_disp) == -1) {
455 390d412c 2020-01-28 stsp error = got_error_from_errno("asprintf");
456 390d412c 2020-01-28 stsp goto done;
457 390d412c 2020-01-28 stsp }
458 87f9ebf5 2020-01-15 tracey
459 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, diff);
460 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
461 c25c2314 2020-01-28 stsp error = gw_kcgi_error(kerr);
462 390d412c 2020-01-28 stsp done:
463 2dcb56a8 2020-01-28 stsp got_ref_list_free(&header->refs);
464 f2f46662 2020-01-23 tracey gw_free_headers(header);
465 f2f46662 2020-01-23 tracey free(diff_html_disp);
466 f2f46662 2020-01-23 tracey free(diff_html);
467 f2f46662 2020-01-23 tracey free(diff);
468 2204c934 2020-01-15 tracey return error;
469 2204c934 2020-01-15 tracey }
470 2204c934 2020-01-15 tracey
471 2204c934 2020-01-15 tracey static const struct got_error *
472 54415d85 2020-01-15 tracey gw_index(struct gw_trans *gw_trans)
473 2c251c14 2020-01-15 tracey {
474 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
475 46b9c89b 2020-01-15 tracey struct gw_dir *gw_dir = NULL;
476 2c251c14 2020-01-15 tracey char *html, *navs, *next, *prev;
477 387a29ba 2020-01-15 tracey unsigned int prev_disp = 0, next_disp = 1, dir_c = 0;
478 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
479 2c251c14 2020-01-15 tracey
480 6bee13de 2020-01-16 tracey if (pledge("stdio rpath proc exec sendfd unveil",
481 6bee13de 2020-01-16 tracey NULL) == -1) {
482 6bee13de 2020-01-16 tracey error = got_error_from_errno("pledge");
483 6bee13de 2020-01-16 tracey return error;
484 6bee13de 2020-01-16 tracey }
485 6bee13de 2020-01-16 tracey
486 54415d85 2020-01-15 tracey error = gw_apply_unveil(gw_trans->gw_conf->got_repos_path, NULL);
487 46b9c89b 2020-01-15 tracey if (error)
488 46b9c89b 2020-01-15 tracey return error;
489 46b9c89b 2020-01-15 tracey
490 2c251c14 2020-01-15 tracey error = gw_load_got_paths(gw_trans);
491 46b9c89b 2020-01-15 tracey if (error)
492 2c251c14 2020-01-15 tracey return error;
493 2c251c14 2020-01-15 tracey
494 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, index_projects_header);
495 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
496 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
497 2c251c14 2020-01-15 tracey
498 bce5dac1 2020-01-28 stsp if (TAILQ_EMPTY(&gw_trans->gw_dirs)) {
499 bce5dac1 2020-01-28 stsp if (asprintf(&html, index_projects_empty,
500 bce5dac1 2020-01-28 stsp gw_trans->gw_conf->got_repos_path) == -1)
501 bce5dac1 2020-01-28 stsp return got_error_from_errno("asprintf");
502 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, html);
503 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
504 c25c2314 2020-01-28 stsp error = gw_kcgi_error(kerr);
505 bce5dac1 2020-01-28 stsp free(html);
506 c25c2314 2020-01-28 stsp return error;
507 bce5dac1 2020-01-28 stsp }
508 bce5dac1 2020-01-28 stsp
509 46b9c89b 2020-01-15 tracey TAILQ_FOREACH(gw_dir, &gw_trans->gw_dirs, entry)
510 2c251c14 2020-01-15 tracey dir_c++;
511 2c251c14 2020-01-15 tracey
512 46b9c89b 2020-01-15 tracey TAILQ_FOREACH(gw_dir, &gw_trans->gw_dirs, entry) {
513 2c251c14 2020-01-15 tracey if (gw_trans->page > 0 && (gw_trans->page *
514 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_max_repos_display) > prev_disp) {
515 2c251c14 2020-01-15 tracey prev_disp++;
516 2c251c14 2020-01-15 tracey continue;
517 2c251c14 2020-01-15 tracey }
518 2c251c14 2020-01-15 tracey
519 2c251c14 2020-01-15 tracey prev_disp++;
520 f2f46662 2020-01-23 tracey
521 f2f46662 2020-01-23 tracey if (error)
522 f2f46662 2020-01-23 tracey return error;
523 88d59c36 2020-01-29 stsp if(asprintf(&navs, index_navs, gw_dir->name, gw_dir->name,
524 88d59c36 2020-01-29 stsp gw_dir->name, gw_dir->name) == -1)
525 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
526 2c251c14 2020-01-15 tracey
527 88d59c36 2020-01-29 stsp if (asprintf(&html, index_projects, gw_dir->name, gw_dir->name,
528 46b9c89b 2020-01-15 tracey gw_dir->description, gw_dir->owner, gw_dir->age,
529 88d59c36 2020-01-29 stsp navs) == -1)
530 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
531 2c251c14 2020-01-15 tracey
532 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, html);
533 2c251c14 2020-01-15 tracey free(navs);
534 2c251c14 2020-01-15 tracey free(html);
535 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
536 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
537 2c251c14 2020-01-15 tracey
538 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_max_repos_display == 0)
539 2c251c14 2020-01-15 tracey continue;
540 2c251c14 2020-01-15 tracey
541 c25c2314 2020-01-28 stsp if (next_disp == gw_trans->gw_conf->got_max_repos_display) {
542 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, np_wrapper_start);
543 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
544 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
545 c25c2314 2020-01-28 stsp } else if ((gw_trans->gw_conf->got_max_repos_display > 0) &&
546 2c251c14 2020-01-15 tracey (gw_trans->page > 0) &&
547 2c251c14 2020-01-15 tracey (next_disp == gw_trans->gw_conf->got_max_repos_display ||
548 c25c2314 2020-01-28 stsp prev_disp == gw_trans->repos_total)) {
549 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, np_wrapper_start);
550 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
551 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
552 c25c2314 2020-01-28 stsp }
553 2c251c14 2020-01-15 tracey
554 2c251c14 2020-01-15 tracey if ((gw_trans->gw_conf->got_max_repos_display > 0) &&
555 2c251c14 2020-01-15 tracey (gw_trans->page > 0) &&
556 2c251c14 2020-01-15 tracey (next_disp == gw_trans->gw_conf->got_max_repos_display ||
557 2c251c14 2020-01-15 tracey prev_disp == gw_trans->repos_total)) {
558 88d59c36 2020-01-29 stsp if (asprintf(&prev, nav_prev, gw_trans->page - 1) == -1)
559 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
560 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, prev);
561 2c251c14 2020-01-15 tracey free(prev);
562 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
563 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
564 2c251c14 2020-01-15 tracey }
565 2c251c14 2020-01-15 tracey
566 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, div_end);
567 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
568 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
569 2c251c14 2020-01-15 tracey
570 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_max_repos_display > 0 &&
571 2c251c14 2020-01-15 tracey next_disp == gw_trans->gw_conf->got_max_repos_display &&
572 2c251c14 2020-01-15 tracey dir_c != (gw_trans->page + 1) *
573 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_max_repos_display) {
574 88d59c36 2020-01-29 stsp if (asprintf(&next, nav_next, gw_trans->page + 1) == -1)
575 2c251c14 2020-01-15 tracey return got_error_from_errno("calloc");
576 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, next);
577 2c251c14 2020-01-15 tracey free(next);
578 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
579 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
580 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, div_end);
581 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
582 c25c2314 2020-01-28 stsp error = gw_kcgi_error(kerr);
583 2c251c14 2020-01-15 tracey next_disp = 0;
584 2c251c14 2020-01-15 tracey break;
585 2c251c14 2020-01-15 tracey }
586 2c251c14 2020-01-15 tracey
587 2c251c14 2020-01-15 tracey if ((gw_trans->gw_conf->got_max_repos_display > 0) &&
588 2c251c14 2020-01-15 tracey (gw_trans->page > 0) &&
589 2c251c14 2020-01-15 tracey (next_disp == gw_trans->gw_conf->got_max_repos_display ||
590 c25c2314 2020-01-28 stsp prev_disp == gw_trans->repos_total)) {
591 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, div_end);
592 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
593 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
594 c25c2314 2020-01-28 stsp }
595 2c251c14 2020-01-15 tracey
596 2c251c14 2020-01-15 tracey next_disp++;
597 2c251c14 2020-01-15 tracey }
598 2c251c14 2020-01-15 tracey return error;
599 2c251c14 2020-01-15 tracey }
600 2c251c14 2020-01-15 tracey
601 2c251c14 2020-01-15 tracey static const struct got_error *
602 f2f46662 2020-01-23 tracey gw_commits(struct gw_trans *gw_trans)
603 2c251c14 2020-01-15 tracey {
604 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
605 f2f46662 2020-01-23 tracey char *commits_html, *commits_navs_html;
606 f2f46662 2020-01-23 tracey struct gw_header *header = NULL, *n_header = NULL;
607 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
608 6bee13de 2020-01-16 tracey
609 ae36ed87 2020-01-28 stsp if ((header = gw_init_header()) == NULL)
610 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
611 f2f46662 2020-01-23 tracey
612 6bee13de 2020-01-16 tracey if (pledge("stdio rpath proc exec sendfd unveil",
613 6bee13de 2020-01-16 tracey NULL) == -1) {
614 6bee13de 2020-01-16 tracey error = got_error_from_errno("pledge");
615 5ddf0079 2020-01-29 stsp goto done;
616 6bee13de 2020-01-16 tracey }
617 8087c3c5 2020-01-15 tracey
618 54415d85 2020-01-15 tracey error = gw_apply_unveil(gw_trans->gw_dir->path, NULL);
619 8087c3c5 2020-01-15 tracey if (error)
620 5ddf0079 2020-01-29 stsp goto done;
621 2c251c14 2020-01-15 tracey
622 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header,
623 f2f46662 2020-01-23 tracey gw_trans->gw_conf->got_max_commits_display);
624 18da9978 2020-01-29 stsp if (error)
625 18da9978 2020-01-29 stsp goto done;
626 4ceb8155 2020-01-15 tracey
627 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, commits_wrapper);
628 18da9978 2020-01-29 stsp if (kerr != KCGI_OK) {
629 18da9978 2020-01-29 stsp error = gw_kcgi_error(kerr);
630 18da9978 2020-01-29 stsp goto done;
631 18da9978 2020-01-29 stsp }
632 f2f46662 2020-01-23 tracey TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry) {
633 88d59c36 2020-01-29 stsp if (asprintf(&commits_navs_html, commits_navs,
634 f2f46662 2020-01-23 tracey gw_trans->repo_name, n_header->commit_id,
635 f2f46662 2020-01-23 tracey gw_trans->repo_name, n_header->commit_id,
636 88d59c36 2020-01-29 stsp gw_trans->repo_name, n_header->commit_id) == -1) {
637 18da9978 2020-01-29 stsp error = got_error_from_errno("asprintf");
638 18da9978 2020-01-29 stsp goto done;
639 18da9978 2020-01-29 stsp }
640 2c251c14 2020-01-15 tracey
641 88d59c36 2020-01-29 stsp if (asprintf(&commits_html, commits_line,
642 e46f587c 2020-01-29 tracey gw_gen_commit_header(n_header->commit_id,
643 f2f46662 2020-01-23 tracey n_header->refs_str),
644 e46f587c 2020-01-29 tracey gw_gen_author_header(n_header->author),
645 e46f587c 2020-01-29 tracey gw_gen_committer_header(n_header->committer),
646 f2f46662 2020-01-23 tracey gw_gen_age_header(gw_get_time_str(n_header->committer_time,
647 f2f46662 2020-01-23 tracey TM_LONG)), gw_html_escape(n_header->commit_msg),
648 88d59c36 2020-01-29 stsp commits_navs_html) == -1) {
649 18da9978 2020-01-29 stsp error = got_error_from_errno("asprintf");
650 18da9978 2020-01-29 stsp goto done;
651 18da9978 2020-01-29 stsp }
652 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, commits_html);
653 18da9978 2020-01-29 stsp if (kerr != KCGI_OK) {
654 18da9978 2020-01-29 stsp error = gw_kcgi_error(kerr);
655 18da9978 2020-01-29 stsp goto done;
656 18da9978 2020-01-29 stsp }
657 f2f46662 2020-01-23 tracey }
658 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, div_end);
659 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
660 c25c2314 2020-01-28 stsp error = gw_kcgi_error(kerr);
661 18da9978 2020-01-29 stsp done:
662 2dcb56a8 2020-01-28 stsp got_ref_list_free(&header->refs);
663 f2f46662 2020-01-23 tracey gw_free_headers(header);
664 f2f46662 2020-01-23 tracey TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry)
665 f2f46662 2020-01-23 tracey gw_free_headers(n_header);
666 2c251c14 2020-01-15 tracey return error;
667 2c251c14 2020-01-15 tracey }
668 2c251c14 2020-01-15 tracey
669 2c251c14 2020-01-15 tracey static const struct got_error *
670 f2f46662 2020-01-23 tracey gw_briefs(struct gw_trans *gw_trans)
671 2c251c14 2020-01-15 tracey {
672 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
673 f2f46662 2020-01-23 tracey char *briefs_html = NULL, *briefs_navs_html = NULL, *newline;
674 f2f46662 2020-01-23 tracey struct gw_header *header = NULL, *n_header = NULL;
675 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
676 17a96b9f 2020-01-15 tracey
677 ae36ed87 2020-01-28 stsp if ((header = gw_init_header()) == NULL)
678 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
679 f2f46662 2020-01-23 tracey
680 6bee13de 2020-01-16 tracey if (pledge("stdio rpath proc exec sendfd unveil",
681 6bee13de 2020-01-16 tracey NULL) == -1) {
682 6bee13de 2020-01-16 tracey error = got_error_from_errno("pledge");
683 5ddf0079 2020-01-29 stsp goto done;
684 6bee13de 2020-01-16 tracey }
685 6bee13de 2020-01-16 tracey
686 54415d85 2020-01-15 tracey error = gw_apply_unveil(gw_trans->gw_dir->path, NULL);
687 8087c3c5 2020-01-15 tracey if (error)
688 5ddf0079 2020-01-29 stsp goto done;
689 9d84e7dd 2020-01-15 tracey
690 f2f46662 2020-01-23 tracey if (gw_trans->action == GW_SUMMARY)
691 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header, D_MAXSLCOMMDISP);
692 f2f46662 2020-01-23 tracey else
693 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header,
694 f2f46662 2020-01-23 tracey gw_trans->gw_conf->got_max_commits_display);
695 c25c2314 2020-01-28 stsp if (error)
696 0e00e8f4 2020-01-29 stsp goto done;
697 c25c2314 2020-01-28 stsp
698 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, briefs_wrapper);
699 0e00e8f4 2020-01-29 stsp if (kerr != KCGI_OK) {
700 0e00e8f4 2020-01-29 stsp error = gw_kcgi_error(kerr);
701 0e00e8f4 2020-01-29 stsp goto done;
702 0e00e8f4 2020-01-29 stsp }
703 c25c2314 2020-01-28 stsp
704 f2f46662 2020-01-23 tracey TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry) {
705 88d59c36 2020-01-29 stsp if (asprintf(&briefs_navs_html, briefs_navs,
706 f2f46662 2020-01-23 tracey gw_trans->repo_name, n_header->commit_id,
707 f2f46662 2020-01-23 tracey gw_trans->repo_name, n_header->commit_id,
708 88d59c36 2020-01-29 stsp gw_trans->repo_name, n_header->commit_id) == -1) {
709 0e00e8f4 2020-01-29 stsp error = got_error_from_errno("asprintf");
710 0e00e8f4 2020-01-29 stsp goto done;
711 0e00e8f4 2020-01-29 stsp }
712 f2f46662 2020-01-23 tracey newline = strchr(n_header->commit_msg, '\n');
713 f2f46662 2020-01-23 tracey if (newline)
714 f2f46662 2020-01-23 tracey *newline = '\0';
715 88d59c36 2020-01-29 stsp if (asprintf(&briefs_html, briefs_line,
716 f2f46662 2020-01-23 tracey gw_get_time_str(n_header->committer_time, TM_DIFF),
717 f2f46662 2020-01-23 tracey n_header->author, gw_html_escape(n_header->commit_msg),
718 88d59c36 2020-01-29 stsp briefs_navs_html) == -1) {
719 0e00e8f4 2020-01-29 stsp error = got_error_from_errno("asprintf");
720 0e00e8f4 2020-01-29 stsp goto done;
721 0e00e8f4 2020-01-29 stsp }
722 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, briefs_html);
723 0e00e8f4 2020-01-29 stsp if (kerr != KCGI_OK) {
724 0e00e8f4 2020-01-29 stsp error = gw_kcgi_error(kerr);
725 0e00e8f4 2020-01-29 stsp goto done;
726 0e00e8f4 2020-01-29 stsp }
727 9d84e7dd 2020-01-15 tracey }
728 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, div_end);
729 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
730 c25c2314 2020-01-28 stsp error = gw_kcgi_error(kerr);
731 0e00e8f4 2020-01-29 stsp done:
732 2dcb56a8 2020-01-28 stsp got_ref_list_free(&header->refs);
733 f2f46662 2020-01-23 tracey gw_free_headers(header);
734 f2f46662 2020-01-23 tracey TAILQ_FOREACH(n_header, &gw_trans->gw_headers, entry)
735 f2f46662 2020-01-23 tracey gw_free_headers(n_header);
736 2c251c14 2020-01-15 tracey return error;
737 2c251c14 2020-01-15 tracey }
738 2c251c14 2020-01-15 tracey
739 2c251c14 2020-01-15 tracey static const struct got_error *
740 54415d85 2020-01-15 tracey gw_summary(struct gw_trans *gw_trans)
741 387a29ba 2020-01-15 tracey {
742 387a29ba 2020-01-15 tracey const struct got_error *error = NULL;
743 20f34652 2020-01-29 stsp char *description_html = NULL, *repo_owner_html = NULL;
744 20f34652 2020-01-29 stsp char *age = NULL, *repo_age_html = NULL, *cloneurl_html = NULL;
745 20f34652 2020-01-29 stsp char *tags = NULL, *tags_html = NULL;
746 20f34652 2020-01-29 stsp char *heads = NULL, *heads_html = NULL;
747 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
748 387a29ba 2020-01-15 tracey
749 f4df82f9 2020-01-29 stsp if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
750 f4df82f9 2020-01-29 stsp return got_error_from_errno("pledge");
751 6bee13de 2020-01-16 tracey
752 f2f46662 2020-01-23 tracey /* unveil is applied with gw_briefs below */
753 46b9c89b 2020-01-15 tracey
754 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, summary_wrapper);
755 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
756 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
757 c25c2314 2020-01-28 stsp
758 46b9c89b 2020-01-15 tracey if (gw_trans->gw_conf->got_show_repo_description) {
759 46b9c89b 2020-01-15 tracey if (gw_trans->gw_dir->description != NULL &&
760 46b9c89b 2020-01-15 tracey (strcmp(gw_trans->gw_dir->description, "") != 0)) {
761 88d59c36 2020-01-29 stsp if (asprintf(&description_html, description,
762 20f34652 2020-01-29 stsp gw_trans->gw_dir->description) == -1) {
763 20f34652 2020-01-29 stsp error = got_error_from_errno("asprintf");
764 20f34652 2020-01-29 stsp goto done;
765 20f34652 2020-01-29 stsp }
766 46b9c89b 2020-01-15 tracey
767 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, description_html);
768 20f34652 2020-01-29 stsp if (kerr != KCGI_OK) {
769 20f34652 2020-01-29 stsp error = gw_kcgi_error(kerr);
770 20f34652 2020-01-29 stsp goto done;
771 20f34652 2020-01-29 stsp }
772 46b9c89b 2020-01-15 tracey }
773 46b9c89b 2020-01-15 tracey }
774 46b9c89b 2020-01-15 tracey
775 46b9c89b 2020-01-15 tracey if (gw_trans->gw_conf->got_show_repo_owner) {
776 46b9c89b 2020-01-15 tracey if (gw_trans->gw_dir->owner != NULL &&
777 46b9c89b 2020-01-15 tracey (strcmp(gw_trans->gw_dir->owner, "") != 0)) {
778 88d59c36 2020-01-29 stsp if (asprintf(&repo_owner_html, repo_owner,
779 20f34652 2020-01-29 stsp gw_trans->gw_dir->owner) == -1) {
780 20f34652 2020-01-29 stsp error = got_error_from_errno("asprintf");
781 20f34652 2020-01-29 stsp goto done;
782 20f34652 2020-01-29 stsp }
783 46b9c89b 2020-01-15 tracey
784 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, repo_owner_html);
785 20f34652 2020-01-29 stsp if (kerr != KCGI_OK) {
786 20f34652 2020-01-29 stsp error = gw_kcgi_error(kerr);
787 20f34652 2020-01-29 stsp goto done;
788 20f34652 2020-01-29 stsp }
789 46b9c89b 2020-01-15 tracey }
790 46b9c89b 2020-01-15 tracey }
791 46b9c89b 2020-01-15 tracey
792 46b9c89b 2020-01-15 tracey if (gw_trans->gw_conf->got_show_repo_age) {
793 d126c1b7 2020-01-29 stsp error = gw_get_repo_age(&age, gw_trans, gw_trans->gw_dir->path,
794 c6b62706 2020-01-15 tracey "refs/heads", TM_LONG);
795 d126c1b7 2020-01-29 stsp if (error)
796 20f34652 2020-01-29 stsp goto done;
797 d126c1b7 2020-01-29 stsp if (strcmp(age, "") != 0) {
798 20f34652 2020-01-29 stsp if (asprintf(&repo_age_html, last_change, age) == -1) {
799 20f34652 2020-01-29 stsp error = got_error_from_errno("asprintf");
800 20f34652 2020-01-29 stsp goto done;
801 20f34652 2020-01-29 stsp }
802 46b9c89b 2020-01-15 tracey
803 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, repo_age_html);
804 20f34652 2020-01-29 stsp if (kerr != KCGI_OK) {
805 20f34652 2020-01-29 stsp error = gw_kcgi_error(kerr);
806 20f34652 2020-01-29 stsp goto done;
807 20f34652 2020-01-29 stsp }
808 46b9c89b 2020-01-15 tracey }
809 46b9c89b 2020-01-15 tracey }
810 46b9c89b 2020-01-15 tracey
811 46b9c89b 2020-01-15 tracey if (gw_trans->gw_conf->got_show_repo_cloneurl) {
812 46b9c89b 2020-01-15 tracey if (gw_trans->gw_dir->url != NULL &&
813 46b9c89b 2020-01-15 tracey (strcmp(gw_trans->gw_dir->url, "") != 0)) {
814 88d59c36 2020-01-29 stsp if (asprintf(&cloneurl_html, cloneurl,
815 20f34652 2020-01-29 stsp gw_trans->gw_dir->url) == -1) {
816 20f34652 2020-01-29 stsp error = got_error_from_errno("asprintf");
817 20f34652 2020-01-29 stsp goto done;
818 20f34652 2020-01-29 stsp }
819 46b9c89b 2020-01-15 tracey
820 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, cloneurl_html);
821 20f34652 2020-01-29 stsp if (kerr != KCGI_OK) {
822 20f34652 2020-01-29 stsp error = gw_kcgi_error(kerr);
823 20f34652 2020-01-29 stsp goto done;
824 20f34652 2020-01-29 stsp }
825 46b9c89b 2020-01-15 tracey }
826 46b9c89b 2020-01-15 tracey }
827 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, div_end);
828 20f34652 2020-01-29 stsp if (kerr != KCGI_OK) {
829 20f34652 2020-01-29 stsp error = gw_kcgi_error(kerr);
830 20f34652 2020-01-29 stsp goto done;
831 20f34652 2020-01-29 stsp }
832 46b9c89b 2020-01-15 tracey
833 f2f46662 2020-01-23 tracey error = gw_briefs(gw_trans);
834 f2f46662 2020-01-23 tracey if (error)
835 20f34652 2020-01-29 stsp goto done;
836 f2f46662 2020-01-23 tracey
837 4ff7391f 2020-01-28 tracey tags = gw_get_repo_tags(gw_trans, NULL, D_MAXSLCOMMDISP, TAGBRIEF);
838 8d4d2453 2020-01-15 tracey heads = gw_get_repo_heads(gw_trans);
839 387a29ba 2020-01-15 tracey
840 8d4d2453 2020-01-15 tracey if (tags != NULL && strcmp(tags, "") != 0) {
841 20f34652 2020-01-29 stsp if (asprintf(&tags_html, summary_tags, tags) == -1) {
842 20f34652 2020-01-29 stsp error = got_error_from_errno("asprintf");
843 20f34652 2020-01-29 stsp goto done;
844 20f34652 2020-01-29 stsp }
845 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, tags_html);
846 20f34652 2020-01-29 stsp if (kerr != KCGI_OK) {
847 20f34652 2020-01-29 stsp error = gw_kcgi_error(kerr);
848 20f34652 2020-01-29 stsp goto done;
849 20f34652 2020-01-29 stsp }
850 8d4d2453 2020-01-15 tracey }
851 8d4d2453 2020-01-15 tracey
852 8d4d2453 2020-01-15 tracey if (heads != NULL && strcmp(heads, "") != 0) {
853 20f34652 2020-01-29 stsp if (asprintf(&heads_html, summary_heads, heads) == -1) {
854 20f34652 2020-01-29 stsp error = got_error_from_errno("asprintf");
855 20f34652 2020-01-29 stsp goto done;
856 20f34652 2020-01-29 stsp }
857 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, heads_html);
858 20f34652 2020-01-29 stsp if (kerr != KCGI_OK) {
859 20f34652 2020-01-29 stsp error = gw_kcgi_error(kerr);
860 20f34652 2020-01-29 stsp goto done;
861 20f34652 2020-01-29 stsp }
862 8d4d2453 2020-01-15 tracey }
863 20f34652 2020-01-29 stsp done:
864 20f34652 2020-01-29 stsp free(description_html);
865 20f34652 2020-01-29 stsp free(repo_owner_html);
866 20f34652 2020-01-29 stsp free(age);
867 20f34652 2020-01-29 stsp free(repo_age_html);
868 20f34652 2020-01-29 stsp free(cloneurl_html);
869 20f34652 2020-01-29 stsp free(tags);
870 20f34652 2020-01-29 stsp free(tags_html);
871 20f34652 2020-01-29 stsp free(heads);
872 20f34652 2020-01-29 stsp free(heads_html);
873 2204c934 2020-01-15 tracey return error;
874 2204c934 2020-01-15 tracey }
875 2204c934 2020-01-15 tracey
876 2204c934 2020-01-15 tracey static const struct got_error *
877 f2f46662 2020-01-23 tracey gw_tree(struct gw_trans *gw_trans)
878 b772de24 2020-01-15 tracey {
879 b772de24 2020-01-15 tracey const struct got_error *error = NULL;
880 f2f46662 2020-01-23 tracey struct gw_header *header = NULL;
881 f2f46662 2020-01-23 tracey char *tree = NULL, *tree_html = NULL, *tree_html_disp = NULL;
882 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
883 6bee13de 2020-01-16 tracey
884 f2f46662 2020-01-23 tracey if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
885 f2f46662 2020-01-23 tracey return got_error_from_errno("pledge");
886 b772de24 2020-01-15 tracey
887 ae36ed87 2020-01-28 stsp if ((header = gw_init_header()) == NULL)
888 f2f46662 2020-01-23 tracey return got_error_from_errno("malloc");
889 f2f46662 2020-01-23 tracey
890 54415d85 2020-01-15 tracey error = gw_apply_unveil(gw_trans->gw_dir->path, NULL);
891 b772de24 2020-01-15 tracey if (error)
892 5ddf0079 2020-01-29 stsp goto done;
893 b772de24 2020-01-15 tracey
894 f2f46662 2020-01-23 tracey error = gw_get_header(gw_trans, header, 1);
895 f2f46662 2020-01-23 tracey if (error)
896 42281175 2020-01-29 stsp goto done;
897 b772de24 2020-01-15 tracey
898 f2f46662 2020-01-23 tracey tree_html = gw_get_repo_tree(gw_trans);
899 b772de24 2020-01-15 tracey
900 4ff7391f 2020-01-28 tracey if (tree_html == NULL) {
901 f2f46662 2020-01-23 tracey tree_html = strdup("");
902 4ff7391f 2020-01-28 tracey if (tree_html == NULL) {
903 4ff7391f 2020-01-28 tracey error = got_error_from_errno("strdup");
904 4ff7391f 2020-01-28 tracey goto done;
905 4ff7391f 2020-01-28 tracey }
906 4ff7391f 2020-01-28 tracey }
907 6bee13de 2020-01-16 tracey
908 88d59c36 2020-01-29 stsp if (asprintf(&tree_html_disp, tree_header,
909 f2f46662 2020-01-23 tracey gw_gen_age_header(gw_get_time_str(header->committer_time, TM_LONG)),
910 f2f46662 2020-01-23 tracey gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)),
911 88d59c36 2020-01-29 stsp tree_html) == -1) {
912 42281175 2020-01-29 stsp error = got_error_from_errno("asprintf");
913 42281175 2020-01-29 stsp goto done;
914 42281175 2020-01-29 stsp }
915 8087c3c5 2020-01-15 tracey
916 42281175 2020-01-29 stsp if (asprintf(&tree, tree_wrapper, tree_html_disp) == -1) {
917 42281175 2020-01-29 stsp error = got_error_from_errno("asprintf");
918 42281175 2020-01-29 stsp goto done;
919 42281175 2020-01-29 stsp }
920 8087c3c5 2020-01-15 tracey
921 c25c2314 2020-01-28 stsp kerr = khttp_puts(gw_trans->gw_req, tree);
922 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
923 c25c2314 2020-01-28 stsp error = gw_kcgi_error(kerr);
924 4ff7391f 2020-01-28 tracey done:
925 2dcb56a8 2020-01-28 stsp got_ref_list_free(&header->refs);
926 f2f46662 2020-01-23 tracey gw_free_headers(header);
927 f2f46662 2020-01-23 tracey free(tree_html_disp);
928 f2f46662 2020-01-23 tracey free(tree_html);
929 f2f46662 2020-01-23 tracey free(tree);
930 4ff7391f 2020-01-28 tracey return error;
931 4ff7391f 2020-01-28 tracey }
932 4ff7391f 2020-01-28 tracey
933 4ff7391f 2020-01-28 tracey static const struct got_error *
934 4ff7391f 2020-01-28 tracey gw_tag(struct gw_trans *gw_trans)
935 4ff7391f 2020-01-28 tracey {
936 4ff7391f 2020-01-28 tracey const struct got_error *error = NULL;
937 4ff7391f 2020-01-28 tracey struct gw_header *header = NULL;
938 4ff7391f 2020-01-28 tracey char *tag = NULL, *tag_html = NULL, *tag_html_disp = NULL;
939 4ff7391f 2020-01-28 tracey enum kcgi_err kerr;
940 4ff7391f 2020-01-28 tracey
941 4ff7391f 2020-01-28 tracey if (pledge("stdio rpath proc exec sendfd unveil", NULL) == -1)
942 4ff7391f 2020-01-28 tracey return got_error_from_errno("pledge");
943 4ff7391f 2020-01-28 tracey
944 4ff7391f 2020-01-28 tracey if ((header = gw_init_header()) == NULL)
945 4ff7391f 2020-01-28 tracey return got_error_from_errno("malloc");
946 4ff7391f 2020-01-28 tracey
947 4ff7391f 2020-01-28 tracey error = gw_apply_unveil(gw_trans->gw_dir->path, NULL);
948 4ff7391f 2020-01-28 tracey if (error)
949 5ddf0079 2020-01-29 stsp goto done;
950 4ff7391f 2020-01-28 tracey
951 4ff7391f 2020-01-28 tracey error = gw_get_header(gw_trans, header, 1);
952 4ff7391f 2020-01-28 tracey if (error)
953 470cd826 2020-01-29 stsp goto done;
954 4ff7391f 2020-01-28 tracey
955 4ff7391f 2020-01-28 tracey tag_html = gw_get_repo_tags(gw_trans, header, 1, TAGFULL);
956 4ff7391f 2020-01-28 tracey if (tag_html == NULL) {
957 4ff7391f 2020-01-28 tracey tag_html = strdup("");
958 4ff7391f 2020-01-28 tracey if (tag_html == NULL) {
959 4ff7391f 2020-01-28 tracey error = got_error_from_errno("strdup");
960 4ff7391f 2020-01-28 tracey goto done;
961 4ff7391f 2020-01-28 tracey }
962 4ff7391f 2020-01-28 tracey }
963 4ff7391f 2020-01-28 tracey
964 88d59c36 2020-01-29 stsp if (asprintf(&tag_html_disp, tag_header,
965 4ff7391f 2020-01-28 tracey gw_gen_commit_header(header->commit_id, header->refs_str),
966 4ff7391f 2020-01-28 tracey gw_gen_commit_msg_header(gw_html_escape(header->commit_msg)),
967 88d59c36 2020-01-29 stsp tag_html) == -1) {
968 470cd826 2020-01-29 stsp error = got_error_from_errno("asprintf");
969 470cd826 2020-01-29 stsp goto done;
970 470cd826 2020-01-29 stsp }
971 4ff7391f 2020-01-28 tracey
972 470cd826 2020-01-29 stsp if (asprintf(&tag, tag_wrapper, tag_html_disp) == -1) {
973 470cd826 2020-01-29 stsp error = got_error_from_errno("asprintf");
974 470cd826 2020-01-29 stsp goto done;
975 470cd826 2020-01-29 stsp }
976 4ff7391f 2020-01-28 tracey
977 4ff7391f 2020-01-28 tracey kerr = khttp_puts(gw_trans->gw_req, tag);
978 4ff7391f 2020-01-28 tracey if (kerr != KCGI_OK)
979 4ff7391f 2020-01-28 tracey error = gw_kcgi_error(kerr);
980 4ff7391f 2020-01-28 tracey done:
981 4ff7391f 2020-01-28 tracey got_ref_list_free(&header->refs);
982 4ff7391f 2020-01-28 tracey gw_free_headers(header);
983 4ff7391f 2020-01-28 tracey free(tag_html_disp);
984 4ff7391f 2020-01-28 tracey free(tag_html);
985 4ff7391f 2020-01-28 tracey free(tag);
986 2c251c14 2020-01-15 tracey return error;
987 2c251c14 2020-01-15 tracey }
988 2c251c14 2020-01-15 tracey
989 2c251c14 2020-01-15 tracey static const struct got_error *
990 54415d85 2020-01-15 tracey gw_load_got_path(struct gw_trans *gw_trans, struct gw_dir *gw_dir)
991 2c251c14 2020-01-15 tracey {
992 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
993 2c251c14 2020-01-15 tracey DIR *dt;
994 2c251c14 2020-01-15 tracey char *dir_test;
995 4ceb8155 2020-01-15 tracey int opened = 0;
996 2c251c14 2020-01-15 tracey
997 88d59c36 2020-01-29 stsp if (asprintf(&dir_test, "%s/%s/%s",
998 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_repos_path, gw_dir->name,
999 88d59c36 2020-01-29 stsp GOTWEB_GIT_DIR) == -1)
1000 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
1001 2c251c14 2020-01-15 tracey
1002 2c251c14 2020-01-15 tracey dt = opendir(dir_test);
1003 2c251c14 2020-01-15 tracey if (dt == NULL) {
1004 2c251c14 2020-01-15 tracey free(dir_test);
1005 2c251c14 2020-01-15 tracey } else {
1006 2c251c14 2020-01-15 tracey gw_dir->path = strdup(dir_test);
1007 4ceb8155 2020-01-15 tracey opened = 1;
1008 2c251c14 2020-01-15 tracey goto done;
1009 2c251c14 2020-01-15 tracey }
1010 2c251c14 2020-01-15 tracey
1011 88d59c36 2020-01-29 stsp if (asprintf(&dir_test, "%s/%s/%s",
1012 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_repos_path, gw_dir->name,
1013 88d59c36 2020-01-29 stsp GOTWEB_GOT_DIR) == -1)
1014 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
1015 2c251c14 2020-01-15 tracey
1016 2c251c14 2020-01-15 tracey dt = opendir(dir_test);
1017 2c251c14 2020-01-15 tracey if (dt == NULL)
1018 2c251c14 2020-01-15 tracey free(dir_test);
1019 2c251c14 2020-01-15 tracey else {
1020 4ceb8155 2020-01-15 tracey opened = 1;
1021 2c251c14 2020-01-15 tracey error = got_error(GOT_ERR_NOT_GIT_REPO);
1022 2c251c14 2020-01-15 tracey goto errored;
1023 2c251c14 2020-01-15 tracey }
1024 2c251c14 2020-01-15 tracey
1025 88d59c36 2020-01-29 stsp if (asprintf(&dir_test, "%s/%s",
1026 88d59c36 2020-01-29 stsp gw_trans->gw_conf->got_repos_path, gw_dir->name) == -1)
1027 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
1028 2c251c14 2020-01-15 tracey
1029 2c251c14 2020-01-15 tracey gw_dir->path = strdup(dir_test);
1030 2c251c14 2020-01-15 tracey
1031 2c251c14 2020-01-15 tracey done:
1032 2c251c14 2020-01-15 tracey gw_dir->description = gw_get_repo_description(gw_trans,
1033 2c251c14 2020-01-15 tracey gw_dir->path);
1034 2c251c14 2020-01-15 tracey gw_dir->owner = gw_get_repo_owner(gw_trans, gw_dir->path);
1035 d126c1b7 2020-01-29 stsp error = gw_get_repo_age(&gw_dir->age, gw_trans, gw_dir->path,
1036 d126c1b7 2020-01-29 stsp "refs/heads", TM_DIFF);
1037 d126c1b7 2020-01-29 stsp if (error)
1038 d126c1b7 2020-01-29 stsp goto errored;
1039 2c251c14 2020-01-15 tracey gw_dir->url = gw_get_clone_url(gw_trans, gw_dir->path);
1040 2c251c14 2020-01-15 tracey
1041 2c251c14 2020-01-15 tracey errored:
1042 2c251c14 2020-01-15 tracey free(dir_test);
1043 2c251c14 2020-01-15 tracey if (opened)
1044 2c251c14 2020-01-15 tracey closedir(dt);
1045 2c251c14 2020-01-15 tracey return error;
1046 2c251c14 2020-01-15 tracey }
1047 2c251c14 2020-01-15 tracey
1048 2c251c14 2020-01-15 tracey static const struct got_error *
1049 54415d85 2020-01-15 tracey gw_load_got_paths(struct gw_trans *gw_trans)
1050 2c251c14 2020-01-15 tracey {
1051 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
1052 2c251c14 2020-01-15 tracey DIR *d;
1053 2c251c14 2020-01-15 tracey struct dirent **sd_dent;
1054 2c251c14 2020-01-15 tracey struct gw_dir *gw_dir;
1055 2c251c14 2020-01-15 tracey struct stat st;
1056 2c251c14 2020-01-15 tracey unsigned int d_cnt, d_i;
1057 2c251c14 2020-01-15 tracey
1058 2c251c14 2020-01-15 tracey d = opendir(gw_trans->gw_conf->got_repos_path);
1059 2c251c14 2020-01-15 tracey if (d == NULL) {
1060 2c251c14 2020-01-15 tracey error = got_error_from_errno2("opendir",
1061 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_repos_path);
1062 2c251c14 2020-01-15 tracey return error;
1063 2c251c14 2020-01-15 tracey }
1064 2c251c14 2020-01-15 tracey
1065 2c251c14 2020-01-15 tracey d_cnt = scandir(gw_trans->gw_conf->got_repos_path, &sd_dent, NULL,
1066 2c251c14 2020-01-15 tracey alphasort);
1067 2c251c14 2020-01-15 tracey if (d_cnt == -1) {
1068 2c251c14 2020-01-15 tracey error = got_error_from_errno2("scandir",
1069 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_repos_path);
1070 2c251c14 2020-01-15 tracey return error;
1071 2c251c14 2020-01-15 tracey }
1072 2c251c14 2020-01-15 tracey
1073 2c251c14 2020-01-15 tracey for (d_i = 0; d_i < d_cnt; d_i++) {
1074 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_max_repos > 0 &&
1075 2c251c14 2020-01-15 tracey (d_i - 2) == gw_trans->gw_conf->got_max_repos)
1076 2c251c14 2020-01-15 tracey break; /* account for parent and self */
1077 2c251c14 2020-01-15 tracey
1078 2c251c14 2020-01-15 tracey if (strcmp(sd_dent[d_i]->d_name, ".") == 0 ||
1079 2c251c14 2020-01-15 tracey strcmp(sd_dent[d_i]->d_name, "..") == 0)
1080 2c251c14 2020-01-15 tracey continue;
1081 2c251c14 2020-01-15 tracey
1082 2c251c14 2020-01-15 tracey if ((gw_dir = gw_init_gw_dir(sd_dent[d_i]->d_name)) == NULL)
1083 2c251c14 2020-01-15 tracey return got_error_from_errno("gw_dir malloc");
1084 2c251c14 2020-01-15 tracey
1085 2c251c14 2020-01-15 tracey error = gw_load_got_path(gw_trans, gw_dir);
1086 2c251c14 2020-01-15 tracey if (error && error->code == GOT_ERR_NOT_GIT_REPO)
1087 2c251c14 2020-01-15 tracey continue;
1088 2c251c14 2020-01-15 tracey else if (error)
1089 2c251c14 2020-01-15 tracey return error;
1090 2c251c14 2020-01-15 tracey
1091 2c251c14 2020-01-15 tracey if (lstat(gw_dir->path, &st) == 0 && S_ISDIR(st.st_mode) &&
1092 2c251c14 2020-01-15 tracey !got_path_dir_is_empty(gw_dir->path)) {
1093 2c251c14 2020-01-15 tracey TAILQ_INSERT_TAIL(&gw_trans->gw_dirs, gw_dir,
1094 2c251c14 2020-01-15 tracey entry);
1095 2c251c14 2020-01-15 tracey gw_trans->repos_total++;
1096 2c251c14 2020-01-15 tracey }
1097 2c251c14 2020-01-15 tracey }
1098 2c251c14 2020-01-15 tracey
1099 2c251c14 2020-01-15 tracey closedir(d);
1100 2c251c14 2020-01-15 tracey return error;
1101 2c251c14 2020-01-15 tracey }
1102 2c251c14 2020-01-15 tracey
1103 2c251c14 2020-01-15 tracey static const struct got_error *
1104 54415d85 2020-01-15 tracey gw_parse_querystring(struct gw_trans *gw_trans)
1105 2c251c14 2020-01-15 tracey {
1106 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
1107 2c251c14 2020-01-15 tracey struct kpair *p;
1108 2c251c14 2020-01-15 tracey struct gw_query_action *action = NULL;
1109 2c251c14 2020-01-15 tracey unsigned int i;
1110 2c251c14 2020-01-15 tracey
1111 2c251c14 2020-01-15 tracey if (gw_trans->gw_req->fieldnmap[0]) {
1112 2c251c14 2020-01-15 tracey error = got_error_from_errno("bad parse");
1113 2c251c14 2020-01-15 tracey return error;
1114 2c251c14 2020-01-15 tracey } else if ((p = gw_trans->gw_req->fieldmap[KEY_PATH])) {
1115 2c251c14 2020-01-15 tracey /* define gw_trans->repo_path */
1116 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->repo_name, "%s", p->parsed.s) == -1)
1117 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
1118 2c251c14 2020-01-15 tracey
1119 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->repo_path, "%s/%s",
1120 88d59c36 2020-01-29 stsp gw_trans->gw_conf->got_repos_path, p->parsed.s) == -1)
1121 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
1122 2c251c14 2020-01-15 tracey
1123 2c251c14 2020-01-15 tracey /* get action and set function */
1124 2c251c14 2020-01-15 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_ACTION]))
1125 2c251c14 2020-01-15 tracey for (i = 0; i < nitems(gw_query_funcs); i++) {
1126 2c251c14 2020-01-15 tracey action = &gw_query_funcs[i];
1127 2c251c14 2020-01-15 tracey if (action->func_name == NULL)
1128 2c251c14 2020-01-15 tracey continue;
1129 077f6c5a 2020-01-15 tracey
1130 2c251c14 2020-01-15 tracey if (strcmp(action->func_name,
1131 2c251c14 2020-01-15 tracey p->parsed.s) == 0) {
1132 2c251c14 2020-01-15 tracey gw_trans->action = i;
1133 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->action_name,
1134 88d59c36 2020-01-29 stsp "%s", action->func_name) == -1)
1135 2c251c14 2020-01-15 tracey return
1136 b772de24 2020-01-15 tracey got_error_from_errno(
1137 2c251c14 2020-01-15 tracey "asprintf");
1138 2c251c14 2020-01-15 tracey
1139 2c251c14 2020-01-15 tracey break;
1140 2c251c14 2020-01-15 tracey }
1141 2c251c14 2020-01-15 tracey
1142 2c251c14 2020-01-15 tracey action = NULL;
1143 2c251c14 2020-01-15 tracey }
1144 ec46ccd7 2020-01-15 tracey
1145 ec46ccd7 2020-01-15 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_COMMIT_ID]))
1146 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->commit, "%s",
1147 88d59c36 2020-01-29 stsp p->parsed.s) == -1)
1148 ec46ccd7 2020-01-15 tracey return got_error_from_errno("asprintf");
1149 2c251c14 2020-01-15 tracey
1150 2c251c14 2020-01-15 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_FILE]))
1151 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->repo_file, "%s",
1152 88d59c36 2020-01-29 stsp p->parsed.s) == -1)
1153 8087c3c5 2020-01-15 tracey return got_error_from_errno("asprintf");
1154 8087c3c5 2020-01-15 tracey
1155 ec46ccd7 2020-01-15 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_FOLDER]))
1156 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->repo_folder, "%s",
1157 88d59c36 2020-01-29 stsp p->parsed.s) == -1)
1158 ec46ccd7 2020-01-15 tracey return got_error_from_errno("asprintf");
1159 ec46ccd7 2020-01-15 tracey
1160 8087c3c5 2020-01-15 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_HEADREF]))
1161 88d59c36 2020-01-29 stsp if (asprintf(&gw_trans->headref, "%s",
1162 88d59c36 2020-01-29 stsp p->parsed.s) == -1)
1163 2c251c14 2020-01-15 tracey return got_error_from_errno("asprintf");
1164 2c251c14 2020-01-15 tracey
1165 2c251c14 2020-01-15 tracey if (action == NULL) {
1166 2c251c14 2020-01-15 tracey error = got_error_from_errno("invalid action");
1167 2c251c14 2020-01-15 tracey return error;
1168 2c251c14 2020-01-15 tracey }
1169 46b9c89b 2020-01-15 tracey if ((gw_trans->gw_dir =
1170 46b9c89b 2020-01-15 tracey gw_init_gw_dir(gw_trans->repo_name)) == NULL)
1171 46b9c89b 2020-01-15 tracey return got_error_from_errno("gw_dir malloc");
1172 46b9c89b 2020-01-15 tracey
1173 46b9c89b 2020-01-15 tracey error = gw_load_got_path(gw_trans, gw_trans->gw_dir);
1174 46b9c89b 2020-01-15 tracey if (error)
1175 46b9c89b 2020-01-15 tracey return error;
1176 2c251c14 2020-01-15 tracey } else
1177 2c251c14 2020-01-15 tracey gw_trans->action = GW_INDEX;
1178 2c251c14 2020-01-15 tracey
1179 2c251c14 2020-01-15 tracey if ((p = gw_trans->gw_req->fieldmap[KEY_PAGE]))
1180 2c251c14 2020-01-15 tracey gw_trans->page = p->parsed.i;
1181 2c251c14 2020-01-15 tracey
1182 b27da801 2020-01-29 tracey if (gw_trans->action == GW_BLOB)
1183 b27da801 2020-01-29 tracey gw_trans->mime = KMIME_TEXT_PLAIN;
1184 2c251c14 2020-01-15 tracey
1185 2c251c14 2020-01-15 tracey return error;
1186 2c251c14 2020-01-15 tracey }
1187 2c251c14 2020-01-15 tracey
1188 2c251c14 2020-01-15 tracey static struct gw_dir *
1189 2c251c14 2020-01-15 tracey gw_init_gw_dir(char *dir)
1190 2c251c14 2020-01-15 tracey {
1191 2c251c14 2020-01-15 tracey struct gw_dir *gw_dir;
1192 2c251c14 2020-01-15 tracey
1193 2c251c14 2020-01-15 tracey if ((gw_dir = malloc(sizeof(*gw_dir))) == NULL)
1194 2c251c14 2020-01-15 tracey return NULL;
1195 2c251c14 2020-01-15 tracey
1196 88d59c36 2020-01-29 stsp if (asprintf(&gw_dir->name, "%s", dir) == -1)
1197 2c251c14 2020-01-15 tracey return NULL;
1198 2c251c14 2020-01-15 tracey
1199 2c251c14 2020-01-15 tracey return gw_dir;
1200 474370cb 2020-01-15 tracey }
1201 474370cb 2020-01-15 tracey
1202 c25c2314 2020-01-28 stsp static const struct got_error *
1203 54415d85 2020-01-15 tracey gw_display_open(struct gw_trans *gw_trans, enum khttp code, enum kmime mime)
1204 2c251c14 2020-01-15 tracey {
1205 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
1206 c25c2314 2020-01-28 stsp
1207 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, kresps[KRESP_ALLOW], "GET");
1208 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
1209 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
1210 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, kresps[KRESP_STATUS], "%s",
1211 2c251c14 2020-01-15 tracey khttps[code]);
1212 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
1213 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
1214 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, kresps[KRESP_CONTENT_TYPE], "%s",
1215 2c251c14 2020-01-15 tracey kmimetypes[mime]);
1216 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
1217 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
1218 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, "X-Content-Type-Options", "nosniff");
1219 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
1220 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
1221 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, "X-Frame-Options", "DENY");
1222 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
1223 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
1224 c25c2314 2020-01-28 stsp kerr = khttp_head(gw_trans->gw_req, "X-XSS-Protection", "1; mode=block");
1225 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK)
1226 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
1227 c25c2314 2020-01-28 stsp
1228 c25c2314 2020-01-28 stsp kerr = khttp_body(gw_trans->gw_req);
1229 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
1230 2c251c14 2020-01-15 tracey }
1231 2c251c14 2020-01-15 tracey
1232 c25c2314 2020-01-28 stsp static const struct got_error *
1233 6d8d8a26 2020-01-29 stsp gw_display_index(struct gw_trans *gw_trans)
1234 2c251c14 2020-01-15 tracey {
1235 4bec7539 2020-01-29 stsp const struct got_error *error;
1236 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
1237 c25c2314 2020-01-28 stsp
1238 4bec7539 2020-01-29 stsp error = gw_display_open(gw_trans, KHTTP_200, gw_trans->mime);
1239 4bec7539 2020-01-29 stsp if (error)
1240 4bec7539 2020-01-29 stsp return error;
1241 4bec7539 2020-01-29 stsp
1242 c25c2314 2020-01-28 stsp kerr = khtml_open(gw_trans->gw_html_req, gw_trans->gw_req, 0);
1243 6d8d8a26 2020-01-29 stsp if (kerr)
1244 6d8d8a26 2020-01-29 stsp return gw_kcgi_error(kerr);
1245 2c251c14 2020-01-15 tracey
1246 6d8d8a26 2020-01-29 stsp kerr = khttp_template(gw_trans->gw_req, gw_trans->gw_tmpl,
1247 6d8d8a26 2020-01-29 stsp gw_query_funcs[gw_trans->action].template);
1248 7a9bfbff 2020-01-29 stsp if (kerr != KCGI_OK) {
1249 7a9bfbff 2020-01-29 stsp khtml_close(gw_trans->gw_html_req);
1250 c25c2314 2020-01-28 stsp return gw_kcgi_error(kerr);
1251 7a9bfbff 2020-01-29 stsp }
1252 2c251c14 2020-01-15 tracey
1253 7a9bfbff 2020-01-29 stsp return gw_kcgi_error(khtml_close(gw_trans->gw_html_req));
1254 2c251c14 2020-01-15 tracey }
1255 2c251c14 2020-01-15 tracey
1256 6d8d8a26 2020-01-29 stsp static void
1257 6d8d8a26 2020-01-29 stsp gw_display_error(struct gw_trans *gw_trans, const struct got_error *err)
1258 6d8d8a26 2020-01-29 stsp {
1259 6d8d8a26 2020-01-29 stsp if (gw_display_open(gw_trans, KHTTP_200, gw_trans->mime) != NULL)
1260 6d8d8a26 2020-01-29 stsp return;
1261 6d8d8a26 2020-01-29 stsp
1262 6d8d8a26 2020-01-29 stsp if (khtml_open(gw_trans->gw_html_req, gw_trans->gw_req, 0) != KCGI_OK)
1263 6d8d8a26 2020-01-29 stsp return;
1264 6d8d8a26 2020-01-29 stsp
1265 6d8d8a26 2020-01-29 stsp khttp_puts(gw_trans->gw_req, err->msg);
1266 6d8d8a26 2020-01-29 stsp khtml_close(gw_trans->gw_html_req);
1267 6d8d8a26 2020-01-29 stsp }
1268 6d8d8a26 2020-01-29 stsp
1269 2c251c14 2020-01-15 tracey static int
1270 2c251c14 2020-01-15 tracey gw_template(size_t key, void *arg)
1271 2c251c14 2020-01-15 tracey {
1272 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
1273 54415d85 2020-01-15 tracey struct gw_trans *gw_trans = arg;
1274 2c251c14 2020-01-15 tracey char *gw_got_link, *gw_site_link;
1275 2c251c14 2020-01-15 tracey char *site_owner_name, *site_owner_name_h;
1276 2c251c14 2020-01-15 tracey
1277 2c251c14 2020-01-15 tracey switch (key) {
1278 2c251c14 2020-01-15 tracey case (TEMPL_HEAD):
1279 2c251c14 2020-01-15 tracey khttp_puts(gw_trans->gw_req, head);
1280 2c251c14 2020-01-15 tracey break;
1281 2c251c14 2020-01-15 tracey case(TEMPL_HEADER):
1282 2c251c14 2020-01-15 tracey gw_got_link = gw_get_got_link(gw_trans);
1283 2c251c14 2020-01-15 tracey if (gw_got_link != NULL)
1284 2c251c14 2020-01-15 tracey khttp_puts(gw_trans->gw_req, gw_got_link);
1285 2c251c14 2020-01-15 tracey
1286 2c251c14 2020-01-15 tracey free(gw_got_link);
1287 2c251c14 2020-01-15 tracey break;
1288 2c251c14 2020-01-15 tracey case (TEMPL_SITEPATH):
1289 2c251c14 2020-01-15 tracey gw_site_link = gw_get_site_link(gw_trans);
1290 2c251c14 2020-01-15 tracey if (gw_site_link != NULL)
1291 2c251c14 2020-01-15 tracey khttp_puts(gw_trans->gw_req, gw_site_link);
1292 2c251c14 2020-01-15 tracey
1293 2c251c14 2020-01-15 tracey free(gw_site_link);
1294 2c251c14 2020-01-15 tracey break;
1295 2c251c14 2020-01-15 tracey case(TEMPL_TITLE):
1296 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_site_name != NULL)
1297 2c251c14 2020-01-15 tracey khtml_puts(gw_trans->gw_html_req,
1298 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_site_name);
1299 2c251c14 2020-01-15 tracey
1300 2c251c14 2020-01-15 tracey break;
1301 2c251c14 2020-01-15 tracey case (TEMPL_SEARCH):
1302 2c251c14 2020-01-15 tracey khttp_puts(gw_trans->gw_req, search);
1303 2c251c14 2020-01-15 tracey break;
1304 2c251c14 2020-01-15 tracey case(TEMPL_SITEOWNER):
1305 2c251c14 2020-01-15 tracey if (gw_trans->gw_conf->got_site_owner != NULL &&
1306 2c251c14 2020-01-15 tracey gw_trans->gw_conf->got_show_site_owner) {
1307 2c251c14 2020-01-15 tracey site_owner_name =
1308 2c251c14 2020-01-15 tracey gw_html_escape(gw_trans->gw_conf->got_site_owner);
1309 88d59c36 2020-01-29 stsp if (asprintf(&site_owner_name_h, site_owner,
1310 88d59c36 2020-01-29 stsp site_owner_name) == -1)
1311 2c251c14 2020-01-15 tracey return 0;
1312 2c251c14 2020-01-15 tracey
1313 2c251c14 2020-01-15 tracey khttp_puts(gw_trans->gw_req, site_owner_name_h);
1314 2c251c14 2020-01-15 tracey free(site_owner_name);
1315 2c251c14 2020-01-15 tracey free(site_owner_name_h);
1316 2c251c14 2020-01-15 tracey }
1317 2c251c14 2020-01-15 tracey break;
1318 2c251c14 2020-01-15 tracey case(TEMPL_CONTENT):
1319 2c251c14 2020-01-15 tracey error = gw_query_funcs[gw_trans->action].func_main(gw_trans);
1320 2c251c14 2020-01-15 tracey if (error)
1321 2c251c14 2020-01-15 tracey khttp_puts(gw_trans->gw_req, error->msg);
1322 2c251c14 2020-01-15 tracey break;
1323 2c251c14 2020-01-15 tracey default:
1324 2c251c14 2020-01-15 tracey return 0;
1325 2c251c14 2020-01-15 tracey }
1326 2c251c14 2020-01-15 tracey return 1;
1327 2c251c14 2020-01-15 tracey }
1328 2c251c14 2020-01-15 tracey
1329 2c251c14 2020-01-15 tracey static char *
1330 f2f46662 2020-01-23 tracey gw_gen_commit_header(char *str1, char *str2)
1331 f2f46662 2020-01-23 tracey {
1332 f2f46662 2020-01-23 tracey char *return_html = NULL, *ref_str = NULL;
1333 f2f46662 2020-01-23 tracey
1334 f2f46662 2020-01-23 tracey if (strcmp(str2, "") != 0) {
1335 88d59c36 2020-01-29 stsp if (asprintf(&ref_str, "(%s)", str2) == -1) {
1336 f2f46662 2020-01-23 tracey return_html = strdup("");
1337 f2f46662 2020-01-23 tracey return return_html;
1338 f2f46662 2020-01-23 tracey }
1339 f2f46662 2020-01-23 tracey } else
1340 f2f46662 2020-01-23 tracey ref_str = strdup("");
1341 f2f46662 2020-01-23 tracey
1342 f2f46662 2020-01-23 tracey
1343 88d59c36 2020-01-29 stsp if (asprintf(&return_html, header_commit_html, str1, ref_str) == -1)
1344 f2f46662 2020-01-23 tracey return_html = strdup("");
1345 f2f46662 2020-01-23 tracey
1346 f2f46662 2020-01-23 tracey free(ref_str);
1347 f2f46662 2020-01-23 tracey return return_html;
1348 f2f46662 2020-01-23 tracey }
1349 f2f46662 2020-01-23 tracey
1350 f2f46662 2020-01-23 tracey static char *
1351 f2f46662 2020-01-23 tracey gw_gen_diff_header(char *str1, char *str2)
1352 f2f46662 2020-01-23 tracey {
1353 f2f46662 2020-01-23 tracey char *return_html = NULL;
1354 f2f46662 2020-01-23 tracey
1355 88d59c36 2020-01-29 stsp if (asprintf(&return_html, header_diff_html, str1, str2) == -1)
1356 f2f46662 2020-01-23 tracey return_html = strdup("");
1357 f2f46662 2020-01-23 tracey
1358 f2f46662 2020-01-23 tracey return return_html;
1359 f2f46662 2020-01-23 tracey }
1360 f2f46662 2020-01-23 tracey
1361 f2f46662 2020-01-23 tracey static char *
1362 f2f46662 2020-01-23 tracey gw_gen_author_header(char *str)
1363 f2f46662 2020-01-23 tracey {
1364 f2f46662 2020-01-23 tracey char *return_html = NULL;
1365 f2f46662 2020-01-23 tracey
1366 88d59c36 2020-01-29 stsp if (asprintf(&return_html, header_author_html, str) == -1)
1367 f2f46662 2020-01-23 tracey return_html = strdup("");
1368 f2f46662 2020-01-23 tracey
1369 f2f46662 2020-01-23 tracey return return_html;
1370 f2f46662 2020-01-23 tracey }
1371 f2f46662 2020-01-23 tracey
1372 f2f46662 2020-01-23 tracey static char *
1373 f2f46662 2020-01-23 tracey gw_gen_committer_header(char *str)
1374 f2f46662 2020-01-23 tracey {
1375 f2f46662 2020-01-23 tracey char *return_html = NULL;
1376 f2f46662 2020-01-23 tracey
1377 88d59c36 2020-01-29 stsp if (asprintf(&return_html, header_committer_html, str) == -1)
1378 f2f46662 2020-01-23 tracey return_html = strdup("");
1379 f2f46662 2020-01-23 tracey
1380 f2f46662 2020-01-23 tracey return return_html;
1381 f2f46662 2020-01-23 tracey }
1382 f2f46662 2020-01-23 tracey
1383 f2f46662 2020-01-23 tracey static char *
1384 f2f46662 2020-01-23 tracey gw_gen_age_header(char *str)
1385 f2f46662 2020-01-23 tracey {
1386 f2f46662 2020-01-23 tracey char *return_html = NULL;
1387 f2f46662 2020-01-23 tracey
1388 88d59c36 2020-01-29 stsp if (asprintf(&return_html, header_age_html, str) == -1)
1389 f2f46662 2020-01-23 tracey return_html = strdup("");
1390 f2f46662 2020-01-23 tracey
1391 f2f46662 2020-01-23 tracey return return_html;
1392 f2f46662 2020-01-23 tracey }
1393 f2f46662 2020-01-23 tracey
1394 f2f46662 2020-01-23 tracey static char *
1395 f2f46662 2020-01-23 tracey gw_gen_commit_msg_header(char *str)
1396 f2f46662 2020-01-23 tracey {
1397 f2f46662 2020-01-23 tracey char *return_html = NULL;
1398 f2f46662 2020-01-23 tracey
1399 88d59c36 2020-01-29 stsp if (asprintf(&return_html, header_commit_msg_html, str) == -1)
1400 f2f46662 2020-01-23 tracey return_html = strdup("");
1401 f2f46662 2020-01-23 tracey
1402 f2f46662 2020-01-23 tracey return return_html;
1403 f2f46662 2020-01-23 tracey }
1404 f2f46662 2020-01-23 tracey
1405 f2f46662 2020-01-23 tracey static char *
1406 f2f46662 2020-01-23 tracey gw_gen_tree_header(char *str)
1407 f2f46662 2020-01-23 tracey {
1408 f2f46662 2020-01-23 tracey char *return_html = NULL;
1409 f2f46662 2020-01-23 tracey
1410 88d59c36 2020-01-29 stsp if (asprintf(&return_html, header_tree_html, str) == -1)
1411 f2f46662 2020-01-23 tracey return_html = strdup("");
1412 f2f46662 2020-01-23 tracey
1413 f2f46662 2020-01-23 tracey return return_html;
1414 f2f46662 2020-01-23 tracey }
1415 f2f46662 2020-01-23 tracey
1416 f2f46662 2020-01-23 tracey static char *
1417 54415d85 2020-01-15 tracey gw_get_repo_description(struct gw_trans *gw_trans, char *dir)
1418 2c251c14 2020-01-15 tracey {
1419 2c251c14 2020-01-15 tracey FILE *f;
1420 2c251c14 2020-01-15 tracey char *description = NULL, *d_file = NULL;
1421 2c251c14 2020-01-15 tracey unsigned int len;
1422 2c251c14 2020-01-15 tracey
1423 0b20762b 2020-01-29 stsp if (gw_trans->gw_conf->got_show_repo_description == 0)
1424 2c251c14 2020-01-15 tracey goto err;
1425 2c251c14 2020-01-15 tracey
1426 88d59c36 2020-01-29 stsp if (asprintf(&d_file, "%s/description", dir) == -1)
1427 2c251c14 2020-01-15 tracey goto err;
1428 2c251c14 2020-01-15 tracey
1429 2c251c14 2020-01-15 tracey if ((f = fopen(d_file, "r")) == NULL)
1430 2c251c14 2020-01-15 tracey goto err;
1431 2c251c14 2020-01-15 tracey
1432 2c251c14 2020-01-15 tracey fseek(f, 0, SEEK_END);
1433 2c251c14 2020-01-15 tracey len = ftell(f) + 1;
1434 2c251c14 2020-01-15 tracey fseek(f, 0, SEEK_SET);
1435 2c251c14 2020-01-15 tracey if ((description = calloc(len, sizeof(char *))) == NULL)
1436 2c251c14 2020-01-15 tracey goto err;
1437 2c251c14 2020-01-15 tracey
1438 2c251c14 2020-01-15 tracey fread(description, 1, len, f);
1439 2c251c14 2020-01-15 tracey fclose(f);
1440 2c251c14 2020-01-15 tracey free(d_file);
1441 2c251c14 2020-01-15 tracey return description;
1442 2c251c14 2020-01-15 tracey err:
1443 4b60fece 2020-01-29 stsp return strdup("");
1444 2c251c14 2020-01-15 tracey }
1445 2c251c14 2020-01-15 tracey
1446 2c251c14 2020-01-15 tracey static char *
1447 474370cb 2020-01-15 tracey gw_get_time_str(time_t committer_time, int ref_tm)
1448 474370cb 2020-01-15 tracey {
1449 474370cb 2020-01-15 tracey struct tm tm;
1450 474370cb 2020-01-15 tracey time_t diff_time;
1451 474370cb 2020-01-15 tracey char *years = "years ago", *months = "months ago";
1452 474370cb 2020-01-15 tracey char *weeks = "weeks ago", *days = "days ago", *hours = "hours ago";
1453 474370cb 2020-01-15 tracey char *minutes = "minutes ago", *seconds = "seconds ago";
1454 474370cb 2020-01-15 tracey char *now = "right now";
1455 474370cb 2020-01-15 tracey char *repo_age, *s;
1456 6c6c85af 2020-01-15 tracey char datebuf[29];
1457 474370cb 2020-01-15 tracey
1458 474370cb 2020-01-15 tracey switch (ref_tm) {
1459 474370cb 2020-01-15 tracey case TM_DIFF:
1460 474370cb 2020-01-15 tracey diff_time = time(NULL) - committer_time;
1461 474370cb 2020-01-15 tracey if (diff_time > 60 * 60 * 24 * 365 * 2) {
1462 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%lld %s",
1463 88d59c36 2020-01-29 stsp (diff_time / 60 / 60 / 24 / 365), years) == -1)
1464 474370cb 2020-01-15 tracey return NULL;
1465 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 60 * 24 * (365 / 12) * 2) {
1466 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%lld %s",
1467 474370cb 2020-01-15 tracey (diff_time / 60 / 60 / 24 / (365 / 12)),
1468 88d59c36 2020-01-29 stsp months) == -1)
1469 474370cb 2020-01-15 tracey return NULL;
1470 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 60 * 24 * 7 * 2) {
1471 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%lld %s",
1472 88d59c36 2020-01-29 stsp (diff_time / 60 / 60 / 24 / 7), weeks) == -1)
1473 474370cb 2020-01-15 tracey return NULL;
1474 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 60 * 24 * 2) {
1475 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%lld %s",
1476 88d59c36 2020-01-29 stsp (diff_time / 60 / 60 / 24), days) == -1)
1477 474370cb 2020-01-15 tracey return NULL;
1478 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 60 * 2) {
1479 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%lld %s",
1480 88d59c36 2020-01-29 stsp (diff_time / 60 / 60), hours) == -1)
1481 474370cb 2020-01-15 tracey return NULL;
1482 474370cb 2020-01-15 tracey } else if (diff_time > 60 * 2) {
1483 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%lld %s", (diff_time / 60),
1484 88d59c36 2020-01-29 stsp minutes) == -1)
1485 474370cb 2020-01-15 tracey return NULL;
1486 474370cb 2020-01-15 tracey } else if (diff_time > 2) {
1487 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%lld %s", diff_time,
1488 88d59c36 2020-01-29 stsp seconds) == -1)
1489 474370cb 2020-01-15 tracey return NULL;
1490 474370cb 2020-01-15 tracey } else {
1491 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%s", now) == -1)
1492 474370cb 2020-01-15 tracey return NULL;
1493 474370cb 2020-01-15 tracey }
1494 474370cb 2020-01-15 tracey break;
1495 474370cb 2020-01-15 tracey case TM_LONG:
1496 474370cb 2020-01-15 tracey if (gmtime_r(&committer_time, &tm) == NULL)
1497 474370cb 2020-01-15 tracey return NULL;
1498 474370cb 2020-01-15 tracey
1499 474370cb 2020-01-15 tracey s = asctime_r(&tm, datebuf);
1500 474370cb 2020-01-15 tracey if (s == NULL)
1501 474370cb 2020-01-15 tracey return NULL;
1502 474370cb 2020-01-15 tracey
1503 88d59c36 2020-01-29 stsp if (asprintf(&repo_age, "%s UTC", datebuf) == -1)
1504 474370cb 2020-01-15 tracey return NULL;
1505 474370cb 2020-01-15 tracey break;
1506 474370cb 2020-01-15 tracey }
1507 474370cb 2020-01-15 tracey return repo_age;
1508 474370cb 2020-01-15 tracey }
1509 474370cb 2020-01-15 tracey
1510 d126c1b7 2020-01-29 stsp static const struct got_error *
1511 d126c1b7 2020-01-29 stsp gw_get_repo_age(char **repo_age, struct gw_trans *gw_trans, char *dir,
1512 d126c1b7 2020-01-29 stsp char *repo_ref, int ref_tm)
1513 2c251c14 2020-01-15 tracey {
1514 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
1515 2c251c14 2020-01-15 tracey struct got_object_id *id = NULL;
1516 2c251c14 2020-01-15 tracey struct got_repository *repo = NULL;
1517 2c251c14 2020-01-15 tracey struct got_commit_object *commit = NULL;
1518 2c251c14 2020-01-15 tracey struct got_reflist_head refs;
1519 2c251c14 2020-01-15 tracey struct got_reflist_entry *re;
1520 2c251c14 2020-01-15 tracey struct got_reference *head_ref;
1521 87f9ebf5 2020-01-15 tracey int is_head = 0;
1522 474370cb 2020-01-15 tracey time_t committer_time = 0, cmp_time = 0;
1523 87f9ebf5 2020-01-15 tracey const char *refname;
1524 a0f36e03 2020-01-28 stsp
1525 d126c1b7 2020-01-29 stsp *repo_age = NULL;
1526 a0f36e03 2020-01-28 stsp SIMPLEQ_INIT(&refs);
1527 387a29ba 2020-01-15 tracey
1528 387a29ba 2020-01-15 tracey if (repo_ref == NULL)
1529 387a29ba 2020-01-15 tracey return NULL;
1530 87f9ebf5 2020-01-15 tracey
1531 87f9ebf5 2020-01-15 tracey if (strncmp(repo_ref, "refs/heads/", 11) == 0)
1532 87f9ebf5 2020-01-15 tracey is_head = 1;
1533 2c251c14 2020-01-15 tracey
1534 d126c1b7 2020-01-29 stsp if (gw_trans->gw_conf->got_show_repo_age == 0) {
1535 d126c1b7 2020-01-29 stsp *repo_age = strdup("");
1536 d126c1b7 2020-01-29 stsp if (*repo_age == NULL)
1537 d126c1b7 2020-01-29 stsp return got_error_from_errno("strdup");
1538 d126c1b7 2020-01-29 stsp return NULL;
1539 d126c1b7 2020-01-29 stsp }
1540 87f9ebf5 2020-01-15 tracey
1541 2c251c14 2020-01-15 tracey error = got_repo_open(&repo, dir, NULL);
1542 ec46ccd7 2020-01-15 tracey if (error)
1543 d126c1b7 2020-01-29 stsp goto done;
1544 2c251c14 2020-01-15 tracey
1545 87f9ebf5 2020-01-15 tracey if (is_head)
1546 87f9ebf5 2020-01-15 tracey error = got_ref_list(&refs, repo, "refs/heads",
1547 87f9ebf5 2020-01-15 tracey got_ref_cmp_by_name, NULL);
1548 87f9ebf5 2020-01-15 tracey else
1549 87f9ebf5 2020-01-15 tracey error = got_ref_list(&refs, repo, repo_ref,
1550 87f9ebf5 2020-01-15 tracey got_ref_cmp_by_name, NULL);
1551 ec46ccd7 2020-01-15 tracey if (error)
1552 d126c1b7 2020-01-29 stsp goto done;
1553 2c251c14 2020-01-15 tracey
1554 2c251c14 2020-01-15 tracey SIMPLEQ_FOREACH(re, &refs, entry) {
1555 87f9ebf5 2020-01-15 tracey if (is_head)
1556 87f9ebf5 2020-01-15 tracey refname = strdup(repo_ref);
1557 87f9ebf5 2020-01-15 tracey else
1558 87f9ebf5 2020-01-15 tracey refname = got_ref_get_name(re->ref);
1559 2c251c14 2020-01-15 tracey error = got_ref_open(&head_ref, repo, refname, 0);
1560 ec46ccd7 2020-01-15 tracey if (error)
1561 d126c1b7 2020-01-29 stsp goto done;
1562 2c251c14 2020-01-15 tracey
1563 2c251c14 2020-01-15 tracey error = got_ref_resolve(&id, repo, head_ref);
1564 2c251c14 2020-01-15 tracey got_ref_close(head_ref);
1565 ec46ccd7 2020-01-15 tracey if (error)
1566 d126c1b7 2020-01-29 stsp goto done;
1567 2c251c14 2020-01-15 tracey
1568 2c251c14 2020-01-15 tracey error = got_object_open_as_commit(&commit, repo, id);
1569 ec46ccd7 2020-01-15 tracey if (error)
1570 d126c1b7 2020-01-29 stsp goto done;
1571 2c251c14 2020-01-15 tracey
1572 2c251c14 2020-01-15 tracey committer_time =
1573 2c251c14 2020-01-15 tracey got_object_commit_get_committer_time(commit);
1574 2c251c14 2020-01-15 tracey
1575 387a29ba 2020-01-15 tracey if (cmp_time < committer_time)
1576 2c251c14 2020-01-15 tracey cmp_time = committer_time;
1577 2c251c14 2020-01-15 tracey }
1578 2c251c14 2020-01-15 tracey
1579 474370cb 2020-01-15 tracey if (cmp_time != 0) {
1580 2c251c14 2020-01-15 tracey committer_time = cmp_time;
1581 d126c1b7 2020-01-29 stsp *repo_age = gw_get_time_str(committer_time, ref_tm);
1582 d126c1b7 2020-01-29 stsp } else {
1583 d126c1b7 2020-01-29 stsp *repo_age = strdup("");
1584 d126c1b7 2020-01-29 stsp if (*repo_age == NULL)
1585 d126c1b7 2020-01-29 stsp error = got_error_from_errno("strdup");
1586 d126c1b7 2020-01-29 stsp }
1587 d126c1b7 2020-01-29 stsp done:
1588 2c251c14 2020-01-15 tracey got_ref_list_free(&refs);
1589 2c251c14 2020-01-15 tracey free(id);
1590 d126c1b7 2020-01-29 stsp return error;
1591 ec46ccd7 2020-01-15 tracey }
1592 ec46ccd7 2020-01-15 tracey
1593 ec46ccd7 2020-01-15 tracey static char *
1594 f2f46662 2020-01-23 tracey gw_get_diff(struct gw_trans *gw_trans, struct gw_header *header)
1595 ec46ccd7 2020-01-15 tracey {
1596 ec46ccd7 2020-01-15 tracey const struct got_error *error;
1597 ec46ccd7 2020-01-15 tracey FILE *f = NULL;
1598 ec46ccd7 2020-01-15 tracey struct got_object_id *id1 = NULL, *id2 = NULL;
1599 ec46ccd7 2020-01-15 tracey struct buf *diffbuf = NULL;
1600 e46f587c 2020-01-29 tracey char *label1 = NULL, *label2 = NULL, *diff_html = NULL, *buf = NULL;
1601 e46f587c 2020-01-29 tracey char *buf_color = NULL, *n_buf = NULL, *newline = NULL;
1602 05ce9a79 2020-01-24 tracey int obj_type;
1603 ec46ccd7 2020-01-15 tracey size_t newsize;
1604 ec46ccd7 2020-01-15 tracey
1605 ec46ccd7 2020-01-15 tracey f = got_opentemp();
1606 ec46ccd7 2020-01-15 tracey if (f == NULL)
1607 ec46ccd7 2020-01-15 tracey return NULL;
1608 ec46ccd7 2020-01-15 tracey
1609 ec46ccd7 2020-01-15 tracey error = buf_alloc(&diffbuf, 0);
1610 ec46ccd7 2020-01-15 tracey if (error)
1611 ec46ccd7 2020-01-15 tracey return NULL;
1612 ec46ccd7 2020-01-15 tracey
1613 90f16cb8 2020-01-24 tracey error = got_repo_open(&header->repo, gw_trans->repo_path, NULL);
1614 ec46ccd7 2020-01-15 tracey if (error)
1615 ec46ccd7 2020-01-15 tracey goto done;
1616 ec46ccd7 2020-01-15 tracey
1617 05ce9a79 2020-01-24 tracey if (strncmp(header->parent_id, "/dev/null", 9) != 0) {
1618 05ce9a79 2020-01-24 tracey error = got_repo_match_object_id(&id1, &label1,
1619 05ce9a79 2020-01-24 tracey header->parent_id, GOT_OBJ_TYPE_ANY, 1, header->repo);
1620 05ce9a79 2020-01-24 tracey if (error)
1621 05ce9a79 2020-01-24 tracey goto done;
1622 05ce9a79 2020-01-24 tracey }
1623 ec46ccd7 2020-01-15 tracey
1624 90f16cb8 2020-01-24 tracey error = got_repo_match_object_id(&id2, &label2,
1625 2ac037ec 2020-01-24 tracey header->commit_id, GOT_OBJ_TYPE_ANY, 1, header->repo);
1626 90f16cb8 2020-01-24 tracey if (error)
1627 90f16cb8 2020-01-24 tracey goto done;
1628 ec46ccd7 2020-01-15 tracey
1629 05ce9a79 2020-01-24 tracey error = got_object_get_type(&obj_type, header->repo, id2);
1630 90f16cb8 2020-01-24 tracey if (error)
1631 90f16cb8 2020-01-24 tracey goto done;
1632 05ce9a79 2020-01-24 tracey switch (obj_type) {
1633 ec46ccd7 2020-01-15 tracey case GOT_OBJ_TYPE_BLOB:
1634 90f16cb8 2020-01-24 tracey error = got_diff_objects_as_blobs(id1, id2, NULL, NULL, 3, 0,
1635 90f16cb8 2020-01-24 tracey header->repo, f);
1636 ec46ccd7 2020-01-15 tracey break;
1637 ec46ccd7 2020-01-15 tracey case GOT_OBJ_TYPE_TREE:
1638 90f16cb8 2020-01-24 tracey error = got_diff_objects_as_trees(id1, id2, "", "", 3, 0,
1639 90f16cb8 2020-01-24 tracey header->repo, f);
1640 ec46ccd7 2020-01-15 tracey break;
1641 ec46ccd7 2020-01-15 tracey case GOT_OBJ_TYPE_COMMIT:
1642 90f16cb8 2020-01-24 tracey error = got_diff_objects_as_commits(id1, id2, 3, 0,
1643 90f16cb8 2020-01-24 tracey header->repo, f);
1644 ec46ccd7 2020-01-15 tracey break;
1645 ec46ccd7 2020-01-15 tracey default:
1646 ec46ccd7 2020-01-15 tracey error = got_error(GOT_ERR_OBJ_TYPE);
1647 ec46ccd7 2020-01-15 tracey }
1648 ec46ccd7 2020-01-15 tracey
1649 ec46ccd7 2020-01-15 tracey if ((buf = calloc(128, sizeof(char *))) == NULL)
1650 ec46ccd7 2020-01-15 tracey goto done;
1651 ec46ccd7 2020-01-15 tracey
1652 ec46ccd7 2020-01-15 tracey fseek(f, 0, SEEK_SET);
1653 ec46ccd7 2020-01-15 tracey
1654 bfd30182 2020-01-24 tracey while ((fgets(buf, 2048, f)) != NULL) {
1655 65559f29 2020-01-24 tracey n_buf = buf;
1656 65559f29 2020-01-24 tracey while (*n_buf == '\n')
1657 65559f29 2020-01-24 tracey n_buf++;
1658 65559f29 2020-01-24 tracey newline = strchr(n_buf, '\n');
1659 65559f29 2020-01-24 tracey if (newline)
1660 65559f29 2020-01-24 tracey *newline = ' ';
1661 65559f29 2020-01-24 tracey
1662 65559f29 2020-01-24 tracey buf_color = gw_colordiff_line(gw_html_escape(n_buf));
1663 bfd30182 2020-01-24 tracey if (buf_color == NULL)
1664 bfd30182 2020-01-24 tracey continue;
1665 bfd30182 2020-01-24 tracey
1666 ec46ccd7 2020-01-15 tracey error = buf_puts(&newsize, diffbuf, buf_color);
1667 ec46ccd7 2020-01-15 tracey if (error)
1668 ec46ccd7 2020-01-15 tracey return NULL;
1669 ec46ccd7 2020-01-15 tracey
1670 ec46ccd7 2020-01-15 tracey error = buf_puts(&newsize, diffbuf, div_end);
1671 ec46ccd7 2020-01-15 tracey if (error)
1672 ec46ccd7 2020-01-15 tracey return NULL;
1673 ec46ccd7 2020-01-15 tracey }
1674 ec46ccd7 2020-01-15 tracey
1675 ec46ccd7 2020-01-15 tracey if (buf_len(diffbuf) > 0) {
1676 ec46ccd7 2020-01-15 tracey error = buf_putc(diffbuf, '\0');
1677 ec46ccd7 2020-01-15 tracey diff_html = strdup(buf_get(diffbuf));
1678 ec46ccd7 2020-01-15 tracey }
1679 ec46ccd7 2020-01-15 tracey done:
1680 ec46ccd7 2020-01-15 tracey fclose(f);
1681 ec46ccd7 2020-01-15 tracey free(buf_color);
1682 ec46ccd7 2020-01-15 tracey free(buf);
1683 ec46ccd7 2020-01-15 tracey free(diffbuf);
1684 ec46ccd7 2020-01-15 tracey free(label1);
1685 ec46ccd7 2020-01-15 tracey free(label2);
1686 ec46ccd7 2020-01-15 tracey free(id1);
1687 ec46ccd7 2020-01-15 tracey free(id2);
1688 ec46ccd7 2020-01-15 tracey
1689 ec46ccd7 2020-01-15 tracey if (error)
1690 ec46ccd7 2020-01-15 tracey return NULL;
1691 ec46ccd7 2020-01-15 tracey else
1692 ec46ccd7 2020-01-15 tracey return diff_html;
1693 2c251c14 2020-01-15 tracey }
1694 2c251c14 2020-01-15 tracey
1695 2c251c14 2020-01-15 tracey static char *
1696 54415d85 2020-01-15 tracey gw_get_repo_owner(struct gw_trans *gw_trans, char *dir)
1697 2c251c14 2020-01-15 tracey {
1698 2c251c14 2020-01-15 tracey FILE *f;
1699 2c251c14 2020-01-15 tracey char *owner = NULL, *d_file = NULL;
1700 2c251c14 2020-01-15 tracey char *gotweb = "[gotweb]", *gitweb = "[gitweb]", *gw_owner = "owner";
1701 2c251c14 2020-01-15 tracey char *comp, *pos, *buf;
1702 2c251c14 2020-01-15 tracey unsigned int i;
1703 2c251c14 2020-01-15 tracey
1704 0b20762b 2020-01-29 stsp if (gw_trans->gw_conf->got_show_repo_owner == 0)
1705 2c251c14 2020-01-15 tracey goto err;
1706 2c251c14 2020-01-15 tracey
1707 88d59c36 2020-01-29 stsp if (asprintf(&d_file, "%s/config", dir) == -1)
1708 2c251c14 2020-01-15 tracey goto err;
1709 2c251c14 2020-01-15 tracey
1710 2c251c14 2020-01-15 tracey if ((f = fopen(d_file, "r")) == NULL)
1711 2c251c14 2020-01-15 tracey goto err;
1712 2c251c14 2020-01-15 tracey
1713 6c6c85af 2020-01-15 tracey if ((buf = calloc(128, sizeof(char *))) == NULL)
1714 2c251c14 2020-01-15 tracey goto err;
1715 2c251c14 2020-01-15 tracey
1716 6c6c85af 2020-01-15 tracey while ((fgets(buf, 128, f)) != NULL) {
1717 2c251c14 2020-01-15 tracey if ((pos = strstr(buf, gotweb)) != NULL)
1718 2c251c14 2020-01-15 tracey break;
1719 2c251c14 2020-01-15 tracey
1720 2c251c14 2020-01-15 tracey if ((pos = strstr(buf, gitweb)) != NULL)
1721 2c251c14 2020-01-15 tracey break;
1722 2c251c14 2020-01-15 tracey }
1723 2c251c14 2020-01-15 tracey
1724 2c251c14 2020-01-15 tracey if (pos == NULL)
1725 2c251c14 2020-01-15 tracey goto err;
1726 2c251c14 2020-01-15 tracey
1727 2c251c14 2020-01-15 tracey do {
1728 6c6c85af 2020-01-15 tracey fgets(buf, 128, f);
1729 2c251c14 2020-01-15 tracey } while ((comp = strcasestr(buf, gw_owner)) == NULL);
1730 2c251c14 2020-01-15 tracey
1731 2c251c14 2020-01-15 tracey if (comp == NULL)
1732 2c251c14 2020-01-15 tracey goto err;
1733 2c251c14 2020-01-15 tracey
1734 2c251c14 2020-01-15 tracey if (strncmp(gw_owner, comp, strlen(gw_owner)) != 0)
1735 2c251c14 2020-01-15 tracey goto err;
1736 2c251c14 2020-01-15 tracey
1737 2c251c14 2020-01-15 tracey for (i = 0; i < 2; i++) {
1738 2c251c14 2020-01-15 tracey owner = strsep(&buf, "\"");
1739 2c251c14 2020-01-15 tracey }
1740 2c251c14 2020-01-15 tracey
1741 2c251c14 2020-01-15 tracey if (owner == NULL)
1742 2c251c14 2020-01-15 tracey goto err;
1743 2c251c14 2020-01-15 tracey
1744 2c251c14 2020-01-15 tracey fclose(f);
1745 2c251c14 2020-01-15 tracey free(d_file);
1746 2c251c14 2020-01-15 tracey return owner;
1747 2c251c14 2020-01-15 tracey err:
1748 4b60fece 2020-01-29 stsp return strdup("");
1749 2c251c14 2020-01-15 tracey }
1750 2c251c14 2020-01-15 tracey
1751 2c251c14 2020-01-15 tracey static char *
1752 54415d85 2020-01-15 tracey gw_get_clone_url(struct gw_trans *gw_trans, char *dir)
1753 2c251c14 2020-01-15 tracey {
1754 2c251c14 2020-01-15 tracey FILE *f;
1755 2c251c14 2020-01-15 tracey char *url = NULL, *d_file = NULL;
1756 2c251c14 2020-01-15 tracey unsigned int len;
1757 2c251c14 2020-01-15 tracey
1758 88d59c36 2020-01-29 stsp if (asprintf(&d_file, "%s/cloneurl", dir) == -1)
1759 2c251c14 2020-01-15 tracey return NULL;
1760 2c251c14 2020-01-15 tracey
1761 2c251c14 2020-01-15 tracey if ((f = fopen(d_file, "r")) == NULL)
1762 2c251c14 2020-01-15 tracey return NULL;
1763 2c251c14 2020-01-15 tracey
1764 2c251c14 2020-01-15 tracey fseek(f, 0, SEEK_END);
1765 2c251c14 2020-01-15 tracey len = ftell(f) + 1;
1766 2c251c14 2020-01-15 tracey fseek(f, 0, SEEK_SET);
1767 2c251c14 2020-01-15 tracey
1768 2c251c14 2020-01-15 tracey if ((url = calloc(len, sizeof(char *))) == NULL)
1769 2c251c14 2020-01-15 tracey return NULL;
1770 2c251c14 2020-01-15 tracey
1771 2c251c14 2020-01-15 tracey fread(url, 1, len, f);
1772 2c251c14 2020-01-15 tracey fclose(f);
1773 2c251c14 2020-01-15 tracey free(d_file);
1774 2c251c14 2020-01-15 tracey return url;
1775 8d4d2453 2020-01-15 tracey }
1776 8d4d2453 2020-01-15 tracey
1777 8d4d2453 2020-01-15 tracey static char *
1778 4ff7391f 2020-01-28 tracey gw_get_repo_tags(struct gw_trans *gw_trans, struct gw_header *header, int limit,
1779 4ff7391f 2020-01-28 tracey int tag_type)
1780 8d4d2453 2020-01-15 tracey {
1781 87f9ebf5 2020-01-15 tracey const struct got_error *error = NULL;
1782 87f9ebf5 2020-01-15 tracey struct got_repository *repo = NULL;
1783 87f9ebf5 2020-01-15 tracey struct got_reflist_head refs;
1784 87f9ebf5 2020-01-15 tracey struct got_reflist_entry *re;
1785 e46f587c 2020-01-29 tracey char *tags = NULL, *tag_row = NULL, *tags_navs_disp = NULL;
1786 e46f587c 2020-01-29 tracey char *age = NULL, *newline;
1787 87f9ebf5 2020-01-15 tracey struct buf *diffbuf = NULL;
1788 87f9ebf5 2020-01-15 tracey size_t newsize;
1789 8d4d2453 2020-01-15 tracey
1790 a0f36e03 2020-01-28 stsp SIMPLEQ_INIT(&refs);
1791 a0f36e03 2020-01-28 stsp
1792 6c6c85af 2020-01-15 tracey error = buf_alloc(&diffbuf, 0);
1793 ec46ccd7 2020-01-15 tracey if (error)
1794 6c6c85af 2020-01-15 tracey return NULL;
1795 87f9ebf5 2020-01-15 tracey
1796 87f9ebf5 2020-01-15 tracey error = got_repo_open(&repo, gw_trans->repo_path, NULL);
1797 ec46ccd7 2020-01-15 tracey if (error)
1798 87f9ebf5 2020-01-15 tracey goto done;
1799 87f9ebf5 2020-01-15 tracey
1800 add40c4f 2020-01-15 tracey error = got_ref_list(&refs, repo, "refs/tags", got_ref_cmp_tags, repo);
1801 87f9ebf5 2020-01-15 tracey if (error)
1802 87f9ebf5 2020-01-15 tracey goto done;
1803 87f9ebf5 2020-01-15 tracey
1804 87f9ebf5 2020-01-15 tracey SIMPLEQ_FOREACH(re, &refs, entry) {
1805 87f9ebf5 2020-01-15 tracey const char *refname;
1806 f2f46662 2020-01-23 tracey char *refstr, *tag_commit0, *tag_commit, *id_str;
1807 4ff7391f 2020-01-28 tracey const char *tagger;
1808 87f9ebf5 2020-01-15 tracey time_t tagger_time;
1809 87f9ebf5 2020-01-15 tracey struct got_object_id *id;
1810 87f9ebf5 2020-01-15 tracey struct got_tag_object *tag;
1811 87f9ebf5 2020-01-15 tracey
1812 87f9ebf5 2020-01-15 tracey refname = got_ref_get_name(re->ref);
1813 87f9ebf5 2020-01-15 tracey if (strncmp(refname, "refs/tags/", 10) != 0)
1814 87f9ebf5 2020-01-15 tracey continue;
1815 87f9ebf5 2020-01-15 tracey refname += 10;
1816 87f9ebf5 2020-01-15 tracey refstr = got_ref_to_str(re->ref);
1817 87f9ebf5 2020-01-15 tracey if (refstr == NULL) {
1818 87f9ebf5 2020-01-15 tracey error = got_error_from_errno("got_ref_to_str");
1819 87f9ebf5 2020-01-15 tracey goto done;
1820 87f9ebf5 2020-01-15 tracey }
1821 87f9ebf5 2020-01-15 tracey
1822 87f9ebf5 2020-01-15 tracey error = got_ref_resolve(&id, repo, re->ref);
1823 87f9ebf5 2020-01-15 tracey if (error)
1824 87f9ebf5 2020-01-15 tracey goto done;
1825 87f9ebf5 2020-01-15 tracey error = got_object_open_as_tag(&tag, repo, id);
1826 87f9ebf5 2020-01-15 tracey free(id);
1827 87f9ebf5 2020-01-15 tracey if (error)
1828 87f9ebf5 2020-01-15 tracey goto done;
1829 87f9ebf5 2020-01-15 tracey
1830 4ff7391f 2020-01-28 tracey tagger = got_object_tag_get_tagger(tag);
1831 87f9ebf5 2020-01-15 tracey tagger_time = got_object_tag_get_tagger_time(tag);
1832 87f9ebf5 2020-01-15 tracey
1833 87f9ebf5 2020-01-15 tracey error = got_object_id_str(&id_str,
1834 87f9ebf5 2020-01-15 tracey got_object_tag_get_object_id(tag));
1835 87f9ebf5 2020-01-15 tracey if (error)
1836 87f9ebf5 2020-01-15 tracey goto done;
1837 87f9ebf5 2020-01-15 tracey
1838 f2f46662 2020-01-23 tracey tag_commit0 = strdup(got_object_tag_get_message(tag));
1839 87f9ebf5 2020-01-15 tracey
1840 f2f46662 2020-01-23 tracey if (tag_commit0 == NULL) {
1841 87f9ebf5 2020-01-15 tracey error = got_error_from_errno("strdup");
1842 87f9ebf5 2020-01-15 tracey goto done;
1843 87f9ebf5 2020-01-15 tracey }
1844 87f9ebf5 2020-01-15 tracey
1845 f2f46662 2020-01-23 tracey tag_commit = tag_commit0;
1846 f2f46662 2020-01-23 tracey while (*tag_commit == '\n')
1847 f2f46662 2020-01-23 tracey tag_commit++;
1848 87f9ebf5 2020-01-15 tracey
1849 87f9ebf5 2020-01-15 tracey switch (tag_type) {
1850 87f9ebf5 2020-01-15 tracey case TAGBRIEF:
1851 f2f46662 2020-01-23 tracey newline = strchr(tag_commit, '\n');
1852 87f9ebf5 2020-01-15 tracey if (newline)
1853 87f9ebf5 2020-01-15 tracey *newline = '\0';
1854 87f9ebf5 2020-01-15 tracey
1855 88d59c36 2020-01-29 stsp if (asprintf(&age, "%s", gw_get_time_str(tagger_time,
1856 88d59c36 2020-01-29 stsp TM_DIFF)) == -1) {
1857 87f9ebf5 2020-01-15 tracey error = got_error_from_errno("asprintf");
1858 87f9ebf5 2020-01-15 tracey goto done;
1859 87f9ebf5 2020-01-15 tracey }
1860 87f9ebf5 2020-01-15 tracey
1861 88d59c36 2020-01-29 stsp if (asprintf(&tags_navs_disp, tags_navs,
1862 87f9ebf5 2020-01-15 tracey gw_trans->repo_name, id_str, gw_trans->repo_name,
1863 87f9ebf5 2020-01-15 tracey id_str, gw_trans->repo_name, id_str,
1864 88d59c36 2020-01-29 stsp gw_trans->repo_name, id_str) == -1) {
1865 87f9ebf5 2020-01-15 tracey error = got_error_from_errno("asprintf");
1866 87f9ebf5 2020-01-15 tracey goto done;
1867 87f9ebf5 2020-01-15 tracey }
1868 87f9ebf5 2020-01-15 tracey
1869 88d59c36 2020-01-29 stsp if (asprintf(&tag_row, tags_row, age, refname,
1870 88d59c36 2020-01-29 stsp tag_commit, tags_navs_disp) == -1) {
1871 87f9ebf5 2020-01-15 tracey error = got_error_from_errno("asprintf");
1872 87f9ebf5 2020-01-15 tracey goto done;
1873 87f9ebf5 2020-01-15 tracey }
1874 87f9ebf5 2020-01-15 tracey
1875 87f9ebf5 2020-01-15 tracey free(tags_navs_disp);
1876 87f9ebf5 2020-01-15 tracey break;
1877 87f9ebf5 2020-01-15 tracey case TAGFULL:
1878 88d59c36 2020-01-29 stsp if (asprintf(&age, "%s", gw_get_time_str(tagger_time,
1879 88d59c36 2020-01-29 stsp TM_LONG)) == -1) {
1880 4ff7391f 2020-01-28 tracey error = got_error_from_errno("asprintf");
1881 4ff7391f 2020-01-28 tracey goto done;
1882 4ff7391f 2020-01-28 tracey }
1883 88d59c36 2020-01-29 stsp if (asprintf(&tag_row, tag_info, age,
1884 4ff7391f 2020-01-28 tracey gw_html_escape(tagger),
1885 88d59c36 2020-01-29 stsp gw_html_escape(tag_commit)) == -1) {
1886 4ff7391f 2020-01-28 tracey error = got_error_from_errno("asprintf");
1887 4ff7391f 2020-01-28 tracey goto done;
1888 4ff7391f 2020-01-28 tracey }
1889 87f9ebf5 2020-01-15 tracey break;
1890 87f9ebf5 2020-01-15 tracey default:
1891 87f9ebf5 2020-01-15 tracey break;
1892 87f9ebf5 2020-01-15 tracey }
1893 87f9ebf5 2020-01-15 tracey
1894 6c6c85af 2020-01-15 tracey got_object_tag_close(tag);
1895 87f9ebf5 2020-01-15 tracey
1896 6c6c85af 2020-01-15 tracey error = buf_puts(&newsize, diffbuf, tag_row);
1897 87f9ebf5 2020-01-15 tracey
1898 6c6c85af 2020-01-15 tracey free(id_str);
1899 6c6c85af 2020-01-15 tracey free(refstr);
1900 6c6c85af 2020-01-15 tracey free(age);
1901 f2f46662 2020-01-23 tracey free(tag_commit0);
1902 87f9ebf5 2020-01-15 tracey free(tag_row);
1903 87f9ebf5 2020-01-15 tracey
1904 87f9ebf5 2020-01-15 tracey if (error || (limit && --limit == 0))
1905 87f9ebf5 2020-01-15 tracey break;
1906 87f9ebf5 2020-01-15 tracey }
1907 6c6c85af 2020-01-15 tracey
1908 6c6c85af 2020-01-15 tracey if (buf_len(diffbuf) > 0) {
1909 6c6c85af 2020-01-15 tracey error = buf_putc(diffbuf, '\0');
1910 6c6c85af 2020-01-15 tracey tags = strdup(buf_get(diffbuf));
1911 6c6c85af 2020-01-15 tracey }
1912 87f9ebf5 2020-01-15 tracey done:
1913 87f9ebf5 2020-01-15 tracey buf_free(diffbuf);
1914 87f9ebf5 2020-01-15 tracey got_ref_list_free(&refs);
1915 87f9ebf5 2020-01-15 tracey if (repo)
1916 87f9ebf5 2020-01-15 tracey got_repo_close(repo);
1917 87f9ebf5 2020-01-15 tracey if (error)
1918 87f9ebf5 2020-01-15 tracey return NULL;
1919 87f9ebf5 2020-01-15 tracey else
1920 87f9ebf5 2020-01-15 tracey return tags;
1921 f2f46662 2020-01-23 tracey }
1922 f2f46662 2020-01-23 tracey
1923 f2f46662 2020-01-23 tracey static void
1924 f2f46662 2020-01-23 tracey gw_free_headers(struct gw_header *header)
1925 f2f46662 2020-01-23 tracey {
1926 f2f46662 2020-01-23 tracey free(header->id);
1927 f2f46662 2020-01-23 tracey free(header->path);
1928 f2f46662 2020-01-23 tracey if (header->commit != NULL)
1929 f2f46662 2020-01-23 tracey got_object_commit_close(header->commit);
1930 f2f46662 2020-01-23 tracey if (header->repo)
1931 f2f46662 2020-01-23 tracey got_repo_close(header->repo);
1932 f2f46662 2020-01-23 tracey free(header->refs_str);
1933 f2f46662 2020-01-23 tracey free(header->commit_id);
1934 f2f46662 2020-01-23 tracey free(header->parent_id);
1935 f2f46662 2020-01-23 tracey free(header->tree_id);
1936 f2f46662 2020-01-23 tracey free(header->author);
1937 f2f46662 2020-01-23 tracey free(header->committer);
1938 f2f46662 2020-01-23 tracey free(header->commit_msg);
1939 f2f46662 2020-01-23 tracey }
1940 f2f46662 2020-01-23 tracey
1941 f2f46662 2020-01-23 tracey static struct gw_header *
1942 f2f46662 2020-01-23 tracey gw_init_header()
1943 f2f46662 2020-01-23 tracey {
1944 f2f46662 2020-01-23 tracey struct gw_header *header;
1945 f2f46662 2020-01-23 tracey
1946 ae36ed87 2020-01-28 stsp header = malloc(sizeof(*header));
1947 ae36ed87 2020-01-28 stsp if (header == NULL)
1948 f2f46662 2020-01-23 tracey return NULL;
1949 f2f46662 2020-01-23 tracey
1950 f2f46662 2020-01-23 tracey header->repo = NULL;
1951 f2f46662 2020-01-23 tracey header->commit = NULL;
1952 f2f46662 2020-01-23 tracey header->id = NULL;
1953 f2f46662 2020-01-23 tracey header->path = NULL;
1954 ae36ed87 2020-01-28 stsp SIMPLEQ_INIT(&header->refs);
1955 f2f46662 2020-01-23 tracey
1956 f2f46662 2020-01-23 tracey return header;
1957 f2f46662 2020-01-23 tracey }
1958 f2f46662 2020-01-23 tracey
1959 f2f46662 2020-01-23 tracey static const struct got_error *
1960 f2f46662 2020-01-23 tracey gw_get_commits(struct gw_trans * gw_trans, struct gw_header *header,
1961 f2f46662 2020-01-23 tracey int limit)
1962 f2f46662 2020-01-23 tracey {
1963 f2f46662 2020-01-23 tracey const struct got_error *error = NULL;
1964 f2f46662 2020-01-23 tracey struct got_commit_graph *graph = NULL;
1965 f2f46662 2020-01-23 tracey
1966 f2f46662 2020-01-23 tracey error = got_commit_graph_open(&graph, header->path, 0);
1967 f2f46662 2020-01-23 tracey if (error)
1968 f2f46662 2020-01-23 tracey goto done;
1969 f2f46662 2020-01-23 tracey
1970 f2f46662 2020-01-23 tracey error = got_commit_graph_iter_start(graph, header->id, header->repo,
1971 f2f46662 2020-01-23 tracey NULL, NULL);
1972 f2f46662 2020-01-23 tracey if (error)
1973 f2f46662 2020-01-23 tracey goto done;
1974 f2f46662 2020-01-23 tracey
1975 f2f46662 2020-01-23 tracey for (;;) {
1976 f2f46662 2020-01-23 tracey error = got_commit_graph_iter_next(&header->id, graph,
1977 f2f46662 2020-01-23 tracey header->repo, NULL, NULL);
1978 f2f46662 2020-01-23 tracey if (error) {
1979 f2f46662 2020-01-23 tracey if (error->code == GOT_ERR_ITER_COMPLETED)
1980 f2f46662 2020-01-23 tracey error = NULL;
1981 f2f46662 2020-01-23 tracey goto done;
1982 f2f46662 2020-01-23 tracey }
1983 f2f46662 2020-01-23 tracey if (header->id == NULL)
1984 f2f46662 2020-01-23 tracey goto done;
1985 f2f46662 2020-01-23 tracey
1986 f2f46662 2020-01-23 tracey error = got_object_open_as_commit(&header->commit, header->repo,
1987 f2f46662 2020-01-23 tracey header->id);
1988 f2f46662 2020-01-23 tracey if (error)
1989 f2f46662 2020-01-23 tracey goto done;
1990 f2f46662 2020-01-23 tracey
1991 f2f46662 2020-01-23 tracey error = gw_get_commit(gw_trans, header);
1992 f2f46662 2020-01-23 tracey if (limit > 1) {
1993 f2f46662 2020-01-23 tracey struct gw_header *n_header = NULL;
1994 5147ab56 2020-01-29 stsp if ((n_header = gw_init_header()) == NULL) {
1995 f2f46662 2020-01-23 tracey error = got_error_from_errno("malloc");
1996 5147ab56 2020-01-29 stsp goto done;
1997 5147ab56 2020-01-29 stsp }
1998 f2f46662 2020-01-23 tracey
1999 f2f46662 2020-01-23 tracey n_header->refs_str = strdup(header->refs_str);
2000 f2f46662 2020-01-23 tracey n_header->commit_id = strdup(header->commit_id);
2001 f2f46662 2020-01-23 tracey n_header->parent_id = strdup(header->parent_id);
2002 f2f46662 2020-01-23 tracey n_header->tree_id = strdup(header->tree_id);
2003 f2f46662 2020-01-23 tracey n_header->author = strdup(header->author);
2004 f2f46662 2020-01-23 tracey n_header->committer = strdup(header->committer);
2005 f2f46662 2020-01-23 tracey n_header->commit_msg = strdup(header->commit_msg);
2006 f2f46662 2020-01-23 tracey n_header->committer_time = header->committer_time;
2007 f2f46662 2020-01-23 tracey TAILQ_INSERT_TAIL(&gw_trans->gw_headers, n_header,
2008 f2f46662 2020-01-23 tracey entry);
2009 f2f46662 2020-01-23 tracey }
2010 f2f46662 2020-01-23 tracey if (error || (limit && --limit == 0))
2011 f2f46662 2020-01-23 tracey break;
2012 f2f46662 2020-01-23 tracey }
2013 f2f46662 2020-01-23 tracey done:
2014 f2f46662 2020-01-23 tracey if (graph)
2015 f2f46662 2020-01-23 tracey got_commit_graph_close(graph);
2016 f2f46662 2020-01-23 tracey return error;
2017 f2f46662 2020-01-23 tracey }
2018 f2f46662 2020-01-23 tracey
2019 f2f46662 2020-01-23 tracey static const struct got_error *
2020 f2f46662 2020-01-23 tracey gw_get_commit(struct gw_trans *gw_trans, struct gw_header *header)
2021 f2f46662 2020-01-23 tracey {
2022 f2f46662 2020-01-23 tracey const struct got_error *error = NULL;
2023 f2f46662 2020-01-23 tracey struct got_reflist_entry *re;
2024 f2f46662 2020-01-23 tracey struct got_object_id *id2 = NULL;
2025 f2f46662 2020-01-23 tracey struct got_object_qid *parent_id;
2026 e46f587c 2020-01-29 tracey char *refs_str = NULL, *commit_msg = NULL, *commit_msg0;
2027 f2f46662 2020-01-23 tracey
2028 f2f46662 2020-01-23 tracey /*print commit*/
2029 f2f46662 2020-01-23 tracey SIMPLEQ_FOREACH(re, &header->refs, entry) {
2030 f2f46662 2020-01-23 tracey char *s;
2031 f2f46662 2020-01-23 tracey const char *name;
2032 f2f46662 2020-01-23 tracey struct got_tag_object *tag = NULL;
2033 f2f46662 2020-01-23 tracey int cmp;
2034 f2f46662 2020-01-23 tracey
2035 f2f46662 2020-01-23 tracey name = got_ref_get_name(re->ref);
2036 f2f46662 2020-01-23 tracey if (strcmp(name, GOT_REF_HEAD) == 0)
2037 f2f46662 2020-01-23 tracey continue;
2038 f2f46662 2020-01-23 tracey if (strncmp(name, "refs/", 5) == 0)
2039 f2f46662 2020-01-23 tracey name += 5;
2040 f2f46662 2020-01-23 tracey if (strncmp(name, "got/", 4) == 0)
2041 f2f46662 2020-01-23 tracey continue;
2042 f2f46662 2020-01-23 tracey if (strncmp(name, "heads/", 6) == 0)
2043 f2f46662 2020-01-23 tracey name += 6;
2044 f2f46662 2020-01-23 tracey if (strncmp(name, "remotes/", 8) == 0)
2045 f2f46662 2020-01-23 tracey name += 8;
2046 f2f46662 2020-01-23 tracey if (strncmp(name, "tags/", 5) == 0) {
2047 f2f46662 2020-01-23 tracey error = got_object_open_as_tag(&tag, header->repo,
2048 f2f46662 2020-01-23 tracey re->id);
2049 f2f46662 2020-01-23 tracey if (error) {
2050 f2f46662 2020-01-23 tracey if (error->code != GOT_ERR_OBJ_TYPE)
2051 f2f46662 2020-01-23 tracey continue;
2052 f2f46662 2020-01-23 tracey /*
2053 f2f46662 2020-01-23 tracey * Ref points at something other
2054 f2f46662 2020-01-23 tracey * than a tag.
2055 f2f46662 2020-01-23 tracey */
2056 f2f46662 2020-01-23 tracey error = NULL;
2057 f2f46662 2020-01-23 tracey tag = NULL;
2058 f2f46662 2020-01-23 tracey }
2059 f2f46662 2020-01-23 tracey }
2060 f2f46662 2020-01-23 tracey cmp = got_object_id_cmp(tag ?
2061 f2f46662 2020-01-23 tracey got_object_tag_get_object_id(tag) : re->id, header->id);
2062 f2f46662 2020-01-23 tracey if (tag)
2063 f2f46662 2020-01-23 tracey got_object_tag_close(tag);
2064 f2f46662 2020-01-23 tracey if (cmp != 0)
2065 f2f46662 2020-01-23 tracey continue;
2066 f2f46662 2020-01-23 tracey s = refs_str;
2067 88d59c36 2020-01-29 stsp if (asprintf(&refs_str, "%s%s%s", s ? s : "",
2068 88d59c36 2020-01-29 stsp s ? ", " : "", name) == -1) {
2069 f2f46662 2020-01-23 tracey error = got_error_from_errno("asprintf");
2070 f2f46662 2020-01-23 tracey free(s);
2071 f2f46662 2020-01-23 tracey return error;
2072 f2f46662 2020-01-23 tracey }
2073 f2f46662 2020-01-23 tracey header->refs_str = strdup(refs_str);
2074 f2f46662 2020-01-23 tracey free(s);
2075 f2f46662 2020-01-23 tracey }
2076 f2f46662 2020-01-23 tracey
2077 f2f46662 2020-01-23 tracey if (refs_str == NULL)
2078 f2f46662 2020-01-23 tracey header->refs_str = strdup("");
2079 f2f46662 2020-01-23 tracey free(refs_str);
2080 f2f46662 2020-01-23 tracey
2081 f2f46662 2020-01-23 tracey error = got_object_id_str(&header->commit_id, header->id);
2082 f2f46662 2020-01-23 tracey if (error)
2083 f2f46662 2020-01-23 tracey return error;
2084 f2f46662 2020-01-23 tracey
2085 f2f46662 2020-01-23 tracey error = got_object_id_str(&header->tree_id,
2086 f2f46662 2020-01-23 tracey got_object_commit_get_tree_id(header->commit));
2087 f2f46662 2020-01-23 tracey if (error)
2088 f2f46662 2020-01-23 tracey return error;
2089 f2f46662 2020-01-23 tracey
2090 f2f46662 2020-01-23 tracey if (gw_trans->action == GW_DIFF) {
2091 f2f46662 2020-01-23 tracey parent_id = SIMPLEQ_FIRST(
2092 f2f46662 2020-01-23 tracey got_object_commit_get_parent_ids(header->commit));
2093 f2f46662 2020-01-23 tracey if (parent_id != NULL) {
2094 f2f46662 2020-01-23 tracey id2 = got_object_id_dup(parent_id->id);
2095 f2f46662 2020-01-23 tracey free (parent_id);
2096 f2f46662 2020-01-23 tracey error = got_object_id_str(&header->parent_id, id2);
2097 f2f46662 2020-01-23 tracey if (error)
2098 f2f46662 2020-01-23 tracey return error;
2099 f2f46662 2020-01-23 tracey free(id2);
2100 f2f46662 2020-01-23 tracey } else
2101 f2f46662 2020-01-23 tracey header->parent_id = strdup("/dev/null");
2102 f2f46662 2020-01-23 tracey } else
2103 f2f46662 2020-01-23 tracey header->parent_id = strdup("");
2104 f2f46662 2020-01-23 tracey
2105 f2f46662 2020-01-23 tracey header->committer_time =
2106 f2f46662 2020-01-23 tracey got_object_commit_get_committer_time(header->commit);
2107 1177268c 2020-01-28 tracey
2108 1177268c 2020-01-28 tracey if (gw_trans->action != GW_BRIEFS && gw_trans->action != GW_SUMMARY) {
2109 1177268c 2020-01-28 tracey header->author = strdup(
2110 1177268c 2020-01-28 tracey gw_html_escape(got_object_commit_get_author(header->commit))
2111 1177268c 2020-01-28 tracey );
2112 1177268c 2020-01-28 tracey } else {
2113 1177268c 2020-01-28 tracey header->author = strdup(
2114 1177268c 2020-01-28 tracey got_object_commit_get_author(header->commit)
2115 1177268c 2020-01-28 tracey );
2116 1177268c 2020-01-28 tracey }
2117 1177268c 2020-01-28 tracey
2118 4ff7391f 2020-01-28 tracey header->committer = strdup(
2119 4ff7391f 2020-01-28 tracey gw_html_escape(got_object_commit_get_committer(header->commit))
2120 4ff7391f 2020-01-28 tracey );
2121 f2f46662 2020-01-23 tracey
2122 f2f46662 2020-01-23 tracey error = got_object_commit_get_logmsg(&commit_msg0, header->commit);
2123 f2f46662 2020-01-23 tracey if (error)
2124 f2f46662 2020-01-23 tracey return error;
2125 f2f46662 2020-01-23 tracey
2126 f2f46662 2020-01-23 tracey commit_msg = commit_msg0;
2127 f2f46662 2020-01-23 tracey while (*commit_msg == '\n')
2128 f2f46662 2020-01-23 tracey commit_msg++;
2129 f2f46662 2020-01-23 tracey
2130 f2f46662 2020-01-23 tracey header->commit_msg = strdup(commit_msg);
2131 f2f46662 2020-01-23 tracey free(commit_msg0);
2132 f2f46662 2020-01-23 tracey return error;
2133 f2f46662 2020-01-23 tracey }
2134 f2f46662 2020-01-23 tracey
2135 f2f46662 2020-01-23 tracey static const struct got_error *
2136 f2f46662 2020-01-23 tracey gw_get_header(struct gw_trans *gw_trans, struct gw_header *header, int limit)
2137 f2f46662 2020-01-23 tracey {
2138 f2f46662 2020-01-23 tracey const struct got_error *error = NULL;
2139 f2f46662 2020-01-23 tracey char *in_repo_path = NULL;
2140 f2f46662 2020-01-23 tracey
2141 f2f46662 2020-01-23 tracey error = got_repo_open(&header->repo, gw_trans->repo_path, NULL);
2142 f2f46662 2020-01-23 tracey if (error)
2143 f2f46662 2020-01-23 tracey return error;
2144 f2f46662 2020-01-23 tracey
2145 f2f46662 2020-01-23 tracey if (gw_trans->commit == NULL) {
2146 f2f46662 2020-01-23 tracey struct got_reference *head_ref;
2147 f2f46662 2020-01-23 tracey error = got_ref_open(&head_ref, header->repo,
2148 f2f46662 2020-01-23 tracey gw_trans->headref, 0);
2149 f2f46662 2020-01-23 tracey if (error)
2150 f2f46662 2020-01-23 tracey return error;
2151 f2f46662 2020-01-23 tracey
2152 f2f46662 2020-01-23 tracey error = got_ref_resolve(&header->id, header->repo, head_ref);
2153 f2f46662 2020-01-23 tracey got_ref_close(head_ref);
2154 f2f46662 2020-01-23 tracey if (error)
2155 f2f46662 2020-01-23 tracey return error;
2156 f2f46662 2020-01-23 tracey
2157 f2f46662 2020-01-23 tracey error = got_object_open_as_commit(&header->commit,
2158 f2f46662 2020-01-23 tracey header->repo, header->id);
2159 f2f46662 2020-01-23 tracey } else {
2160 f2f46662 2020-01-23 tracey struct got_reference *ref;
2161 f2f46662 2020-01-23 tracey error = got_ref_open(&ref, header->repo, gw_trans->commit, 0);
2162 f2f46662 2020-01-23 tracey if (error == NULL) {
2163 f2f46662 2020-01-23 tracey int obj_type;
2164 f2f46662 2020-01-23 tracey error = got_ref_resolve(&header->id, header->repo, ref);
2165 f2f46662 2020-01-23 tracey got_ref_close(ref);
2166 f2f46662 2020-01-23 tracey if (error)
2167 f2f46662 2020-01-23 tracey return error;
2168 f2f46662 2020-01-23 tracey error = got_object_get_type(&obj_type, header->repo,
2169 f2f46662 2020-01-23 tracey header->id);
2170 f2f46662 2020-01-23 tracey if (error)
2171 f2f46662 2020-01-23 tracey return error;
2172 f2f46662 2020-01-23 tracey if (obj_type == GOT_OBJ_TYPE_TAG) {
2173 f2f46662 2020-01-23 tracey struct got_tag_object *tag;
2174 f2f46662 2020-01-23 tracey error = got_object_open_as_tag(&tag,
2175 f2f46662 2020-01-23 tracey header->repo, header->id);
2176 f2f46662 2020-01-23 tracey if (error)
2177 f2f46662 2020-01-23 tracey return error;
2178 f2f46662 2020-01-23 tracey if (got_object_tag_get_object_type(tag) !=
2179 f2f46662 2020-01-23 tracey GOT_OBJ_TYPE_COMMIT) {
2180 f2f46662 2020-01-23 tracey got_object_tag_close(tag);
2181 f2f46662 2020-01-23 tracey error = got_error(GOT_ERR_OBJ_TYPE);
2182 f2f46662 2020-01-23 tracey return error;
2183 f2f46662 2020-01-23 tracey }
2184 f2f46662 2020-01-23 tracey free(header->id);
2185 f2f46662 2020-01-23 tracey header->id = got_object_id_dup(
2186 f2f46662 2020-01-23 tracey got_object_tag_get_object_id(tag));
2187 f2f46662 2020-01-23 tracey if (header->id == NULL)
2188 f2f46662 2020-01-23 tracey error = got_error_from_errno(
2189 f2f46662 2020-01-23 tracey "got_object_id_dup");
2190 f2f46662 2020-01-23 tracey got_object_tag_close(tag);
2191 f2f46662 2020-01-23 tracey if (error)
2192 f2f46662 2020-01-23 tracey return error;
2193 f2f46662 2020-01-23 tracey } else if (obj_type != GOT_OBJ_TYPE_COMMIT) {
2194 f2f46662 2020-01-23 tracey error = got_error(GOT_ERR_OBJ_TYPE);
2195 f2f46662 2020-01-23 tracey return error;
2196 f2f46662 2020-01-23 tracey }
2197 f2f46662 2020-01-23 tracey error = got_object_open_as_commit(&header->commit,
2198 f2f46662 2020-01-23 tracey header->repo, header->id);
2199 f2f46662 2020-01-23 tracey if (error)
2200 f2f46662 2020-01-23 tracey return error;
2201 f2f46662 2020-01-23 tracey }
2202 f2f46662 2020-01-23 tracey if (header->commit == NULL) {
2203 f2f46662 2020-01-23 tracey error = got_repo_match_object_id_prefix(&header->id,
2204 f2f46662 2020-01-23 tracey gw_trans->commit, GOT_OBJ_TYPE_COMMIT,
2205 f2f46662 2020-01-23 tracey header->repo);
2206 f2f46662 2020-01-23 tracey if (error)
2207 f2f46662 2020-01-23 tracey return error;
2208 f2f46662 2020-01-23 tracey }
2209 f2f46662 2020-01-23 tracey error = got_repo_match_object_id_prefix(&header->id,
2210 f2f46662 2020-01-23 tracey gw_trans->commit, GOT_OBJ_TYPE_COMMIT,
2211 f2f46662 2020-01-23 tracey header->repo);
2212 f2f46662 2020-01-23 tracey }
2213 f2f46662 2020-01-23 tracey
2214 f2f46662 2020-01-23 tracey error = got_repo_map_path(&in_repo_path, header->repo,
2215 f2f46662 2020-01-23 tracey gw_trans->repo_path, 1);
2216 f2f46662 2020-01-23 tracey if (error)
2217 f2f46662 2020-01-23 tracey return error;
2218 f2f46662 2020-01-23 tracey
2219 f2f46662 2020-01-23 tracey if (in_repo_path) {
2220 f2f46662 2020-01-23 tracey header->path = strdup(in_repo_path);
2221 f2f46662 2020-01-23 tracey }
2222 f2f46662 2020-01-23 tracey free(in_repo_path);
2223 f2f46662 2020-01-23 tracey
2224 f2f46662 2020-01-23 tracey error = got_ref_list(&header->refs, header->repo, NULL,
2225 f2f46662 2020-01-23 tracey got_ref_cmp_by_name, NULL);
2226 f2f46662 2020-01-23 tracey if (error)
2227 f2f46662 2020-01-23 tracey return error;
2228 f2f46662 2020-01-23 tracey
2229 f2f46662 2020-01-23 tracey error = gw_get_commits(gw_trans, header, limit);
2230 f2f46662 2020-01-23 tracey return error;
2231 ec46ccd7 2020-01-15 tracey }
2232 ec46ccd7 2020-01-15 tracey
2233 ec46ccd7 2020-01-15 tracey struct blame_line {
2234 ec46ccd7 2020-01-15 tracey int annotated;
2235 ec46ccd7 2020-01-15 tracey char *id_str;
2236 ec46ccd7 2020-01-15 tracey char *committer;
2237 ec46ccd7 2020-01-15 tracey char datebuf[11]; /* YYYY-MM-DD + NUL */
2238 ec46ccd7 2020-01-15 tracey };
2239 ec46ccd7 2020-01-15 tracey
2240 147269d5 2020-01-15 tracey struct gw_blame_cb_args {
2241 ec46ccd7 2020-01-15 tracey struct blame_line *lines;
2242 ec46ccd7 2020-01-15 tracey int nlines;
2243 ec46ccd7 2020-01-15 tracey int nlines_prec;
2244 ec46ccd7 2020-01-15 tracey int lineno_cur;
2245 ec46ccd7 2020-01-15 tracey off_t *line_offsets;
2246 ec46ccd7 2020-01-15 tracey FILE *f;
2247 ec46ccd7 2020-01-15 tracey struct got_repository *repo;
2248 54415d85 2020-01-15 tracey struct gw_trans *gw_trans;
2249 2e676fc5 2020-01-15 tracey struct buf *blamebuf;
2250 ec46ccd7 2020-01-15 tracey };
2251 ec46ccd7 2020-01-15 tracey
2252 ec46ccd7 2020-01-15 tracey static const struct got_error *
2253 147269d5 2020-01-15 tracey gw_blame_cb(void *arg, int nlines, int lineno, struct got_object_id *id)
2254 ec46ccd7 2020-01-15 tracey {
2255 ec46ccd7 2020-01-15 tracey const struct got_error *err = NULL;
2256 147269d5 2020-01-15 tracey struct gw_blame_cb_args *a = arg;
2257 ec46ccd7 2020-01-15 tracey struct blame_line *bline;
2258 ec46ccd7 2020-01-15 tracey char *line = NULL;
2259 2e676fc5 2020-01-15 tracey size_t linesize = 0, newsize;
2260 ec46ccd7 2020-01-15 tracey struct got_commit_object *commit = NULL;
2261 ec46ccd7 2020-01-15 tracey off_t offset;
2262 ec46ccd7 2020-01-15 tracey struct tm tm;
2263 ec46ccd7 2020-01-15 tracey time_t committer_time;
2264 ec46ccd7 2020-01-15 tracey
2265 ec46ccd7 2020-01-15 tracey if (nlines != a->nlines ||
2266 ec46ccd7 2020-01-15 tracey (lineno != -1 && lineno < 1) || lineno > a->nlines)
2267 ec46ccd7 2020-01-15 tracey return got_error(GOT_ERR_RANGE);
2268 ec46ccd7 2020-01-15 tracey
2269 ec46ccd7 2020-01-15 tracey if (lineno == -1)
2270 ec46ccd7 2020-01-15 tracey return NULL; /* no change in this commit */
2271 ec46ccd7 2020-01-15 tracey
2272 ec46ccd7 2020-01-15 tracey /* Annotate this line. */
2273 ec46ccd7 2020-01-15 tracey bline = &a->lines[lineno - 1];
2274 ec46ccd7 2020-01-15 tracey if (bline->annotated)
2275 ec46ccd7 2020-01-15 tracey return NULL;
2276 ec46ccd7 2020-01-15 tracey err = got_object_id_str(&bline->id_str, id);
2277 ec46ccd7 2020-01-15 tracey if (err)
2278 ec46ccd7 2020-01-15 tracey return err;
2279 ec46ccd7 2020-01-15 tracey
2280 ec46ccd7 2020-01-15 tracey err = got_object_open_as_commit(&commit, a->repo, id);
2281 ec46ccd7 2020-01-15 tracey if (err)
2282 ec46ccd7 2020-01-15 tracey goto done;
2283 ec46ccd7 2020-01-15 tracey
2284 ec46ccd7 2020-01-15 tracey bline->committer = strdup(got_object_commit_get_committer(commit));
2285 ec46ccd7 2020-01-15 tracey if (bline->committer == NULL) {
2286 ec46ccd7 2020-01-15 tracey err = got_error_from_errno("strdup");
2287 ec46ccd7 2020-01-15 tracey goto done;
2288 ec46ccd7 2020-01-15 tracey }
2289 ec46ccd7 2020-01-15 tracey
2290 ec46ccd7 2020-01-15 tracey committer_time = got_object_commit_get_committer_time(commit);
2291 ec46ccd7 2020-01-15 tracey if (localtime_r(&committer_time, &tm) == NULL)
2292 ec46ccd7 2020-01-15 tracey return got_error_from_errno("localtime_r");
2293 ec46ccd7 2020-01-15 tracey if (strftime(bline->datebuf, sizeof(bline->datebuf), "%G-%m-%d",
2294 ec46ccd7 2020-01-15 tracey &tm) >= sizeof(bline->datebuf)) {
2295 ec46ccd7 2020-01-15 tracey err = got_error(GOT_ERR_NO_SPACE);
2296 ec46ccd7 2020-01-15 tracey goto done;
2297 ec46ccd7 2020-01-15 tracey }
2298 ec46ccd7 2020-01-15 tracey bline->annotated = 1;
2299 ec46ccd7 2020-01-15 tracey
2300 ec46ccd7 2020-01-15 tracey /* Print lines annotated so far. */
2301 ec46ccd7 2020-01-15 tracey bline = &a->lines[a->lineno_cur - 1];
2302 ec46ccd7 2020-01-15 tracey if (!bline->annotated)
2303 ec46ccd7 2020-01-15 tracey goto done;
2304 ec46ccd7 2020-01-15 tracey
2305 ec46ccd7 2020-01-15 tracey offset = a->line_offsets[a->lineno_cur - 1];
2306 ec46ccd7 2020-01-15 tracey if (fseeko(a->f, offset, SEEK_SET) == -1) {
2307 ec46ccd7 2020-01-15 tracey err = got_error_from_errno("fseeko");
2308 ec46ccd7 2020-01-15 tracey goto done;
2309 ec46ccd7 2020-01-15 tracey }
2310 ec46ccd7 2020-01-15 tracey
2311 ec46ccd7 2020-01-15 tracey while (bline->annotated) {
2312 0311ce2d 2020-01-15 tracey char *smallerthan, *at, *nl, *committer, *blame_row = NULL,
2313 0311ce2d 2020-01-15 tracey *line_escape = NULL;
2314 ec46ccd7 2020-01-15 tracey size_t len;
2315 ec46ccd7 2020-01-15 tracey
2316 ec46ccd7 2020-01-15 tracey if (getline(&line, &linesize, a->f) == -1) {
2317 ec46ccd7 2020-01-15 tracey if (ferror(a->f))
2318 ec46ccd7 2020-01-15 tracey err = got_error_from_errno("getline");
2319 ec46ccd7 2020-01-15 tracey break;
2320 ec46ccd7 2020-01-15 tracey }
2321 ec46ccd7 2020-01-15 tracey
2322 ec46ccd7 2020-01-15 tracey committer = bline->committer;
2323 ec46ccd7 2020-01-15 tracey smallerthan = strchr(committer, '<');
2324 ec46ccd7 2020-01-15 tracey if (smallerthan && smallerthan[1] != '\0')
2325 ec46ccd7 2020-01-15 tracey committer = smallerthan + 1;
2326 ec46ccd7 2020-01-15 tracey at = strchr(committer, '@');
2327 ec46ccd7 2020-01-15 tracey if (at)
2328 ec46ccd7 2020-01-15 tracey *at = '\0';
2329 ec46ccd7 2020-01-15 tracey len = strlen(committer);
2330 ec46ccd7 2020-01-15 tracey if (len >= 9)
2331 ec46ccd7 2020-01-15 tracey committer[8] = '\0';
2332 ec46ccd7 2020-01-15 tracey
2333 ec46ccd7 2020-01-15 tracey nl = strchr(line, '\n');
2334 ec46ccd7 2020-01-15 tracey if (nl)
2335 ec46ccd7 2020-01-15 tracey *nl = '\0';
2336 0311ce2d 2020-01-15 tracey
2337 0311ce2d 2020-01-15 tracey if (strcmp(line, "") != 0)
2338 0311ce2d 2020-01-15 tracey line_escape = strdup(gw_html_escape(line));
2339 0311ce2d 2020-01-15 tracey else
2340 0311ce2d 2020-01-15 tracey line_escape = strdup("");
2341 0311ce2d 2020-01-15 tracey
2342 f2f46662 2020-01-23 tracey asprintf(&blame_row, blame_line, a->nlines_prec,
2343 2e676fc5 2020-01-15 tracey a->lineno_cur, bline->id_str, bline->datebuf, committer,
2344 0311ce2d 2020-01-15 tracey line_escape);
2345 ec46ccd7 2020-01-15 tracey a->lineno_cur++;
2346 2e676fc5 2020-01-15 tracey err = buf_puts(&newsize, a->blamebuf, blame_row);
2347 2e676fc5 2020-01-15 tracey if (err)
2348 2e676fc5 2020-01-15 tracey return err;
2349 2e676fc5 2020-01-15 tracey
2350 ec46ccd7 2020-01-15 tracey bline = &a->lines[a->lineno_cur - 1];
2351 0311ce2d 2020-01-15 tracey free(line_escape);
2352 2e676fc5 2020-01-15 tracey free(blame_row);
2353 ec46ccd7 2020-01-15 tracey }
2354 ec46ccd7 2020-01-15 tracey done:
2355 ec46ccd7 2020-01-15 tracey if (commit)
2356 ec46ccd7 2020-01-15 tracey got_object_commit_close(commit);
2357 ec46ccd7 2020-01-15 tracey free(line);
2358 ec46ccd7 2020-01-15 tracey return err;
2359 8d4d2453 2020-01-15 tracey }
2360 bcbc97d8 2020-01-15 tracey
2361 bcbc97d8 2020-01-15 tracey static char*
2362 e46f587c 2020-01-29 tracey gw_get_file_blame_blob(struct gw_trans *gw_trans)
2363 bcbc97d8 2020-01-15 tracey {
2364 bcbc97d8 2020-01-15 tracey const struct got_error *error = NULL;
2365 bcbc97d8 2020-01-15 tracey struct got_repository *repo = NULL;
2366 ec46ccd7 2020-01-15 tracey struct got_object_id *obj_id = NULL;
2367 ec46ccd7 2020-01-15 tracey struct got_object_id *commit_id = NULL;
2368 ec46ccd7 2020-01-15 tracey struct got_blob_object *blob = NULL;
2369 e46f587c 2020-01-29 tracey char *blame_html = NULL, *path = NULL, *in_repo_path = NULL;
2370 e46f587c 2020-01-29 tracey char *folder = NULL;
2371 147269d5 2020-01-15 tracey struct gw_blame_cb_args bca;
2372 119bf4ed 2020-01-15 tracey int i, obj_type;
2373 ec46ccd7 2020-01-15 tracey size_t filesize;
2374 ec46ccd7 2020-01-15 tracey
2375 ec46ccd7 2020-01-15 tracey error = got_repo_open(&repo, gw_trans->repo_path, NULL);
2376 ec46ccd7 2020-01-15 tracey if (error)
2377 ec46ccd7 2020-01-15 tracey goto done;
2378 ec46ccd7 2020-01-15 tracey
2379 2e676fc5 2020-01-15 tracey if (gw_trans->repo_folder != NULL) {
2380 88d59c36 2020-01-29 stsp if (asprintf(&folder, "%s/", gw_trans->repo_folder) == -1) {
2381 2e676fc5 2020-01-15 tracey error = got_error_from_errno("asprintf");
2382 2e676fc5 2020-01-15 tracey goto done;
2383 2e676fc5 2020-01-15 tracey }
2384 2e676fc5 2020-01-15 tracey } else
2385 2e676fc5 2020-01-15 tracey folder = strdup("");
2386 2e676fc5 2020-01-15 tracey
2387 88d59c36 2020-01-29 stsp if (asprintf(&path, "%s%s", folder, gw_trans->repo_file) == -1) {
2388 2e676fc5 2020-01-15 tracey error = got_error_from_errno("asprintf");
2389 2e676fc5 2020-01-15 tracey goto done;
2390 2e676fc5 2020-01-15 tracey }
2391 2e676fc5 2020-01-15 tracey free(folder);
2392 2e676fc5 2020-01-15 tracey
2393 2e676fc5 2020-01-15 tracey error = got_repo_map_path(&in_repo_path, repo, path, 1);
2394 ec46ccd7 2020-01-15 tracey if (error)
2395 ec46ccd7 2020-01-15 tracey goto done;
2396 ec46ccd7 2020-01-15 tracey
2397 f2f46662 2020-01-23 tracey error = got_repo_match_object_id(&commit_id, NULL, gw_trans->commit,
2398 147269d5 2020-01-15 tracey GOT_OBJ_TYPE_COMMIT, 1, repo);
2399 ec46ccd7 2020-01-15 tracey if (error)
2400 ec46ccd7 2020-01-15 tracey goto done;
2401 ec46ccd7 2020-01-15 tracey
2402 ec46ccd7 2020-01-15 tracey error = got_object_id_by_path(&obj_id, repo, commit_id, in_repo_path);
2403 ec46ccd7 2020-01-15 tracey if (error)
2404 ec46ccd7 2020-01-15 tracey goto done;
2405 2e676fc5 2020-01-15 tracey
2406 ec46ccd7 2020-01-15 tracey if (obj_id == NULL) {
2407 ec46ccd7 2020-01-15 tracey error = got_error(GOT_ERR_NO_OBJ);
2408 ec46ccd7 2020-01-15 tracey goto done;
2409 ec46ccd7 2020-01-15 tracey }
2410 ec46ccd7 2020-01-15 tracey
2411 ec46ccd7 2020-01-15 tracey error = got_object_get_type(&obj_type, repo, obj_id);
2412 ec46ccd7 2020-01-15 tracey if (error)
2413 ec46ccd7 2020-01-15 tracey goto done;
2414 ec46ccd7 2020-01-15 tracey
2415 ec46ccd7 2020-01-15 tracey if (obj_type != GOT_OBJ_TYPE_BLOB) {
2416 ec46ccd7 2020-01-15 tracey error = got_error(GOT_ERR_OBJ_TYPE);
2417 ec46ccd7 2020-01-15 tracey goto done;
2418 ec46ccd7 2020-01-15 tracey }
2419 ec46ccd7 2020-01-15 tracey
2420 ec46ccd7 2020-01-15 tracey error = got_object_open_as_blob(&blob, repo, obj_id, 8192);
2421 ec46ccd7 2020-01-15 tracey if (error)
2422 ec46ccd7 2020-01-15 tracey goto done;
2423 ec46ccd7 2020-01-15 tracey
2424 2e676fc5 2020-01-15 tracey error = buf_alloc(&bca.blamebuf, 0);
2425 2e676fc5 2020-01-15 tracey if (error)
2426 2e676fc5 2020-01-15 tracey goto done;
2427 2e676fc5 2020-01-15 tracey
2428 ec46ccd7 2020-01-15 tracey bca.f = got_opentemp();
2429 ec46ccd7 2020-01-15 tracey if (bca.f == NULL) {
2430 ec46ccd7 2020-01-15 tracey error = got_error_from_errno("got_opentemp");
2431 ec46ccd7 2020-01-15 tracey goto done;
2432 ec46ccd7 2020-01-15 tracey }
2433 ec46ccd7 2020-01-15 tracey error = got_object_blob_dump_to_file(&filesize, &bca.nlines,
2434 ec46ccd7 2020-01-15 tracey &bca.line_offsets, bca.f, blob);
2435 ec46ccd7 2020-01-15 tracey if (error || bca.nlines == 0)
2436 ec46ccd7 2020-01-15 tracey goto done;
2437 ec46ccd7 2020-01-15 tracey
2438 e46f587c 2020-01-29 tracey if (gw_trans->action == GW_BLOB) {
2439 e46f587c 2020-01-29 tracey int len;
2440 e46f587c 2020-01-29 tracey fseek(bca.f, 0, SEEK_END);
2441 e46f587c 2020-01-29 tracey len = ftell(bca.f) + 1;
2442 e46f587c 2020-01-29 tracey fseek(bca.f, 0, SEEK_SET);
2443 e46f587c 2020-01-29 tracey if ((blame_html = calloc(len, sizeof(char *))) == NULL)
2444 e46f587c 2020-01-29 tracey goto done;
2445 e46f587c 2020-01-29 tracey fread(blame_html, 1, len, bca.f);
2446 e46f587c 2020-01-29 tracey goto done;
2447 e46f587c 2020-01-29 tracey }
2448 e46f587c 2020-01-29 tracey
2449 ec46ccd7 2020-01-15 tracey /* Don't include \n at EOF in the blame line count. */
2450 ec46ccd7 2020-01-15 tracey if (bca.line_offsets[bca.nlines - 1] == filesize)
2451 ec46ccd7 2020-01-15 tracey bca.nlines--;
2452 ec46ccd7 2020-01-15 tracey
2453 ec46ccd7 2020-01-15 tracey bca.lines = calloc(bca.nlines, sizeof(*bca.lines));
2454 ec46ccd7 2020-01-15 tracey if (bca.lines == NULL) {
2455 ec46ccd7 2020-01-15 tracey error = got_error_from_errno("calloc");
2456 ec46ccd7 2020-01-15 tracey goto done;
2457 ec46ccd7 2020-01-15 tracey }
2458 ec46ccd7 2020-01-15 tracey bca.lineno_cur = 1;
2459 ec46ccd7 2020-01-15 tracey bca.nlines_prec = 0;
2460 ec46ccd7 2020-01-15 tracey i = bca.nlines;
2461 ec46ccd7 2020-01-15 tracey while (i > 0) {
2462 ec46ccd7 2020-01-15 tracey i /= 10;
2463 ec46ccd7 2020-01-15 tracey bca.nlines_prec++;
2464 ec46ccd7 2020-01-15 tracey }
2465 ec46ccd7 2020-01-15 tracey bca.repo = repo;
2466 2e676fc5 2020-01-15 tracey bca.gw_trans = gw_trans;
2467 ec46ccd7 2020-01-15 tracey
2468 147269d5 2020-01-15 tracey error = got_blame(in_repo_path, commit_id, repo, gw_blame_cb, &bca,
2469 147269d5 2020-01-15 tracey NULL, NULL);
2470 e46f587c 2020-01-29 tracey if (error)
2471 e46f587c 2020-01-29 tracey goto done;
2472 2e676fc5 2020-01-15 tracey if (buf_len(bca.blamebuf) > 0) {
2473 2e676fc5 2020-01-15 tracey error = buf_putc(bca.blamebuf, '\0');
2474 2e676fc5 2020-01-15 tracey blame_html = strdup(buf_get(bca.blamebuf));
2475 2e676fc5 2020-01-15 tracey }
2476 ec46ccd7 2020-01-15 tracey done:
2477 e46f587c 2020-01-29 tracey free(bca.line_offsets);
2478 2e676fc5 2020-01-15 tracey free(bca.blamebuf);
2479 2e676fc5 2020-01-15 tracey free(in_repo_path);
2480 2e676fc5 2020-01-15 tracey free(commit_id);
2481 2e676fc5 2020-01-15 tracey free(obj_id);
2482 2e676fc5 2020-01-15 tracey free(path);
2483 2e676fc5 2020-01-15 tracey
2484 e46f587c 2020-01-29 tracey if (gw_trans->action != GW_BLOB && bca.lines) {
2485 2e676fc5 2020-01-15 tracey for (i = 0; i < bca.nlines; i++) {
2486 2e676fc5 2020-01-15 tracey struct blame_line *bline = &bca.lines[i];
2487 2e676fc5 2020-01-15 tracey free(bline->id_str);
2488 2e676fc5 2020-01-15 tracey free(bline->committer);
2489 2e676fc5 2020-01-15 tracey }
2490 2e676fc5 2020-01-15 tracey free(bca.lines);
2491 2e676fc5 2020-01-15 tracey }
2492 e46f587c 2020-01-29 tracey if (error)
2493 e46f587c 2020-01-29 tracey return NULL;
2494 2e676fc5 2020-01-15 tracey if (bca.f && fclose(bca.f) == EOF && error == NULL)
2495 e46f587c 2020-01-29 tracey return NULL;
2496 e46f587c 2020-01-29 tracey if (blob)
2497 e46f587c 2020-01-29 tracey error = got_object_blob_close(blob);
2498 2e676fc5 2020-01-15 tracey if (error)
2499 2e676fc5 2020-01-15 tracey return NULL;
2500 e46f587c 2020-01-29 tracey if (repo)
2501 e46f587c 2020-01-29 tracey error = got_repo_close(repo);
2502 e46f587c 2020-01-29 tracey if (error)
2503 e46f587c 2020-01-29 tracey return NULL;
2504 ec46ccd7 2020-01-15 tracey else
2505 ec46ccd7 2020-01-15 tracey return blame_html;
2506 ec46ccd7 2020-01-15 tracey }
2507 ec46ccd7 2020-01-15 tracey
2508 ec46ccd7 2020-01-15 tracey static char*
2509 f2f46662 2020-01-23 tracey gw_get_repo_tree(struct gw_trans *gw_trans)
2510 ec46ccd7 2020-01-15 tracey {
2511 ec46ccd7 2020-01-15 tracey const struct got_error *error = NULL;
2512 ec46ccd7 2020-01-15 tracey struct got_repository *repo = NULL;
2513 bcbc97d8 2020-01-15 tracey struct got_object_id *tree_id = NULL, *commit_id = NULL;
2514 bcbc97d8 2020-01-15 tracey struct got_tree_object *tree = NULL;
2515 bcbc97d8 2020-01-15 tracey struct buf *diffbuf = NULL;
2516 bcbc97d8 2020-01-15 tracey size_t newsize;
2517 bcbc97d8 2020-01-15 tracey char *tree_html = NULL, *path = NULL, *in_repo_path = NULL,
2518 c3bcdfd5 2020-01-29 tracey *tree_row = NULL, *id_str, *class = NULL;
2519 c3bcdfd5 2020-01-29 tracey int nentries, i, class_flip = 0;
2520 8d4d2453 2020-01-15 tracey
2521 bcbc97d8 2020-01-15 tracey error = buf_alloc(&diffbuf, 0);
2522 ec46ccd7 2020-01-15 tracey if (error)
2523 bcbc97d8 2020-01-15 tracey return NULL;
2524 bcbc97d8 2020-01-15 tracey
2525 bcbc97d8 2020-01-15 tracey error = got_repo_open(&repo, gw_trans->repo_path, NULL);
2526 ec46ccd7 2020-01-15 tracey if (error)
2527 bcbc97d8 2020-01-15 tracey goto done;
2528 bcbc97d8 2020-01-15 tracey
2529 bcbc97d8 2020-01-15 tracey error = got_repo_map_path(&in_repo_path, repo, gw_trans->repo_path, 1);
2530 ec46ccd7 2020-01-15 tracey if (error)
2531 bcbc97d8 2020-01-15 tracey goto done;
2532 bcbc97d8 2020-01-15 tracey
2533 ec46ccd7 2020-01-15 tracey if (gw_trans->repo_folder != NULL)
2534 ec46ccd7 2020-01-15 tracey path = strdup(gw_trans->repo_folder);
2535 ec46ccd7 2020-01-15 tracey else if (in_repo_path) {
2536 bcbc97d8 2020-01-15 tracey free(path);
2537 bcbc97d8 2020-01-15 tracey path = in_repo_path;
2538 bcbc97d8 2020-01-15 tracey }
2539 bcbc97d8 2020-01-15 tracey
2540 f2f46662 2020-01-23 tracey if (gw_trans->commit == NULL) {
2541 ec46ccd7 2020-01-15 tracey struct got_reference *head_ref;
2542 ec46ccd7 2020-01-15 tracey error = got_ref_open(&head_ref, repo, gw_trans->headref, 0);
2543 ec46ccd7 2020-01-15 tracey if (error)
2544 ec46ccd7 2020-01-15 tracey goto done;
2545 ec46ccd7 2020-01-15 tracey
2546 ec46ccd7 2020-01-15 tracey error = got_ref_resolve(&commit_id, repo, head_ref);
2547 ec46ccd7 2020-01-15 tracey got_ref_close(head_ref);
2548 ec46ccd7 2020-01-15 tracey
2549 ec46ccd7 2020-01-15 tracey } else
2550 f2f46662 2020-01-23 tracey error = got_repo_match_object_id(&commit_id, NULL,
2551 f2f46662 2020-01-23 tracey gw_trans->commit, GOT_OBJ_TYPE_COMMIT, 1, repo);
2552 f2f46662 2020-01-23 tracey if (error)
2553 f2f46662 2020-01-23 tracey goto done;
2554 f2f46662 2020-01-23 tracey
2555 f2f46662 2020-01-23 tracey error = got_object_id_str(&gw_trans->commit, commit_id);
2556 bcbc97d8 2020-01-15 tracey if (error)
2557 bcbc97d8 2020-01-15 tracey goto done;
2558 bcbc97d8 2020-01-15 tracey
2559 ec46ccd7 2020-01-15 tracey error = got_object_id_by_path(&tree_id, repo, commit_id, path);
2560 bcbc97d8 2020-01-15 tracey if (error)
2561 bcbc97d8 2020-01-15 tracey goto done;
2562 bcbc97d8 2020-01-15 tracey
2563 bcbc97d8 2020-01-15 tracey error = got_object_open_as_tree(&tree, repo, tree_id);
2564 bcbc97d8 2020-01-15 tracey if (error)
2565 bcbc97d8 2020-01-15 tracey goto done;
2566 bcbc97d8 2020-01-15 tracey
2567 bcbc97d8 2020-01-15 tracey nentries = got_object_tree_get_nentries(tree);
2568 bcbc97d8 2020-01-15 tracey
2569 bcbc97d8 2020-01-15 tracey for (i = 0; i < nentries; i++) {
2570 bcbc97d8 2020-01-15 tracey struct got_tree_entry *te;
2571 ec46ccd7 2020-01-15 tracey const char *modestr = "";
2572 ec46ccd7 2020-01-15 tracey char *id = NULL, *url_html = NULL;
2573 bcbc97d8 2020-01-15 tracey
2574 bcbc97d8 2020-01-15 tracey te = got_object_tree_get_entry(tree, i);
2575 bcbc97d8 2020-01-15 tracey
2576 bcbc97d8 2020-01-15 tracey error = got_object_id_str(&id_str, got_tree_entry_get_id(te));
2577 bcbc97d8 2020-01-15 tracey if (error)
2578 bcbc97d8 2020-01-15 tracey goto done;
2579 bcbc97d8 2020-01-15 tracey
2580 88d59c36 2020-01-29 stsp if (asprintf(&id, "%s", id_str) == -1) {
2581 bcbc97d8 2020-01-15 tracey error = got_error_from_errno("asprintf");
2582 bcbc97d8 2020-01-15 tracey free(id_str);
2583 bcbc97d8 2020-01-15 tracey goto done;
2584 bcbc97d8 2020-01-15 tracey }
2585 bcbc97d8 2020-01-15 tracey
2586 bcbc97d8 2020-01-15 tracey mode_t mode = got_tree_entry_get_mode(te);
2587 bcbc97d8 2020-01-15 tracey
2588 bcbc97d8 2020-01-15 tracey if (got_object_tree_entry_is_submodule(te))
2589 bcbc97d8 2020-01-15 tracey modestr = "$";
2590 bcbc97d8 2020-01-15 tracey else if (S_ISLNK(mode))
2591 bcbc97d8 2020-01-15 tracey modestr = "@";
2592 bcbc97d8 2020-01-15 tracey else if (S_ISDIR(mode))
2593 bcbc97d8 2020-01-15 tracey modestr = "/";
2594 bcbc97d8 2020-01-15 tracey else if (mode & S_IXUSR)
2595 bcbc97d8 2020-01-15 tracey modestr = "*";
2596 c3bcdfd5 2020-01-29 tracey
2597 c3bcdfd5 2020-01-29 tracey if (class_flip == 0) {
2598 c3bcdfd5 2020-01-29 tracey class = strdup("back_lightgray");
2599 c3bcdfd5 2020-01-29 tracey class_flip = 1;
2600 c3bcdfd5 2020-01-29 tracey } else {
2601 c3bcdfd5 2020-01-29 tracey class = strdup("back_white");
2602 c3bcdfd5 2020-01-29 tracey class_flip = 0;
2603 c3bcdfd5 2020-01-29 tracey }
2604 bcbc97d8 2020-01-15 tracey
2605 ec46ccd7 2020-01-15 tracey char *build_folder = NULL;
2606 ec46ccd7 2020-01-15 tracey if (S_ISDIR(got_tree_entry_get_mode(te))) {
2607 ec46ccd7 2020-01-15 tracey if (gw_trans->repo_folder != NULL) {
2608 88d59c36 2020-01-29 stsp if (asprintf(&build_folder, "%s/%s",
2609 ec46ccd7 2020-01-15 tracey gw_trans->repo_folder,
2610 88d59c36 2020-01-29 stsp got_tree_entry_get_name(te)) == -1) {
2611 ec46ccd7 2020-01-15 tracey error =
2612 ec46ccd7 2020-01-15 tracey got_error_from_errno("asprintf");
2613 ec46ccd7 2020-01-15 tracey goto done;
2614 ec46ccd7 2020-01-15 tracey }
2615 ec46ccd7 2020-01-15 tracey } else {
2616 ec46ccd7 2020-01-15 tracey if (asprintf(&build_folder, "%s",
2617 ec46ccd7 2020-01-15 tracey got_tree_entry_get_name(te)) == -1)
2618 ec46ccd7 2020-01-15 tracey goto done;
2619 ec46ccd7 2020-01-15 tracey }
2620 ec46ccd7 2020-01-15 tracey
2621 88d59c36 2020-01-29 stsp if (asprintf(&url_html, folder_html,
2622 ec46ccd7 2020-01-15 tracey gw_trans->repo_name, gw_trans->action_name,
2623 ec46ccd7 2020-01-15 tracey gw_trans->commit, build_folder,
2624 88d59c36 2020-01-29 stsp got_tree_entry_get_name(te), modestr) == -1) {
2625 ec46ccd7 2020-01-15 tracey error = got_error_from_errno("asprintf");
2626 ec46ccd7 2020-01-15 tracey goto done;
2627 ec46ccd7 2020-01-15 tracey }
2628 e46f587c 2020-01-29 tracey if (asprintf(&tree_row, tree_line, class, url_html,
2629 e46f587c 2020-01-29 tracey class) == -1) {
2630 e46f587c 2020-01-29 tracey error = got_error_from_errno("asprintf");
2631 e46f587c 2020-01-29 tracey goto done;
2632 e46f587c 2020-01-29 tracey }
2633 e46f587c 2020-01-29 tracey
2634 ec46ccd7 2020-01-15 tracey } else {
2635 ec46ccd7 2020-01-15 tracey if (gw_trans->repo_folder != NULL) {
2636 88d59c36 2020-01-29 stsp if (asprintf(&build_folder, "%s",
2637 88d59c36 2020-01-29 stsp gw_trans->repo_folder) == -1) {
2638 ec46ccd7 2020-01-15 tracey error =
2639 ec46ccd7 2020-01-15 tracey got_error_from_errno("asprintf");
2640 ec46ccd7 2020-01-15 tracey goto done;
2641 ec46ccd7 2020-01-15 tracey }
2642 ec46ccd7 2020-01-15 tracey } else
2643 ec46ccd7 2020-01-15 tracey build_folder = strdup("");
2644 ec46ccd7 2020-01-15 tracey
2645 88d59c36 2020-01-29 stsp if (asprintf(&url_html, file_html, gw_trans->repo_name,
2646 e46f587c 2020-01-29 tracey "blob", gw_trans->commit,
2647 ec46ccd7 2020-01-15 tracey got_tree_entry_get_name(te), build_folder,
2648 88d59c36 2020-01-29 stsp got_tree_entry_get_name(te), modestr) == -1) {
2649 ec46ccd7 2020-01-15 tracey error = got_error_from_errno("asprintf");
2650 ec46ccd7 2020-01-15 tracey goto done;
2651 ec46ccd7 2020-01-15 tracey }
2652 e46f587c 2020-01-29 tracey
2653 e46f587c 2020-01-29 tracey if (asprintf(&tree_row, tree_line_with_navs, class,
2654 e46f587c 2020-01-29 tracey url_html, class, gw_trans->repo_name, "blob",
2655 e46f587c 2020-01-29 tracey gw_trans->commit, got_tree_entry_get_name(te),
2656 e46f587c 2020-01-29 tracey build_folder, "blob", gw_trans->repo_name,
2657 e46f587c 2020-01-29 tracey "blame", gw_trans->commit,
2658 e46f587c 2020-01-29 tracey got_tree_entry_get_name(te), build_folder,
2659 e46f587c 2020-01-29 tracey "blame") == -1) {
2660 e46f587c 2020-01-29 tracey error = got_error_from_errno("asprintf");
2661 e46f587c 2020-01-29 tracey goto done;
2662 e46f587c 2020-01-29 tracey }
2663 ec46ccd7 2020-01-15 tracey }
2664 ec46ccd7 2020-01-15 tracey free(build_folder);
2665 ec46ccd7 2020-01-15 tracey
2666 ec46ccd7 2020-01-15 tracey if (error)
2667 ec46ccd7 2020-01-15 tracey goto done;
2668 ec46ccd7 2020-01-15 tracey
2669 bcbc97d8 2020-01-15 tracey error = buf_puts(&newsize, diffbuf, tree_row);
2670 ec46ccd7 2020-01-15 tracey if (error)
2671 ec46ccd7 2020-01-15 tracey goto done;
2672 ec46ccd7 2020-01-15 tracey
2673 bcbc97d8 2020-01-15 tracey free(id);
2674 bcbc97d8 2020-01-15 tracey free(id_str);
2675 ec46ccd7 2020-01-15 tracey free(url_html);
2676 ec46ccd7 2020-01-15 tracey free(tree_row);
2677 bcbc97d8 2020-01-15 tracey }
2678 bcbc97d8 2020-01-15 tracey
2679 bcbc97d8 2020-01-15 tracey if (buf_len(diffbuf) > 0) {
2680 bcbc97d8 2020-01-15 tracey error = buf_putc(diffbuf, '\0');
2681 bcbc97d8 2020-01-15 tracey tree_html = strdup(buf_get(diffbuf));
2682 bcbc97d8 2020-01-15 tracey }
2683 bcbc97d8 2020-01-15 tracey done:
2684 bcbc97d8 2020-01-15 tracey if (tree)
2685 bcbc97d8 2020-01-15 tracey got_object_tree_close(tree);
2686 2e676fc5 2020-01-15 tracey if (repo)
2687 2e676fc5 2020-01-15 tracey got_repo_close(repo);
2688 bcbc97d8 2020-01-15 tracey
2689 2e676fc5 2020-01-15 tracey free(in_repo_path);
2690 bcbc97d8 2020-01-15 tracey free(tree_id);
2691 bcbc97d8 2020-01-15 tracey free(diffbuf);
2692 bcbc97d8 2020-01-15 tracey if (error)
2693 bcbc97d8 2020-01-15 tracey return NULL;
2694 bcbc97d8 2020-01-15 tracey else
2695 bcbc97d8 2020-01-15 tracey return tree_html;
2696 bcbc97d8 2020-01-15 tracey }
2697 bcbc97d8 2020-01-15 tracey
2698 8d4d2453 2020-01-15 tracey static char *
2699 54415d85 2020-01-15 tracey gw_get_repo_heads(struct gw_trans *gw_trans)
2700 8d4d2453 2020-01-15 tracey {
2701 87f9ebf5 2020-01-15 tracey const struct got_error *error = NULL;
2702 87f9ebf5 2020-01-15 tracey struct got_repository *repo = NULL;
2703 87f9ebf5 2020-01-15 tracey struct got_reflist_head refs;
2704 87f9ebf5 2020-01-15 tracey struct got_reflist_entry *re;
2705 87f9ebf5 2020-01-15 tracey char *heads, *head_row = NULL, *head_navs_disp = NULL, *age = NULL;
2706 87f9ebf5 2020-01-15 tracey struct buf *diffbuf = NULL;
2707 87f9ebf5 2020-01-15 tracey size_t newsize;
2708 a0f36e03 2020-01-28 stsp
2709 a0f36e03 2020-01-28 stsp SIMPLEQ_INIT(&refs);
2710 8d4d2453 2020-01-15 tracey
2711 6c6c85af 2020-01-15 tracey error = buf_alloc(&diffbuf, 0);
2712 ec46ccd7 2020-01-15 tracey if (error)
2713 6c6c85af 2020-01-15 tracey return NULL;
2714 87f9ebf5 2020-01-15 tracey
2715 87f9ebf5 2020-01-15 tracey error = got_repo_open(&repo, gw_trans->repo_path, NULL);
2716 ec46ccd7 2020-01-15 tracey if (error)
2717 87f9ebf5 2020-01-15 tracey goto done;
2718 87f9ebf5 2020-01-15 tracey
2719 87f9ebf5 2020-01-15 tracey error = got_ref_list(&refs, repo, "refs/heads", got_ref_cmp_by_name,
2720 87f9ebf5 2020-01-15 tracey NULL);
2721 87f9ebf5 2020-01-15 tracey if (error)
2722 87f9ebf5 2020-01-15 tracey goto done;
2723 87f9ebf5 2020-01-15 tracey
2724 87f9ebf5 2020-01-15 tracey SIMPLEQ_FOREACH(re, &refs, entry) {
2725 87f9ebf5 2020-01-15 tracey char *refname;
2726 87f9ebf5 2020-01-15 tracey
2727 87f9ebf5 2020-01-15 tracey refname = strdup(got_ref_get_name(re->ref));
2728 87f9ebf5 2020-01-15 tracey if (refname == NULL) {
2729 87f9ebf5 2020-01-15 tracey error = got_error_from_errno("got_ref_to_str");
2730 87f9ebf5 2020-01-15 tracey goto done;
2731 87f9ebf5 2020-01-15 tracey }
2732 87f9ebf5 2020-01-15 tracey
2733 87f9ebf5 2020-01-15 tracey if (strncmp(refname, "refs/heads/", 11) != 0) {
2734 87f9ebf5 2020-01-15 tracey free(refname);
2735 87f9ebf5 2020-01-15 tracey continue;
2736 87f9ebf5 2020-01-15 tracey }
2737 87f9ebf5 2020-01-15 tracey
2738 d126c1b7 2020-01-29 stsp error = gw_get_repo_age(&age, gw_trans, gw_trans->gw_dir->path, refname,
2739 87f9ebf5 2020-01-15 tracey TM_DIFF);
2740 d126c1b7 2020-01-29 stsp if (error)
2741 d126c1b7 2020-01-29 stsp goto done;
2742 87f9ebf5 2020-01-15 tracey
2743 88d59c36 2020-01-29 stsp if (asprintf(&head_navs_disp, heads_navs, gw_trans->repo_name,
2744 87f9ebf5 2020-01-15 tracey refname, gw_trans->repo_name, refname,
2745 87f9ebf5 2020-01-15 tracey gw_trans->repo_name, refname, gw_trans->repo_name,
2746 88d59c36 2020-01-29 stsp refname) == -1) {
2747 87f9ebf5 2020-01-15 tracey error = got_error_from_errno("asprintf");
2748 87f9ebf5 2020-01-15 tracey goto done;
2749 87f9ebf5 2020-01-15 tracey }
2750 87f9ebf5 2020-01-15 tracey
2751 87f9ebf5 2020-01-15 tracey if (strncmp(refname, "refs/heads/", 11) == 0)
2752 87f9ebf5 2020-01-15 tracey refname += 11;
2753 87f9ebf5 2020-01-15 tracey
2754 88d59c36 2020-01-29 stsp if (asprintf(&head_row, heads_row, age, refname,
2755 88d59c36 2020-01-29 stsp head_navs_disp) == -1) {
2756 87f9ebf5 2020-01-15 tracey error = got_error_from_errno("asprintf");
2757 87f9ebf5 2020-01-15 tracey goto done;
2758 87f9ebf5 2020-01-15 tracey }
2759 87f9ebf5 2020-01-15 tracey
2760 6c6c85af 2020-01-15 tracey error = buf_puts(&newsize, diffbuf, head_row);
2761 87f9ebf5 2020-01-15 tracey
2762 87f9ebf5 2020-01-15 tracey free(head_navs_disp);
2763 87f9ebf5 2020-01-15 tracey free(head_row);
2764 87f9ebf5 2020-01-15 tracey }
2765 87f9ebf5 2020-01-15 tracey
2766 6c6c85af 2020-01-15 tracey if (buf_len(diffbuf) > 0) {
2767 6c6c85af 2020-01-15 tracey error = buf_putc(diffbuf, '\0');
2768 6c6c85af 2020-01-15 tracey heads = strdup(buf_get(diffbuf));
2769 6c6c85af 2020-01-15 tracey }
2770 87f9ebf5 2020-01-15 tracey done:
2771 87f9ebf5 2020-01-15 tracey buf_free(diffbuf);
2772 87f9ebf5 2020-01-15 tracey got_ref_list_free(&refs);
2773 87f9ebf5 2020-01-15 tracey if (repo)
2774 87f9ebf5 2020-01-15 tracey got_repo_close(repo);
2775 87f9ebf5 2020-01-15 tracey if (error)
2776 87f9ebf5 2020-01-15 tracey return NULL;
2777 87f9ebf5 2020-01-15 tracey else
2778 87f9ebf5 2020-01-15 tracey return heads;
2779 8d4d2453 2020-01-15 tracey }
2780 8d4d2453 2020-01-15 tracey
2781 8d4d2453 2020-01-15 tracey static char *
2782 54415d85 2020-01-15 tracey gw_get_got_link(struct gw_trans *gw_trans)
2783 2c251c14 2020-01-15 tracey {
2784 2c251c14 2020-01-15 tracey char *link;
2785 2c251c14 2020-01-15 tracey
2786 88d59c36 2020-01-29 stsp if (asprintf(&link, got_link, gw_trans->gw_conf->got_logo_url,
2787 88d59c36 2020-01-29 stsp gw_trans->gw_conf->got_logo) == -1)
2788 2c251c14 2020-01-15 tracey return NULL;
2789 2c251c14 2020-01-15 tracey
2790 2c251c14 2020-01-15 tracey return link;
2791 2c251c14 2020-01-15 tracey }
2792 2c251c14 2020-01-15 tracey
2793 2c251c14 2020-01-15 tracey static char *
2794 54415d85 2020-01-15 tracey gw_get_site_link(struct gw_trans *gw_trans)
2795 2c251c14 2020-01-15 tracey {
2796 2c251c14 2020-01-15 tracey char *link, *repo = "", *action = "";
2797 2c251c14 2020-01-15 tracey
2798 2c251c14 2020-01-15 tracey if (gw_trans->repo_name != NULL)
2799 88d59c36 2020-01-29 stsp if (asprintf(&repo, " / <a href='?path=%s&action=summary'>%s" \
2800 88d59c36 2020-01-29 stsp "</a>", gw_trans->repo_name, gw_trans->repo_name) == -1)
2801 2c251c14 2020-01-15 tracey return NULL;
2802 2c251c14 2020-01-15 tracey
2803 2c251c14 2020-01-15 tracey if (gw_trans->action_name != NULL)
2804 88d59c36 2020-01-29 stsp if (asprintf(&action, " / %s", gw_trans->action_name) == -1)
2805 2c251c14 2020-01-15 tracey return NULL;
2806 2c251c14 2020-01-15 tracey
2807 88d59c36 2020-01-29 stsp if (asprintf(&link, site_link, GOTWEB,
2808 88d59c36 2020-01-29 stsp gw_trans->gw_conf->got_site_link, repo, action) == -1)
2809 2c251c14 2020-01-15 tracey return NULL;
2810 2c251c14 2020-01-15 tracey
2811 2c251c14 2020-01-15 tracey return link;
2812 2c251c14 2020-01-15 tracey }
2813 2c251c14 2020-01-15 tracey
2814 2c251c14 2020-01-15 tracey static char *
2815 d0ea9c5b 2020-01-15 tracey gw_colordiff_line(char *buf)
2816 ec46ccd7 2020-01-15 tracey {
2817 ec46ccd7 2020-01-15 tracey const struct got_error *error = NULL;
2818 ec46ccd7 2020-01-15 tracey char *colorized_line = NULL, *div_diff_line_div = NULL, *color = NULL;
2819 ec46ccd7 2020-01-15 tracey struct buf *diffbuf = NULL;
2820 ec46ccd7 2020-01-15 tracey size_t newsize;
2821 ec46ccd7 2020-01-15 tracey
2822 ec46ccd7 2020-01-15 tracey error = buf_alloc(&diffbuf, 0);
2823 ec46ccd7 2020-01-15 tracey if (error)
2824 ec46ccd7 2020-01-15 tracey return NULL;
2825 ec46ccd7 2020-01-15 tracey
2826 bfd30182 2020-01-24 tracey if (buf == NULL)
2827 bfd30182 2020-01-24 tracey return NULL;
2828 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "-", 1) == 0)
2829 ec46ccd7 2020-01-15 tracey color = "diff_minus";
2830 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "+", 1) == 0)
2831 ec46ccd7 2020-01-15 tracey color = "diff_plus";
2832 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "@@", 2) == 0)
2833 ec46ccd7 2020-01-15 tracey color = "diff_chunk_header";
2834 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "@@", 2) == 0)
2835 ec46ccd7 2020-01-15 tracey color = "diff_chunk_header";
2836 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "commit +", 8) == 0)
2837 ec46ccd7 2020-01-15 tracey color = "diff_meta";
2838 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "commit -", 8) == 0)
2839 ec46ccd7 2020-01-15 tracey color = "diff_meta";
2840 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "blob +", 6) == 0)
2841 ec46ccd7 2020-01-15 tracey color = "diff_meta";
2842 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "blob -", 6) == 0)
2843 ec46ccd7 2020-01-15 tracey color = "diff_meta";
2844 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "file +", 6) == 0)
2845 ec46ccd7 2020-01-15 tracey color = "diff_meta";
2846 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "file -", 6) == 0)
2847 ec46ccd7 2020-01-15 tracey color = "diff_meta";
2848 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "from:", 5) == 0)
2849 ec46ccd7 2020-01-15 tracey color = "diff_author";
2850 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "via:", 4) == 0)
2851 ec46ccd7 2020-01-15 tracey color = "diff_author";
2852 ec46ccd7 2020-01-15 tracey if (strncmp(buf, "date:", 5) == 0)
2853 ec46ccd7 2020-01-15 tracey color = "diff_date";
2854 ec46ccd7 2020-01-15 tracey
2855 88d59c36 2020-01-29 stsp if (asprintf(&div_diff_line_div, div_diff_line, color) == -1)
2856 ec46ccd7 2020-01-15 tracey return NULL;
2857 ec46ccd7 2020-01-15 tracey
2858 ec46ccd7 2020-01-15 tracey error = buf_puts(&newsize, diffbuf, div_diff_line_div);
2859 ec46ccd7 2020-01-15 tracey if (error)
2860 ec46ccd7 2020-01-15 tracey return NULL;
2861 ec46ccd7 2020-01-15 tracey
2862 ec46ccd7 2020-01-15 tracey error = buf_puts(&newsize, diffbuf, buf);
2863 ec46ccd7 2020-01-15 tracey if (error)
2864 ec46ccd7 2020-01-15 tracey return NULL;
2865 ec46ccd7 2020-01-15 tracey
2866 ec46ccd7 2020-01-15 tracey if (buf_len(diffbuf) > 0) {
2867 ec46ccd7 2020-01-15 tracey error = buf_putc(diffbuf, '\0');
2868 ec46ccd7 2020-01-15 tracey colorized_line = strdup(buf_get(diffbuf));
2869 ec46ccd7 2020-01-15 tracey }
2870 ec46ccd7 2020-01-15 tracey
2871 ec46ccd7 2020-01-15 tracey free(diffbuf);
2872 ec46ccd7 2020-01-15 tracey free(div_diff_line_div);
2873 ec46ccd7 2020-01-15 tracey return colorized_line;
2874 ec46ccd7 2020-01-15 tracey }
2875 ec46ccd7 2020-01-15 tracey
2876 ec46ccd7 2020-01-15 tracey static char *
2877 2c251c14 2020-01-15 tracey gw_html_escape(const char *html)
2878 2c251c14 2020-01-15 tracey {
2879 2c251c14 2020-01-15 tracey char *escaped_str = NULL, *buf;
2880 2c251c14 2020-01-15 tracey char c[1];
2881 6c6c85af 2020-01-15 tracey size_t sz, i, buff_sz = 2048;
2882 2c251c14 2020-01-15 tracey
2883 6c6c85af 2020-01-15 tracey if ((buf = calloc(buff_sz, sizeof(char *))) == NULL)
2884 2c251c14 2020-01-15 tracey return NULL;
2885 2c251c14 2020-01-15 tracey
2886 2c251c14 2020-01-15 tracey if (html == NULL)
2887 2c251c14 2020-01-15 tracey return NULL;
2888 2c251c14 2020-01-15 tracey else
2889 2c251c14 2020-01-15 tracey if ((sz = strlen(html)) == 0)
2890 2c251c14 2020-01-15 tracey return NULL;
2891 2c251c14 2020-01-15 tracey
2892 6c6c85af 2020-01-15 tracey /* only work with buff_sz */
2893 6c6c85af 2020-01-15 tracey if (buff_sz < sz)
2894 6c6c85af 2020-01-15 tracey sz = buff_sz;
2895 2c251c14 2020-01-15 tracey
2896 2c251c14 2020-01-15 tracey for (i = 0; i < sz; i++) {
2897 2c251c14 2020-01-15 tracey c[0] = html[i];
2898 2c251c14 2020-01-15 tracey switch (c[0]) {
2899 2c251c14 2020-01-15 tracey case ('>'):
2900 2c251c14 2020-01-15 tracey strcat(buf, "&gt;");
2901 2c251c14 2020-01-15 tracey break;
2902 2c251c14 2020-01-15 tracey case ('&'):
2903 2c251c14 2020-01-15 tracey strcat(buf, "&amp;");
2904 2c251c14 2020-01-15 tracey break;
2905 2c251c14 2020-01-15 tracey case ('<'):
2906 2c251c14 2020-01-15 tracey strcat(buf, "&lt;");
2907 2c251c14 2020-01-15 tracey break;
2908 2c251c14 2020-01-15 tracey case ('"'):
2909 2c251c14 2020-01-15 tracey strcat(buf, "&quot;");
2910 2c251c14 2020-01-15 tracey break;
2911 2c251c14 2020-01-15 tracey case ('\''):
2912 2c251c14 2020-01-15 tracey strcat(buf, "&apos;");
2913 2c251c14 2020-01-15 tracey break;
2914 2c251c14 2020-01-15 tracey case ('\n'):
2915 2c251c14 2020-01-15 tracey strcat(buf, "<br />");
2916 2c251c14 2020-01-15 tracey default:
2917 2c251c14 2020-01-15 tracey strcat(buf, &c[0]);
2918 2c251c14 2020-01-15 tracey break;
2919 2c251c14 2020-01-15 tracey }
2920 2c251c14 2020-01-15 tracey }
2921 2c251c14 2020-01-15 tracey asprintf(&escaped_str, "%s", buf);
2922 2c251c14 2020-01-15 tracey free(buf);
2923 2c251c14 2020-01-15 tracey return escaped_str;
2924 2c251c14 2020-01-15 tracey }
2925 2c251c14 2020-01-15 tracey
2926 2c251c14 2020-01-15 tracey int
2927 c08369d7 2020-01-15 tracey main(int argc, char *argv[])
2928 2c251c14 2020-01-15 tracey {
2929 2c251c14 2020-01-15 tracey const struct got_error *error = NULL;
2930 54415d85 2020-01-15 tracey struct gw_trans *gw_trans;
2931 2c251c14 2020-01-15 tracey struct gw_dir *dir = NULL, *tdir;
2932 2c251c14 2020-01-15 tracey const char *page = "index";
2933 4ceb8155 2020-01-15 tracey int gw_malloc = 1;
2934 c25c2314 2020-01-28 stsp enum kcgi_err kerr;
2935 2c251c14 2020-01-15 tracey
2936 54415d85 2020-01-15 tracey if ((gw_trans = malloc(sizeof(struct gw_trans))) == NULL)
2937 2c251c14 2020-01-15 tracey errx(1, "malloc");
2938 2c251c14 2020-01-15 tracey
2939 2c251c14 2020-01-15 tracey if ((gw_trans->gw_req = malloc(sizeof(struct kreq))) == NULL)
2940 2c251c14 2020-01-15 tracey errx(1, "malloc");
2941 2c251c14 2020-01-15 tracey
2942 2c251c14 2020-01-15 tracey if ((gw_trans->gw_html_req = malloc(sizeof(struct khtmlreq))) == NULL)
2943 2c251c14 2020-01-15 tracey errx(1, "malloc");
2944 2c251c14 2020-01-15 tracey
2945 2c251c14 2020-01-15 tracey if ((gw_trans->gw_tmpl = malloc(sizeof(struct ktemplate))) == NULL)
2946 2c251c14 2020-01-15 tracey errx(1, "malloc");
2947 2c251c14 2020-01-15 tracey
2948 c25c2314 2020-01-28 stsp kerr = khttp_parse(gw_trans->gw_req, gw_keys, KEY__ZMAX, &page, 1, 0);
2949 c25c2314 2020-01-28 stsp if (kerr != KCGI_OK) {
2950 c25c2314 2020-01-28 stsp error = gw_kcgi_error(kerr);
2951 c119608e 2020-01-28 stsp goto done;
2952 c25c2314 2020-01-28 stsp }
2953 2c251c14 2020-01-15 tracey
2954 2c251c14 2020-01-15 tracey if ((gw_trans->gw_conf =
2955 2c251c14 2020-01-15 tracey malloc(sizeof(struct gotweb_conf))) == NULL) {
2956 4ceb8155 2020-01-15 tracey gw_malloc = 0;
2957 387a29ba 2020-01-15 tracey error = got_error_from_errno("malloc");
2958 c119608e 2020-01-28 stsp goto done;
2959 46b9c89b 2020-01-15 tracey }
2960 46b9c89b 2020-01-15 tracey
2961 2c251c14 2020-01-15 tracey TAILQ_INIT(&gw_trans->gw_dirs);
2962 f2f46662 2020-01-23 tracey TAILQ_INIT(&gw_trans->gw_headers);
2963 2c251c14 2020-01-15 tracey
2964 2c251c14 2020-01-15 tracey gw_trans->page = 0;
2965 2c251c14 2020-01-15 tracey gw_trans->repos_total = 0;
2966 2c251c14 2020-01-15 tracey gw_trans->repo_path = NULL;
2967 2c251c14 2020-01-15 tracey gw_trans->commit = NULL;
2968 8087c3c5 2020-01-15 tracey gw_trans->headref = strdup(GOT_REF_HEAD);
2969 2c251c14 2020-01-15 tracey gw_trans->mime = KMIME_TEXT_HTML;
2970 54415d85 2020-01-15 tracey gw_trans->gw_tmpl->key = gw_templs;
2971 2c251c14 2020-01-15 tracey gw_trans->gw_tmpl->keysz = TEMPL__MAX;
2972 2c251c14 2020-01-15 tracey gw_trans->gw_tmpl->arg = gw_trans;
2973 2c251c14 2020-01-15 tracey gw_trans->gw_tmpl->cb = gw_template;
2974 2c251c14 2020-01-15 tracey error = parse_conf(GOTWEB_CONF, gw_trans->gw_conf);
2975 c119608e 2020-01-28 stsp if (error)
2976 2c251c14 2020-01-15 tracey goto done;
2977 2c251c14 2020-01-15 tracey
2978 2c251c14 2020-01-15 tracey error = gw_parse_querystring(gw_trans);
2979 2c251c14 2020-01-15 tracey if (error)
2980 c119608e 2020-01-28 stsp goto done;
2981 2c251c14 2020-01-15 tracey
2982 6d8d8a26 2020-01-29 stsp error = gw_display_index(gw_trans);
2983 2c251c14 2020-01-15 tracey done:
2984 c119608e 2020-01-28 stsp if (error) {
2985 c119608e 2020-01-28 stsp gw_trans->mime = KMIME_TEXT_PLAIN;
2986 c119608e 2020-01-28 stsp gw_trans->action = GW_ERR;
2987 6d8d8a26 2020-01-29 stsp gw_display_error(gw_trans, error);
2988 c119608e 2020-01-28 stsp }
2989 2c251c14 2020-01-15 tracey if (gw_malloc) {
2990 2c251c14 2020-01-15 tracey free(gw_trans->gw_conf->got_repos_path);
2991 2c251c14 2020-01-15 tracey free(gw_trans->gw_conf->got_site_name);
2992 2c251c14 2020-01-15 tracey free(gw_trans->gw_conf->got_site_owner);
2993 2c251c14 2020-01-15 tracey free(gw_trans->gw_conf->got_site_link);
2994 2c251c14 2020-01-15 tracey free(gw_trans->gw_conf->got_logo);
2995 2c251c14 2020-01-15 tracey free(gw_trans->gw_conf->got_logo_url);
2996 2c251c14 2020-01-15 tracey free(gw_trans->gw_conf);
2997 2c251c14 2020-01-15 tracey free(gw_trans->commit);
2998 2c251c14 2020-01-15 tracey free(gw_trans->repo_path);
2999 2c251c14 2020-01-15 tracey free(gw_trans->repo_name);
3000 2c251c14 2020-01-15 tracey free(gw_trans->repo_file);
3001 2c251c14 2020-01-15 tracey free(gw_trans->action_name);
3002 8087c3c5 2020-01-15 tracey free(gw_trans->headref);
3003 2c251c14 2020-01-15 tracey
3004 2c251c14 2020-01-15 tracey TAILQ_FOREACH_SAFE(dir, &gw_trans->gw_dirs, entry, tdir) {
3005 2c251c14 2020-01-15 tracey free(dir->name);
3006 2c251c14 2020-01-15 tracey free(dir->description);
3007 2c251c14 2020-01-15 tracey free(dir->age);
3008 2c251c14 2020-01-15 tracey free(dir->url);
3009 2c251c14 2020-01-15 tracey free(dir->path);
3010 2c251c14 2020-01-15 tracey free(dir);
3011 2c251c14 2020-01-15 tracey }
3012 2c251c14 2020-01-15 tracey
3013 2c251c14 2020-01-15 tracey }
3014 2c251c14 2020-01-15 tracey
3015 2c251c14 2020-01-15 tracey khttp_free(gw_trans->gw_req);
3016 d56b34ca 2020-01-29 stsp return 0;
3017 2c251c14 2020-01-15 tracey }