Annotation of 43BSDReno/usr.sbin/sendmail/aux/mail-dm.c, revision 1.1

1.1     ! root        1: #include <arpa/netopen.h>
        !             2: #include "srvrftp.h"
        !             3: #include <statbuf.h>
        !             4: #include <arpa/hostnames.h>
        !             5: #include <io_buf.h>
        !             6: #include <arpa/mail.h>
        !             7: #include <ident.h>
        !             8: #include <signal.h>
        !             9: #include <log.h>
        !            10: extern int fout;
        !            11: 
        !            12: static char SccsId[] = "@(#)mail-dm.c  4.1     7/25/83";
        !            13: 
        !            14: /*
        !            15: Name:
        !            16:        mail
        !            17: 
        !            18: Function:
        !            19:        handle the MAIL <user> command over the command connection
        !            20: 
        !            21: Algorithm:
        !            22:        see if we have a known user
        !            23: 
        !            24:        if mailbox file can't be gotten
        !            25:                return
        !            26:        tell him it is ok to go ahead with mail
        !            27: 
        !            28:        while he doesn't type a period
        !            29:                read and write data
        !            30:        say completed
        !            31: 
        !            32: Parameters:
        !            33:        username in arg
        !            34: 
        !            35: Returns:
        !            36:        nothing
        !            37: 
        !            38: Globals:
        !            39:        arg
        !            40:        username=
        !            41: 
        !            42: Calls:
        !            43:        strmove
        !            44:        getuser
        !            45:        loguser
        !            46:        openmail
        !            47:        closemail
        !            48:        getline
        !            49:        chown (sys)
        !            50:        time (sys)
        !            51:        printf (sys)
        !            52:        getch   (util)
        !            53:        putch   (util)
        !            54: 
        !            55: Called by:
        !            56:        main thru command array
        !            57: 
        !            58: History:
        !            59:        initial coding          Mark Kampe UCLA-ATS
        !            60:        modified 4/13/76 by S. F. Holmgren for Illinois version
        !            61:        modified 6/30/76 by S. F. Holmgren to call getmbox
        !            62:        modified 10/18/76 by J. S. Kravitz to improve net mail header
        !            63:        chown removed by R. Balocca @ CAC, Sunday 1977 February 20
        !            64:        getline removed and limit on line length removed by using
        !            65:        getch and putch added by R. Balocca @ CAC, 1977 March 8 Tuesday
        !            66:        Fixed oversight in above (forgot to translate <crlf> to <lf>)
        !            67:                1977 March 10 Thursday by Rick Balocca @ CAC
        !            68:        Added openmail & closemail, added logging, and fixed several
        !            69:                bugs on or about 12/21/79 by Eric Allman, UCB/INGRES.
        !            70:        Changed to always accept mail -- bad mail will be sent back --
        !            71:                1/9/80 by Eric Allman, UCB/INGRES.
        !            72:        Don't print out 350 enter mail or 256 mail accepted messages --
        !            73:                sendmail will do that.  8/19/81 Eric Allman UCB/INGRES.
        !            74: */
        !            75: #define gt (c = getch())
        !            76: mail()
        !            77: {
        !            78:        register char *p;       /* general use */
        !            79:        register int c;
        !            80:        int i;
        !            81: 
        !            82:        /* extern struct io_buf obuf; */
        !            83: 
        !            84:        /* get to open mailbox file descriptor */
        !            85:        fflush(&fout);
        !            86:        if( (fout = openmail(arg, 0)) < 0 )
        !            87:                return;
        !            88: 
        !            89:        for(;;)                         /* while no error or <crlf>.<crlf> */
        !            90:        {
        !            91:                /* we are at beginning of line */
        !            92: 
        !            93:                if(gt=='.')                     /*"."*/
        !            94:                {
        !            95:                        if(gt=='\r')                    /*".\r"*/
        !            96:                        {
        !            97:                                if(gt=='\n')                    /*".\r\n"*/
        !            98:                                {
        !            99:                                        /* end of message */
        !           100:                                        break;
        !           101:                                }
        !           102:                                else
        !           103:                                {                               /*".\r"c*/
        !           104:                                        putch('.');
        !           105:                                        putch('\r');
        !           106:                                }
        !           107:                        }
        !           108:                        else                            /*"."c"*/
        !           109:                                putch('.');
        !           110:                }
        !           111:                                                                /*"-"*/
        !           112:                                        /* c */
        !           113:                for(;;)
        !           114:                {
        !           115:                        for(; c != '\r'; gt)
        !           116:                        {
        !           117:                                if( c < 0 )
        !           118:                                {
        !           119:                                        fflush(&fout);
        !           120:                                        write(fout, "\n***** Sender aborted connection *****\n", 39);
        !           121:                                        goto out;
        !           122:                                }
        !           123:                                else
        !           124:                                        putch(c);
        !           125:                        }
        !           126:        
        !           127:                                                /*"\r"*/
        !           128:                        if( gt == '\n' )
        !           129:                        {                       /*"\r\n"*/
        !           130: crlf:
        !           131:                                putch('\n');
        !           132:                                break;
        !           133:                        }
        !           134:                        else
        !           135:                        {                       /*"\r"c*/
        !           136: crc:
        !           137:                                putch('\r');
        !           138:                                if(c=='\0')
        !           139:                                        gt;     /* "\r\0" */
        !           140:                                                /* is arpa escape for "\r" */
        !           141:                        }
        !           142:                }
        !           143:        }
        !           144: 
        !           145: out:
        !           146:        fflush(&fout);
        !           147:        closemail(fout);
        !           148: }
        !           149: 
        !           150: /*
        !           151: Name:
        !           152:        datamail
        !           153: 
        !           154: Function:
        !           155:        handle the MLFL command
        !           156: 
        !           157: Algorithm:
        !           158:        fork
        !           159:                make sure we have a valid user
        !           160:                        say bad user and exit
        !           161:                send sock command
        !           162:                open data connection
        !           163:                get open mailbox file descriptor
        !           164:                call rcvdata to receive mail
        !           165: 
        !           166: Parameters:
        !           167:        username in arg
        !           168: 
        !           169: Returns:
        !           170:        nothing
        !           171: 
        !           172: Globals:
        !           173:        arg
        !           174: 
        !           175: Calls:
        !           176:        fork (sys)
        !           177:        strmove
        !           178:        netreply
        !           179:        sendsock
        !           180:        dataconnection
        !           181:        getmbox
        !           182:        rcvdata
        !           183:        printf (sys)
        !           184:        time (sys)
        !           185: 
        !           186: Called by:
        !           187:        main thru command array 
        !           188: 
        !           189: History:
        !           190:        initial coding 4/13/76 by S. F. Holmgren
        !           191:        modified 10/18/76 by J. S. Kravitz to put net mail header
        !           192:        chown removed by R. Balocca @ CAC, Sunday 1977 February 20
        !           193: */
        !           194: datamail()
        !           195: {
        !           196:        register netdata;
        !           197:        /* register mboxfid; */
        !           198:        register int i;
        !           199: 
        !           200:        i = fork();
        !           201:        if (i < 0)
        !           202:        {
        !           203:                netreply("455 Mail server temporarily unavailable\r\n");
        !           204:                return;
        !           205:        }
        !           206:        else if (i == 0)
        !           207:        {
        !           208:                fflush(&fout);
        !           209:                if ((fout = openmail(arg, 1)) < 0)
        !           210:                        exit(3);
        !           211: 
        !           212:                /* send sock command */
        !           213:                sendsock( U4 );
        !           214: 
        !           215:                /* open data connection */
        !           216:                netdata = dataconnection( U4 );
        !           217: 
        !           218:                /* say its ok to proceed */
        !           219:                numreply( NUM250 );
        !           220: 
        !           221:                /* get data from net connection and copy to mail file */
        !           222:                /* rcvdata( netdata,mboxfid ); */
        !           223:                if (rcvdata(netdata, fout) < 0)
        !           224:                        exit(1);
        !           225: 
        !           226:                /* close the mail, see if ok; if so say ok */
        !           227:                fflush(&fout);
        !           228:                closemail(fout);
        !           229: 
        !           230:                exit( 0 );
        !           231:        }
        !           232: }
        !           233: /*
        !           234: **  OPENMAIL -- Open a channel to the mail server
        !           235: **
        !           236: **     Gets the mail server started up ready to handle our
        !           237: **     mail.
        !           238: **
        !           239: **     Algorithm:
        !           240: **             See if the user is specified.
        !           241: **                     If not, send to user "root".
        !           242: **             See if the user exists.
        !           243: **                     If not, signal error 450 and return.
        !           244: **             Fork.
        !           245: **             Create a pipe
        !           246: **                     Signal "unavailable" and exit on failure.
        !           247: **             Fork.
        !           248: **                     Signal "unavailable" and exit on failure
        !           249: **                     In child:
        !           250: **                             Call mailer: /etc/delivermail is preferred.
        !           251: **                     In parent:
        !           252: **                             Avoid pipe signals in case delivermail dies.
        !           253: **                             Save the childs pid.
        !           254: **                             Return file descriptor.
        !           255: **
        !           256: **     Notes:
        !           257: **             The check to see if the user actually exists should
        !           258: **             go away so that we can do real mail forwarding.
        !           259: **
        !           260: **     Parameters:
        !           261: **             who -- the user to send the mail to.
        !           262: **             mode -- 0 -- called from mail
        !           263: **                     1 -- called from mlfl
        !           264: **
        !           265: **     Returns:
        !           266: **             File descriptor to send mail to.
        !           267: **             -1 on failure.
        !           268: **
        !           269: **     Side Effects:
        !           270: **             Forks /etc/delivermail or /bin/mail or /usr/bin/mail.
        !           271: **             Becomes "network" in the child.
        !           272: **
        !           273: **     Requires:
        !           274: **             strmove
        !           275: **             getuser
        !           276: **             netreply
        !           277: **             pipe (sys)
        !           278: **             fork (sys)
        !           279: **             close (sys)
        !           280: **             dup (sys)
        !           281: **             execl (sys)
        !           282: **             signal (sys)
        !           283: **             exit (sys)
        !           284: **
        !           285: **     Called By:
        !           286: **             mail
        !           287: **             datamail
        !           288: **
        !           289: **     History:
        !           290: **             1/9/80 -- Added 050 & 455 reply messages if execl's
        !           291: **                     fail.  Eric Allman UCB/INGRES.
        !           292: **             11/26/79 -- Modified to map upper case to lower
        !           293: **                     case.  Eric Allman UCB/INGRES.
        !           294: **             11/10/79 -- Written by Eric Allman UCB/INGRES
        !           295: **             3/6/80 -- Dropped case mapping; delivermail does
        !           296: **                     that now.  EPA UCB/INGRES.
        !           297: **             8/19/81 -- Added "mode" parameter; call sendmail
        !           298: **                     instead of delivermail.  EPA
        !           299: */
        !           300: 
        !           301: int Mail_pid;
        !           302: char *Mail_user;
        !           303: 
        !           304: openmail(who, mode)
        !           305:        char *who;
        !           306:        int mode;
        !           307: {
        !           308:        register char *w;
        !           309:        register int i;
        !           310:        int pvect[2];
        !           311:        register char *p;
        !           312: 
        !           313:        w = who;
        !           314:        if (w == 0)
        !           315:                w = "root";
        !           316:        Mail_user = w;
        !           317: 
        !           318:        /* see if the user exists */
        !           319:        strmove(w, username);
        !           320: 
        !           321:        /* try to get a pipe to the mailer */
        !           322:        if (pipe(pvect) < 0)
        !           323:        {
        !           324:          unavailable:
        !           325:                netreply("455 Mail server temporarily unavailable\r\n");
        !           326:                return (-1);
        !           327:        }
        !           328: 
        !           329:        /* fork */
        !           330:        i = fork();
        !           331:        if (i < 0)
        !           332:        {
        !           333:                /* failure */
        !           334:                close(pvect[0]);
        !           335:                close(pvect[1]);
        !           336:                goto unavailable;
        !           337:        }
        !           338:        else if (i == 0)
        !           339:        {
        !           340:                /* child */
        !           341:                close(pvect[1]);
        !           342:                close(0);
        !           343:                dup(pvect[0]);
        !           344:                close(pvect[0]);
        !           345:                setuid(NETUID);
        !           346: 
        !           347:                /* try to call something to deliver the mail */
        !           348:                execl("/etc/sendmail", "sendmail", "-v", mode == 1 ? "-af" : "-am", w, 0);
        !           349: 
        !           350:                /* doesn't seem to be anything around */
        !           351:                netreply("455 Mail server unavailable\r\n");
        !           352:                exit(3);
        !           353:        }
        !           354: 
        !           355:        /* else parent */
        !           356:        signal(SIGPIPE, SIG_IGN);
        !           357:        Mail_pid = i;
        !           358:        close(pvect[0]);
        !           359:        return (pvect[1]);
        !           360: }
        !           361: /*
        !           362: **  CLOSEMAIL -- Close the mail file and get actual status
        !           363: **
        !           364: **     The mail file is closed.
        !           365: **
        !           366: **     Algorithm:
        !           367: **             Wait for the mailer to die.
        !           368: **                     If it wasn't there, be non-comittal.
        !           369: **             If it died a violent death, give error.
        !           370: **
        !           371: **     Parameters:
        !           372: **             fd -- the file descriptor of the mail file.
        !           373: **
        !           374: **     Returns:
        !           375: **             none.
        !           376: **
        !           377: **     Side Effects:
        !           378: **             mailer is soaked up.
        !           379: **
        !           380: **     Requires:
        !           381: **             close (sys)
        !           382: **             wait (sys)
        !           383: **
        !           384: **     Called By:
        !           385: **             mail
        !           386: **             datamail
        !           387: **
        !           388: **     History:
        !           389: **             1/9/80 -- Changed to not check for errors in mailing,
        !           390: **                     since these will be mailed back.
        !           391: **             11/10/79 -- Written by Eric Allman UCB/INGRES.
        !           392: */
        !           393: 
        !           394: closemail(fd)
        !           395:        int fd;
        !           396: {
        !           397:        auto int st;
        !           398:        register int i;
        !           399: 
        !           400:        /* close the pipe -- mail should go away */
        !           401:        close(fd);
        !           402: 
        !           403:        /* wait for its body */
        !           404:        while ((i = wait(&st)) != Mail_pid)
        !           405:        {
        !           406:                if (i < 0)
        !           407:                {
        !           408:                        /* how did this happen? */
        !           409:                        logmsg(LOG_ERR, "mail from host %d to %s: no child",
        !           410:                            openparams.o_frnhost & 0377, Mail_user);
        !           411:                        goto unavailable;
        !           412:                }
        !           413:        }
        !           414: 
        !           415:        /* 'st' is now the status of the mailer */
        !           416:        if ((st & 0377) != 0)
        !           417:        {
        !           418:                logmsg(LOG_ERR, "mail from host %d to %s: status %o",
        !           419:                    openparams.o_frnhost & 0377, Mail_user, st);
        !           420: unavailable:
        !           421:                netreply("455 Mail not delivered -- local system error\r\n");
        !           422:                return (-1);
        !           423:        }
        !           424: 
        !           425:        return (0);
        !           426: }

unix.superglobalmegacorp.com

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