📄 savemail.c
字号:
case ESM_PANIC: /* leave the locked queue & transcript files around */ syserr("!554 savemail: cannot save rejected email anywhere"); } }}/*** RETURNTOSENDER -- return a message to the sender with an error.**** Parameters:** msg -- the explanatory message.** returnq -- the queue of people to send the message to.** sendbody -- if TRUE, also send back the body of the** message; otherwise just send the header.** e -- the current envelope.**** Returns:** zero -- if everything went ok.** else -- some error.**** Side Effects:** Returns the current message to the sender via** mail.*/static bool SendBody;#define MAXRETURNS 6 /* max depth of returning messages */#define ERRORFUDGE 100 /* nominal size of error message text */returntosender(msg, returnq, sendbody, e) char *msg; ADDRESS *returnq; bool sendbody; register ENVELOPE *e;{ char buf[MAXNAME]; extern putheader(), errbody(); register ENVELOPE *ee; ENVELOPE *oldcur = CurEnv; ENVELOPE errenvelope; static int returndepth; register ADDRESS *q; if (returnq == NULL) return (-1); if (msg == NULL) msg = "Unable to deliver mail"; if (tTd(6, 1)) { printf("Return To Sender: msg=\"%s\", depth=%d, e=%x, returnq=", msg, returndepth, e); printaddr(returnq, TRUE); } if (++returndepth >= MAXRETURNS) { if (returndepth != MAXRETURNS) syserr("554 returntosender: infinite recursion on %s", returnq->q_paddr); /* don't "unrecurse" and fake a clean exit */ /* returndepth--; */ return (0); } SendBody = sendbody; define('g', e->e_from.q_paddr, e); define('u', NULL, e); ee = newenvelope(&errenvelope, e); define('a', "\201b", ee); define('r', "internal", ee); define('s', "localhost", ee); define('_', "localhost", ee); ee->e_puthdr = putheader; ee->e_putbody = errbody; ee->e_flags |= EF_RESPONSE|EF_METOO; if (!bitset(EF_OLDSTYLE, e->e_flags)) ee->e_flags &= ~EF_OLDSTYLE; ee->e_sendqueue = returnq; ee->e_msgsize = ERRORFUDGE; if (!NoReturn) ee->e_msgsize += e->e_msgsize; initsys(ee); for (q = returnq; q != NULL; q = q->q_next) { if (bitset(QBADADDR, q->q_flags)) continue; if (!bitset(QDONTSEND, q->q_flags)) ee->e_nrcpts++; if (!DontPruneRoutes && pruneroute(q->q_paddr)) parseaddr(q->q_paddr, q, RF_COPYPARSE, '\0', NULL, e); if (q->q_alias == NULL) addheader("To", q->q_paddr, ee); }# ifdef LOG if (LogLevel > 5) syslog(LOG_INFO, "%s: %s: return to sender: %s", e->e_id, ee->e_id, msg);# endif (void) sprintf(buf, "Returned mail: %s", msg); addheader("Subject", buf, ee); if (SendMIMEErrors) { addheader("MIME-Version", "1.0", ee); (void) sprintf(buf, "%s.%ld/%s", ee->e_id, curtime(), MyHostName); ee->e_msgboundary = newstr(buf); (void) sprintf(buf, "multipart/mixed; boundary=\"%s\"", ee->e_msgboundary); addheader("Content-Type", buf, ee); } /* fake up an address header for the from person */ expand("\201n", buf, &buf[sizeof buf - 1], e); if (parseaddr(buf, &ee->e_from, RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL) { syserr("553 Can't parse myself!"); ExitStat = EX_SOFTWARE; returndepth--; return (-1); } ee->e_sender = ee->e_from.q_paddr; /* push state into submessage */ CurEnv = ee; define('f', "\201n", ee); define('x', "Mail Delivery Subsystem", ee); eatheader(ee, TRUE); /* mark statistics */ markstats(ee, NULLADDR); /* actually deliver the error message */ sendall(ee, SM_DEFAULT); /* restore state */ dropenvelope(ee); CurEnv = oldcur; returndepth--; /* should check for delivery errors here */ return (0);}/*** ERRBODY -- output the body of an error message.**** Typically this is a copy of the transcript plus a copy of the** original offending message.**** Parameters:** mci -- the mailer connection information.** e -- the envelope we are working in.**** Returns:** none**** Side Effects:** Outputs the body of an error message.*/errbody(mci, e) register MCI *mci; register ENVELOPE *e;{ register FILE *xfile; char *p; register ADDRESS *q; bool printheader; char buf[MAXLINE]; if (e->e_parent == NULL) { syserr("errbody: null parent"); putline(" ----- Original message lost -----\n", mci); return; } /* ** Output MIME header. */ if (e->e_msgboundary != NULL) { putline("This is a MIME-encapsulated message", mci); putline("", mci); (void) sprintf(buf, "--%s", e->e_msgboundary); putline(buf, mci); putline("", mci); } /* ** Output introductory information. */ for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) if (bitset(QBADADDR, q->q_flags)) break; if (q == NULL && !bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags)) { putline(" **********************************************", mci); putline(" ** THIS IS A WARNING MESSAGE ONLY **", mci); putline(" ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **", mci); putline(" **********************************************", mci); putline("", mci); } sprintf(buf, "The original message was received at %s", arpadate(ctime(&e->e_parent->e_ctime))); putline(buf, mci); expand("from \201_", buf, &buf[sizeof buf - 1], e->e_parent); putline(buf, mci); putline("", mci); /* ** Output error message header (if specified and available). */ if (ErrMsgFile != NULL) { if (*ErrMsgFile == '/') { xfile = fopen(ErrMsgFile, "r"); if (xfile != NULL) { while (fgets(buf, sizeof buf, xfile) != NULL) { expand(buf, buf, &buf[sizeof buf - 1], e); putline(buf, mci); } (void) fclose(xfile); putline("\n", mci); } } else { expand(ErrMsgFile, buf, &buf[sizeof buf - 1], e); putline(buf, mci); putline("", mci); } } /* ** Output message introduction */ printheader = TRUE; for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) { if (bitset(QBADADDR|QREPORT, q->q_flags)) { if (printheader) { putline(" ----- The following addresses had delivery problems -----", mci); printheader = FALSE; } strcpy(buf, q->q_paddr); if (bitset(QBADADDR, q->q_flags)) strcat(buf, " (unrecoverable error)"); else strcat(buf, " (transient failure)"); putline(buf, mci); if (q->q_alias != NULL) { strcpy(buf, " (expanded from: "); strcat(buf, q->q_alias->q_paddr); strcat(buf, ")"); putline(buf, mci); } } } if (!printheader) putline("\n", mci); /* ** Output transcript of errors */ (void) fflush(stdout); p = queuename(e->e_parent, 'x'); if ((xfile = fopen(p, "r")) == NULL) { syserr("Cannot open %s", p); putline(" ----- Transcript of session is unavailable -----\n", mci); } else { putline(" ----- Transcript of session follows -----\n", mci); if (e->e_xfp != NULL) (void) fflush(e->e_xfp); while (fgets(buf, sizeof buf, xfile) != NULL) putline(buf, mci); (void) xfclose(xfile, "errbody xscript", p); } errno = 0; /* ** Output text of original message */ if (NoReturn) SendBody = FALSE; putline("", mci); if (e->e_parent->e_df != NULL) { if (SendBody) putline(" ----- Original message follows -----\n", mci); else putline(" ----- Message header follows -----\n", mci); (void) fflush(mci->mci_out); if (e->e_msgboundary != NULL) { putline("", mci); (void) sprintf(buf, "--%s", e->e_msgboundary); putline(buf, mci); putline("Content-Type: message/rfc822", mci); putline("", mci); } putheader(mci, e->e_parent); putline("", mci); if (SendBody) putbody(mci, e->e_parent, e->e_msgboundary); else putline(" ----- Message body suppressed -----", mci); } else { putline(" ----- No message was collected -----\n", mci); } if (e->e_msgboundary != NULL) { putline("", mci); (void) sprintf(buf, "--%s--", e->e_msgboundary); putline(buf, mci); } putline("", mci); /* ** Cleanup and exit */ if (errno != 0) syserr("errbody: I/O error");}/*** PRUNEROUTE -- prune an RFC-822 source route** ** Trims down a source route to the last internet-registered hop.** This is encouraged by RFC 1123 section 5.3.3.** ** Parameters:** addr -- the address** ** Returns:** TRUE -- address was modified** FALSE -- address could not be pruned** ** Side Effects:** modifies addr in-place*/pruneroute(addr) char *addr;{#if NAMED_BIND char *start, *at, *comma; char c; int rcode; char hostbuf[BUFSIZ]; char *mxhosts[MAXMXHOSTS + 1]; /* check to see if this is really a route-addr */ if (*addr != '<' || addr[1] != '@' || addr[strlen(addr) - 1] != '>') return FALSE; start = strchr(addr, ':'); at = strrchr(addr, '@'); if (start == NULL || at == NULL || at < start) return FALSE; /* slice off the angle brackets */ strcpy(hostbuf, at + 1); hostbuf[strlen(hostbuf) - 1] = '\0'; while (start) { if (getmxrr(hostbuf, mxhosts, FALSE, &rcode) > 0) { strcpy(addr + 1, start + 1); return TRUE; } c = *start; *start = '\0'; comma = strrchr(addr, ','); if (comma && comma[1] == '@') strcpy(hostbuf, comma + 2); else comma = 0; *start = c; start = comma; }#endif return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -