13 #define FATAL "ezmlm-make: fatal: "
17 strerr_die1x(100,"ezmlm-make: usage: ezmlm-make [ -aApP ] dir dot local host");
21 strerr_die2x(100,FATAL,"dir must start with slash");
25 strerr_die2x(100,FATAL,"newlines not allowed");
29 strerr_die2x(100,FATAL,"quotes not allowed");
33 strerr_die2x(111,FATAL,"out of memory");
43 ch = u; if (!stralloc_append(&key,&ch)) die_nomem(); u >>= 8;
44 ch = u; if (!stralloc_append(&key,&ch)) die_nomem(); u >>= 8;
45 ch = u; if (!stralloc_append(&key,&ch)) die_nomem(); u >>= 8;
46 ch = u; if (!stralloc_append(&key,&ch)) die_nomem();
51 gettimeofday(&tv,(struct timezone *) 0);
60 stralloc dotplus = {0};
61 stralloc dirplus = {0};
63 void dirplusmake(slash)
66 if (!stralloc_copys(&dirplus,dir)) die_nomem();
67 if (!stralloc_cats(&dirplus,slash)) die_nomem();
68 if (!stralloc_0(&dirplus)) die_nomem();
71 void linkdotdir(dash,slash)
75 if (!stralloc_copys(&dotplus,dot)) die_nomem();
76 if (!stralloc_cats(&dotplus,dash)) die_nomem();
77 if (!stralloc_0(&dotplus)) die_nomem();
79 if (symlink(dirplus.s,dotplus.s) == -1)
80 strerr_die4sys(111,FATAL,"unable to create ",dotplus.s,": ");
88 if (mkdir(dirplus.s,0755) == -1)
89 strerr_die4sys(111,FATAL,"unable to create ",dirplus.s,": ");
94 char ssbuf[SUBSTDIO_OUTSIZE];
102 fd = open_trunc(dirplus.s);
104 strerr_die4sys(111,FATAL,"unable to create ",dirplus.s,": ");
106 substdio_fdbuf(&ss,write,fd,ssbuf,sizeof(ssbuf));
113 if (substdio_bput(&ss,buf,len) == -1)
114 strerr_die4sys(111,FATAL,"unable to write to ",dirplus.s,": ");
119 if (substdio_bputs(&ss,buf) == -1)
120 strerr_die4sys(111,FATAL,"unable to write to ",dirplus.s,": ");
125 if (substdio_flush(&ss) == -1)
126 strerr_die4sys(111,FATAL,"unable to write to ",dirplus.s,": ");
127 if (fsync(ss.fd) == -1)
128 strerr_die4sys(111,FATAL,"unable to write to ",dirplus.s,": ");
129 if (close(ss.fd) == -1) /* NFS stupidity */
130 strerr_die4sys(111,FATAL,"unable to write to ",dirplus.s,": ");
146 gettimeofday(&tv,(struct timezone *) 0);
154 while ((opt = getopt(argc,argv,"aApP")) != opteof)
156 case 'a': flagarchived = 1; break;
157 case 'A': flagarchived = 0; break;
158 case 'p': flagpublic = 1; break;
159 case 'P': flagpublic = 0; break;
165 if (!(dir = *argv++)) die_usage();
166 if (!(dot = *argv++)) die_usage();
167 if (!(local = *argv++)) die_usage();
168 if (!(host = *argv++)) die_usage();
170 if (dir[0] != '/') die_relative();
171 if (dir[str_chr(dir,'\'')]) die_quote();
172 if (dir[str_chr(dir,'\n')]) die_newline();
173 if (local[str_chr(local,'\n')]) die_newline();
174 if (host[str_chr(host,'\n')]) die_newline();
178 dcreate("/subscribers");
183 linkdotdir("-owner","/owner");
184 linkdotdir("-default","/manager");
185 linkdotdir("-return-default","/bouncer");
186 linkdotdir("","/editor");
188 fopen("/lock"); fclose();
189 fopen("/lockbounce"); fclose();
191 fopen("/public"); fclose();
194 fopen("/archived"); fclose();
196 fopen("/num"); fputs("0\n"); fclose();
197 fopen("/inhost"); fputs(host); fputs("\n"); fclose();
198 fopen("/outhost"); fputs(host); fputs("\n"); fclose();
199 fopen("/inlocal"); fputs(local); fputs("\n"); fclose();
200 fopen("/outlocal"); fputs(local); fputs("\n"); fclose();
202 fopen("/mailinglist");
204 fputs(local); fputs("-help@"); fputs(host); fputs("; run by ezmlm\n");
208 fputs(dir); fputs("/Mailbox\n");
209 fputs("|"); fputs(auto_bin); fputs("/ezmlm-warn '"); fputs(dir);
210 fputs("' || exit 0\n");
214 fputs("|"); fputs(auto_bin); fputs("/ezmlm-manage '"); fputs(dir); fputs("'\n");
215 fputs("|"); fputs(auto_bin); fputs("/ezmlm-warn '"); fputs(dir);
216 fputs("' || exit 0\n");
220 fputs("|"); fputs(auto_bin); fputs("/ezmlm-reject\n");
221 fputs("|"); fputs(auto_bin); fputs("/ezmlm-send '"); fputs(dir); fputs("'\n");
222 fputs("|"); fputs(auto_bin); fputs("/ezmlm-warn '"); fputs(dir);
223 fputs("' || exit 0\n");
227 fputs("|"); fputs(auto_bin); fputs("/ezmlm-warn '"); fputs(dir);
228 fputs("' || exit 0\n");
229 fputs("|"); fputs(auto_bin); fputs("/ezmlm-weed\n");
230 fputs("|"); fputs(auto_bin); fputs("/ezmlm-return '"); fputs(dir); fputs("'\n");
233 fopen("/headerremove");
246 fputs("Hi! This is the ezmlm program. I'm managing the\n");
247 fputs(local); fputs("@"); fputs(host); fputs(" mailing list.\n\n");
250 fopen("/text/bottom");
251 fputs("\n--- Here are the ezmlm command addresses.\n\
253 I can handle administrative requests automatically.\n\
254 Just send an empty note to any of these addresses:\n\n <");
255 fputs(local); fputs("-subscribe@"); fputs(host); fputs(">:\n");
256 fputs(" Receive future messages sent to the mailing list.\n\n <");
257 fputs(local); fputs("-unsubscribe@"); fputs(host); fputs(">:\n");
258 fputs(" Stop receiving messages.\n\n <");
259 fputs(local); fputs("-get.12345@"); fputs(host); fputs(">:\n");
260 fputs(" Retrieve a copy of message 12345 from the archive.\n\
262 DO NOT SEND ADMINISTRATIVE REQUESTS TO THE MAILING LIST!\n\
263 If you do, I won't see them, and subscribers will yell at you.\n\
265 To specify God@heaven.af.mil as your subscription address, send mail\n\
267 fputs(local); fputs("-subscribe-God=heaven.af.mil@"); fputs(host);
269 I'll send a confirmation message to that address; when you receive that\n\
270 message, simply reply to it to complete your subscription.\n\
272 fputs("\n--- Below this line is a copy of the request I received.\n\n");
275 fopen("/text/sub-confirm");
276 fputs("To confirm that you would like\n\
280 added to this mailing list, please send an empty reply to this address:\n\
284 Your mailer should have a Reply feature that uses this address automatically.\n\
286 This confirmation serves two purposes. First, it verifies that I am able\n\
287 to get mail through to you. Second, it protects you in case someone\n\
288 forges a subscription request in your name.\n\
292 fopen("/text/unsub-confirm");
293 fputs("To confirm that you would like\n\
297 removed from this mailing list, please send an empty reply to this address:\n\
301 Your mailer should have a Reply feature that uses this address automatically.\n\
303 I haven't checked whether your address is currently on the mailing list.\n\
304 To see what address you used to subscribe, look at the messages you are\n\
305 receiving from the mailing list. Each message has your address hidden\n\
306 inside its return path; for example, God@heaven.af.mil receives messages\n\
307 with return path ...-God=heaven.af.mil.\n\
311 fopen("/text/sub-ok");
312 fputs("Acknowledgment: I have added the address\n\
316 to this mailing list.\n\
320 fopen("/text/unsub-ok");
321 fputs("Acknowledgment: I have removed the address\n\
325 from this mailing list.\n\
329 fopen("/text/sub-nop");
330 fputs("Acknowledgment: The address\n\
334 is on this mailing list.\n\
338 fopen("/text/unsub-nop");
339 fputs("Acknowledgment: The address\n\
343 is not on this mailing list.\n\
347 fopen("/text/sub-bad");
348 fputs("Oops, that confirmation number appears to be invalid.\n\
350 The most common reason for invalid numbers is expiration. I have to\n\
351 receive confirmation of each request within ten days.\n\
353 I've set up a new confirmation number. To confirm that you would like\n\
357 added to this mailing list, please send an empty reply to this address:\n\
361 Sorry for the trouble.\n\
365 fopen("/text/unsub-bad");
366 fputs("Oops, that confirmation number appears to be invalid.\n\
368 The most common reason for invalid numbers is expiration. I have to\n\
369 receive confirmation of each request within ten days.\n\
371 I've set up a new confirmation number. To confirm that you would like\n\
375 removed from this mailing list, please send an empty reply to this address:\n\
379 Sorry for the trouble.\n\
383 fopen("/text/get-bad");
384 fputs("Sorry, I don't see that message.\n\n");
387 fopen("/text/bounce-bottom");
389 --- Below this line is a copy of the bounce message I received.\n\n");
392 fopen("/text/bounce-warn");
394 Messages to you seem to have been bouncing. I've attached a copy of\n\
395 the first bounce message I received.\n\
397 If this message bounces too, I will send you a probe. If the probe bounces,\n\
398 I will remove your address from the mailing list, without further notice.\n\
402 fopen("/text/bounce-probe");
404 Messages to you seem to have been bouncing. I sent you a warning\n\
405 message, but it bounced. I've attached a copy of the bounce message.\n\
407 This is a probe to check whether your address is reachable. If this\n\
408 probe bounces, I will remove your address from the mailing list, without\n\
413 fopen("/text/bounce-num");
415 I've kept a list of which messages bounced from your address. Copies of\n\
416 these messages may be in the archive. To get message 12345 from the\n\
417 archive, send an empty note to ");
418 fputs(local); fputs("-get.12345@"); fputs(host); fputs(".\n\
419 Here are the message numbers:\n\
425 This is a generic help message. The message I received wasn't sent to\n\
426 any of my command addresses.\n\