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)(&params);
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