Mercurial > hg > Applications > mh
comparison uip/post.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children | 441a2190cfae |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
1 /* post.c - enter messages into the transport system */ | |
2 #ifndef lint | |
3 static char ident[] = "@(#)$Id$"; | |
4 #endif /* lint */ | |
5 | |
6 #include "../h/mh.h" | |
7 #include "../h/addrsbr.h" | |
8 #include "../h/aliasbr.h" | |
9 #include "../h/dropsbr.h" | |
10 #include "../zotnet/tws.h" | |
11 #ifndef MMDFMTS | |
12 #include <ctype.h> | |
13 #include <errno.h> | |
14 #include <setjmp.h> | |
15 #include <stdio.h> | |
16 #include <sys/types.h> | |
17 #else /* MMDFMTS */ | |
18 #include "../mts/mmdf/util.h" | |
19 #include "../mts/mmdf/mmdf.h" | |
20 #endif /* MMDFMTS */ | |
21 #include "../zotnet/mts.h" | |
22 #ifdef MHMTS | |
23 #ifndef V7 | |
24 #include <sys/ioctl.h> | |
25 #endif /* not V7 */ | |
26 #include <sys/stat.h> | |
27 #endif /* MHMTS */ | |
28 #ifdef SENDMTS | |
29 #include "../mts/sendmail/smail.h" | |
30 #undef MF | |
31 #endif /* SENDMTS */ | |
32 #include <signal.h> | |
33 #ifdef MIME | |
34 #include "../h/mhn.h" | |
35 #endif /* MIME */ | |
36 #ifdef LOCALE | |
37 #include <locale.h> | |
38 #endif | |
39 | |
40 | |
41 #ifndef MMDFMTS | |
42 #define uptolow(c) ((isalpha(c) && isupper (c)) ? tolower (c) : (c)) | |
43 #endif /* not MMDFMTS */ | |
44 | |
45 #define FCCS 10 /* max number of fccs allowed */ | |
46 | |
47 /* */ | |
48 | |
49 #ifndef MIME | |
50 #define MIMEminc(a) (a) | |
51 #else | |
52 #define MIMEminc(a) 0 | |
53 #endif | |
54 | |
55 #ifndef TMA | |
56 #define TMAminc(a) (a) | |
57 #else /* TMA */ | |
58 #define TMAminc(a) 0 | |
59 #endif /* TMA */ | |
60 | |
61 static struct swit switches[] = { | |
62 #define ALIASW 0 | |
63 "alias aliasfile", 0, | |
64 | |
65 #define CHKSW 1 | |
66 "check", -5, /* interface from whom */ | |
67 #define NCHKSW 2 | |
68 "nocheck", -7, /* interface from whom */ | |
69 | |
70 #define DEBUGSW 3 | |
71 "debug", -5, | |
72 | |
73 #define DISTSW 4 | |
74 "dist", -4, /* interface from dist */ | |
75 | |
76 #define ENCRSW 5 | |
77 "encrypt", TMAminc (-7), | |
78 #define NENCRSW 6 | |
79 "noencrypt", TMAminc (-9), | |
80 | |
81 #define FILTSW 7 | |
82 "filter filterfile", 0, | |
83 #define NFILTSW 8 | |
84 "nofilter", 0, | |
85 | |
86 #define FRMTSW 9 | |
87 "format", 0, | |
88 #define NFRMTSW 10 | |
89 "noformat", 0, | |
90 | |
91 #define LIBSW 11 /* interface from send, whom */ | |
92 "library directory", -7, | |
93 | |
94 #define MIMESW 12 | |
95 "mime", MIMEminc(-4), | |
96 #define NMIMESW 13 | |
97 "nomime", MIMEminc(-6), | |
98 | |
99 #define MSGDSW 14 | |
100 "msgid", 0, | |
101 #define NMSGDSW 15 | |
102 "nomsgid", 0, | |
103 | |
104 #define VERBSW 16 | |
105 "verbose", 0, | |
106 #define NVERBSW 17 | |
107 "noverbose", 0, | |
108 | |
109 #define WATCSW 18 | |
110 "watch", 0, | |
111 #define NWATCSW 19 | |
112 "nowatch", 0, | |
113 | |
114 #define WHOMSW 20 /* interface from whom */ | |
115 "whom", -4, | |
116 | |
117 #define WIDTHSW 21 | |
118 "width columns", 0, | |
119 | |
120 #define HELPSW 22 | |
121 "help", 4, | |
122 | |
123 #define MAILSW 23 | |
124 "mail", -4, | |
125 #define SAMLSW 24 | |
126 "saml", -4, | |
127 #define SENDSW 25 | |
128 "send", -4, | |
129 #define SOMLSW 26 | |
130 "soml", -4, | |
131 | |
132 #define ANNOSW 27 /* interface from send */ | |
133 "idanno number", -6, | |
134 | |
135 #define DLVRSW 28 | |
136 "deliver address-list", -7, | |
137 | |
138 #define CLIESW 29 | |
139 "client host", -6, | |
140 #define SERVSW 30 | |
141 "server host", -6, | |
142 #define SNOOPSW 31 | |
143 "snoop", -5, | |
144 | |
145 #define FILLSW 32 | |
146 "fill-in file", -7, | |
147 #define FILLUSW 33 | |
148 "fill-up", -7, | |
149 #define PARTSW 34 | |
150 "partno", -6, | |
151 | |
152 #define QUEUESW 35 | |
153 "queued", -6, | |
154 | |
155 #define RECORSW 36 | |
156 "record program", -6, | |
157 #define NRECOSW 37 | |
158 "norecord", -8, | |
159 | |
160 #ifdef MIME_HEADERS | |
161 #define HENCDSW 38 | |
162 "hencode", 0, | |
163 #define NHENCDSW 39 | |
164 "nohencode", 0, | |
165 #endif /* MIME_HEADERS */ | |
166 | |
167 #ifdef MH_PLUS | |
168 #define USERSW 40 | |
169 "user", -4, | |
170 #define FROMSW 41 | |
171 "from", -4, | |
172 #endif /* MH_PLUS */ | |
173 | |
174 NULL, 0 | |
175 }; | |
176 | |
177 /* */ | |
178 | |
179 struct headers { | |
180 char *value; | |
181 | |
182 unsigned int flags; | |
183 #define HNOP 0x0000 /* just used to keep .set around */ | |
184 #define HBAD 0x0001 /* bad header - don't let it through */ | |
185 #define HADR 0x0002 /* header has an address field */ | |
186 #define HSUB 0x0004 /* Subject: header */ | |
187 #define HTRY 0x0008 /* try to send to addrs on header */ | |
188 #define HBCC 0x0010 /* don't output this header */ | |
189 #define HMNG 0x0020 /* munge this header */ | |
190 #define HNGR 0x0040 /* no groups allowed in this header */ | |
191 #define HFCC 0x0080 /* FCC: type header */ | |
192 #define HNIL 0x0100 /* okay for this header not to have addrs */ | |
193 #define HIGN 0x0200 /* ignore this header */ | |
194 #define HDCC 0x0400 /* another undocumented feature */ | |
195 | |
196 unsigned int set; | |
197 #define MFRM 0x0001 /* we've seen a From: */ | |
198 #define MDAT 0x0002 /* we've seen a Date: */ | |
199 #define MRFM 0x0004 /* we've seen a Resent-From: */ | |
200 #define MVIS 0x0008 /* we've seen sighted addrs */ | |
201 #define MINV 0x0010 /* we've seen blind addrs */ | |
202 #define MRPY 0x0020 /* we've seen a Reply-to: */ | |
203 }; | |
204 | |
205 /* */ | |
206 | |
207 static struct headers NHeaders[] = { | |
208 "Return-Path", HBAD, 0, | |
209 "Received", HBAD, 0, | |
210 "Reply-To", HADR | HNGR, MRPY, | |
211 "From", HADR | HNGR, MFRM, | |
212 "Sender", HADR | HBAD, 0, | |
213 "Date", HBAD, 0, | |
214 "Subject", HSUB, 0, | |
215 "To", HADR | HTRY, MVIS, | |
216 "cc", HADR | HTRY, MVIS, | |
217 "Bcc", HADR | HTRY | HBCC | HNIL, MINV, | |
218 "Dcc", HADR | HTRY | HDCC | HNIL, MVIS, /* sorta cc & bcc combined */ | |
219 "Message-ID", HBAD, 0, | |
220 "Fcc", HFCC, 0, | |
221 | |
222 NULL | |
223 }; | |
224 | |
225 static struct headers RHeaders[] = { | |
226 "Resent-Reply-To", HADR | HNGR, MRPY, | |
227 "Resent-From", HADR | HNGR, MRFM, | |
228 "Resent-Sender", HADR | HBAD, 0, | |
229 "Resent-Date", HBAD, 0, | |
230 "Resent-Subject", HSUB, 0, | |
231 "Resent-To", HADR | HTRY, MVIS, | |
232 "Resent-cc", HADR | HTRY, MVIS, | |
233 "Resent-Bcc", HADR | HTRY | HBCC, MINV, | |
234 "Resent-Message-ID", HBAD, 0, | |
235 "Resent-Fcc", HFCC, 0, | |
236 "Reply-To", HADR, MRPY, | |
237 "From", HADR | HNGR, MFRM, | |
238 #ifdef MMDFI | |
239 "Sender", HADR | HMNG | HNGR, 0, | |
240 #else /* not MMFDI */ | |
241 "Sender", HADR | HNGR, 0, | |
242 #endif /* not MMDFI */ | |
243 "Date", HNOP, MDAT, | |
244 "To", HADR | HNIL, 0, | |
245 "cc", HADR | HNIL, 0, | |
246 "Bcc", HADR | HTRY | HBCC | HNIL, 0, | |
247 "Fcc", HIGN, 0, | |
248 | |
249 NULL | |
250 }; | |
251 | |
252 /* */ | |
253 | |
254 | |
255 static short fccind = 0; /* index into fccfold[] */ | |
256 static short outputlinelen = OUTPUTLINELEN; | |
257 | |
258 static int pfd = NOTOK; /* fd to write annotation list to */ | |
259 static int myuid= -1; /* my user id */ | |
260 static int mygid= -1; /* my group id */ | |
261 static int recipients = 0; /* how many people will get a copy */ | |
262 static int unkadr = 0; /* how many of those were unknown */ | |
263 static int badadr = 0; /* number of bad addrs */ | |
264 static int badmsg = 0; /* message has bad semantics */ | |
265 static int verbose = 0; /* spell it out */ | |
266 static int format = 1; /* format addresses */ | |
267 static int mime = 0; /* use MIME-style encapsulations */ | |
268 static int msgid = 0; /* add msgid */ | |
269 static int debug = 0; /* debugging post */ | |
270 static int watch = 0; /* watch the delivery process */ | |
271 static int whomsw = 0; /* we are whom not post */ | |
272 static int checksw = 0; /* whom -check */ | |
273 static int linepos=0; /* putadr()'s position on the line */ | |
274 static int nameoutput=0; /* putadr() has output header name */ | |
275 #ifdef MIME_HEADERS | |
276 static int hencode = -1; /* encode header in RFC-2047 style */ | |
277 #endif /* MIME_HEADERS */ | |
278 | |
279 static unsigned msgflags = 0; /* what we've seen */ | |
280 | |
281 #define NORMAL 0 | |
282 #define RESENT 1 | |
283 static int msgstate = NORMAL; | |
284 | |
285 static time_t tclock = 0L; /* the time we started (more or less) */ | |
286 | |
287 static TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) (); | |
288 | |
289 static char tmpfil[BUFSIZ]; | |
290 static char bccfil[BUFSIZ]; | |
291 | |
292 static char from[BUFSIZ]; /* my network address */ | |
293 static char signature[BUFSIZ]; /* my signature */ | |
294 static char *filter = NULL; /* the filter for BCC'ing */ | |
295 static char *msgfrom = NULL; /* the From: field for Bcc'ing */ | |
296 static char *subject = NULL; /* the subject field for BCC'ing */ | |
297 static char *fccfold[FCCS]; /* foldernames for FCC'ing */ | |
298 | |
299 static struct headers *hdrtab; /* table for the message we're doing */ | |
300 | |
301 static struct mailname localaddrs={NULL}; /* local addrs */ | |
302 static struct mailname netaddrs={NULL}; /* network addrs */ | |
303 static struct mailname uuaddrs={NULL}; /* uucp addrs */ | |
304 static struct mailname tmpaddrs={NULL}; /* temporary queue */ | |
305 | |
306 /* */ | |
307 | |
308 #ifdef MMDFMTS | |
309 static char *submitmode = "m"; /* deliver to mailbox only */ | |
310 static char submitopts[6] = "vl";/* initial options for submit */ | |
311 #endif /* MMDFMTS */ | |
312 | |
313 #ifdef MHMTS | |
314 static char *deliver = NULL; | |
315 | |
316 extern char **environ; | |
317 | |
318 TYPESIG sigser (); | |
319 #endif /* MHMTS */ | |
320 | |
321 #ifdef SENDMTS | |
322 static int smtpmode = S_MAIL; | |
323 static int snoop = 0; | |
324 static char *clientsw = NULL; | |
325 static char *serversw = NULL; | |
326 | |
327 extern struct smtp sm_reply; | |
328 #endif /* SENDMTS */ | |
329 | |
330 #ifdef TMA | |
331 #define post(a,b,c) \ | |
332 if (encryptsw) postcipher ((a), (b), (c)); else postplain ((a), (b), (c)) | |
333 | |
334 #ifndef SENDMTS | |
335 #define tmasnoop 0 | |
336 #else /* SENDMTS */ | |
337 #define tmasnoop snoop | |
338 #endif /* SENDMTS */ | |
339 #endif /* TMA */ | |
340 | |
341 static int encryptsw = 0; /* encrypt it */ | |
342 #ifdef MH_PLUS | |
343 static char *usersw = NULLCP; | |
344 static char *fromsw = NULLCP; | |
345 #endif /* MH_PLUS */ | |
346 | |
347 | |
348 #ifdef BERK | |
349 #undef WP | |
350 #endif | |
351 | |
352 #ifdef MIME | |
353 static char prefix[] = "----- =_aaaaaaaaaa"; | |
354 static int find_prefix(); | |
355 #endif /* MIME */ | |
356 | |
357 static int fill_up = 0; | |
358 static char *fill_in = NULLCP; | |
359 static char *partno = NULLCP; | |
360 | |
361 static int queued = 0; | |
362 | |
363 static char *record = NULLCP; | |
364 | |
365 off_t lseek (); | |
366 time_t time (); | |
367 | |
368 static putfmt(), start_headers(), finish_headers(), putgrp(), pl(); | |
369 static anno(), make_bcc_file(), verify_all_addresses(); | |
370 static chkadr(), do_addresses(), do_text(), do_an_address(), sigon(); | |
371 static sigoff(), p_refile(), fcc(), die(), insert_fcc(), p_record (); | |
372 static int get_header(), putadr(), insert(), annoaux(); | |
373 #ifdef TMA | |
374 static postplain(); | |
375 #else | |
376 static post(); | |
377 #endif /* !TMA */ | |
378 | |
379 /* MAIN */ | |
380 | |
381 /* ARGSUSED */ | |
382 | |
383 main (argc, argv) | |
384 int argc; | |
385 char *argv[]; | |
386 { | |
387 int state, | |
388 compnum; | |
389 char *cp, | |
390 *msg = NULL, | |
391 **argp = argv + 1, | |
392 buf[BUFSIZ], | |
393 name[NAMESZ]; | |
394 FILE *in, | |
395 *out; | |
396 | |
397 #ifdef LOCALE | |
398 setlocale(LC_ALL, ""); | |
399 #endif | |
400 #ifdef JAPAN | |
401 ml_init(); | |
402 #endif /* JAPAN */ | |
403 invo_name = r1bindex (argv[0], '/'); | |
404 m_foil (NULLCP); | |
405 mts_init (invo_name); | |
406 #ifdef MMDFMTS | |
407 #ifdef MMDFII | |
408 mmdf_init (invo_name); | |
409 #endif /* MMDFII */ | |
410 #endif /* MMDFMTS */ | |
411 | |
412 /* */ | |
413 | |
414 while (cp = *argp++) { | |
415 if (*cp == '-') | |
416 switch (smatch (++cp, switches)) { | |
417 case AMBIGSW: | |
418 ambigsw (cp, switches); | |
419 done (1); | |
420 case UNKWNSW: | |
421 adios (NULLCP, "-%s unknown", cp); | |
422 case HELPSW: | |
423 (void) sprintf (buf, "%s [switches] file", invo_name); | |
424 help (buf, switches); | |
425 done (1); | |
426 | |
427 case LIBSW: | |
428 if (!(cp = *argp++) || *cp == '-') | |
429 adios (NULLCP, "missing argument to %s", argp[-2]); | |
430 m_foil (cp); | |
431 continue; | |
432 | |
433 case ALIASW: | |
434 if (!(cp = *argp++) || *cp == '-') | |
435 adios (NULLCP, "missing argument to %s", argp[-2]); | |
436 #ifdef MHMTS | |
437 if (access (libpath (cp), 04) == NOTOK) | |
438 adios (cp, "unable to read"); | |
439 #endif /* MHMTS */ | |
440 if ((state = alias (cp)) != AK_OK) | |
441 adios (NULLCP, "aliasing error in %s - %s", | |
442 cp, akerror (state)); | |
443 continue; | |
444 | |
445 case CHKSW: | |
446 checksw++; | |
447 continue; | |
448 case NCHKSW: | |
449 checksw = 0; | |
450 continue; | |
451 | |
452 case DEBUGSW: | |
453 debug++; | |
454 continue; | |
455 | |
456 case DISTSW: | |
457 msgstate = RESENT; | |
458 continue; | |
459 | |
460 case FILTSW: | |
461 if (!(filter = *argp++) || *filter == '-') | |
462 adios (NULLCP, "missing argument to %s", argp[-2]); | |
463 mime = 0; | |
464 continue; | |
465 case NFILTSW: | |
466 filter = NULL; | |
467 continue; | |
468 | |
469 case FRMTSW: | |
470 format++; | |
471 continue; | |
472 case NFRMTSW: | |
473 format = 0; | |
474 continue; | |
475 | |
476 case MIMESW: | |
477 #ifdef MIME | |
478 mime++; | |
479 filter = 0; | |
480 #endif | |
481 continue; | |
482 case NMIMESW: | |
483 mime = 0; | |
484 continue; | |
485 | |
486 case MSGDSW: | |
487 msgid++; | |
488 continue; | |
489 case NMSGDSW: | |
490 msgid = 0; | |
491 continue; | |
492 | |
493 case VERBSW: | |
494 verbose++; | |
495 continue; | |
496 case NVERBSW: | |
497 verbose = 0; | |
498 continue; | |
499 | |
500 case WATCSW: | |
501 watch++; | |
502 continue; | |
503 case NWATCSW: | |
504 watch = 0; | |
505 continue; | |
506 | |
507 case WHOMSW: | |
508 whomsw++; | |
509 continue; | |
510 | |
511 case WIDTHSW: | |
512 if (!(cp = *argp++) || *cp == '-') | |
513 adios (NULLCP, "missing argument to %s", argp[-2]); | |
514 if ((outputlinelen = atoi (cp)) < 10) | |
515 adios (NULLCP, "impossible width %d", outputlinelen); | |
516 continue; | |
517 | |
518 case ENCRSW: | |
519 encryptsw++; | |
520 continue; | |
521 case NENCRSW: | |
522 encryptsw = 0; | |
523 continue; | |
524 | |
525 case ANNOSW: | |
526 if (!(cp = *argp++) || *cp == '-') | |
527 adios (NULLCP, "missing argument to %s", argp[-2]); | |
528 if ((pfd = atoi (cp)) <= 2) | |
529 adios (NULLCP, "bad argument %s %s", argp[-2], cp); | |
530 continue; | |
531 | |
532 #ifdef MMDFMTS | |
533 case MAILSW: | |
534 submitmode = "m"; | |
535 continue; | |
536 case SOMLSW: /* for right now, sigh... */ | |
537 case SAMLSW: | |
538 submitmode = "b"; | |
539 continue; | |
540 case SENDSW: | |
541 submitmode = "y"; | |
542 continue; | |
543 #endif /* MMDFMTS */ | |
544 | |
545 #ifndef MHMTS | |
546 case DLVRSW: | |
547 if (!(cp = *argp++) || *cp == '-') | |
548 adios (NULLCP, "missing argument to %s", argp[-2]); | |
549 continue; | |
550 #else /* MHMTS */ | |
551 case MAILSW: | |
552 case SAMLSW: | |
553 case SOMLSW: | |
554 case SENDSW: | |
555 continue; | |
556 case DLVRSW: | |
557 if (!(deliver = *argp++) || *deliver == '-') | |
558 adios (NULLCP, "missing argument to %s", argp[-2]); | |
559 continue; | |
560 #endif /* MHMTS */ | |
561 | |
562 #ifndef SENDMTS | |
563 case CLIESW: | |
564 case SERVSW: | |
565 if (!(cp = *argp++) || *cp == '-') | |
566 adios (NULLCP, "missing argument to %s", argp[-2]); | |
567 continue; | |
568 | |
569 case SNOOPSW: | |
570 continue; | |
571 #else /* SENDMTS */ | |
572 case MAILSW: | |
573 smtpmode = S_MAIL; | |
574 continue; | |
575 case SAMLSW: | |
576 smtpmode = S_SAML; | |
577 continue; | |
578 case SOMLSW: | |
579 smtpmode = S_SOML; | |
580 continue; | |
581 case SENDSW: | |
582 smtpmode = S_SEND; | |
583 continue; | |
584 case CLIESW: | |
585 if (!(clientsw = *argp++) || *clientsw == '-') | |
586 adios (NULLCP, "missing argument to %s", argp[-2]); | |
587 continue; | |
588 case SERVSW: | |
589 if (!(serversw = *argp++) || *serversw == '-') | |
590 adios (NULLCP, "missing argument to %s", argp[-2]); | |
591 continue; | |
592 case SNOOPSW: | |
593 snoop++; | |
594 continue; | |
595 #endif /* SENDMTS */ | |
596 | |
597 case FILLSW: | |
598 if (!(fill_in = *argp++) || *fill_in == '-') | |
599 adios (NULLCP, "missing argument to %s", argp[-2]); | |
600 continue; | |
601 case FILLUSW: | |
602 fill_up++; | |
603 continue; | |
604 case PARTSW: | |
605 if (!(partno = *argp++) || *partno == '-') | |
606 adios (NULLCP, "missing argument to %s", argp[-2]); | |
607 continue; | |
608 | |
609 case QUEUESW: | |
610 queued++; | |
611 continue; | |
612 | |
613 case RECORSW: | |
614 if (!(record = *argp++) || *record == '-') | |
615 adios (NULLCP, "missing argument to %s", argp[-2]); | |
616 continue; | |
617 case NRECOSW: | |
618 record = NULLCP; | |
619 continue; | |
620 #ifdef MIME_HEADERS | |
621 case HENCDSW: | |
622 hencode = 1; | |
623 continue; | |
624 case NHENCDSW: | |
625 hencode = 0; | |
626 continue; | |
627 #endif /* MIME_HEADERS */ | |
628 | |
629 #ifdef MH_PLUS | |
630 case USERSW: | |
631 if (!(usersw = *argp++) || *usersw == '-') | |
632 adios (NULLCP, "missing argument to %s", argp[-2]); | |
633 continue; | |
634 case FROMSW: | |
635 if (!(fromsw = *argp++) || *fromsw == '-') | |
636 adios (NULLCP, "missing argument to %s", argp[-2]); | |
637 continue; | |
638 #endif /* MH_PLUS */ | |
639 } | |
640 if (msg) | |
641 adios (NULLCP, "only one message at a time!"); | |
642 else | |
643 msg = cp; | |
644 } | |
645 | |
646 (void) alias (AliasFile); | |
647 | |
648 /* */ | |
649 | |
650 if (!msg) | |
651 adios (NULLCP, "usage: %s [switches] file", invo_name); | |
652 | |
653 if (outputlinelen < 10) | |
654 adios (NULLCP, "impossible width %d", outputlinelen); | |
655 | |
656 #ifdef MHMTS | |
657 if (access (msg, 04) == NOTOK) | |
658 adios (msg, "unable to read"); | |
659 #endif /* MHMTS */ | |
660 if ((in = fopen (msg, "r")) == NULL) | |
661 adios (msg, "unable to open"); | |
662 | |
663 #ifdef MIME_HEADERS | |
664 if (hencode == -1) { | |
665 hencode = 0; | |
666 for (state = FLD;;) { | |
667 switch (state = m_getfld (state, name, buf, sizeof buf, in)) { | |
668 case FLD: | |
669 case FLDEOF: | |
670 case FLDPLUS: | |
671 if (uleq (name, "MIME-Version")) { | |
672 hencode = 1; | |
673 break; | |
674 } | |
675 continue; | |
676 | |
677 default: | |
678 break; | |
679 } | |
680 break; | |
681 } | |
682 (void) fseek (in, 0L, 0); | |
683 } | |
684 #endif /* MIME_HEADERS */ | |
685 | |
686 start_headers (); | |
687 if (debug) { | |
688 verbose++; | |
689 discard (out = stdout); /* XXX: reference discard() to help loader */ | |
690 #ifdef MHMTS | |
691 if (deliver) { | |
692 (void) strcpy (tmpfil, msg); | |
693 putfmt ("To", deliver, out); | |
694 goto daemon; | |
695 } | |
696 #endif /* MHMTS */ | |
697 } | |
698 else | |
699 #ifdef MHMTS | |
700 if (deliver) { | |
701 if ((out = fopen ("/dev/null", "r")) == NULL) | |
702 adios ("/dev/null", "unable to write"); | |
703 (void) strcpy (tmpfil, msg); | |
704 putfmt ("To", deliver, out); | |
705 goto daemon; | |
706 } | |
707 else | |
708 #endif /* MHMTS */ | |
709 if (whomsw) { | |
710 if ((out = fopen (fill_in ? fill_in : "/dev/null", "w")) == NULL) | |
711 adios ("/dev/null", "unable to open"); | |
712 } | |
713 else { | |
714 (void) strcpy (tmpfil, m_scratch ("", m_maildir (invo_name))); | |
715 if ((out = fopen (tmpfil, "w")) == NULL) { | |
716 (void) strcpy (tmpfil, m_tmpfil (invo_name)); | |
717 if ((out = fopen (tmpfil, "w")) == NULL) | |
718 adios (tmpfil, "unable to create"); | |
719 } | |
720 #ifdef MHMTS | |
721 (void) chown (tmpfil, myuid, mygid); | |
722 #endif /* MHMTS */ | |
723 (void) chmod (tmpfil, 0600); | |
724 } | |
725 | |
726 /* */ | |
727 | |
728 hdrtab = msgstate == NORMAL ? NHeaders : RHeaders; | |
729 | |
730 for (compnum = 1, state = FLD;;) { | |
731 switch (state = m_getfld (state, name, buf, sizeof buf, in)) { | |
732 case FLD: | |
733 case FLDEOF: | |
734 case FLDPLUS: | |
735 compnum++; | |
736 cp = add (buf, NULLCP); | |
737 while (state == FLDPLUS) { | |
738 state = m_getfld (state, name, buf, sizeof buf, in); | |
739 cp = add (buf, cp); | |
740 } | |
741 putfmt (name, cp, out); | |
742 free (cp); | |
743 if (state != FLDEOF) | |
744 continue; | |
745 finish_headers (out); | |
746 break; | |
747 | |
748 case BODY: | |
749 case BODYEOF: | |
750 finish_headers (out); | |
751 if (whomsw && !fill_in) | |
752 break; | |
753 fprintf (out, "\n%s", buf); | |
754 while (state == BODY) { | |
755 state = m_getfld (state, name, buf, sizeof buf, in); | |
756 fputs (buf, out); | |
757 } | |
758 break; | |
759 | |
760 case FILEEOF: | |
761 finish_headers (out); | |
762 break; | |
763 | |
764 case LENERR: | |
765 case FMTERR: | |
766 adios (NULLCP, "message format error in component #%d", | |
767 compnum); | |
768 | |
769 default: | |
770 adios (NULLCP, "getfld() returned %d", state); | |
771 } | |
772 break; | |
773 } | |
774 | |
775 /* */ | |
776 | |
777 #ifdef MHMTS | |
778 daemon: ; | |
779 #endif /* MHMTS */ | |
780 if (pfd != NOTOK) | |
781 anno (); | |
782 (void) fclose (in); | |
783 if (debug) { | |
784 pl (); | |
785 done (0); | |
786 } | |
787 else | |
788 (void) fclose (out); | |
789 | |
790 #ifdef TMA | |
791 if (encryptsw) | |
792 tmastart (tmasnoop); | |
793 #endif /* TMA */ | |
794 if (whomsw) { | |
795 if (!fill_up) | |
796 verify_all_addresses (1); | |
797 done (0); | |
798 } | |
799 | |
800 #ifdef MMDFMTS | |
801 (void) strcat (submitopts, submitmode); | |
802 if (watch) | |
803 (void) strcat (submitopts, "nw"); | |
804 #endif /* MMDFMTS */ | |
805 #ifdef MHMTS | |
806 verify_all_addresses (0); | |
807 #endif /* MHMTS */ | |
808 if (encryptsw) | |
809 verify_all_addresses (verbose); | |
810 if (msgflags & MINV) { | |
811 make_bcc_file (); | |
812 if (msgflags & MVIS) { | |
813 #ifndef MHMTS | |
814 if (!encryptsw) | |
815 verify_all_addresses (verbose); | |
816 #endif /* not MHMTS */ | |
817 post (tmpfil, 0, verbose); | |
818 } | |
819 post (bccfil, 1, verbose); | |
820 (void) unlink (bccfil); | |
821 } | |
822 else | |
823 post (tmpfil, 0, isatty (1)); | |
824 #ifdef TMA | |
825 if (encryptsw) | |
826 tmastop (); | |
827 #endif /* TMA */ | |
828 | |
829 p_refile (tmpfil); | |
830 | |
831 p_record (); | |
832 | |
833 #ifdef MHMTS | |
834 if (!deliver) | |
835 #endif /* MHMTS */ | |
836 (void) unlink (tmpfil); | |
837 | |
838 if (verbose) | |
839 printf (partno ? "Partial Message #%s Processed\n" : "Message Processed\n", | |
840 partno); | |
841 | |
842 done (0); | |
843 } | |
844 | |
845 /* DRAFT GENERATION */ | |
846 | |
847 static putfmt (name, str, out) | |
848 register char *name, | |
849 *str; | |
850 register FILE *out; | |
851 { | |
852 int count, | |
853 grp, | |
854 i, | |
855 keep; | |
856 register char *cp, | |
857 *pp, | |
858 *qp; | |
859 #ifdef MIME_HEADERS | |
860 char *origstr; | |
861 #endif /* MIME_HEADERS */ | |
862 char namep[BUFSIZ]; | |
863 register struct mailname *mp, | |
864 *np; | |
865 register struct headers *hdr; | |
866 | |
867 while (*str == ' ' || *str == '\t') | |
868 str++; | |
869 | |
870 if (msgstate == NORMAL && uprf (name, "resent")) { | |
871 advise (NULLCP, "illegal header line -- %s:", name); | |
872 badmsg++; | |
873 return; | |
874 } | |
875 | |
876 #ifdef MIME_HEADERS | |
877 if (hencode) { | |
878 char *ep; | |
879 if ((ep = malloc((unsigned)strlen(str)*10+1)) == NULL) | |
880 adios(NULLCP, "out of memory"); | |
881 #ifdef JAPAN | |
882 (void) ml_conv(str); | |
883 #endif /* JAPAN */ | |
884 (void) exthdr_encode(str, ep, strlen(name)+2, name); | |
885 origstr = str; | |
886 str = ep; | |
887 } | |
888 #endif /* MIME_HEADERS */ | |
889 | |
890 if ((i = get_header (name, hdrtab)) == NOTOK) { | |
891 fprintf (out, "%s: %s", name, str); | |
892 return; | |
893 } | |
894 | |
895 hdr = &hdrtab[i]; | |
896 if (hdr -> flags & HIGN) { | |
897 if (fill_in) | |
898 fprintf (out, "%s: %s", name, str); | |
899 return; | |
900 } | |
901 if (hdr -> flags & HBAD) { | |
902 if (fill_in) | |
903 fprintf (out, "%s: %s", name, str); | |
904 else { | |
905 advise (NULLCP, "illegal header line -- %s:", name); | |
906 badmsg++; | |
907 } | |
908 return; | |
909 } | |
910 msgflags |= (hdr -> set & ~(MVIS | MINV)); | |
911 | |
912 if (hdr -> set & MFRM) | |
913 msgfrom = msgfrom ? add (str, add (",", msgfrom)) : getcpy (str); | |
914 if (hdr -> flags & HSUB) | |
915 subject = subject ? add (str, add ("\t", subject)) : getcpy (str); | |
916 if (hdr -> flags & HFCC) { | |
917 if (fill_in) { | |
918 fprintf (out, "%s: %s", name, str); | |
919 return; | |
920 } | |
921 | |
922 if (cp = rindex (str, '\n')) | |
923 *cp = 0; | |
924 for (cp = pp = str; cp = index (pp, ','); pp = cp) { | |
925 *cp++ = 0; | |
926 insert_fcc (hdr, pp); | |
927 } | |
928 insert_fcc (hdr, pp); | |
929 return; | |
930 } | |
931 | |
932 /* */ | |
933 | |
934 if (!(hdr -> flags & HADR)) { | |
935 fprintf (out, "%s: %s", name, str); | |
936 return; | |
937 } | |
938 | |
939 #ifdef MIME_HEADERS | |
940 if (hencode && format) | |
941 /* encode again after format */ | |
942 (void) exthdr_decode(origstr, str); | |
943 #endif /* MIME_HEADERS */ | |
944 | |
945 tmpaddrs.m_next = NULL; | |
946 for (count = 0; cp = getname (str); count++) | |
947 if (mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP)) { | |
948 if (tmpaddrs.m_next) | |
949 np -> m_next = mp; | |
950 else | |
951 tmpaddrs.m_next = mp; | |
952 np = mp; | |
953 } | |
954 else | |
955 if (hdr -> flags & HTRY) | |
956 badadr++; | |
957 else | |
958 badmsg++; | |
959 | |
960 if (count < 1) { | |
961 if (hdr -> flags & HNIL) { | |
962 if (!(hdr -> flags & HBCC)) | |
963 fprintf (out, "%s: %s", name, str); | |
964 } | |
965 else { | |
966 #ifdef notdef | |
967 advise (NULLCP, "%s: field requires at least one address", name); | |
968 badmsg++; | |
969 #endif /* notdef */ | |
970 } | |
971 return; | |
972 } | |
973 | |
974 /* */ | |
975 | |
976 nameoutput = linepos = 0; | |
977 (void) sprintf (namep, "%s%s", | |
978 !fill_in && (hdr -> flags & HMNG) ? "Original-" : "", | |
979 name); | |
980 | |
981 for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np) | |
982 if (mp -> m_nohost) { /* also used to test (hdr -> flags & HTRY) */ | |
983 pp = akvalue (mp -> m_mbox); | |
984 qp = akvisible () ? mp -> m_mbox : ""; | |
985 np = mp; | |
986 if (np -> m_gname) | |
987 putgrp (namep, np -> m_gname, out, hdr -> flags); | |
988 while (cp = getname (pp)) { | |
989 if (!(mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP))) { | |
990 badadr++; | |
991 continue; | |
992 } | |
993 if (hdr -> flags & HBCC) | |
994 mp -> m_bcc++; | |
995 if (np -> m_ingrp) | |
996 mp -> m_ingrp = np -> m_ingrp; | |
997 else | |
998 if (mp -> m_gname) | |
999 putgrp (namep, mp -> m_gname, out, hdr -> flags); | |
1000 if (mp -> m_ingrp) | |
1001 grp++; | |
1002 #ifdef MHMTS | |
1003 mp -> m_aka = getcpy (np -> m_mbox); | |
1004 #endif /* MHMTS */ | |
1005 if (putadr (namep, qp, mp, out, hdr -> flags)) | |
1006 msgflags |= (hdr -> set & (MVIS | MINV)); | |
1007 else | |
1008 mnfree (mp); | |
1009 } | |
1010 mp = np; | |
1011 np = np -> m_next; | |
1012 mnfree (mp); | |
1013 } | |
1014 else { | |
1015 if (hdr -> flags & HBCC) | |
1016 mp -> m_bcc++; | |
1017 if (mp -> m_gname) | |
1018 putgrp (namep, mp -> m_gname, out, hdr -> flags); | |
1019 if (mp -> m_ingrp) | |
1020 grp++; | |
1021 keep = putadr (namep, "", mp, out, hdr -> flags); | |
1022 np = mp -> m_next; | |
1023 if (keep) { | |
1024 mp -> m_next = NULL; | |
1025 msgflags |= (hdr -> set & (MVIS | MINV)); | |
1026 } | |
1027 else | |
1028 mnfree (mp); | |
1029 } | |
1030 | |
1031 if (grp > 0 && (hdr -> flags & HNGR)) { | |
1032 advise (NULLCP, "%s: field does not allow groups", name); | |
1033 badmsg++; | |
1034 } | |
1035 if (linepos) { | |
1036 if (fill_in && grp > 0) | |
1037 (void) putc (';', out); | |
1038 (void) putc ('\n', out); | |
1039 } | |
1040 } | |
1041 | |
1042 /* */ | |
1043 | |
1044 static start_headers () { | |
1045 register char *cp; | |
1046 char *user = NULLCP, *addr; | |
1047 char myhost[BUFSIZ], | |
1048 sigbuf[BUFSIZ]; | |
1049 register struct mailname *mp; | |
1050 | |
1051 myuid = getuid (); | |
1052 mygid = getgid (); | |
1053 (void) time (&tclock); | |
1054 | |
1055 #ifdef MH_PLUS | |
1056 if (LocalUser && usersw) | |
1057 user = usersw; | |
1058 #endif /* MH_PLUS */ | |
1059 (void) strcpy (from, adrsprintf (user, NULLCP)); | |
1060 | |
1061 (void) strcpy (myhost, LocalName ()); | |
1062 for (cp = myhost; *cp; cp++) | |
1063 *cp = uptolow (*cp); | |
1064 | |
1065 #ifdef MHMTS | |
1066 if (deliver) { | |
1067 if (geteuid () == 0 && myuid != 0 && myuid != 1 && mygid != 1) | |
1068 adios (NULLCP, "-deliver unknown"); | |
1069 (void) strcpy (signature, from); | |
1070 } | |
1071 #endif /* MHMTS */ | |
1072 | |
1073 addr = adrsprintf (user, NULLCP); | |
1074 #ifdef MH_PLUS | |
1075 if (fromsw) { | |
1076 if (strcmp(fromsw, addr) == 0) fromsw = NULL; | |
1077 else addr = fromsw; | |
1078 } | |
1079 #endif /* MH_PLUS */ | |
1080 if ((cp = getfullname ()) && *cp) { | |
1081 (void) strcpy (sigbuf, cp); | |
1082 (void) sprintf (signature, "%s <%s>", sigbuf, addr); | |
1083 #ifdef MIME_HEADERS | |
1084 if (hencode) { | |
1085 char *ep; | |
1086 #ifdef JAPAN | |
1087 (void) ml_conv(signature); | |
1088 #endif /* JAPAN */ | |
1089 ep = getcpy (signature); | |
1090 (void) exthdr_encode (ep, signature, 5, "From"); | |
1091 free(ep); | |
1092 } | |
1093 #endif /* MIME_HEADERS */ | |
1094 if ((cp = getname (signature)) == NULL) | |
1095 adios (NULLCP, "getname () failed -- you lose extraordinarily big"); | |
1096 if ((mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP)) == NULL) | |
1097 adios (NULLCP, "bad signature '%s'", sigbuf); | |
1098 mnfree (mp); | |
1099 while (getname ("")) | |
1100 continue; | |
1101 } | |
1102 else | |
1103 (void) strcpy (signature, addr); | |
1104 } | |
1105 | |
1106 /* */ | |
1107 | |
1108 static finish_headers (out) | |
1109 register FILE *out; | |
1110 { | |
1111 switch (msgstate) { | |
1112 case NORMAL: | |
1113 if (whomsw && !fill_up) | |
1114 break; | |
1115 | |
1116 fprintf (out, "Date: %s\n", dtime (&tclock)); | |
1117 if (msgid) | |
1118 fprintf (out, "Message-ID: <%d.%ld@%s>\n", | |
1119 getpid (), (long)tclock, LocalName ()); | |
1120 if (msgflags & MFRM) | |
1121 fprintf (out, "Sender: %s\n", from); | |
1122 else { | |
1123 fprintf (out, "From: %s\n", signature); | |
1124 #ifdef MH_PLUS | |
1125 if (fromsw) fprintf (out, "Sender: %s\n", from); | |
1126 #endif /* MH_PLUS */ | |
1127 } | |
1128 if (whomsw) | |
1129 break; | |
1130 | |
1131 if (!(msgflags & MVIS) && (msgflags & MINV)) | |
1132 fprintf (out, "Bcc: Blind Distribution List: ;\n"); | |
1133 break; | |
1134 | |
1135 case RESENT: | |
1136 if (!(msgflags & MDAT)) { | |
1137 advise (NULLCP, "message has no Date: header"); | |
1138 badmsg++; | |
1139 } | |
1140 if (!(msgflags & MFRM)) { | |
1141 advise (NULLCP, "message has no From: header"); | |
1142 badmsg++; | |
1143 } | |
1144 if (whomsw && !fill_up) | |
1145 break; | |
1146 | |
1147 #ifdef MMDFI /* sigh */ | |
1148 fprintf (out, "Sender: %s\n", from); | |
1149 #endif /* MMDFI */ | |
1150 | |
1151 fprintf (out, "Resent-Date: %s\n", dtime (&tclock)); | |
1152 if (msgid) | |
1153 fprintf (out, "Resent-Message-ID: <%d.%ld@%s>\n", | |
1154 getpid (), (long)tclock, LocalName ()); | |
1155 if (msgflags & MRFM) | |
1156 fprintf (out, "Resent-Sender: %s\n", from); | |
1157 else { | |
1158 fprintf (out, "Resent-From: %s\n", signature); | |
1159 #ifdef MH_PLUS | |
1160 if (fromsw) fprintf (out, "Resent-Sender: %s\n", from); | |
1161 #endif /* MH_PLUS */ | |
1162 } | |
1163 if (whomsw) | |
1164 break; | |
1165 if (!(msgflags & MVIS) && (msgflags & MINV)) | |
1166 fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n"); | |
1167 break; | |
1168 } | |
1169 | |
1170 if (badmsg) | |
1171 adios (NULLCP, "re-format message and try again"); | |
1172 if (!recipients) | |
1173 adios (NULLCP, "no addresses"); | |
1174 } | |
1175 | |
1176 /* */ | |
1177 | |
1178 static int get_header (header, table) | |
1179 register char *header; | |
1180 register struct headers *table; | |
1181 { | |
1182 register struct headers *h; | |
1183 | |
1184 for (h = table; h -> value; h++) | |
1185 if (uleq (header, h -> value)) | |
1186 return (h - table); | |
1187 | |
1188 return NOTOK; | |
1189 } | |
1190 | |
1191 /* */ | |
1192 | |
1193 static int putadr (name, aka, mp, out, flags) | |
1194 register char *name, | |
1195 *aka; | |
1196 register struct mailname *mp; | |
1197 register FILE *out; | |
1198 unsigned int flags; | |
1199 { | |
1200 int len; | |
1201 register char *cp; | |
1202 #ifdef MIME_HEADERS | |
1203 char *ep = NULL; | |
1204 #endif /* MIME_HEADERS */ | |
1205 char buffer[BUFSIZ]; | |
1206 | |
1207 if (mp -> m_mbox == NULL || ((flags & HTRY) && !insert (mp))) | |
1208 return 0; | |
1209 if (!fill_in && (flags & (HBCC | HDCC)) || mp -> m_ingrp) | |
1210 return 1; | |
1211 | |
1212 if (!nameoutput) { | |
1213 fprintf (out, "%s: ", name); | |
1214 linepos += (nameoutput = strlen (name) + 2); | |
1215 } | |
1216 | |
1217 if (*aka && mp -> m_type != UUCPHOST && !mp -> m_pers) | |
1218 mp -> m_pers = getcpy (aka); | |
1219 if (format) { | |
1220 if (mp -> m_gname && !fill_in) | |
1221 (void) sprintf (cp = buffer, "%s;", mp -> m_gname); | |
1222 else | |
1223 cp = adrformat (mp); | |
1224 } | |
1225 else | |
1226 cp = mp -> m_text; | |
1227 #ifdef MIME_HEADERS | |
1228 if (hencode) { | |
1229 if ((ep = malloc((unsigned)strlen(cp)*10+1)) == NULL) | |
1230 adios(NULLCP, "out of memory"); | |
1231 (void) exthdr_encode(cp, ep, linepos + 2, name); | |
1232 len = strlen (ep); | |
1233 } else | |
1234 #endif /* MIME_HEADERS */ | |
1235 len = strlen (cp); | |
1236 | |
1237 if (linepos != nameoutput) | |
1238 if (len + linepos + 2 > outputlinelen) { | |
1239 fprintf (out, ",\n%*s", linepos = nameoutput, ""); | |
1240 #ifdef MIME_HEADERS | |
1241 if (hencode) | |
1242 (void) exthdr_encode (cp, ep, linepos, name); | |
1243 #endif /* MIME_HEADERS */ | |
1244 } else { | |
1245 fputs (", ", out); | |
1246 linepos += 2; | |
1247 } | |
1248 #ifdef MIME_HEADERS | |
1249 if (hencode) { | |
1250 char *p; | |
1251 fputs (ep, out); | |
1252 if ((p = rindex (ep, '\n'))) | |
1253 len -= (p+1) - ep; | |
1254 free(ep); | |
1255 } else | |
1256 fputs (cp, out); | |
1257 #else /* MIME_HEADERS */ | |
1258 fputs (cp, out); | |
1259 #endif /* MIME_HEADERS */ | |
1260 linepos += len; | |
1261 | |
1262 return (flags & HTRY); | |
1263 } | |
1264 | |
1265 /* */ | |
1266 | |
1267 static putgrp (name, group, out, flags) | |
1268 register char *name, | |
1269 *group; | |
1270 register FILE *out; | |
1271 unsigned int flags; | |
1272 { | |
1273 int len; | |
1274 char *cp; | |
1275 #ifdef MIME_HEADERS | |
1276 char *ep; | |
1277 #endif /* MIME_HEADERS */ | |
1278 | |
1279 if (!fill_in && (flags & HBCC)) | |
1280 return; | |
1281 | |
1282 if (!nameoutput) { | |
1283 fprintf (out, "%s: ", name); | |
1284 linepos += (nameoutput = strlen (name) + 2); | |
1285 if (fill_in) | |
1286 linepos -= strlen (group); | |
1287 } | |
1288 | |
1289 cp = fill_in ? group : concat (group, ";", NULLCP); | |
1290 #ifdef MIME_HEADERS | |
1291 if (hencode) { | |
1292 if ((ep = malloc((unsigned)strlen(cp)*10+1)) == NULL) | |
1293 adios(NULLCP, "out of memory"); | |
1294 (void) exthdr_encode(cp, ep, linepos + 2, name); | |
1295 len = strlen (ep); | |
1296 } else | |
1297 #endif /* MIME_HEADERS */ | |
1298 len = strlen (cp); | |
1299 | |
1300 if (linepos > nameoutput) | |
1301 if (len + linepos + 2 > outputlinelen) { | |
1302 fprintf (out, ",\n%*s", nameoutput, ""); | |
1303 linepos = nameoutput; | |
1304 #ifdef MIME_HEADERS | |
1305 if (hencode) | |
1306 (void) exthdr_encode (cp, ep, linepos, name); | |
1307 #endif /* MIME_HEADERS */ | |
1308 } | |
1309 else { | |
1310 fputs (", ", out); | |
1311 linepos += 2; | |
1312 } | |
1313 | |
1314 #ifdef MIME_HEADERS | |
1315 if (hencode) { | |
1316 char *p; | |
1317 fputs (ep, out); | |
1318 if ((p = rindex (ep, '\n'))) | |
1319 len -= (p+1) - ep; | |
1320 free(ep); | |
1321 } else | |
1322 fputs (cp, out); | |
1323 #else /* MIME_HEADERS */ | |
1324 fputs (cp, out); | |
1325 #endif /* MIME_HEADERS */ | |
1326 linepos += len; | |
1327 } | |
1328 | |
1329 /* */ | |
1330 | |
1331 static int insert (np) | |
1332 register struct mailname *np; | |
1333 { | |
1334 register struct mailname *mp; | |
1335 | |
1336 if (np -> m_mbox == NULL) | |
1337 return 0; | |
1338 | |
1339 for (mp = np -> m_type == LOCALHOST ? &localaddrs | |
1340 : np -> m_type == UUCPHOST ? &uuaddrs | |
1341 : &netaddrs; | |
1342 mp -> m_next; | |
1343 mp = mp -> m_next) | |
1344 if (uleq (np -> m_host, mp -> m_next -> m_host) | |
1345 && uleq (np -> m_mbox, mp -> m_next -> m_mbox) | |
1346 && np -> m_bcc == mp -> m_next -> m_bcc) | |
1347 return 0; | |
1348 | |
1349 mp -> m_next = np; | |
1350 recipients++; | |
1351 return 1; | |
1352 } | |
1353 | |
1354 | |
1355 static pl () { | |
1356 register int i; | |
1357 register struct mailname *mp; | |
1358 | |
1359 printf ("-------\n\t-- Addresses --\nlocal:\t"); | |
1360 for (mp = localaddrs.m_next; mp; mp = mp -> m_next) | |
1361 printf ("%s%s%s", mp -> m_mbox, | |
1362 mp -> m_bcc ? "[BCC]" : "", | |
1363 mp -> m_next ? ",\n\t" : ""); | |
1364 | |
1365 printf ("\nnet:\t"); | |
1366 for (mp = netaddrs.m_next; mp; mp = mp -> m_next) | |
1367 printf ("%s%s@%s%s%s", mp -> m_path ? mp -> m_path : "", | |
1368 mp -> m_mbox, mp -> m_host, | |
1369 mp -> m_bcc ? "[BCC]" : "", | |
1370 mp -> m_next ? ",\n\t" : ""); | |
1371 | |
1372 printf ("\nuucp:\t"); | |
1373 for (mp = uuaddrs.m_next; mp; mp = mp -> m_next) | |
1374 printf ("%s!%s%s", mp -> m_host, mp -> m_mbox, | |
1375 mp -> m_bcc ? "[BCC]" : "", | |
1376 mp -> m_next ? ",\n\t" : ""); | |
1377 | |
1378 printf ("\n\t-- Folder Copies --\nfcc:\t"); | |
1379 for (i = 0; i < fccind; i++) | |
1380 printf ("%s%s", fccfold[i], i + 1 < fccind ? ",\n\t" : ""); | |
1381 printf ("\n"); | |
1382 } | |
1383 | |
1384 /* */ | |
1385 | |
1386 static anno () { | |
1387 register struct mailname *mp; | |
1388 | |
1389 for (mp = localaddrs.m_next; mp; mp = mp -> m_next) | |
1390 if (annoaux (mp) == NOTOK) | |
1391 goto oops; | |
1392 | |
1393 for (mp = netaddrs.m_next; mp; mp = mp -> m_next) | |
1394 if (annoaux (mp) == NOTOK) | |
1395 goto oops; | |
1396 | |
1397 for (mp = uuaddrs.m_next; mp; mp = mp -> m_next) | |
1398 if (annoaux (mp) == NOTOK) | |
1399 break; | |
1400 | |
1401 oops: ; | |
1402 (void) close (pfd); | |
1403 pfd = NOTOK; | |
1404 } | |
1405 | |
1406 | |
1407 static int annoaux (mp) | |
1408 register struct mailname *mp; | |
1409 { | |
1410 int i; | |
1411 char buffer[BUFSIZ]; | |
1412 | |
1413 (void) sprintf (buffer, "%s\n", adrformat (mp)); | |
1414 i = strlen (buffer); | |
1415 | |
1416 return (write (pfd, buffer, i) == i ? OK : NOTOK); | |
1417 } | |
1418 | |
1419 /* */ | |
1420 | |
1421 static insert_fcc (hdr, pp) | |
1422 register struct headers *hdr; | |
1423 register char *pp; | |
1424 { | |
1425 register char *cp; | |
1426 | |
1427 for (cp = pp; isspace (*cp); cp++) | |
1428 continue; | |
1429 for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--) | |
1430 continue; | |
1431 if (pp >= cp) | |
1432 *++pp = 0; | |
1433 if (*cp == 0) | |
1434 return; | |
1435 | |
1436 if (fccind >= FCCS) | |
1437 adios (NULLCP, "too many %ss", hdr -> value); | |
1438 fccfold[fccind++] = getcpy (cp); | |
1439 } | |
1440 | |
1441 /* BCC GENERATION */ | |
1442 | |
1443 static make_bcc_file () { | |
1444 int fd, | |
1445 i, | |
1446 child_id; | |
1447 char *vec[6]; | |
1448 register FILE *out; | |
1449 | |
1450 (void) strcpy (bccfil, m_tmpfil ("bccs")); | |
1451 if ((out = fopen (bccfil, "w")) == NULL) | |
1452 adios (bccfil, "unable to create"); | |
1453 (void) chmod (bccfil, 0600); | |
1454 | |
1455 fprintf (out, "Date: %s\n", dtime (&tclock)); | |
1456 if (msgid) | |
1457 fprintf (out, "Message-ID: <%d.%ld.1@%s>\n", | |
1458 getpid (), (long)tclock, LocalName ()); | |
1459 if (msgflags & MFRM) { | |
1460 fprintf (out, "From: %s", msgfrom); | |
1461 fprintf (out, "Sender: %s\n", from); | |
1462 } | |
1463 else { | |
1464 fprintf (out, "From: %s\n", signature); | |
1465 #ifdef MH_PLUS | |
1466 if (fromsw) fprintf (out, "Sender: %s\n", from); | |
1467 #endif /* MH_PLUS */ | |
1468 } | |
1469 if (subject) | |
1470 fprintf (out, "Subject: %s", subject); | |
1471 fprintf (out, "BCC:\n"); | |
1472 #ifdef MIME | |
1473 if (mime) { | |
1474 char *cp; | |
1475 | |
1476 if ((cp = index (prefix, 'a')) == NULL) | |
1477 adios (NULLCP, "lost prefix start"); | |
1478 while (find_prefix () == NOTOK) | |
1479 if (*cp < 'z') | |
1480 (*cp)++; | |
1481 else | |
1482 if (*++cp == 0) | |
1483 adios (NULLCP, | |
1484 "giving up trying to find a unique delimiter string"); | |
1485 else | |
1486 (*cp)++; | |
1487 | |
1488 fprintf (out, "%s: %s\n%s: multipart/digest; boundary=\"", | |
1489 VRSN_FIELD, VRSN_VALUE, TYPE_FIELD); | |
1490 fprintf (out, "%s\"\n%s: %s\n\n--%s\n%s: %s\n%s: %s\n\n", prefix, | |
1491 DESCR_FIELD, "Blind Carbon Copy", prefix, | |
1492 TYPE_FIELD, "message/rfc822", | |
1493 DESCR_FIELD, "Original Message"); | |
1494 } | |
1495 else | |
1496 #endif /* MIME */ | |
1497 fprintf (out, "\n------- Blind-Carbon-Copy\n\n"); | |
1498 (void) fflush (out); | |
1499 | |
1500 if (filter == NULL) { | |
1501 if ((fd = open (tmpfil, 0)) == NOTOK) | |
1502 adios (tmpfil, "unable to re-open"); | |
1503 #ifdef MIME | |
1504 if (mime) | |
1505 cpydata (fd, fileno (out), tmpfil, bccfil); | |
1506 else | |
1507 #endif /* MIME */ | |
1508 cpydgst (fd, fileno (out), tmpfil, bccfil); | |
1509 (void) close (fd); | |
1510 } | |
1511 else { | |
1512 vec[0] = r1bindex (mhlproc, '/'); | |
1513 | |
1514 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) | |
1515 sleep (5); | |
1516 switch (child_id) { | |
1517 case NOTOK: | |
1518 adios ("fork", "unable to"); | |
1519 | |
1520 case OK: | |
1521 (void) dup2 (fileno (out), 1); | |
1522 | |
1523 i = 1; | |
1524 vec[i++] = "-forward"; | |
1525 vec[i++] = "-form"; | |
1526 vec[i++] = filter; | |
1527 vec[i++] = tmpfil; | |
1528 vec[i] = NULL; | |
1529 | |
1530 execvp (mhlproc, vec); | |
1531 fprintf (stderr, "unable to exec "); | |
1532 perror (mhlproc); | |
1533 _exit (-1); | |
1534 | |
1535 default: | |
1536 (void) pidXwait (child_id, mhlproc); | |
1537 break; | |
1538 } | |
1539 } | |
1540 | |
1541 (void) fseek (out, 0L, 2); | |
1542 #ifdef MIME | |
1543 if (mime) | |
1544 fprintf (out, "\n--%s--\n", prefix); | |
1545 else | |
1546 #endif /* MIME */ | |
1547 fprintf (out, "\n------- End of Blind-Carbon-Copy\n"); | |
1548 (void) fclose (out); | |
1549 } | |
1550 | |
1551 /* */ | |
1552 | |
1553 #ifdef MIME | |
1554 static int find_prefix () | |
1555 { | |
1556 int len, | |
1557 result; | |
1558 char buffer[BUFSIZ]; | |
1559 FILE *in; | |
1560 | |
1561 if ((in = fopen (tmpfil, "r")) == NULL) | |
1562 adios (tmpfil, "unable to re-open"); | |
1563 | |
1564 len = strlen (prefix); | |
1565 | |
1566 result = OK; | |
1567 while (fgets (buffer, sizeof buffer - 1, in)) | |
1568 if (buffer[0] == '-' && buffer[1] == '-') { | |
1569 register char *cp; | |
1570 | |
1571 for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--) | |
1572 if (!isspace (*cp & 0xff)) | |
1573 break; | |
1574 *++cp = '\0'; | |
1575 if (strcmp (buffer + 2, prefix) == 0) { | |
1576 result = NOTOK; | |
1577 break; | |
1578 } | |
1579 } | |
1580 | |
1581 (void) fclose (in); | |
1582 | |
1583 return result; | |
1584 } | |
1585 #endif /* MIME */ | |
1586 | |
1587 /* ADDRESS VERIFICATION */ | |
1588 | |
1589 static verify_all_addresses (talk) | |
1590 int talk; | |
1591 { | |
1592 #ifndef MHMTS | |
1593 int retval; | |
1594 #endif /* not MHMTS */ | |
1595 #ifdef MMDFMTS | |
1596 #ifdef RP_NS | |
1597 int len; | |
1598 struct rp_bufstruct reply; | |
1599 #endif /* RP_NS */ | |
1600 #endif /* MMDFMTS */ | |
1601 register struct mailname *lp; | |
1602 | |
1603 #ifndef MHMTS | |
1604 sigon (); | |
1605 #endif /* not MHMTS */ | |
1606 | |
1607 #ifdef MMDFMTS | |
1608 if (!whomsw || checksw) { | |
1609 if (rp_isbad (retval = mm_init ()) | |
1610 || rp_isbad (retval = mm_sbinit ()) | |
1611 || rp_isbad (retval = mm_winit (NULLCP, submitopts, from))) | |
1612 die (NULLCP, "problem initializing MMDF system [%s]", | |
1613 rp_valstr (retval)); | |
1614 #ifdef RP_NS | |
1615 if (rp_isbad (retval = mm_rrply (&reply, &len))) | |
1616 die (NULLCP, "problem with sender address [%s]", | |
1617 rp_valstr (retval)); | |
1618 #endif /* RP_NS */ | |
1619 } | |
1620 #endif /* MMDFMTS */ | |
1621 #ifdef SENDMTS | |
1622 if (!whomsw || checksw) | |
1623 if (rp_isbad (retval = sm_init (clientsw, serversw, 0, 0, snoop, 0, 0)) | |
1624 || rp_isbad (retval = sm_winit (smtpmode, from))) | |
1625 die (NULLCP, "problem initializing server; %s", | |
1626 rp_string (retval)); | |
1627 #endif /* SENDMTS */ | |
1628 | |
1629 if (talk && !whomsw) | |
1630 printf (" -- Address Verification --\n"); | |
1631 #ifndef BERK | |
1632 if (talk && localaddrs.m_next) | |
1633 printf (" -- Local Recipients --\n"); | |
1634 #endif /* BERK */ | |
1635 for (lp = localaddrs.m_next; lp; lp = lp -> m_next) | |
1636 do_an_address (lp, talk, encryptsw); | |
1637 | |
1638 #ifndef BERK | |
1639 if (talk && uuaddrs.m_next) | |
1640 printf (" -- UUCP Recipients --\n"); | |
1641 #endif /* BERK */ | |
1642 for (lp = uuaddrs.m_next; lp; lp = lp -> m_next) | |
1643 do_an_address (lp, talk, encryptsw); | |
1644 | |
1645 #ifndef BERK | |
1646 if (talk && netaddrs.m_next) | |
1647 printf (" -- Network Recipients --\n"); | |
1648 #endif /* BERK */ | |
1649 for (lp = netaddrs.m_next; lp; lp = lp -> m_next) | |
1650 do_an_address (lp, talk, encryptsw); | |
1651 | |
1652 chkadr (); | |
1653 if (talk && !whomsw) | |
1654 printf (" -- Address Verification Successful --\n"); | |
1655 | |
1656 #ifdef MMDFMTS | |
1657 if (!whomsw || checksw) | |
1658 (void) mm_end (NOTOK); | |
1659 #endif /* MMDFMTS */ | |
1660 #ifdef SENDMTS | |
1661 if (!whomsw || checksw) | |
1662 (void) sm_end (DONE); | |
1663 #endif /* SENDMTS */ | |
1664 (void) fflush (stdout); | |
1665 | |
1666 #ifndef MHMTS | |
1667 sigoff (); | |
1668 #endif /* not MHMTS */ | |
1669 } | |
1670 | |
1671 /* */ | |
1672 | |
1673 static chkadr () { | |
1674 #define plural(x) (x == 1 ? "" : "s") | |
1675 | |
1676 if (badadr && unkadr) | |
1677 die (NULLCP, "%d address%s unparsable, %d addressee%s undeliverable", | |
1678 badadr, plural (badadr), unkadr, plural (badadr)); | |
1679 if (badadr) | |
1680 die (NULLCP, "%d address%s unparsable", badadr, plural (badadr)); | |
1681 if (unkadr) | |
1682 die (NULLCP, "%d addressee%s undeliverable", unkadr, plural (unkadr)); | |
1683 } | |
1684 | |
1685 /* MTS INTERACTION */ | |
1686 | |
1687 #ifdef TMA | |
1688 static postplain (file, bccque, talk) | |
1689 #else /* TMA */ | |
1690 static post (file, bccque, talk) | |
1691 #endif /* TMA */ | |
1692 register char *file; | |
1693 int bccque, | |
1694 talk; | |
1695 { | |
1696 int fd, | |
1697 onex = !(msgflags & MINV) || bccque; | |
1698 #ifndef MHMTS | |
1699 int retval; | |
1700 #ifdef MMDFMTS | |
1701 #ifdef RP_NS | |
1702 int len; | |
1703 struct rp_bufstruct reply; | |
1704 #endif /* RP_NS */ | |
1705 #endif /* MMDFMTS */ | |
1706 #else /* MHMTS */ | |
1707 int ud; | |
1708 #endif /* MHMTS */ | |
1709 | |
1710 if (verbose) | |
1711 if (msgflags & MINV) | |
1712 printf (" -- Posting for %s Recipients --\n", | |
1713 bccque ? "Blind" : "Sighted"); | |
1714 else | |
1715 printf (" -- Posting for All Recipients --\n"); | |
1716 | |
1717 sigon (); | |
1718 | |
1719 #ifdef MMDFMTS | |
1720 if (rp_isbad (retval = mm_init ()) | |
1721 || rp_isbad (retval = mm_sbinit ()) | |
1722 || rp_isbad (retval = mm_winit (NULLCP, submitopts, from))) | |
1723 die (NULLCP, "problem initializing MMDF system [%s]", | |
1724 rp_valstr (retval)); | |
1725 #ifdef RP_NS | |
1726 if (rp_isbad (retval = mm_rrply (&reply, &len))) | |
1727 die (NULLCP, "problem with sender address [%s]", | |
1728 rp_valstr (retval)); | |
1729 #endif /* RP_NS */ | |
1730 #endif /* MMDFMTS */ | |
1731 #ifdef SENDMTS | |
1732 if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop, | |
1733 onex, queued)) | |
1734 || rp_isbad (retval = sm_winit (smtpmode, from))) | |
1735 die (NULLCP, "problem initializing server; %s", rp_string (retval)); | |
1736 #endif /* SENDMTS */ | |
1737 | |
1738 #ifndef MHMTS | |
1739 do_addresses (bccque, talk && verbose); | |
1740 if ((fd = open (file, 0)) == NOTOK) | |
1741 die (file, "unable to re-open"); | |
1742 do_text (file, fd); | |
1743 #else /* MHMTS */ | |
1744 if ((fd = open (file, 0)) == NULL) | |
1745 adios (file, "unable to re-open"); | |
1746 #ifdef MF | |
1747 ud = UucpChan () && uuaddrs.m_next ? make_uucp_file (fd) : NOTOK; | |
1748 #else /* not MF */ | |
1749 ud = NOTOK; | |
1750 #endif /* not MF */ | |
1751 do_addresses (file, fd, ud, bccque, talk && verbose); | |
1752 if (ud != NOTOK) | |
1753 (void) close (ud); | |
1754 #endif /* MHMTS */ | |
1755 (void) close (fd); | |
1756 (void) fflush (stdout); | |
1757 | |
1758 #ifdef MMDFMTS | |
1759 (void) mm_sbend (); | |
1760 (void) mm_end (OK); | |
1761 #endif /* MMDFMTS */ | |
1762 #ifdef SENDMTS | |
1763 (void) sm_end (onex ? OK : DONE); | |
1764 #endif /* SENDMTS */ | |
1765 | |
1766 sigoff (); | |
1767 | |
1768 if (verbose) | |
1769 if (msgflags & MINV) | |
1770 printf (" -- %s Recipient Copies Posted --\n", | |
1771 bccque ? "Blind" : "Sighted"); | |
1772 else | |
1773 printf (" -- Recipient Copies Posted --\n"); | |
1774 (void) fflush (stdout); | |
1775 } | |
1776 | |
1777 /* */ | |
1778 | |
1779 #ifdef TMA | |
1780 static postcipher (file, bccque, talk) | |
1781 register char *file; | |
1782 int bccque, | |
1783 talk; | |
1784 { | |
1785 int fdP, | |
1786 state; | |
1787 char reason[BUFSIZ]; | |
1788 struct mailname *lp; | |
1789 | |
1790 if (verbose) | |
1791 if (msgflags & MINV) | |
1792 printf (" -- Posting for %s Recipients --\n", | |
1793 bccque ? "Blind" : "Sighted"); | |
1794 else | |
1795 printf (" -- Posting for All Recipients --\n"); | |
1796 | |
1797 if ((fdP = open (file, 0)) == NOTOK) | |
1798 adios (file, "unable to re-open"); | |
1799 if (ciphinit (fdP, reason) == NOTOK) | |
1800 adios (NULLCP, "%s", reason); | |
1801 (void) close (fdP); | |
1802 | |
1803 for (state = 0, lp = localaddrs.m_next; lp; lp = lp -> m_next) | |
1804 if (lp -> m_bcc ? bccque : !bccque) { | |
1805 #ifndef BERK | |
1806 if (talk && !state) | |
1807 printf (" -- Local Recipients --\n"); | |
1808 #endif /* BERK */ | |
1809 do_a_cipher (lp, talk); | |
1810 #ifndef BERK | |
1811 state++; | |
1812 #endif /* BERK */ | |
1813 } | |
1814 | |
1815 for (state = 0, lp = uuaddrs.m_next; lp; lp = lp -> m_next) | |
1816 if (lp -> m_bcc ? bccque : !bccque) { | |
1817 #ifndef BERK | |
1818 if (talk && !state) | |
1819 printf (" -- UUCP Recipients --\n"); | |
1820 #endif /* BERK */ | |
1821 do_a_cipher (lp, talk); | |
1822 #ifndef BERK | |
1823 state++; | |
1824 #endif /* BERK */ | |
1825 } | |
1826 | |
1827 for (state = 0, lp = netaddrs.m_next; lp; lp = lp -> m_next) | |
1828 if (lp -> m_bcc ? bccque : !bccque) { | |
1829 #ifndef BERK | |
1830 if (talk && !state) | |
1831 printf (" -- Network Recipients --\n"); | |
1832 #endif /* BERK */ | |
1833 do_a_cipher (lp, talk); | |
1834 #ifndef BERK | |
1835 state++; | |
1836 #endif /* BERK */ | |
1837 } | |
1838 | |
1839 if (ciphdone (reason) == NOTOK) | |
1840 admonish (NULLCP, "%s", reason); | |
1841 #ifdef SENDMTS | |
1842 if (!(msgflags & MINV) || bccque) | |
1843 (void) sm_end (OK); | |
1844 #endif /* SENDMTS */ | |
1845 | |
1846 if (verbose) | |
1847 if (msgflags & MINV) | |
1848 printf (" -- %s Recipient Copies Posted --\n", | |
1849 bccque ? "Blind" : "Sighted"); | |
1850 else | |
1851 printf (" -- Recipient Copies Posted --\n"); | |
1852 (void) fflush (stdout); | |
1853 } | |
1854 | |
1855 /* */ | |
1856 | |
1857 static do_a_cipher (lp, talk) | |
1858 register struct mailname *lp; | |
1859 int talk; | |
1860 { | |
1861 int fd, | |
1862 retval; | |
1863 register char *mbox, | |
1864 *host; | |
1865 char addr[BUFSIZ], | |
1866 reason[BUFSIZ]; | |
1867 #ifdef MMDFMTS | |
1868 #ifdef RP_NS | |
1869 int len; | |
1870 struct rp_bufstruct reply; | |
1871 #endif /* RP_NS */ | |
1872 #endif /* MMDFMTS */ | |
1873 | |
1874 sigon (); | |
1875 | |
1876 #ifdef MMDFMTS | |
1877 if (rp_isbad (retval = mm_init ()) | |
1878 || rp_isbad (retval = mm_sbinit ()) | |
1879 || rp_isbad (retval = mm_winit (NULL, submitopts, from))) | |
1880 die (NULLCP, "problem initializing MMDF system [%s]", | |
1881 rp_valstr (retval)); | |
1882 #ifdef RP_NS | |
1883 if (rp_isbad (retval = mm_rrply (&reply, &len))) | |
1884 die (NULLCP, "problem with sender address [%s]", | |
1885 rp_valstr (retval)); | |
1886 #endif /* RP_NS */ | |
1887 #endif /* MMDFMTS */ | |
1888 #ifdef SENDMTS | |
1889 if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop, | |
1890 0, 0)) | |
1891 || rp_isbad (retval = sm_winit (smtpmode, from))) | |
1892 die (NULLCP, "problem initializing server; %s", rp_string (retval)); | |
1893 #endif /* SENDMTS */ | |
1894 | |
1895 do_an_address (lp, talk, 0); | |
1896 | |
1897 switch (lp -> m_type) { | |
1898 case LOCALHOST: | |
1899 mbox = lp -> m_mbox; | |
1900 host = LocalName (); | |
1901 (void) strcpy (addr, mbox); | |
1902 break; | |
1903 | |
1904 case UUCPHOST: | |
1905 #ifdef MMDFMTS | |
1906 mbox = concat (lp -> m_host, "!", lp -> m_mbox, NULLCP); | |
1907 host = UucpChan (); | |
1908 #endif /* MMDFMTS */ | |
1909 #ifdef SENDMTS | |
1910 mbox = auxformat (lp, 0); | |
1911 host = NULL; | |
1912 #endif /* SENDMTS */ | |
1913 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox); | |
1914 break; | |
1915 | |
1916 default: | |
1917 mbox = lp -> m_mbox; | |
1918 host = lp -> m_host; | |
1919 (void) sprintf (addr, "%s at %s", lp -> m_mbox, lp -> m_host); | |
1920 break; | |
1921 } | |
1922 chkadr (); /* XXX */ | |
1923 | |
1924 #ifdef MMDFMTS | |
1925 if (rp_isbad (retval = mm_waend ())) | |
1926 die (NULLCP, "problem ending addresses [%s]\n", | |
1927 rp_valstr (retval)); | |
1928 #endif /* MMDFMTS */ | |
1929 #ifdef SENDMTS | |
1930 if (rp_isbad (retval = sm_waend ())) | |
1931 die (NULLCP, "problem ending addresses; %s", rp_string (retval)); | |
1932 #endif /* SENDMTS */ | |
1933 | |
1934 if ((fd = encipher (mbox, host, reason)) == NOTOK) | |
1935 die (NULLCP, "%s: %s", addr, reason); | |
1936 do_text ("temporary file", fd); | |
1937 (void) close (fd); | |
1938 (void) fflush (stdout); | |
1939 | |
1940 #ifdef MMDFMTS | |
1941 (void) mm_sbend (); | |
1942 (void) mm_end (OK); | |
1943 #endif /* MMDFMTS */ | |
1944 #ifdef SENDMTS | |
1945 (void) sm_end (DONE); | |
1946 #endif /* SENDMTS */ | |
1947 | |
1948 sigoff (); | |
1949 } | |
1950 #endif /* TMA */ | |
1951 | |
1952 /* */ | |
1953 | |
1954 #ifndef MHMTS | |
1955 static do_addresses (bccque, talk) | |
1956 #else /* MHMTS */ | |
1957 static do_addresses (file, fd, ud, bccque, talk) | |
1958 register char *file; | |
1959 int fd, | |
1960 ud; | |
1961 #endif /* MHMTS */ | |
1962 int bccque, | |
1963 talk; | |
1964 { | |
1965 int retval; | |
1966 #ifndef BERK | |
1967 int state; | |
1968 #endif /* not BERK */ | |
1969 register struct mailname *lp; | |
1970 | |
1971 #ifndef BERK | |
1972 state = 0; | |
1973 #endif /* not BERK */ | |
1974 for (lp = localaddrs.m_next; lp; lp = lp -> m_next) | |
1975 if (lp -> m_bcc ? bccque : !bccque) { | |
1976 #ifndef BERK | |
1977 if (talk && !state) | |
1978 printf (" -- Local Recipients --\n"); | |
1979 #endif /* not BERK */ | |
1980 #ifndef MHMTS | |
1981 do_an_address (lp, talk, 0); | |
1982 #else /* MHMTS */ | |
1983 localmail (lp, talk, fd); | |
1984 #endif /* MHMTS */ | |
1985 #ifndef BERK | |
1986 state++; | |
1987 #endif /* not BERK */ | |
1988 } | |
1989 | |
1990 #ifndef BERK | |
1991 state = 0; | |
1992 #endif /* not BERK */ | |
1993 for (lp = uuaddrs.m_next; lp; lp = lp -> m_next) | |
1994 if (lp -> m_bcc ? bccque : !bccque) { | |
1995 #ifndef BERK | |
1996 if (talk && !state) | |
1997 printf (" -- UUCP Recipients --\n"); | |
1998 #endif /* not BERK */ | |
1999 #ifndef MHMTS | |
2000 do_an_address (lp, talk, 0); | |
2001 #else /* MHMTS */ | |
2002 uucpmail (lp, talk, ud != NOTOK ? ud : fd, ud == NOTOK); | |
2003 #endif /* MHMTS */ | |
2004 #ifndef BERK | |
2005 state++; | |
2006 #endif /* not BERK */ | |
2007 } | |
2008 | |
2009 #ifndef BERK | |
2010 state = 0; | |
2011 #endif /* not BERK */ | |
2012 for (lp = netaddrs.m_next; lp; lp = lp -> m_next) | |
2013 if (lp -> m_bcc ? bccque : !bccque) { | |
2014 #ifndef BERK | |
2015 if (talk && !state) | |
2016 printf (" -- Network Recipients --\n"); | |
2017 #endif /* not BERK */ | |
2018 #ifndef MHMTS | |
2019 do_an_address (lp, talk, 0); | |
2020 #else /* MHMTS */ | |
2021 netmail (talk, fd, bccque); | |
2022 #endif /* MHMTS */ | |
2023 #ifndef BERK | |
2024 state++; | |
2025 #endif /* not BERK */ | |
2026 } | |
2027 | |
2028 /* */ | |
2029 | |
2030 chkadr (); | |
2031 | |
2032 #ifdef MMDFMTS | |
2033 if (rp_isbad (retval = mm_waend ())) | |
2034 die (NULLCP, "problem ending addresses [%s]\n", | |
2035 rp_valstr (retval)); | |
2036 #endif /* MMDFMTS */ | |
2037 #ifdef SENDMTS | |
2038 if (rp_isbad (retval = sm_waend ())) | |
2039 die (NULLCP, "problem ending addresses; %s", rp_string (retval)); | |
2040 #endif /* SENDMTS */ | |
2041 } | |
2042 | |
2043 /* */ | |
2044 | |
2045 #ifndef MHMTS | |
2046 static do_text (file, fd) | |
2047 register char *file; | |
2048 int fd; | |
2049 { | |
2050 int retval, | |
2051 state; | |
2052 char buf[BUFSIZ]; | |
2053 #ifdef MMDFMTS | |
2054 struct rp_bufstruct reply; | |
2055 #endif /* MMDFMTS */ | |
2056 | |
2057 (void) lseek (fd, (off_t)0, 0); | |
2058 while ((state = read (fd, buf, sizeof buf)) > 0) | |
2059 #ifdef MMDFMTS | |
2060 if (rp_isbad (mm_wtxt (buf, state))) | |
2061 die (NULLCP, "problem writing text [%s]\n", rp_valstr (retval)); | |
2062 #endif /* MMDFMTS */ | |
2063 #ifdef SENDMTS | |
2064 if (rp_isbad (retval = sm_wtxt (buf, state))) | |
2065 die (NULLCP, "problem writing text; %s\n", rp_string (retval)); | |
2066 #endif /* SENDMTS */ | |
2067 | |
2068 if (state == NOTOK) | |
2069 die (file, "problem reading from"); | |
2070 | |
2071 #ifdef MMDFMTS | |
2072 if (rp_isbad (retval = mm_wtend ())) | |
2073 die (NULLCP, "problem ending text [%s]\n", rp_valstr (retval)); | |
2074 | |
2075 if (rp_isbad (retval = mm_rrply (&reply, &state))) | |
2076 die (NULLCP, "problem getting submission status [%s]\n", | |
2077 rp_valstr (retval)); | |
2078 | |
2079 switch (rp_gval (reply.rp_val)) { | |
2080 case RP_OK: | |
2081 case RP_MOK: | |
2082 break; | |
2083 | |
2084 case RP_NO: | |
2085 die (NULLCP, "you lose; %s", reply.rp_line); | |
2086 | |
2087 case RP_NDEL: | |
2088 die (NULLCP, "no delivery occurred; %s", reply.rp_line); | |
2089 | |
2090 case RP_AGN: | |
2091 die (NULLCP, "try again later; %s", reply.rp_line); | |
2092 | |
2093 case RP_NOOP: | |
2094 die (NULLCP, "nothing done; %s", reply.rp_line); | |
2095 | |
2096 default: | |
2097 die (NULLCP, "unexpected response;\n\t[%s] -- %s", | |
2098 rp_valstr (reply.rp_val), reply.rp_line); | |
2099 } | |
2100 #endif /* MMDFMTS */ | |
2101 #ifdef SENDMTS | |
2102 switch (retval = sm_wtend ()) { | |
2103 case RP_OK: | |
2104 break; | |
2105 | |
2106 case RP_NO: | |
2107 case RP_NDEL: | |
2108 die (NULLCP, "posting failed; %s", rp_string (retval)); | |
2109 | |
2110 default: | |
2111 die (NULLCP, "unexpected response; %s", rp_string (retval)); | |
2112 } | |
2113 #endif /* SENDMTS */ | |
2114 } | |
2115 #endif /* not MHMTS */ | |
2116 | |
2117 /* MTS-SPECIFIC INTERACTION */ | |
2118 | |
2119 #ifdef MMDFMTS | |
2120 | |
2121 #ifndef TMA | |
2122 /* ARGSUSED */ | |
2123 #endif /* TMA */ | |
2124 | |
2125 static do_an_address (lp, talk, tma) | |
2126 register struct mailname *lp; | |
2127 int talk, | |
2128 tma; | |
2129 { | |
2130 int len, | |
2131 retval; | |
2132 register char *mbox, | |
2133 *host, | |
2134 *text, | |
2135 *path; | |
2136 char addr[BUFSIZ]; | |
2137 #ifdef TMA | |
2138 char reason[BUFSIZ]; | |
2139 #endif /* TMA */ | |
2140 struct rp_bufstruct reply; | |
2141 | |
2142 switch (lp -> m_type) { | |
2143 case LOCALHOST: | |
2144 mbox = lp -> m_mbox; | |
2145 host = LocalName (); | |
2146 (void) strcpy (addr, mbox); | |
2147 break; | |
2148 | |
2149 case UUCPHOST: | |
2150 #ifdef MF | |
2151 mbox = concat (lp -> m_host, "!", lp -> m_mbox, NULLCP); | |
2152 host = UucpChan (); | |
2153 (void) strcpy (addr, mbox); | |
2154 break; | |
2155 #else /* MF */ | |
2156 fprintf (talk ? stdout : stderr, " %s!%s: %s\n", | |
2157 lp -> m_host, lp -> m_mbox, "not supported; UUCP address"); | |
2158 unkadr++; | |
2159 (void) fflush (stdout); | |
2160 return; | |
2161 #endif /* MF */ | |
2162 | |
2163 default: /* let MMDF decide if the host is bad */ | |
2164 mbox = lp -> m_mbox; | |
2165 host = lp -> m_host; | |
2166 (void) sprintf (addr, "%s at %s", mbox, host); | |
2167 break; | |
2168 } | |
2169 #ifdef TMA | |
2170 if ((!whomsw || checksw) | |
2171 && tma | |
2172 && seekaddr (mbox, host, reason) == NOTOK) { | |
2173 fprintf (talk ? stdout : stderr, " %s%s: %s\n", | |
2174 addr, "[TMA]", reason); | |
2175 unkadr++; | |
2176 } | |
2177 #endif /* TMA */ | |
2178 | |
2179 if (talk) | |
2180 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : ""); | |
2181 | |
2182 if (whomsw && !checksw) { | |
2183 (void) putchar ('\n'); | |
2184 return; | |
2185 } | |
2186 if (talk) | |
2187 printf (": "); | |
2188 (void) fflush (stdout); | |
2189 | |
2190 /* */ | |
2191 | |
2192 #ifdef MMDFII | |
2193 if (lp -> m_path) | |
2194 path = concat (lp -> m_path, mbox, "@", host, NULLCP); | |
2195 else | |
2196 #endif /* MMDFII */ | |
2197 path = NULLCP; | |
2198 if (rp_isbad (retval = mm_wadr (path ? NULLCP : host, path ? path : mbox)) | |
2199 || rp_isbad (retval = mm_rrply (&reply, &len))) | |
2200 die (NULLCP, "problem submitting address [%s]", rp_valstr (retval)); | |
2201 | |
2202 switch (rp_gval (reply.rp_val)) { | |
2203 case RP_AOK: | |
2204 if (talk) | |
2205 printf ("address ok\n"); | |
2206 (void) fflush (stdout); | |
2207 return; | |
2208 | |
2209 #ifdef RP_DOK | |
2210 case RP_DOK: | |
2211 if (talk) | |
2212 printf ("nameserver timeout - queued for checking\n"); | |
2213 (void) fflush (stdout); | |
2214 return; | |
2215 #endif /* RP_DOK */ | |
2216 | |
2217 case RP_NO: | |
2218 text = "you lose"; | |
2219 break; | |
2220 | |
2221 #ifdef RP_NS | |
2222 case RP_NS: | |
2223 text = "temporary nameserver failure"; | |
2224 break; | |
2225 | |
2226 #endif /* RP_NS */ | |
2227 | |
2228 case RP_USER: | |
2229 case RP_NDEL: | |
2230 text = "not deliverable"; | |
2231 break; | |
2232 | |
2233 case RP_AGN: | |
2234 text = "try again later"; | |
2235 break; | |
2236 | |
2237 case RP_NOOP: | |
2238 text = "nothing done"; | |
2239 break; | |
2240 | |
2241 default: | |
2242 if (!talk) | |
2243 fprintf (stderr, " %s: ", addr); | |
2244 text = "unexpected response"; | |
2245 die (NULLCP, "%s;\n [%s] -- %s", text, | |
2246 rp_valstr (reply.rp_val), reply.rp_line); | |
2247 } | |
2248 | |
2249 if (!talk) | |
2250 fprintf (stderr, " %s: ", addr); | |
2251 fprintf (talk ? stdout : stderr, "%s;\n %s\n", text, reply.rp_line); | |
2252 unkadr++; | |
2253 | |
2254 (void) fflush (stdout); | |
2255 } | |
2256 #endif /* MMDFMTS */ | |
2257 | |
2258 /* */ | |
2259 | |
2260 #ifdef MHMTS | |
2261 /* ARGSUSED */ | |
2262 | |
2263 static do_an_address (lp, talk, tma) | |
2264 register struct mailname *lp; | |
2265 int talk, | |
2266 tma; | |
2267 { | |
2268 register char *mbox; | |
2269 char addr[BUFSIZ]; | |
2270 | |
2271 switch (lp -> m_type) { | |
2272 case LOCALHOST: | |
2273 (void) strcpy (addr, lp -> m_mbox); | |
2274 break; | |
2275 | |
2276 case UUCPHOST: | |
2277 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox); | |
2278 break; | |
2279 | |
2280 default: | |
2281 (void) sprintf (addr, "%s at %s", lp -> m_mbox, lp -> m_host); | |
2282 break; | |
2283 } | |
2284 if (talk) | |
2285 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : ""); | |
2286 | |
2287 if (whomsw && !checksw) { | |
2288 (void) putchar ('\n'); | |
2289 return; | |
2290 } | |
2291 if (talk) | |
2292 printf (": "); | |
2293 (void) fflush (stdout); | |
2294 | |
2295 /* */ | |
2296 | |
2297 switch (lp -> m_type) { | |
2298 case LOCALHOST: | |
2299 mbox = lp -> m_mbox; | |
2300 if (*mbox == '~') | |
2301 mbox++; | |
2302 if (seek_home (mbox)) { | |
2303 lp -> m_mbox = mbox; | |
2304 if (talk) | |
2305 printf ("address ok\n"); | |
2306 } | |
2307 else { | |
2308 if (!talk) | |
2309 fprintf (stderr, " %s: ", addr); | |
2310 fprintf (talk ? stdout : stderr, | |
2311 "not deliverable; unknown user\n"); | |
2312 unkadr++; | |
2313 } | |
2314 break; | |
2315 | |
2316 case UUCPHOST: | |
2317 if (uucpsite (lp -> m_host) == OK) { | |
2318 if (talk) | |
2319 printf ("address ok\n"); | |
2320 } | |
2321 else { | |
2322 if (!talk) | |
2323 fprintf (stderr, " %s: ", addr); | |
2324 fprintf (talk ? stdout : stderr, | |
2325 "not deliverable; unknown system\n"); | |
2326 unkadr++; | |
2327 } | |
2328 break; | |
2329 | |
2330 case NETHOST: | |
2331 if (talk) | |
2332 printf ("address ok\n"); | |
2333 break; | |
2334 | |
2335 default: | |
2336 if (!talk) | |
2337 fprintf (stderr, " %s: ", addr); | |
2338 fprintf (talk ? stdout : stderr, | |
2339 "not deliverable; unknown host\n"); | |
2340 unkadr++; | |
2341 break; | |
2342 } | |
2343 | |
2344 (void) fflush (stdout); | |
2345 } | |
2346 #endif /* MHMTS */ | |
2347 | |
2348 /* */ | |
2349 | |
2350 #ifdef SENDMTS | |
2351 | |
2352 #ifndef TMA | |
2353 /* ARGSUSED */ | |
2354 #endif /* TMA */ | |
2355 | |
2356 static do_an_address (lp, talk, tma) | |
2357 register struct mailname *lp; | |
2358 int talk, | |
2359 tma; | |
2360 { | |
2361 int retval; | |
2362 register char *mbox, | |
2363 *host; | |
2364 char addr[BUFSIZ]; | |
2365 #ifdef TMA | |
2366 char reason[BUFSIZ]; | |
2367 #endif /* TMA */ | |
2368 | |
2369 switch (lp -> m_type) { | |
2370 case LOCALHOST: | |
2371 mbox = lp -> m_mbox; | |
2372 host = lp -> m_host; | |
2373 (void) strcpy (addr, mbox); | |
2374 break; | |
2375 | |
2376 case UUCPHOST: | |
2377 mbox = auxformat (lp, 0); | |
2378 host = NULL; | |
2379 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox); | |
2380 break; | |
2381 | |
2382 default: /* let SendMail decide if the host is bad */ | |
2383 mbox = lp -> m_mbox; | |
2384 host = lp -> m_host; | |
2385 (void) sprintf (addr, "%s at %s", mbox, host); | |
2386 break; | |
2387 } | |
2388 | |
2389 #ifdef TMA | |
2390 if ((!whomsw || checksw) | |
2391 && tma | |
2392 && seekaddr (mbox, host, reason) == NOTOK) { | |
2393 fprintf (talk ? stdout : stderr, " %s%s: %s\n", | |
2394 addr, "[TMA]", reason); | |
2395 unkadr++; | |
2396 } | |
2397 #endif /* TMA */ | |
2398 | |
2399 if (talk) | |
2400 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : ""); | |
2401 | |
2402 if (whomsw && !checksw) { | |
2403 (void) putchar ('\n'); | |
2404 return; | |
2405 } | |
2406 if (talk) | |
2407 printf (": "); | |
2408 (void) fflush (stdout); | |
2409 | |
2410 /* */ | |
2411 | |
2412 switch (retval = sm_wadr (mbox, host, | |
2413 lp -> m_type != UUCPHOST ? lp -> m_path : NULLCP)) { | |
2414 case RP_OK: | |
2415 if (talk) | |
2416 printf ("address ok\n"); | |
2417 break; | |
2418 | |
2419 case RP_NO: | |
2420 case RP_USER: | |
2421 if (!talk) | |
2422 fprintf (stderr, " %s: ", addr); | |
2423 fprintf (talk ? stdout : stderr, "loses; %s\n", | |
2424 rp_string (retval)); | |
2425 unkadr++; | |
2426 break; | |
2427 | |
2428 default: | |
2429 if (!talk) | |
2430 fprintf (stderr, " %s: ", addr); | |
2431 die (NULLCP, "unexpected response; %s", rp_string (retval)); | |
2432 } | |
2433 | |
2434 (void) fflush (stdout); | |
2435 } | |
2436 #endif /* SENDMTS */ | |
2437 | |
2438 /* SIGNAL HANDLING */ | |
2439 | |
2440 #ifndef MHMTS | |
2441 | |
2442 /* ARGSUSED */ | |
2443 | |
2444 static TYPESIG sigser (i) | |
2445 int i; | |
2446 { | |
2447 #ifndef BSD42 | |
2448 (void) signal (i, SIG_IGN); | |
2449 #endif /* not BSD42 */ | |
2450 (void) unlink (tmpfil); | |
2451 if (msgflags & MINV) | |
2452 (void) unlink (bccfil); | |
2453 #ifdef MMDFMTS | |
2454 if (!whomsw || checksw) | |
2455 (void) mm_end (NOTOK); | |
2456 #endif /* MMDFMTS */ | |
2457 #ifdef SENDMTS | |
2458 if (!whomsw || checksw) | |
2459 (void) sm_end (NOTOK); | |
2460 #endif /* SENDMTS */ | |
2461 done (1); | |
2462 } | |
2463 #endif /* not MHMTS */ | |
2464 | |
2465 | |
2466 static sigon () { | |
2467 if (debug) | |
2468 return; | |
2469 | |
2470 #ifndef MHMTS | |
2471 setsigx (hstat, SIGHUP, sigser); | |
2472 setsigx (istat, SIGINT, sigser); | |
2473 setsigx (qstat, SIGQUIT, sigser); | |
2474 setsigx (tstat, SIGTERM, sigser); | |
2475 #else /* MHMTS */ | |
2476 setsigx (hstat, SIGHUP, SIG_IGN); | |
2477 setsigx (istat, SIGINT, SIG_IGN); | |
2478 setsigx (qstat, SIGQUIT, SIG_IGN); | |
2479 setsigx (tstat, SIGTERM, SIG_IGN); | |
2480 #endif /* MHMTS */ | |
2481 } | |
2482 | |
2483 | |
2484 static sigoff () { | |
2485 if (debug) | |
2486 return; | |
2487 | |
2488 (void) signal (SIGHUP, hstat); | |
2489 (void) signal (SIGINT, istat); | |
2490 (void) signal (SIGQUIT, qstat); | |
2491 (void) signal (SIGTERM, tstat); | |
2492 } | |
2493 | |
2494 /* FCC INTERACTION */ | |
2495 | |
2496 static p_refile (file) | |
2497 register char *file; | |
2498 { | |
2499 register int i; | |
2500 | |
2501 if (fccind == 0) | |
2502 return; | |
2503 | |
2504 #ifdef MHMTS | |
2505 (void) setuid (myuid); | |
2506 #endif /* MHMTS */ | |
2507 if (verbose) | |
2508 printf (" -- Filing Folder Copies --\n"); | |
2509 for (i = 0; i < fccind; i++) | |
2510 fcc (file, fccfold[i]); | |
2511 if (verbose) | |
2512 printf (" -- Folder Copies Filed --\n"); | |
2513 } | |
2514 | |
2515 | |
2516 static fcc (file, folder) | |
2517 register char *file, | |
2518 *folder; | |
2519 { | |
2520 int i, | |
2521 child_id, | |
2522 status; | |
2523 char fold[BUFSIZ]; | |
2524 | |
2525 if (verbose) | |
2526 printf (" %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder); | |
2527 (void) fflush (stdout); | |
2528 | |
2529 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) | |
2530 sleep (5); | |
2531 switch (child_id) { | |
2532 case NOTOK: | |
2533 if (!verbose) | |
2534 fprintf (stderr, " %sFcc %s: ", | |
2535 msgstate == RESENT ? "Resent-" : "", folder); | |
2536 fprintf (verbose ? stdout : stderr, "no forks, so not ok\n"); | |
2537 break; | |
2538 | |
2539 case OK: | |
2540 (void) sprintf (fold, "%s%s", | |
2541 *folder == '+' || *folder == '@' ? "" : "+", folder); | |
2542 execlp (fileproc, r1bindex (fileproc, '/'), | |
2543 "-link", "-file", file, fold, NULLCP); | |
2544 _exit (-1); | |
2545 | |
2546 default: | |
2547 if (status = pidwait (child_id, OK)) { | |
2548 if (!verbose) | |
2549 fprintf (stderr, " %sFcc %s: ", | |
2550 msgstate == RESENT ? "Resent-" : "", folder); | |
2551 (void) pidstatus (status, verbose ? stdout : stderr, NULLCP); | |
2552 } | |
2553 else | |
2554 if (verbose) | |
2555 printf ("folder ok\n"); | |
2556 } | |
2557 | |
2558 (void) fflush (stdout); | |
2559 } | |
2560 | |
2561 /* RECORD RECIPIENTS */ | |
2562 | |
2563 static p_record () | |
2564 { | |
2565 int i, | |
2566 child_id, | |
2567 status; | |
2568 char recfile[BUFSIZ]; | |
2569 register struct mailname *ap, | |
2570 **app; | |
2571 struct mailname *addrs[3]; | |
2572 register FILE *out; | |
2573 | |
2574 if (!record || (msgflags & (MFRM | MRFM | MRPY))) | |
2575 return; | |
2576 | |
2577 addrs[0] = &localaddrs; | |
2578 addrs[1] = &netaddrs; | |
2579 addrs[2] = NULL; | |
2580 if (verbose) { | |
2581 printf ("recording recipients... "); | |
2582 fflush (stdout); | |
2583 } | |
2584 | |
2585 (void) strcpy (recfile, m_tmpfil ("record")); | |
2586 if ((out = fopen (recfile, "w")) == NULL) { | |
2587 fprintf (verbose ? stdout : stderr, "unable to create temporary file"); | |
2588 if (!verbose) | |
2589 fprintf (stderr, ", so can't record recipients"); | |
2590 fprintf (verbose ? stdout : stderr, "\n"); | |
2591 return; | |
2592 } | |
2593 (void) chmod (recfile, 0600); | |
2594 | |
2595 for (app = addrs; ap = *app; app++) { | |
2596 register struct mailname *mp; | |
2597 | |
2598 for (mp = ap -> m_next; mp; mp = mp -> m_next) | |
2599 fprintf (out, "%s\n", adrformat (mp)); | |
2600 } | |
2601 | |
2602 (void) fclose (out); | |
2603 | |
2604 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) | |
2605 sleep (5); | |
2606 switch (child_id) { | |
2607 case NOTOK: | |
2608 fprintf (verbose ? stdout : stderr, "unable to fork"); | |
2609 if (!verbose) | |
2610 fprintf (stderr, ", so can't record recipients"); | |
2611 fprintf (verbose ? stdout : stderr, "\n"); | |
2612 break; | |
2613 | |
2614 case OK: | |
2615 execlp (record, r1bindex (record, '/'), recfile, NULLCP); | |
2616 _exit (-1); | |
2617 | |
2618 default: | |
2619 if (status = pidwait (child_id, OK)) { | |
2620 if (!verbose) | |
2621 fprintf (stderr, "problem with %s: ", recfile); | |
2622 (void) pidstatus (status, verbose ? stdout : stderr, NULLCP); | |
2623 } | |
2624 else | |
2625 if (verbose) | |
2626 printf ("done\n"); | |
2627 } | |
2628 | |
2629 (void) unlink (recfile); | |
2630 } | |
2631 | |
2632 /* TERMINATION */ | |
2633 | |
2634 /* VARARGS2 */ | |
2635 | |
2636 static die (what, fmt, a, b, c, d) | |
2637 char *what, | |
2638 *fmt, | |
2639 *a, | |
2640 *b, | |
2641 *c, | |
2642 *d; | |
2643 { | |
2644 #ifndef MHMTS | |
2645 (void) unlink (tmpfil); | |
2646 if (msgflags & MINV) | |
2647 (void) unlink (bccfil); | |
2648 #endif /* MHMTS */ | |
2649 #ifdef MMDFMTS | |
2650 if (!whomsw || checksw) | |
2651 (void) mm_end (NOTOK); | |
2652 #endif /* MMDFMTS */ | |
2653 #ifdef SENDMTS | |
2654 if (!whomsw || checksw) | |
2655 (void) sm_end (NOTOK); | |
2656 #endif /* SENDMTS */ | |
2657 | |
2658 adios (what, fmt, a, b, c, d); | |
2659 } | |
2660 | |
2661 | |
2662 #ifdef MMDFMTS | |
2663 /* | |
2664 * err_abrt() is used by the mm_ routines | |
2665 * do not, under *ANY* circumstances, remove it from post, | |
2666 * or you will lose *BIG* | |
2667 */ | |
2668 | |
2669 err_abrt (code, fmt, a, b, c) | |
2670 int code; | |
2671 char *fmt, | |
2672 *a, | |
2673 *b, | |
2674 *c; | |
2675 { | |
2676 char buffer[BUFSIZ]; | |
2677 | |
2678 (void) sprintf (buffer, "[%s]", rp_valstr (code)); | |
2679 | |
2680 adios (buffer, fmt, a, b, c); | |
2681 } | |
2682 #endif /* MMDFMTS */ | |
2683 | |
2684 /* STAND-ALONE DELIVERY */ | |
2685 | |
2686 #ifdef MHMTS | |
2687 | |
2688 /* BUG: MHMTS ignores 822-style route addresses... */ | |
2689 | |
2690 static localmail (lp, talk, fd) | |
2691 register struct mailname *lp; | |
2692 int talk, | |
2693 fd; | |
2694 { | |
2695 int md; | |
2696 char mailbox[BUFSIZ], | |
2697 ddate[BUFSIZ]; | |
2698 register struct home *hp; | |
2699 | |
2700 if (talk) | |
2701 printf (" %s: ", lp -> m_mbox); | |
2702 (void) fflush (stdout); | |
2703 | |
2704 if ((hp = seek_home (lp -> m_mbox)) == NULL) { | |
2705 if (!talk) | |
2706 fprintf (stderr, " %s: ", lp -> m_mbox); | |
2707 fprintf (talk ? stdout : stderr, | |
2708 "not deliverable; unknown address\n"); | |
2709 unkadr++; | |
2710 return; | |
2711 } | |
2712 | |
2713 (void) sprintf (mailbox, "%s/%s", | |
2714 mmdfldir[0] ? mmdfldir : hp -> h_home, | |
2715 mmdflfil[0] ? mmdflfil : hp -> h_name); | |
2716 | |
2717 /* */ | |
2718 | |
2719 switch (access (slocalproc, 01)) { | |
2720 default: | |
2721 if (talk) | |
2722 printf ("(invoking hook)\n\t"); | |
2723 (void) fflush (stdout); | |
2724 | |
2725 if (usr_hook (lp, talk, fd, hp, mailbox) != NOTOK) | |
2726 return; | |
2727 if (talk) | |
2728 printf (" %s: ", lp -> m_mbox); | |
2729 (void) fflush (stdout); | |
2730 | |
2731 case NOTOK: | |
2732 (void) lseek (fd, (off_t)0, 0); | |
2733 if ((md = mbx_open (mailbox, hp -> h_uid, hp -> h_gid, m_gmprot ())) | |
2734 == NOTOK) { | |
2735 if (!talk) | |
2736 fprintf (stderr, " %s: ", lp -> m_mbox); | |
2737 fprintf (talk ? stdout : stderr, | |
2738 "error in transmission; unable to open maildrop\n"); | |
2739 unkadr++; | |
2740 return; | |
2741 } | |
2742 (void) sprintf (ddate, "Delivery-Date: %s\n", dtimenow ()); | |
2743 if (mbx_copy (mailbox, md, fd, 0, ddate, 0) == NOTOK) { | |
2744 if (!talk) | |
2745 fprintf (stderr, " %s: ", lp -> m_mbox); | |
2746 fprintf (talk ? stdout : stderr, | |
2747 "error in transmission; write to maildrop failed\n"); | |
2748 unkadr++; | |
2749 (void) close (md); | |
2750 return; | |
2751 } | |
2752 mbx_close (mailbox, md); | |
2753 | |
2754 if (talk) | |
2755 printf ("sent\n"); | |
2756 break; | |
2757 } | |
2758 | |
2759 (void) fflush (stdout); | |
2760 } | |
2761 | |
2762 /* */ | |
2763 | |
2764 static int usr_hook (lp, talk, fd, hp, mailbox) | |
2765 register struct mailname *lp; | |
2766 int talk, | |
2767 fd; | |
2768 register struct home *hp; | |
2769 register char *mailbox; | |
2770 { | |
2771 int i, | |
2772 child_id, | |
2773 status; | |
2774 char tmpfil[BUFSIZ]; | |
2775 | |
2776 if ((fd = copyfile (fd, tmpfil)) == NOTOK) { | |
2777 if (!talk) | |
2778 fprintf (stderr, " %s: ", lp -> m_mbox); | |
2779 fprintf (talk ? stdout : stderr, | |
2780 "unable to copy message; skipping hook\n"); | |
2781 return NOTOK; | |
2782 } | |
2783 (void) chown (tmpfil, hp -> h_uid, hp -> h_gid); | |
2784 | |
2785 (void) fflush (stdout); | |
2786 | |
2787 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) | |
2788 sleep (5); | |
2789 switch (child_id) { | |
2790 case NOTOK: | |
2791 if (!talk) | |
2792 fprintf (stderr, " %s: ", lp -> m_mbox); | |
2793 fprintf (talk ? stdout : stderr, | |
2794 "unable to invoke hook; fork() failed\n"); | |
2795 return NOTOK; | |
2796 | |
2797 case OK: | |
2798 if (fd != 0) | |
2799 (void) dup2 (fd, 0); | |
2800 (void) freopen ("/dev/null", "w", stdout); | |
2801 (void) freopen ("/dev/null", "w", stderr); | |
2802 if (fd != 3) /* backwards compatible... */ | |
2803 (void) dup2 (fd, 3); | |
2804 closefds (4); | |
2805 #ifdef TIOCNOTTY | |
2806 if ((fd = open ("/dev/tty", 2)) != NOTOK) { | |
2807 (void) ioctl (fd, TIOCNOTTY, NULLCP); | |
2808 (void) close (fd); | |
2809 } | |
2810 #endif /* TIOCNOTTY */ | |
2811 #ifdef BSD42 | |
2812 (void) setpgrp (0, getpid ()); | |
2813 #endif /* BSD42 */ | |
2814 | |
2815 *environ = NULL; | |
2816 (void) m_putenv ("USER", hp -> h_name); | |
2817 (void) m_putenv ("HOME", hp -> h_home); | |
2818 (void) m_putenv ("SHELL", hp -> h_shell); | |
2819 if (chdir (hp -> h_home) == NOTOK) | |
2820 (void) chdir ("/"); | |
2821 (void) umask (0077); | |
2822 #ifdef BSD41A | |
2823 (void) inigrp (hp -> h_name, hp -> h_gid); | |
2824 #endif /* BSD41A */ | |
2825 (void) setgid (hp -> h_gid); | |
2826 #if defined(BSD42) || defiined(SVR4) | |
2827 (void) initgroups (hp -> h_name, hp -> h_gid); | |
2828 #endif /* BSD42 || SVR4 */ | |
2829 (void) setuid (hp -> h_uid); | |
2830 | |
2831 execlp (slocalproc, r1bindex (slocalproc, '/'), | |
2832 "-file", tmpfil, "-mailbox", mailbox, | |
2833 "-home", hp -> h_home, "-addr", lp -> m_aka, | |
2834 "-user", hp -> h_name, "-sender", from, | |
2835 talk ? "-verbose" : NULLCP, NULLCP); | |
2836 _exit (-1); | |
2837 | |
2838 /* */ | |
2839 | |
2840 default: | |
2841 (void) close (fd); | |
2842 | |
2843 status = pidwait (child_id, OK); | |
2844 | |
2845 (void) unlink (tmpfil); | |
2846 if (status == 0) { | |
2847 if (talk) | |
2848 printf ("accepted\n"); | |
2849 return OK; | |
2850 } | |
2851 if (!talk) | |
2852 fprintf (stderr, " %s: ", lp -> m_mbox); | |
2853 fprintf (talk ? stdout : stderr, | |
2854 "%s error on hook; status=0%o\n", | |
2855 status & 0x00ff ? "system" : "user", | |
2856 status & 0x00ff ? status & 0xff | |
2857 : (status & 0xff00) >> 8); | |
2858 return NOTOK; | |
2859 } | |
2860 } | |
2861 | |
2862 /* */ | |
2863 | |
2864 static int copyfile (qd, tmpfil) | |
2865 int qd; | |
2866 register char *tmpfil; | |
2867 { | |
2868 int i, | |
2869 fd; | |
2870 char buffer[BUFSIZ]; | |
2871 | |
2872 (void) strcpy (tmpfil, m_tmpfil ("hook")); | |
2873 if ((fd = creat (tmpfil, 0600)) == NOTOK) | |
2874 return NOTOK; | |
2875 (void) close (fd); | |
2876 if ((fd = open (tmpfil, 2)) == NOTOK) | |
2877 return NOTOK; | |
2878 | |
2879 (void) lseek (qd, (off_t)0, 0); | |
2880 while ((i = read (qd, buffer, sizeof buffer)) > 0) | |
2881 if (write (fd, buffer, i) != i) { | |
2882 (void) close (fd); | |
2883 return NOTOK; | |
2884 } | |
2885 if (i == NOTOK) { | |
2886 (void) close (fd); | |
2887 return NOTOK; | |
2888 } | |
2889 | |
2890 (void) lseek (fd, (off_t)0, 0); | |
2891 | |
2892 return fd; | |
2893 } | |
2894 | |
2895 /* */ | |
2896 | |
2897 static uucpmail (lp, talk, fd, from) | |
2898 register struct mailname *lp; | |
2899 int talk, | |
2900 fd, | |
2901 from; | |
2902 { | |
2903 int i; | |
2904 TYPESIG (*pstat) (); | |
2905 char addr[BUFSIZ], | |
2906 buffer[BUFSIZ]; | |
2907 register FILE *fp; | |
2908 | |
2909 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox); | |
2910 if (talk) | |
2911 printf (" %s: ", addr); | |
2912 (void) fflush (stdout); | |
2913 | |
2914 #ifndef UCI | |
2915 (void) sprintf (buffer, "uux -r -p %s!rmail \\(%s\\)", | |
2916 lp -> m_host, lp -> m_mbox); | |
2917 #else /* UCI */ | |
2918 (void) sprintf (buffer, "uux -p %s!rmail \\(%s\\)", lp -> m_host, | |
2919 lp -> m_mbox); | |
2920 #endif /* UCI */ | |
2921 if ((fp = popen (buffer, "w")) == NULL) { | |
2922 if (!talk) | |
2923 fprintf (stderr, " %s: ", addr); | |
2924 fprintf (talk ? stdout : stderr, | |
2925 "unable to start uux; popen() failed\n"); | |
2926 unkadr++; | |
2927 return; | |
2928 } | |
2929 | |
2930 pstat = signal (SIGPIPE, SIG_IGN); | |
2931 if (from) { /* no mail filtering, so... */ | |
2932 (void) sprintf (buffer, "From %s %.24s remote from %s\n", | |
2933 getusr (), ctime (&tclock), SystemName ()); | |
2934 i = strlen (buffer); | |
2935 if (fwrite (buffer, sizeof *buffer, i, fp) != i) | |
2936 goto oops; | |
2937 } | |
2938 | |
2939 (void) lseek (fd, (off_t)0, 0); | |
2940 while ((i = read (fd, buffer, sizeof buffer)) > 0) | |
2941 if (fwrite (buffer, sizeof *buffer, i, fp) != i) { | |
2942 oops: ; | |
2943 if (!talk) | |
2944 fprintf (stderr, " %s: ", addr); | |
2945 fprintf (talk ? stdout : stderr, | |
2946 "error in transmission; write to uux failed\n"); | |
2947 unkadr++; | |
2948 (void) pclose (fp); | |
2949 return; | |
2950 } | |
2951 if (pclose (fp)) | |
2952 goto oops; | |
2953 (void) signal (SIGPIPE, pstat); | |
2954 | |
2955 if (i < 0) { | |
2956 if (!talk) | |
2957 fprintf (stderr, " %s: ", addr); | |
2958 fprintf (talk ? stdout : stderr, | |
2959 "error in transmission; read failed\n"); | |
2960 unkadr++; | |
2961 return; | |
2962 } | |
2963 | |
2964 if (talk) | |
2965 printf ("queued (via uux)\n"); | |
2966 (void) fflush (stdout); | |
2967 } | |
2968 | |
2969 /* */ | |
2970 | |
2971 #ifdef MF | |
2972 static int make_uucp_file (td) | |
2973 int td; | |
2974 { | |
2975 int i, | |
2976 qd, | |
2977 fd; | |
2978 char tmpfil[BUFSIZ]; | |
2979 | |
2980 (void) lseek (td, (off_t)0, 0); | |
2981 if ((qd = dup (td)) == NOTOK) | |
2982 adios ("fd", "unable to dup"); | |
2983 | |
2984 (void) strcpy (tmpfil, m_tmpfil ("uumf")); | |
2985 if ((fd = creat (tmpfil, 0600)) == NOTOK) | |
2986 adios (tmpfil, "unable to create"); | |
2987 (void) close (fd); | |
2988 if ((fd = open (tmpfil, 2)) == NOTOK) | |
2989 adios (tmpfil, "unable to re-open"); | |
2990 | |
2991 switch (i = mmdf2uucp (qd, fd, 1)) { | |
2992 case OK: | |
2993 if (!debug) | |
2994 (void) unlink (tmpfil); | |
2995 break; | |
2996 | |
2997 default: | |
2998 adios (NULLCP, "unable to filter mail(%d), examine %s", i, tmpfil); | |
2999 } | |
3000 (void) close (qd); | |
3001 | |
3002 return fd; | |
3003 } | |
3004 #endif /* MF */ | |
3005 | |
3006 /* */ | |
3007 | |
3008 static netmail (talk, fd, bccque) | |
3009 int talk, | |
3010 fd, | |
3011 bccque; | |
3012 { | |
3013 int i, | |
3014 naddrs; | |
3015 char buffer[BUFSIZ]; | |
3016 register struct mailname *lp; | |
3017 | |
3018 naddrs = 0; | |
3019 if (nm_init (getusr (), &tclock) == NOTOK) { | |
3020 for (lp = netaddrs.m_next; lp; lp = lp -> m_next) | |
3021 if (lp -> m_bcc ? bccque : !bccque) | |
3022 fprintf (stderr, " %s at %s: unable to get queue file\n", | |
3023 lp -> m_mbox, lp -> m_host); | |
3024 return; | |
3025 } | |
3026 | |
3027 for (lp = netaddrs.m_next; lp; lp = lp -> m_next) | |
3028 if (lp -> m_bcc ? bccque : !bccque) { | |
3029 (void) nm_wadr (lp -> m_mbox, lp -> m_host); | |
3030 naddrs++; | |
3031 if (talk) | |
3032 printf (" %s at %s: queued\n", lp -> m_mbox, lp -> m_host); | |
3033 (void) fflush (stdout); | |
3034 } | |
3035 nm_waend (); | |
3036 | |
3037 (void) lseek (fd, (off_t)0, 0); | |
3038 while ((i = read (fd, buffer, sizeof buffer)) > 0) | |
3039 if (nm_wtxt (buffer, i) == NOTOK) { | |
3040 fprintf (stderr, | |
3041 "error in transmission; write to temporary failed"); | |
3042 unkadr += naddrs; | |
3043 return; | |
3044 } | |
3045 | |
3046 if (i < 0) { | |
3047 fprintf (stderr, "error in transmission; read failed\n"); | |
3048 unkadr += naddrs; | |
3049 return; | |
3050 } | |
3051 | |
3052 if (nm_wtend () == NOTOK) { | |
3053 fprintf (stderr, "error in transmission; unable to queue message\n"); | |
3054 unkadr += naddrs; | |
3055 return; | |
3056 } | |
3057 } | |
3058 #endif /* MHMTS */ |