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

Defined functions

errhdr defined in line 222; used 2 times
savemail defined in line 29; used 1 times

Defined variables

SccsId defined in line 5; never used
Last modified: 1981-02-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 994
Valid CSS Valid XHTML 1.0 Strict