1 /*
2 * $Id: mailinglist.c,v 1.5.2.15 2009/03/09 01:35:01 tomcollins Exp $
3 * Copyright (C) 1999-2004 Inter7 Internet Technologies, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18 *
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include <unistd.h>
29 #include <pwd.h>
30 #include <dirent.h>
31 #include <errno.h>
32
33 #include <vpopmail_config.h>
34 /* undef some macros that get redefined in config.h below */
35 #undef PACKAGE_NAME
36 #undef PACKAGE_STRING
37 #undef PACKAGE_TARNAME
38 #undef PACKAGE_VERSION
39 #include <vpopmail.h>
40
41 #include "cgi.h"
42 #include "config.h"
43 #include "limits.h"
44 #include "mailinglist.h"
45 #include "printh.h"
46 #include "qmailadmin.h"
47 #include "qmailadminx.h"
48 #include "show.h"
49 #include "template.h"
50 #include "util.h"
51
52 char dotqmail_name[MAX_FILE_NAME];
53 char replyto_addr[256];
54 int replyto;
55 int dotnum;
56 int checkopt[256]; /* used to display mailing list options */
57
58 #define REPLYTO_SENDER 1
59 #define REPLYTO_LIST 2
60 #define REPLYTO_ADDRESS 3
61
62 void set_options();
63 void default_options();
64
show_mailing_lists(char * user,char * dom,time_t mytime)65 void show_mailing_lists(char *user, char *dom, time_t mytime)
66 {
67 if ( AdminType!=DOMAIN_ADMIN ) {
68 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
69 vclose();
70 exit(0);
71 }
72
73 /* see if there's anything to display */
74 count_mailinglists();
75 if ( CurMailingLists == 0 ) {
76 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[231]);
77 show_menu(Username, Domain, Mytime);
78 vclose();
79 exit(0);
80 }
81
82 if ( MaxMailingLists == 0 ) {
83 return;
84 }
85 send_template( "show_mailinglist.html" );
86 }
87
show_mailing_list_line(char * user,char * dom,time_t mytime,char * dir)88 void show_mailing_list_line(char *user, char* dom, time_t mytime, char *dir)
89 {
90 DIR *mydir;
91 struct dirent *mydirent;
92 FILE *fs;
93 char *addr;
94 char testfn[MAX_FILE_NAME];
95 int i;
96
97 if ( AdminType!=DOMAIN_ADMIN ) {
98 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
99 vclose();
100 exit(0);
101 }
102
103 if ( MaxMailingLists == 0 ) {
104 return;
105 }
106
107 if ( (mydir = opendir(".")) == NULL ) {
108 printf ("<tr><td>%s %d</tr><td>", html_text[143], 1);
109 return;
110 }
111
112 /* First display the title row */
113 printf ("<tr bgcolor=\"#cccccc\">");
114 printf ("<th align=center><font size=2>%s</font></th>", html_text[72]);
115 #ifdef EZMLMIDX
116 printf ("<th align=center><font size=2>%s</font></th>", html_text[71]);
117 #endif
118 printf ("<th align=center><font size=2>%s</font></th>", html_text[81]);
119 printf ("<th align=center><font size=2>%s</font></th>", html_text[83]);
120 printf ("<th align=center><font size=2>%s</font></th>", html_text[84]);
121 printf ("<th align=center><font size=2>%s</font></th>", html_text[85]);
122 #ifdef EZMLMIDX
123 printf ("<th align=center><font size=2>%s</font></th>", html_text[86]);
124 printf ("<th align=center><font size=2>%s</font></th>", html_text[87]);
125 printf ("<th align=center><font size=2>%s</font></th>", html_text[88]);
126 printf ("<th align=center><font size=2>%s</font></th>", html_text[237]);
127 printf ("<th align=center><font size=2>%s</font></th>", html_text[238]);
128 printf ("<th align=center><font size=2>%s</font></th>", html_text[239]);
129 #endif
130 printf ("</tr>\n");
131
132 sort_init();
133
134 /* Now, display each list */
135 while( (mydirent=readdir(mydir)) != NULL ) {
136 if ( strncmp(".qmail-", mydirent->d_name, 7) == 0 ) {
137 if ( (fs=fopen(mydirent->d_name,"r"))==NULL) {
138 #ifdef EZMLMIDX
139 printf ("<tr><td colspan=12>%s %s</td></tr>\n", html_text[144], mydirent->d_name);
140 #else
141 printf ("<tr><td colspan=5>%s %s</td></tr>\n", html_text[144], mydirent->d_name);
142 #endif
143 continue;
144 }
145 fgets(TmpBuf2, sizeof(TmpBuf2), fs);
146 fclose(fs);
147 if ( strstr( TmpBuf2, "ezmlm-reject") != 0 ) {
148 sort_add_entry (&mydirent->d_name[7], 0);
149 }
150 }
151 }
152 closedir(mydir);
153 sort_dosort();
154
155 for (i = 0; (addr = sort_get_entry(i)); ++i) {
156 sprintf (testfn, ".qmail-%s-digest-owner", addr);
157 /* convert ':' in addr to '.' */
158 str_replace (addr, ':', '.');
159
160 printf ("<tr>");
161 qmail_button(addr, "delmailinglist", user, dom, mytime, "trash.png");
162
163 #ifdef EZMLMIDX
164 qmail_button(addr, "modmailinglist", user, dom, mytime, "modify.png");
165 #endif
166 printh ("<td align=left>%H</td>\n", addr);
167
168 qmail_button(addr, "addlistuser", user, dom, mytime, "delete.png");
169 qmail_button(addr, "dellistuser", user, dom, mytime, "delete.png");
170 qmail_button(addr, "showlistusers", user, dom, mytime, "delete.png");
171
172 #ifdef EZMLMIDX
173 qmail_button(addr, "addlistmod", user, dom, mytime, "delete.png");
174 qmail_button(addr, "dellistmod", user, dom, mytime, "delete.png");
175 qmail_button(addr, "showlistmod", user, dom, mytime, "delete.png");
176
177 /* Is it a digest list? */
178 if ( (fs=fopen(testfn,"r"))==NULL) {
179 /* not a digest list */
180 printf ("<TD COLSPAN=3> </TD>");
181 } else {
182 qmail_button(addr, "addlistdig", user, dom, mytime, "delete.png");
183 qmail_button(addr, "dellistdig", user, dom, mytime, "delete.png");
184 qmail_button(addr, "showlistdig", user, dom, mytime, "delete.png");
185 fclose(fs);
186 }
187 #endif
188 printf ("</tr>\n");
189 }
190 sort_cleanup();
191 }
192
is_mailing_list(FILE * fs)193 int is_mailing_list(FILE *fs)
194 {
195 while (!feof(fs)) {
196 fgets( TmpBuf2, sizeof(TmpBuf2), fs);
197 if ( strstr( TmpBuf2, "ezmlm-reject") != 0 ||
198 strstr( TmpBuf2, "ezmlm-send") != 0 )
199 return -1;
200 }
201 return 0;
202 }
203
204 /* mailing list lines on the add user page */
show_mailing_list_line2(char * user,char * dom,time_t mytime,char * dir)205 void show_mailing_list_line2(char *user, char *dom, time_t mytime, char *dir)
206 {
207 DIR *mydir;
208 struct dirent *mydirent;
209 FILE *fs;
210 char *addr;
211 int i;
212 int listcount;
213
214 if ( AdminType!=DOMAIN_ADMIN ) {
215 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
216 vclose();
217 exit(0);
218 }
219
220 if (*EZMLMDIR == 'n' || MaxMailingLists == 0 ) {
221 return;
222 }
223
224 if ( (mydir = opendir(".")) == NULL ) {
225 printf ("%s %d<BR>\n", html_text[143], 1);
226 return;
227 }
228
229 listcount = 0;
230 sort_init();
231
232 while( (mydirent=readdir(mydir)) != NULL ) {
233 if ( strncmp(".qmail-", mydirent->d_name, 7) == 0 ) {
234 if ( (fs=fopen(mydirent->d_name,"r"))==NULL) {
235 printf ("%s %s<br>\n",
236 html_text[144], mydirent->d_name);
237 continue;
238 }
239 fgets( TmpBuf2, sizeof(TmpBuf2), fs);
240 fclose(fs);
241 if ( strstr( TmpBuf2, "ezmlm-reject") != 0 ) {
242 sort_add_entry (&mydirent->d_name[7], 0);
243 listcount++;
244 }
245 }
246 }
247 closedir(mydir);
248
249 /* if there aren't any lists, don't display anything */
250 if (listcount == 0) {
251 sort_cleanup();
252 return;
253 }
254
255 printf ("<hr><table width=100%% cellpadding=1 cellspacing=0 border=0");
256 printf (" align=center bgcolor=\"#000000\"><tr><td>");
257 printf ("<table width=100%% cellpadding=0 cellspacing=0 border=0 bgcolor=\"#e6e6e6\">");
258 printf ("<tr><th bgcolor=\"#000000\" colspan=2>");
259 printf ("<font color=\"#ffffff\">%s</font></th>\n",
260 html_text[95]);
261
262 sort_dosort();
263
264 printf ("<INPUT NAME=number_of_mailinglist TYPE=hidden VALUE=%d>\n", listcount);
265 for (i = 0; i < listcount; ++i)
266 {
267 addr = sort_get_entry(i);
268 str_replace (addr, ':', '.');
269 printh ("<TR><TD ALIGN=RIGHT><INPUT NAME=\"subscribe%d\" TYPE=checkbox VALUE=\"%H\"></TD>", i, addr);
270 printh ("<TD align=LEFT>%H@%H</TD></TR>", addr, Domain);
271 }
272 printf ("</table></td></tr></table>\n");
273 sort_cleanup();
274 }
275
addmailinglist()276 void addmailinglist()
277 {
278 if ( AdminType!=DOMAIN_ADMIN ) {
279 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
280 vclose();
281 exit(0);
282 }
283
284 count_mailinglists();
285 load_limits();
286 if ( MaxMailingLists != -1 && CurMailingLists >= MaxMailingLists ) {
287 printf ("%s %d\n", html_text[184],
288 MaxMailingLists);
289 show_menu(Username, Domain, Mytime);
290 vclose();
291 exit(0);
292 }
293
294 /* set up default options for new list */
295 default_options();
296
297 #ifdef EZMLMIDX
298 send_template( "add_mailinglist-idx.html" );
299 #else
300 send_template( "add_mailinglist-no-idx.html" );
301 #endif
302
303 }
304
delmailinglist()305 void delmailinglist()
306 {
307 if ( AdminType!=DOMAIN_ADMIN ) {
308 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
309 vclose();
310 exit(0);
311 }
312
313 send_template( "del_mailinglist_confirm.html" );
314 }
315
delmailinglistnow()316 void delmailinglistnow()
317 {
318 DIR *mydir;
319 struct dirent *mydirent;
320
321 if ( AdminType!=DOMAIN_ADMIN ) {
322 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
323 vclose();
324 exit(0);
325 }
326
327 if (fixup_local_name (ActionUser)) {
328 // invalid address given, abort
329 vclose();
330 exit(0);
331 }
332
333 if ( (mydir = opendir(".")) == NULL ) {
334 printf ("%s %d<BR>\n", html_text[143], 1);
335 printf ("</table>");
336 return;
337 }
338
339 #ifdef ONCHANGE_SCRIPT
340 snprintf ( onchange_buf , MAX_BUFF , "%s@%s" , ActionUser , Domain ) ;
341 call_onchange ( "delmailinglist" ) ;
342 #endif
343
344 /* make dotqmail name */
345 strcpy(dotqmail_name, ActionUser);
346 for(dotnum=0;dotqmail_name[dotnum]!='\0';dotnum++) {
347 if(dotqmail_name[dotnum]=='.') dotqmail_name[dotnum] = ':';
348 }
349
350 sprintf(TmpBuf2, ".qmail-%s", dotqmail_name);
351 sprintf(TmpBuf3, ".qmail-%s-", dotqmail_name);
352 while( (mydirent=readdir(mydir)) != NULL ) {
353
354 /* delete the main .qmail-"list" file */
355 if ( strcmp(TmpBuf2, mydirent->d_name) == 0 ) {
356 if ( unlink(mydirent->d_name) != 0 ) {
357 ack("185", TmpBuf2);
358 }
359
360 /* delete secondary .qmail-"list"-* files */
361 } else if ( strncmp(TmpBuf3, mydirent->d_name, strlen(TmpBuf3)) == 0 ) {
362 if ( unlink(mydirent->d_name) != 0 ) {
363 ack("185", TmpBuf2);
364 }
365 }
366 }
367 closedir(mydir);
368
369
370 sprintf(TmpBuf2, "%s/%s", RealDir, ActionUser);
371 vdelfiles(TmpBuf2);
372
373 count_mailinglists();
374 snprinth (StatusMessage, sizeof(StatusMessage), "%s %H\n", html_text[186], ActionUser);
375 if ( CurMailingLists == 0 ) {
376 show_menu(Username, Domain, Mytime);
377 } else {
378 show_mailing_lists(Username, Domain, Mytime);
379 }
380
381 }
382
383 /* sets the Reply-To header in header* files based on form fields
384 * designed to be called by ezmlm_make() (after calling ezmlm-make)
385 * Replaces the "Reply-To" line in <filename> with <newtext>.
386 */
ezmlm_setreplyto(char * filename,char * newtext)387 void ezmlm_setreplyto (char *filename, char *newtext)
388 {
389 FILE *headerfile, *temp;
390 char realfn[256];
391 char tempfn[256];
392 char buf[256];
393
394 sprintf (realfn, "%s/%s/%s", RealDir, ActionUser, filename);
395 sprintf (tempfn, "%s.tmp", realfn);
396
397 headerfile = fopen(realfn, "r");
398 if (!headerfile) return;
399 temp = fopen(tempfn, "w");
400 if (!temp) { fclose (headerfile); return; }
401
402 /* copy contents to new file, except for Reply-To header */
403 while (fgets (buf, sizeof(buf), headerfile) != NULL) {
404 if (strncasecmp ("Reply-To", buf, 8) != 0) {
405 fputs (buf, temp);
406 }
407 }
408
409 fputs (newtext, temp);
410
411 fclose (headerfile);
412 fclose (temp);
413 unlink (realfn);
414 rename (tempfn, realfn);
415 }
416
ezmlm_make(int newlist)417 void ezmlm_make (int newlist)
418 {
419 FILE * file;
420 int pid;
421
422 #ifdef EZMLMIDX
423 char list_owner[MAX_BUFF];
424 char owneremail[MAX_BUFF+5];
425 #endif
426 char options[MAX_BUFF];
427 char *arguments[MAX_BUFF];
428 int argc;
429 int i=0;
430 char tmp[MAX_BUFF];
431 char *tmpstr;
432 char loop_ch[64];
433 int loop;
434
435 /* Initialize listopt to be a string of the characters A-Z, with each one
436 * set to the correct case (e.g., A or a) to match the expected behavior
437 * of not checking any checkboxes. Leave other letters blank.
438 * NOTE: Leave F out, since we handle it manually.
439 */
440 char listopt[] = "A D hIj L N pQRST ";
441
442 if ( AdminType!=DOMAIN_ADMIN ) {
443 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
444 vclose();
445 exit(0);
446 }
447
448 if ( fixup_local_name(ActionUser) ) {
449 snprinth (StatusMessage, sizeof(StatusMessage), "%s %H\n", html_text[188], ActionUser);
450 addmailinglist();
451 vclose();
452 exit(0);
453 }
454
455 /* update listopt based on user selections */
456 for (loop = 0; loop < 20; loop++) {
457 sprintf(tmp, "opt%d=", loop);
458 GetValue(TmpCGI, loop_ch, tmp, sizeof(loop_ch));
459 for (tmpstr = loop_ch; *tmpstr; tmpstr++)
460 {
461 if ((*tmpstr >= 'A') && (*tmpstr <= 'Z')) {
462 listopt[*tmpstr-'A'] = *tmpstr;
463 } else if ((*tmpstr >= 'a') && (*tmpstr <= 'z')) {
464 listopt[*tmpstr-'a'] = *tmpstr;
465 }
466 }
467 }
468
469 /* don't allow option c, force option e if modifying existing list */
470 listopt[2] = ' ';
471 listopt[4] = newlist ? ' ' : 'e';
472
473 argc=0;
474 arguments[argc++] = "ezmlm-make";
475
476 #ifdef EZMLMIDX
477 /* check the list owner entry */
478 GetValue(TmpCGI, list_owner, "listowner=", sizeof(list_owner)); // Get the listowner
479 if ( strlen(list_owner) > 0 ) {
480 sprintf (owneremail, "-5%s", list_owner);
481 arguments[argc++] = owneremail;
482 }
483 #endif
484
485 /* build the option string */
486 tmpstr = options;
487 arguments[argc++] = tmpstr;
488 *tmpstr++ = '-';
489 #ifndef EZMLMIDX
490 /* non idx list, only allows options A and P */
491 *tmpstr++ = listopt[0]; /* a or A */
492 *tmpstr++ = listopt['p'-'a']; /* p or P */
493 *tmpstr++ = 0; /* add NULL terminator */
494 #else
495 /* ignore options v-z, but test a-u */
496 for (i = 0; i <= ('u'-'a'); i++)
497 {
498 if (listopt[i] != ' ') {
499 *tmpstr++ = listopt[i];
500 }
501 }
502 *tmpstr++ = 0; /* add NULL terminator */
503
504 /* check for sql support */
505 GetValue(TmpCGI, tmp, "sqlsupport=", sizeof(tmp));
506 if( strlen(tmp) > 0 ) {
507 arguments[argc++] = tmpstr;
508 tmpstr += sprintf (tmpstr, "%s", tmp) + 1;
509 arguments[argc++] = tmpstr;
510 for(loop = 1; loop <= NUM_SQL_OPTIONS; loop++) {
511 sprintf(tmp, "sql%d=", loop);
512 GetValue(TmpCGI, loop_ch, tmp, sizeof(loop_ch));
513 tmpstr += sprintf (tmpstr, "%s:", loop_ch);
514 }
515 /* remove trailing : */
516 tmpstr--;
517 *tmpstr++ = 0;
518 }
519 #endif
520
521 /* make dotqmail name */
522 strcpy(dotqmail_name, ActionUser);
523 for(dotnum=0;dotqmail_name[dotnum]!='\0';dotnum++) {
524 if(dotqmail_name[dotnum]=='.') dotqmail_name[dotnum] = ':';
525 }
526 pid=fork();
527 if (pid==0) {
528 sprintf(TmpBuf1, "%s/ezmlm-make", EZMLMDIR);
529 sprintf(TmpBuf2, "%s/%s", RealDir, ActionUser);
530 sprintf(TmpBuf3, "%s/.qmail-%s", RealDir, dotqmail_name);
531
532 arguments[argc++]=TmpBuf2;
533 arguments[argc++]=TmpBuf3;
534 arguments[argc++]=ActionUser;
535 arguments[argc++]=Domain;
536 arguments[argc]=NULL;
537
538 execv(TmpBuf1, arguments);
539 exit(127);
540 } else {
541 wait(&pid);
542 }
543
544 /*
545 * ezmlm-make -e leaves .qmail-listname-(accept||reject) links for some reason.
546 * (causing file permission errors in "show mailing lists") Also, it doesn't
547 * delete dir/digest/ when turning off digests. This section cleans up...
548 */
549 if(listopt['M'-'A'] == 'M') { /* moderation off */
550 sprintf(tmp, "%s/.qmail-%s-accept-default", RealDir, dotqmail_name);
551 unlink (tmp);
552 sprintf(tmp, "%s/.qmail-%s-reject-default", RealDir, dotqmail_name);
553 unlink (tmp);
554 }
555 if(listopt['D'-'A'] == 'D') { /* digest off */
556 sprintf(tmp, "%s/.qmail-%s-digest-return-default", RealDir, dotqmail_name);
557 unlink (tmp);
558 sprintf(tmp, "%s/.qmail-%s-digest-owner", RealDir, dotqmail_name);
559 unlink (tmp);
560
561 /* delete the digest directory */
562 sprintf(tmp, "%s/%s/digest", RealDir, ActionUser);
563 vdelfiles(tmp);
564 chdir(RealDir);
565 }
566
567 /* Check for prefix setting */
568 GetValue(TmpCGI, tmp, "prefix=", sizeof(tmp));
569
570 /* strip leading '[' and trailing ']' from tmp */
571 tmpstr = strchr (tmp, ']');
572 if (tmpstr != NULL) *tmpstr = '\0';
573 tmpstr = tmp;
574 while (*tmpstr == '[') tmpstr++;
575
576 /* Create (or delete) the file as appropriate */
577 sprintf(TmpBuf, "%s/%s/prefix", RealDir, ActionUser);
578 if (strlen(tmp) > 0)
579 {
580 file=fopen(TmpBuf , "w");
581 if (file)
582 {
583 fprintf(file, "[%s]", tmpstr);
584 fclose(file);
585 }
586 }
587 else
588 {
589 unlink (TmpBuf);
590 }
591
592 /* set Reply-To header */
593 GetValue (TmpCGI, TmpBuf, "replyto=", sizeof(TmpBuf));
594 replyto = atoi(TmpBuf);
595 if (replyto == REPLYTO_SENDER) {
596 /* ezmlm shouldn't remove/add Reply-To header */
597 ezmlm_setreplyto ("headeradd", "");
598 ezmlm_setreplyto ("headerremove", "");
599 } else {
600 if (replyto == REPLYTO_ADDRESS) {
601 GetValue (TmpCGI, replyto_addr, "replyaddr=", sizeof(replyto_addr));
602 sprintf (TmpBuf, "Reply-To: %s\n", replyto_addr);
603 } else { /* REPLYTO_LIST */
604 strcpy (TmpBuf, "Reply-To: <#l#>@<#h#>\n");
605 }
606 ezmlm_setreplyto ("headeradd", TmpBuf);
607 ezmlm_setreplyto ("headerremove", "Reply-To");
608 }
609
610 /* update inlocal file */
611 sprintf(TmpBuf, "%s/%s/inlocal", RealDir, ActionUser);
612 if ((file=fopen(TmpBuf, "w")) != NULL) {
613 fprintf(file, "%s-%s", Domain, ActionUser);
614 fclose(file);
615 }
616
617 #ifdef EZMLMIDX
618 /* if this is a new list, add owner as subscriber */
619 if (newlist && (*list_owner != '\0')) {
620 ezmlm_sub ("", list_owner);
621 if (listopt['M'-'A'] == 'm') { /* moderation on */
622 /* add owner as moderator/remote admin as well */
623 ezmlm_sub ("mod", list_owner);
624 }
625 }
626 #endif
627 }
628
addmailinglistnow()629 void addmailinglistnow()
630 {
631 count_mailinglists();
632 load_limits();
633 if ( MaxMailingLists != -1 && CurMailingLists >= MaxMailingLists ) {
634 printf ("%s %d\n", html_text[184],
635 MaxMailingLists);
636 show_menu(Username, Domain, Mytime);
637 vclose();
638 exit(0);
639 }
640
641 if ( check_local_user(ActionUser) ) {
642 snprinth (StatusMessage, sizeof(StatusMessage), "%s %H\n", html_text[175], ActionUser);
643 addmailinglist();
644 vclose();
645 exit(0);
646 }
647
648 ezmlm_make(1);
649
650 #ifdef ONCHANGE_SCRIPT
651 snprintf ( onchange_buf , MAX_BUFF , "%s@%s" , ActionUser , Domain ) ;
652 call_onchange ( "addmailinglist" ) ;
653 #endif
654
655 snprinth (StatusMessage, sizeof(StatusMessage), "%s %H@%H\n", html_text[187],
656 ActionUser, Domain);
657 show_mailing_lists(Username, Domain, Mytime);
658 }
659
show_list_group_now(int mod)660 void show_list_group_now(int mod)
661 {
662 /* mod = 0 for subscribers, 1 for moderators, 2 for digest users */
663
664 FILE *fs;
665 int handles[2],pid,z = 0,subuser_count = 0;
666 char buf[256];
667 char *addr;
668
669 if ( AdminType!=DOMAIN_ADMIN ) {
670 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
671 vclose();
672 exit(0);
673 }
674
675 lowerit(ActionUser);
676 pipe(handles);
677
678 pid=fork();
679 if (pid==0) {
680 close(handles[0]);
681 dup2(handles[1],fileno(stdout));
682 sprintf(TmpBuf1, "%s/ezmlm-list", EZMLMDIR);
683 if(mod == 1) {
684 sprintf(TmpBuf2, "%s/%s/mod", RealDir, ActionUser);
685 } else if(mod == 2) {
686 sprintf(TmpBuf2, "%s/%s/digest", RealDir, ActionUser);
687 } else {
688 sprintf(TmpBuf2, "%s/%s/", RealDir, ActionUser);
689 }
690 execl(TmpBuf1, "ezmlm-list", TmpBuf2, NULL);
691 exit(127);
692 } else {
693 close(handles[1]);
694 fs = fdopen(handles[0],"r");
695
696 /* Load subscriber/moderator list */
697
698 sort_init();
699 while( (fgets(buf, sizeof(buf), fs)!= NULL)) {
700 sort_add_entry (buf, '\n'); /* don't copy newline */
701 subuser_count++;
702 }
703
704 sort_dosort();
705
706 /* Display subscriber/moderator/digest list, along with delete button */
707 if(mod == 1) {
708 strcpy(TmpBuf, "228"); strcpy(TmpBuf1, "220");
709 /* strcpy(TmpBuf2, "087"); */
710 } else if(mod == 2) {
711 strcpy(TmpBuf, "244"); strcpy(TmpBuf1, "246");
712 /* strcpy(TmpBuf2, "245"); */
713 } else {
714 strcpy(TmpBuf, "230"); strcpy(TmpBuf1, "222");
715 /* strcpy(TmpBuf2, "084"); */
716 }
717 strcpy(TmpBuf2, "072");
718 printf ("<TABLE border=0 width=\"100%%\">\n");
719 printf (" <TR>\n");
720 printf (" <TH align=left COLSPAN=4><B>%s</B> %d<BR><BR></TH>\n", get_html_text(TmpBuf), subuser_count);
721 printf (" </TR>\n");
722 printf (" <TR align=center bgcolor=%s>\n", get_color_text("002"));
723 printf (" <TH align=center><b><font size=2>%s</font></b></TH>\n", get_html_text(TmpBuf2));
724 printf (" <TH align=center><b><font size=2>%s</font></b></TH>\n", get_html_text(TmpBuf1));
725 printf (" <TH align=center><b><font size=2>%s</font></b></TH>\n", get_html_text(TmpBuf2));
726 printf (" <TH align=center><b><font size=2>%s</font></b></TH>\n", get_html_text(TmpBuf1));
727 printf (" </TR>\n");
728
729 if(mod == 1) {
730 strcpy(TmpBuf, "dellistmodnow");
731 } else if(mod == 2) {
732 strcpy(TmpBuf, "dellistdignow");
733 } else {
734 strcpy(TmpBuf, "dellistusernow");
735 }
736 for(z = 0; (addr = sort_get_entry(z)); ++z) {
737 printf (" <TR align=center>");
738 printh (" <TD align=right><A href=\"%s&modu=%C&newu=%C\"><IMG src=\"%s/trash.png\" border=0></A></TD>\n",
739 cgiurl(TmpBuf), ActionUser, addr, IMAGEURL);
740 printh (" <TD align=left>%H</TD>\n", addr);
741 ++z;
742 if( (addr = sort_get_entry(z)) ) {
743 printh (" <TD align=right><A href=\"%s&modu=%C&newu=%C\"><IMG src=\"%s/trash.png\" border=0></A></TD>\n",
744 cgiurl(TmpBuf), ActionUser, addr, IMAGEURL);
745 printh (" <TD align=left>%H</TD>\n", addr);
746 } else {
747 printf (" <TD COLSPAN=2> </TD>");
748 }
749 printf (" </TR>");
750 }
751
752 sort_cleanup();
753
754 printf ("</TABLE>");
755 fclose(fs); close(handles[0]);
756 wait(&pid);
757 snprintf (StatusMessage, sizeof(StatusMessage), "%s\n", html_text[190]);
758 /* printf (get_html_text("END_LIST_NAMES")); */
759
760 }
761 }
762
show_list_group(char * template)763 void show_list_group(char *template)
764 {
765 if (AdminType != DOMAIN_ADMIN) {
766 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
767 vclose();
768 exit(0);
769 }
770
771 if (MaxMailingLists == 0) {
772 return;
773 }
774
775 send_template(template);
776 }
777
addlistgroup(char * template)778 void addlistgroup (char *template)
779 {
780 if ( AdminType!=DOMAIN_ADMIN ) {
781 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
782 vclose();
783 exit(0);
784 }
785 send_template(template);
786 }
787
addlistuser()788 void addlistuser() { addlistgroup( "add_listuser.html" ); }
addlistmod()789 void addlistmod() { addlistgroup( "add_listmod.html" ); }
addlistdig()790 void addlistdig() { addlistgroup( "add_listdig.html" ); }
791
792 /* returns 0 for success */
ezmlm_sub(char * dir,char * email)793 int ezmlm_sub (char *dir, char *email)
794 {
795 int pid;
796 char subpath[MAX_BUFF];
797 char listpath[MAX_BUFF];
798
799 pid=fork();
800 if (pid==0) {
801 snprintf(subpath, sizeof(subpath), "%s/ezmlm-sub", EZMLMDIR);
802 snprintf(listpath, sizeof(listpath), "%s/%s/%s",
803 RealDir, ActionUser, dir);
804 execl(subpath, "ezmlm-sub", listpath, email, NULL);
805 exit(127);
806 } else wait(&pid);
807
808 /* need to check exit code for failure somehow */
809
810 return 0;
811 }
812
addlistgroupnow(int mod)813 void addlistgroupnow (int mod)
814 {
815 // mod = 0 for subscribers, 1 for moderators, 2 for digest subscribers
816
817 if ( AdminType!=DOMAIN_ADMIN ) {
818 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
819 vclose();
820 exit(0);
821 }
822
823 lowerit(ActionUser);
824
825 if ( check_email_addr(Newu) ) {
826 snprinth (StatusMessage, sizeof(StatusMessage), "%s %H\n", html_text[148], Newu);
827 if (mod == 1) {
828 addlistmod();
829 } else if (mod == 2) {
830 addlistdig();
831 } else {
832 addlistuser();
833 }
834 vclose();
835 exit(0);
836 }
837
838 if(mod == 1 ) {
839 ezmlm_sub ("mod", Newu);
840 snprinth (StatusMessage, sizeof(StatusMessage), "%H %s %H@%H\n", Newu,
841 html_text[194], ActionUser, Domain);
842 send_template( "add_listmod.html" );
843 } else if(mod == 2) {
844 ezmlm_sub ("digest", Newu);
845 snprinth (StatusMessage, sizeof(StatusMessage), "%H %s %H@%H\n", Newu,
846 html_text[240], ActionUser, Domain);
847 send_template( "add_listdig.html" );
848 } else {
849 ezmlm_sub ("", Newu);
850 snprinth (StatusMessage, sizeof(StatusMessage), "%H %s %H@%H\n", Newu,
851 html_text[193], ActionUser, Domain);
852 send_template( "add_listuser.html" );
853 }
854 vclose();
855 exit(0);
856 }
857
dellistgroup(char * template)858 void dellistgroup(char *template)
859 {
860 if ( AdminType!=DOMAIN_ADMIN ) {
861 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
862 vclose();
863 exit(0);
864 }
865
866 send_template(template);
867 }
868
dellistgroupnow(int mod)869 void dellistgroupnow(int mod)
870 {
871 int pid;
872 char *p;
873
874 if ( AdminType!=DOMAIN_ADMIN ) {
875 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
876 vclose();
877 exit(0);
878 }
879
880 lowerit(Newu);
881
882 // for dealing with AOL spam complaints, if address doesn't contain @,
883 // but does contain '=', change the '=' to '@'.
884 if (! strchr (Newu, '@')) {
885 if ((p = strchr (Newu, '='))) *p = '@';
886 }
887
888 pid=fork();
889 if (pid==0) {
890 sprintf(TmpBuf1, "%s/ezmlm-unsub", EZMLMDIR);
891 if(mod == 1) {
892 sprintf(TmpBuf2, "%s/%s/mod", RealDir, ActionUser);
893 } else if(mod == 2 ) {
894 sprintf(TmpBuf2, "%s/%s/digest", RealDir, ActionUser);
895 } else {
896 sprintf(TmpBuf2, "%s/%s/", RealDir, ActionUser);
897 }
898 execl(TmpBuf1, "ezmlm-unsub", TmpBuf2, Newu, NULL);
899 exit(127);
900 } else wait(&pid);
901
902 if(mod == 1) {
903 snprinth (StatusMessage, sizeof(StatusMessage), "%H %s %H@%H\n", Newu, html_text[197],
904 ActionUser, Domain);
905 } else if(mod == 2) {
906 snprinth (StatusMessage, sizeof(StatusMessage), "%H %s %H@%H\n", Newu, html_text[242],
907 ActionUser, Domain);
908 } else {
909 snprinth (StatusMessage, sizeof(StatusMessage), "%H %s %H@%H\n", Newu, html_text[203],
910 ActionUser, Domain);
911 }
912 show_mailing_lists(Username, Domain, Mytime);
913 vclose();
914 exit(0);
915 }
916
count_mailinglists()917 void count_mailinglists()
918 {
919 DIR *mydir;
920 struct dirent *mydirent;
921 FILE *fs;
922
923 if ( (mydir = opendir(".")) == NULL ) {
924 printf ("%s %d<BR>\n", html_text[143], 1);
925 printf ("</table>");
926 return;
927 }
928
929
930 CurMailingLists = 0;
931 while( (mydirent=readdir(mydir)) != NULL ) {
932 if ( strncmp(".qmail-", mydirent->d_name, 7) == 0 ) {
933 if ( (fs=fopen(mydirent->d_name,"r"))==NULL) {
934 printf (html_text[144], mydirent->d_name);
935 continue;
936 }
937 fgets( TmpBuf2, sizeof(TmpBuf2), fs);
938 if ( strstr( TmpBuf2, "ezmlm-reject") != 0 ) {
939 ++CurMailingLists;
940 }
941 fclose(fs);
942 }
943 }
944 closedir(mydir);
945
946 }
947
modmailinglist()948 void modmailinglist()
949 {
950 /* name of list to modify is stored in ActionUser */
951 int i;
952 FILE *fs;
953
954 if ( AdminType!=DOMAIN_ADMIN ) {
955 snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[142]);
956 vclose();
957 exit(0);
958 }
959
960 strcpy (Alias, ""); /* initialize Alias (list owner) to empty string */
961
962 /* get the current listowner and copy it to Alias */
963 strcpy (dotqmail_name, ActionUser);
964 str_replace (dotqmail_name, '.', ':');
965 sprintf(TmpBuf, ".qmail-%s-owner", dotqmail_name);
966 if((fs=fopen(TmpBuf, "r"))!=NULL) {
967 while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
968 if(strstr(TmpBuf2, "@")!=NULL) {
969 /* strip leading & if present */
970 sprintf(Alias, "%s", (*TmpBuf2 == '&' ? (TmpBuf2 + 1) : TmpBuf2) );
971 i = strlen(Alias); --i; Alias[i] = '\0'; /* strip newline */
972 }
973 }
974 fclose(fs);
975 }
976
977 /* set default to "replies go to original sender" */
978 replyto = REPLYTO_SENDER; /* default */
979 *replyto_addr = '\0';
980 sprintf(TmpBuf, "%s/headeradd", ActionUser);
981 /* get the Reply-To setting for the list */
982 if ((fs = fopen (TmpBuf, "r")) != NULL) {
983 while (fgets (TmpBuf2, sizeof(TmpBuf2), fs)) {
984 if (strncasecmp ("Reply-To: ", TmpBuf2, 10) == 0) {
985 i = strlen(TmpBuf2); --i; TmpBuf2[i] = '\0'; /* strip newline */
986 if (strcmp ("<#l#>@<#h#>", TmpBuf2 + 10) == 0) {
987 replyto = REPLYTO_LIST;
988 } else {
989 replyto = REPLYTO_ADDRESS;
990 strcpy (replyto_addr, TmpBuf2 + 10);
991 }
992 }
993 }
994 fclose(fs);
995 }
996
997 /* read in options for the current list */
998 set_options();
999
1000 #ifdef EZMLMIDX
1001 send_template( "mod_mailinglist-idx.html" );
1002 #else
1003 send_template( "show_mailinglists.html" );
1004 #endif
1005
1006 }
1007
modmailinglistnow()1008 void modmailinglistnow()
1009 {
1010 ezmlm_make(0);
1011
1012 snprinth (StatusMessage, sizeof(StatusMessage), "%s %H@%H\n", html_text[226],
1013 ActionUser, Domain);
1014 show_mailing_lists(Username, Domain, Mytime);
1015 }
1016
build_list_value(char * param,char * color,char * opt1,int desc1,char * opt2,int desc2,int checked)1017 void build_list_value(char *param, char *color, char *opt1, int desc1, char *opt2, int desc2, int checked)
1018 {
1019 printf ("<tr bgcolor=%s>\n", get_color_text(color));
1020 printf (" <td>\n");
1021 printf (" <input type=radio name=%s value=%s%s></td>\n", param, opt1, checked ? "" : " CHECKED");
1022 printf (" <td>%s</td>\n", html_text[desc1]);
1023 printf (" <td>\n");
1024 printf (" <input type=radio name=%s value=%s%s></td>\n", param, opt2, checked ? " CHECKED" : "");
1025 printf (" <td>%s</td>\n", html_text[desc2]);
1026 printf ("</tr>\n");
1027 }
1028
build_option_str(char * type,char * param,char * options,char * description)1029 void build_option_str (char *type, char *param, char *options, char *description)
1030 {
1031 int selected;
1032 char *optptr;
1033
1034 selected = 1;
1035 for (optptr = options; *optptr; optptr++)
1036 {
1037 selected = selected && checkopt[(int) *optptr];
1038 }
1039 /* selected is now true if all options for this radio button are true */
1040
1041 printh ("<INPUT TYPE=%s NAME=\"%H\" VALUE=\"%H\"%s> %s\n",
1042 type, param, options, selected ? " CHECKED" : "", description);
1043 }
1044
file_exists(char * filename)1045 int file_exists (char *filename)
1046 {
1047 FILE *fs;
1048 if( (fs=fopen(filename, "r")) !=NULL ) {
1049 fclose(fs);
1050 return 1;
1051 } else {
1052 return 0;
1053 }
1054 }
1055
get_ezmlmidx_line_arguments(char * line,char * program,char argument)1056 int get_ezmlmidx_line_arguments(char *line, char *program, char argument)
1057 {
1058 char *begin;
1059 char *end;
1060 char *arg;
1061
1062 // does line contain program name?
1063 if ((strstr(line, program)) != NULL) {
1064 // find the options
1065 begin=strchr(line, ' ');
1066 begin++;
1067 if (*begin == '-') {
1068 end=strchr(begin, ' ');
1069 arg=strchr(begin, argument);
1070 // if arg is found && it's in the options (before the trailing space), return 1
1071 if (arg && (arg < end)) return 1;
1072 }
1073 }
1074 return 0;
1075 }
1076
set_options()1077 void set_options() {
1078 char c;
1079 FILE *fs;
1080
1081 /*
1082 * Note that with ezmlm-idx it might be possible to replace most
1083 * of this code by reading the config file in the list's directory.
1084 */
1085
1086 /* make dotqmail name (ActionUser with '.' replaced by ':') */
1087 strcpy(dotqmail_name, ActionUser);
1088 for(dotnum=0;dotqmail_name[dotnum]!='\0';dotnum++) {
1089 if(dotqmail_name[dotnum]=='.') dotqmail_name[dotnum] = ':';
1090 }
1091
1092 // default to false for lowercase letters
1093 for (c = 'a'; c <= 'z'; checkopt[(int) c++] = 0);
1094
1095 // figure out some options in the -default file
1096 sprintf(TmpBuf, ".qmail-%s-default", dotqmail_name);
1097 if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
1098 while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
1099 if((get_ezmlmidx_line_arguments(TmpBuf2, "ezmlm-get", 'P')) > 0) {
1100 checkopt['b'] = 1;
1101 }
1102 if((get_ezmlmidx_line_arguments(TmpBuf2, "ezmlm-get", 's')) > 0) {
1103 checkopt['g'] = 1;
1104 }
1105 if((get_ezmlmidx_line_arguments(TmpBuf2, "ezmlm-manage", 'S')) > 0) {
1106 checkopt['h'] = 1;
1107 }
1108 if((get_ezmlmidx_line_arguments(TmpBuf2, "ezmlm-manage", 'U')) > 0) {
1109 checkopt['j'] = 1;
1110 }
1111 if((get_ezmlmidx_line_arguments(TmpBuf2, "ezmlm-manage", 'l')) > 0) {
1112 checkopt['l'] = 1;
1113 }
1114 if((get_ezmlmidx_line_arguments(TmpBuf2, "ezmlm-manage", 'e')) > 0) {
1115 checkopt['n'] = 1;
1116 }
1117 if((strstr(TmpBuf2, "ezmlm-request")) != 0) {
1118 checkopt['q'] = 1;
1119 }
1120 }
1121 fclose(fs);
1122 }
1123
1124 // figure out some options in the -accept-default file
1125 sprintf(TmpBuf, ".qmail-%s-accept-default", dotqmail_name);
1126 if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
1127 while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
1128 if(strstr(TmpBuf2, "ezmlm-archive") !=0) {
1129 checkopt['i'] = 1;
1130 }
1131 }
1132 fclose(fs);
1133 }
1134
1135 // figure out some options in the qmail file
1136 sprintf(TmpBuf, ".qmail-%s", dotqmail_name);
1137 if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
1138 while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
1139 if((get_ezmlmidx_line_arguments(TmpBuf2, "ezmlm-store", 'P')) > 0) {
1140 checkopt['o'] = 1;
1141 }
1142 if((strstr(TmpBuf2, "ezmlm-gate")) != 0 || (strstr(TmpBuf2, "ezmlm-issubn")) != 0) {
1143 checkopt['u'] = 1;
1144 }
1145 if(strstr(TmpBuf2, "ezmlm-archive") !=0) {
1146 checkopt['i'] = 1;
1147 }
1148 }
1149 fclose(fs);
1150 }
1151
1152 sprintf(TmpBuf, ".qmail-%s-accept-default", dotqmail_name);
1153 checkopt['m'] = file_exists(TmpBuf);
1154
1155 sprintf(TmpBuf, "%s/archived", ActionUser);
1156 checkopt['a'] = file_exists(TmpBuf);
1157
1158 sprintf(TmpBuf, "%s/digest/bouncer", ActionUser);
1159 checkopt['d'] = file_exists(TmpBuf);
1160
1161 sprintf(TmpBuf, "%s/prefix", ActionUser);
1162 checkopt['f'] = file_exists(TmpBuf);
1163
1164 sprintf(TmpBuf, "%s/public", ActionUser);
1165 checkopt['p'] = file_exists(TmpBuf);
1166
1167 sprintf(TmpBuf, "%s/remote", ActionUser);
1168 checkopt['r'] = file_exists(TmpBuf);
1169
1170 sprintf(TmpBuf, "%s/modsub", ActionUser);
1171 checkopt['s'] = file_exists(TmpBuf);
1172
1173 sprintf(TmpBuf, "%s/text/trailer", ActionUser);
1174 checkopt['t'] = file_exists(TmpBuf);
1175
1176 /* update the uppercase option letters (just the opposite of the lowercase) */
1177 for (c = 'A'; c <= 'Z'; c++)
1178 {
1179 checkopt[(int) c] = !checkopt[(int) (c - 'A' + 'a')];
1180 }
1181 }
1182
default_options()1183 void default_options() {
1184 char c;
1185
1186 *dotqmail_name = '\0';
1187 replyto = REPLYTO_SENDER;
1188 *replyto_addr = '\0';
1189
1190 /* These are currently set to defaults for a good, generic list.
1191 * Basically, make it safe/friendly and don't turn anything extra on.
1192 */
1193
1194 /* for the options below, use 1 for "on" or "yes" */
1195 checkopt['a'] = 1; /* Archive */
1196 checkopt['b'] = 1; /* Moderator-only access to archive */
1197 checkopt['c'] = 0; /* ignored */
1198 checkopt['d'] = 0; /* Digest */
1199 checkopt['e'] = 0; /* ignored */
1200 checkopt['f'] = 1; /* Prefix */
1201 checkopt['g'] = 1; /* Guard Archive */
1202 checkopt['h'] = 0; /* Subscribe doesn't require conf */
1203 checkopt['i'] = 0; /* Indexed */
1204 checkopt['j'] = 0; /* Unsubscribe doesn't require conf */
1205 checkopt['k'] = 0; /* Create a blocked sender list */
1206 checkopt['l'] = 0; /* Remote admins can access subscriber list */
1207 checkopt['m'] = 0; /* Moderated */
1208 checkopt['n'] = 0; /* Remote admins can edit text files */
1209 checkopt['o'] = 0; /* Others rejected (for Moderated lists only */
1210 checkopt['p'] = 1; /* Public */
1211 checkopt['q'] = 1; /* Service listname-request */
1212 checkopt['r'] = 0; /* Remote Administration */
1213 checkopt['s'] = 0; /* Subscriptions are moderated */
1214 checkopt['t'] = 0; /* Add Trailer to outgoing messages */
1215 checkopt['u'] = 1; /* Only subscribers can post */
1216 checkopt['v'] = 0; /* ignored */
1217 checkopt['w'] = 0; /* special ezmlm-warn handling (ignored) */
1218 checkopt['x'] = 0; /* enable some extras (ignored) */
1219 checkopt['y'] = 0; /* ignored */
1220 checkopt['z'] = 0; /* ignored */
1221
1222 /* update the uppercase option letters (just the opposite of the lowercase) */
1223 for (c = 'A'; c <= 'Z'; c++)
1224 {
1225 checkopt[(int) c] = !checkopt[(int) (c - 'A' + 'a')];
1226 }
1227 }
1228
show_current_list_values()1229 void show_current_list_values() {
1230 FILE *fs;
1231 int sqlfileok = 0;
1232 int usesql = 0;
1233 int i=0,j;
1234 char checked1[MAX_BUFF] = "";
1235 char listname[128];
1236 int checked;
1237
1238 /* Note that we do not support the following list options:
1239 * k - posts from addresses in listname/deny are rejected
1240 * x - strip annoying MIME parts (spreadsheets, rtf, html, etc.)
1241 * 0 - make the list a sublist of another list
1242 * 3 - replace the From: header with another address
1243 * 4 - digest options (limits related to sending digest out)
1244 * 7, 8, 9 - break moderators up into message, subscription and admin
1245 */
1246
1247 /* IMPORTANT: If you change the behavior of the checkboxes, you need
1248 * to update the default settings in modmailinglistnow so qmailadmin
1249 * will use the proper settings when a checkbox isn't checked.
1250 */
1251
1252 if (*dotqmail_name) { /* modifying an existing list */
1253 snprinth (listname, sizeof(listname), "%H", dotqmail_name);
1254 str_replace (listname, ':', '.');
1255 } else {
1256 sprintf (listname, "<I>%s</I>", html_text[261]);
1257 }
1258
1259 /* Posting Messages */
1260 printf ("<P><B><U>%s</U></B><BR>\n", html_text[262]);
1261 build_option_str ("RADIO", "opt1", "MU", html_text[263]);
1262 printf ("<BR>\n");
1263 build_option_str ("RADIO", "opt1", "Mu", html_text[264]);
1264 printf ("<BR>\n");
1265 build_option_str ("RADIO", "opt1", "mu", html_text[265]);
1266 printf ("<BR>\n");
1267 build_option_str ("RADIO", "opt1", "mUo", html_text[266]);
1268 printf ("<BR>\n");
1269 build_option_str ("RADIO", "opt1", "mUO", html_text[267]);
1270 printf ("</P>\n");
1271
1272 /* List Options */
1273 printf ("<P><B><U>%s</U></B><BR>\n", html_text[268]);
1274 /* this next option isn't necessary since we use the edit box to
1275 * set/delete the prefix
1276 sprintf (TmpBuf, html_text[269], listname);
1277 build_option_str ("CHECKBOX", "opt3", "f", TmpBuf);
1278 printf ("<BR>\n");
1279 */
1280 printf ("<TABLE><TR><TD ROWSPAN=3 VALIGN=TOP>%s</TD>",
1281 html_text[310]);
1282 printf ("<TD><INPUT TYPE=RADIO NAME=\"replyto\" VALUE=\"%d\"%s>%s</TD></TR>\n",
1283 REPLYTO_SENDER, (replyto == REPLYTO_SENDER) ? " CHECKED" : "", html_text[311]);
1284 printf ("<TR><TD><INPUT TYPE=RADIO NAME=\"replyto\" VALUE=\"%d\"%s>%s</TD></TR>\n",
1285 REPLYTO_LIST, (replyto == REPLYTO_LIST) ? " CHECKED" : "", html_text[312]);
1286 printf ("<TR><TD><INPUT TYPE=RADIO NAME=\"replyto\" VALUE=\"%d\"%s>%s ",
1287 REPLYTO_ADDRESS, (replyto == REPLYTO_ADDRESS) ? " CHECKED" : "", html_text[313]);
1288 printh ("<INPUT TYPE=TEXT NAME=\"replyaddr\" VALUE=\"%H\" SIZE=30></TD></TR>\n",
1289 replyto_addr);
1290 printf ("</TABLE><BR>\n");
1291 build_option_str ("CHECKBOX", "opt4", "t", html_text[270]);
1292 printf ("<BR>\n");
1293 build_option_str ("CHECKBOX", "opt5", "d", html_text[271]);
1294 sprintf (TmpBuf, html_text[272], listname);
1295 printf ("<SMALL>(%s)</SMALL>", TmpBuf);
1296 printf ("<BR>\n");
1297 sprintf (TmpBuf, html_text[273], listname);
1298 build_option_str ("CHECKBOX", "opt6", "q", TmpBuf);
1299 printf ("<BR>\n");
1300 sprintf (TmpBuf, html_text[274], listname, listname, listname);
1301 printf (" <SMALL>(%s)</SMALL></P>", TmpBuf);
1302
1303 /* Remote Administration */
1304 printf ("<P><B><U>%s</U></B><BR>\n", html_text[275]);
1305 build_option_str ("CHECKBOX", "opt7", "r", html_text[276]);
1306 printf ("<BR>\n");
1307 build_option_str ("CHECKBOX", "opt8", "P", html_text[277]);
1308 printf ("<SMALL>(%s)</SMALL><BR>", html_text[278]);
1309 printf ("<TABLE><TR><TD ROWSPAN=2 VALIGN=TOP>%s</TD>",
1310 html_text[279]);
1311 printf ("<TD>");
1312 build_option_str ("CHECKBOX", "opt9", "l", html_text[280]);
1313 printf ("</TD>\n</TR><TR>\n<TD>");
1314 build_option_str ("CHECKBOX", "opt10", "n", html_text[281]);
1315 printf ("<SMALL>(%s)</SMALL>.</TD>\n", html_text[282]);
1316 printf ("</TR></TABLE>\n</P>\n");
1317
1318 printf ("<P><B><U>%s</U></B><BR>\n", html_text[283]);
1319 printf ("%s<BR>\n ", html_text[284]);
1320 build_option_str ("CHECKBOX", "opt11", "H", html_text[285]);
1321 printf ("<BR>\n ");
1322 build_option_str ("CHECKBOX", "opt12", "s", html_text[286]);
1323 printf ("<BR>\n%s<BR>\n ", html_text[287]);
1324 build_option_str ("CHECKBOX", "opt13", "J", html_text[285]);
1325 printf ("<BR>\n");
1326 printf ("<SMALL>%s</SMALL>\n</P>\n", html_text[288]);
1327
1328 printf ("<P><B><U>%s</U></B><BR>\n", html_text[289]);
1329 build_option_str ("CHECKBOX", "opt14", "a", html_text[290]);
1330 printf (" %s\n<SELECT NAME=\"opt15\">", html_text[292]);
1331 printf ("<OPTION VALUE=\"BG\"%s>%s\n",
1332 checkopt['B'] && checkopt['G'] ? " SELECTED" : "", html_text[293]);
1333 printf ("<OPTION VALUE=\"Bg\"%s>%s\n",
1334 checkopt['B'] && checkopt['g'] ? " SELECTED" : "", html_text[294]);
1335 printf ("<OPTION VALUE=\"b\"%s>%s\n",
1336 checkopt['b'] ? " SELECTED" : "", html_text[295]);
1337 printf ("</SELECT>.");
1338 printf ("<BR>\n");
1339 /* note that if user doesn't have ezmlm-cgi installed, it might be
1340 a good idea to default to having option i off. */
1341 build_option_str ("CHECKBOX", "opt16", "i", html_text[291]);
1342 printf ("</P>\n");
1343
1344 /***********************/
1345 /* begin MySQL options */
1346 /***********************/
1347
1348 /* See if sql is turned on */
1349 checked = 0;
1350 sprintf(TmpBuf, "%s/sql", ActionUser);
1351 if( (fs=fopen(TmpBuf, "r")) !=NULL ) {
1352 checked = 1;
1353 while(fgets(TmpBuf2, sizeof(TmpBuf2), fs)) {
1354 strcpy(TmpBuf1, TmpBuf2);
1355 i = strlen(TmpBuf1); --i; TmpBuf1[i] = 0; /* take off newline */
1356 if((strstr(TmpBuf1, ":")) != NULL) {
1357 sqlfileok = 1;
1358 }
1359 }
1360 usesql = 1;
1361 fclose(fs);
1362 }
1363 #ifdef ENABLE_MYSQL
1364 printf ("<P><B><U>%s</U></B><BR>\n", html_text[99]);
1365 printf ("<input type=checkbox name=\"sqlsupport\" value=\"-6\"%s> %s",
1366 checked ? " CHECKED" : "", html_text[53]);
1367
1368 /* parse dir/sql file for SQL settings */
1369 printf (" <table cellpadding=0 cellspacing=2 border=0>\n");
1370 #else
1371 if (checked)
1372 printf ("<INPUT TYPE=HIDDEN NAME=sqlsupport VALUE=\"-6\">\n");
1373 #endif
1374
1375 /* get hostname */
1376 strcpy(checked1, "localhost");
1377 if(usesql == 1 && sqlfileok == 1) {
1378 strncpy(TmpBuf3, TmpBuf1, 1);
1379 if((strstr(TmpBuf3, ":")) == NULL) {
1380 for(i=0,j=0;TmpBuf1[i]!=':'&&TmpBuf1[i]!='\0';++j,++i) checked1[j] = TmpBuf1[i];
1381 checked1[j] = '\0';
1382 }
1383 }
1384
1385 #ifdef ENABLE_MYSQL
1386 printf (" <tr>\n");
1387 printf (" <td ALIGN=RIGHT>%s:\n", html_text[54]);
1388 printf (" </td><td>\n");
1389 printh (" <input type=text name=sql1 value=\"%H\"></td>\n", checked1);
1390 #else
1391 printh ("<INPUT TYPE=HIDDEN NAME=sql1 VALUE=\"%H\">\n", checked1);
1392 #endif
1393
1394 /* get port */
1395 strcpy(checked1, "3306");
1396 if(usesql == 1 && sqlfileok == 1) {
1397 strncpy(TmpBuf3, &TmpBuf1[++i], 1);
1398 if((strstr(TmpBuf3, ":")) == NULL) {
1399 for(j=0;TmpBuf1[i]!=':'&&TmpBuf1[i]!='\0';++j,++i) checked1[j] = TmpBuf1[i];
1400 checked1[j] = '\0';
1401 }
1402 }
1403 #ifdef ENABLE_MYSQL
1404 printf (" <td ALIGN=RIGHT>%s:\n", html_text[55]);
1405 printf (" </td><td>\n");
1406 printh (" <input type=text size=7 name=sql2 value=\"%H\"></td>\n", checked1);
1407 printf (" </tr>\n");
1408 #else
1409 printh ("<INPUT TYPE=HIDDEN NAME=sql2 VALUE=\"%H\">\n", checked1);
1410 #endif
1411
1412 /* get user */
1413 strcpy(checked1, "");
1414 if(usesql == 1 && sqlfileok == 1) {
1415 strncpy(TmpBuf3, &TmpBuf1[++i], 1);
1416 if((strstr(TmpBuf3, ":")) == NULL) {
1417 for(j=0;TmpBuf1[i]!=':'&&TmpBuf1[i]!='\0';++j,++i) checked1[j] = TmpBuf1[i];
1418 checked1[j] = '\0';
1419 }
1420 }
1421 #ifdef ENABLE_MYSQL
1422 printf (" <tr>\n");
1423 printf (" <td ALIGN=RIGHT>%s:\n", html_text[56]);
1424 printf (" </td><td>\n");
1425 printh (" <input type=text name=sql3 value=\"%H\"></td>\n", checked1);
1426 #else
1427 printh ("<INPUT TYPE=HIDDEN NAME=sql3 VALUE=\"%H\">\n", checked1);
1428 #endif
1429
1430 /* get password */
1431 strcpy(checked1, "");
1432 if(usesql == 1 && sqlfileok == 1) {
1433 strncpy(TmpBuf3, &TmpBuf1[++i], 1);
1434 if((strstr(TmpBuf3, ":")) == NULL) {
1435 for(j=0;TmpBuf1[i]!=':'&&TmpBuf1[i]!='\0';++j,++i) checked1[j] = TmpBuf1[i];
1436 checked1[j] = '\0';
1437 }
1438 }
1439 #ifdef ENABLE_MYSQL
1440 printf (" <td ALIGN=RIGHT>%s:\n", html_text[57]);
1441 printf (" </td><td>\n");
1442 printh (" <input type=text name=sql4 value=\"%H\"></td>\n", checked1);
1443 printf (" </tr>\n");
1444 #else
1445 printh ("<INPUT TYPE=HIDDEN NAME=sql4 VALUE=\"%H\">\n", checked1);
1446 #endif
1447
1448 /* get database name */
1449 strcpy(checked1, "");
1450 if(usesql == 1 && sqlfileok == 1) {
1451 strncpy(TmpBuf3, &TmpBuf1[++i], 1);
1452 if((strstr(TmpBuf3, ":")) == NULL) {
1453 for(j=0;TmpBuf1[i]!=':'&&TmpBuf1[i]!='\0';++j,++i) checked1[j] = TmpBuf1[i];
1454 checked1[j] = '\0';
1455 }
1456 }
1457 #ifdef ENABLE_MYSQL
1458 printf (" <tr>\n");
1459 printf (" <td ALIGN=RIGHT>%s:\n", html_text[58]);
1460 printf (" </td><td>\n");
1461 printh (" <input type=text name=sql5 value=\"%H\"></td>\n", checked1);
1462 #else
1463 printh ("<INPUT TYPE=HIDDEN NAME=sql5 VALUE=\"%H\">\n", checked1);
1464 #endif
1465
1466 /* get table name */
1467 strcpy(checked1, "ezmlm");
1468 if(usesql == 1 && sqlfileok == 1) {
1469 ++i;
1470 if(strlen(TmpBuf1) != i) {
1471 for(j=0;TmpBuf1[i]!=':'&&TmpBuf1[i]!='\0';++j,++i) checked1[j] = TmpBuf1[i];
1472 checked1[j] = '\0';
1473 }
1474 }
1475 #ifdef ENABLE_MYSQL
1476 printf (" <td ALIGN=RIGHT>%s:\n", html_text[59]);
1477 printf (" </td><td>\n");
1478 printh (" <input type=text name=\"sql6\" value=\"%H\"></td>\n", checked1);
1479 printf (" </tr>\n");
1480 printf (" </table>\n");
1481 #else
1482 printh ("<INPUT TYPE=HIDDEN NAME=sql6 VALUE=\"%H\">\n", checked1);
1483 #endif
1484
1485 }
1486
get_mailinglist_prefix(char * prefix)1487 int get_mailinglist_prefix(char* prefix)
1488 {
1489 char buffer[MAX_BUFF];
1490 char *b, *p;
1491 FILE* file;
1492
1493 sprintf(buffer, "%s/%s/prefix", RealDir, ActionUser);
1494 file=fopen(buffer , "r");
1495
1496 if (file)
1497 {
1498 fgets(buffer, sizeof(buffer), file);
1499 fclose(file);
1500
1501 b = buffer;
1502 p = prefix;
1503 while (*b == '[') b++;
1504 while ((*b != ']') && (*b != '\n') && (*b != '\0')) *p++ = *b++;
1505 *p++ = '\0';
1506 }
1507 else
1508 {
1509 return 1;
1510 }
1511 return 0;
1512 }
1513
1514