Annotation of 43BSD/usr.lib/sendmail/aux/mail-dm.c, revision 1.1.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.