|
diff --git a/cgit.c b/cgit.c index 2039ab1..779a464 100644 --- a/ cgit.c+++ b/ cgit.c |
|
@@ -12,16 +12,31 @@ |
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); |
|
|
diff --git a/cgit.h b/cgit.h index 8c64efe..d0fff1f 100644 --- a/ cgit.h+++ b/ cgit.h |
|
@@ -124,16 +124,25 @@ struct cgit_query { |
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; |
@@ -243,10 +252,13 @@ extern char *fmt(const char *format,...); |
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 |
|
@@ -350,8 +350,43 @@ int cgit_parse_snapshots_mask(const char *str) |
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 | } |
|