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