1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 
5 #ifndef WIN32
6 #include <unistd.h>
7 #else
8 #include <winsock2.h>
9 #endif
10 
11 #include "toolbox.h"
12 
qmail_dot_file(const char * list,const char * suffix,const char * flags,const char * siteconfig)13 void qmail_dot_file(const char *list, const char *suffix, const char *flags,
14                     const char *siteconfig)
15 {
16    char tempbuf[BIG_BUF];
17    char buf[BIG_BUF];
18    FILE *outfile;
19 
20    LMAPI->buffer_printf(buf, sizeof(buf) - 1, "qmail-aliases/.qmail-%s%s",
21                         list, suffix);
22    LMAPI->listdir_file(tempbuf, list, buf);
23 
24    if ((outfile = LMAPI->open_file(tempbuf,"w")) == NULL) {
25       fprintf(stderr,"ERROR creating %s\n",tempbuf);
26       return;
27    }
28 
29    LMAPI->write_file(outfile,"|%s/%s %s%s %s\n",
30      LMAPI->get_string("listserver-bin-dir"), SERVICE_NAME_LC,
31      siteconfig, flags, list);
32 
33    LMAPI->close_file(outfile);
34 }
35 
make_list_aliases(const char * listname,const char * siteconfig,const char * hostname)36 void make_list_aliases(const char *listname, const char *siteconfig, const char *hostname)
37 {
38    char tempbuf[BIG_BUF];
39 
40    if (LMAPI->get_bool("newlist-procmail")) {
41       printf("\n# Procmail Recipes for '%s' mailing list.\n", listname);
42 
43       printf(":0\n* ^To: %s@%s\n|%s/%s %s-s %s\n",
44               listname, hostname, LMAPI->get_string("listserver-bin-dir"),
45               SERVICE_NAME_LC, siteconfig, listname);
46 
47       printf(":0\n* ^To: %s-request@%s\n|%s/%s %s-r %s\n",
48               listname, hostname, LMAPI->get_string("listserver-bin-dir"),
49               SERVICE_NAME_LC, siteconfig, listname);
50 
51       printf(":0\n* ^To: %s-repost@%s\n|%s/%s %s-a %s\n",
52               listname, hostname, LMAPI->get_string("listserver-bin-dir"),
53               SERVICE_NAME_LC, siteconfig, listname);
54 
55       printf(":0\n* ^To: %s-admins@%s\n|%s/%s %s-admins %s\n",
56               listname, hostname, LMAPI->get_string("listserver-bin-dir"),
57               SERVICE_NAME_LC, siteconfig, listname);
58 
59       printf(":0\n* ^To: %s-moderators@%s\n|%s/%s %s-moderators %s\n",
60               listname, hostname, LMAPI->get_string("listserver-bin-dir"),
61               SERVICE_NAME_LC, siteconfig, listname);
62 
63       printf(":0\n* ^To: %s-bounce@%s\n|%s/%s %s-bounce %s\n\n",
64               listname, hostname, LMAPI->get_string("listserver-bin-dir"),
65               SERVICE_NAME_LC, siteconfig, listname);
66 
67       printf("\n# Fetchmail skeleton for '%s' mailing list (replace pop and pwd with server and password.\n", listname);
68       printf("poll pop proto pop3 user \"%s@%s\" password \"pwd\" \n", listname, hostname);
69       printf("poll pop proto pop3 user \"%s-request@%s\" password \"pwd\" \n", listname, hostname);
70       printf("poll pop proto pop3 user \"%s-repost@%s\" password \"pwd\" \n", listname, hostname);
71       printf("poll pop proto pop3 user \"%s-admins@%s\" password \"pwd\" \n", listname, hostname);
72       printf("poll pop proto pop3 user \"%s-moderators@%s\" password \"pwd\" \n", listname, hostname);
73       printf("poll pop proto pop3 user \"%s-bounce@%s\" password \"pwd\" \n", listname, hostname);
74 
75    } else if (!LMAPI->get_bool("newlist-qmail")) {
76      const char *vhpref;
77 
78      printf("\n# Aliases for '%s' mailing list.\n", listname);
79 
80      vhpref = LMAPI->get_string("vhost-alias-prefix");
81 
82      printf("%s%s: \"|%s/%s %s-s %s\"\n",
83        vhpref ? vhpref : "",
84        listname, LMAPI->get_string("listserver-bin-dir"),
85        SERVICE_NAME_LC, siteconfig, listname);
86 
87      printf("%s%s-request: \"|%s/%s %s-r %s\"\n",
88        vhpref ? vhpref : "",
89        listname, LMAPI->get_string("listserver-bin-dir"),
90        SERVICE_NAME_LC, siteconfig, listname);
91 
92      printf("%s%s-repost: \"|%s/%s %s-a %s\"\n",
93        vhpref ? vhpref : "",
94        listname, LMAPI->get_string("listserver-bin-dir"),
95        SERVICE_NAME_LC, siteconfig, listname);
96 
97      printf("%s%s-admins: \"|%s/%s %s-admins %s\"\n",
98        vhpref ? vhpref : "",
99        listname, LMAPI->get_string("listserver-bin-dir"),
100        SERVICE_NAME_LC, siteconfig, listname);
101 
102      printf("%s%s-moderators: \"|%s/%s %s-moderators %s\"\n",
103        vhpref ? vhpref : "",
104        listname, LMAPI->get_string("listserver-bin-dir"),
105        SERVICE_NAME_LC, siteconfig, listname);
106 
107      printf("%s%s-bounce: \"|%s/%s %s-bounce %s\"\n",
108        vhpref ? vhpref : "",
109        listname, LMAPI->get_string("listserver-bin-dir"),
110        SERVICE_NAME_LC, siteconfig, listname);
111    } else {
112      fprintf(stderr,"Creating dot-qmail aliases...");
113 
114      LMAPI->listdir_file(tempbuf, listname, "qmail-aliases/dummyfile");
115      LMAPI->mkdirs(tempbuf);
116 
117      qmail_dot_file(listname,"","-s",siteconfig);
118      qmail_dot_file(listname,"-request","-r",siteconfig);
119      qmail_dot_file(listname,"-repost","-a",siteconfig);
120      qmail_dot_file(listname,"-admins","-admins",siteconfig);
121      qmail_dot_file(listname,"-bounce","-bounce",siteconfig);
122      qmail_dot_file(listname,"-moderators","-moderators",siteconfig);
123 
124      fprintf(stderr,"done.\n");
125      fprintf(stderr,"qmail dot-aliases are in the 'qmail-aliases' directory under the list.\nCopy them to your global aliases dir.\n");
126    }
127 }
128 
newlist(const char * listname)129 void newlist(const char *listname)
130 {
131    char tempbuf[BIG_BUF];
132    char hostname[BIG_BUF];
133    char admin[BIG_BUF];
134    char *siteconfig;
135    struct list_user u;
136    FILE *dummyfile;
137 
138    if (LMAPI->get_var("hostname")) {
139       LMAPI->buffer_printf(hostname, sizeof(hostname) - 1, "%s",
140         LMAPI->get_string("hostname"));
141    } else {
142       memset(hostname, 0, sizeof(hostname));
143       LMAPI->build_hostname(&hostname[0],sizeof(hostname));
144    }
145 
146    siteconfig = NULL;
147 
148    if (!LMAPI->get_var("listserver-bin-dir")) {
149       LMAPI->set_var("listserver-bin-dir",LMAPI->get_string("listserver-root"),
150                      VAR_GLOBAL);
151    }
152 
153    if (LMAPI->get_var("site-config-file")) {
154       char sitebuf[BIG_BUF];
155       char *ptr;
156 
157       stringcpy(tempbuf,LMAPI->get_string("site-config-file"));
158       ptr = &tempbuf[0] + strlen(LMAPI->get_string("listserver-conf")) + 1;
159 
160       LMAPI->buffer_printf(sitebuf, sizeof(sitebuf) - 1, "-c %s ", ptr);
161       siteconfig = strdup(sitebuf);
162    } else {
163       siteconfig = strdup("");
164    }
165 
166    if (!LMAPI->get_var("newlist-admin")) {
167       fprintf(stderr,"List admin e-mail: ");
168       LMAPI->read_file(admin, sizeof(admin), stdin);
169    } else {
170       LMAPI->buffer_printf(admin, sizeof(admin) - 1, "%s", LMAPI->get_string("newlist-admin"));
171    }
172 
173    if (admin[strlen(admin) - 1] == '\n')
174       admin[strlen(admin) - 1] = 0;
175 
176    if (!strchr(admin,'@')) {
177       if ((strlen(admin) + strlen(hostname) + 1) < (sizeof(admin) - 1)) {
178         stringcat(admin, "@");
179         stringcat(admin, hostname);
180       } else {
181         fprintf(stderr,"Invalid administrator address!\n");
182         return;
183       }
184    }
185 
186    LMAPI->set_var("list-owner", admin, VAR_LIST);
187 
188    LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "%s-bounce@%s",
189      listname, hostname);
190    LMAPI->set_var("send-as", tempbuf, VAR_LIST);
191 
192    LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "%s@%s",
193      listname, hostname);
194    LMAPI->set_var("reply-to", tempbuf, VAR_LIST);
195 
196    LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "%s-admins@%s",
197      listname, hostname);
198    LMAPI->set_var("administrivia-address", tempbuf, VAR_LIST);
199 
200    LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "%s-moderators@%s",
201      listname, hostname);
202    LMAPI->set_var("moderator", tempbuf, VAR_LIST);
203 
204    LMAPI->buffer_printf(tempbuf, sizeof(tempbuf) - 1, "[%s]",
205      listname);
206    LMAPI->set_var("subject-tag", tempbuf, VAR_LIST);
207 
208    LMAPI->listdir_file(tempbuf, listname, "dummyfile");
209    LMAPI->mkdirs(tempbuf);
210    LMAPI->listdir_file(tempbuf, listname, "text/dummyfile");
211    LMAPI->mkdirs(tempbuf);
212 
213    fprintf(stderr," Writing config file...");
214 
215    LMAPI->listdir_file(tempbuf, listname, "config");
216    LMAPI->write_configfile(tempbuf,VAR_LIST,
217      ":Basic Configuration:CGI:Debugging:Digest:Bouncer:");
218 
219    fprintf(stderr,"done.\n");
220 
221    fprintf(stderr," Creating default user file...");
222 
223    /* Dummy up a user file - eventually we'll want a 'user_file_create'
224       function that takes a list, and then it will be able to work with
225       things other than a textfile for users, like a SQL database. */
226    LMAPI->listdir_file(tempbuf, listname, "users");
227    dummyfile = LMAPI->open_file(tempbuf,"w");
228    LMAPI->close_file(dummyfile);
229 
230    strncpy(u.address,admin,BIG_BUF - 1);
231    LMAPI->buffer_printf(u.flags,HUGE_BUF - 1,
232      "|ADMIN|SUPERADMIN|MODERATOR|CCERRORS|REPORTS|ECHOPOST|");
233    LMAPI->user_write(tempbuf,&u);
234 
235    fprintf(stderr,"done.\n");
236 
237    fprintf(stderr,"Sending aliases for sendmail/Exim/Postfix/Zmailer to stdout.\n");
238    make_list_aliases(listname, siteconfig, hostname);
239 
240    free(siteconfig);
241 
242    LMAPI->do_hooks("NEWLIST");
243 }
244 
CMDARG_HANDLER(cmdarg_qmail)245 CMDARG_HANDLER(cmdarg_qmail)
246 {
247    LMAPI->set_var("newlist-qmail","yes",VAR_GLOBAL);
248    return CMDARG_OK;
249 }
250 
CMDARG_HANDLER(cmdarg_procmail)251 CMDARG_HANDLER(cmdarg_procmail)
252 {
253 	   LMAPI->set_var("newlist-procmail","yes",VAR_GLOBAL);
254 	      return CMDARG_OK;
255 }
256 
MODE_HANDLER(mode_newlist)257 MODE_HANDLER(mode_newlist)
258 {
259    fprintf(stderr,"Creating new list '%s'...\n", LMAPI->get_string("list"));
260    newlist(LMAPI->get_string("list"));
261    return MODE_OK;
262 }
263 
MODE_HANDLER(mode_freshen)264 MODE_HANDLER(mode_freshen)
265 {
266    char tempbuf[BIG_BUF];
267 
268    fprintf(stderr,"Freshening list '%s'...", LMAPI->get_string("list"));
269    LMAPI->listdir_file(tempbuf, LMAPI->get_string("list"), "config");
270    LMAPI->write_configfile(tempbuf,VAR_LIST,
271                            ":Basic Configuration:CGI:Debugging:Digest:Bouncer:");
272    fprintf(stderr,"done.\n");
273 
274    return MODE_OK;
275 }
276 
MODE_HANDLER(mode_buildaliases)277 MODE_HANDLER(mode_buildaliases)
278 {
279    char tempbuf[BIG_BUF];
280    int status;
281    char *siteconfig;
282 
283    if (LMAPI->get_var("site-config-file")) {
284       char sitebuf[BIG_BUF];
285       char *ptr;
286 
287       stringcpy(tempbuf,LMAPI->get_string("site-config-file"));
288       ptr = &tempbuf[0] + strlen(LMAPI->get_string("listserver-conf")) + 1;
289 
290       LMAPI->buffer_printf(sitebuf, sizeof(sitebuf) - 1, "-c %s ", ptr);
291       siteconfig = strdup(sitebuf);
292    } else {
293       siteconfig = strdup("");
294    }
295 
296    fprintf(stderr,"Rebuilding aliases for all lists: ");
297 
298    status = LMAPI->walk_lists(&tempbuf[0]);
299    while (status) {
300       if (LMAPI->list_valid(tempbuf)) {
301          fprintf(stderr,"%s ",tempbuf);
302          make_list_aliases(tempbuf,siteconfig,"");
303       }
304       printf("\n");
305       status = LMAPI->next_lists(&tempbuf[0]);
306    }
307 
308    fprintf(stderr,"\n");
309 
310    free(siteconfig);
311 
312    return MODE_OK;
313 }
314 
CMDARG_HANDLER(cmdarg_buildaliases)315 CMDARG_HANDLER(cmdarg_buildaliases)
316 {
317    LMAPI->set_var("mode","buildaliases",VAR_GLOBAL);
318    LMAPI->set_var("fakequeue","yes",VAR_GLOBAL);
319 
320    return CMDARG_OK;
321 }
322 
CMDARG_HANDLER(cmdarg_newlist)323 CMDARG_HANDLER(cmdarg_newlist)
324 {
325    if(!argv[0]) {
326        fprintf(stderr,"Switch -newlist requires a list as a parameter.\n");
327        return CMDARG_ERR;
328    } else {
329        char *listname;
330        char *tmp;
331 
332        listname = LMAPI->lowerstr(argv[0]);
333 
334 	   if (listname[0] == '/' || strstr(listname, "../") != NULL) {
335 		   fprintf(stderr, "List '%s' could not be created because of invalid characters in the list name.", argv[0]);
336 		   return CMDARG_ERR;
337 	   }
338 
339        tmp = LMAPI->list_directory(listname);
340        if (LMAPI->exists_file(tmp)) {
341            fprintf(stderr,"List '%s' cannot be created because of a filename conflict.\n", argv[0]);
342            free(tmp);
343            return CMDARG_ERR;
344        }
345        LMAPI->set_var("list", listname, VAR_GLOBAL);
346        LMAPI->set_var("mode", "newlist", VAR_GLOBAL);
347        LMAPI->set_var("fakequeue", "yes", VAR_GLOBAL);
348        free(listname);
349        free(tmp);
350        return CMDARG_OK;
351    }
352 }
353 
CMDARG_HANDLER(cmdarg_admin)354 CMDARG_HANDLER(cmdarg_admin)
355 {
356    if(!argv[0]) {
357        fprintf(stderr,"Switch -admin requires an address as a parameter.\n");
358    }
359    else if (!strchr(argv[0],'@')) {
360        fprintf(stderr,"Switch -admin requires a valid address as a parameter.\n");
361        return CMDARG_ERR;
362    }
363 
364    LMAPI->set_var("newlist-admin", argv[0], VAR_GLOBAL);
365 
366    return CMDARG_OK;
367 }
368 
CMDARG_HANDLER(cmdarg_freshen)369 CMDARG_HANDLER(cmdarg_freshen)
370 {
371    if(!argv[0]) {
372        fprintf(stderr,"Switch -freshen requires a list as a parameter.\n");
373        return CMDARG_ERR;
374    } else {
375        char *listname;
376 
377        listname = LMAPI->lowerstr(argv[0]);
378 
379        if (!LMAPI->list_valid(listname)) {
380            fprintf(stderr,"List '%s' not found.\n", argv[0]);
381            free(listname);
382            return CMDARG_ERR;
383        }
384        LMAPI->set_var("list", listname, VAR_GLOBAL);
385        LMAPI->set_var("mode", "freshen", VAR_GLOBAL);
386        LMAPI->set_var("fakequeue", "yes", VAR_GLOBAL);
387        free(listname);
388        return CMDARG_OK;
389    }
390 }
391 
392