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