1 /* post.c - enter messages into the transport system */
3 static char ident[] = "@(#)$Id: post.c,v 2.26 1996/02/10 00:22:14 jromine Exp $";
7 #include "../h/addrsbr.h"
8 #include "../h/aliasbr.h"
9 #include "../h/dropsbr.h"
10 #include "../zotnet/tws.h"
16 #include <sys/types.h>
18 #include "../mts/mmdf/util.h"
19 #include "../mts/mmdf/mmdf.h"
21 #include "../zotnet/mts.h"
24 #include <sys/ioctl.h>
29 #include "../mts/sendmail/smail.h"
42 #define uptolow(c) ((isalpha(c) && isupper (c)) ? tolower (c) : (c))
43 #endif /* not MMDFMTS */
45 #define FCCS 10 /* max number of fccs allowed */
50 #define MIMEminc(a) (a)
56 #define TMAminc(a) (a)
61 static struct swit switches[] = {
66 "check", -1, /* interface from whom */
68 "nocheck", -3, /* interface from whom */
74 "dist", -4, /* interface from dist */
77 "encrypt", TMAminc (-7),
79 "noencrypt", TMAminc (-9),
82 "filter filterfile", 0,
91 #define LIBSW 11 /* interface from send, whom */
92 "library directory", -7,
97 "nomime", MIMEminc(-6),
114 #define WHOMSW 20 /* interface from whom */
132 #define ANNOSW 27 /* interface from send */
136 "deliver address-list", -7,
156 "record program", -6,
169 #define HNOP 0x0000 /* just used to keep .set around */
170 #define HBAD 0x0001 /* bad header - don't let it through */
171 #define HADR 0x0002 /* header has an address field */
172 #define HSUB 0x0004 /* Subject: header */
173 #define HTRY 0x0008 /* try to send to addrs on header */
174 #define HBCC 0x0010 /* don't output this header */
175 #define HMNG 0x0020 /* munge this header */
176 #define HNGR 0x0040 /* no groups allowed in this header */
177 #define HFCC 0x0080 /* FCC: type header */
178 #define HNIL 0x0100 /* okay for this header not to have addrs */
179 #define HIGN 0x0200 /* ignore this header */
180 #define HDCC 0x0400 /* another undocumented feature */
183 #define MFRM 0x0001 /* we've seen a From: */
184 #define MDAT 0x0002 /* we've seen a Date: */
185 #define MRFM 0x0004 /* we've seen a Resent-From: */
186 #define MVIS 0x0008 /* we've seen sighted addrs */
187 #define MINV 0x0010 /* we've seen blind addrs */
188 #define MRPY 0x0020 /* we've seen a Reply-to: */
193 static struct headers NHeaders[] = {
194 "Return-Path", HBAD, 0,
196 "Reply-To", HADR | HNGR, MRPY,
197 "From", HADR | HNGR, MFRM,
198 "Sender", HADR | HBAD, 0,
201 "To", HADR | HTRY, MVIS,
202 "cc", HADR | HTRY, MVIS,
203 "Bcc", HADR | HTRY | HBCC | HNIL, MINV,
204 "Dcc", HADR | HTRY | HDCC | HNIL, MVIS, /* sorta cc & bcc combined */
205 "Message-ID", HBAD, 0,
211 static struct headers RHeaders[] = {
212 "Resent-Reply-To", HADR | HNGR, MRPY,
213 "Resent-From", HADR | HNGR, MRFM,
214 "Resent-Sender", HADR | HBAD, 0,
215 "Resent-Date", HBAD, 0,
216 "Resent-Subject", HSUB, 0,
217 "Resent-To", HADR | HTRY, MVIS,
218 "Resent-cc", HADR | HTRY, MVIS,
219 "Resent-Bcc", HADR | HTRY | HBCC, MINV,
220 "Resent-Message-ID", HBAD, 0,
221 "Resent-Fcc", HFCC, 0,
222 "Reply-To", HADR, MRPY,
223 "From", HADR | HNGR, MFRM,
225 "Sender", HADR | HMNG | HNGR, 0,
226 #else /* not MMFDI */
227 "Sender", HADR | HNGR, 0,
228 #endif /* not MMDFI */
230 "To", HADR | HNIL, 0,
231 "cc", HADR | HNIL, 0,
232 "Bcc", HADR | HTRY | HBCC | HNIL, 0,
241 static short fccind = 0; /* index into fccfold[] */
242 static short outputlinelen = OUTPUTLINELEN;
244 static int pfd = NOTOK; /* fd to write annotation list to */
245 static int myuid= -1; /* my user id */
246 static int mygid= -1; /* my group id */
247 static int recipients = 0; /* how many people will get a copy */
248 static int unkadr = 0; /* how many of those were unknown */
249 static int badadr = 0; /* number of bad addrs */
250 static int badmsg = 0; /* message has bad semantics */
251 static int verbose = 0; /* spell it out */
252 static int format = 1; /* format addresses */
253 static int mime = 0; /* use MIME-style encapsulations */
254 static int msgid = 0; /* add msgid */
255 static int debug = 0; /* debugging post */
256 static int watch = 0; /* watch the delivery process */
257 static int whomsw = 0; /* we are whom not post */
258 static int checksw = 0; /* whom -check */
259 static int linepos=0; /* putadr()'s position on the line */
260 static int nameoutput=0; /* putadr() has output header name */
262 static unsigned msgflags = 0; /* what we've seen */
266 static int msgstate = NORMAL;
268 static long tclock = 0L; /* the time we started (more or less) */
270 static TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
272 static char tmpfil[BUFSIZ];
273 static char bccfil[BUFSIZ];
275 static char from[BUFSIZ]; /* my network address */
276 static char signature[BUFSIZ]; /* my signature */
277 static char *filter = NULL; /* the filter for BCC'ing */
278 static char *msgfrom = NULL; /* the From: field for Bcc'ing */
279 static char *subject = NULL; /* the subject field for BCC'ing */
280 static char *fccfold[FCCS]; /* foldernames for FCC'ing */
282 static struct headers *hdrtab; /* table for the message we're doing */
284 static struct mailname localaddrs={NULL}; /* local addrs */
285 static struct mailname netaddrs={NULL}; /* network addrs */
286 static struct mailname uuaddrs={NULL}; /* uucp addrs */
287 static struct mailname tmpaddrs={NULL}; /* temporary queue */
292 static char *submitmode = "m"; /* deliver to mailbox only */
293 static char submitopts[6] = "vl";/* initial options for submit */
297 static char *deliver = NULL;
299 extern char **environ;
305 static int smtpmode = S_MAIL;
306 static int snoop = 0;
307 static char *clientsw = NULL;
308 static char *serversw = NULL;
310 extern struct smtp sm_reply;
314 #define post(a,b,c) \
315 if (encryptsw) postcipher ((a), (b), (c)); else postplain ((a), (b), (c))
320 #define tmasnoop snoop
324 static int encryptsw = 0; /* encrypt it */
332 static char prefix[] = "----- =_aaaaaaaaaa";
333 static int find_prefix();
336 static int fill_up = 0;
337 static char *fill_in = NULLCP;
338 static char *partno = NULLCP;
340 static int queued = 0;
342 static char *record = NULLCP;
347 static putfmt(), start_headers(), finish_headers(), putgrp(), pl();
348 static anno(), make_bcc_file(), verify_all_addresses();
349 static chkadr(), do_addresses(), do_text(), do_an_address(), sigon();
350 static sigoff(), p_refile(), fcc(), die(), insert_fcc(), p_record ();
351 static int get_header(), putadr(), insert(), annoaux();
376 setlocale(LC_ALL, "");
378 invo_name = r1bindex (argv[0], '/');
380 mts_init (invo_name);
383 mmdf_init (invo_name);
389 while (cp = *argp++) {
391 switch (smatch (++cp, switches)) {
393 ambigsw (cp, switches);
396 adios (NULLCP, "-%s unknown", cp);
398 (void) sprintf (buf, "%s [switches] file", invo_name);
399 help (buf, switches);
403 if (!(cp = *argp++) || *cp == '-')
404 adios (NULLCP, "missing argument to %s", argp[-2]);
409 if (!(cp = *argp++) || *cp == '-')
410 adios (NULLCP, "missing argument to %s", argp[-2]);
412 if (access (libpath (cp), 04) == NOTOK)
413 adios (cp, "unable to read");
415 if ((state = alias (cp)) != AK_OK)
416 adios (NULLCP, "aliasing error in %s - %s",
417 cp, akerror (state));
436 if (!(filter = *argp++) || *filter == '-')
437 adios (NULLCP, "missing argument to %s", argp[-2]);
487 if (!(cp = *argp++) || *cp == '-')
488 adios (NULLCP, "missing argument to %s", argp[-2]);
489 if ((outputlinelen = atoi (cp)) < 10)
490 adios (NULLCP, "impossible width %d", outputlinelen);
501 if (!(cp = *argp++) || *cp == '-')
502 adios (NULLCP, "missing argument to %s", argp[-2]);
503 if ((pfd = atoi (cp)) <= 2)
504 adios (NULLCP, "bad argument %s %s", argp[-2], cp);
511 case SOMLSW: /* for right now, sigh... */
522 if (!(cp = *argp++) || *cp == '-')
523 adios (NULLCP, "missing argument to %s", argp[-2]);
532 if (!(deliver = *argp++) || *deliver == '-')
533 adios (NULLCP, "missing argument to %s", argp[-2]);
540 if (!(cp = *argp++) || *cp == '-')
541 adios (NULLCP, "missing argument to %s", argp[-2]);
560 if (!(clientsw = *argp++) || *clientsw == '-')
561 adios (NULLCP, "missing argument to %s", argp[-2]);
564 if (!(serversw = *argp++) || *serversw == '-')
565 adios (NULLCP, "missing argument to %s", argp[-2]);
573 if (!(fill_in = *argp++) || *fill_in == '-')
574 adios (NULLCP, "missing argument to %s", argp[-2]);
580 if (!(partno = *argp++) || *partno == '-')
581 adios (NULLCP, "missing argument to %s", argp[-2]);
589 if (!(record = *argp++) || *record == '-')
590 adios (NULLCP, "missing argument to %s", argp[-2]);
597 adios (NULLCP, "only one message at a time!");
602 (void) alias (AliasFile);
607 adios (NULLCP, "usage: %s [switches] file", invo_name);
609 if (outputlinelen < 10)
610 adios (NULLCP, "impossible width %d", outputlinelen);
613 if (access (msg, 04) == NOTOK)
614 adios (msg, "unable to read");
616 if ((in = fopen (msg, "r")) == NULL)
617 adios (msg, "unable to open");
622 discard (out = stdout); /* XXX: reference discard() to help loader */
625 (void) strcpy (tmpfil, msg);
626 putfmt ("To", deliver, out);
634 if ((out = fopen ("/dev/null", "r")) == NULL)
635 adios ("/dev/null", "unable to write");
636 (void) strcpy (tmpfil, msg);
637 putfmt ("To", deliver, out);
643 if ((out = fopen (fill_in ? fill_in : "/dev/null", "w")) == NULL)
644 adios ("/dev/null", "unable to open");
647 (void) strcpy (tmpfil, m_scratch ("", m_maildir (invo_name)));
648 if ((out = fopen (tmpfil, "w")) == NULL) {
649 (void) strcpy (tmpfil, m_tmpfil (invo_name));
650 if ((out = fopen (tmpfil, "w")) == NULL)
651 adios (tmpfil, "unable to create");
654 (void) chown (tmpfil, myuid, mygid);
656 (void) chmod (tmpfil, 0600);
661 hdrtab = msgstate == NORMAL ? NHeaders : RHeaders;
663 for (compnum = 1, state = FLD;;) {
664 switch (state = m_getfld (state, name, buf, sizeof buf, in)) {
669 cp = add (buf, NULLCP);
670 while (state == FLDPLUS) {
671 state = m_getfld (state, name, buf, sizeof buf, in);
674 putfmt (name, cp, out);
678 finish_headers (out);
683 finish_headers (out);
684 if (whomsw && !fill_in)
686 fprintf (out, "\n%s", buf);
687 while (state == BODY) {
688 state = m_getfld (state, name, buf, sizeof buf, in);
694 finish_headers (out);
699 adios (NULLCP, "message format error in component #%d",
703 adios (NULLCP, "getfld() returned %d", state);
729 verify_all_addresses (1);
734 (void) strcat (submitopts, submitmode);
736 (void) strcat (submitopts, "nw");
739 verify_all_addresses (0);
742 verify_all_addresses (verbose);
743 if (msgflags & MINV) {
745 if (msgflags & MVIS) {
748 verify_all_addresses (verbose);
749 #endif /* not MHMTS */
750 post (tmpfil, 0, verbose);
752 post (bccfil, 1, verbose);
753 (void) unlink (bccfil);
756 post (tmpfil, 0, isatty (1));
769 (void) unlink (tmpfil);
772 printf (partno ? "Partial Message #%s Processed\n" : "Message Processed\n",
778 /*
\f DRAFT GENERATION */
780 static putfmt (name, str, out)
793 register struct mailname *mp,
795 register struct headers *hdr;
797 while (*str == ' ' || *str == '\t')
800 if (msgstate == NORMAL && uprf (name, "resent")) {
801 advise (NULLCP, "illegal header line -- %s:", name);
806 if ((i = get_header (name, hdrtab)) == NOTOK) {
807 fprintf (out, "%s: %s", name, str);
812 if (hdr -> flags & HIGN) {
814 fprintf (out, "%s: %s", name, str);
817 if (hdr -> flags & HBAD) {
819 fprintf (out, "%s: %s", name, str);
821 advise (NULLCP, "illegal header line -- %s:", name);
826 msgflags |= (hdr -> set & ~(MVIS | MINV));
828 if (hdr -> set & MFRM)
829 msgfrom = msgfrom ? add (str, add (",", msgfrom)) : getcpy (str);
830 if (hdr -> flags & HSUB)
831 subject = subject ? add (str, add ("\t", subject)) : getcpy (str);
832 if (hdr -> flags & HFCC) {
834 fprintf (out, "%s: %s", name, str);
838 if (cp = rindex (str, '\n'))
840 for (cp = pp = str; cp = index (pp, ','); pp = cp) {
842 insert_fcc (hdr, pp);
844 insert_fcc (hdr, pp);
850 if (!(hdr -> flags & HADR)) {
851 fprintf (out, "%s: %s", name, str);
855 tmpaddrs.m_next = NULL;
856 for (count = 0; cp = getname (str); count++)
857 if (mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP)) {
861 tmpaddrs.m_next = mp;
865 if (hdr -> flags & HTRY)
871 if (hdr -> flags & HNIL) {
872 if (!(hdr -> flags & HBCC))
873 fprintf (out, "%s: %s", name, str);
877 advise (NULLCP, "%s: field requires at least one address", name);
886 nameoutput = linepos = 0;
887 (void) sprintf (namep, "%s%s",
888 !fill_in && (hdr -> flags & HMNG) ? "Original-" : "",
891 for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np)
892 if (mp -> m_nohost) { /* also used to test (hdr -> flags & HTRY) */
893 pp = akvalue (mp -> m_mbox);
894 qp = akvisible () ? mp -> m_mbox : "";
897 putgrp (namep, np -> m_gname, out, hdr -> flags);
898 while (cp = getname (pp)) {
899 if (!(mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP))) {
903 if (hdr -> flags & HBCC)
906 mp -> m_ingrp = np -> m_ingrp;
909 putgrp (namep, mp -> m_gname, out, hdr -> flags);
913 mp -> m_aka = getcpy (np -> m_mbox);
915 if (putadr (namep, qp, mp, out, hdr -> flags))
916 msgflags |= (hdr -> set & (MVIS | MINV));
925 if (hdr -> flags & HBCC)
928 putgrp (namep, mp -> m_gname, out, hdr -> flags);
931 keep = putadr (namep, "", mp, out, hdr -> flags);
935 msgflags |= (hdr -> set & (MVIS | MINV));
941 if (grp > 0 && (hdr -> flags & HNGR)) {
942 advise (NULLCP, "%s: field does not allow groups", name);
946 if (fill_in && grp > 0)
947 (void) putc (';', out);
948 (void) putc ('\n', out);
954 static start_headers () {
958 register struct mailname *mp;
962 (void) time (&tclock);
964 (void) strcpy (from, adrsprintf (NULLCP, NULLCP));
966 (void) strcpy (myhost, LocalName ());
967 for (cp = myhost; *cp; cp++)
972 if (geteuid () == 0 && myuid != 0 && myuid != 1 && mygid != 1)
973 adios (NULLCP, "-deliver unknown");
974 (void) strcpy (signature, from);
978 if ((cp = getfullname ()) && *cp) {
979 (void) strcpy (sigbuf, cp);
980 (void) sprintf (signature, "%s <%s>", sigbuf, adrsprintf (NULLCP, NULLCP));
981 if ((cp = getname (signature)) == NULL)
982 adios (NULLCP, "getname () failed -- you lose extraordinarily big");
983 if ((mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP)) == NULL)
984 adios (NULLCP, "bad signature '%s'", sigbuf);
990 (void) strcpy (signature, adrsprintf (NULLCP, NULLCP));
995 static finish_headers (out)
1000 if (whomsw && !fill_up)
1003 fprintf (out, "Date: %s\n", dtime (&tclock));
1005 fprintf (out, "Message-ID: <%d.%ld@%s>\n",
1006 getpid (), tclock, LocalName ());
1007 if (msgflags & MFRM)
1008 fprintf (out, "Sender: %s\n", from);
1010 fprintf (out, "From: %s\n", signature);
1014 if (!(msgflags & MVIS))
1015 fprintf (out, "Bcc: Blind Distribution List: ;\n");
1019 if (!(msgflags & MDAT)) {
1020 advise (NULLCP, "message has no Date: header");
1023 if (!(msgflags & MFRM)) {
1024 advise (NULLCP, "message has no From: header");
1027 if (whomsw && !fill_up)
1030 #ifdef MMDFI /* sigh */
1031 fprintf (out, "Sender: %s\n", from);
1034 fprintf (out, "Resent-Date: %s\n", dtime (&tclock));
1036 fprintf (out, "Resent-Message-ID: <%d.%ld@%s>\n",
1037 getpid (), tclock, LocalName ());
1038 if (msgflags & MRFM)
1039 fprintf (out, "Resent-Sender: %s\n", from);
1041 fprintf (out, "Resent-From: %s\n", signature);
1044 if (!(msgflags & MVIS))
1045 fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n");
1050 adios (NULLCP, "re-format message and try again");
1052 adios (NULLCP, "no addressees");
1057 static int get_header (header, table)
1058 register char *header;
1059 register struct headers *table;
1061 register struct headers *h;
1063 for (h = table; h -> value; h++)
1064 if (uleq (header, h -> value))
1072 static int putadr (name, aka, mp, out, flags)
1073 register char *name,
1075 register struct mailname *mp;
1081 char buffer[BUFSIZ];
1083 if (mp -> m_mbox == NULL || ((flags & HTRY) && !insert (mp)))
1085 if (!fill_in && (flags & (HBCC | HDCC)) || mp -> m_ingrp)
1089 fprintf (out, "%s: ", name);
1090 linepos += (nameoutput = strlen (name) + 2);
1093 if (*aka && mp -> m_type != UUCPHOST && !mp -> m_pers)
1094 mp -> m_pers = getcpy (aka);
1096 if (mp -> m_gname && !fill_in)
1097 (void) sprintf (cp = buffer, "%s;", mp -> m_gname);
1099 cp = adrformat (mp);
1105 if (linepos != nameoutput)
1106 if (len + linepos + 2 > outputlinelen)
1107 fprintf (out, ",\n%*s", linepos = nameoutput, "");
1116 return (flags & HTRY);
1121 static putgrp (name, group, out, flags)
1122 register char *name,
1130 if (!fill_in && (flags & HBCC))
1134 fprintf (out, "%s: ", name);
1135 linepos += (nameoutput = strlen (name) + 2);
1137 linepos -= strlen (group);
1140 cp = fill_in ? group : concat (group, ";", NULLCP);
1143 if (linepos > nameoutput)
1144 if (len + linepos + 2 > outputlinelen) {
1145 fprintf (out, ",\n%*s", nameoutput, "");
1146 linepos = nameoutput;
1159 static int insert (np)
1160 register struct mailname *np;
1162 register struct mailname *mp;
1164 if (np -> m_mbox == NULL)
1167 for (mp = np -> m_type == LOCALHOST ? &localaddrs
1168 : np -> m_type == UUCPHOST ? &uuaddrs
1172 if (uleq (np -> m_host, mp -> m_next -> m_host)
1173 && uleq (np -> m_mbox, mp -> m_next -> m_mbox)
1174 && np -> m_bcc == mp -> m_next -> m_bcc)
1185 register struct mailname *mp;
1187 printf ("-------\n\t-- Addresses --\nlocal:\t");
1188 for (mp = localaddrs.m_next; mp; mp = mp -> m_next)
1189 printf ("%s%s%s", mp -> m_mbox,
1190 mp -> m_bcc ? "[BCC]" : "",
1191 mp -> m_next ? ",\n\t" : "");
1193 printf ("\nnet:\t");
1194 for (mp = netaddrs.m_next; mp; mp = mp -> m_next)
1195 printf ("%s%s@%s%s%s", mp -> m_path ? mp -> m_path : "",
1196 mp -> m_mbox, mp -> m_host,
1197 mp -> m_bcc ? "[BCC]" : "",
1198 mp -> m_next ? ",\n\t" : "");
1200 printf ("\nuucp:\t");
1201 for (mp = uuaddrs.m_next; mp; mp = mp -> m_next)
1202 printf ("%s!%s%s", mp -> m_host, mp -> m_mbox,
1203 mp -> m_bcc ? "[BCC]" : "",
1204 mp -> m_next ? ",\n\t" : "");
1206 printf ("\n\t-- Folder Copies --\nfcc:\t");
1207 for (i = 0; i < fccind; i++)
1208 printf ("%s%s", fccfold[i], i + 1 < fccind ? ",\n\t" : "");
1215 register struct mailname *mp;
1217 for (mp = localaddrs.m_next; mp; mp = mp -> m_next)
1218 if (annoaux (mp) == NOTOK)
1221 for (mp = netaddrs.m_next; mp; mp = mp -> m_next)
1222 if (annoaux (mp) == NOTOK)
1225 for (mp = uuaddrs.m_next; mp; mp = mp -> m_next)
1226 if (annoaux (mp) == NOTOK)
1235 static int annoaux (mp)
1236 register struct mailname *mp;
1239 char buffer[BUFSIZ];
1241 (void) sprintf (buffer, "%s\n", adrformat (mp));
1242 i = strlen (buffer);
1244 return (write (pfd, buffer, i) == i ? OK : NOTOK);
1249 static insert_fcc (hdr, pp)
1250 register struct headers *hdr;
1255 for (cp = pp; isspace (*cp); cp++)
1257 for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--)
1265 adios (NULLCP, "too many %ss", hdr -> value);
1266 fccfold[fccind++] = getcpy (cp);
1269 /*
\f BCC GENERATION */
1271 static make_bcc_file () {
1278 (void) strcpy (bccfil, m_tmpfil ("bccs"));
1279 if ((out = fopen (bccfil, "w")) == NULL)
1280 adios (bccfil, "unable to create");
1281 (void) chmod (bccfil, 0600);
1283 fprintf (out, "Date: %s\n", dtime (&tclock));
1285 fprintf (out, "Message-ID: <%d.%ld.1@%s>\n",
1286 getpid (), tclock, LocalName ());
1287 if (msgflags & MFRM) {
1288 fprintf (out, "From: %s", msgfrom);
1289 fprintf (out, "Sender: %s\n", from);
1292 fprintf (out, "From: %s\n", signature);
1294 fprintf (out, "Subject: %s", subject);
1295 fprintf (out, "BCC:\n");
1300 if ((cp = index (prefix, 'a')) == NULL)
1301 adios (NULLCP, "lost prefix start");
1302 while (find_prefix () == NOTOK)
1308 "giving up trying to find a unique delimiter string");
1312 fprintf (out, "%s: %s\n%s: multipart/digest; boundary=\"",
1313 VRSN_FIELD, VRSN_VALUE, TYPE_FIELD);
1314 fprintf (out, "%s\"\n%s: %s\n\n--%s\n%s: %s\n%s: %s\n\n", prefix,
1315 DESCR_FIELD, "Blind Carbon Copy", prefix,
1316 TYPE_FIELD, "message/rfc822",
1317 DESCR_FIELD, "Original Message");
1321 fprintf (out, "\n------- Blind-Carbon-Copy\n\n");
1322 (void) fflush (out);
1324 if (filter == NULL) {
1325 if ((fd = open (tmpfil, 0)) == NOTOK)
1326 adios (tmpfil, "unable to re-open");
1329 cpydata (fd, fileno (out), tmpfil, bccfil);
1332 cpydgst (fd, fileno (out), tmpfil, bccfil);
1336 vec[0] = r1bindex (mhlproc, '/');
1338 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
1342 adios ("fork", "unable to");
1345 (void) dup2 (fileno (out), 1);
1348 vec[i++] = "-forward";
1354 execvp (mhlproc, vec);
1355 fprintf (stderr, "unable to exec ");
1360 (void) pidXwait (child_id, mhlproc);
1365 (void) fseek (out, 0L, 2);
1368 fprintf (out, "\n--%s--\n", prefix);
1371 fprintf (out, "\n------- End of Blind-Carbon-Copy\n");
1372 (void) fclose (out);
1378 static int find_prefix ()
1382 char buffer[BUFSIZ];
1385 if ((in = fopen (tmpfil, "r")) == NULL)
1386 adios (tmpfil, "unable to re-open");
1388 len = strlen (prefix);
1391 while (fgets (buffer, sizeof buffer - 1, in))
1392 if (buffer[0] == '-' && buffer[1] == '-') {
1395 for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--)
1399 if (strcmp (buffer + 2, prefix) == 0) {
1411 /*
\f ADDRESS VERIFICATION */
1413 static verify_all_addresses (talk)
1418 #endif /* not MHMTS */
1422 struct rp_bufstruct reply;
1424 #endif /* MMDFMTS */
1425 register struct mailname *lp;
1429 #endif /* not MHMTS */
1432 if (!whomsw || checksw) {
1433 if (rp_isbad (retval = mm_init ())
1434 || rp_isbad (retval = mm_sbinit ())
1435 || rp_isbad (retval = mm_winit (NULLCP, submitopts, from)))
1436 die (NULLCP, "problem initializing MMDF system [%s]",
1437 rp_valstr (retval));
1439 if (rp_isbad (retval = mm_rrply (&reply, &len)))
1440 die (NULLCP, "problem with sender address [%s]",
1441 rp_valstr (retval));
1444 #endif /* MMDFMTS */
1446 if (!whomsw || checksw)
1447 if (rp_isbad (retval = sm_init (clientsw, serversw, 0, 0, snoop, 0, 0))
1448 || rp_isbad (retval = sm_winit (smtpmode, from)))
1449 die (NULLCP, "problem initializing server; %s",
1450 rp_string (retval));
1451 #endif /* SENDMTS */
1453 if (talk && !whomsw)
1454 printf (" -- Address Verification --\n");
1456 if (talk && localaddrs.m_next)
1457 printf (" -- Local Recipients --\n");
1459 for (lp = localaddrs.m_next; lp; lp = lp -> m_next)
1460 do_an_address (lp, talk, encryptsw);
1463 if (talk && uuaddrs.m_next)
1464 printf (" -- UUCP Recipients --\n");
1466 for (lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1467 do_an_address (lp, talk, encryptsw);
1470 if (talk && netaddrs.m_next)
1471 printf (" -- Network Recipients --\n");
1473 for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
1474 do_an_address (lp, talk, encryptsw);
1477 if (talk && !whomsw)
1478 printf (" -- Address Verification Successful --\n");
1481 if (!whomsw || checksw)
1482 (void) mm_end (NOTOK);
1483 #endif /* MMDFMTS */
1485 if (!whomsw || checksw)
1486 (void) sm_end (DONE);
1487 #endif /* SENDMTS */
1488 (void) fflush (stdout);
1492 #endif /* not MHMTS */
1498 #define plural(x) (x == 1 ? "" : "s")
1500 if (badadr && unkadr)
1501 die (NULLCP, "%d address%s unparsable, %d addressee%s undeliverable",
1502 badadr, plural (badadr), unkadr, plural (badadr));
1504 die (NULLCP, "%d address%s unparsable", badadr, plural (badadr));
1506 die (NULLCP, "%d addressee%s undeliverable", unkadr, plural (unkadr));
1509 /*
\f MTS INTERACTION */
1512 static postplain (file, bccque, talk)
1514 static post (file, bccque, talk)
1516 register char *file;
1521 onex = !(msgflags & MINV) || bccque;
1527 struct rp_bufstruct reply;
1529 #endif /* MMDFMTS */
1535 if (msgflags & MINV)
1536 printf (" -- Posting for %s Recipients --\n",
1537 bccque ? "Blind" : "Sighted");
1539 printf (" -- Posting for All Recipients --\n");
1544 if (rp_isbad (retval = mm_init ())
1545 || rp_isbad (retval = mm_sbinit ())
1546 || rp_isbad (retval = mm_winit (NULLCP, submitopts, from)))
1547 die (NULLCP, "problem initializing MMDF system [%s]",
1548 rp_valstr (retval));
1550 if (rp_isbad (retval = mm_rrply (&reply, &len)))
1551 die (NULLCP, "problem with sender address [%s]",
1552 rp_valstr (retval));
1554 #endif /* MMDFMTS */
1556 if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop,
1558 || rp_isbad (retval = sm_winit (smtpmode, from)))
1559 die (NULLCP, "problem initializing server; %s", rp_string (retval));
1560 #endif /* SENDMTS */
1563 do_addresses (bccque, talk && verbose);
1564 if ((fd = open (file, 0)) == NOTOK)
1565 die (file, "unable to re-open");
1568 if ((fd = open (file, 0)) == NULL)
1569 adios (file, "unable to re-open");
1571 ud = UucpChan () && uuaddrs.m_next ? make_uucp_file (fd) : NOTOK;
1575 do_addresses (file, fd, ud, bccque, talk && verbose);
1580 (void) fflush (stdout);
1585 #endif /* MMDFMTS */
1587 (void) sm_end (onex ? OK : DONE);
1588 #endif /* SENDMTS */
1593 if (msgflags & MINV)
1594 printf (" -- %s Recipient Copies Posted --\n",
1595 bccque ? "Blind" : "Sighted");
1597 printf (" -- Recipient Copies Posted --\n");
1598 (void) fflush (stdout);
1604 static postcipher (file, bccque, talk)
1605 register char *file;
1611 char reason[BUFSIZ];
1612 struct mailname *lp;
1615 if (msgflags & MINV)
1616 printf (" -- Posting for %s Recipients --\n",
1617 bccque ? "Blind" : "Sighted");
1619 printf (" -- Posting for All Recipients --\n");
1621 if ((fdP = open (file, 0)) == NOTOK)
1622 adios (file, "unable to re-open");
1623 if (ciphinit (fdP, reason) == NOTOK)
1624 adios (NULLCP, "%s", reason);
1627 for (state = 0, lp = localaddrs.m_next; lp; lp = lp -> m_next)
1628 if (lp -> m_bcc ? bccque : !bccque) {
1631 printf (" -- Local Recipients --\n");
1633 do_a_cipher (lp, talk);
1639 for (state = 0, lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1640 if (lp -> m_bcc ? bccque : !bccque) {
1643 printf (" -- UUCP Recipients --\n");
1645 do_a_cipher (lp, talk);
1651 for (state = 0, lp = netaddrs.m_next; lp; lp = lp -> m_next)
1652 if (lp -> m_bcc ? bccque : !bccque) {
1655 printf (" -- Network Recipients --\n");
1657 do_a_cipher (lp, talk);
1663 if (ciphdone (reason) == NOTOK)
1664 admonish (NULLCP, "%s", reason);
1666 if (!(msgflags & MINV) || bccque)
1668 #endif /* SENDMTS */
1671 if (msgflags & MINV)
1672 printf (" -- %s Recipient Copies Posted --\n",
1673 bccque ? "Blind" : "Sighted");
1675 printf (" -- Recipient Copies Posted --\n");
1676 (void) fflush (stdout);
1681 static do_a_cipher (lp, talk)
1682 register struct mailname *lp;
1687 register char *mbox,
1694 struct rp_bufstruct reply;
1696 #endif /* MMDFMTS */
1701 if (rp_isbad (retval = mm_init ())
1702 || rp_isbad (retval = mm_sbinit ())
1703 || rp_isbad (retval = mm_winit (NULL, submitopts, from)))
1704 die (NULLCP, "problem initializing MMDF system [%s]",
1705 rp_valstr (retval));
1707 if (rp_isbad (retval = mm_rrply (&reply, &len)))
1708 die (NULLCP, "problem with sender address [%s]",
1709 rp_valstr (retval));
1711 #endif /* MMDFMTS */
1713 if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop,
1715 || rp_isbad (retval = sm_winit (smtpmode, from)))
1716 die (NULLCP, "problem initializing server; %s", rp_string (retval));
1717 #endif /* SENDMTS */
1719 do_an_address (lp, talk, 0);
1721 switch (lp -> m_type) {
1723 mbox = lp -> m_mbox;
1724 host = LocalName ();
1725 (void) strcpy (addr, mbox);
1730 mbox = concat (lp -> m_host, "!", lp -> m_mbox, NULLCP);
1732 #endif /* MMDFMTS */
1734 mbox = auxformat (lp, 0);
1736 #endif /* SENDMTS */
1737 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
1741 mbox = lp -> m_mbox;
1742 host = lp -> m_host;
1743 (void) sprintf (addr, "%s at %s", lp -> m_mbox, lp -> m_host);
1746 chkadr (); /* XXX */
1749 if (rp_isbad (retval = mm_waend ()))
1750 die (NULLCP, "problem ending addresses [%s]\n",
1751 rp_valstr (retval));
1752 #endif /* MMDFMTS */
1754 if (rp_isbad (retval = sm_waend ()))
1755 die (NULLCP, "problem ending addresses; %s", rp_string (retval));
1756 #endif /* SENDMTS */
1758 if ((fd = encipher (mbox, host, reason)) == NOTOK)
1759 die (NULLCP, "%s: %s", addr, reason);
1760 do_text ("temporary file", fd);
1762 (void) fflush (stdout);
1767 #endif /* MMDFMTS */
1769 (void) sm_end (DONE);
1770 #endif /* SENDMTS */
1779 static do_addresses (bccque, talk)
1781 static do_addresses (file, fd, ud, bccque, talk)
1782 register char *file;
1792 #endif /* not BERK */
1793 register struct mailname *lp;
1797 #endif /* not BERK */
1798 for (lp = localaddrs.m_next; lp; lp = lp -> m_next)
1799 if (lp -> m_bcc ? bccque : !bccque) {
1802 printf (" -- Local Recipients --\n");
1803 #endif /* not BERK */
1805 do_an_address (lp, talk, 0);
1807 localmail (lp, talk, fd);
1811 #endif /* not BERK */
1816 #endif /* not BERK */
1817 for (lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1818 if (lp -> m_bcc ? bccque : !bccque) {
1821 printf (" -- UUCP Recipients --\n");
1822 #endif /* not BERK */
1824 do_an_address (lp, talk, 0);
1826 uucpmail (lp, talk, ud != NOTOK ? ud : fd, ud == NOTOK);
1830 #endif /* not BERK */
1835 #endif /* not BERK */
1836 for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
1837 if (lp -> m_bcc ? bccque : !bccque) {
1840 printf (" -- Network Recipients --\n");
1841 #endif /* not BERK */
1843 do_an_address (lp, talk, 0);
1845 netmail (talk, fd, bccque);
1849 #endif /* not BERK */
1857 if (rp_isbad (retval = mm_waend ()))
1858 die (NULLCP, "problem ending addresses [%s]\n",
1859 rp_valstr (retval));
1860 #endif /* MMDFMTS */
1862 if (rp_isbad (retval = sm_waend ()))
1863 die (NULLCP, "problem ending addresses; %s", rp_string (retval));
1864 #endif /* SENDMTS */
1870 static do_text (file, fd)
1871 register char *file;
1878 struct rp_bufstruct reply;
1879 #endif /* MMDFMTS */
1881 (void) lseek (fd, (off_t)0, 0);
1882 while ((state = read (fd, buf, sizeof buf)) > 0)
1884 if (rp_isbad (mm_wtxt (buf, state)))
1885 die (NULLCP, "problem writing text [%s]\n", rp_valstr (retval));
1886 #endif /* MMDFMTS */
1888 if (rp_isbad (retval = sm_wtxt (buf, state)))
1889 die (NULLCP, "problem writing text; %s\n", rp_string (retval));
1890 #endif /* SENDMTS */
1893 die (file, "problem reading from");
1896 if (rp_isbad (retval = mm_wtend ()))
1897 die (NULLCP, "problem ending text [%s]\n", rp_valstr (retval));
1899 if (rp_isbad (retval = mm_rrply (&reply, &state)))
1900 die (NULLCP, "problem getting submission status [%s]\n",
1901 rp_valstr (retval));
1903 switch (rp_gval (reply.rp_val)) {
1909 die (NULLCP, "you lose; %s", reply.rp_line);
1912 die (NULLCP, "no delivery occurred; %s", reply.rp_line);
1915 die (NULLCP, "try again later; %s", reply.rp_line);
1918 die (NULLCP, "nothing done; %s", reply.rp_line);
1921 die (NULLCP, "unexpected response;\n\t[%s] -- %s",
1922 rp_valstr (reply.rp_val), reply.rp_line);
1924 #endif /* MMDFMTS */
1926 switch (retval = sm_wtend ()) {
1932 die (NULLCP, "posting failed; %s", rp_string (retval));
1935 die (NULLCP, "unexpected response; %s", rp_string (retval));
1937 #endif /* SENDMTS */
1939 #endif /* not MHMTS */
1941 /*
\f MTS-SPECIFIC INTERACTION */
1949 static do_an_address (lp, talk, tma)
1950 register struct mailname *lp;
1956 register char *mbox,
1962 char reason[BUFSIZ];
1964 struct rp_bufstruct reply;
1966 switch (lp -> m_type) {
1968 mbox = lp -> m_mbox;
1969 host = LocalName ();
1970 (void) strcpy (addr, mbox);
1975 mbox = concat (lp -> m_host, "!", lp -> m_mbox, NULLCP);
1977 (void) strcpy (addr, mbox);
1980 fprintf (talk ? stdout : stderr, " %s!%s: %s\n",
1981 lp -> m_host, lp -> m_mbox, "not supported; UUCP address");
1983 (void) fflush (stdout);
1987 default: /* let MMDF decide if the host is bad */
1988 mbox = lp -> m_mbox;
1989 host = lp -> m_host;
1990 (void) sprintf (addr, "%s at %s", mbox, host);
1994 if ((!whomsw || checksw)
1996 && seekaddr (mbox, host, reason) == NOTOK) {
1997 fprintf (talk ? stdout : stderr, " %s%s: %s\n",
1998 addr, "[TMA]", reason);
2004 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
2006 if (whomsw && !checksw) {
2007 (void) putchar ('\n');
2012 (void) fflush (stdout);
2018 path = concat (lp -> m_path, mbox, "@", host, NULLCP);
2022 if (rp_isbad (retval = mm_wadr (path ? NULLCP : host, path ? path : mbox))
2023 || rp_isbad (retval = mm_rrply (&reply, &len)))
2024 die (NULLCP, "problem submitting address [%s]", rp_valstr (retval));
2026 switch (rp_gval (reply.rp_val)) {
2029 printf ("address ok\n");
2030 (void) fflush (stdout);
2036 printf ("nameserver timeout - queued for checking\n");
2037 (void) fflush (stdout);
2047 text = "temporary nameserver failure";
2054 text = "not deliverable";
2058 text = "try again later";
2062 text = "nothing done";
2067 fprintf (stderr, " %s: ", addr);
2068 text = "unexpected response";
2069 die (NULLCP, "%s;\n [%s] -- %s", text,
2070 rp_valstr (reply.rp_val), reply.rp_line);
2074 fprintf (stderr, " %s: ", addr);
2075 fprintf (talk ? stdout : stderr, "%s;\n %s\n", text, reply.rp_line);
2078 (void) fflush (stdout);
2080 #endif /* MMDFMTS */
2087 static do_an_address (lp, talk, tma)
2088 register struct mailname *lp;
2092 register char *mbox;
2095 switch (lp -> m_type) {
2097 (void) strcpy (addr, lp -> m_mbox);
2101 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
2105 (void) sprintf (addr, "%s at %s", lp -> m_mbox, lp -> m_host);
2109 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
2111 if (whomsw && !checksw) {
2112 (void) putchar ('\n');
2117 (void) fflush (stdout);
2121 switch (lp -> m_type) {
2123 mbox = lp -> m_mbox;
2126 if (seek_home (mbox)) {
2127 lp -> m_mbox = mbox;
2129 printf ("address ok\n");
2133 fprintf (stderr, " %s: ", addr);
2134 fprintf (talk ? stdout : stderr,
2135 "not deliverable; unknown user\n");
2141 if (uucpsite (lp -> m_host) == OK) {
2143 printf ("address ok\n");
2147 fprintf (stderr, " %s: ", addr);
2148 fprintf (talk ? stdout : stderr,
2149 "not deliverable; unknown system\n");
2156 printf ("address ok\n");
2161 fprintf (stderr, " %s: ", addr);
2162 fprintf (talk ? stdout : stderr,
2163 "not deliverable; unknown host\n");
2168 (void) fflush (stdout);
2180 static do_an_address (lp, talk, tma)
2181 register struct mailname *lp;
2186 register char *mbox,
2190 char reason[BUFSIZ];
2193 switch (lp -> m_type) {
2195 mbox = lp -> m_mbox;
2196 host = lp -> m_host;
2197 (void) strcpy (addr, mbox);
2201 mbox = auxformat (lp, 0);
2203 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
2206 default: /* let SendMail decide if the host is bad */
2207 mbox = lp -> m_mbox;
2208 host = lp -> m_host;
2209 (void) sprintf (addr, "%s at %s", mbox, host);
2214 if ((!whomsw || checksw)
2216 && seekaddr (mbox, host, reason) == NOTOK) {
2217 fprintf (talk ? stdout : stderr, " %s%s: %s\n",
2218 addr, "[TMA]", reason);
2224 printf (" %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
2226 if (whomsw && !checksw) {
2227 (void) putchar ('\n');
2232 (void) fflush (stdout);
2236 switch (retval = sm_wadr (mbox, host,
2237 lp -> m_type != UUCPHOST ? lp -> m_path : NULLCP)) {
2240 printf ("address ok\n");
2246 fprintf (stderr, " %s: ", addr);
2247 fprintf (talk ? stdout : stderr, "loses; %s\n",
2248 rp_string (retval));
2254 fprintf (stderr, " %s: ", addr);
2255 die (NULLCP, "unexpected response; %s", rp_string (retval));
2258 (void) fflush (stdout);
2260 #endif /* SENDMTS */
2262 /*
\f SIGNAL HANDLING */
2268 static TYPESIG sigser (i)
2272 (void) signal (i, SIG_IGN);
2273 #endif /* not BSD42 */
2274 (void) unlink (tmpfil);
2275 if (msgflags & MINV)
2276 (void) unlink (bccfil);
2278 if (!whomsw || checksw)
2279 (void) mm_end (NOTOK);
2280 #endif /* MMDFMTS */
2282 if (!whomsw || checksw)
2283 (void) sm_end (NOTOK);
2284 #endif /* SENDMTS */
2287 #endif /* not MHMTS */
2295 setsigx (hstat, SIGHUP, sigser);
2296 setsigx (istat, SIGINT, sigser);
2297 setsigx (qstat, SIGQUIT, sigser);
2298 setsigx (tstat, SIGTERM, sigser);
2300 setsigx (hstat, SIGHUP, SIG_IGN);
2301 setsigx (istat, SIGINT, SIG_IGN);
2302 setsigx (qstat, SIGQUIT, SIG_IGN);
2303 setsigx (tstat, SIGTERM, SIG_IGN);
2312 (void) signal (SIGHUP, hstat);
2313 (void) signal (SIGINT, istat);
2314 (void) signal (SIGQUIT, qstat);
2315 (void) signal (SIGTERM, tstat);
2318 /*
\f FCC INTERACTION */
2320 static p_refile (file)
2321 register char *file;
2329 (void) setuid (myuid);
2332 printf (" -- Filing Folder Copies --\n");
2333 for (i = 0; i < fccind; i++)
2334 fcc (file, fccfold[i]);
2336 printf (" -- Folder Copies Filed --\n");
2340 static fcc (file, folder)
2341 register char *file,
2350 printf (" %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder);
2351 (void) fflush (stdout);
2353 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
2358 fprintf (stderr, " %sFcc %s: ",
2359 msgstate == RESENT ? "Resent-" : "", folder);
2360 fprintf (verbose ? stdout : stderr, "no forks, so not ok\n");
2364 (void) sprintf (fold, "%s%s",
2365 *folder == '+' || *folder == '@' ? "" : "+", folder);
2366 execlp (fileproc, r1bindex (fileproc, '/'),
2367 "-link", "-file", file, fold, NULLCP);
2371 if (status = pidwait (child_id, OK)) {
2373 fprintf (stderr, " %sFcc %s: ",
2374 msgstate == RESENT ? "Resent-" : "", folder);
2375 (void) pidstatus (status, verbose ? stdout : stderr, NULLCP);
2379 printf ("folder ok\n");
2382 (void) fflush (stdout);
2385 /*
\f RECORD RECIPIENTS */
2392 char recfile[BUFSIZ];
2393 register struct mailname *ap,
2395 struct mailname *addrs[3];
2398 if (!record || (msgflags & (MFRM | MRFM | MRPY)))
2401 addrs[0] = &localaddrs;
2402 addrs[1] = &netaddrs;
2405 printf ("recording recipients... ");
2409 (void) strcpy (recfile, m_tmpfil ("record"));
2410 if ((out = fopen (recfile, "w")) == NULL) {
2411 fprintf (verbose ? stdout : stderr, "unable to create temporary file");
2413 fprintf (stderr, ", so can't record recipients");
2414 fprintf (verbose ? stdout : stderr, "\n");
2417 (void) chmod (recfile, 0600);
2419 for (app = addrs; ap = *app; app++) {
2420 register struct mailname *mp;
2422 for (mp = ap -> m_next; mp; mp = mp -> m_next)
2423 fprintf (out, "%s\n", adrformat (mp));
2426 (void) fclose (out);
2428 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
2432 fprintf (verbose ? stdout : stderr, "unable to fork");
2434 fprintf (stderr, ", so can't record recipients");
2435 fprintf (verbose ? stdout : stderr, "\n");
2439 execlp (record, r1bindex (record, '/'), recfile, NULLCP);
2443 if (status = pidwait (child_id, OK)) {
2445 fprintf (stderr, "problem with %s: ", recfile);
2446 (void) pidstatus (status, verbose ? stdout : stderr, NULLCP);
2453 (void) unlink (recfile);
2456 /*
\f TERMINATION */
2460 static die (what, fmt, a, b, c, d)
2469 (void) unlink (tmpfil);
2470 if (msgflags & MINV)
2471 (void) unlink (bccfil);
2474 if (!whomsw || checksw)
2475 (void) mm_end (NOTOK);
2476 #endif /* MMDFMTS */
2478 if (!whomsw || checksw)
2479 (void) sm_end (NOTOK);
2480 #endif /* SENDMTS */
2482 adios (what, fmt, a, b, c, d);
2488 * err_abrt() is used by the mm_ routines
2489 * do not, under *ANY* circumstances, remove it from post,
2490 * or you will lose *BIG*
2493 err_abrt (code, fmt, a, b, c)
2500 char buffer[BUFSIZ];
2502 (void) sprintf (buffer, "[%s]", rp_valstr (code));
2504 adios (buffer, fmt, a, b, c);
2506 #endif /* MMDFMTS */
2508 /*
\f STAND-ALONE DELIVERY */
2512 /* BUG: MHMTS ignores 822-style route addresses... */
2514 static localmail (lp, talk, fd)
2515 register struct mailname *lp;
2520 char mailbox[BUFSIZ],
2522 register struct home *hp;
2525 printf (" %s: ", lp -> m_mbox);
2526 (void) fflush (stdout);
2528 if ((hp = seek_home (lp -> m_mbox)) == NULL) {
2530 fprintf (stderr, " %s: ", lp -> m_mbox);
2531 fprintf (talk ? stdout : stderr,
2532 "not deliverable; unknown address\n");
2537 (void) sprintf (mailbox, "%s/%s",
2538 mmdfldir[0] ? mmdfldir : hp -> h_home,
2539 mmdflfil[0] ? mmdflfil : hp -> h_name);
2543 switch (access (slocalproc, 01)) {
2546 printf ("(invoking hook)\n\t");
2547 (void) fflush (stdout);
2549 if (usr_hook (lp, talk, fd, hp, mailbox) != NOTOK)
2552 printf (" %s: ", lp -> m_mbox);
2553 (void) fflush (stdout);
2556 (void) lseek (fd, (off_t)0, 0);
2557 if ((md = mbx_open (mailbox, hp -> h_uid, hp -> h_gid, m_gmprot ()))
2560 fprintf (stderr, " %s: ", lp -> m_mbox);
2561 fprintf (talk ? stdout : stderr,
2562 "error in transmission; unable to open maildrop\n");
2566 (void) sprintf (ddate, "Delivery-Date: %s\n", dtimenow ());
2567 if (mbx_copy (mailbox, md, fd, 0, ddate, 0) == NOTOK) {
2569 fprintf (stderr, " %s: ", lp -> m_mbox);
2570 fprintf (talk ? stdout : stderr,
2571 "error in transmission; write to maildrop failed\n");
2576 mbx_close (mailbox, md);
2583 (void) fflush (stdout);
2588 static int usr_hook (lp, talk, fd, hp, mailbox)
2589 register struct mailname *lp;
2592 register struct home *hp;
2593 register char *mailbox;
2598 char tmpfil[BUFSIZ];
2600 if ((fd = copyfile (fd, tmpfil)) == NOTOK) {
2602 fprintf (stderr, " %s: ", lp -> m_mbox);
2603 fprintf (talk ? stdout : stderr,
2604 "unable to copy message; skipping hook\n");
2607 (void) chown (tmpfil, hp -> h_uid, hp -> h_gid);
2609 (void) fflush (stdout);
2611 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
2616 fprintf (stderr, " %s: ", lp -> m_mbox);
2617 fprintf (talk ? stdout : stderr,
2618 "unable to invoke hook; fork() failed\n");
2623 (void) dup2 (fd, 0);
2624 (void) freopen ("/dev/null", "w", stdout);
2625 (void) freopen ("/dev/null", "w", stderr);
2626 if (fd != 3) /* backwards compatible... */
2627 (void) dup2 (fd, 3);
2630 if ((fd = open ("/dev/tty", 2)) != NOTOK) {
2631 (void) ioctl (fd, TIOCNOTTY, NULLCP);
2634 #endif /* TIOCNOTTY */
2636 (void) setpgrp (0, getpid ());
2640 (void) m_putenv ("USER", hp -> h_name);
2641 (void) m_putenv ("HOME", hp -> h_home);
2642 (void) m_putenv ("SHELL", hp -> h_shell);
2643 if (chdir (hp -> h_home) == NOTOK)
2645 (void) umask (0077);
2647 (void) inigrp (hp -> h_name, hp -> h_gid);
2649 (void) setgid (hp -> h_gid);
2651 (void) initgroups (hp -> h_name, hp -> h_gid);
2653 (void) setuid (hp -> h_uid);
2655 execlp (slocalproc, r1bindex (slocalproc, '/'),
2656 "-file", tmpfil, "-mailbox", mailbox,
2657 "-home", hp -> h_home, "-addr", lp -> m_aka,
2658 "-user", hp -> h_name, "-sender", from,
2659 talk ? "-verbose" : NULLCP, NULLCP);
2667 status = pidwait (child_id, OK);
2669 (void) unlink (tmpfil);
2672 printf ("accepted\n");
2676 fprintf (stderr, " %s: ", lp -> m_mbox);
2677 fprintf (talk ? stdout : stderr,
2678 "%s error on hook; status=0%o\n",
2679 status & 0x00ff ? "system" : "user",
2680 status & 0x00ff ? status & 0xff
2681 : (status & 0xff00) >> 8);
2688 static int copyfile (qd, tmpfil)
2690 register char *tmpfil;
2694 char buffer[BUFSIZ];
2696 (void) strcpy (tmpfil, m_tmpfil ("hook"));
2697 if ((fd = creat (tmpfil, 0600)) == NOTOK)
2700 if ((fd = open (tmpfil, 2)) == NOTOK)
2703 (void) lseek (qd, (off_t)0, 0);
2704 while ((i = read (qd, buffer, sizeof buffer)) > 0)
2705 if (write (fd, buffer, i) != i) {
2714 (void) lseek (fd, (off_t)0, 0);
2721 static uucpmail (lp, talk, fd, from)
2722 register struct mailname *lp;
2728 TYPESIG (*pstat) ();
2733 (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
2735 printf (" %s: ", addr);
2736 (void) fflush (stdout);
2739 (void) sprintf (buffer, "uux -r -p %s!rmail \\(%s\\)",
2740 lp -> m_host, lp -> m_mbox);
2742 (void) sprintf (buffer, "uux -p %s!rmail \\(%s\\)", lp -> m_host,
2745 if ((fp = popen (buffer, "w")) == NULL) {
2747 fprintf (stderr, " %s: ", addr);
2748 fprintf (talk ? stdout : stderr,
2749 "unable to start uux; popen() failed\n");
2754 pstat = signal (SIGPIPE, SIG_IGN);
2755 if (from) { /* no mail filtering, so... */
2756 (void) sprintf (buffer, "From %s %.24s remote from %s\n",
2757 getusr (), ctime (&tclock), SystemName ());
2758 i = strlen (buffer);
2759 if (fwrite (buffer, sizeof *buffer, i, fp) != i)
2763 (void) lseek (fd, (off_t)0, 0);
2764 while ((i = read (fd, buffer, sizeof buffer)) > 0)
2765 if (fwrite (buffer, sizeof *buffer, i, fp) != i) {
2768 fprintf (stderr, " %s: ", addr);
2769 fprintf (talk ? stdout : stderr,
2770 "error in transmission; write to uux failed\n");
2777 (void) signal (SIGPIPE, pstat);
2781 fprintf (stderr, " %s: ", addr);
2782 fprintf (talk ? stdout : stderr,
2783 "error in transmission; read failed\n");
2789 printf ("queued (via uux)\n");
2790 (void) fflush (stdout);
2796 static int make_uucp_file (td)
2802 char tmpfil[BUFSIZ];
2804 (void) lseek (td, (off_t)0, 0);
2805 if ((qd = dup (td)) == NOTOK)
2806 adios ("fd", "unable to dup");
2808 (void) strcpy (tmpfil, m_tmpfil ("uumf"));
2809 if ((fd = creat (tmpfil, 0600)) == NOTOK)
2810 adios (tmpfil, "unable to create");
2812 if ((fd = open (tmpfil, 2)) == NOTOK)
2813 adios (tmpfil, "unable to re-open");
2815 switch (i = mmdf2uucp (qd, fd, 1)) {
2818 (void) unlink (tmpfil);
2822 adios (NULLCP, "unable to filter mail(%d), examine %s", i, tmpfil);
2832 static netmail (talk, fd, bccque)
2839 char buffer[BUFSIZ];
2840 register struct mailname *lp;
2843 if (nm_init (getusr (), &tclock) == NOTOK) {
2844 for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
2845 if (lp -> m_bcc ? bccque : !bccque)
2846 fprintf (stderr, " %s at %s: unable to get queue file\n",
2847 lp -> m_mbox, lp -> m_host);
2851 for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
2852 if (lp -> m_bcc ? bccque : !bccque) {
2853 (void) nm_wadr (lp -> m_mbox, lp -> m_host);
2856 printf (" %s at %s: queued\n", lp -> m_mbox, lp -> m_host);
2857 (void) fflush (stdout);
2861 (void) lseek (fd, (off_t)0, 0);
2862 while ((i = read (fd, buffer, sizeof buffer)) > 0)
2863 if (nm_wtxt (buffer, i) == NOTOK) {
2865 "error in transmission; write to temporary failed");
2871 fprintf (stderr, "error in transmission; read failed\n");
2876 if (nm_wtend () == NOTOK) {
2877 fprintf (stderr, "error in transmission; unable to queue message\n");