1 #include <stdio.h>
2 #include <string.h>
3 #include <ctype.h>
4 #include <stdlib.h>
5
6 #ifndef WIN32
7 #include <unistd.h>
8 #endif
9
10 #include "config.h"
11 #include "user.h"
12 #include "list.h"
13 #include "command.h"
14 #include "parse.h"
15 #include "forms.h"
16 #include "smtp.h"
17 #include "core.h"
18 #include "fileapi.h"
19 #include "variables.h"
20 #include "modes.h"
21 #include "mystring.h"
22
23 FILE *adminspitfile;
24
get_adminspit()25 FILE *get_adminspit()
26 {
27 return adminspitfile;
28 }
29
open_adminspit(const char * filename)30 int open_adminspit(const char *filename)
31 {
32 if (adminspitfile) close_file(adminspitfile);
33
34 if ((adminspitfile = open_file(filename,"w")) == NULL) return 0;
35
36 set_var("adminspit", "true", VAR_GLOBAL);
37
38 return 1;
39 }
40
strip_queue()41 void strip_queue()
42 {
43 FILE *infile, *outfile;
44 char buffer[BIG_BUF], filenamebuf[BIG_BUF];
45 int gottask, donetask, inbody, skiplen = 0;
46
47 gottask = 0; donetask = 0; inbody = 0;
48
49 if (!exists_file(get_string("queuefile"))) return;
50
51 if ((infile = open_file(get_string("queuefile"),"r")) == NULL)
52 return;
53
54 buffer_printf(filenamebuf, sizeof(filenamebuf) - 1, "%s.striptask", get_string("queuefile"));
55
56 if ((outfile = open_file(filenamebuf,"w")) == NULL) {
57 close_file(infile);
58 return;
59 }
60
61 while (read_file(buffer, sizeof(buffer), infile)) {
62
63 if (inbody) {
64 if (!strncasecmp(buffer,"// job",6) ||
65 !strncasecmp(buffer,"//job",5) ||
66 !strncasecmp(buffer+1,"// job",6) ||
67 !strncasecmp(buffer+1,"//job",5) ||
68 !strncasecmp(buffer+2,"// job",6) ||
69 !strncasecmp(buffer+2,"//job",5)) {
70 char *skip = strchr(buffer, '/');
71 skiplen = skip-buffer;
72 gottask = 1;
73 donetask = 0;
74 read_file(buffer, sizeof(buffer), infile);
75 set_var("jobeoj-wrapper","yes",VAR_GLOBAL);
76 }
77 if(!strncasecmp(buffer+skiplen, "// eoj", 6) ||
78 !strncasecmp(buffer+skiplen, "//eoj", 5)) {
79 donetask = 1;
80 }
81 }
82
83 if ((gottask && !donetask) || !inbody) {
84 write_file(outfile,"%s",buffer+skiplen);
85 }
86
87 if (buffer[skiplen] == '\n') inbody = 1;
88 }
89
90 close_file(infile);
91 close_file(outfile);
92
93 if (gottask) {
94 replace_file(filenamebuf,get_string("queuefile"));
95 }
96
97 (void)unlink_file(filenamebuf);
98 }
99
handle_spit_admin(const char * line)100 int handle_spit_admin(const char *line)
101 {
102 if (!adminspitfile) return 0;
103
104 if (!strncmp(line,"ENDFILE",7)) {
105 close_file(adminspitfile);
106 adminspitfile = NULL;
107 clean_var("adminspit", VAR_GLOBAL);
108 set_var("cur-parse-line","ENDFILE",VAR_GLOBAL);
109 spit_status("File accepted.");
110 } else {
111 write_file(adminspitfile,"%s",line);
112 }
113 return 1;
114 }
115
handle_spit_admin2(const char * line)116 int handle_spit_admin2(const char *line)
117 {
118 if (!adminspitfile) return 0;
119
120 if (!strncasecmp(line,"adminend2",9) || !strncasecmp(line, "end", 3)) {
121 char tbuf[SMALL_BUF];
122 char buf[SMALL_BUF];
123
124 write_file(adminspitfile,"adminend\n// eoj\n");
125 close_file(adminspitfile);
126 adminspitfile = NULL;
127 clean_var("adminspit2", VAR_GLOBAL);
128 set_var("cur-parse-line",line,VAR_GLOBAL);
129 spit_status("Admin request queued, you will receive a wrapper.");
130
131 buffer_printf(tbuf, sizeof(tbuf) - 1, "%s.adminspit2", get_string("queuefile"));
132 buffer_printf(buf, sizeof(buf) - 1, "%s admin wrapper", SERVICE_NAME_MC);
133 set_var("task-form-subject", buf, VAR_TEMP);
134 send_textfile(get_string("realsender"),tbuf);
135 (void)unlink_file(tbuf);
136 } else {
137 write_file(adminspitfile,"%s",line);
138 }
139 return 1;
140 }
141
parse_line(const char * input_line_base,int type,FILE * queuefile,int * counter)142 int parse_line(const char *input_line_base, int type, FILE *queuefile, int *counter)
143 {
144 char *ptr;
145 char *ptr2, *outparse;
146 char *name, *c;
147 struct listserver_cmd *runcmd;
148 int lastspace;
149 int blocknext;
150 int mysize;
151 int i, j;
152 char input_line[HUGE_BUF];
153 struct cmd_params params;
154
155 buffer_printf(input_line, sizeof(input_line) - 1, "%s", input_line_base);
156
157 /* Convert reply-format to normal-format */
158 if (input_line[0] == '>') input_line[0] = ' ';
159
160 if (input_line[strlen(input_line) - 1] == '\n') {
161 input_line[strlen(input_line) - 1] = '\0';
162 }
163
164 if (input_line[0] == '#')
165 return CMD_RESULT_CONTINUE;
166
167 if ((input_line[0] == '/') && (input_line[1] == '/'))
168 return CMD_RESULT_CONTINUE;
169
170 while(input_line[strlen(input_line) - 1] == '\\') {
171 char tempbuf[BIG_BUF];
172
173 input_line[strlen(input_line) - 1] = ' ';
174
175 if (read_file(tempbuf, sizeof(tempbuf), queuefile)) {
176 stringcat(input_line, tempbuf);
177 if (input_line[strlen(input_line) - 1] == '\n') {
178 input_line[strlen(input_line) - 1] = '\0';
179 }
180 }
181 }
182
183 mysize = strlen(input_line) + 3;
184 outparse = (char *)malloc(mysize);
185 memset(outparse,0,mysize);
186 ptr2 = outparse;
187 ptr = input_line;
188 lastspace = 1;
189 blocknext = 0;
190
191 while(*ptr && ((*ptr != '\n') || blocknext)) {
192 if (isspace((int)(*ptr))) {
193 if (!lastspace) {
194 lastspace = 1;
195 *ptr2++ = ' ';
196 }
197 ptr++;
198 } else {
199 lastspace = 0;
200 blocknext = 0;
201 if (*ptr == '\\') {
202 blocknext = 1;
203 ptr++;
204 *ptr2++ = ' ';
205 } else if (*ptr == '\n') {
206 ptr++;
207 } else
208 *ptr2++ = *ptr++;
209 }
210 }
211
212 *ptr2 = '\0';
213
214 if (!*outparse) return CMD_RESULT_CONTINUE;
215
216 set_var("cur-parse-line",outparse, VAR_GLOBAL);
217
218 name = strtok(outparse, " \t");
219 i = 0;
220 while((c = strtok(NULL, " \t"))) {
221 params.words[i] = c;
222 i++;
223 if(i == MAX_PARAMS)
224 break;
225 }
226 params.num = i;
227
228 log_printf(9, "cmd: %s\n", name);
229 for(j = 0; j < i; j++)
230 log_printf(9, "param %d: %s\n", j, params.words[j]);
231
232 runcmd = find_command(name,type);
233
234 if (runcmd) {
235 int result;
236
237 (*counter)++;
238
239 if(!get_var("initial-cmd"))
240 set_var("initial-cmd", get_string("cur-parse-line"), VAR_GLOBAL);
241 result = (runcmd->cmd)(¶ms);
242 free(outparse);
243
244 if (type == CMD_HEADER) {
245 /* Check for prevent-second-message variable */
246 if (!get_bool("prevent-second-message")) {
247 result_printf("\nValid command was found in subject field, body won't be checked for further commands.\n");
248 }
249 result = CMD_RESULT_END;
250 }
251
252 return result;
253 } else {
254 if (type != CMD_HEADER)
255 spit_status("Unknown command.");
256 free(outparse);
257 return CMD_RESULT_CONTINUE;
258 }
259 }
260
parse_message(void)261 int parse_message(void)
262 {
263 struct listserver_mode *mode;
264 char buffer[BIG_BUF];
265 int res;
266
267 clean_var("adminspit", VAR_GLOBAL);
268 adminspitfile = NULL;
269
270 mode = find_mode(get_string("mode"));
271 if(!mode) {
272 buffer_printf(buffer, sizeof(buffer) - 1, "Unknown mode '%s'", get_string("mode"));
273 internal_error(buffer);
274 return PARSE_END;
275 }
276
277 res = mode->modefn();
278
279 if (res == MODE_ERR)
280 return PARSE_ERR;
281
282 if (res == MODE_END)
283 return PARSE_END;
284
285 return PARSE_OK;
286 }
287