Annotation of 41BSD/cmd/delivermail/savemail.c, revision 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.