1 #include <string.h>
2 #include <stdlib.h>
3 
4 #include "core.h"
5 #include "config.h"
6 #include "fileapi.h"
7 #include "lcgi.h"
8 #include "liscript.h"
9 #include "mystring.h"
10 #include "variables.h"
11 
12 struct listserver_cgi_hook *cgi_hooks;
13 struct listserver_cgi_mode *cgi_modes;
14 struct listserver_cgi_tempvar *cgi_tempvars;
15 
new_cgi_hooks()16 void new_cgi_hooks()
17 {
18    cgi_hooks = NULL;
19 }
20 
nuke_cgi_hooks()21 void nuke_cgi_hooks()
22 {
23   struct listserver_cgi_hook *temp;
24 
25   temp = cgi_hooks;
26 
27   while(cgi_hooks) {
28     temp = cgi_hooks->next;
29     free(cgi_hooks->name);
30     free(cgi_hooks);
31     cgi_hooks = temp;
32   }
33 }
34 
add_cgi_hook(const char * name,CgiHook function)35 void add_cgi_hook(const char *name, CgiHook function)
36 {
37   struct listserver_cgi_hook *temphook;
38 
39   temphook = (struct listserver_cgi_hook *)malloc(sizeof(struct
40              listserver_cgi_hook));
41 
42   temphook->name = strdup(name);
43   temphook->hook = function;
44 
45   temphook->next = cgi_hooks;
46   cgi_hooks = temphook;
47 }
48 
find_cgi_hook(const char * name)49 struct listserver_cgi_hook *find_cgi_hook(const char *name)
50 {
51   struct listserver_cgi_hook *temp;
52 
53   temp = cgi_hooks;
54 
55   while(temp) {
56     if (strcasecmp(temp->name,name) == 0) break;
57     temp = temp->next;
58   }
59 
60   return temp;
61 }
62 
get_cgi_hooks()63 struct listserver_cgi_hook *get_cgi_hooks()
64 {
65   return cgi_hooks;
66 }
67 
cgi_unparse_template(const char * name)68 int cgi_unparse_template(const char *name)
69 {
70   char outfilename[BIG_BUF],infilename[BIG_BUF];
71   int inval;
72   int cgi_unparse_mode;
73   char inchar;
74   FILE *infile;
75   char varbuffer[BIG_BUF];
76   char parmbuffer[BIG_BUF];
77   int varbuflen, parmbuflen;
78 
79   buffer_printf(infilename, sizeof(infilename) - 1, "%s/%s.lsc", get_string("cgi-template-dir"),
80     name);
81 
82   buffer_printf(outfilename, sizeof(outfilename) - 1, "%s.cgi-unparse", get_string("queuefile"));
83 
84   log_printf(9,"LCGI unparse: %s\n", infilename);
85 
86   if (!liscript_parse_file(infilename,outfilename)) {
87     log_printf(2,"Unable to parse liscript %s into %s\n",
88       infilename, outfilename);
89     return 0;
90   }
91 
92   if ((infile = open_file(outfilename,"r")) == NULL) {
93     log_printf(2,"Unable to read %s for LCGI parse!\n", outfilename);
94     unlink_file(outfilename);
95     return 0;
96   }
97 
98   cgi_unparse_mode = 0;
99   memset(varbuffer, 0, sizeof(varbuffer));
100   varbuflen = 0;
101   memset(parmbuffer, 0, sizeof(parmbuffer));
102   parmbuflen = 0;
103 
104   while((inval = getc_file(infile)) != EOF) {
105     inchar = (char)inval;
106 
107     switch(cgi_unparse_mode) {
108        case CGI_UNPARSE_NORMAL:
109          if (inchar == '[') cgi_unparse_mode = CGI_UNPARSE_FIRSTHASH;
110             else putc_file(inchar,stdout);
111          break;
112 
113        case CGI_UNPARSE_FIRSTHASH:
114          if (inchar == '@') cgi_unparse_mode = CGI_UNPARSE_GETVAR;
115             else {
116                 cgi_unparse_mode = CGI_UNPARSE_NORMAL;
117                 printf("[%c",inchar);
118             }
119          break;
120 
121        case CGI_UNPARSE_GETVAR:
122          if (inchar == ']') {
123                struct listserver_cgi_hook *tempcgihook;
124 
125                tempcgihook = find_cgi_hook(varbuffer);
126                if (tempcgihook) {
127                   (*tempcgihook->hook)(parmbuffer);
128                } else {
129                   printf("<!-- Unknown CGI hook: %s -->\n",
130                     varbuffer);
131                }
132 
133                cgi_unparse_mode = CGI_UNPARSE_NORMAL;
134                memset(varbuffer, 0, sizeof(varbuffer));
135                varbuflen = 0;
136                memset(parmbuffer, 0, sizeof(parmbuffer));
137                parmbuflen = 0;
138             }
139             else if (inchar == ':') {
140                cgi_unparse_mode = CGI_UNPARSE_GETPARM;
141             }
142             else if (varbuflen < sizeof(varbuffer)) {
143                varbuffer[varbuflen++] = inchar;
144             }
145          break;
146 
147        case CGI_UNPARSE_GETPARM:
148          if (inchar == ']') {
149                struct listserver_cgi_hook *tempcgihook;
150 
151                tempcgihook = find_cgi_hook(varbuffer);
152                if (tempcgihook) {
153                   (*tempcgihook->hook)(parmbuffer);
154                } else {
155                   printf("<!-- Unknown CGI hook: %s -->\n",
156                     varbuffer);
157                }
158 
159                cgi_unparse_mode = CGI_UNPARSE_NORMAL;
160                memset(varbuffer, 0, sizeof(varbuffer));
161                varbuflen = 0;
162                memset(parmbuffer, 0, sizeof(parmbuffer));
163                parmbuflen = 0;
164             }
165             else if (parmbuflen < sizeof(parmbuffer)) {
166                parmbuffer[parmbuflen++] = inchar;
167             }
168          break;
169     }
170 
171   }
172 
173   close_file(infile);
174   unlink_file(outfilename);
175 
176   return 1;
177 }
178 
new_cgi_modes()179 void new_cgi_modes()
180 {
181   cgi_modes = NULL;
182 }
183 
nuke_cgi_modes()184 void nuke_cgi_modes()
185 {
186   struct listserver_cgi_mode *temp;
187 
188   temp = cgi_modes;
189 
190   while(cgi_modes) {
191     temp = cgi_modes->next;
192     free(cgi_modes->name);
193     free(cgi_modes);
194     cgi_modes = temp;
195   }
196 }
197 
add_cgi_mode(const char * name,CgiMode function)198 void add_cgi_mode(const char *name, CgiMode function)
199 {
200   struct listserver_cgi_mode *temphook;
201 
202   temphook = (struct listserver_cgi_mode *)malloc(sizeof(struct
203              listserver_cgi_mode));
204 
205   temphook->name = strdup(name);
206   temphook->mode = function;
207 
208   temphook->next = cgi_modes;
209   cgi_modes = temphook;
210 }
211 
find_cgi_mode(const char * name)212 struct listserver_cgi_mode *find_cgi_mode(const char *name)
213 {
214   struct listserver_cgi_mode *temp;
215 
216   temp = cgi_modes;
217 
218   while(temp) {
219     if (strcasecmp(temp->name,name) == 0) break;
220     temp = temp->next;
221   }
222 
223   return temp;
224 }
225 
226 
new_cgi_tempvars()227 void new_cgi_tempvars()
228 {
229   cgi_tempvars = NULL;
230 }
231 
nuke_cgi_tempvars()232 void nuke_cgi_tempvars()
233 {
234   struct listserver_cgi_tempvar *temp;
235 
236   temp = cgi_tempvars;
237 
238   while(cgi_tempvars) {
239     temp = cgi_tempvars->next;
240     free(cgi_tempvars->name);
241     free(cgi_tempvars->value);
242     free(cgi_tempvars);
243     cgi_tempvars = temp;
244   }
245 }
246 
add_cgi_tempvar(const char * name,const char * val)247 void add_cgi_tempvar(const char *name, const char *val)
248 {
249   struct listserver_cgi_tempvar *tempvar;
250 
251   tempvar = (struct listserver_cgi_tempvar *)malloc(sizeof(struct
252              listserver_cgi_tempvar));
253 
254   tempvar->name = strdup(name);
255   tempvar->value = strdup(val);
256 
257   tempvar->next = cgi_tempvars;
258   cgi_tempvars = tempvar;
259 }
260 
get_cgi_tempvars()261 struct listserver_cgi_tempvar *get_cgi_tempvars()
262 {
263   return cgi_tempvars;
264 }
265 
find_cgi_tempvar(const char * name)266 struct listserver_cgi_tempvar *find_cgi_tempvar(const char *name)
267 {
268   struct listserver_cgi_tempvar *temp;
269 
270   temp = cgi_tempvars;
271 
272   while(temp) {
273     log_printf(18,"CGI: tempvar search: comparing %s to %s...\n",
274        name, temp->name);
275     if (strcasecmp(temp->name,name) == 0) break;
276     temp = temp->next;
277   }
278 
279   return temp;
280 }
281