Annotation of 40BSD/cmd/delivermail/savemail.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.