diff options
Diffstat (limited to 'filter.c')
-rw-r--r-- | filter.c | 66 |
1 files changed, 50 insertions, 16 deletions
@@ -13,15 +13,13 @@ | |||
13 | #include <string.h> | 13 | #include <string.h> |
14 | #include <stdlib.h> | 14 | #include <stdlib.h> |
15 | 15 | ||
16 | int cgit_open_filter(struct cgit_filter *filter, ...) | 16 | static int open_exec_filter(struct cgit_filter *base, va_list ap) |
17 | { | 17 | { |
18 | struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base; | ||
18 | int i; | 19 | int i; |
19 | va_list ap; | ||
20 | 20 | ||
21 | va_start(ap, filter); | ||
22 | for (i = 0; i < filter->extra_args; i++) | 21 | for (i = 0; i < filter->extra_args; i++) |
23 | filter->argv[i+1] = va_arg(ap, char *); | 22 | filter->argv[i+1] = va_arg(ap, char *); |
24 | va_end(ap); | ||
25 | 23 | ||
26 | filter->old_stdout = chk_positive(dup(STDOUT_FILENO), | 24 | filter->old_stdout = chk_positive(dup(STDOUT_FILENO), |
27 | "Unable to duplicate STDOUT"); | 25 | "Unable to duplicate STDOUT"); |
@@ -41,9 +39,9 @@ int cgit_open_filter(struct cgit_filter *filter, ...) | |||
41 | return 0; | 39 | return 0; |
42 | } | 40 | } |
43 | 41 | ||
44 | 42 | static int close_exec_filter(struct cgit_filter *base) | |
45 | int cgit_close_filter(struct cgit_filter *filter) | ||
46 | { | 43 | { |
44 | struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base; | ||
47 | int i, exit_status; | 45 | int i, exit_status; |
48 | 46 | ||
49 | chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), | 47 | chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), |
@@ -63,21 +61,50 @@ done: | |||
63 | 61 | ||
64 | } | 62 | } |
65 | 63 | ||
66 | void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix) | 64 | static void fprintf_exec_filter(struct cgit_filter *base, FILE *f, const char *prefix) |
67 | { | 65 | { |
66 | struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base; | ||
68 | fprintf(f, "%s%s\n", prefix, filter->cmd); | 67 | fprintf(f, "%s%s\n", prefix, filter->cmd); |
69 | } | 68 | } |
70 | 69 | ||
71 | struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype) | 70 | int cgit_open_filter(struct cgit_filter *filter, ...) |
72 | { | 71 | { |
73 | struct cgit_filter *f; | 72 | int result; |
74 | int args_size = 0; | 73 | va_list ap; |
74 | va_start(ap, filter); | ||
75 | result = filter->open(filter, ap); | ||
76 | va_end(ap); | ||
77 | return result; | ||
78 | } | ||
75 | 79 | ||
76 | if (!cmd || !cmd[0]) | 80 | int cgit_close_filter(struct cgit_filter *filter) |
77 | return NULL; | 81 | { |
82 | return filter->close(filter); | ||
83 | } | ||
84 | |||
85 | void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix) | ||
86 | { | ||
87 | filter->fprintf(filter, f, prefix); | ||
88 | } | ||
89 | |||
90 | void cgit_exec_filter_init(struct cgit_exec_filter *filter, char *cmd, char **argv) | ||
91 | { | ||
92 | memset(filter, 0, sizeof(*filter)); | ||
93 | filter->base.open = open_exec_filter; | ||
94 | filter->base.close = close_exec_filter; | ||
95 | filter->base.fprintf = fprintf_exec_filter; | ||
96 | filter->cmd = cmd; | ||
97 | filter->argv = argv; | ||
98 | } | ||
99 | |||
100 | static struct cgit_filter *new_exec_filter(const char *cmd, filter_type filtertype) | ||
101 | { | ||
102 | struct cgit_exec_filter *f; | ||
103 | int args_size = 0; | ||
78 | 104 | ||
79 | f = xmalloc(sizeof(struct cgit_filter)); | 105 | f = xmalloc(sizeof(*f)); |
80 | memset(f, 0, sizeof(struct cgit_filter)); | 106 | /* We leave argv for now and assign it below. */ |
107 | cgit_exec_filter_init(f, xstrdup(cmd), NULL); | ||
81 | 108 | ||
82 | switch (filtertype) { | 109 | switch (filtertype) { |
83 | case SOURCE: | 110 | case SOURCE: |
@@ -91,10 +118,17 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype) | |||
91 | break; | 118 | break; |
92 | } | 119 | } |
93 | 120 | ||
94 | f->cmd = xstrdup(cmd); | ||
95 | args_size = (2 + f->extra_args) * sizeof(char *); | 121 | args_size = (2 + f->extra_args) * sizeof(char *); |
96 | f->argv = xmalloc(args_size); | 122 | f->argv = xmalloc(args_size); |
97 | memset(f->argv, 0, args_size); | 123 | memset(f->argv, 0, args_size); |
98 | f->argv[0] = f->cmd; | 124 | f->argv[0] = f->cmd; |
99 | return f; | 125 | return &f->base; |
126 | } | ||
127 | |||
128 | struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype) | ||
129 | { | ||
130 | if (!cmd || !cmd[0]) | ||
131 | return NULL; | ||
132 | |||
133 | return new_exec_filter(cmd, filtertype); | ||
100 | } | 134 | } |