9 date 96.02.10.00.22.14; author jromine; state Exp;
14 date 95.12.06.19.20.22; author jromine; state Exp;
19 date 94.04.21.19.23.38; author jromine; state Exp;
24 date 93.08.25.17.26.51; author jromine; state Exp;
29 date 93.08.20.15.53.20; author jromine; state Exp;
34 date 92.12.15.00.20.22; author jromine; state Exp;
39 date 92.11.24.19.02.24; author jromine; state Exp;
44 date 92.11.19.23.24.00; author jromine; state Exp;
49 date 92.11.04.02.58.40; author jromine; state Exp;
54 date 92.11.04.00.55.52; author jromine; state Exp;
59 date 92.10.16.23.55.56; author jromine; state Exp;
64 date 92.10.16.21.37.31; author jromine; state Exp;
69 date 92.03.02.17.06.14; author jromine; state Exp;
74 date 92.01.31.22.23.44; author jromine; state Exp;
79 date 92.01.31.16.34.06; author jromine; state Exp;
84 date 92.01.30.22.39.58; author jromine; state Exp;
89 date 92.01.29.23.54.10; author jromine; state Exp;
94 date 92.01.24.00.05.24; author jromine; state Exp;
99 date 90.04.05.15.35.20; author sources; state Exp;
104 date 90.04.05.14.55.10; author sources; state Exp;
109 date 90.03.20.16.21.26; author sources; state Exp;
114 date 90.03.12.13.58.09; author sources; state Exp;
119 date 90.02.23.14.18.43; author sources; state Exp;
124 date 90.02.06.13.27.11; author sources; state Exp;
129 date 90.02.05.15.40.11; author sources; state Exp;
134 date 90.02.05.14.25.54; author sources; state Exp;
139 date 89.11.17.15.58.07; author sources; state Exp;
144 date 89.05.03.16.25.05; author sources; state Exp;
149 date 89.05.03.16.07.15; author sources; state Exp;
160 @allow "whom -c" to work (default -c to -check)
163 @/* post.c - enter messages into the transport system */
165 static char ident[] = "@@(#)$Id: post.c,v 2.25 1995/12/06 19:20:22 jromine Exp jromine $";
169 #include "../h/addrsbr.h"
170 #include "../h/aliasbr.h"
171 #include "../h/dropsbr.h"
172 #include "../zotnet/tws.h"
178 #include <sys/types.h>
180 #include "../mts/mmdf/util.h"
181 #include "../mts/mmdf/mmdf.h"
183 #include "../zotnet/mts.h"
186 #include <sys/ioctl.h>
188 #include <sys/stat.h>
191 #include "../mts/sendmail/smail.h"
196 #include "../h/mhn.h"
204 #define uptolow(c) ((isalpha(c) && isupper (c)) ? tolower (c) : (c))
205 #endif /* not MMDFMTS */
207 #define FCCS 10 /* max number of fccs allowed */
212 #define MIMEminc(a) (a)
214 #define MIMEminc(a) 0
218 #define TMAminc(a) (a)
223 static struct swit switches[] = {
225 "alias aliasfile", 0,
228 "check", -1, /* interface from whom */
230 "nocheck", -3, /* interface from whom */
236 "dist", -4, /* interface from dist */
239 "encrypt", TMAminc (-7),
241 "noencrypt", TMAminc (-9),
244 "filter filterfile", 0,
253 #define LIBSW 11 /* interface from send, whom */
254 "library directory", -7,
257 "mime", MIMEminc(-4),
259 "nomime", MIMEminc(-6),
276 #define WHOMSW 20 /* interface from whom */
294 #define ANNOSW 27 /* interface from send */
298 "deliver address-list", -7,
318 "record program", -6,
331 #define HNOP 0x0000 /* just used to keep .set around */
332 #define HBAD 0x0001 /* bad header - don't let it through */
333 #define HADR 0x0002 /* header has an address field */
334 #define HSUB 0x0004 /* Subject: header */
335 #define HTRY 0x0008 /* try to send to addrs on header */
336 #define HBCC 0x0010 /* don't output this header */
337 #define HMNG 0x0020 /* munge this header */
338 #define HNGR 0x0040 /* no groups allowed in this header */
339 #define HFCC 0x0080 /* FCC: type header */
340 #define HNIL 0x0100 /* okay for this header not to have addrs */
341 #define HIGN 0x0200 /* ignore this header */
342 #define HDCC 0x0400 /* another undocumented feature */
345 #define MFRM 0x0001 /* we've seen a From: */
346 #define MDAT 0x0002 /* we've seen a Date: */
347 #define MRFM 0x0004 /* we've seen a Resent-From: */
348 #define MVIS 0x0008 /* we've seen sighted addrs */
349 #define MINV 0x0010 /* we've seen blind addrs */
350 #define MRPY 0x0020 /* we've seen a Reply-to: */
355 static struct headers NHeaders[] = {
356 "Return-Path", HBAD, 0,
358 "Reply-To", HADR | HNGR, MRPY,
359 "From", HADR | HNGR, MFRM,
360 "Sender", HADR | HBAD, 0,
363 "To", HADR | HTRY, MVIS,
364 "cc", HADR | HTRY, MVIS,
365 "Bcc", HADR | HTRY | HBCC | HNIL, MINV,
366 "Dcc", HADR | HTRY | HDCC | HNIL, MVIS, /* sorta cc & bcc combined */
367 "Message-ID", HBAD, 0,
373 static struct headers RHeaders[] = {
374 "Resent-Reply-To", HADR | HNGR, MRPY,
375 "Resent-From", HADR | HNGR, MRFM,
376 "Resent-Sender", HADR | HBAD, 0,
377 "Resent-Date", HBAD, 0,
378 "Resent-Subject", HSUB, 0,
379 "Resent-To", HADR | HTRY, MVIS,
380 "Resent-cc", HADR | HTRY, MVIS,
381 "Resent-Bcc", HADR | HTRY | HBCC, MINV,
382 "Resent-Message-ID", HBAD, 0,
383 "Resent-Fcc", HFCC, 0,
384 "Reply-To", HADR, MRPY,
385 "From", HADR | HNGR, MFRM,
387 "Sender", HADR | HMNG | HNGR, 0,
388 #else /* not MMFDI */
389 "Sender", HADR | HNGR, 0,
390 #endif /* not MMDFI */
392 "To", HADR | HNIL, 0,
393 "cc", HADR | HNIL, 0,
394 "Bcc", HADR | HTRY | HBCC | HNIL, 0,
403 static short fccind = 0; /* index into fccfold[] */
404 static short outputlinelen = OUTPUTLINELEN;
406 static int pfd = NOTOK; /* fd to write annotation list to */
407 static int myuid= -1; /* my user id */
408 static int mygid= -1; /* my group id */
409 static int recipients = 0; /* how many people will get a copy */
410 static int unkadr = 0; /* how many of those were unknown */
411 static int badadr = 0; /* number of bad addrs */
412 static int badmsg = 0; /* message has bad semantics */
413 static int verbose = 0; /* spell it out */
414 static int format = 1; /* format addresses */
415 static int mime = 0; /* use MIME-style encapsulations */
416 static int msgid = 0; /* add msgid */
417 static int debug = 0; /* debugging post */
418 static int watch = 0; /* watch the delivery process */
419 static int whomsw = 0; /* we are whom not post */
420 static int checksw = 0; /* whom -check */
421 static int linepos=0; /* putadr()'s position on the line */
422 static int nameoutput=0; /* putadr() has output header name */
424 static unsigned msgflags = 0; /* what we've seen */
428 static int msgstate = NORMAL;
430 static long tclock = 0L; /* the time we started (more or less) */
432 static TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
434 static char tmpfil[BUFSIZ];
435 static char bccfil[BUFSIZ];
437 static char from[BUFSIZ]; /* my network address */
438 static char signature[BUFSIZ]; /* my signature */
439 static char *filter = NULL; /* the filter for BCC'ing */
440 static char *msgfrom = NULL; /* the From: field for Bcc'ing */
441 static char *subject = NULL; /* the subject field for BCC'ing */
442 static char *fccfold[FCCS]; /* foldernames for FCC'ing */
444 static struct headers *hdrtab; /* table for the message we're doing */
446 static struct mailname localaddrs={NULL}; /* local addrs */
447 static struct mailname netaddrs={NULL}; /* network addrs */
448 static struct mailname uuaddrs={NULL}; /* uucp addrs */
449 static struct mailname tmpaddrs={NULL}; /* temporary queue */
454 static char *submitmode = "m"; /* deliver to mailbox only */
455 static char submitopts[6] = "vl";/* initial options for submit */
459 static char *deliver = NULL;
461 extern char **environ;
467 static int smtpmode = S_MAIL;
468 static int snoop = 0;
469 static char *clientsw = NULL;
470 static char *serversw = NULL;
472 extern struct smtp sm_reply;
476 #define post(a,b,c) \
477 if (encryptsw) postcipher ((a), (b), (c)); else postplain ((a), (b), (c))
482 #define tmasnoop snoop
486 static int encryptsw = 0; /* encrypt it */
494 static char prefix[] = "----- =_aaaaaaaaaa";
495 static int find_prefix();
498 static int fill_up = 0;
499 static char *fill_in = NULLCP;
500 static char *partno = NULLCP;
502 static int queued = 0;
504 static char *record = NULLCP;
509 static putfmt(), start_headers(), finish_headers(), putgrp(), pl();
510 static anno(), make_bcc_file(), verify_all_addresses();
511 static chkadr(), do_addresses(), do_text(), do_an_address(), sigon();
512 static sigoff(), p_refile(), fcc(), die(), insert_fcc(), p_record ();
513 static int get_header(), putadr(), insert(), annoaux();
538 setlocale(LC_ALL, "");
540 invo_name = r1bindex (argv[0], '/');
542 mts_init (invo_name);
545 mmdf_init (invo_name);
551 while (cp = *argp++) {
553 switch (smatch (++cp, switches)) {
555 ambigsw (cp, switches);
558 adios (NULLCP, "-%s unknown", cp);
560 (void) sprintf (buf, "%s [switches] file", invo_name);
561 help (buf, switches);
565 if (!(cp = *argp++) || *cp == '-')
566 adios (NULLCP, "missing argument to %s", argp[-2]);
571 if (!(cp = *argp++) || *cp == '-')
572 adios (NULLCP, "missing argument to %s", argp[-2]);
574 if (access (libpath (cp), 04) == NOTOK)
575 adios (cp, "unable to read");
577 if ((state = alias (cp)) != AK_OK)
578 adios (NULLCP, "aliasing error in %s - %s",
579 cp, akerror (state));
598 if (!(filter = *argp++) || *filter == '-')
599 adios (NULLCP, "missing argument to %s", argp[-2]);
649 if (!(cp = *argp++) || *cp == '-')
650 adios (NULLCP, "missing argument to %s", argp[-2]);
651 if ((outputlinelen = atoi (cp)) < 10)
652 adios (NULLCP, "impossible width %d", outputlinelen);
663 if (!(cp = *argp++) || *cp == '-')
664 adios (NULLCP, "missing argument to %s", argp[-2]);
665 if ((pfd = atoi (cp)) <= 2)
666 adios (NULLCP, "bad argument %s %s", argp[-2], cp);
673 case SOMLSW: /* for right now, sigh... */
684 if (!(cp = *argp++) || *cp == '-')
685 adios (NULLCP, "missing argument to %s", argp[-2]);
694 if (!(deliver = *argp++) || *deliver == '-')
695 adios (NULLCP, "missing argument to %s", argp[-2]);
702 if (!(cp = *argp++) || *cp == '-')
703 adios (NULLCP, "missing argument to %s", argp[-2]);
722 if (!(clientsw = *argp++) || *clientsw == '-')
723 adios (NULLCP, "missing argument to %s", argp[-2]);
726 if (!(serversw = *argp++) || *serversw == '-')
727 adios (NULLCP, "missing argument to %s", argp[-2]);
735 if (!(fill_in = *argp++) || *fill_in == '-')
736 adios (NULLCP, "missing argument to %s", argp[-2]);
742 if (!(partno = *argp++) || *partno == '-')
743 adios (NULLCP, "missing argument to %s", argp[-2]);
751 if (!(record = *argp++) || *record == '-')
752 adios (NULLCP, "missing argument to %s", argp[-2]);
759 adios (NULLCP, "only one message at a time!");
764 (void) alias (AliasFile);
769 adios (NULLCP, "usage: %s [switches] file", invo_name);
771 if (outputlinelen < 10)
772 adios (NULLCP, "impossible width %d", outputlinelen);
775 if (access (msg, 04) == NOTOK)
776 adios (msg, "unable to read");
778 if ((in = fopen (msg, "r")) == NULL)
779 adios (msg, "unable to open");
784 discard (out = stdout); /* XXX: reference discard() to help loader */
787 (void) strcpy (tmpfil, msg);
788 putfmt ("To", deliver, out);
796 if ((out = fopen ("/dev/null", "r")) == NULL)
797 adios ("/dev/null", "unable to write");
798 (void) strcpy (tmpfil, msg);
799 putfmt ("To", deliver, out);
805 if ((out = fopen (fill_in ? fill_in : "/dev/null", "w")) == NULL)
806 adios ("/dev/null", "unable to open");
809 (void) strcpy (tmpfil, m_scratch ("", m_maildir (invo_name)));
810 if ((out = fopen (tmpfil, "w")) == NULL) {
811 (void) strcpy (tmpfil, m_tmpfil (invo_name));
812 if ((out = fopen (tmpfil, "w")) == NULL)
813 adios (tmpfil, "unable to create");
816 (void) chown (tmpfil, myuid, mygid);
818 (void) chmod (tmpfil, 0600);
823 hdrtab = msgstate == NORMAL ? NHeaders : RHeaders;
825 for (compnum = 1, state = FLD;;) {
826 switch (state = m_getfld (state, name, buf, sizeof buf, in)) {
831 cp = add (buf, NULLCP);
832 while (state == FLDPLUS) {
833 state = m_getfld (state, name, buf, sizeof buf, in);
836 putfmt (name, cp, out);
840 finish_headers (out);
845 finish_headers (out);
846 if (whomsw && !fill_in)
848 fprintf (out, "\n%s", buf);
849 while (state == BODY) {
850 state = m_getfld (state, name, buf, sizeof buf, in);
856 finish_headers (out);
861 adios (NULLCP, "message format error in component #%d",
865 adios (NULLCP, "getfld() returned %d", state);
891 verify_all_addresses (1);
896 (void) strcat (submitopts, submitmode);
898 (void) strcat (submitopts, "nw");
901 verify_all_addresses (0);
904 verify_all_addresses (verbose);
905 if (msgflags & MINV) {
907 if (msgflags & MVIS) {
910 verify_all_addresses (verbose);
911 #endif /* not MHMTS */
912 post (tmpfil, 0, verbose);
914 post (bccfil, 1, verbose);
915 (void) unlink (bccfil);
918 post (tmpfil, 0, isatty (1));
931 (void) unlink (tmpfil);
934 printf (partno ? "Partial Message #%s Processed\n" : "Message Processed\n",
940 /*
\f DRAFT GENERATION */
942 static putfmt (name, str, out)
955 register struct mailname *mp,
957 register struct headers *hdr;
959 while (*str == ' ' || *str == '\t')
962 if (msgstate == NORMAL && uprf (name, "resent")) {
963 advise (NULLCP, "illegal header line -- %s:", name);
968 if ((i = get_header (name, hdrtab)) == NOTOK) {
969 fprintf (out, "%s: %s", name, str);
974 if (hdr -> flags & HIGN) {
976 fprintf (out, "%s: %s", name, str);
979 if (hdr -> flags & HBAD) {
981 fprintf (out, "%s: %s", name, str);
983 advise (NULLCP, "illegal header line -- %s:", name);
988 msgflags |= (hdr -> set & ~(MVIS | MINV));
990 if (hdr -> set & MFRM)
991 msgfrom = msgfrom ? add (str, add (",", msgfrom)) : getcpy (str);
992 if (hdr -> flags & HSUB)
993 subject = subject ? add (str, add ("\t", subject)) : getcpy (str);
994 if (hdr -> flags & HFCC) {
996 fprintf (out, "%s: %s", name, str);
1000 if (cp = rindex (str, '\n'))
1002 for (cp = pp = str; cp = index (pp, ','); pp = cp) {
1004 insert_fcc (hdr, pp);
1006 insert_fcc (hdr, pp);
1012 if (!(hdr -> flags & HADR)) {
1013 fprintf (out, "%s: %s", name, str);
1017 tmpaddrs.m_next = NULL;
1018 for (count = 0; cp = getname (str); count++)
1019 if (mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP)) {
1020 if (tmpaddrs.m_next)
1023 tmpaddrs.m_next = mp;
1027 if (hdr -> flags & HTRY)
1033 if (hdr -> flags & HNIL) {
1034 if (!(hdr -> flags & HBCC))
1035 fprintf (out, "%s: %s", name, str);
1039 advise (NULLCP, "%s: field requires at least one address", name);
1048 nameoutput = linepos = 0;
1049 (void) sprintf (namep, "%s%s",
1050 !fill_in && (hdr -> flags & HMNG) ? "Original-" : "",
1053 for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np)
1054 if (mp -> m_nohost) { /* also used to test (hdr -> flags & HTRY) */
1055 pp = akvalue (mp -> m_mbox);
1056 qp = akvisible () ? mp -> m_mbox : "";
1059 putgrp (namep, np -> m_gname, out, hdr -> flags);
1060 while (cp = getname (pp)) {
1061 if (!(mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP))) {
1065 if (hdr -> flags & HBCC)
1068 mp -> m_ingrp = np -> m_ingrp;
1071 putgrp (namep, mp -> m_gname, out, hdr -> flags);
1075 mp -> m_aka = getcpy (np -> m_mbox);
1077 if (putadr (namep, qp, mp, out, hdr -> flags))
1078 msgflags |= (hdr -> set & (MVIS | MINV));
1087 if (hdr -> flags & HBCC)
1090 putgrp (namep, mp -> m_gname, out, hdr -> flags);
1093 keep = putadr (namep, "", mp, out, hdr -> flags);
1096 mp -> m_next = NULL;
1097 msgflags |= (hdr -> set & (MVIS | MINV));
1103 if (grp > 0 && (hdr -> flags & HNGR)) {
1104 advise (NULLCP, "%s: field does not allow groups", name);
1108 if (fill_in && grp > 0)
1109 (void) putc (';', out);
1110 (void) putc ('\n', out);
1116 static start_headers () {
1118 char myhost[BUFSIZ],
1120 register struct mailname *mp;
1124 (void) time (&tclock);
1126 (void) strcpy (from, adrsprintf (NULLCP, NULLCP));
1128 (void) strcpy (myhost, LocalName ());
1129 for (cp = myhost; *cp; cp++)
1130 *cp = uptolow (*cp);
1134 if (geteuid () == 0 && myuid != 0 && myuid != 1 && mygid != 1)
1135 adios (NULLCP, "-deliver unknown");
1136 (void) strcpy (signature, from);
1140 if ((cp = getfullname ()) && *cp) {
1141 (void) strcpy (sigbuf, cp);
1142 (void) sprintf (signature, "%s <%s>", sigbuf, adrsprintf (NULLCP, NULLCP));
1143 if ((cp = getname (signature)) == NULL)
1144 adios (NULLCP, "getname () failed -- you lose extraordinarily big");
1145 if ((mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP)) == NULL)
1146 adios (NULLCP, "bad signature '%s'", sigbuf);
1148 while (getname (""))
1152 (void) strcpy (signature, adrsprintf (NULLCP, NULLCP));
1157 static finish_headers (out)
1162 if (whomsw && !fill_up)
1165 fprintf (out, "Date: %s\n", dtime (&tclock));
1167 fprintf (out, "Message-ID: <%d.%ld@@%s>\n",
1168 getpid (), tclock, LocalName ());
1169 if (msgflags & MFRM)
1170 fprintf (out, "Sender: %s\n", from);
1172 fprintf (out, "From: %s\n", signature);
1176 if (!(msgflags & MVIS))
1177 fprintf (out, "Bcc: Blind Distribution List: ;\n");
1181 if (!(msgflags & MDAT)) {
1182 advise (NULLCP, "message has no Date: header");
1185 if (!(msgflags & MFRM)) {
1186 advise (NULLCP, "message has no From: header");
1189 if (whomsw && !fill_up)
1192 #ifdef MMDFI /* sigh */
1193 fprintf (out, "Sender: %s\n", from);
1196 fprintf (out, "Resent-Date: %s\n", dtime (&tclock));
1198 fprintf (out, "Resent-Message-ID: <%d.%ld@@%s>\n",
1199 getpid (), tclock, LocalName ());
1200 if (msgflags & MRFM)
1201 fprintf (out, "Resent-Sender: %s\n", from);
1203 fprintf (out, "Resent-From: %s\n", signature);
1206 if (!(msgflags & MVIS))
1207 fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n");
1212 adios (NULLCP, "re-format message and try again");
1214 adios (NULLCP, "no addressees");
1219 static int get_header (header, table)
1220 register char *header;
1221 register struct headers *table;
1223 register struct headers *h;
1225 for (h = table; h -> value; h++)
1226 if (uleq (header, h -> value))
1234 static int putadr (name, aka, mp, out, flags)
1235 register char *name,
1237 register struct mailname *mp;
1243 char buffer[BUFSIZ];
1245 if (mp -> m_mbox == NULL || ((flags & HTRY) && !insert (mp)))
1247 if (!fill_in && (flags & (HBCC | HDCC)) || mp -> m_ingrp)
1251 fprintf (out, "%s: ", name);
1252 linepos += (nameoutput = strlen (name) + 2);
1255 if (*aka && mp -> m_type != UUCPHOST && !mp -> m_pers)
1256 mp -> m_pers = getcpy (aka);
1258 if (mp -> m_gname && !fill_in)
1259 (void) sprintf (cp = buffer, "%s;", mp -> m_gname);
1261 cp = adrformat (mp);
1267 if (linepos != nameoutput)
1268 if (len + linepos + 2 > outputlinelen)
1269 fprintf (out, ",\n%*s", linepos = nameoutput, "");
1278 return (flags & HTRY);
1283 static putgrp (name, group, out, flags)
1284 register char *name,
1292 if (!fill_in && (flags & HBCC))
1296 fprintf (out, "%s: ", name);
1297 linepos += (nameoutput = strlen (name) + 2);
1299 linepos -= strlen (group);
1302 cp = fill_in ? group : concat (group, ";", NULLCP);
1305 if (linepos > nameoutput)
1306 if (len + linepos + 2 > outputlinelen) {
1307 fprintf (out, ",\n%*s", nameoutput, "");
1308 linepos = nameoutput;
1321 static int insert (np)
1322 register struct mailname *np;
1324 register struct mailname *mp;
1326 if (np -> m_mbox == NULL)
1329 for (mp = np -> m_type == LOCALHOST ? &localaddrs
1330 : np -> m_type == UUCPHOST ? &uuaddrs
1334 if (uleq (np -> m_host, mp -> m_next -> m_host)
1335 && uleq (np -> m_mbox, mp -> m_next -> m_mbox)
1336 && np -> m_bcc == mp -> m_next -> m_bcc)
1347 register struct mailname *mp;
1349 printf ("-------\n\t-- Addresses --\nlocal:\t");
1350 for (mp = localaddrs.m_next; mp; mp = mp -> m_next)
1351 printf ("%s%s%s", mp -> m_mbox,
1352 mp -> m_bcc ? "[BCC]" : "",
1353 mp -> m_next ? ",\n\t" : "");
1355 printf ("\nnet:\t");
1356 for (mp = netaddrs.m_next; mp; mp = mp -> m_next)
1357 printf ("%s%s@@%s%s%s", mp -> m_path ? mp -> m_path : "",
1358 mp -> m_mbox, mp -> m_host,
1359 mp -> m_bcc ? "[BCC]" : "",
1360 mp -> m_next ? ",\n\t" : "");
1362 printf ("\nuucp:\t");
1363 for (mp = uuaddrs.m_next; mp; mp = mp -> m_next)
1364 printf ("%s!%s%s", mp -> m_host, mp -> m_mbox,
1365 mp -> m_bcc ? "[BCC]" : "",
1366 mp -> m_next ? ",\n\t" : "");
1368 printf ("\n\t-- Folder Copies --\nfcc:\t");
1369 for (i = 0; i < fccind; i++)
1370 printf ("%s%s", fccfold[i], i + 1 < fccind ? ",\n\t" : "");
1377 register struct mailname *mp;
1379 for (mp = localaddrs.m_next; mp; mp = mp -> m_next)
1380 if (annoaux (mp) == NOTOK)
1383 for (mp = netaddrs.m_next; mp; mp = mp -> m_next)
1384 if (annoaux (mp) == NOTOK)
1387 for (mp = uuaddrs.m_next; mp; mp = mp -> m_next)
1388 if (annoaux (mp) == NOTOK)
1397 static int annoaux (mp)
1398 register struct mailname *mp;
1401 char buffer[BUFSIZ];
1403 (void) sprintf (buffer, "%s\n", adrformat (mp));
1404 i = strlen (buffer);
1406 return (write (pfd, buffer, i) == i ? OK : NOTOK);
1411 static insert_fcc (hdr, pp)
1412 register struct headers *hdr;
1417 for (cp = pp; isspace (*cp); cp++)
1419 for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--)
1427 adios (NULLCP, "too many %ss", hdr -> value);
1428 fccfold[fccind++] = getcpy (cp);
1431 /*
\f BCC GENERATION */
1433 static make_bcc_file () {
1440 (void) strcpy (bccfil, m_tmpfil ("bccs"));
1441 if ((out = fopen (bccfil, "w")) == NULL)
1442 adios (bccfil, "unable to create");
1443 (void) chmod (bccfil, 0600);
1445 fprintf (out, "Date: %s\n", dtime (&tclock));
1447 fprintf (out, "Message-ID: <%d.%ld.1@@%s>\n",
1448 getpid (), tclock, LocalName ());
1449 if (msgflags & MFRM) {
1450 fprintf (out, "From: %s", msgfrom);
1451 fprintf (out, "Sender: %s\n", from);
1454 fprintf (out, "From: %s\n", signature);
1456 fprintf (out, "Subject: %s", subject);
1457 fprintf (out, "BCC:\n");
1462 if ((cp = index (prefix, 'a')) == NULL)
1463 adios (NULLCP, "lost prefix start");
1464 while (find_prefix () == NOTOK)
1470 "giving up trying to find a unique delimiter string");
1474 fprintf (out, "%s: %s\n%s: multipart/digest; boundary=\"",
1475 VRSN_FIELD, VRSN_VALUE, TYPE_FIELD);
1476 fprintf (out, "%s\"\n%s: %s\n\n--%s\n%s: %s\n%s: %s\n\n", prefix,
1477 DESCR_FIELD, "Blind Carbon Copy", prefix,
1478 TYPE_FIELD, "message/rfc822",
1479 DESCR_FIELD, "Original Message");
1483 fprintf (out, "\n------- Blind-Carbon-Copy\n\n");
1484 (void) fflush (out);
1486 if (filter == NULL) {
1487 if ((fd = open (tmpfil, 0)) == NOTOK)
1488 adios (tmpfil, "unable to re-open");
1491 cpydata (fd, fileno (out), tmpfil, bccfil);
1494 cpydgst (fd, fileno (out), tmpfil, bccfil);
1498 vec[0] = r1bindex (mhlproc, '/');
1500 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
1504 adios ("fork", "unable to");
1507 (void) dup2 (fileno (out), 1);
1510 vec[i++] = "-forward";
1516 execvp (mhlproc, vec);
1517 fprintf (stderr, "unable to exec ");
1522 (void) pidXwait (child_id, mhlproc);
1527 (void) fseek (out, 0L, 2);
1530 fprintf (out, "\n--%s--\n", prefix);
1533 fprintf (out, "\n------- End of Blind-Carbon-Copy\n");
1534 (void) fclose (out);
1540 static int find_prefix ()
1544 char buffer[BUFSIZ];
1547 if ((in = fopen (tmpfil, "r")) == NULL)
1548 adios (tmpfil, "unable to re-open");
1550 len = strlen (prefix);
1553 while (fgets (buffer, sizeof buffer - 1, in))
1554 if (buffer[0] == '-' && buffer[1] == '-') {
1557 for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--)
1561 if (strcmp (buffer + 2, prefix) == 0) {
1573 /*
\f ADDRESS VERIFICATION */
1575 static verify_all_addresses (talk)
1580 #endif /* not MHMTS */
1584 struct rp_bufstruct reply;
1586 #endif /* MMDFMTS */
1587 register struct mailname *lp;
1591 #endif /* not MHMTS */
1594 if (!whomsw || checksw) {
1595 if (rp_isbad (retval = mm_init ())
1596 || rp_isbad (retval = mm_sbinit ())
1597 || rp_isbad (retval = mm_winit (NULLCP, submitopts, from)))
1598 die (NULLCP, "problem initializing MMDF system [%s]",
1599 rp_valstr (retval));
1601 if (rp_isbad (retval = mm_rrply (&reply, &len)))
1602 die (NULLCP, "problem with sender address [%s]",
1603 rp_valstr (retval));
1606 #endif /* MMDFMTS */
1608 if (!whomsw || checksw)
1609 if (rp_isbad (retval = sm_init (clientsw, serversw, 0, 0, snoop, 0, 0))
1610 || rp_isbad (retval = sm_winit (smtpmode, from)))
1611 die (NULLCP, "problem initializing server; %s",
1612 rp_string (retval));
1613 #endif /* SENDMTS */
1615 if (talk && !whomsw)
1616 printf (" -- Address Verification --\n");
1618 if (talk && localaddrs.m_next)
1619 printf (" -- Local Recipients --\n");
1621 for (lp = localaddrs.m_next; lp; lp = lp -> m_next)
1622 do_an_address (lp, talk, encryptsw);
1625 if (talk && uuaddrs.m_next)
1626 printf (" -- UUCP Recipients --\n");
1628 for (lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1629 do_an_address (lp, talk, encryptsw);
1632 if (talk && netaddrs.m_next)
1633 printf (" -- Network Recipients --\n");
1635 for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
1636 do_an_address (lp, talk, encryptsw);
1639 if (talk && !whomsw)
1640 printf (" -- Address Verification Successful --\n");
1643 if (!whomsw || checksw)
1644 (void) mm_end (NOTOK);
1645 #endif /* MMDFMTS */
1647 if (!whomsw || checksw)
1648 (void) sm_end (DONE);
1649 #endif /* SENDMTS */
1650 (void) fflush (stdout);
1654 #endif /* not MHMTS */
1660 #define plural(x) (x == 1 ? "" : "s")
1662 if (badadr && unkadr)
1663 die (NULLCP, "%d address%s unparsable, %d addressee%s undeliverable",
1664 badadr, plural (badadr), unkadr, plural (badadr));
1666 die (NULLCP, "%d address%s unparsable", badadr, plural (badadr));
1668 die (NULLCP, "%d addressee%s undeliverable", unkadr, plural (unkadr));
1671 /*
\f MTS INTERACTION */
1674 static postplain (file, bccque, talk)
1676 static post (file, bccque, talk)
1678 register char *file;
1683 onex = !(msgflags & MINV) || bccque;
1689 struct rp_bufstruct reply;
1691 #endif /* MMDFMTS */
1697 if (msgflags & MINV)
1698 printf (" -- Posting for %s Recipients --\n",
1699 bccque ? "Blind" : "Sighted");
1701 printf (" -- Posting for All Recipients --\n");
1706 if (rp_isbad (retval = mm_init ())
1707 || rp_isbad (retval = mm_sbinit ())
1708 || rp_isbad (retval = mm_winit (NULLCP, submitopts, from)))
1709 die (NULLCP, "problem initializing MMDF system [%s]",
1710 rp_valstr (retval));
1712 if (rp_isbad (retval = mm_rrply (&reply, &len)))
1713 die (NULLCP, "problem with sender address [%s]",
1714 rp_valstr (retval));
1716 #endif /* MMDFMTS */
1718 if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop,
1720 || rp_isbad (retval = sm_winit (smtpmode, from)))
1721 die (NULLCP, "problem initializing server; %s", rp_string (retval));
1722 #endif /* SENDMTS */
1725 do_addresses (bccque, talk && verbose);
1726 if ((fd = open (file, 0)) == NOTOK)
1727 die (file, "unable to re-open");
1730 if ((fd = open (file, 0)) == NULL)
1731 adios (file, "unable to re-open");
1733 ud = UucpChan () && uuaddrs.m_next ? make_uucp_file (fd) : NOTOK;
1737 do_addresses (file, fd, ud, bccque, talk && verbose);
1742 (void) fflush (stdout);
1747 #endif /* MMDFMTS */
1749 (void) sm_end (onex ? OK : DONE);
1750 #endif /* SENDMTS */
1755 if (msgflags & MINV)
1756 printf (" -- %s Recipient Copies Posted --\n",
1757 bccque ? "Blind" : "Sighted");
1759 printf (" -- Recipient Copies Posted --\n");
1760 (void) fflush (stdout);
1766 static postcipher (file, bccque, talk)
1767 register char *file;
1773 char reason[BUFSIZ];
1774 struct mailname *lp;
1777 if (msgflags & MINV)
1778 printf (" -- Posting for %s Recipients --\n",
1779 bccque ? "Blind" : "Sighted");
1781 printf (" -- Posting for All Recipients --\n");
1783 if ((fdP = open (file, 0)) == NOTOK)
1784 adios (file, "unable to re-open");
1785 if (ciphinit (fdP, reason) == NOTOK)
1786 adios (NULLCP, "%s", reason);
1789 for (state = 0, lp = localaddrs.m_next; lp; lp = lp -> m_next)
1790 if (lp -> m_bcc ? bccque : !bccque) {
1793 printf (" -- Local Recipients --\n");
1795 do_a_cipher (lp, talk);
1801 for (state = 0, lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1802 if (lp -> m_bcc ? bccque : !bccque) {
1805 printf (" -- UUCP Recipients --\n");
1807 do_a_cipher (lp, talk);
1813 for (state = 0, lp = netaddrs.m_next; lp; lp = lp -> m_next)
1814 if (lp -> m_bcc ? bccque : !bccque) {
1817 printf (" -- Network Recipients --\n");
1819 do_a_cipher (lp, talk);
1825 if (ciphdone (reason) == NOTOK)
1826 admonish (NULLCP, "%s", reason);
1828 if (!(msgflags & MINV) || bccque)
1830 #endif /* SENDMTS */
1833 if (msgflags & MINV)
1834 printf (" -- %s Recipient Copies Posted --\n",
1835 bccque ? "Blind" : "Sighted");
1837 printf (" -- Recipient Copies Posted --\n");
1838 (void) fflush (stdout);
1843 static do_a_cipher (lp, talk)
1844 register struct mailname *lp;
1849 register char *mbox,
1856 struct rp_bufstruct reply;
1858 #endif /* MMDFMTS */
1863 if (rp_isbad (retval = mm_init ())
1864 || rp_isbad (retval = mm_sbinit ())
1865 || rp_isbad (retval = mm_winit (NULL, submitopts, from)))
1866 die (NULLCP, "problem initializing MMDF system [%s]",
1867 rp_valstr (retval));
1869 if (rp_isbad (retval = mm_rrply (&reply, &len)))
1870 die (NULLCP, "problem with sender address [%s]",
1871 rp_valstr (retval));
1873 #endif /* MMDFMTS */
1875 if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop,
1877 || rp_isbad (retval = sm_winit (smtpmode, from)))
1878 die (NULLCP, "problem initializing server; %s", rp_string (retval));
1879 #endif /* SENDMTS */
1881 do_an_address (lp, talk, 0);
1883 switch (lp -> m_type) {
1885 mbox = lp -> m_mbox;
1886 host = LocalName ();
1887 (void) strcpy (addr, mbox);
1892 mbox = concat (lp -> m_host, "!", lp -> m_mbox, NULLCP);
1894 #endif /* MMDFMTS */
1896 mbox = auxformat (lp, 0);
1898 #endif /* SENDMTS */
1899 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
1903 mbox = lp -> m_mbox;
1904 host = lp -> m_host;
1905 (void) sprintf (addr, "%s at %s", lp -> m_mbox, lp -> m_host);
1908 chkadr (); /* XXX */
1911 if (rp_isbad (retval = mm_waend ()))
1912 die (NULLCP, "problem ending addresses [%s]\n",
1913 rp_valstr (retval));
1914 #endif /* MMDFMTS */
1916 if (rp_isbad (retval = sm_waend ()))
1917 die (NULLCP, "problem ending addresses; %s", rp_string (retval));
1918 #endif /* SENDMTS */
1920 if ((fd = encipher (mbox, host, reason)) == NOTOK)
1921 die (NULLCP, "%s: %s", addr, reason);
1922 do_text ("temporary file", fd);
1924 (void) fflush (stdout);
1929 #endif /* MMDFMTS */
1931 (void) sm_end (DONE);
1932 #endif /* SENDMTS */
1941 static do_addresses (bccque, talk)
1943 static do_addresses (file, fd, ud, bccque, talk)
1944 register char *file;
1954 #endif /* not BERK */
1955 register struct mailname *lp;
1959 #endif /* not BERK */
1960 for (lp = localaddrs.m_next; lp; lp = lp -> m_next)
1961 if (lp -> m_bcc ? bccque : !bccque) {
1964 printf (" -- Local Recipients --\n");
1965 #endif /* not BERK */
1967 do_an_address (lp, talk, 0);
1969 localmail (lp, talk, fd);
1973 #endif /* not BERK */
1978 #endif /* not BERK */
1979 for (lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1980 if (lp -> m_bcc ? bccque : !bccque) {
1983 printf (" -- UUCP Recipients --\n");
1984 #endif /* not BERK */
1986 do_an_address (lp, talk, 0);
1988 uucpmail (lp, talk, ud != NOTOK ? ud : fd, ud == NOTOK);
1992 #endif /* not BERK */
1997 #endif /* not BERK */
1998 for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
1999 if (lp -> m_bcc ? bccque : !bccque) {
2002 printf (" -- Network Recipients --\n");
2003 #endif /* not BERK */
2005 do_an_address (lp, talk, 0);
2007 netmail (talk, fd, bccque);
2011 #endif /* not BERK */
2019 if (rp_isbad (retval = mm_waend ()))
2020 die (NULLCP, "problem ending addresses [%s]\n",
2021 rp_valstr (retval));
2022 #endif /* MMDFMTS */
2024 if (rp_isbad (retval = sm_waend ()))
2025 die (NULLCP, "problem ending addresses; %s", rp_string (retval));
2026 #endif /* SENDMTS */
2032 static do_text (file, fd)
2033 register char *file;
2040 struct rp_bufstruct reply;
2041 #endif /* MMDFMTS */
2043 (void) lseek (fd, (off_t)0, 0);
2044 while ((state = read (fd, buf, sizeof buf)) > 0)
2046 if (rp_isbad (mm_wtxt (buf, state)))
2047 die (NULLCP, "problem writing text [%s]\n", rp_valstr (retval));
2048 #endif /* MMDFMTS */
2050 if (rp_isbad (retval = sm_wtxt (buf, state)))
2051 die (NULLCP, "problem writing text; %s\n", rp_string (retval));
2052 #endif /* SENDMTS */
2055 die (file, "problem reading from");
2058 if (rp_isbad (retval = mm_wtend ()))
2059 die (NULLCP, "problem ending text [%s]\n", rp_valstr (retval));
2061 if (rp_isbad (retval = mm_rrply (&reply, &state)))
2062 die (NULLCP, "problem getting submission status [%s]\n",
2063 rp_valstr (retval));
2065 switch (rp_gval (reply.rp_val)) {
2071 die (NULLCP, "you lose; %s", reply.rp_line);
2074 die (NULLCP, "no delivery occurred; %s", reply.rp_line);
2077 die (NULLCP, "try again later; %s", reply.rp_line);
2080 die (NULLCP, "nothing done; %s", reply.rp_line);
2083 die (NULLCP, "unexpected response;\n\t[%s] -- %s",
2084 rp_valstr (reply.rp_val), reply.rp_line);
2086 #endif /* MMDFMTS */
2088 switch (retval = sm_wtend ()) {
2094 die (NULLCP, "posting failed; %s", rp_string (retval));
2097 die (NULLCP, "unexpected response; %s", rp_string (retval));
2099 #endif /* SENDMTS */
2101 #endif /* not MHMTS */
2103 /*
\f MTS-SPECIFIC INTERACTION */
2111 static do_an_address (lp, talk, tma)
2112 register struct mailname *lp;
2118 register char *mbox,
2124 char reason[BUFSIZ];
2126 struct rp_bufstruct reply;
2128 switch (lp -> m_type) {
2130 mbox = lp -> m_mbox;
2131 host = LocalName ();
2132 (void) strcpy (addr, mbox);
2137 mbox = concat (lp -> m_host, "!", lp -> m_mbox, NULLCP);
2139 (void) strcpy (addr, mbox);
2142 fprintf (talk ? stdout : stderr, " %s!%s: %s\n",
2143 lp -> m_host, lp -> m_mbox, "not supported; UUCP address");
2145 (void) fflush (stdout);
2149 default: /* let MMDF decide if the host is bad */
2150 mbox = lp -> m_mbox;
2151 host = lp -> m_host;
2152 (void) sprintf (addr, "%s at %s", mbox, host);
2156 if ((!whomsw || checksw)
2158 && seekaddr (mbox, host, reason) == NOTOK) {
2159 fprintf (talk ? stdout : stderr, " %s%s: %s\n",
2160 addr, "[TMA]", reason);
2166 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
2168 if (whomsw && !checksw) {
2169 (void) putchar ('\n');
2174 (void) fflush (stdout);
2180 path = concat (lp -> m_path, mbox, "@@", host, NULLCP);
2184 if (rp_isbad (retval = mm_wadr (path ? NULLCP : host, path ? path : mbox))
2185 || rp_isbad (retval = mm_rrply (&reply, &len)))
2186 die (NULLCP, "problem submitting address [%s]", rp_valstr (retval));
2188 switch (rp_gval (reply.rp_val)) {
2191 printf ("address ok\n");
2192 (void) fflush (stdout);
2198 printf ("nameserver timeout - queued for checking\n");
2199 (void) fflush (stdout);
2209 text = "temporary nameserver failure";
2216 text = "not deliverable";
2220 text = "try again later";
2224 text = "nothing done";
2229 fprintf (stderr, " %s: ", addr);
2230 text = "unexpected response";
2231 die (NULLCP, "%s;\n [%s] -- %s", text,
2232 rp_valstr (reply.rp_val), reply.rp_line);
2236 fprintf (stderr, " %s: ", addr);
2237 fprintf (talk ? stdout : stderr, "%s;\n %s\n", text, reply.rp_line);
2240 (void) fflush (stdout);
2242 #endif /* MMDFMTS */
2249 static do_an_address (lp, talk, tma)
2250 register struct mailname *lp;
2254 register char *mbox;
2257 switch (lp -> m_type) {
2259 (void) strcpy (addr, lp -> m_mbox);
2263 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
2267 (void) sprintf (addr, "%s at %s", lp -> m_mbox, lp -> m_host);
2271 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
2273 if (whomsw && !checksw) {
2274 (void) putchar ('\n');
2279 (void) fflush (stdout);
2283 switch (lp -> m_type) {
2285 mbox = lp -> m_mbox;
2288 if (seek_home (mbox)) {
2289 lp -> m_mbox = mbox;
2291 printf ("address ok\n");
2295 fprintf (stderr, " %s: ", addr);
2296 fprintf (talk ? stdout : stderr,
2297 "not deliverable; unknown user\n");
2303 if (uucpsite (lp -> m_host) == OK) {
2305 printf ("address ok\n");
2309 fprintf (stderr, " %s: ", addr);
2310 fprintf (talk ? stdout : stderr,
2311 "not deliverable; unknown system\n");
2318 printf ("address ok\n");
2323 fprintf (stderr, " %s: ", addr);
2324 fprintf (talk ? stdout : stderr,
2325 "not deliverable; unknown host\n");
2330 (void) fflush (stdout);
2342 static do_an_address (lp, talk, tma)
2343 register struct mailname *lp;
2348 register char *mbox,
2352 char reason[BUFSIZ];
2355 switch (lp -> m_type) {
2357 mbox = lp -> m_mbox;
2358 host = lp -> m_host;
2359 (void) strcpy (addr, mbox);
2363 mbox = auxformat (lp, 0);
2365 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
2368 default: /* let SendMail decide if the host is bad */
2369 mbox = lp -> m_mbox;
2370 host = lp -> m_host;
2371 (void) sprintf (addr, "%s at %s", mbox, host);
2376 if ((!whomsw || checksw)
2378 && seekaddr (mbox, host, reason) == NOTOK) {
2379 fprintf (talk ? stdout : stderr, " %s%s: %s\n",
2380 addr, "[TMA]", reason);
2386 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
2388 if (whomsw && !checksw) {
2389 (void) putchar ('\n');
2394 (void) fflush (stdout);
2398 switch (retval = sm_wadr (mbox, host,
2399 lp -> m_type != UUCPHOST ? lp -> m_path : NULLCP)) {
2402 printf ("address ok\n");
2408 fprintf (stderr, " %s: ", addr);
2409 fprintf (talk ? stdout : stderr, "loses; %s\n",
2410 rp_string (retval));
2416 fprintf (stderr, " %s: ", addr);
2417 die (NULLCP, "unexpected response; %s", rp_string (retval));
2420 (void) fflush (stdout);
2422 #endif /* SENDMTS */
2424 /*
\f SIGNAL HANDLING */
2430 static TYPESIG sigser (i)
2434 (void) signal (i, SIG_IGN);
2435 #endif /* not BSD42 */
2436 (void) unlink (tmpfil);
2437 if (msgflags & MINV)
2438 (void) unlink (bccfil);
2440 if (!whomsw || checksw)
2441 (void) mm_end (NOTOK);
2442 #endif /* MMDFMTS */
2444 if (!whomsw || checksw)
2445 (void) sm_end (NOTOK);
2446 #endif /* SENDMTS */
2449 #endif /* not MHMTS */
2457 setsigx (hstat, SIGHUP, sigser);
2458 setsigx (istat, SIGINT, sigser);
2459 setsigx (qstat, SIGQUIT, sigser);
2460 setsigx (tstat, SIGTERM, sigser);
2462 setsigx (hstat, SIGHUP, SIG_IGN);
2463 setsigx (istat, SIGINT, SIG_IGN);
2464 setsigx (qstat, SIGQUIT, SIG_IGN);
2465 setsigx (tstat, SIGTERM, SIG_IGN);
2474 (void) signal (SIGHUP, hstat);
2475 (void) signal (SIGINT, istat);
2476 (void) signal (SIGQUIT, qstat);
2477 (void) signal (SIGTERM, tstat);
2480 /*
\f FCC INTERACTION */
2482 static p_refile (file)
2483 register char *file;
2491 (void) setuid (myuid);
2494 printf (" -- Filing Folder Copies --\n");
2495 for (i = 0; i < fccind; i++)
2496 fcc (file, fccfold[i]);
2498 printf (" -- Folder Copies Filed --\n");
2502 static fcc (file, folder)
2503 register char *file,
2512 printf (" %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder);
2513 (void) fflush (stdout);
2515 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
2520 fprintf (stderr, " %sFcc %s: ",
2521 msgstate == RESENT ? "Resent-" : "", folder);
2522 fprintf (verbose ? stdout : stderr, "no forks, so not ok\n");
2526 (void) sprintf (fold, "%s%s",
2527 *folder == '+' || *folder == '@@' ? "" : "+", folder);
2528 execlp (fileproc, r1bindex (fileproc, '/'),
2529 "-link", "-file", file, fold, NULLCP);
2533 if (status = pidwait (child_id, OK)) {
2535 fprintf (stderr, " %sFcc %s: ",
2536 msgstate == RESENT ? "Resent-" : "", folder);
2537 (void) pidstatus (status, verbose ? stdout : stderr, NULLCP);
2541 printf ("folder ok\n");
2544 (void) fflush (stdout);
2547 /*
\f RECORD RECIPIENTS */
2554 char recfile[BUFSIZ];
2555 register struct mailname *ap,
2557 struct mailname *addrs[3];
2560 if (!record || (msgflags & (MFRM | MRFM | MRPY)))
2563 addrs[0] = &localaddrs;
2564 addrs[1] = &netaddrs;
2567 printf ("recording recipients... ");
2571 (void) strcpy (recfile, m_tmpfil ("record"));
2572 if ((out = fopen (recfile, "w")) == NULL) {
2573 fprintf (verbose ? stdout : stderr, "unable to create temporary file");
2575 fprintf (stderr, ", so can't record recipients");
2576 fprintf (verbose ? stdout : stderr, "\n");
2579 (void) chmod (recfile, 0600);
2581 for (app = addrs; ap = *app; app++) {
2582 register struct mailname *mp;
2584 for (mp = ap -> m_next; mp; mp = mp -> m_next)
2585 fprintf (out, "%s\n", adrformat (mp));
2588 (void) fclose (out);
2590 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
2594 fprintf (verbose ? stdout : stderr, "unable to fork");
2596 fprintf (stderr, ", so can't record recipients");
2597 fprintf (verbose ? stdout : stderr, "\n");
2601 execlp (record, r1bindex (record, '/'), recfile, NULLCP);
2605 if (status = pidwait (child_id, OK)) {
2607 fprintf (stderr, "problem with %s: ", recfile);
2608 (void) pidstatus (status, verbose ? stdout : stderr, NULLCP);
2615 (void) unlink (recfile);
2618 /*
\f TERMINATION */
2622 static die (what, fmt, a, b, c, d)
2631 (void) unlink (tmpfil);
2632 if (msgflags & MINV)
2633 (void) unlink (bccfil);
2636 if (!whomsw || checksw)
2637 (void) mm_end (NOTOK);
2638 #endif /* MMDFMTS */
2640 if (!whomsw || checksw)
2641 (void) sm_end (NOTOK);
2642 #endif /* SENDMTS */
2644 adios (what, fmt, a, b, c, d);
2650 * err_abrt() is used by the mm_ routines
2651 * do not, under *ANY* circumstances, remove it from post,
2652 * or you will lose *BIG*
2655 err_abrt (code, fmt, a, b, c)
2662 char buffer[BUFSIZ];
2664 (void) sprintf (buffer, "[%s]", rp_valstr (code));
2666 adios (buffer, fmt, a, b, c);
2668 #endif /* MMDFMTS */
2670 /*
\f STAND-ALONE DELIVERY */
2674 /* BUG: MHMTS ignores 822-style route addresses... */
2676 static localmail (lp, talk, fd)
2677 register struct mailname *lp;
2682 char mailbox[BUFSIZ],
2684 register struct home *hp;
2687 printf (" %s: ", lp -> m_mbox);
2688 (void) fflush (stdout);
2690 if ((hp = seek_home (lp -> m_mbox)) == NULL) {
2692 fprintf (stderr, " %s: ", lp -> m_mbox);
2693 fprintf (talk ? stdout : stderr,
2694 "not deliverable; unknown address\n");
2699 (void) sprintf (mailbox, "%s/%s",
2700 mmdfldir[0] ? mmdfldir : hp -> h_home,
2701 mmdflfil[0] ? mmdflfil : hp -> h_name);
2705 switch (access (slocalproc, 01)) {
2708 printf ("(invoking hook)\n\t");
2709 (void) fflush (stdout);
2711 if (usr_hook (lp, talk, fd, hp, mailbox) != NOTOK)
2714 printf (" %s: ", lp -> m_mbox);
2715 (void) fflush (stdout);
2718 (void) lseek (fd, (off_t)0, 0);
2719 if ((md = mbx_open (mailbox, hp -> h_uid, hp -> h_gid, m_gmprot ()))
2722 fprintf (stderr, " %s: ", lp -> m_mbox);
2723 fprintf (talk ? stdout : stderr,
2724 "error in transmission; unable to open maildrop\n");
2728 (void) sprintf (ddate, "Delivery-Date: %s\n", dtimenow ());
2729 if (mbx_copy (mailbox, md, fd, 0, ddate, 0) == NOTOK) {
2731 fprintf (stderr, " %s: ", lp -> m_mbox);
2732 fprintf (talk ? stdout : stderr,
2733 "error in transmission; write to maildrop failed\n");
2738 mbx_close (mailbox, md);
2745 (void) fflush (stdout);
2750 static int usr_hook (lp, talk, fd, hp, mailbox)
2751 register struct mailname *lp;
2754 register struct home *hp;
2755 register char *mailbox;
2760 char tmpfil[BUFSIZ];
2762 if ((fd = copyfile (fd, tmpfil)) == NOTOK) {
2764 fprintf (stderr, " %s: ", lp -> m_mbox);
2765 fprintf (talk ? stdout : stderr,
2766 "unable to copy message; skipping hook\n");
2769 (void) chown (tmpfil, hp -> h_uid, hp -> h_gid);
2771 (void) fflush (stdout);
2773 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
2778 fprintf (stderr, " %s: ", lp -> m_mbox);
2779 fprintf (talk ? stdout : stderr,
2780 "unable to invoke hook; fork() failed\n");
2785 (void) dup2 (fd, 0);
2786 (void) freopen ("/dev/null", "w", stdout);
2787 (void) freopen ("/dev/null", "w", stderr);
2788 if (fd != 3) /* backwards compatible... */
2789 (void) dup2 (fd, 3);
2792 if ((fd = open ("/dev/tty", 2)) != NOTOK) {
2793 (void) ioctl (fd, TIOCNOTTY, NULLCP);
2796 #endif /* TIOCNOTTY */
2798 (void) setpgrp (0, getpid ());
2802 (void) m_putenv ("USER", hp -> h_name);
2803 (void) m_putenv ("HOME", hp -> h_home);
2804 (void) m_putenv ("SHELL", hp -> h_shell);
2805 if (chdir (hp -> h_home) == NOTOK)
2807 (void) umask (0077);
2809 (void) inigrp (hp -> h_name, hp -> h_gid);
2811 (void) setgid (hp -> h_gid);
2813 (void) initgroups (hp -> h_name, hp -> h_gid);
2815 (void) setuid (hp -> h_uid);
2817 execlp (slocalproc, r1bindex (slocalproc, '/'),
2818 "-file", tmpfil, "-mailbox", mailbox,
2819 "-home", hp -> h_home, "-addr", lp -> m_aka,
2820 "-user", hp -> h_name, "-sender", from,
2821 talk ? "-verbose" : NULLCP, NULLCP);
2829 status = pidwait (child_id, OK);
2831 (void) unlink (tmpfil);
2834 printf ("accepted\n");
2838 fprintf (stderr, " %s: ", lp -> m_mbox);
2839 fprintf (talk ? stdout : stderr,
2840 "%s error on hook; status=0%o\n",
2841 status & 0x00ff ? "system" : "user",
2842 status & 0x00ff ? status & 0xff
2843 : (status & 0xff00) >> 8);
2850 static int copyfile (qd, tmpfil)
2852 register char *tmpfil;
2856 char buffer[BUFSIZ];
2858 (void) strcpy (tmpfil, m_tmpfil ("hook"));
2859 if ((fd = creat (tmpfil, 0600)) == NOTOK)
2862 if ((fd = open (tmpfil, 2)) == NOTOK)
2865 (void) lseek (qd, (off_t)0, 0);
2866 while ((i = read (qd, buffer, sizeof buffer)) > 0)
2867 if (write (fd, buffer, i) != i) {
2876 (void) lseek (fd, (off_t)0, 0);
2883 static uucpmail (lp, talk, fd, from)
2884 register struct mailname *lp;
2890 TYPESIG (*pstat) ();
2895 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
2897 printf (" %s: ", addr);
2898 (void) fflush (stdout);
2901 (void) sprintf (buffer, "uux -r -p %s!rmail \\(%s\\)",
2902 lp -> m_host, lp -> m_mbox);
2904 (void) sprintf (buffer, "uux -p %s!rmail \\(%s\\)", lp -> m_host,
2907 if ((fp = popen (buffer, "w")) == NULL) {
2909 fprintf (stderr, " %s: ", addr);
2910 fprintf (talk ? stdout : stderr,
2911 "unable to start uux; popen() failed\n");
2916 pstat = signal (SIGPIPE, SIG_IGN);
2917 if (from) { /* no mail filtering, so... */
2918 (void) sprintf (buffer, "From %s %.24s remote from %s\n",
2919 getusr (), ctime (&tclock), SystemName ());
2920 i = strlen (buffer);
2921 if (fwrite (buffer, sizeof *buffer, i, fp) != i)
2925 (void) lseek (fd, (off_t)0, 0);
2926 while ((i = read (fd, buffer, sizeof buffer)) > 0)
2927 if (fwrite (buffer, sizeof *buffer, i, fp) != i) {
2930 fprintf (stderr, " %s: ", addr);
2931 fprintf (talk ? stdout : stderr,
2932 "error in transmission; write to uux failed\n");
2939 (void) signal (SIGPIPE, pstat);
2943 fprintf (stderr, " %s: ", addr);
2944 fprintf (talk ? stdout : stderr,
2945 "error in transmission; read failed\n");
2951 printf ("queued (via uux)\n");
2952 (void) fflush (stdout);
2958 static int make_uucp_file (td)
2964 char tmpfil[BUFSIZ];
2966 (void) lseek (td, (off_t)0, 0);
2967 if ((qd = dup (td)) == NOTOK)
2968 adios ("fd", "unable to dup");
2970 (void) strcpy (tmpfil, m_tmpfil ("uumf"));
2971 if ((fd = creat (tmpfil, 0600)) == NOTOK)
2972 adios (tmpfil, "unable to create");
2974 if ((fd = open (tmpfil, 2)) == NOTOK)
2975 adios (tmpfil, "unable to re-open");
2977 switch (i = mmdf2uucp (qd, fd, 1)) {
2980 (void) unlink (tmpfil);
2984 adios (NULLCP, "unable to filter mail(%d), examine %s", i, tmpfil);
2994 static netmail (talk, fd, bccque)
3001 char buffer[BUFSIZ];
3002 register struct mailname *lp;
3005 if (nm_init (getusr (), &tclock) == NOTOK) {
3006 for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
3007 if (lp -> m_bcc ? bccque : !bccque)
3008 fprintf (stderr, " %s at %s: unable to get queue file\n",
3009 lp -> m_mbox, lp -> m_host);
3013 for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
3014 if (lp -> m_bcc ? bccque : !bccque) {
3015 (void) nm_wadr (lp -> m_mbox, lp -> m_host);
3018 printf (" %s at %s: queued\n", lp -> m_mbox, lp -> m_host);
3019 (void) fflush (stdout);
3023 (void) lseek (fd, (off_t)0, 0);
3024 while ((i = read (fd, buffer, sizeof buffer)) > 0)
3025 if (nm_wtxt (buffer, i) == NOTOK) {
3027 "error in transmission; write to temporary failed");
3033 fprintf (stderr, "error in transmission; read failed\n");
3038 if (nm_wtend () == NOTOK) {
3039 fprintf (stderr, "error in transmission; unable to queue message\n");
3055 static char ident[] = "@@(#)$Id: post.c,v 2.24 1994/04/21 19:23:38 jromine Exp jromine $";
3058 "check", -5, /* interface from whom */
3061 "nocheck", -7, /* interface from whom */
3072 static char ident[] = "@@(#)$Id: post.c,v 2.23 1993/08/25 17:26:51 jromine Exp jromine $";
3077 "Reply-To", HADR | HNGR, 0,
3080 "Resent-Reply-To", HADR | HNGR, 0,
3083 "Reply-To", HADR, 0,
3088 static sigoff(), p_refile(), fcc(), die(), insert_fcc();
3094 if (hdr -> flags & HNIL)
3095 fprintf (out, "%s: %s", name, str);
3098 fprintf (out, "From: %s\n", signature);
3101 fprintf (out, "%s\"\n%s: %s\n\n--%s\n%s: %s\n\n", prefix, DESCR_FIELD,
3102 "Blind Carbon Copy", prefix, DESCR_FIELD, "Original Message");
3109 @off_t fixes for BSD44
3114 static char ident[] = "@@(#)$Id: post.c,v 2.22 1993/08/20 15:53:20 jromine Exp jromine $";
3117 fprintf (out, "Message-ID: <%d.%ld@@%s>\n",
3120 fprintf (out, "%s\"\n\n--%s\n\n", prefix, prefix);
3127 make use of ONEX SMTP command
3132 static char ident[] = "@@(#)$Id: post.c,v 2.21 1992/12/15 00:20:22 jromine Exp jromine $";
3135 long lseek (), time ();
3138 (void) lseek (fd, 0L, 0);
3141 (void) lseek (fd, 0L, 0);
3144 (void) lseek (qd, 0L, 0);
3147 (void) lseek (fd, 0L, 0);
3150 (void) lseek (fd, 0L, 0);
3153 (void) lseek (td, 0L, 0);
3156 (void) lseek (fd, 0L, 0);
3167 static char ident[] = "@@(#)$Id: post.c,v 2.20 1992/11/24 19:02:24 jromine Exp jromine $";
3173 if (rp_isbad (retval = sm_init (clientsw, serversw, 0, 0, snoop))
3179 if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop))
3182 (void) sm_end (!(msgflags & MINV) || bccque ? OK : DONE);
3185 if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop))
3196 static char ident[] = "@@(#)$Id: post.c,v 2.19 1992/11/19 23:24:00 jromine Exp jromine $";
3625 @fix bug in blind list handling
3630 static char ident[] = "@@(#)$Id: post.c,v 2.18 1992/11/04 02:58:40 jromine Exp $";
3642 static char ident[] = "@@(#)$Id: post.c,v 2.17 1992/11/04 00:55:52 jromine Exp jromine $";
3646 if (mp -> m_ingrp = np -> m_ingrp)
3653 putgrp (namep, mp -> m_gname, out, hdr -> flags);
3666 static char ident[] = "@@(#)$Id: post.c,v 2.16 1992/10/16 23:55:56 jromine Exp jromine $";
3669 (void) putenv ("USER", hp -> h_name);
3670 (void) putenv ("HOME", hp -> h_home);
3671 (void) putenv ("SHELL", hp -> h_shell);
3682 static char ident[] = "@@(#)$Id: post.c,v 2.15 1992/10/16 21:37:31 jromine Exp jromine $";
3686 #define uptolow(c) (isupper (c) ? tolower (c) : (c))
3693 static int sigser (i)
3704 static char ident[] = "@@(#)$Id: post.c,v 2.14 1992/03/02 17:06:14 jromine Exp jromine $";
3718 static char ident[] = "@@(#)$Id: post.c,v 2.13 1992/01/31 22:23:44 jromine Exp jromine $";
3741 #define WHOMSW 18 /* interface from whom */
3762 #define ANNOSW 25 /* interface from send */
3790 fprintf (out, "BCC:\n\n------- Blind-Carbon-Copy\n\n");
3793 adios (NULLCP, "unable to re-open");
3794 cpydgst (fd, fileno (out), tmpfil, bccfil);
3797 fprintf (out, "\n------- End of Blind-Carbon-Copy\n");
3809 static char ident[] = "@@(#)$Id: post.c,v 2.12 1992/01/31 16:34:06 jromine Exp jromine $";
3824 static char ident[] = "@@(#)$Id: post.c,v 2.11 1992/01/30 22:39:58 jromine Exp $";
3830 "Return-Path", HBAD, NULL,
3831 "Received", HBAD, NULL,
3832 "Reply-To", HADR | HNGR, NULL,
3835 "Sender", HADR | HBAD, NULL,
3837 "Subject", HSUB, NULL,
3840 "Message-ID", HBAD, NULL,
3844 "Resent-Reply-To", HADR | HNGR, NULL,
3847 "Resent-Sender", HADR | HBAD, NULL,
3848 "Resent-Date", HBAD, NULL,
3849 "Resent-Subject", HSUB, NULL,
3852 "Resent-Message-ID", HBAD, NULL,
3853 "Resent-Fcc", HFCC, NULL,
3854 "Reply-To", HADR, NULL,
3857 "Sender", HADR | HMNG | HNGR, NULL,
3860 "Sender", HADR | HNGR, NULL,
3863 "To", HADR | HNIL, NULL,
3864 "cc", HADR | HNIL, NULL,
3865 "Bcc", HADR | HTRY | HBCC | HNIL, NULL,
3869 static anno(), insert_foc(), make_bcc_file(), verify_all_addresses();
3890 static char ident[] = "@@(#)$Id: post.c,v 2.10 1992/01/29 23:54:10 jromine Exp jromine $";
3896 if ((out = fopen ("/dev/null", "w")) == NULL)
3902 verify_all_addresses (1);
3905 printf ("Message Processed\n");
3908 if (hdr -> flags & HIGN)
3912 advise (NULLCP, "illegal header line -- %s:", name);
3917 (hdr -> flags & HMNG) ? "Original-" : "", name);
3932 if ((flags & (HBCC|HDCC)) || mp -> m_ingrp)
3942 cp = concat (group, ";", NULLCP);
3948 @bug fix for groups in alias files (yea!)
3953 static char ident[] = "@@(#)$Id: post.c,v 2.9 1992/01/24 00:05:24 jromine Exp jromine $";
3960 extern int do_wp; /* fill-in white pages queries */
3962 static char *fill_in = NULLCP;
3969 if (!(fill_in = *argp++) || *fill_in == '-')
3970 adios (NULLCP, "missing argument to %s", argp[-2]);
3979 if ((out = fopen (fill_in ? fill_in : "/dev/null", "w")) == NULL)
3982 if (whomsw && !fill_in)
3985 if (hdr -> flags & HIGN) {
3987 fprintf (out, "%s: %s", name, str);
3993 fprintf (out, "%s: %s", name, str);
3995 advise (NULLCP, "illegal header line -- %s:", name);
4000 fprintf (out, "%s: %s", name, str);
4006 !fill_in && (hdr -> flags & HMNG) ? "Original-" : "",
4011 if (fill_in && grp > 0)
4012 (void) putc (';', out);
4017 if (!fill_in && ((flags & (HBCC|HDCC)) || mp -> m_ingrp))
4020 if (mp -> m_gname && !fill_in)
4023 if (!fill_in && (flags & HBCC))
4026 linepos -= strlen (group);
4029 cp = fill_in ? group : concat (group, ";", NULLCP);
4035 @"clock" -> "tclock" (reserved word on ncr)
4040 static char ident[] = "@@(#)$Id: post.c,v 2.8 1990/04/05 15:35:20 sources Exp jromine $";
4043 if (mp -> m_ingrp = np -> m_ingrp)
4055 static char ident[] = "@@(#)$Id:$";
4058 static long clock = 0L; /* the time we started (more or less) */
4061 (void) time (&clock);
4064 fprintf (out, "Date: %s\n", dtime (&clock));
4067 getpid (), clock, LocalName ());
4070 fprintf (out, "Resent-Date: %s\n", dtime (&clock));
4073 getpid (), clock, LocalName ());
4076 fprintf (out, "Date: %s\n", dtime (&clock));
4079 getpid (), clock, LocalName ());
4082 getusr (), ctime (&clock), SystemName ());
4085 if (nm_init (getusr (), &clock) == NOTOK) {
4096 static char ident[] = "@@(#)$Id:";
4116 static sigoff(), p_refile(), fcc(), die();
4122 @"refile" -> "p_refile()"
4138 static sigoff(), refile(), fcc(), die();
4144 static refile (file)
4168 if ((out = fopen ("/dev/null", "w")) == NULL)
4174 if (hdr -> flags & HIGN)
4178 advise (NULLCP, "illegal header line -- %s:", name);
4183 (hdr -> flags & HMNG) ? "Original-" : "", name);
4190 if ((flags & (HBCC|HDCC)) || mp -> m_ingrp)
4196 if (flags & (HBCC|HDCC))
4200 cp = concat (group, ";", NULLCP);
4203 if (linepos != nameoutput)
4209 @changes for SUN40 shared libraries and NNTP under bbc
4214 static int (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
4220 @add "Dcc:" header line. This is basically a blind distribution copy.
4221 addresses listed on Dcc: lines are put in the envelope only!
4222 I don't intend to document this since Bcc: is the socially appropriate
4223 header to use for such copies.
4229 #define HDCC 0x0400 /* oh joy, another undocumented feature */
4242 if ((flags & HBCC) || mp -> m_ingrp)