From bc854e30ec85268fc16d88e1426d88ef66d84a8f Mon Sep 17 00:00:00 2001 From: Eric Allman Date: Tue, 16 Mar 1993 17:16:29 -0800 Subject: [PATCH] delete e_sender and e_returnpath; fix some bugs in envelope splitting SCCS-vsn: usr.sbin/sendmail/src/usersmtp.c 6.16 SCCS-vsn: usr.sbin/sendmail/src/recipient.c 6.27 SCCS-vsn: usr.sbin/sendmail/src/envelope.c 6.21 SCCS-vsn: usr.sbin/sendmail/src/parseaddr.c 6.28 SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 6.28 SCCS-vsn: usr.sbin/sendmail/src/savemail.c 6.22 SCCS-vsn: usr.sbin/sendmail/src/util.c 6.12 SCCS-vsn: usr.sbin/sendmail/src/deliver.c 6.44 SCCS-vsn: usr.sbin/sendmail/src/queue.c 6.26 SCCS-vsn: usr.sbin/sendmail/src/alias.c 6.25 SCCS-vsn: usr.sbin/sendmail/src/mci.c 6.6 --- usr/src/usr.sbin/sendmail/src/alias.c | 10 +- usr/src/usr.sbin/sendmail/src/deliver.c | 154 +++++++++++++--------- usr/src/usr.sbin/sendmail/src/envelope.c | 28 ++-- usr/src/usr.sbin/sendmail/src/mci.c | 6 +- usr/src/usr.sbin/sendmail/src/parseaddr.c | 6 +- usr/src/usr.sbin/sendmail/src/queue.c | 25 ++-- usr/src/usr.sbin/sendmail/src/recipient.c | 20 +-- usr/src/usr.sbin/sendmail/src/savemail.c | 125 +++++++++--------- usr/src/usr.sbin/sendmail/src/sendmail.h | 6 +- usr/src/usr.sbin/sendmail/src/usersmtp.c | 20 ++- usr/src/usr.sbin/sendmail/src/util.c | 25 +++- 11 files changed, 245 insertions(+), 180 deletions(-) diff --git a/usr/src/usr.sbin/sendmail/src/alias.c b/usr/src/usr.sbin/sendmail/src/alias.c index 39492d6902..d2c247bfc1 100644 --- a/usr/src/usr.sbin/sendmail/src/alias.c +++ b/usr/src/usr.sbin/sendmail/src/alias.c @@ -28,15 +28,15 @@ ERROR: DBM is no longer supported -- use NDBM instead. #ifndef lint #ifdef NEWDB #ifdef NDBM -static char sccsid[] = "@(#)alias.c 6.24 (Berkeley) %G% (with NEWDB and NDBM)"; +static char sccsid[] = "@(#)alias.c 6.25 (Berkeley) %G% (with NEWDB and NDBM)"; #else -static char sccsid[] = "@(#)alias.c 6.24 (Berkeley) %G% (with NEWDB)"; +static char sccsid[] = "@(#)alias.c 6.25 (Berkeley) %G% (with NEWDB)"; #endif #else #ifdef NDBM -static char sccsid[] = "@(#)alias.c 6.24 (Berkeley) %G% (with NDBM)"; +static char sccsid[] = "@(#)alias.c 6.25 (Berkeley) %G% (with NDBM)"; #else -static char sccsid[] = "@(#)alias.c 6.24 (Berkeley) %G% (without NEWDB or NDBM)"; +static char sccsid[] = "@(#)alias.c 6.25 (Berkeley) %G% (without NEWDB or NDBM)"; #endif #endif #endif /* not lint */ @@ -122,7 +122,7 @@ alias(a, sendq, e) printf("alias(%s)\n", a->q_paddr); /* don't realias already aliased names */ - if (bitset(QDONTSEND|QVERIFIED, a->q_flags)) + if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags)) return; e->e_to = a->q_paddr; diff --git a/usr/src/usr.sbin/sendmail/src/deliver.c b/usr/src/usr.sbin/sendmail/src/deliver.c index 4db20bfae5..80ab983eb0 100644 --- a/usr/src/usr.sbin/sendmail/src/deliver.c +++ b/usr/src/usr.sbin/sendmail/src/deliver.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)deliver.c 6.43 (Berkeley) %G%"; +static char sccsid[] = "@(#)deliver.c 6.44 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -59,12 +59,10 @@ deliver(e, firstto) bool clever = FALSE; /* running user smtp to this mailer */ ADDRESS *tochain = NULL; /* chain of users in this mailer call */ int rcode; /* response code */ - char *from; /* pointer to from person */ char *firstsig; /* signature of firstto */ char *pv[MAXPV+1]; char tobuf[MAXLINE-50]; /* text line of to people */ char buf[MAXNAME]; - char tfrombuf[MAXNAME]; /* translated from person */ char rpathbuf[MAXNAME]; /* translated return path */ extern int checkcompat(); extern ADDRESS *getctladdr(); @@ -106,7 +104,7 @@ deliver(e, firstto) { for (; to != NULL; to = to->q_next) { - if (bitset(QDONTSEND|QQUEUEUP, to->q_flags) || + if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) || to->q_mailer != m) continue; to->q_flags |= QQUEUEUP|QDONTSEND; @@ -131,22 +129,11 @@ deliver(e, firstto) */ /* rewrite from address, using rewriting rules */ - (void) strcpy(rpathbuf, remotename(e->e_returnpath, m, TRUE, FALSE, + (void) strcpy(rpathbuf, remotename(e->e_from.q_paddr, m, TRUE, FALSE, TRUE, FALSE, e)); - if (e->e_returnpath == e->e_sender) - { - from = rpathbuf; - } - else - { - (void) strcpy(tfrombuf, remotename(e->e_sender, m, TRUE, FALSE, - TRUE, FALSE, e)); - from = tfrombuf; - } - define('f', e->e_returnpath, e); /* raw return path */ - define('<', rpathbuf, e); /* translated return path */ - define('g', from, e); /* translated sender */ + define('f', e->e_from.q_paddr, e); /* raw return path */ + define('g', rpathbuf, e); /* translated return path */ define('h', host, e); /* to host */ Errors = 0; pvp = pv; @@ -231,7 +218,7 @@ deliver(e, firstto) break; /* if already sent or not for this host, don't send */ - if (bitset(QDONTSEND|QQUEUEUP, to->q_flags) || + if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) || to->q_mailer != firstto->q_mailer || strcmp(hostsignature(to->q_mailer, to->q_host, e), firstsig) != 0) continue; @@ -252,12 +239,12 @@ deliver(e, firstto) user = to->q_user; e->e_to = to->q_paddr; - to->q_flags |= QDONTSEND; if (tTd(10, 5)) { printf("deliver: QDONTSEND "); printaddr(to, FALSE); } + to->q_flags |= QDONTSEND; /* ** Check to see that these people are allowed to @@ -663,9 +650,9 @@ endmailer(mci, name) /* close any connections */ if (mci->mci_in != NULL) - (void) fclose(mci->mci_in); + (void) xfclose(mci->mci_in, name, "mci_in"); if (mci->mci_out != NULL) - (void) fclose(mci->mci_out); + (void) xfclose(mci->mci_out, name, "mci_out"); mci->mci_in = mci->mci_out = NULL; mci->mci_state = MCIS_CLOSED; @@ -1257,7 +1244,7 @@ putfromline(fp, m, e) char *bang; char xbuf[MAXLINE]; - expand("\201<", buf, &buf[sizeof buf - 1], e); + expand("\201g", buf, &buf[sizeof buf - 1], e); bang = strchr(buf, '!'); if (bang == NULL) syserr("554 No ! in UUCP! (%s)", buf); @@ -1337,28 +1324,6 @@ putbody(fp, m, e) errno = 0; } /* -** PARENTBODY -- put the body of the parent of a message. -** -** Parameters: -** fp -- file to output onto. -** m -- a mailer descriptor to control output format. -** e -- the envelope whose parent to put out. -** -** Returns: -** none. -** -** Side Effects: -** The message is written onto fp. -*/ - -parentbody(fp, m, e) - FILE *fp; - MAILER *m; - register ENVELOPE *e; -{ - putbody(fp, m, e->e_parent); -} - /* ** MAILFILE -- Send a message to a file. ** ** If the file has the setuid/setgid bits set, but NO execute @@ -1483,7 +1448,7 @@ mailfile(filename, ctladdr, e) message("451 I/O error"); setstat(EX_IOERR); } - (void) fclose(f); + (void) xfclose(f, "mailfile", filename); (void) fflush(stdout); /* reset ISUID & ISGID bits for paranoid systems */ @@ -1527,8 +1492,6 @@ sendall(e, mode) char mode; { register ADDRESS *q; - bool oldverbose; - int pid; char *owner; int otherowners; ENVELOPE *splitenv = NULL; @@ -1549,7 +1512,9 @@ sendall(e, mode) if (tTd(13, 1)) { - printf("\nSENDALL: mode %c, sendqueue:\n", mode); + printf("\nSENDALL: mode %c, e_from ", mode); + printaddr(&e->e_from, FALSE); + printf("sendqueue:\n"); printaddr(e->e_sendqueue, TRUE); } @@ -1574,12 +1539,12 @@ sendall(e, mode) { extern ADDRESS *recipient(); - e->e_from.q_flags |= QDONTSEND; if (tTd(13, 5)) { printf("sendall: QDONTSEND "); printaddr(&e->e_from, FALSE); } + e->e_from.q_flags |= QDONTSEND; (void) recipient(&e->e_from, &e->e_sendqueue, e); } @@ -1599,8 +1564,9 @@ sendall(e, mode) if (a != NULL) q->q_owner = a->q_owner; - if (q->q_owner != NULL && !bitset(QDONTSEND, q->q_flags) && - strcmp(q->q_owner, e->e_returnpath) == 0) + if (q->q_owner != NULL && + !bitset(QDONTSEND, q->q_flags) && + strcmp(q->q_owner, e->e_from.q_paddr) == 0) q->q_owner = NULL; } @@ -1646,16 +1612,34 @@ sendall(e, mode) extern HDR *copyheader(); extern ADDRESS *copyqueue(); + /* + ** Split this envelope into two. + */ + ee = (ENVELOPE *) xalloc(sizeof(ENVELOPE)); - STRUCTCOPY(*e, *ee); + *ee = *e; ee->e_id = NULL; - ee->e_parent = e; + (void) queuename(ee, '\0'); + + if (tTd(13, 1)) + printf("sendall: split %s into %s\n", + e->e_id, ee->e_id); + ee->e_header = copyheader(e->e_header); ee->e_sendqueue = copyqueue(e->e_sendqueue); ee->e_errorqueue = copyqueue(e->e_errorqueue); ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE); - ee->e_returnpath = owner; - ee->e_putbody = parentbody; + (void) parseaddr(owner, &ee->e_from, 1, '\0', NULL, ee); + if (tTd(13, 5)) + { + printf("sendall(split): QDONTSEND "); + printaddr(&ee->e_from, FALSE); + } + ee->e_from.q_flags |= QDONTSEND; + ee->e_dfp = NULL; + ee->e_xfp = NULL; + ee->e_lockfp = NULL; + ee->e_df = NULL; ee->e_sibling = splitenv; splitenv = ee; @@ -1676,11 +1660,32 @@ sendall(e, mode) e->e_df, ee->e_df); } } + + if (mode != SM_VERIFY) + { + char xfbuf1[20], xfbuf2[20]; + + (void) strcpy(xfbuf1, queuename(e, 'x')); + (void) strcpy(xfbuf2, queuename(ee, 'x')); + if (link(xfbuf1, xfbuf2) < 0) + { + syserr("sendall: link(%s, %s)", + xfbuf1, xfbuf2); + } + } } } if (owner != NULL) - e->e_returnpath = owner; + { + (void) parseaddr(owner, &e->e_from, 1, '\0', NULL, e); + if (tTd(13, 5)) + { + printf("sendall(owner): QDONTSEND "); + printaddr(&e->e_from, FALSE); + } + e->e_from.q_flags |= QDONTSEND; + } # ifdef QUEUE if ((mode == SM_QUEUE || mode == SM_FORK || @@ -1691,20 +1696,35 @@ sendall(e, mode) if (splitenv != NULL) { + register ENVELOPE *ee; + if (tTd(13, 1)) { printf("\nsendall: Split queue; remaining queue:\n"); printaddr(e->e_sendqueue, TRUE); } - while (splitenv != NULL) + for (ee = splitenv; ee != NULL; ee = ee->e_sibling) { - sendall(splitenv, mode); - splitenv = splitenv->e_sibling; + CurEnv = ee; + sendenvelope(ee, mode); } CurEnv = e; } + sendenvelope(e, mode); + + for (; splitenv != NULL; splitenv = splitenv->e_sibling) + dropenvelope(splitenv); +} + +sendenvelope(e, mode) + register ENVELOPE *e; + char mode; +{ + bool oldverbose; + int pid; + register ADDRESS *q; oldverbose = Verbose; switch (mode) @@ -1732,7 +1752,7 @@ sendall(e, mode) if (e->e_lockfp != NULL) { - (void) fclose(e->e_lockfp); + (void) xfclose(e->e_lockfp, "sendenvelope", "lockfp"); e->e_lockfp = NULL; } # endif /* LOCKF */ @@ -1749,7 +1769,7 @@ sendall(e, mode) # ifndef LOCKF if (e->e_lockfp != NULL) { - (void) fclose(e->e_lockfp); + (void) xfclose(e->e_lockfp, "sendenvelope", "lockfp"); e->e_lockfp = NULL; } # endif @@ -1757,12 +1777,12 @@ sendall(e, mode) /* close any random open files in the envelope */ if (e->e_dfp != NULL) { - (void) fclose(e->e_dfp); + (void) xfclose(e->e_dfp, "sendenvelope", "dfp"); e->e_dfp = NULL; } if (e->e_xfp != NULL) { - (void) fclose(e->e_xfp); + (void) xfclose(e->e_xfp, "sendenvelope", "xfp"); e->e_xfp = NULL; } return; @@ -1824,7 +1844,7 @@ sendall(e, mode) if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) message("deliverable"); } - else if (!bitset(QDONTSEND, q->q_flags)) + else if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) { # ifdef QUEUE /* @@ -1847,7 +1867,9 @@ sendall(e, mode) */ if (mode == SM_VERIFY) + { return; + } for (q = e->e_sendqueue; q != NULL; q = q->q_next) { @@ -1861,6 +1883,8 @@ sendall(e, mode) if (!bitset(QBADADDR, q->q_flags)) continue; + e->e_flags |= EF_FATALERRS; + if (q->q_owner == NULL && strcmp(e->e_from.q_paddr, "<>") != 0) (void) sendtolist(e->e_from.q_paddr, NULL, &e->e_errorqueue, e); diff --git a/usr/src/usr.sbin/sendmail/src/envelope.c b/usr/src/usr.sbin/sendmail/src/envelope.c index c18e68d39f..05ca2b51cc 100644 --- a/usr/src/usr.sbin/sendmail/src/envelope.c +++ b/usr/src/usr.sbin/sendmail/src/envelope.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)envelope.c 6.20 (Berkeley) %G%"; +static char sccsid[] = "@(#)envelope.c 6.21 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -81,13 +81,14 @@ dropenvelope(e) if (tTd(50, 1)) { - printf("dropenvelope %x id=", e); + printf("dropenvelope %x: id=", e); xputs(e->e_id); - printf(" flags=%o\n", e->e_flags); + printf(", flags=%o\n", e->e_flags); } + /* we must have an id to remove disk files */ if (id == NULL) - id = "(none)"; + return; #ifdef LOG if (LogLevel > 84) @@ -95,10 +96,6 @@ dropenvelope(e) id, e->e_flags, getpid()); #endif /* LOG */ - /* we must have an id to remove disk files */ - if (e->e_id == NULL) - return; - /* ** Extract state information from dregs of send list. */ @@ -153,10 +150,10 @@ dropenvelope(e) unlockqueue(e); /* make sure that this envelope is marked unused */ - e->e_id = e->e_df = NULL; if (e->e_dfp != NULL) - (void) fclose(e->e_dfp); + (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); e->e_dfp = NULL; + e->e_id = e->e_df = NULL; #ifdef LOG if (LogLevel > 74) @@ -195,9 +192,10 @@ clearenvelope(e, fullclear) { /* clear out any file information */ if (e->e_xfp != NULL) - (void) fclose(e->e_xfp); + (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); if (e->e_dfp != NULL) - (void) fclose(e->e_dfp); + (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df); + e->e_xfp = e->e_dfp = NULL; } /* now clear out the data */ @@ -379,7 +377,7 @@ closexscript(e) { if (e->e_xfp == NULL) return; - (void) fclose(e->e_xfp); + (void) xfclose(e->e_xfp, "closexscript", e->e_id); e->e_xfp = NULL; } /* @@ -571,10 +569,8 @@ setsender(from, e, delimptr) rewrite(pvp, 3); rewrite(pvp, 1); rewrite(pvp, 4); - cataddr(pvp, buf, sizeof buf, '\0'); - e->e_sender = e->e_returnpath = newstr(buf); - define('f', e->e_sender, e); + define('f', e->e_from.q_paddr, e); /* save the domain spec if this mailer wants it */ if (e->e_from.q_mailer != NULL && diff --git a/usr/src/usr.sbin/sendmail/src/mci.c b/usr/src/usr.sbin/sendmail/src/mci.c index c2a22113b7..2d87895d28 100644 --- a/usr/src/usr.sbin/sendmail/src/mci.c +++ b/usr/src/usr.sbin/sendmail/src/mci.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)mci.c 6.5 (Berkeley) %G%"; +static char sccsid[] = "@(#)mci.c 6.6 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -172,9 +172,9 @@ mci_uncache(mcislot, doquit) else { if (mci->mci_in != NULL) - fclose(mci->mci_in); + xfclose(mci->mci_in, "mci_uncache", "mci_in"); if (mci->mci_out != NULL) - fclose(mci->mci_out); + xfclose(mci->mci_out, "mci_uncache", "mci_out"); mci->mci_in = mci->mci_out = NULL; mci->mci_state = MCIS_CLOSED; mci->mci_exitstat = EX_OK; diff --git a/usr/src/usr.sbin/sendmail/src/parseaddr.c b/usr/src/usr.sbin/sendmail/src/parseaddr.c index 6cba4608d0..df01e83b37 100644 --- a/usr/src/usr.sbin/sendmail/src/parseaddr.c +++ b/usr/src/usr.sbin/sendmail/src/parseaddr.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)parseaddr.c 6.27 (Berkeley) %G%"; +static char sccsid[] = "@(#)parseaddr.c 6.28 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -1483,7 +1483,7 @@ buildaddr(tv, a) return (NULL); } tv++; - if (!strcasecmp(*tv, "error")) + if (strcasecmp(*tv, "error") == 0) { if ((**++tv & 0377) == CANONHOST) { @@ -1524,7 +1524,7 @@ buildaddr(tv, a) for (mp = Mailer; (m = *mp++) != NULL; ) { - if (!strcasecmp(m->m_name, *tv)) + if (strcasecmp(m->m_name, *tv) == 0) break; } if (m == NULL) diff --git a/usr/src/usr.sbin/sendmail/src/queue.c b/usr/src/usr.sbin/sendmail/src/queue.c index 22f57365b9..ec70b8d981 100644 --- a/usr/src/usr.sbin/sendmail/src/queue.c +++ b/usr/src/usr.sbin/sendmail/src/queue.c @@ -10,9 +10,9 @@ #ifndef lint #ifdef QUEUE -static char sccsid[] = "@(#)queue.c 6.25 (Berkeley) %G% (with queueing)"; +static char sccsid[] = "@(#)queue.c 6.26 (Berkeley) %G% (with queueing)"; #else -static char sccsid[] = "@(#)queue.c 6.25 (Berkeley) %G% (without queueing)"; +static char sccsid[] = "@(#)queue.c 6.26 (Berkeley) %G% (without queueing)"; #endif #endif /* not lint */ @@ -158,12 +158,12 @@ queueup(e, queueall, announce) { syserr("queueup: cannot create %s", e->e_df); if (!newid) - (void) fclose(tfp); + (void) xfclose(tfp, "queueup tfp", e->e_id); return; } dfp = fdopen(fd, "w"); (*e->e_putbody)(dfp, ProgMailer, e); - (void) fclose(dfp); + (void) xfclose(dfp, "queueup dfp", e->e_id); e->e_putbody = putbody; } @@ -199,7 +199,7 @@ queueup(e, queueall, announce) lastctladdr = NULL; for (q = e->e_errorqueue; q != NULL; q = q->q_next) { - if (!bitset(QDONTSEND, q->q_flags)) + if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) { ADDRESS *ctladdr; @@ -219,7 +219,7 @@ queueup(e, queueall, announce) for (q = e->e_sendqueue; q != NULL; q = q->q_next) { if (bitset(QQUEUEUP, q->q_flags) || - (queueall && !bitset(QDONTSEND|QSENT, q->q_flags))) + (queueall && !bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags))) { ADDRESS *ctladdr; @@ -317,7 +317,7 @@ queueup(e, queueall, announce) if (rename(tf, qf) < 0) syserr("cannot rename(%s, %s), df=%s", tf, qf, e->e_df); if (e->e_lockfp != NULL) - (void) fclose(e->e_lockfp); + (void) xfclose(e->e_lockfp, "queueup lockfp", e->e_id); e->e_lockfp = tfp; } else @@ -1226,8 +1226,8 @@ queuename(e, type) { static char buf[MAXNAME]; static int pid = -1; - char c1 = 'A'; - char c2 = 'A'; + static char c1 = 'A'; + static char c2 = 'A'; if (e->e_id == NULL) { @@ -1323,9 +1323,12 @@ queuename(e, type) unlockqueue(e) ENVELOPE *e; { + if (tTd(51, 4)) + printf("unlockqueue(%s)\n", e->e_id); + /* if there is a lock file in the envelope, close it */ if (e->e_lockfp != NULL) - fclose(e->e_lockfp); + xfclose(e->e_lockfp, "unlockqueue", e->e_id); e->e_lockfp = NULL; /* remove the transcript */ @@ -1333,7 +1336,7 @@ unlockqueue(e) if (LogLevel > 87) syslog(LOG_DEBUG, "%s: unlock", e->e_id); # endif /* LOG */ - if (!tTd(51, 4)) + if (!tTd(51, 104)) xunlink(queuename(e, 'x')); } diff --git a/usr/src/usr.sbin/sendmail/src/recipient.c b/usr/src/usr.sbin/sendmail/src/recipient.c index c0307cdd3d..55b7518aba 100644 --- a/usr/src/usr.sbin/sendmail/src/recipient.c +++ b/usr/src/usr.sbin/sendmail/src/recipient.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)recipient.c 6.26 (Berkeley) %G%"; +static char sccsid[] = "@(#)recipient.c 6.27 (Berkeley) %G%"; #endif /* not lint */ # include "sendmail.h" @@ -252,7 +252,7 @@ recipient(a, sendq, e) /* check for direct mailing to restricted mailers */ if (a->q_alias == NULL && m == ProgMailer) { - a->q_flags |= QDONTSEND|QBADADDR; + a->q_flags |= QBADADDR; usrerr("550 Cannot mail directly to programs", m->m_name); } @@ -298,7 +298,7 @@ recipient(a, sendq, e) if (tTd(29, 7)) printf("at trylocaluser %s\n", a->q_user); - if (bitset(QDONTSEND|QVERIFIED, a->q_flags)) + if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags)) return (a); if (m == InclMailer) @@ -306,7 +306,7 @@ recipient(a, sendq, e) a->q_flags |= QDONTSEND; if (a->q_alias == NULL) { - a->q_flags |= QDONTSEND|QBADADDR; + a->q_flags |= QBADADDR; usrerr("550 Cannot mail directly to :include:s"); } else @@ -328,13 +328,13 @@ recipient(a, sendq, e) /* check if writable or creatable */ if (a->q_alias == NULL && !QueueRun) { - a->q_flags |= QDONTSEND|QBADADDR; + a->q_flags |= QBADADDR; usrerr("550 Cannot mail directly to files"); } else if ((stat(buf, &stb) >= 0) ? (!writable(&stb)) : (*p = '\0', safefile(buf, getruid(), S_IWRITE|S_IEXEC) != 0)) { - a->q_flags |= QDONTSEND|QBADADDR; + a->q_flags |= QBADADDR; giveresponse(EX_CANTCREAT, m, NULL, e); } } @@ -410,7 +410,7 @@ recipient(a, sendq, e) pw = finduser(buf, &fuzzy); if (pw == NULL) { - a->q_flags |= QDONTSEND|QBADADDR; + a->q_flags |= QBADADDR; giveresponse(EX_NOUSER, m, NULL, e); } else @@ -423,7 +423,7 @@ recipient(a, sendq, e) a->q_user = newstr(pw->pw_name); if (findusercount++ > 3) { - a->q_flags |= QDONTSEND|QBADADDR; + a->q_flags |= QBADADDR; usrerr("554 aliasing/forwarding loop for %s broken", pw->pw_name); return (a); @@ -691,7 +691,7 @@ include(fname, forwarding, ctladdr, sendq, e) if (bitset(EF_VRFYONLY, e->e_flags)) { /* don't do any more now */ - fclose(fp); + xfclose(fp, "include", fname); return 0; } @@ -732,7 +732,7 @@ include(fname, forwarding, ctladdr, sendq, e) ctladdr->q_flags |= QDONTSEND; } - (void) fclose(fp); + (void) xfclose(fp, "include", fname); FileName = oldfilename; LineNumber = oldlinenumber; return 0; diff --git a/usr/src/usr.sbin/sendmail/src/savemail.c b/usr/src/usr.sbin/sendmail/src/savemail.c index 03be2babea..eba0b2cac5 100644 --- a/usr/src/usr.sbin/sendmail/src/savemail.c +++ b/usr/src/usr.sbin/sendmail/src/savemail.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)savemail.c 6.21 (Berkeley) %G%"; +static char sccsid[] = "@(#)savemail.c 6.22 (Berkeley) %G%"; #endif /* not lint */ # include @@ -58,7 +58,10 @@ savemail(e) typedef int (*fnptr)(); if (tTd(6, 1)) - printf("\nsavemail, ErrorMode = %c\n", ErrorMode); + { + printf("\nsavemail, ErrorMode = %c\n e_from=", ErrorMode); + printaddr(&e->e_from, FALSE); + } if (bitset(EF_RESPONSE, e->e_flags)) return; @@ -176,14 +179,13 @@ savemail(e) while (fgets(buf, sizeof buf, fp) != NULL && !ferror(stdout)) fputs(buf, stdout); - (void) fclose(fp); + (void) xfclose(fp, "savemail transcript", e->e_id); } printf("Original message will be saved in dead.letter.\r\n"); state = ESM_DEADLETTER; break; case ESM_MAIL: - case ESM_POSTMASTER: /* ** If mailing back, do it. ** Throw away all further output. Don't alias, @@ -193,52 +195,54 @@ savemail(e) ** joe@x, which gives a response, etc. Also force ** the mail to be delivered even if a version of ** it has already been sent to the sender. - ** - ** Clever technique for computing rpath from - ** Eric Wassenaar . */ - if (state == ESM_MAIL) + if (strcmp(e->e_from.q_paddr, "<>") != 0) + (void) sendtolist(e->e_from.q_paddr, + (ADDRESS *) NULL, + &e->e_errorqueue, e); + + /* deliver a cc: to the postmaster if desired */ + if (PostMasterCopy != NULL) { - char *rpath; + auto ADDRESS *rlist = NULL; - if (e->e_returnpath != e->e_sender) - rpath = e->e_returnpath; - else - rpath = e->e_from.q_paddr; - if (strcmp(rpath, "<>") != 0) - (void) sendtolist(rpath, + (void) sendtolist(PostMasterCopy, (ADDRESS *) NULL, - &e->e_errorqueue, e); + &rlist, e); + (void) returntosender(e->e_message, + rlist, FALSE, e); + } + q = e->e_errorqueue; + if (q == NULL) + { + /* this is an error-error */ + state = ESM_POSTMASTER; + break; + } + if (returntosender(e->e_message != NULL ? e->e_message : + "Unable to deliver mail", + q, (e->e_class >= 0), e) == 0) + { + state = ESM_DONE; + break; + } - /* deliver a cc: to the postmaster if desired */ - if (PostMasterCopy != NULL) - { - auto ADDRESS *rlist = NULL; + /* didn't work -- return to postmaster */ + state = ESM_POSTMASTER; + break; - (void) sendtolist(PostMasterCopy, - (ADDRESS *) NULL, - &rlist, e); - (void) returntosender(e->e_message, - rlist, FALSE, e); - } - q = e->e_errorqueue; - if (q == NULL) - { - /* this is an error-error */ - state = ESM_USRTMP; - break; - } - } - else + case ESM_POSTMASTER: + /* + ** Similar to previous case, but to system postmaster. + */ + + if (parseaddr("postmaster", q, 0, '\0', NULL, e) == NULL) { - if (parseaddr("postmaster", q, 0, '\0', NULL, e) == NULL) - { - syserr("553 cannot parse postmaster!"); - ExitStat = EX_SOFTWARE; - state = ESM_USRTMP; - break; - } + syserr("553 cannot parse postmaster!"); + ExitStat = EX_SOFTWARE; + state = ESM_USRTMP; + break; } if (returntosender(e->e_message != NULL ? e->e_message : "Unable to deliver mail", @@ -248,7 +252,8 @@ savemail(e) break; } - state = state == ESM_MAIL ? ESM_POSTMASTER : ESM_USRTMP; + /* didn't work -- last resort */ + state = ESM_USRTMP; break; case ESM_DEADLETTER: @@ -326,7 +331,7 @@ savemail(e) putline("\n", fp, FileMailer); (void) fflush(fp); state = ferror(fp) ? ESM_PANIC : ESM_DONE; - (void) fclose(fp); + (void) xfclose(fp, "savemail", "/usr/tmp/dead.letter"); break; default: @@ -374,6 +379,7 @@ returntosender(msg, returnq, sendbody, e) char buf[MAXNAME]; extern putheader(), errbody(); register ENVELOPE *ee; + ENVELOPE *oldcur = CurEnv; extern ENVELOPE *newenvelope(); ENVELOPE errenvelope; static int returndepth; @@ -381,9 +387,8 @@ returntosender(msg, returnq, sendbody, e) if (tTd(6, 1)) { - printf("Return To Sender: msg=\"%s\", depth=%d, e=%x,\n", + printf("Return To Sender: msg=\"%s\", depth=%d, e=%x, returnq=", msg, returndepth, e); - printf("\treturnq="); printaddr(returnq, TRUE); } @@ -397,8 +402,7 @@ returntosender(msg, returnq, sendbody, e) } SendBody = sendbody; - define('g', e->e_sender, e); - define('<', e->e_returnpath, e); + define('g', e->e_from.q_paddr, e); ee = newenvelope(&errenvelope, e); define('a', "\201b", ee); ee->e_puthdr = putheader; @@ -434,12 +438,7 @@ returntosender(msg, returnq, sendbody, e) /* fake up an address header for the from person */ expand("\201n", buf, &buf[sizeof buf - 1], e); - ee->e_sender = newstr(buf); - if (ConfigLevel >= 4) - ee->e_returnpath = "<>"; - else - ee->e_returnpath = ee->e_sender; - if (parseaddr(buf, &ee->e_from, -1, '\0', NULL, e) == NULL) + if (parseaddr(buf, &ee->e_from, 1, '\0', NULL, e) == NULL) { syserr("553 Can't parse myself!"); ExitStat = EX_SOFTWARE; @@ -458,7 +457,7 @@ returntosender(msg, returnq, sendbody, e) /* restore state */ dropenvelope(ee); - CurEnv = CurEnv->e_parent; + CurEnv = oldcur; returndepth--; /* should check for delivery errors here */ @@ -491,6 +490,14 @@ errbody(fp, m, e) char buf[MAXLINE]; char *p; + if (e->e_parent == NULL) + { + syserr("errbody: null parent"); + putline("\n", fp, m); + putline(" ----- Original message lost -----\n", fp, m); + return; + } + /* ** Output error message header (if specified and available). */ @@ -528,16 +535,16 @@ errbody(fp, m, e) if ((xfile = fopen(p, "r")) == NULL) { syserr("Cannot open %s", p); - fprintf(fp, " ----- Transcript of session is unavailable -----\n"); + putline(" ----- Transcript of session is unavailable -----\n", fp, m); } else { - fprintf(fp, " ----- Transcript of session follows -----\n"); + putline(" ----- Transcript of session follows -----\n", fp, m); if (e->e_xfp != NULL) (void) fflush(e->e_xfp); while (fgets(buf, sizeof buf, xfile) != NULL) putline(buf, fp, m); - (void) fclose(xfile); + (void) xfclose(xfile, "errbody xscript", p); } errno = 0; @@ -547,7 +554,7 @@ errbody(fp, m, e) if (NoReturn) SendBody = FALSE; - if (e->e_parent->e_dfp != NULL) + if (e->e_parent->e_df != NULL) { if (SendBody) { diff --git a/usr/src/usr.sbin/sendmail/src/sendmail.h b/usr/src/usr.sbin/sendmail/src/sendmail.h index f5d13edcf0..4e43b15332 100644 --- a/usr/src/usr.sbin/sendmail/src/sendmail.h +++ b/usr/src/usr.sbin/sendmail/src/sendmail.h @@ -5,7 +5,7 @@ * * %sccs.include.redist.c% * - * @(#)sendmail.h 6.27 (Berkeley) %G% + * @(#)sendmail.h 6.28 (Berkeley) %G% */ /* @@ -15,7 +15,7 @@ # ifdef _DEFINE # define EXTERN # ifndef lint -static char SmailSccsId[] = "@(#)sendmail.h 6.27 %G%"; +static char SmailSccsId[] = "@(#)sendmail.h 6.28 %G%"; # endif lint # else /* _DEFINE */ # define EXTERN extern @@ -249,8 +249,6 @@ struct envelope char *e_to; /* the target person */ char *e_receiptto; /* return receipt address */ ADDRESS e_from; /* the person it is from */ - char *e_sender; /* string version of from person */ - char *e_returnpath; /* string version of return path */ char **e_fromdomain; /* the domain part of the sender */ ADDRESS *e_returnto; /* place to return the message to */ ADDRESS *e_sendqueue; /* list of message recipients */ diff --git a/usr/src/usr.sbin/sendmail/src/usersmtp.c b/usr/src/usr.sbin/sendmail/src/usersmtp.c index 488ef1b672..01eefc93d3 100644 --- a/usr/src/usr.sbin/sendmail/src/usersmtp.c +++ b/usr/src/usr.sbin/sendmail/src/usersmtp.c @@ -10,9 +10,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)usersmtp.c 6.15 (Berkeley) %G% (with SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 6.16 (Berkeley) %G% (with SMTP)"; #else -static char sccsid[] = "@(#)usersmtp.c 6.15 (Berkeley) %G% (without SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 6.16 (Berkeley) %G% (without SMTP)"; #endif #endif /* not lint */ @@ -191,7 +191,10 @@ smtpmailfrom(m, mci, e) mci->mci_state = MCIS_ACTIVE; - expand("\201<", buf, &buf[sizeof buf - 1], e); + if (bitset(EF_RESPONSE, e->e_flags)) + (void) strcpy(buf, ""); + else + expand("\201g", buf, &buf[sizeof buf - 1], e); if (e->e_from.q_mailer == LocalMailer || !bitnset(M_FROMPATH, m->m_flags)) { @@ -497,6 +500,9 @@ reply(m, mci, e, timeout) if (mci->mci_state == MCIS_CLOSED) return (SMTPCLOSING); + if (mci->mci_out != NULL) + fflush(mci->mci_out); + /* get the line from the other side */ p = sfgets(SmtpReplyBuffer, sizeof SmtpReplyBuffer, mci->mci_in, timeout); @@ -605,11 +611,19 @@ smtpmessage(f, m, mci, va_alist) VA_START(mci); (void) vsprintf(SmtpMsgBuffer, f, ap); VA_END; + if (tTd(18, 1) || Verbose) nmessage(">>> %s", SmtpMsgBuffer); if (mci->mci_out != NULL) + { fprintf(mci->mci_out, "%s%s", SmtpMsgBuffer, m == NULL ? "\r\n" : m->m_eol); + (void) fflush(mci->mci_out); + if (ferror(mci->mci_out)) + syserr("smtpmessage: ERROR mci_out"); + } + else + syserr("smtpmessage: NULL mci_out"); } # endif /* SMTP */ diff --git a/usr/src/usr.sbin/sendmail/src/util.c b/usr/src/usr.sbin/sendmail/src/util.c index 195641789c..508582315f 100644 --- a/usr/src/usr.sbin/sendmail/src/util.c +++ b/usr/src/usr.sbin/sendmail/src/util.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)util.c 6.11 (Berkeley) %G%"; +static char sccsid[] = "@(#)util.c 6.12 (Berkeley) %G%"; #endif /* not lint */ # include "sendmail.h" @@ -616,6 +616,29 @@ xunlink(f) # endif /* LOG */ } /* +** XFCLOSE -- close a file, doing logging as appropriate. +** +** Parameters: +** fp -- file pointer for the file to close +** a, b -- miscellaneous crud to print for debugging +** +** Returns: +** none. +** +** Side Effects: +** fp is closed. +*/ + +xfclose(fp, a, b) + FILE *fp; + char *a, *b; +{ + if (tTd(9, 99)) + printf("xfclose(%x) %s %s\n", fp, a, b); + if (fclose(fp) < 0 && tTd(9, 99)) + printf("xfclose FAILURE: %s\n", errstring(errno)); +} + /* ** SFGETS -- "safe" fgets -- times out and ignores random interrupts. ** ** Parameters: -- 2.20.1