+ /* deliver a cc: to the postmaster if desired */
+ if (PostMasterCopy != NULL)
+ sendtolist(PostMasterCopy,
+ (ADDRESS *) NULL,
+ &e->e_errorqueue);
+ q = e->e_errorqueue;
+ }
+ else
+ {
+ if (parseaddr("postmaster", q, 0, '\0') == NULL)
+ {
+ syserr("cannot parse postmaster!");
+ ExitStat = EX_SOFTWARE;
+ state = ESM_USRTMP;
+ break;
+ }
+ }
+ if (returntosender(e->e_message != NULL ? e->e_message :
+ "Unable to deliver mail",
+ q, TRUE) == 0)
+ {
+ state = ESM_DONE;
+ break;
+ }
+
+ state = state == ESM_MAIL ? ESM_POSTMASTER : ESM_USRTMP;
+ break;
+
+ case ESM_DEADLETTER:
+ /*
+ ** Save the message in dead.letter.
+ ** If we weren't mailing back, and the user is
+ ** local, we should save the message in
+ ** ~/dead.letter so that the poor person doesn't
+ ** have to type it over again -- and we all know
+ ** what poor typists UNIX users are.
+ */
+
+ p = NULL;
+ if (e->e_from.q_mailer == LocalMailer)
+ {
+ if (e->e_from.q_home != NULL)
+ p = e->e_from.q_home;
+ else if ((pw = getpwnam(e->e_from.q_user)) != NULL)
+ p = pw->pw_dir;
+ }
+ if (p == NULL)
+ {
+ syserr("Can't return mail to %s", e->e_from.q_paddr);
+ state = ESM_MAIL;
+ break;
+ }
+ if (e->e_dfp != NULL)
+ {
+ auto ADDRESS *q;
+ bool oldverb = Verbose;
+
+ /* we have a home directory; open dead.letter */
+ define('z', p, e);
+ expand("\001z/dead.letter", buf, &buf[sizeof buf - 1], e);
+ Verbose = TRUE;
+ message(Arpa_Info, "Saving message in %s", buf);
+ Verbose = oldverb;
+ e->e_to = buf;
+ q = NULL;
+ sendtolist(buf, (ADDRESS *) NULL, &q);
+ if (deliver(e, q) == 0)
+ state = ESM_DONE;
+ else
+ state = ESM_MAIL;
+ }
+ else
+ {
+ /* no data file -- try mailing back */
+ state = ESM_MAIL;
+ }
+ break;
+
+ case ESM_USRTMP:
+ /*
+ ** Log the mail in /usr/tmp/dead.letter.
+ */
+
+ fp = dfopen("/usr/tmp/dead.letter", "a");
+ if (fp == NULL)
+ {
+ state = ESM_PANIC;
+ break;
+ }
+
+ putfromline(fp, ProgMailer);
+ (*e->e_puthdr)(fp, ProgMailer, e);
+ putline("\n", fp, ProgMailer);
+ (*e->e_putbody)(fp, ProgMailer, e);
+ putline("\n", fp, ProgMailer);
+ (void) fflush(fp);
+ state = ferror(fp) ? ESM_PANIC : ESM_DONE;
+ (void) fclose(fp);
+ break;
+
+ default:
+ syserr("savemail: unknown state %d", state);
+
+ /* fall through ... */
+
+ case ESM_PANIC:
+ syserr("savemail: HELP!!!!");
+# ifdef LOG
+ if (LogLevel >= 1)
+ syslog(LOG_ALERT, "savemail: HELP!!!!");
+# endif LOG
+
+ /* leave the locked queue & transcript files around */
+ exit(EX_SOFTWARE);