|
diff --git a/cgit.c b/cgit.c index 2039ab1..779a464 100644 --- a/ cgit.c+++ b/ cgit.c |
|
@@ -1,43 +1,58 @@ |
1 | /* cgit.c: cgi for the git scm |
1 | /* cgit.c: cgi for the git scm |
2 | * |
2 | * |
3 | * Copyright (C) 2006 Lars Hjemli |
3 | * Copyright (C) 2006 Lars Hjemli |
4 | * |
4 | * |
5 | * Licensed under GNU General Public License v2 |
5 | * Licensed under GNU General Public License v2 |
6 | * (see COPYING for full license text) |
6 | * (see COPYING for full license text) |
7 | */ |
7 | */ |
8 | |
8 | |
9 | #include "cgit.h" |
9 | #include "cgit.h" |
10 | #include "cache.h" |
10 | #include "cache.h" |
11 | #include "cmd.h" |
11 | #include "cmd.h" |
12 | #include "configfile.h" |
12 | #include "configfile.h" |
13 | #include "html.h" |
13 | #include "html.h" |
14 | #include "ui-shared.h" |
14 | #include "ui-shared.h" |
15 | #include "ui-stats.h" |
15 | #include "ui-stats.h" |
16 | #include "scan-tree.h" |
16 | #include "scan-tree.h" |
17 | |
17 | |
18 | const char *cgit_version = CGIT_VERSION; |
18 | const char *cgit_version = CGIT_VERSION; |
19 | |
19 | |
| |
20 | struct cgit_filter *new_filter(const char *cmd, int extra_args) |
| |
21 | { |
| |
22 | struct cgit_filter *f; |
| |
23 | |
| |
24 | if (!cmd) |
| |
25 | return NULL; |
| |
26 | |
| |
27 | f = xmalloc(sizeof(struct cgit_filter)); |
| |
28 | f->cmd = xstrdup(cmd); |
| |
29 | f->argv = xmalloc((2 + extra_args) * sizeof(char *)); |
| |
30 | f->argv[0] = f->cmd; |
| |
31 | f->argv[1] = NULL; |
| |
32 | return f; |
| |
33 | } |
| |
34 | |
20 | void config_cb(const char *name, const char *value) |
35 | void config_cb(const char *name, const char *value) |
21 | { |
36 | { |
22 | if (!strcmp(name, "root-title")) |
37 | if (!strcmp(name, "root-title")) |
23 | ctx.cfg.root_title = xstrdup(value); |
38 | ctx.cfg.root_title = xstrdup(value); |
24 | else if (!strcmp(name, "root-desc")) |
39 | else if (!strcmp(name, "root-desc")) |
25 | ctx.cfg.root_desc = xstrdup(value); |
40 | ctx.cfg.root_desc = xstrdup(value); |
26 | else if (!strcmp(name, "root-readme")) |
41 | else if (!strcmp(name, "root-readme")) |
27 | ctx.cfg.root_readme = xstrdup(value); |
42 | ctx.cfg.root_readme = xstrdup(value); |
28 | else if (!strcmp(name, "css")) |
43 | else if (!strcmp(name, "css")) |
29 | ctx.cfg.css = xstrdup(value); |
44 | ctx.cfg.css = xstrdup(value); |
30 | else if (!strcmp(name, "favicon")) |
45 | else if (!strcmp(name, "favicon")) |
31 | ctx.cfg.favicon = xstrdup(value); |
46 | ctx.cfg.favicon = xstrdup(value); |
32 | else if (!strcmp(name, "footer")) |
47 | else if (!strcmp(name, "footer")) |
33 | ctx.cfg.footer = xstrdup(value); |
48 | ctx.cfg.footer = xstrdup(value); |
34 | else if (!strcmp(name, "head-include")) |
49 | else if (!strcmp(name, "head-include")) |
35 | ctx.cfg.head_include = xstrdup(value); |
50 | ctx.cfg.head_include = xstrdup(value); |
36 | else if (!strcmp(name, "header")) |
51 | else if (!strcmp(name, "header")) |
37 | ctx.cfg.header = xstrdup(value); |
52 | ctx.cfg.header = xstrdup(value); |
38 | else if (!strcmp(name, "logo")) |
53 | else if (!strcmp(name, "logo")) |
39 | ctx.cfg.logo = xstrdup(value); |
54 | ctx.cfg.logo = xstrdup(value); |
40 | else if (!strcmp(name, "index-header")) |
55 | else if (!strcmp(name, "index-header")) |
41 | ctx.cfg.index_header = xstrdup(value); |
56 | ctx.cfg.index_header = xstrdup(value); |
42 | else if (!strcmp(name, "index-info")) |
57 | else if (!strcmp(name, "index-info")) |
43 | ctx.cfg.index_info = xstrdup(value); |
58 | ctx.cfg.index_info = xstrdup(value); |
|
|
diff --git a/cgit.h b/cgit.h index 8c64efe..d0fff1f 100644 --- a/ cgit.h+++ b/ cgit.h |
|
@@ -108,48 +108,57 @@ struct reflist { |
108 | }; |
108 | }; |
109 | |
109 | |
110 | struct cgit_query { |
110 | struct cgit_query { |
111 | int has_symref; |
111 | int has_symref; |
112 | int has_sha1; |
112 | int has_sha1; |
113 | char *raw; |
113 | char *raw; |
114 | char *repo; |
114 | char *repo; |
115 | char *page; |
115 | char *page; |
116 | char *search; |
116 | char *search; |
117 | char *grep; |
117 | char *grep; |
118 | char *head; |
118 | char *head; |
119 | char *sha1; |
119 | char *sha1; |
120 | char *sha2; |
120 | char *sha2; |
121 | char *path; |
121 | char *path; |
122 | char *name; |
122 | char *name; |
123 | char *mimetype; |
123 | char *mimetype; |
124 | char *url; |
124 | char *url; |
125 | char *period; |
125 | char *period; |
126 | int ofs; |
126 | int ofs; |
127 | int nohead; |
127 | int nohead; |
128 | char *sort; |
128 | char *sort; |
129 | int showmsg; |
129 | int showmsg; |
130 | }; |
130 | }; |
131 | |
131 | |
| |
132 | struct cgit_filter { |
| |
133 | char *cmd; |
| |
134 | char **argv; |
| |
135 | int old_stdout; |
| |
136 | int pipe_fh[2]; |
| |
137 | int pid; |
| |
138 | int exitstatus; |
| |
139 | }; |
| |
140 | |
132 | struct cgit_config { |
141 | struct cgit_config { |
133 | char *agefile; |
142 | char *agefile; |
134 | char *cache_root; |
143 | char *cache_root; |
135 | char *clone_prefix; |
144 | char *clone_prefix; |
136 | char *css; |
145 | char *css; |
137 | char *favicon; |
146 | char *favicon; |
138 | char *footer; |
147 | char *footer; |
139 | char *head_include; |
148 | char *head_include; |
140 | char *header; |
149 | char *header; |
141 | char *index_header; |
150 | char *index_header; |
142 | char *index_info; |
151 | char *index_info; |
143 | char *logo; |
152 | char *logo; |
144 | char *logo_link; |
153 | char *logo_link; |
145 | char *module_link; |
154 | char *module_link; |
146 | char *repo_group; |
155 | char *repo_group; |
147 | char *robots; |
156 | char *robots; |
148 | char *root_title; |
157 | char *root_title; |
149 | char *root_desc; |
158 | char *root_desc; |
150 | char *root_readme; |
159 | char *root_readme; |
151 | char *script_name; |
160 | char *script_name; |
152 | char *virtual_root; |
161 | char *virtual_root; |
153 | int cache_size; |
162 | int cache_size; |
154 | int cache_dynamic_ttl; |
163 | int cache_dynamic_ttl; |
155 | int cache_max_create_time; |
164 | int cache_max_create_time; |
@@ -227,26 +236,29 @@ extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, |
227 | |
236 | |
228 | extern void *cgit_free_commitinfo(struct commitinfo *info); |
237 | extern void *cgit_free_commitinfo(struct commitinfo *info); |
229 | |
238 | |
230 | extern int cgit_diff_files(const unsigned char *old_sha1, |
239 | extern int cgit_diff_files(const unsigned char *old_sha1, |
231 | const unsigned char *new_sha1, |
240 | const unsigned char *new_sha1, |
232 | unsigned long *old_size, unsigned long *new_size, |
241 | unsigned long *old_size, unsigned long *new_size, |
233 | int *binary, linediff_fn fn); |
242 | int *binary, linediff_fn fn); |
234 | |
243 | |
235 | extern void cgit_diff_tree(const unsigned char *old_sha1, |
244 | extern void cgit_diff_tree(const unsigned char *old_sha1, |
236 | const unsigned char *new_sha1, |
245 | const unsigned char *new_sha1, |
237 | filepair_fn fn, const char *prefix); |
246 | filepair_fn fn, const char *prefix); |
238 | |
247 | |
239 | extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); |
248 | extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); |
240 | |
249 | |
241 | extern char *fmt(const char *format,...); |
250 | extern char *fmt(const char *format,...); |
242 | |
251 | |
243 | extern struct commitinfo *cgit_parse_commit(struct commit *commit); |
252 | extern struct commitinfo *cgit_parse_commit(struct commit *commit); |
244 | extern struct taginfo *cgit_parse_tag(struct tag *tag); |
253 | extern struct taginfo *cgit_parse_tag(struct tag *tag); |
245 | extern void cgit_parse_url(const char *url); |
254 | extern void cgit_parse_url(const char *url); |
246 | |
255 | |
247 | extern const char *cgit_repobasename(const char *reponame); |
256 | extern const char *cgit_repobasename(const char *reponame); |
248 | |
257 | |
249 | extern int cgit_parse_snapshots_mask(const char *str); |
258 | extern int cgit_parse_snapshots_mask(const char *str); |
250 | |
259 | |
| |
260 | extern int cgit_open_filter(struct cgit_filter *filter); |
| |
261 | extern int cgit_close_filter(struct cgit_filter *filter); |
| |
262 | |
251 | |
263 | |
252 | #endif /* CGIT_H */ |
264 | #endif /* CGIT_H */ |
|
|
diff --git a/shared.c b/shared.c index cce0af4..288cfa2 100644 --- a/ shared.c+++ b/ shared.c |
|
@@ -334,24 +334,59 @@ int cgit_parse_snapshots_mask(const char *str) |
334 | const struct cgit_snapshot_format *f; |
334 | const struct cgit_snapshot_format *f; |
335 | static const char *delim = " \t,:/|;"; |
335 | static const char *delim = " \t,:/|;"; |
336 | int tl, sl, rv = 0; |
336 | int tl, sl, rv = 0; |
337 | |
337 | |
338 | /* favor legacy setting */ |
338 | /* favor legacy setting */ |
339 | if(atoi(str)) |
339 | if(atoi(str)) |
340 | return 1; |
340 | return 1; |
341 | for(;;) { |
341 | for(;;) { |
342 | str += strspn(str,delim); |
342 | str += strspn(str,delim); |
343 | tl = strcspn(str,delim); |
343 | tl = strcspn(str,delim); |
344 | if (!tl) |
344 | if (!tl) |
345 | break; |
345 | break; |
346 | for (f = cgit_snapshot_formats; f->suffix; f++) { |
346 | for (f = cgit_snapshot_formats; f->suffix; f++) { |
347 | sl = strlen(f->suffix); |
347 | sl = strlen(f->suffix); |
348 | if((tl == sl && !strncmp(f->suffix, str, tl)) || |
348 | if((tl == sl && !strncmp(f->suffix, str, tl)) || |
349 | (tl == sl-1 && !strncmp(f->suffix+1, str, tl-1))) { |
349 | (tl == sl-1 && !strncmp(f->suffix+1, str, tl-1))) { |
350 | rv |= f->bit; |
350 | rv |= f->bit; |
351 | break; |
351 | break; |
352 | } |
352 | } |
353 | } |
353 | } |
354 | str += tl; |
354 | str += tl; |
355 | } |
355 | } |
356 | return rv; |
356 | return rv; |
357 | } |
357 | } |
| |
358 | |
| |
359 | int cgit_open_filter(struct cgit_filter *filter) |
| |
360 | { |
| |
361 | |
| |
362 | filter->old_stdout = chk_positive(dup(STDOUT_FILENO), |
| |
363 | "Unable to duplicate STDOUT"); |
| |
364 | chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); |
| |
365 | filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); |
| |
366 | if (filter->pid == 0) { |
| |
367 | close(filter->pipe_fh[1]); |
| |
368 | chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), |
| |
369 | "Unable to use pipe as STDIN"); |
| |
370 | execvp(filter->cmd, filter->argv); |
| |
371 | die("Unable to exec subprocess %s: %s (%d)", filter->cmd, |
| |
372 | strerror(errno), errno); |
| |
373 | } |
| |
374 | close(filter->pipe_fh[0]); |
| |
375 | chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO), |
| |
376 | "Unable to use pipe as STDOUT"); |
| |
377 | close(filter->pipe_fh[1]); |
| |
378 | return 0; |
| |
379 | } |
| |
380 | |
| |
381 | int cgit_close_filter(struct cgit_filter *filter) |
| |
382 | { |
| |
383 | chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), |
| |
384 | "Unable to restore STDOUT"); |
| |
385 | close(filter->old_stdout); |
| |
386 | if (filter->pid < 0) |
| |
387 | return 0; |
| |
388 | waitpid(filter->pid, &filter->exitstatus, 0); |
| |
389 | if (WIFEXITED(filter->exitstatus) && !WEXITSTATUS(filter->exitstatus)) |
| |
390 | return 0; |
| |
391 | die("Subprocess %s exited abnormally", filter->cmd); |
| |
392 | } |
|