1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 
5 #include "fileapi.h"
6 #include "variables.h"
7 #include "list.h"
8 #include "user.h"
9 #include "unmime.h"
10 #include "core.h"
11 #include "cookie.h"
12 #include "forms.h"
13 #include "hooks.h"
14 #include "modes.h"
15 #include "smtp.h"
16 #include "mystring.h"
17 #include "moderate.h"
18 
19 extern FILE *setup_queuefile(void);
20 extern int anti_loop(void);
21 
22 int appcounter;
23 
COOKIE_HANDLER(expire_modpost)24 COOKIE_HANDLER(expire_modpost)
25 {
26     if(cookietype != 'M') {
27         log_printf(0, "expire_modpost: Called with wrong cookie type '%c'!",
28                    cookietype);
29         return COOKIE_HANDLE_FAIL;
30     }
31 
32     if(exists_file(cookiedata)) {
33         unlink_file(cookiedata);
34     }
35     return COOKIE_HANDLE_OK;
36 }
37 
38 
make_moderated_post(const char * reason)39 void make_moderated_post(const char *reason)
40 {
41     const char *moderator;
42     const char *queuefile;
43     char toutbuf[BIG_BUF], readbuf[BIG_BUF], tfilebuf[SMALL_BUF], tfilebuf2[SMALL_BUF];
44     FILE *newfile, *oldfile;
45     const char *tptr;
46     int founduser;
47     char cookie[BIG_BUF], cookiefile[SMALL_BUF];
48     struct list_user user;
49     char *listdir;
50 
51     founduser = user_find_list(get_string("list"),get_string("realsender"),&user);
52 
53     queuefile = get_string("queuefile");
54 
55     tptr = strrchr(queuefile,'/');
56 
57 #ifdef WIN32
58     if (!tptr) {
59        tptr = strrchr(queuefile,'\\');
60     }
61 #endif
62 
63     listdir = list_directory(get_string("list"));
64 
65     if (!tptr) tptr = queuefile; else tptr++;
66 
67     buffer_printf(tfilebuf, sizeof(tfilebuf) - 1, "%s/modposts/%s", listdir, tptr);
68 
69     mkdirs(tfilebuf);
70 
71     if ((newfile = open_file(tfilebuf,"w")) == NULL) {
72         filesys_error(&tfilebuf[0]);
73         free(listdir);
74         return;
75     }
76 
77     if ((oldfile = open_file(queuefile,"r")) == NULL) {
78         filesys_error(queuefile);
79         close_file(newfile);
80         unlink_file(tfilebuf);
81         free(listdir);
82         return;
83     }
84 
85     while(read_file(readbuf, sizeof(readbuf), oldfile)) {
86         write_file(newfile,"%s",readbuf);
87     }
88 
89     close_file(newfile);
90     rewind_file(oldfile);
91 
92     buffer_printf(tfilebuf2, sizeof(tfilebuf2) - 1, "%s.modpost", queuefile);
93 
94     if ((newfile = open_file(tfilebuf2,"w")) == NULL) {
95         filesys_error(&tfilebuf2[0]);
96         close_file(newfile);
97         unlink_file(tfilebuf);
98         free(listdir);
99         return;
100     }
101 
102     buffer_printf(cookiefile, sizeof(cookiefile) - 1, "%s/cookies", listdir);
103     set_var("cookie-for",get_string("list"),VAR_TEMP);
104 
105     free(listdir);
106 
107     if (!request_cookie(cookiefile,&cookie[0], 'M', tfilebuf)) {
108        filesys_error(cookiefile);
109        close_file(newfile);
110        unlink_file(tfilebuf);
111        return;
112     }
113     clean_var("cookie-for", VAR_TEMP);
114 
115     write_file(newfile,"This message was received for a list you are a moderator on, and\n");
116     write_file(newfile,"was marked for moderation due to the following reason:\n");
117     write_file(newfile,"%s\n", reason);
118     write_file(newfile,"\nTo approve this message and have it go out on the list, forward this to\n");
119     write_file(newfile,"%s\n\n",get_string("approved-address"));
120     write_file(newfile,"If you wish to decline the post, change the 'apppost' below to 'delpost'.\n");
121     write_file(newfile,"If you wish to edit the post, change it to 'modpost' and edit the message\n");
122     write_file(newfile,"as needed - not all mail programs will work with modpost.\n\n", get_string("approved-address"));
123 
124     write_file(newfile,"DO NOT DELETE THE FOLLOWING LINE.  %s needs it.\n",
125                SERVICE_NAME_MC);
126     write_file(newfile,"// apppost %s\n\n", cookie);
127 
128     while(read_file(readbuf, sizeof(readbuf), oldfile)) {
129         write_file(newfile,"%s",readbuf);
130     }
131 
132     write_file(newfile, "// eompost %s\n", cookie);
133     close_file(newfile);
134     close_file(oldfile);
135 
136     if (replace_file(&tfilebuf2[0],queuefile)) {
137         buffer_printf(readbuf, sizeof(readbuf) - 1, "%s -> %s", tfilebuf2, queuefile);
138         filesys_error(&readbuf[0]);
139         return;
140     }
141 
142     set_var("form-reply-to",get_string("fromaddress"),VAR_TEMP);
143     moderator = get_var("moderator");
144     if (!moderator) moderator = get_var("list-owner");
145 
146     if (get_bool("moderate-verbose-subject")) {
147        buffer_printf(toutbuf, sizeof(toutbuf) - 1, "%s: %s post needs approval",
148            get_var("list"), get_var("realsender"));
149     }
150     else {
151        buffer_printf(toutbuf, sizeof(toutbuf) - 1, "Message submitted to '%s'", get_string("list"));
152     }
153     set_var("task-form-subject",&toutbuf[0],VAR_TEMP);
154     set_var("task-no-footer","yes",VAR_TEMP);
155     send_textfile(moderator,queuefile);
156     clean_var("task-no-footer", VAR_TEMP);
157 
158     if (get_bool("moderate-quiet")) return;
159 
160     if (founduser ?
161         (user_hasflag(&user,"ACKPOST") || get_bool("moderate-force-notify")) :
162         get_bool("moderate-notify-nonsub")) {
163        const char *subj;
164        set_var("results-subject-override","Post sent to moderator.",VAR_TEMP);
165 
166        subj = get_var("message-subject");
167        if (subj && *subj) {
168            buffer_printf(toutbuf, sizeof(toutbuf) - 1, "Post to list %s\nSubject: %s", get_string("list"),
169               get_string("message-subject"));
170        } else {
171            buffer_printf(toutbuf, sizeof(toutbuf) - 1, "Post to list %s", get_string("list"));
172        }
173        set_var("cur-parse-line",&toutbuf[0],VAR_GLOBAL);
174        spit_status("Post submitted to moderator for reason: %s", reason);
175 
176        if (get_bool("moderate-include-queue")) {
177           result_printf("\n\n--- Message which triggered moderation ----\n\n");
178 
179           result_append(tfilebuf);
180        }
181     }
182 }
183 
184 /* How to handle sending a pre-approved message to a list */
MODE_HANDLER(mode_approved)185 MODE_HANDLER(mode_approved)
186 {
187     FILE *queuefile;
188     char buffer[BIG_BUF];
189     const char *from;
190     struct list_user user;
191     int permission = 0;
192 
193     /* Generic 'mode' queuefile setup for input. */
194     queuefile = setup_queuefile();
195 
196     /* Something went wrong. */
197     if(!queuefile) {
198         /* Do we stop or requeue? */
199         if (get_bool("address-failure"))
200            return MODE_END;
201         else
202            return MODE_ERR;
203     }
204 
205     /* Fairly generic anti-loop checking. */
206     if(!get_var("resent-from")) {
207        if(anti_loop()) {
208            close_file(queuefile);
209            return MODE_OK;
210        }
211     }
212 
213     /* We're done playing with the queuefile. */
214     close_file(queuefile);
215 
216     /* First, we do a really low-cost check.  list-owner and moderator,
217      * in cases where they aren't a ecartis address, are always allowed
218      * to post. */
219     from = get_string("fromaddress");
220     if((strcmp(from, get_string("moderator")) == 0) ||
221        (strcmp(from, get_string("list-owner")) == 0))
222         permission = 1;
223 
224     /* That check probably didn't pass on any install more recent
225      * than Listar 0.98 in origin, so we'll check the user's flags now. */
226     if(!permission) {
227         if(user_find_list(get_string("list"), from, &user)) {
228             permission = user_hasflag(&user, "ADMIN")  ||
229                          user_hasflag(&user, "MODERATOR");
230 
231         }
232     }
233 
234     /* If permission was still denied, then we end here. */
235     if(!permission) {
236         set_var("task-form-subject", "Moderation attempt denied.", VAR_TEMP);
237         if(!task_heading(from))
238             return MODE_ERR;
239         smtp_body_text("You are not a valid moderator for list '");
240         smtp_body_text(get_string("list"));
241         smtp_body_line("'.");
242         task_ending();
243         log_printf(0, "User %s tried to post to approval address for %s\n",
244                    from, get_string("list"));
245         return MODE_OK;
246     }
247 
248     /* Reset our counter to 0. */
249     appcounter = 0;
250 
251     /* Unmime the file; this allows messages to be forwarded as MIME
252      * digests and moderate multiple messages at once. */
253     buffer_printf(buffer, sizeof(buffer) - 1, "%s.unmime", get_string("queuefile"));
254     set_var("unmime-moderate-mode","yes",VAR_GLOBAL);
255     unmime_file(get_string("queuefile"),buffer);
256     clean_var("unmime-moderate-mode",VAR_GLOBAL);
257 
258     /* In unmime-moderate-mode, we will ONLY be unmimed if we're
259      * a multipart message.  If we aren't unmimed, we handle it as
260      * a single message. */
261     if (!get_bool("just-unmimed")) {
262 
263        /* Turn us back into normal text. */
264        buffer_printf(buffer, sizeof(buffer) - 1, "%s.unquote", get_string("queuefile"));
265        unquote_file(get_string("queuefile"),buffer);
266 
267        if (get_bool("just-unquoted")) {
268           if (replace_file(buffer,get_string("queuefile"))) {
269               char tempbuf[BIG_BUF];
270 
271               buffer_printf(tempbuf, sizeof(tempbuf) - 1, "%s -> %s", buffer,
272                  get_string("queuefile"));
273               filesys_error(&tempbuf[0]);
274               (void)unlink_file(buffer);
275           }
276        }
277 
278        /* ...and do the moderation. */
279        do_moderate(get_string("queuefile"));
280     }
281     else {
282        /* We were unmimed. */
283 
284        buffer_printf(buffer, sizeof(buffer) - 1, "%s.unmime", get_string("queuefile"));
285        unlink_file(buffer);
286     }
287 
288     return MODE_OK;
289 }
290 
do_moderate(const char * infilename)291 void do_moderate(const char *infilename)
292 {
293     FILE *queuefile, *outfile;
294     char buffer[BIG_BUF];
295     char readbuf[BIG_BUF];
296     const char *from;
297     char fromaddy[BIG_BUF];
298     int intoreal, inbody;
299     int gotcookie;
300     int done;
301     int res;
302     char *cookie, *appptr;
303     char corecookie[SMALL_BUF];
304     char cookiedata[BIG_BUF]; /* changed from 256 (SMALL_BUF) to BIG_BUF due to verify_cookie) */
305     char oldqueuefile[BIG_BUF];
306 
307     gotcookie = 0;
308     done = 0;
309 
310     from = get_string("fromaddress");
311 
312     if ((queuefile = open_file(infilename,"r+")) == NULL) {
313        return;
314     }
315 
316     appcounter++;
317 
318     buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", get_string("queuefile"), appcounter);
319     if((outfile = open_file(buffer, "w")) == NULL) {
320         close_file(queuefile);
321         set_var("cur-parse-line", "Post of message to moderated list.", VAR_GLOBAL);
322         filesys_error(buffer);
323         spit_status("Filesystem error encountered.");
324         return;
325     }
326     intoreal = 0;
327     inbody = 0;
328 
329     set_var("moderated-approved-by", from, VAR_GLOBAL);
330     while(read_file(readbuf, sizeof(readbuf), queuefile) && !done) {
331         if((strncasecmp("// eompost", readbuf, 10) == 0) && intoreal) {
332            char *tempcookie;
333            tempcookie = &readbuf[11];
334            tempcookie[strlen(tempcookie) - 1] = 0;
335            if (strcmp(tempcookie,corecookie) == 0) {
336               log_printf(9,"Found eompost, ending moderated post\n");
337               done = 1;
338            }
339         }
340         if(intoreal && !done) {
341             char *tbufp = readbuf;
342             /*
343              * This hack should no longer be needed, but I'm leaving it,
344              * just in case.
345              */
346             if(!inbody && !strncasecmp("=46rom:", readbuf, 6)) {
347                 readbuf[2] = 'F';
348                 tbufp = &readbuf[2];
349             }
350             write_file(outfile, "%s", tbufp);
351         }
352         if(readbuf[0] == '\n') inbody = 1;
353         if((strncasecmp("// modpost", readbuf, 10) == 0)
354           && (inbody && !intoreal)) {
355            cookie = &readbuf[11];
356            readbuf[strlen(readbuf) - 1] = 0;
357            log_printf(9,"Checking moderator cookie: %s\n", cookie);
358            if (match_cookie(cookie,get_string("list"))) {
359               char cookiefile[SMALL_BUF];
360               char *listdir;
361 
362               listdir = list_directory(get_string("list"));
363 
364               buffer_printf(cookiefile, sizeof(cookiefile) - 1, "%s/cookies", listdir);
365 
366               free(listdir);
367 
368               if (verify_cookie(cookiefile, cookie, 'M', &cookiedata[0])) {
369                  gotcookie = 1;
370                  buffer_printf(corecookie, sizeof(corecookie) - 1, "%s", cookie);
371                  del_cookie(cookiefile,cookie);
372               }
373            }
374         } else
375         if((appptr = strstr(readbuf, "// apppost"))
376           && (inbody && !intoreal)) {
377            int pos;
378 
379            pos = appptr - &readbuf[0];
380 
381            cookie = &readbuf[pos + 11];
382            readbuf[strlen(readbuf) - 1] = 0;
383            log_printf(9,"Checking moderator cookie: %s\n", cookie);
384            if (match_cookie(cookie,get_string("list"))) {
385               char cookiefile[SMALL_BUF];
386               char *listdir;
387 
388               listdir = list_directory(get_string("list"));
389 
390               buffer_printf(cookiefile, sizeof(cookiefile) - 1, "%s/cookies", listdir);
391 
392               free(listdir);
393 
394               if (verify_cookie(cookiefile, cookie, 'M', &cookiedata[0])) {
395                  FILE *infile2;
396                  char subbuffer[BIG_BUF];
397 
398                  gotcookie = 1;
399 
400                  if ((infile2 = open_file(&cookiedata[0],"r")) == NULL) {
401                     set_var("task-form-subject", "No stored message.", VAR_TEMP);
402                     close_file(queuefile);
403                     close_file(outfile);
404                     buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", get_string("queuefile"), appcounter);
405                     unlink_file(buffer);
406                     if(!task_heading(from)) {
407                       buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
408                          get_string("queuefile"),appcounter);
409                        unlink_file(buffer);
410 
411                        return;
412                     }
413                     smtp_body_text("Could not find the file associated with the post you approved on ");
414                     smtp_body_text(get_string("list"));
415                     smtp_body_line(".");
416                     task_ending();
417                     log_printf(0, "User %s posted to %s approval address; no stored file found.\n",
418                            from, get_string("list"));
419 
420                     buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
421                       get_string("queuefile"),appcounter);
422                     unlink_file(buffer);
423 
424                     return;
425                  }
426 
427                  while(read_file(subbuffer, sizeof(subbuffer), infile2)) {
428                     write_file(outfile,"%s",subbuffer);
429                  }
430 
431                  close_file(infile2);
432                  del_cookie(cookiefile,cookie);
433                  log_printf(9,"Moderated post approved.\n");
434                  done = 1;
435               } else {
436                  rewind_file(queuefile);
437                  if(!task_heading(from)) {
438                     buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
439                       get_string("queuefile"),appcounter);
440                     unlink_file(buffer);
441 
442                     return;
443                  }
444                  smtp_body_text("Cannot find a cookie for post on ");
445                  smtp_body_text(get_string("list"));
446                  smtp_body_line(".");
447                  smtp_body_line("");
448                  smtp_body_line("It may have been already approved, or it may have expired.");
449                  if (get_bool("verbose-moderate-fail")) {
450                     smtp_body_line("");
451                     smtp_body_line("--- Message in question ---");
452                     rewind_file(queuefile);
453                     while(read_file(buffer, sizeof(buffer), queuefile)) {
454                        smtp_body_text(buffer);
455                     }
456                     smtp_body_line("");
457                  }
458                  close_file(queuefile);
459                  task_ending();
460                  buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
461                      get_string("queuefile"),appcounter);
462                  unlink_file(buffer);
463                  return;
464               }
465            } else {
466               if(!task_heading(from)) {
467                 buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
468                       get_string("queuefile"),appcounter);
469                 unlink_file(buffer);
470                 return;
471               }
472               smtp_body_text("Cookie does not match for ");
473               smtp_body_text(get_string("list"));
474               smtp_body_line(".");
475 
476               if (get_bool("verbose-moderate-fail")) {
477                  smtp_body_line("");
478                  smtp_body_line("--- Message in question ---");
479                  rewind_file(queuefile);
480                  while(read_file(buffer, sizeof(buffer), queuefile)) {
481                     smtp_body_text(buffer);
482                  }
483                  smtp_body_line("");
484               }
485               task_ending();
486               buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
487                  get_string("queuefile"),appcounter);
488               unlink_file(buffer);
489               return;
490            }
491         } else
492         if((strncasecmp("// delpost", readbuf, 10) == 0)
493           && (inbody && !intoreal)) {
494            cookie = &readbuf[11];
495            readbuf[strlen(readbuf) - 1] = 0;
496            log_printf(9,"Checking moderator cookie: %s\n", cookie);
497            if (match_cookie(cookie,get_string("list"))) {
498               char cookiefile[SMALL_BUF];
499               char *listdir;
500 
501               listdir = list_directory(get_string("list"));
502 
503               buffer_printf(cookiefile, sizeof(cookiefile) - 1, "%s/cookies", listdir);
504 
505               free(listdir);
506 
507               if (verify_cookie(cookiefile,cookie, 'M', &cookiedata[0])) {
508                  gotcookie = 1;
509 
510                  if (!exists_file(&cookiedata[0])) {
511                     set_var("task-form-subject", "No stored message.", VAR_TEMP);
512                     close_file(queuefile);
513                     close_file(outfile);
514                     buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", get_string("queuefile"), appcounter);
515                     unlink_file(buffer);
516                     if(!task_heading(from)) {
517                        buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
518                           get_string("queuefile"),appcounter);
519                        unlink_file(buffer);
520                        return;
521                     }
522                     smtp_body_text("Could not find the file associated with the post you declined for ");
523                     smtp_body_text(get_string("list"));
524                     smtp_body_line(".");
525                     task_ending();
526                     log_printf(0, "User %s posted to %s approval address; no stored file found.\n",
527                            from, get_string("list"));
528                     buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
529                       get_string("queuefile"),appcounter);
530                     unlink_file(buffer);
531                     return;
532                  }
533 
534                  buffer_printf(buffer, BIG_BUF - 1, "Moderated post to '%s' declined.", get_string("list"));
535                  log_printf(9, "%s\n", buffer);
536                  set_var("results-subject-override", buffer, VAR_TEMP);
537                  result_printf(">> %s\n", readbuf);
538                  result_printf("%s\n", buffer);
539                  del_cookie(cookiefile, cookie);
540                  done = 1;
541 
542                  smtp_body_line("");
543                  smtp_body_line("--- Message in question ---");
544                  rewind_file(queuefile);
545                  while(read_file(buffer, sizeof(buffer), queuefile)) {
546                     smtp_body_text(buffer);
547                  }
548                  smtp_body_line("");
549 
550                  close_file(queuefile);
551                  close_file(outfile);
552                  buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", get_string("queuefile"), appcounter);
553                  unlink_file(buffer);
554                  return;
555               } else {
556                  if(!task_heading(from)) {
557                     buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
558                       get_string("queuefile"),appcounter);
559                     unlink_file(buffer);
560                     return;
561                  }
562                  smtp_body_text("No cookie found for post to list ");
563                  smtp_body_text(get_string("list"));
564                  smtp_body_line(".");
565                  smtp_body_line("");
566                  smtp_body_line("Has this post already been approved or declined?");
567                  if (get_bool("verbose-moderate-fail")) {
568                     smtp_body_line("");
569                     smtp_body_line("--- Message in question ---");
570                     rewind_file(queuefile);
571                     while(read_file(buffer, sizeof(buffer), queuefile)) {
572                        smtp_body_text(buffer);
573                     }
574                     smtp_body_line("");
575                  }
576                  close_file(queuefile);
577                  task_ending();
578                  buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
579                     get_string("queuefile"),appcounter);
580                  unlink_file(buffer);
581                  return;
582               }
583            } else {
584               if(!task_heading(from)) {
585                  buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
586                       get_string("queuefile"),appcounter);
587                  unlink_file(buffer);
588                  return;
589               }
590               smtp_body_text("Cookie does not match for list ");
591               smtp_body_text(get_string("list"));
592               smtp_body_line(".");
593               if (get_bool("verbose-moderate-fail")) {
594                  smtp_body_line("");
595                  smtp_body_line("--- Message in question ---");
596                  rewind_file(queuefile);
597                  while(read_file(buffer, sizeof(buffer), queuefile)) {
598                     smtp_body_text(buffer);
599                  }
600                  smtp_body_line("");
601               }
602               close_file(queuefile);
603               task_ending();
604               buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d",
605                    get_string("queuefile"),appcounter);
606               unlink_file(buffer);
607               return;
608            }
609         } else
610         if(((strncasecmp(">From ", readbuf, 6) == 0) ||
611             (strncasecmp("> From ", readbuf, 7) == 0) ||
612             (strncasecmp(" From ", readbuf, 6) == 0) ||
613             /* This hack should be unneeded... but... better safe */
614             (strncasecmp("=46rom ", readbuf,7) == 0) ||
615             (strncasecmp("From ", readbuf, 5) == 0)) &&
616             (inbody && !intoreal)) {
617             if (gotcookie) {
618                char *frombuf;
619                frombuf = &readbuf[0];
620                /* This hack should be unneeded... but... better safe */
621                /* Hack for if we have stupid Forte doing quoted printable */
622                if(readbuf[0] == '=') {
623                    readbuf[2] = 'F';
624                    frombuf= &readbuf[2];
625                }
626                if(readbuf[0] == '>' || readbuf[0] == ' ') {
627                    if(readbuf[1] == 'F') frombuf = &readbuf[1];
628                    if(readbuf[2] == 'F') frombuf = &readbuf[2];
629                }
630                sscanf(frombuf, "From %s", fromaddy);
631                set_var("fromaddress", fromaddy, VAR_GLOBAL);
632                write_file(outfile,"%s",frombuf);
633                intoreal = 1;
634                inbody = 0;
635             } else {
636                set_var("task-form-subject", "No moderator cookie.", VAR_TEMP);
637                if(!task_heading(from)) {
638                    buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", get_string("queuefile"), appcounter);
639                    unlink_file(buffer);
640                    return;
641                }
642                smtp_body_text("Could not find a valid cookie for this post for list ");
643                smtp_body_text(get_string("list"));
644                smtp_body_line(".");
645                smtp_body_line("");
646                smtp_body_line("Another moderator may have approved this already.");
647                log_printf(0, "User %s posted to %s approval address; no valid cookie found.\n",
648                    from, get_string("list"));
649                if (get_bool("verbose-moderate-fail")) {
650                   smtp_body_line("");
651                   smtp_body_line("--- Message in question ---");
652                   rewind_file(queuefile);
653                   while(read_file(buffer, sizeof(buffer), queuefile)) {
654                      smtp_body_text(buffer);
655                   }
656                   smtp_body_line("");
657                }
658                task_ending();
659                close_file(queuefile);
660                close_file(outfile);
661                buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", get_string("queuefile"), appcounter);
662                unlink_file(buffer);
663                return;
664             }
665         }
666     }
667     close_file(outfile);
668     close_file(queuefile);
669 
670     if (!gotcookie) {
671         make_moderated_post("Message sent to approval address with no cookie");
672         buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", get_string("queuefile"), appcounter);
673         unlink_file(buffer);
674         return;
675     }
676 
677     buffer_printf(oldqueuefile, sizeof(oldqueuefile) - 1, "%s", get_string("queuefile"));
678     buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", oldqueuefile, appcounter);
679 
680     /* We reset our queuefile temporarily. */
681     set_var("queuefile",buffer,VAR_GLOBAL);
682 
683     /* ...along with the sender address... */
684     /*
685     if ((queuefile = open_file(buffer,"r")) != NULL) {
686        read_file(buffer, sizeof(buffer), queuefile);
687        if (sscanf(readbuf, "From %s", fromaddy))
688           set_var("fromaddress", fromaddy, VAR_GLOBAL);
689        close_file(queuefile);
690     }
691     */
692     queuefile = setup_queuefile();
693     close_file(queuefile);
694 
695     res = do_hooks("SEND");
696     if(res == HOOK_RESULT_OK) {
697         res = do_hooks("FINAL");
698     }
699 
700     /* Remove our file! */
701     /* buffer_printf(buffer, sizeof(buffer) - 1, "%s.appout.%d", get_string("queuefile"), appcounter);*/
702     unlink_file(buffer);
703 
704     /* ...and set the queuefile back. */
705     set_var("queuefile",oldqueuefile,VAR_GLOBAL);
706     queuefile = setup_queuefile();
707     close_file(queuefile);
708 }
709