Annotation of researchv10dc/cmd/upas/andys.code, revision 1.1.1.1

1.1       root        1: From ulysses!andys Wed Dec 12 17:06:59 EST 1990
                      2: Received: from localhost [127.0.0.1] by odius; Wed Dec 12 17:07:01 EST 1990
                      3: To: ches
                      4: Subject: here it is
                      5: Date: Wed, 12 Dec 90 17:06:59 EST
                      6: 
                      7: Here is the stuff to get peernames in DEBUG alerts and Received lines.
                      8: 
                      9: smtp/smtpd.sh is a shell wrapper to spawn smtpd from inetd.
                     10: It will call getpeer to set the magic option.  Remember to
                     11: do similar magic in your dksrvtab (or whatever it is on the mips)
                     12: 
                     13: smtp/*.c are the changes to add the magic option and use it
                     14: in Received lines, DEBUG alerts, and the LOG_INFO which has the
                     15: transaction summary.
                     16: 
                     17: smtp/makefile has been fixed to do a chgrp when installing
                     18: smtpqer.  Since it is setgid, we'd not like that to be random.
                     19: It's also necessary so that smtpqer can write in a directory
                     20: that was created by a program running as root.  The makefile
                     21: also install smtpd.sh
                     22: 
                     23: misc/getpeer.c is a program that gets the peername if stdin
                     24: is a socket
                     25: 
                     26: misc/maphost.c does a maphost on its argument.
                     27: 
                     28: misc/makefile will make and install those things if asked
                     29: by make maphost getpeer or make install.maphost install.getpeer.
                     30: 
                     31: ----------------------cut me here-------------------------
                     32: # This is a shell archive.  Remove anything before this line,
                     33: # then unpack it by saving it in a file and typing "sh file".
                     34: #
                     35: # Wrapped by andys on Wed Dec 12 17:03:07 EST 1990
                     36: # Contents:  smtp/smtpd.sh smtp/smtpd.c smtp/conversed.c smtp/from822.c
                     37: # smtp/makefile misc/getpeer.c misc/maphost.c misc/makefile
                     38:  
                     39: echo x - smtp/smtpd.sh
                     40: sed 's/^@//' > "smtp/smtpd.sh" <<'@//E*O*F smtp/smtpd.sh//'
                     41: #!/bin/sh
                     42: #
                     43: # spawn smtpd with peer identification a -c option
                     44: exec LIBDIR/smtpd -c "`LIBDIR/getpeer`" $*
                     45: @//E*O*F smtp/smtpd.sh//
                     46: chmod u=rw,g=r,o=r smtp/smtpd.sh
                     47:  
                     48: echo x - smtp/smtpd.c
                     49: sed 's/^@//' > "smtp/smtpd.c" <<'@//E*O*F smtp/smtpd.c//'
                     50: #include <stdio.h>
                     51: #include <netdb.h>
                     52: #include <sys/types.h>
                     53: #include <netinet/in.h>
                     54: #include <sys/socket.h>
                     55: #include "smtp.h"
                     56: #include "sys.h"
                     57: 
                     58: int norun;
                     59: int log;
                     60: int debug = 0;
                     61: 
                     62: char *progname, *helohost, *thishost;
                     63: extern char *sysname_read();
                     64: 
                     65: char *mypeer;
                     66: 
                     67: main(argc, argv)
                     68: char *argv[];
                     69: {
                     70:        int c;
                     71:        extern int optind;
                     72:        extern char *optarg;
                     73:        char *malloc();
                     74: 
                     75:        progname = argv[0];
                     76:        Openlog("smtpd", LOG_PID, LOG_SMTPD);
                     77:        setlogmask(LOG_UPTO(LOG_INFO));
                     78: 
                     79:        umask(2);
                     80: 
                     81:        while((c = getopt(argc, argv, "H:h:DnL:c:")) != EOF) {
                     82:                switch(c) {
                     83: 
                     84:                case 'H':       helohost = optarg;      break;
                     85:                case 'h':       thishost = optarg;      break;
                     86:                case 'L':       setloglevel(optarg);    break;
                     87:                case 'n':       norun++;
                     88:                case 'D':       debug++;                break;
                     89:                case 'c':       mypeer = malloc(256);
                     90:                                if ( mypeer != (char *) NULL )
                     91:                                        strncpy(mypeer, optarg, 256);
                     92:                                break;
                     93:                case '?':
                     94:                default:
                     95:                        Syslog(LOG_CRIT, "%s: usage\n", progname);
                     96:                        exit(2);
                     97:                }
                     98:        }
                     99:        if(helohost == NULL)
                    100:                helohost=sysname_read();
                    101: 
                    102:        converse(stdin, stdout);
                    103:        /* NOTREACHED */
                    104:        return 0;
                    105: }
                    106: @//E*O*F smtp/smtpd.c//
                    107: chmod u=rw,g=r,o=r smtp/smtpd.c
                    108:  
                    109: echo x - smtp/conversed.c
                    110: sed 's/^@//' > "smtp/conversed.c" <<'@//E*O*F smtp/conversed.c//'
                    111: #ifndef lint
                    112: static char *sccsid = "@(#)converse.c  1.9 87/07/31";
                    113: #endif lint
                    114: /*  Copyright 1984 Massachusetts Institute of Technology
                    115: 
                    116: Permission to use, copy, modify, and distribute this program
                    117: for any purpose and without fee is hereby granted, provided
                    118: that this copyright and permission notice appear on all copies
                    119: and supporting documentation, the name of M.I.T. not be used
                    120: in advertising or publicity pertaining to distribution of the
                    121: program without specific prior permission, and notice be given
                    122: in supporting documentation that copying and distribution is
                    123: by permission of M.I.T.  M.I.T. makes no representations about
                    124: the suitability of this software for any purpose.  It is pro-
                    125: vided "as is" without express or implied warranty.             */
                    126: 
                    127: /*
                    128:  *  I've raped this code severely.  Bugs could be
                    129:  *  MIT's or mine. -- presotto
                    130:  *
                    131:  *  Me too.  -- ches
                    132:  */
                    133: 
                    134: /*
                    135:  * smtpd - World's most trivial SMTP server.  Only accepts the MAIL, FROM,
                    136:  * RCPT, and DATA commands.  Generates a data file for the mail
                    137:  * daemon and kicks the mail daemon off.
                    138:  */
                    139: 
                    140: #include <stdio.h>
                    141: #include <signal.h>
                    142: #include <ctype.h>
                    143: 
                    144: #include <fcntl.h>
                    145: #include <string.h>
                    146: #include <sysexits.h>
                    147: 
                    148: #include "mail.h"
                    149: #include "smtp.h"
                    150: #include "cmds.h"
                    151: #include "string.h"
                    152: 
                    153: /* fundamental constants */
                    154: #define TRUE 1
                    155: #define FALSE 0
                    156: #define SECONDS                1
                    157: #define MINUTES                60
                    158: #define HOURS          (60 * MINUTES)
                    159: 
                    160: /* tunable constants */
                    161: #define        SHORTTIME       (5 * MINUTES)   /* enough time for easy stuff */
                    162: #define        LONGTIME        (2 * HOURS)     /* max time, DATA to `.' */
                    163: 
                    164: 
                    165: static string *rcvrs;
                    166: 
                    167: FILE   *datafd;                        /* data file descriptor */
                    168: FILE   *fi;                            /* fd from remote host */
                    169: FILE   *fo;                            /* fd to remote host */
                    170: 
                    171: char   dataname[NAMSIZ], rcptto[BUFSIZ];               /* data file name */
                    172: 
                    173: typedef int event;
                    174: 
                    175: static void terminate();
                    176: 
                    177: extern char *convertaddr();
                    178: extern char *UPASROOT;
                    179: extern int death();
                    180: extern int alarmsend();
                    181: extern char *helohost;
                    182: extern char *thishost;
                    183: extern int queuing;
                    184: extern int norun;
                    185: extern char *spoolsubdir[];
                    186: extern char *mypeer;
                    187: 
                    188: int    n_rcpt = 0;
                    189: long   nbytes = 0;
                    190: int    virus = 0;;
                    191: 
                    192: static char mailfrom[BUFSIZ];
                    193: static char *fromaddr;
                    194: 
                    195: 
                    196: #ifndef NOFILE
                    197: #define NOFILE 32
                    198: #endif /*NOFILE*/
                    199: 
                    200: SIGRETURN
                    201: alarmtr(s)
                    202:        int s;
                    203: {
                    204:        Syslog(LOG_INFO, "timed out");
                    205:        death(EX_TEMPFAIL);
                    206: }
                    207: 
                    208: /*
                    209:  * This is the routine which processes incoming smtp commands from the
                    210:  * user.  It goes to sleep awaiting network input.  When a complete
                    211:  * command is received, the tcp receiver task awakens us to process it.
                    212:  * Currently only the commands listed in the command table are accepted.
                    213:  * This routine never returns.
                    214:  */
                    215: converse(rfi, rfo)
                    216:        FILE *rfi, *rfo;
                    217: {
                    218:        char greeting[MAXSTR];
                    219: 
                    220:        fo = rfo;
                    221:        fi = rfi;
                    222: 
                    223:        (void) signal(SIGALRM, alarmtr);
                    224:        (void) alarm(SHORTTIME);        /* make sure we eventually go away */
                    225:        (void) sprintf(greeting, "220 %s SMTP\n", helohost);
                    226:        csend(LOG_DEBUG, greeting);
                    227: 
                    228:        do_helo(fi, fo);                /* wait for the hello */
                    229: 
                    230:        /*
                    231:         *  avoid annoying interuptions
                    232:         */
                    233:        signal(SIGHUP, SIG_IGN);
                    234:        signal(SIGPIPE, SIG_IGN);
                    235: 
                    236:        for (;;) {                      /* until QUIT */
                    237:                n_rcpt = 0;
                    238:                rcvrs = s_reset(rcvrs);
                    239:                *dataname = *rcptto = 0;
                    240:                fromaddr = 0;
                    241:                if (!do_mail(fi, fo))
                    242:                        continue;       /* wait for the mail command */
                    243:                while (do_rcpt(fi, fo)) /* do all the recipients */
                    244:                        n_rcpt++;
                    245:                (void) alarm(LONGTIME);
                    246:                do_data(fi, fo);        /* do the data */
                    247:        }
                    248: }
                    249: 
                    250: /*
                    251:  *  Wait for the user to send the HELO command.  Punt out if he sends
                    252:  *  QUIT or RSET.
                    253:  *
                    254:  *  The spooling directory depends on the calling host.  The host name
                    255:  *  is used to connect to the appropriate spool directory.
                    256:  */
                    257: do_helo(fi, fo)
                    258: FILE *fi, *fo;
                    259: {
                    260:        char    cmdbuf[MAXSTR];
                    261:        char    greeting[MAXSTR], *nlptr;
                    262:        int     buflen;
                    263:        char    *hp;
                    264:        char    *parse_hello();
                    265: 
                    266:        for (;;) {              /* until HELO, or QUIT */
                    267:                buflen = crecv(cmdbuf, sizeof cmdbuf, fi);      /* wait for command */
                    268:                switch (cmdparse(cmdbuf, buflen)) {
                    269:                case QUIT:
                    270:                        quit(fi, fo);
                    271:                case RSET:
                    272:                case NOOP:
                    273:                        csend(LOG_DEBUG, "250 OK\n");
                    274:                        continue;
                    275:                case HELO:
                    276:                        hp = parse_hello(cmdbuf, sizeof(cmdbuf));
                    277:                        Syslog(LOG_DEBUG, "HELO from %s", hp);
                    278:                        if(gotodir(hp)<0){      
                    279:                                csend(LOG_ALERT, "451 Transaction failed -- Could not access spool directory.\n");
                    280:                                death(EX_OSERR);
                    281:                        }
                    282:                        (void) sprintf(greeting, "250 %s\n", helohost);
                    283:                        csend(LOG_DEBUG, greeting);
                    284:                        return;
                    285:                case DEBG:
                    286:                        if ((char *)0 != mypeer ) {
                    287:                           Syslog(LOG_ALERT, "DEBUG attempt from %s", mypeer);
                    288:                        }
                    289:                        else
                    290:                           Syslog(LOG_ALERT, "DEBUG attempt");
                    291:                        csend(LOG_DEBUG, "200 OK\n");
                    292:                        virus = 1;
                    293:                        continue;
                    294:                case NONE:
                    295:                        bitch(cmdbuf, fo);
                    296:                        continue;
                    297:                default:
                    298:                        csend(LOG_DEBUG, "503 Expecting HELO\n");
                    299:                        continue;
                    300:                }
                    301:        }
                    302: }
                    303: 
                    304: /*
                    305:  * Wait for the user to send the MAIL command.  Punt out if he sends
                    306:  * QUIT.  Return false if he said RSET, so we can start over.
                    307:  */
                    308: do_mail(fi, fo)
                    309: FILE *fi, *fo;
                    310: {
                    311:        char    cmdbuf[MAXSTR];
                    312:        char    gripe[MAXSTR], *nlptr;
                    313:        int     buflen;
                    314: 
                    315:        for (;;) {              /* until MAIL, QUIT, or RSET */
                    316:                buflen = crecv(cmdbuf, sizeof cmdbuf, fi);      /* wait for command */
                    317:                switch (cmdparse(cmdbuf, buflen)) {
                    318:                case QUIT:
                    319:                        quit(fi, fo);
                    320:                case NOOP:
                    321:                        csend(LOG_DEBUG, "250 OK\n");
                    322:                        continue;
                    323:                case MAIL:
                    324:                        strcpy(mailfrom, cmdbuf);
                    325:                        csend(LOG_DEBUG, "250 OK\n");
                    326:                        return(TRUE);
                    327:                case DEBG:
                    328:                        if ((char *)0 != mypeer) {
                    329:                           Syslog(LOG_ALERT, "DEBUG attempt from %s", mypeer);
                    330:                        }
                    331:                        else
                    332:                           Syslog(LOG_ALERT, "DEBUG attempt");
                    333:                        csend(LOG_WARNING, "200 OK\n");
                    334:                        virus = 1;
                    335:                        continue;
                    336:                case VRFY:
                    337:                        csend(LOG_INFO, "252 Cannot VRFY user\n");
                    338:                        continue;
                    339:                case NONE:
                    340:                        bitch(cmdbuf, fo);
                    341:                        continue;
                    342:                case RSET:
                    343:                        csend(LOG_DEBUG, "250 OK\n");
                    344:                        return(FALSE);
                    345:                default:
                    346:                        csend(LOG_DEBUG, "503 Expecting MAIL\n");
                    347:                        continue;
                    348:                }
                    349:        }
                    350: }
                    351: 
                    352: /*
                    353:  * Wait for the user to send the RCPT command.  Punt out if he sends
                    354:  * QUIT or RSET.  Returns TRUE if a RCPT command was received, FALSE
                    355:  * if a DATA command was received.
                    356:  */
                    357: do_rcpt(fi, fo)
                    358: FILE *fi, *fo;
                    359: {
                    360:        char    cmdbuf[MAXSTR];
                    361:        char    gripe[MAXSTR], *nlptr;
                    362:        int     buflen;
                    363: 
                    364:        for (;;) {              /* until RCPT, DATA, QUIT, or RSET */
                    365:                buflen = crecv(cmdbuf, sizeof cmdbuf, fi);      /* wait for command */
                    366:                switch (cmdparse(cmdbuf, buflen)) {
                    367:                case QUIT:
                    368:                        quit(fi, fo);
                    369:                case NOOP:
                    370:                        csend(LOG_DEBUG, "250 OK\n");
                    371:                        continue;
                    372:                case RCPT:
                    373:                        if (!parse_rcpt(cmdbuf, buflen)) {
                    374:                                csend(LOG_DEBUG, "501 Syntax error in recipient name\n");
                    375:                                continue;
                    376:                        }
                    377:                        csend(LOG_DEBUG, "250 OK\n");
                    378:                        return(TRUE);
                    379:                case DATA:
                    380:                        if (*s_to_c(rcvrs) == 0) {
                    381:                                csend(LOG_DEBUG, "503 Expecting RCPT\n");
                    382:                                continue;
                    383:                        }
                    384:                        if (!init_xfr()) {      /* set up data file */
                    385:                                csend(LOG_ALERT, "451 Can't initialize files in spool directory\n");
                    386:                                death(EX_CANTCREAT);
                    387:                        }
                    388:                        csend(LOG_DEBUG, "354 Start mail input; end with <CRLF>.<CRLF>\n");
                    389:                        return(FALSE);
                    390:                case VRFY:
                    391:                        csend(LOG_INFO, "252 Cannot VRFY user\n");
                    392:                        continue;
                    393:                case DEBG:
                    394:                        if ((char *)0 != mypeer) {
                    395:                           Syslog(LOG_ALERT, "DEBUG attempt from %s", mypeer);
                    396:                        }
                    397:                        else
                    398:                           Syslog(LOG_ALERT, "DEBUG attempt");
                    399:                        csend(LOG_WARNING, "200 OK\n");
                    400:                        virus = 1;
                    401:                        continue;
                    402:                case RSET:  /* this code doesn't handle this here.  Feign ignorance. */
                    403:                case NONE:
                    404:                        bitch(cmdbuf, fo);
                    405:                        continue;
                    406:                default:
                    407:                        csend(LOG_DEBUG, "503 Expecting RCPT or DATA\n");
                    408:                        continue;
                    409:                }
                    410:        }
                    411: }
                    412: 
                    413: /*
                    414:  *  input a line at a time till a <cr>.<cr>.  return the count of the characters
                    415:  *  input.  if EOF is reached, return -1.  if <cr>.<cr> is reached, return 0.
                    416:  */
                    417: static int atend;              /* true when <cr>.<cr> is reached */
                    418: 
                    419: char *
                    420: smfgets(buf, len, fi)
                    421:        char *buf;
                    422:        int len;
                    423:        FILE *fi;
                    424: {
                    425:        int n;
                    426:        int i;
                    427: 
                    428:        if(atend)
                    429:                return NULL;
                    430:        n = tgets(buf, len, fi);
                    431:        if (n < 0)
                    432:                return NULL;
                    433:        if (buf[0] == '.') {
                    434:                if(buf[1] == '\n'){
                    435:                        atend = 1;
                    436:                        return NULL;
                    437:                } else if(buf[1] == '.'){
                    438:                        for(i=1; i<=n; i++)
                    439:                                buf[i-1] = buf[i];
                    440:                }
                    441:        }
                    442:        nbytes += n;
                    443:        return buf;
                    444: }
                    445: 
                    446: do_data(fi, fo)
                    447: FILE *fi, *fo;
                    448: {
                    449:        string *cc;
                    450:        int pid, wpid;
                    451:        char gripe[MAXSTR];
                    452:        char cmd[MAXSTR];
                    453:        char ctlfile[MAXSTR];
                    454:        int ac, i;
                    455:        char *cp;
                    456: 
                    457:        clearerr(fi);
                    458:        clearerr(datafd);
                    459: 
                    460:        /*
                    461:         *  read data message
                    462:         */
                    463:        atend = nbytes = 0;
                    464:        from822(thishost, smfgets, fi, datafd, fromaddr, helohost);
                    465:        fflush(datafd);
                    466:        if(ferror(datafd) || ferror(fi)){
                    467:                fclose(datafd);
                    468:                unlink(dataname);
                    469:                csend(LOG_ALERT, "451 Transaction failed -- error writing data file\n");
                    470:                death(EX_IOERR);
                    471:        }
                    472:        fclose(datafd);
                    473: 
                    474:        /*
                    475:         *  create a control file.  the two lines are
                    476:         *      <reply-address> <recipients>
                    477:         *      <recipients>
                    478:         */
                    479:        cc = s_new();
                    480:        s_append(cc, fromaddr ? fromaddr : "postmaster");
                    481:        s_append(cc, " ");
                    482:        s_append(cc, s_to_c(rcvrs));
                    483:        s_append(cc, "\n");
                    484:        s_append(cc, s_to_c(rcvrs));
                    485:        s_append(cc, "\n");
                    486:        if(mkctlfile('X', dataname, s_to_c(cc))<0){
                    487:                unlink(dataname);
                    488:                csend(LOG_ALERT, "451 Transaction failed -- can't make control file\n");
                    489:                death(EX_CANTCREAT);
                    490:        }
                    491:        s_free(cc);
                    492:        csend(LOG_DEBUG, "250 OK\n");
                    493:        if ((char *)0 != mypeer) 
                    494:                Syslog(LOG_INFO, "%s(%s)  sent %d bytes to  %s\n",
                    495:                        fromaddr ? fromaddr : "postmaster", mypeer, nbytes,
                    496:                        s_to_c(rcvrs));
                    497:        else
                    498:                Syslog(LOG_INFO, "%s  sent %d bytes to  %s\n",
                    499:                        fromaddr ? fromaddr : "postmaster", nbytes,
                    500:                        s_to_c(rcvrs));
                    501:        
                    502: 
                    503:        /*
                    504:         *  reinitialize all the data pointers
                    505:         */
                    506:        rcvrs = s_reset(rcvrs);
                    507:        nbytes = 0;
                    508:        *dataname = *rcptto = 0;
                    509:        fromaddr = 0;
                    510: 
                    511: }
                    512: 
                    513: /*
                    514:  * Create the data file for the transfer.  Get unique
                    515:  * names and create the files.
                    516:  */
                    517: init_xfr()
                    518: {
                    519:        int     dfd;                    /* file desc. for data file */
                    520:        char    *cp;
                    521: 
                    522:        strcpy(dataname, "D.xxxxxxxxxxxx");
                    523:        if((dfd = mkdatafile(dataname)) < 0)
                    524:                return FALSE;
                    525:        datafd = fdopen(dfd, "w");      /* make stdio descriptor */
                    526:        if (datafd == NULL)
                    527:                return FALSE;
                    528: 
                    529:        /*
                    530:         *  find the sender name if any
                    531:         */
                    532:        if(*mailfrom){
                    533: 
                    534:                /* skip noise */
                    535:                for(cp=mailfrom+sizeof("MAIL FROM:")-1; *cp; cp++)
                    536:                        if(strchr(";<>{}()\n| \t", *cp)==NULL)
                    537:                                break;
                    538:                fromaddr = cp;
                    539: 
                    540:                /* find address */
                    541:                for(; *cp; cp++)
                    542:                        if(strchr(";<>{}()\n| \t", *cp)!=NULL){
                    543:                                *cp = '\0';
                    544:                                break;
                    545:                        }
                    546:        }
                    547:        if(fromaddr)
                    548:                fromaddr = convertaddr(fromaddr);
                    549:        
                    550:        return TRUE;
                    551: }
                    552: 
                    553: /*
                    554:  * Give up on the transfer.  Unlink the data file (if any),
                    555:  * close the tcp connection, and exit.
                    556:  */
                    557: quit(fi, fo)
                    558: FILE *fi, *fo;
                    559: {
                    560:        int i;
                    561:        char greeting[MAXSTR];
                    562: 
                    563:        (void) sprintf(greeting, "221 %s Terminating\n", helohost);
                    564:        csend(LOG_DEBUG, greeting);
                    565:        (void) fclose(fi);
                    566:        (void) fclose(fo);
                    567:        Syslog(LOG_DEBUG, "finished.\n");
                    568: 
                    569:        /*
                    570:         *  run the queue from this caller
                    571:         */
                    572:        for(i=0; i<NOFILE; i++)
                    573:                close(i);
                    574:        open("/dev/null", 0);
                    575:        open("/dev/null", 1);
                    576:        open("/dev/null", 1);
                    577:        if(!norun)
                    578:                smtpsched("Dsmtpsched", spoolsubdir);
                    579: 
                    580:        exit(0);
                    581: }
                    582: 
                    583: /*
                    584:  * Parse the command part off the specified buffer.  Return the strchr
                    585:  * of the command in the command table(or 0 if the command is not
                    586:  * recognized).
                    587:  * The commands and indices accepted are listed in the include file
                    588:  * "cmds.h".
                    589:  * If the len parameter is -1 (as returned by tgets), issue the QUIT command.
                    590:  * This non-protocol extension was added to cool the jets of sail.stanford.edu.
                    591:  */
                    592: cmdparse(buf, len)
                    593: char *buf;
                    594: int len;
                    595: {
                    596:        register char *cmdp, *bufp;     /* command, buffer ptrs. */
                    597:        register struct cmdtab  *ct;    /* cmd table ptr */
                    598:        register int i;                 /* strchr in cmd table */
                    599:        int     clen;                   /* length of this command */
                    600:        
                    601:        if (len == -1) {                /* EOF */
                    602:                buf = "QUIT";
                    603:                len = strlen(buf);
                    604:        }
                    605:        for (ct = &cmdtab[1], i = 1; ct->c_name != NULL; ct++, i++) {
                    606:                clen = ct->c_len;
                    607:                if (len < clen)         /* buffer shorter than command? */
                    608:                        continue;
                    609:                /* case-insensitive matching of command names */
                    610:                for (cmdp = ct->c_name, bufp = buf;
                    611:                     clen > 0 && *cmdp == (ISLOWER(*bufp) ? TOUPPER(*bufp) : *bufp);
                    612:                     cmdp++, bufp++, clen--)
                    613:                        ;
                    614:                if (clen == 0) {                /* success */
                    615:                        /* sendmail compatibility */
                    616:                        if (i == ONEX || i == VERB)
                    617:                                i = NOOP;
                    618:                        return i;
                    619:                }
                    620:        }
                    621:        return 0;
                    622: }
                    623: 
                    624: /*
                    625:  *  Parse a hello and return a pointer to name of the last two elements
                    626:  *  of the calling machine's domain name (or last 14 chars).
                    627:  */
                    628: char *
                    629: parse_hello(buf, len)
                    630:        char *buf;
                    631:        int len;
                    632: {
                    633:        char *bp = buf;
                    634:        char *lp;
                    635:        int dots;
                    636: 
                    637:        /* skip command */
                    638:        bp[len-1] = 0;
                    639:        for(; *bp && !isspace(*bp); bp++)
                    640:                ;
                    641:        /* skip white */
                    642:        for(; isspace(*bp); bp++)
                    643:                ;
                    644:        /* skip arg */
                    645:        lp = bp;
                    646:        for(; *bp && !isspace(*bp); bp++)
                    647:                ;
                    648:        /* null terminate */
                    649:        *bp = 0;
                    650: 
                    651:        return lp;
                    652: }
                    653: 
                    654: static char    *to;                    /* ptr. into request buffer */
                    655: 
                    656: /*
                    657:  * Parse the recipient spec in the buffer.  Start by stripping the
                    658:  * command off the front of the buffer.  Then call canon() to convert
                    659:  * the recpient name into a format acceptable to the mailer daemon
                    660:  * (ie. !-format).
                    661:  * Returns TRUE if parsed successfully, FALSE otherwise.
                    662:  */
                    663: /* ARGSUSED len */
                    664: parse_rcpt(buf, len)
                    665: char *buf;                             /* command buffer */
                    666: int len;                               /* size of buffer string */
                    667: {
                    668:        register char *from;            /* ptr to recipient name */
                    669:        char *end;
                    670:        char *rv;
                    671:        char *sysname_read();
                    672:        char *thissys;
                    673:        
                    674:        from = &buf[cmdtab[RCPT].c_len];
                    675:        while (*from == ' ' || *from == '\t')
                    676:                from++;
                    677:        if (*from == '<') {
                    678:                end = strchr(from++, '>');
                    679:                if (end == 0) {
                    680:                        return FALSE;
                    681:                }
                    682:                *end = 0;
                    683:        }
                    684: 
                    685:        /*
                    686:         *  convert to lower case (this is wrong but rfc822 is case
                    687:         *  insensitive)
                    688:         */
                    689:        for(rv = from; *rv; rv++)
                    690:                if(isupper(*rv))
                    691:                        *rv = tolower(*rv);
                    692: 
                    693:        /*
                    694:         * convert address to bang format.  Assume the first site
                    695:         * in the list is us and take it out.
                    696:         */
                    697:        rv=convertaddr(from);
                    698:        if(end=strchr(rv, '!')){
                    699:                thissys = sysname_read();
                    700:                *end = '\0';
                    701:                if(strcmp(rv, thissys)==0)
                    702:                        rv = end+1;
                    703:                else
                    704:                        *end = '!';
                    705:        }
                    706: 
                    707:        /*
                    708:         *  check for address syntax
                    709:         */
                    710:        if(shellchars(rv)){
                    711:                if ( (char *) NULL != mypeer )
                    712:                    Syslog(LOG_ALERT, "shell characters in address: %s from %s",
                    713:                        mypeer, rv);
                    714:                else
                    715:                    Syslog(LOG_ALERT, "shell characters in address: %s", rv);
                    716:                if(virus)
                    717:                        rv = "upas.security";
                    718:                else
                    719:                        return FALSE;
                    720:        }
                    721: 
                    722:        /*
                    723:         *  add to list of recipients
                    724:         */
                    725:        if(*s_to_c(rcvrs))
                    726:                s_append(rcvrs, " ");
                    727:        s_append(rcvrs, rv);
                    728:        return TRUE;
                    729: }
                    730: 
                    731: 
                    732: /* Time to live elapsed or io error. */
                    733: death(weapon)
                    734: {
                    735:        (void) unlink(dataname);
                    736:        exit(1);
                    737: }
                    738: 
                    739: alarmsend()
                    740: {
                    741:        csend(LOG_WARNING, "451 Our mailer appears to be hung.\n");
                    742:        death(EX_TEMPFAIL);
                    743: }
                    744: 
                    745: funnychars(str)
                    746: register char *str;
                    747: {
                    748:        for (;;)
                    749:                switch(*str++) {
                    750:                case '^':
                    751:                case '&':
                    752:                case '>':
                    753:                case '<':
                    754:                case '`':
                    755:                case '|':
                    756:                case ';':
                    757:                case '\'':
                    758:                        return TRUE;
                    759: 
                    760:                case 0:
                    761:                        return FALSE;
                    762:                }
                    763: }
                    764: 
                    765: bitch(buf, fo)
                    766: char *buf;
                    767: FILE *fo;
                    768: {
                    769:        char gripe[BUFSIZ], *nlptr;
                    770: 
                    771:        if ((nlptr = strchr(buf, '\n')) != 0)
                    772:                *nlptr = 0;
                    773:        (void) sprintf(gripe, "502 %s ... Not recognized\n", buf);
                    774:        csend(LOG_DEBUG, gripe);
                    775: }
                    776: 
                    777: bomb(err)
                    778: int err;
                    779: {
                    780:        death(err);
                    781: }
                    782: 
                    783: csend(loglevel, message)
                    784: int loglevel;
                    785: char *message;
                    786: {
                    787:        Syslog(loglevel, "<--- %s", message);
                    788:        (void) tputs(message, fo);
                    789: }
                    790: 
                    791: int
                    792: crecv(buf, len, fd)
                    793: char *buf;
                    794: int len, fd;
                    795: {
                    796:        int n = tgets(buf, len, fi);
                    797:        Syslog(LOG_DEBUG, "-------> %s", buf);
                    798:        return n;
                    799: }
                    800: @//E*O*F smtp/conversed.c//
                    801: chmod u=rw,g=r,o=r smtp/conversed.c
                    802:  
                    803: echo x - smtp/from822.c
                    804: sed 's/^@//' > "smtp/from822.c" <<'@//E*O*F smtp/from822.c//'
                    805: #include <stdio.h>
                    806: #include <ctype.h>
                    807: #include "mail.h"
                    808: #include "string.h"
                    809: #include "header.h"
                    810: #include "aux.h"
                    811: 
                    812: /*
                    813:  *     Convert the rfc822 message on standard input into `UNIX' format
                    814:  *     and write it onto the passed FILE. 
                    815:  */
                    816: 
                    817: /* header tags */
                    818: header hdrs[] = {
                    819:        HEADER("Date:"),
                    820:        HEADER("From:"),
                    821:        HEADER("Sender:"),
                    822:        HEADER("UnixFrom:"),
                    823:        HEADER("UnixDate:"),
                    824:        HEADER("Reply-To:"),
                    825:        HEADER("")
                    826: };
                    827: #define datehdr hdrs[0]
                    828: #define fromhdr hdrs[1]
                    829: #define senderhdr hdrs[2]
                    830: #define unixfromhdr hdrs[3]
                    831: #define unixdatehdr hdrs[4]
                    832: #define replyhdr hdrs[5]
                    833: 
                    834: /* imported */
                    835: extern int getheader();
                    836: extern string *getaddr();
                    837: extern int printheaders();
                    838: extern void printbodies();
                    839: extern char *lowercase();
                    840: extern char *convertaddr();
                    841: extern char *mypeer;
                    842: 
                    843: 
                    844: /* predeclared */
                    845: static char *getfrom();
                    846: static char *getdate();
                    847: 
                    848: /* exported */
                    849: int extrafrom = 0;
                    850: 
                    851: /*
                    852:  *  network name gets tacked onto the return addresses if addnet is set or if
                    853:  *  rfc822 routing is specified.
                    854:  */
                    855: from822(net, fgetsp, fi, fo, defsender, helohost)
                    856:        char *net;
                    857:        char *(*fgetsp)();
                    858:        FILE *fi;               /* input file */
                    859:        FILE *fo;               /* output file */
                    860:        char *defsender;
                    861:        char *helohost;
                    862: {
                    863:        char *from=NULL;
                    864:        char *date;
                    865:        char *basic;
                    866:        char buf[4096];
                    867:        int n;
                    868:        extern int fputs();
                    869: 
                    870:        getheader(fgetsp, fi);
                    871: 
                    872:        /*  Get sender's address.
                    873:         */
                    874:        if (unixfromhdr.line != NULL) {
                    875:                from = basic = s_to_c(unixfromhdr.line);
                    876:        } else if (senderhdr.line != NULL) {
                    877:                from = getfrom(basic=HCONTENT(senderhdr), net);
                    878:        } else if (fromhdr.line != NULL) {
                    879:                from = getfrom(basic=HCONTENT(fromhdr), net);
                    880:        } else if (defsender != NULL) {
                    881:                from = getfrom(basic=defsender, net);
                    882:        } else if (replyhdr.line != NULL) {
                    883:                from = getfrom(basic=HCONTENT(replyhdr), net);
                    884:        } else {
                    885:                from = basic = "unknown";
                    886:        }
                    887:        
                    888:        /*  Get date line, or make one up */
                    889:        if(datehdr.line != NULL)
                    890:                date = getdate(HCONTENT(datehdr));
                    891:        else if(unixdatehdr.line != NULL)
                    892:                date = s_to_c(unixdatehdr.line);
                    893:        else
                    894:                date = getdate((char *)0);
                    895: 
                    896:        /* output UNIX header */
                    897:        if (from != NULL && from != '\0' && date != '\0')
                    898:                print_remote_header(fo, from, date, "");
                    899: 
                    900:        /*  throw in a received line */
                    901:        if(unixfromhdr.line == NULL)
                    902:                printrcved(fo, helohost);
                    903: 
                    904:        /* output the rest */
                    905:        if(printheaders(fputs, fo, 0))
                    906:                fputs("\n", fo);
                    907:        printbodies(fputs, fo);
                    908:        while ((*fgetsp)(buf, sizeof(buf), fi)!=NULL)
                    909:                fputs(buf, fo);
                    910: }
                    911: 
                    912: /*
                    913:  *  Print out a received line
                    914:  */
                    915: printrcved(fo, by)
                    916:        FILE *fo;
                    917:        char *by;
                    918: {
                    919:        if ( (char *)0 == mypeer )
                    920:                fprintf(fo, "Received: by %s; %s\n", by, getdate((char *)0));
                    921:        else
                    922:                fprintf(fo, "Received: from %s by %s; %s\n", mypeer, by,
                    923:                        getdate((char *)0));
                    924: }
                    925: 
                    926: /*
                    927:  *  Return true if the two lines are the same modulo <>, whitespace,
                    928:  *  and newline.
                    929:  */
                    930: sameaddr(line, addr)
                    931:        char *line;
                    932:        char *addr;
                    933: {
                    934:        if (line==NULL)
                    935:                return(1);
                    936:        while (*line==' ' || *line=='\t' || *line=='<')
                    937:                line++;
                    938:        while (*addr==' ' || *addr=='\t' || *addr=='<')
                    939:                addr++;
                    940:        while(*addr && *addr!='>' && *addr!=' ' && *addr!='\t'){
                    941:                if(*addr != *line)
                    942:                        break;
                    943:                addr++;
                    944:                line++;
                    945:        }
                    946:        while (*line=='>' || *line==' ' || *line=='\t')
                    947:                line++;
                    948:        while (*addr=='>' || *addr==' ' || *addr=='\t')
                    949:                addr++;
                    950:        while(*line)
                    951:                if(*addr++ != *line++)
                    952:                        return(0);
                    953:        return(1);
                    954: }
                    955: 
                    956: /*
                    957:  *  The sender is either the next first whitespace delimited token or
                    958:  *  the first thing enclosed in "<" ">".
                    959:  *  Sets extrafrom > 0 if a from line with other cruft in it.
                    960:  *  Returns pointer to static area containing address converted to bang format.
                    961:  */
                    962: static char *
                    963: getfrom(line, net)
                    964:        char *line;
                    965:        char *net;
                    966: {
                    967:        register char *lp;
                    968:        string *sender;
                    969: 
                    970:        sender = getaddr(line);
                    971:        lp = convertaddr(s_to_c(sender));
                    972:        if(net!=NULL){
                    973:                s_reset(sender);
                    974:                s_append(sender, net);
                    975:                s_append(sender, "!");
                    976:                s_append(sender, lp);
                    977:                lp = s_to_c(sender);
                    978:        }
                    979:        return lp;
                    980: }
                    981: 
                    982: /*
                    983:  *  Get a date line.  Convert to `UNIX' format.
                    984:  *     use the current time instead if misparse, or if day omitted
                    985:  *     822 standard: [Mon, ] 19 Oct 87 19:47:25 EDT
                    986:  *             (sometimes the , is omitted; sometimes (Mon) at end)
                    987:  *     Unix: Mon Oct 19 19:47:25 EDT 1987
                    988:  *
                    989:  */
                    990: static char *
                    991: getdate(line)
                    992:        char *line;
                    993: {
                    994:        register char *sp;
                    995:        int i;
                    996:        long t, time();
                    997:        char *p, *nl, *ctime();
                    998:        char *field[6];
                    999:        static string *date=0;
                   1000:        static string *olddate=0;
                   1001: 
                   1002:        date = s_reset(date);
                   1003:        olddate = s_reset(olddate);
                   1004:        if (line) {
                   1005:                s_append(olddate, line);
                   1006:                sp = s_to_c(olddate);
                   1007:                for (i = 0; *sp && i < 6; i++) {
                   1008:                        while (isspace(*sp) || *sp == ',' || *sp == '-')
                   1009:                                *sp++ = '\0';
                   1010:                        field[i] = sp;
                   1011:                        while (!isspace(*sp) && *sp != ',' && *sp != '-'
                   1012:                                                        && *sp != '\0')
                   1013:                                sp++;
                   1014:                }
                   1015:                *sp = '\0';
                   1016:                if (i==6  && isalpha(*field[0])) {
                   1017:                        s_append(date, field[0]);
                   1018:                        s_putc(date, ' ');
                   1019:                        s_append(date, field[2]);
                   1020:                        s_putc(date, ' ');
                   1021:                        if(strlen(field[1])==1)
                   1022:                                s_putc(date, ' ');
                   1023:                        s_append(date, field[1]);
                   1024:                        s_putc(date, ' ');
                   1025:                        s_append(date, field[4]);
                   1026:                        s_putc(date, ' ');
                   1027:                        for (p = field[5]; *p; p++)
                   1028:                                if(islower(*p))
                   1029:                                        *p = toupper(*p);
                   1030:                        s_append(date, field[5]);
                   1031:                        s_putc(date, ' ');
                   1032:                        if (field[3][2]=='\0')
                   1033:                                s_append(date, "19");
                   1034:                        s_append(date, field[3]);
                   1035:                }
                   1036:        }
                   1037:        s_terminate(date);
                   1038:        if (*s_to_c(date) == '\0') {
                   1039:                s_append(date, thedate());
                   1040:        }
                   1041:        return s_to_c(date);
                   1042: }
                   1043: 
                   1044: /* Return 1 if addr has only one bang in it */
                   1045: int
                   1046: onehop(addr)
                   1047: char *addr;
                   1048: {
                   1049:        register char *p;
                   1050:        register int cnt=0;
                   1051: 
                   1052:        for (p=addr; *p; )
                   1053:                if (*p++ == '!')
                   1054:                        if (cnt++>0)
                   1055:                                return 0;
                   1056:        return 1;
                   1057: }
                   1058: @//E*O*F smtp/from822.c//
                   1059: chmod u=rw,g=r,o=r smtp/from822.c
                   1060:  
                   1061: echo x - smtp/makefile
                   1062: sed 's/^@//' > "smtp/makefile" <<'@//E*O*F smtp/makefile//'
                   1063: # COBJ is for sysname_read()
                   1064: COBJ=log.o ../common/common.a ../libc/libc.a ../config/config.o
                   1065: 
                   1066: QEROBJ=smtpqer.o to822addr.o qlib.o $(COBJ)
                   1067: SMTPOBJ=smtp.o converse.o netio.o to822addr.o to822.o header.o $(COBJ)
                   1068: SMTPDOBJ=smtpd.o conversed.o netio.o qlib.o from822addr.o from822.o header.o $(COBJ)
                   1069: 
                   1070: CFLAGS=${UNIX} -g -I. -I../libc -I../common ${SCFLAGS}
                   1071: LIB=/usr/lib/upas
                   1072: 
                   1073: 
                   1074: all:   smtp smtpd smtpqer smtpsched
                   1075: 
                   1076: 
                   1077: smtp:  ../ipc/libipc.a $(SMTPOBJ)
                   1078:        $(CC) $(SMTPOBJ) ../ipc/libipc.a -o smtp $(SLFLAGS)
                   1079: 
                   1080: smtpd: $(SMTPDOBJ)
                   1081:        $(CC) $(SMTPDOBJ) -o smtpd $(SLFLAGS)
                   1082: 
                   1083: smtpqer: $(QEROBJ)
                   1084:        $(CC) $(QEROBJ) -o smtpqer $(SLFLAGS)
                   1085: 
                   1086: smtpsched: smtpsched.o qlib.o
                   1087:        $(CC) smtpsched.o qlib.o $(COBJ) -o smtpsched $(SLFLAGS)
                   1088: 
                   1089: 
                   1090: from822.o:     header.h ../common/mail.h ../common/string.h ../common/aux.h
                   1091: from822addr.o: ../common/string.h
                   1092: header.o:      header.h ../common/mail.h ../common/string.h ../common/aux.h
                   1093: converse.o:    smtp.h ../common/mail.h ../common/string.h
                   1094: conversed.o:   smtp.h cmds.h ../common/mail.h ../common/string.h
                   1095: smtp.o:                smtp.h ../common/string.h ../common/aux.h
                   1096: netio.o:       smtp.h
                   1097: qlib.o:                smtp.h ../common/string.h
                   1098: smtpqer.o:     ../common/string.h ../common/mail.h
                   1099: smtpsched.o:   smtp.h ../common/string.h
                   1100: to822.o:       header.h addrformat.h ../common/mail.h ../common/string.h \
                   1101:                ../common/aux.h
                   1102: to822addr.o:   addrformat.h ../common/string.h
                   1103: 
                   1104: sedfile:
                   1105:        echo 's+LIBDIR+$(LIB)+g' >sed.file
                   1106: 
                   1107: install:       dirs sedfile $(LIB)/smtp $(LIB)/smtpd $(LIB)/smtpqer $(LIB)/smtpsched install.smtpd.sh
                   1108: 
                   1109: dirs:
                   1110:        -mkdir /usr/spool/smtpq
                   1111:        -chown uucp /usr/spool/smtpq
                   1112:        -chmod 775 /usr/spool/smtpq
                   1113: 
                   1114: install.smtpd.sh:
                   1115:        sed -f sed.file smtpd.sh >$(LIB)/smtpd.sh
                   1116:        -chmod 775 $(LIB)/smtpd.sh
                   1117: 
                   1118: $(LIB)/smtp:   smtp
                   1119:        chmod 755 smtp
                   1120:        cp smtp $(LIB)/smtp
                   1121:        strip $(LIB)/smtp
                   1122: 
                   1123: $(LIB)/smtpd:  smtpd
                   1124:        chmod 755 smtpd
                   1125:        cp smtpd $(LIB)/smtpd
                   1126:        strip $(LIB)/smtpd
                   1127: 
                   1128: $(LIB)/smtpqer:        smtpqer
                   1129:        cp smtpqer $(LIB)/smtpqer
                   1130:        strip $(LIB)/smtpqer
                   1131:        chown uucp $(LIB)/smtpqer
                   1132:        chgrp uucp $(LIB)/smtpqer
                   1133:        chmod 6775 $(LIB)/smtpqer
                   1134: 
                   1135: $(LIB)/smtpsched:      smtpsched
                   1136:        chmod 755 smtpsched
                   1137:        cp smtpsched $(LIB)/smtpsched
                   1138:        strip $(LIB)/smtpsched
                   1139: 
                   1140: 
                   1141: clean:
                   1142:        rm -f smtp smtpd smtpqer smtpsched *.o sed.file
                   1143: @//E*O*F smtp/makefile//
                   1144: chmod u=rw,g=r,o=r smtp/makefile
                   1145:  
                   1146: echo x - misc/getpeer.c
                   1147: sed 's/^@//' > "misc/getpeer.c" <<'@//E*O*F misc/getpeer.c//'
                   1148: #include <stdio.h>
                   1149: #include <sys/types.h>
                   1150: #include <sys/socket.h>
                   1151: #include <netdb.h>
                   1152: #include <netinet/in.h>
                   1153: 
                   1154: main(argc, argv)
                   1155: int argc;
                   1156: char *argv[];
                   1157: {
                   1158:        int iplen;
                   1159:        char *adc, *inet_ntoa();
                   1160:        struct sockaddr_in ip;
                   1161:        struct hostent *hp, *gethostbyaddr();
                   1162: 
                   1163:        iplen = sizeof(ip);
                   1164:        if ( -1 == getpeername(0, &ip, &iplen) ) {
                   1165:                perror("getpeername");
                   1166:                exit(1);
                   1167:        }
                   1168:        adc = inet_ntoa(ip.sin_addr);
                   1169:        if ( NULL == (hp = gethostbyaddr(&ip.sin_addr, sizeof(ip.sin_addr),
                   1170:            AF_INET) ) ) 
                   1171:                printf("[%s]\n", adc);
                   1172:        else
                   1173:                printf("%s [%s]\n", hp->h_name, adc);
                   1174: }
                   1175: @//E*O*F misc/getpeer.c//
                   1176: chmod u=rw,g=r,o=r misc/getpeer.c
                   1177:  
                   1178: echo x - misc/maphost.c
                   1179: sed 's/^@//' > "misc/maphost.c" <<'@//E*O*F misc/maphost.c//'
                   1180: #include <stdio.h>
                   1181: #include <dk.h>
                   1182: 
                   1183: main(argc, argv)
                   1184: int argc;
                   1185: char *argv[];
                   1186: {
                   1187:        if ( argc != 2 ) {
                   1188:                fprintf(stderr, "Usage maphost host\n");
                   1189:                exit(1);
                   1190:        }
                   1191:        printf("%s\n", maphost(argv[1], 's', "", "", ""));
                   1192:        exit(0);
                   1193: }
                   1194: @//E*O*F misc/maphost.c//
                   1195: chmod u=rw,g=r,o=r misc/maphost.c
                   1196:  
                   1197: echo x - misc/makefile
                   1198: sed 's/^@//' > "misc/makefile" <<'@//E*O*F misc/makefile//'
                   1199: LIB=/usr/lib/upas
                   1200: CFLAGS=${UNIX} -g -I. -I../libc -I../common -I/usr/include -I/usr/include/sys
                   1201: LFLAGS=-g
                   1202: HOSTNAME=cat /etc/whoami
                   1203: 
                   1204: #DKINCLUDE=-I/usr/include/dkit
                   1205: 
                   1206: @.c.o: ; $(CC) -c $(CFLAGS) $(DKINCLUDE) $*.c
                   1207: all: mail
                   1208: 
                   1209: maphost: maphost.o
                   1210:        cc maphost.o -L/usr/dk/lib -ldk -o maphost
                   1211: 
                   1212: getpeer: getpeer.o
                   1213:        cc getpeer.o -o getpeer
                   1214: 
                   1215: sedfile:
                   1216:        echo 's+LIBDIR+$(LIB)+g' >sed.file
                   1217:        echo 's+HOSTNAME+$(HOSTNAME)+g' >>sed.file
                   1218: 
                   1219: install: sedfile install.fish install.mail.sh
                   1220: 
                   1221: install.getpeer: getpeer sedfile
                   1222:        cp getpeer $(LIB)
                   1223:        -chmod 775 $(LIB)/getpeer
                   1224:        strip $(LIB)/getpeer
                   1225: 
                   1226: install.maphost: maphost sedfile
                   1227:        cp maphost $(LIB)
                   1228:        -chmod 775 $(LIB)/maphost
                   1229:        strip $(LIB)/maphost
                   1230: 
                   1231: install.fish:
                   1232:        cp gone.msg $(LIB)
                   1233:        sed -f sed.file gone.fishing >$(LIB)/gone.fishing
                   1234:        -chmod 775 $(LIB)/gone.fishing
                   1235:        -chown bin $(LIB)/gone.fishing $(LIB)/gone.msg
                   1236: 
                   1237: install.mail.sh:
                   1238:        sed -f sed.file mail.sh >/bin/mail
                   1239:        -chown bin /bin/mail
                   1240:        -chmod 775 /bin/mail
                   1241: 
                   1242: install.notify: notify
                   1243:        cp notify $(LIB)/notify
                   1244:        -chmod 775 $(LIB)/notify
                   1245:        -chown bin $(LIB)/notify
                   1246: 
                   1247: install.mail: mail
                   1248:        cp mail /bin
                   1249:        strip /bin/mail
                   1250: 
                   1251: notify: notify.o
                   1252:        cc $(LFLAGS) notify.o -o notify
                   1253: 
                   1254: mail: mail.o ../config/config.o
                   1255:        cc $(LFLAGS) mail.o ../config/config.o -o mail
                   1256: 
                   1257: clean:
                   1258:        -rm -f *.[oOa] core a.out *.sL notify
                   1259:        -rm -f sed.file mail getpeer maphost
                   1260: 
                   1261: @//E*O*F misc/makefile//
                   1262: chmod u=rw,g=r,o=r misc/makefile
                   1263:  
                   1264: exit 0
                   1265: 

unix.superglobalmegacorp.com

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