|
|
1.1 ! root 1: # include <stdio.h> ! 2: # include <pwd.h> ! 3: # include "dlvrmail.h" ! 4: ! 5: static char SccsId[] = "@(#)savemail.c 1.4 8/2/80"; ! 6: ! 7: /* ! 8: ** SAVEMAIL -- Save mail on error ! 9: ** ! 10: ** If the MailBack flag is set, mail it back to the originator ! 11: ** together with an error message; otherwise, just put it in ! 12: ** dead.letter in the user's home directory (if he exists on ! 13: ** this machine). ! 14: ** ! 15: ** Parameters: ! 16: ** none ! 17: ** ! 18: ** Returns: ! 19: ** none ! 20: ** ! 21: ** Side Effects: ! 22: ** Saves the letter, by writing or mailing it back to the ! 23: ** sender, or by putting it in dead.letter in her home ! 24: ** directory. ! 25: ** ! 26: ** WARNING: the user id is reset to the original user. ! 27: */ ! 28: ! 29: # define MY_NAME "~MAILER~DAEMON~" ! 30: ! 31: savemail() ! 32: { ! 33: register struct passwd *pw; ! 34: register FILE *xfile; ! 35: char buf[MAXLINE+1]; ! 36: extern errhdr(); ! 37: auto addrq to_addr; ! 38: extern struct passwd *getpwnam(); ! 39: register char *p; ! 40: register int i; ! 41: auto long tim; ! 42: extern int errno; ! 43: extern char *ttypath(); ! 44: extern char *ctime(); ! 45: extern addrq *parse(); ! 46: static int exclusive; ! 47: ! 48: if (exclusive++) ! 49: return; ! 50: ! 51: /* ! 52: ** In the unhappy event we don't know who to return the mail ! 53: ** to, make someone up. ! 54: */ ! 55: ! 56: if (From.q_paddr == NULL) ! 57: { ! 58: if (parse("root", &From, 0) == NULL) ! 59: { ! 60: syserr("Cannot parse root!"); ! 61: ExitStat = EX_SOFTWARE; ! 62: finis(); ! 63: } ! 64: } ! 65: ! 66: /* ! 67: ** If called from Eric Schmidt's network, do special mailback. ! 68: ** Fundamentally, this is the mailback case except that ! 69: ** it returns an OK exit status (assuming the return ! 70: ** worked). ! 71: */ ! 72: ! 73: if (BerkNet) ! 74: { ! 75: ExitStat = EX_OK; ! 76: MailBack++; ! 77: } ! 78: ! 79: /* ! 80: ** If writing back, do it. ! 81: ** If the user is still logged in on the same terminal, ! 82: ** then write the error messages back to hir (sic). ! 83: ** If not, set the MailBack flag so that it will get ! 84: ** mailed back instead. ! 85: */ ! 86: ! 87: if (WriteBack) ! 88: { ! 89: p = ttypath(); ! 90: if (p == NULL || freopen(p, "w", stdout) == NULL) ! 91: { ! 92: MailBack++; ! 93: errno = 0; ! 94: } ! 95: else ! 96: { ! 97: xfile = fopen(Transcript, "r"); ! 98: if (xfile == NULL) ! 99: syserr("Cannot open %s", Transcript); ! 100: printf("\r\nMessage from %s\r\n", MY_NAME); ! 101: printf("Errors occurred while sending mail, transcript follows:\r\n"); ! 102: while (fgets(buf, sizeof buf, xfile) && !ferror(stdout)) ! 103: fputs(buf, stdout); ! 104: if (ferror(stdout)) ! 105: syserr("savemail: stdout: write err"); ! 106: fclose(xfile); ! 107: } ! 108: } ! 109: ! 110: /* ! 111: ** If mailing back, do it. ! 112: ** Throw away all further output. Don't do aliases, since ! 113: ** this could cause loops, e.g., if joe mails to x:joe, ! 114: ** and for some reason the network for x: is down, then ! 115: ** the response gets sent to x:joe, which gives a ! 116: ** response, etc. Also force the mail to be delivered ! 117: ** even if a version of it has already been sent to the ! 118: ** sender. ! 119: */ ! 120: ! 121: if (MailBack || From.q_mailer != &Mailer[0]) ! 122: { ! 123: freopen("/dev/null", "w", stdout); ! 124: NoAlias++; ! 125: ForceMail++; ! 126: ! 127: /* fake up an address header for the from person */ ! 128: bmove((char *) &From, (char *) &to_addr, sizeof to_addr); ! 129: if (parse(MY_NAME, &From, -1) == NULL) ! 130: { ! 131: syserr("Can't parse myself!"); ! 132: ExitStat = EX_SOFTWARE; ! 133: finis(); ! 134: } ! 135: i = deliver(&to_addr, errhdr); ! 136: bmove((char *) &to_addr, (char *) &From, sizeof From); ! 137: if (i != 0) ! 138: syserr("Can't return mail to %s", p); ! 139: else ! 140: return; ! 141: } ! 142: ! 143: /* ! 144: ** Save the message in dead.letter. ! 145: ** If we weren't mailing back, and the user is local, we ! 146: ** should save the message in dead.letter so that the ! 147: ** poor person doesn't have to type it over again -- ! 148: ** and we all know what poor typists programmers are. ! 149: */ ! 150: ! 151: setuid(getuid()); ! 152: setgid(getgid()); ! 153: setpwent(); ! 154: if (From.q_mailer == &Mailer[0] && (pw = getpwnam(From.q_user)) != NULL) ! 155: { ! 156: /* user has a home directory */ ! 157: p = pw->pw_dir; ! 158: } ! 159: else ! 160: { ! 161: syserr("Can't return mail to %s (pw=%u)", From.q_paddr, pw); ! 162: # ifdef DEBUG ! 163: p = "/usr/tmp"; ! 164: # else ! 165: p = NULL; ! 166: # endif ! 167: } ! 168: if (p != NULL) ! 169: { ! 170: /* we have a home directory; open dead.letter */ ! 171: strcpy(buf, p); ! 172: strcat(buf, "/dead.letter"); ! 173: xfile = fopen(buf, "a"); ! 174: if (xfile == NULL) ! 175: printf("Cannot save mail, sorry\n"); ! 176: else ! 177: { ! 178: rewind(stdin); ! 179: errno = 0; ! 180: time(&tim); ! 181: fprintf(xfile, "----- Mail saved at %s", ctime(&tim)); ! 182: while (fgets(buf, sizeof buf, stdin) && !ferror(xfile)) ! 183: fputs(buf, xfile); ! 184: fputs("\n", xfile); ! 185: if (ferror(xfile)) ! 186: syserr("savemail: dead.letter: write err"); ! 187: fclose(xfile); ! 188: printf("Letter saved in dead.letter\n"); ! 189: } ! 190: } ! 191: else ! 192: ! 193: /* add terminator to writeback message */ ! 194: if (WriteBack) ! 195: printf("-----\r\n"); ! 196: } ! 197: /* ! 198: ** ERRHDR -- Output the header for error mail. ! 199: ** ! 200: ** This is the edit filter to error mailbacks. ! 201: ** ! 202: ** Algorithm: ! 203: ** Output fixed header. ! 204: ** Output the transcript part. ! 205: ** Output the original message. ! 206: ** ! 207: ** Parameters: ! 208: ** xfile -- the transcript file. ! 209: ** fp -- the output file. ! 210: ** ! 211: ** Returns: ! 212: ** none ! 213: ** ! 214: ** Side Effects: ! 215: ** input from xfile ! 216: ** output to fp ! 217: ** ! 218: ** Called By: ! 219: ** deliver ! 220: */ ! 221: ! 222: ! 223: errhdr(fp) ! 224: register FILE *fp; ! 225: { ! 226: char copybuf[512]; ! 227: register int i; ! 228: register int xfile; ! 229: extern int errno; ! 230: ! 231: if ((xfile = open(Transcript, 0)) < 0) ! 232: syserr("Cannot open %s", Transcript); ! 233: fflush(stdout); ! 234: errno = 0; ! 235: fprintf(fp, "To: %s\n", To); ! 236: fprintf(fp, "Subject: Unable to deliver mail\n"); ! 237: fprintf(fp, "\n ----- Transcript of session follows -----\n"); ! 238: fflush(fp); ! 239: while ((i = read(xfile, copybuf, sizeof copybuf)) > 0) ! 240: write(fileno(fp), copybuf, i); ! 241: fprintf(fp, "\n ----- Unsent message follows -----\n"); ! 242: fflush(fp); ! 243: rewind(stdin); ! 244: while ((i = read(fileno(stdin), copybuf, sizeof copybuf)) > 0) ! 245: write(fileno(fp), copybuf, i); ! 246: close(xfile); ! 247: if (errno != 0) ! 248: syserr("errhdr: I/O error"); ! 249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.