diff options
-rw-r--r-- | filter.c | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/filter.c b/filter.c index c7037a3..949c931 100644 --- a/filter.c +++ b/filter.c | |||
@@ -8,17 +8,13 @@ | |||
8 | 8 | ||
9 | #include "cgit.h" | 9 | #include "cgit.h" |
10 | #include "html.h" | 10 | #include "html.h" |
11 | #include <dlfcn.h> | ||
12 | #ifndef NO_LUA | 11 | #ifndef NO_LUA |
12 | #include <dlfcn.h> | ||
13 | #include <lua.h> | 13 | #include <lua.h> |
14 | #include <lualib.h> | 14 | #include <lualib.h> |
15 | #include <lauxlib.h> | 15 | #include <lauxlib.h> |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | static ssize_t (*libc_write)(int fd, const void *buf, size_t count); | ||
19 | static ssize_t (*filter_write)(struct cgit_filter *base, const void *buf, size_t count) = NULL; | ||
20 | static struct cgit_filter *current_write_filter = NULL; | ||
21 | |||
22 | static inline void reap_filter(struct cgit_filter *filter) | 18 | static inline void reap_filter(struct cgit_filter *filter) |
23 | { | 19 | { |
24 | if (filter && filter->cleanup) | 20 | if (filter && filter->cleanup) |
@@ -43,37 +39,6 @@ void cgit_cleanup_filters(void) | |||
43 | } | 39 | } |
44 | } | 40 | } |
45 | 41 | ||
46 | void cgit_init_filters(void) | ||
47 | { | ||
48 | libc_write = dlsym(RTLD_NEXT, "write"); | ||
49 | if (!libc_write) | ||
50 | die("Could not locate libc's write function"); | ||
51 | } | ||
52 | |||
53 | ssize_t write(int fd, const void *buf, size_t count) | ||
54 | { | ||
55 | if (fd != STDOUT_FILENO || !filter_write) | ||
56 | return libc_write(fd, buf, count); | ||
57 | return filter_write(current_write_filter, buf, count); | ||
58 | } | ||
59 | |||
60 | static inline void hook_write(struct cgit_filter *filter, ssize_t (*new_write)(struct cgit_filter *base, const void *buf, size_t count)) | ||
61 | { | ||
62 | /* We want to avoid buggy nested patterns. */ | ||
63 | assert(filter_write == NULL); | ||
64 | assert(current_write_filter == NULL); | ||
65 | current_write_filter = filter; | ||
66 | filter_write = new_write; | ||
67 | } | ||
68 | |||
69 | static inline void unhook_write(void) | ||
70 | { | ||
71 | assert(filter_write != NULL); | ||
72 | assert(current_write_filter != NULL); | ||
73 | filter_write = NULL; | ||
74 | current_write_filter = NULL; | ||
75 | } | ||
76 | |||
77 | static int open_exec_filter(struct cgit_filter *base, va_list ap) | 42 | static int open_exec_filter(struct cgit_filter *base, va_list ap) |
78 | { | 43 | { |
79 | struct cgit_exec_filter *filter = (struct cgit_exec_filter *)base; | 44 | struct cgit_exec_filter *filter = (struct cgit_exec_filter *)base; |
@@ -170,7 +135,48 @@ void cgit_exec_filter_init(struct cgit_exec_filter *filter, char *cmd, char **ar | |||
170 | filter->base.argument_count = 0; | 135 | filter->base.argument_count = 0; |
171 | } | 136 | } |
172 | 137 | ||
138 | #ifdef NO_LUA | ||
139 | void cgit_init_filters(void) | ||
140 | { | ||
141 | } | ||
142 | #endif | ||
143 | |||
173 | #ifndef NO_LUA | 144 | #ifndef NO_LUA |
145 | static ssize_t (*libc_write)(int fd, const void *buf, size_t count); | ||
146 | static ssize_t (*filter_write)(struct cgit_filter *base, const void *buf, size_t count) = NULL; | ||
147 | static struct cgit_filter *current_write_filter = NULL; | ||
148 | |||
149 | void cgit_init_filters(void) | ||
150 | { | ||
151 | libc_write = dlsym(RTLD_NEXT, "write"); | ||
152 | if (!libc_write) | ||
153 | die("Could not locate libc's write function"); | ||
154 | } | ||
155 | |||
156 | ssize_t write(int fd, const void *buf, size_t count) | ||
157 | { | ||
158 | if (fd != STDOUT_FILENO || !filter_write) | ||
159 | return libc_write(fd, buf, count); | ||
160 | return filter_write(current_write_filter, buf, count); | ||
161 | } | ||
162 | |||
163 | static inline void hook_write(struct cgit_filter *filter, ssize_t (*new_write)(struct cgit_filter *base, const void *buf, size_t count)) | ||
164 | { | ||
165 | /* We want to avoid buggy nested patterns. */ | ||
166 | assert(filter_write == NULL); | ||
167 | assert(current_write_filter == NULL); | ||
168 | current_write_filter = filter; | ||
169 | filter_write = new_write; | ||
170 | } | ||
171 | |||
172 | static inline void unhook_write(void) | ||
173 | { | ||
174 | assert(filter_write != NULL); | ||
175 | assert(current_write_filter != NULL); | ||
176 | filter_write = NULL; | ||
177 | current_write_filter = NULL; | ||
178 | } | ||
179 | |||
174 | struct lua_filter { | 180 | struct lua_filter { |
175 | struct cgit_filter base; | 181 | struct cgit_filter base; |
176 | char *script_file; | 182 | char *script_file; |