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

unix.superglobalmegacorp.com

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