Annotation of coherent/b/bin/lmail/lmail.c, revision 1.1.1.1

1.1       root        1: static char    *rcsrev = "$Revision: 1.3 $";
                      2: static char    *rcshdr =
                      3:        "$Header: /src386/bin/lmail/RCS/lmail.c,v 1.3 92/11/03 09:06:26 bin Exp Locker: bin $";
                      4: /*
                      5:  * $Header: /src386/bin/lmail/RCS/lmail.c,v 1.3 92/11/03 09:06:26 bin Exp Locker: bin $
                      6:  * $Log:       lmail.c,v $
                      7:  * Revision 1.3  92/11/03  09:06:26  bin
                      8:  * Bob H: restructures routines to lock and write mailboxes and wait for mailbox to become available.
                      9:  * 
                     10:  * Revision 1.1  92/03/13  12:19:15  bin
                     11:  * Initial revision
                     12:  * 
                     13:  * Revision 1.2  92/01/07  08:46:20  bin
                     14:  * Piggy changes for so that if an all caps sitename fails, it will try
                     15:  * lower case.
                     16:  * 
                     17:  * Revision 2.13       90/03/30  16:16:19      wgl
                     18:  * Correct seek pointer work within readmail.
                     19:  * 
                     20:  * Revision 2.12       90/03/12  14:19:08      wgl
                     21:  * New version of send doing aliases in a different place.
                     22:  * 
                     23:  * Revision 2.11       90/03/08  16:41:15      wgl
                     24:  * Add code to get signature file.
                     25:  * 
                     26:  * Revision 2.10       90/03/02  10:41:59      wgl
                     27:  * Add the -a flag so that uucp does not look like it is coming from
                     28:  * somewhere else.
                     29:  * 
                     30:  * Revision 2.9        90/03/01  11:17:19      wgl
                     31:  * Final conversion to rely soley on ^A^A as separators.
                     32:  * Effectively delete concept of m_hsize.
                     33:  * 
                     34:  * Revision 2.8        90/03/01  10:14:31      wgl
                     35:  * Go buy separators, not "From_" lines.
                     36:  * 
                     37:  * Revision 2.7        90/02/28  17:11:41      wgl
                     38:  * Add version print, add some changes to the message-id field.
                     39:  * 
                     40:  * Revision 2.6        90/02/28  16:42:09      wgl
                     41:  * Version number fakeout.
                     42:  * 
                     43:  * Revision 2.5        90/02/28  16:19:44      wgl
                     44:  * Try again to get versioin number right.
                     45:  * 
                     46:  * Revision 2.4        90/02/28  16:18:56      wgl
                     47:  * Get version number right.
                     48:  * 
                     49:  * Revision 2.3        90/02/28  16:04:59      wgl
                     50:  * Many changes; ripped out send.
                     51:  * Changes are to make it work with uucp and internet mail.
                     52:  * 
                     53:  * Revision 1.6        89/02/22  05:34:00      bin
                     54:  * Changes by rec to integrate with lauren's uumail.
                     55:  * 
                     56:  * Revision 1.5        88/09/01  14:49:01      bin
                     57:  * Source administration: Re-install declaration of getenv. 
                     58:  * It was inserted after epstein made his copy.
                     59:  * 
                     60:  * Revision 1.4        88/09/01  14:44:49      bin
                     61:  * Mark Epsteins changes for ASKCC and for message scrolling, and interrupt
                     62:  * handling during processing.
                     63:  * 
                     64:  * Revision 1.3        88/09/01  14:27:41      bin
                     65:  * declare getenv to get rid of integer pointer pun error message.
                     66:  * 
                     67:  * Revision 1.2        88/09/01  11:02:23      bin
                     68:  * Remove extra declaration of header which had rcs stuff in it.
                     69:  * 
                     70:  * Revision 1.1        88/09/01  10:55:34      bin
                     71:  * Initial revision
                     72:  * 
                     73:  */
                     74: /*
                     75:  * The mail command.
                     76:  * Coherent electronic postal system.
                     77:  * (NOTE: this command is written in such a way that
                     78:  * it assumed that it is setuid on execution to `root'.
                     79:  * All file accession is checked on this basis).
                     80:  * Modifications by rec january 1986 to include xmail.
                     81:  *              by epstein november 1987 to include CC:
                     82:  *              by epstein november 1987 to allow ^C exit to leave you in
                     83:  *                                       mail command processor
                     84:  *              by epstein november 1987 to substitute /usr/games/fortune
                     85:  *                                       for printing encrypted messages
                     86:  *             by rec february 1989 to tail to lauren weinstein's
                     87:  *                     mail for alias expansion and uucp queuing.
                     88:  *             by wgl January 1990 to handle uucp mail more directly.
                     89:  */
                     90: 
                     91: char   isummary[] = "\
                     92: \
                     93: Command summary:\n\
                     94:        d               Delete current message and print the next message\n\
                     95:        m [user ...]    Mail current message to each named 'user'\n\
                     96:        p               Print current message again\n\
                     97:        q               Quit and update the mailbox\n\
                     98:        r               Reverse direction of scan\n\
                     99:        s [file ...]    Save message in each named 'file'\n\
                    100:        t [user ...]    Mail standard input to each named 'user'\n\
                    101:        w [file ...]    Save message in each named 'file' without its header\n\
                    102:        x               Exit without updating mailbox\n\
                    103:        newline         Print the next message\n\
                    104:        .               Print current message again\n\
                    105:        +               Print the next message\n\
                    106:        -               Print the previous message\n\
                    107:        EOF             Put undeleted mail back into mailbox and quit\n\
                    108:        ?               Print this command summary\n\
                    109:        !command        Pass 'command' to the shell to execute\n\
                    110: If no 'file' is specified, 'mbox' in user's home directory is default.\n\
                    111: If no 'user' is specified, the invoking user is default.\n\
                    112: If the 'm', 'p', 't' commands are followed by an 'x',\n\
                    113: then the public key cryptosystem is applied to the message.\n\
                    114: \
                    115: ";
                    116: 
                    117: #include "mail.h"
                    118: 
                    119: #define        NARGS   64              /* Maximum # args to interactive command */
                    120: 
                    121: extern char    *getenv();
                    122: extern int     optind;
                    123: extern char    *optarg;
                    124: extern char    getopt();
                    125: char   *revnop();
                    126: 
                    127: char BOBerrmsg[50];
                    128: 
                    129: int    mflag;                  /* `You have mail.' message to recipient */
                    130: int    rflag;                  /* Reverse order of print */
                    131: int    qflag;                  /* Exit after interrrupts */
                    132: int    pflag;                  /* Print mail */
                    133: int    verbflag;               /* verbose */
                    134: int    callmexmail;            /* Xmail modifier present */
                    135: int    callmermail;            /* rmail modifier present */
                    136: struct msg {
                    137:        struct msg *m_next;             /* Link to next message */
                    138:        struct msg *m_prev;             /* Link to previous message */
                    139:        int     m_flag;                 /* Flags - non-zero if deleted */
                    140:        int     m_hsize;                /* Size of header of message */
                    141:        fsize_t m_seek;                 /* Start position of message */
                    142:        fsize_t m_end;                  /* End of message */
                    143: };
                    144: struct msg     *m_first = NULL;        /* First message */
                    145: struct msg     *m_last = NULL;         /* Last message */
                    146: 
                    147: struct tm      *tp;
                    148: 
                    149: char   iusage[] = "Bad command--type '?' for command summary\n";
                    150: char   nombox[] = "No mailbox '%s'.\n";
                    151: char   nomail[] = "No mail.\n";
                    152: char   noperm[] = "Mailbox '%s' access denied.\n";
                    153: char   moerr[] = "Cannot open mailbox '%s'\n";
                    154: char   wrerr[] = "Write error on '%s'\n";
                    155: char   nosave[] = "Cannot save letter in '%s'\n";
                    156: 
                    157: FILE   *mfp;                           /* Mailbox stream */
                    158: int    myuid;                          /* User-id of mail user */
                    159: int    mygid;                          /* Group-id of mail user */
                    160: char   myname[25];                     /* User name */
                    161: char   myfullname[50];
                    162: char   mymbox[256];                    /* $HOME/mbox           */
                    163: char   spoolname[50] = SPOOLDIR;
                    164: char   *mailbox = spoolname;
                    165: char   cmdname[1024];          /* Command for x{en,de}code filter */
                    166:                                /* and for tail recursion to uumail */
                    167:                                /* and for editor recursion */
                    168: 
                    169: char   *args[NARGS];                   /* Interactive command arglist */
                    170: char   msgline[NLINE];
                    171: char   cline[NCLINE] = "+\n";
                    172: char   *temp;                          /* Currently open temp file     */
                    173: char   templ[] = "/tmp/mailXXXXXX";    /* Temp file name template      */
                    174: char   *editname;                      /* name of editor               */
                    175: char   *scatname;                      /* name of scat filter          */
                    176: char   *askcc;                         /* Ask for CC: list? (YES/NO)   */
                    177: 
                    178: fsize_t        ftell();
                    179: char   *getlogin();
                    180: char   *mktemp();
                    181: int    catchintr();
                    182: int    catchpipe();
                    183: void   catchchild();
                    184: int    close_fds();
                    185: char   asuser [32];
                    186: 
                    187: main(argc, argv)
                    188: char *argv[];
                    189: {
                    190:        register char *ap;
                    191:        char    c, *foo;
                    192: 
                    193:        close_fds(); 
                    194:        logopen();
                    195: 
                    196:        ap = argv[0];
                    197:        if ( (foo=rindex(ap, '/')) != NULL )
                    198:                ap = foo+1;
                    199:        callmermail = (strcmp(ap, "rmail") == 0);
                    200:        callmexmail = (strcmp(ap, "xmail") == 0);
                    201: 
                    202:        if (callmermail)
                    203:                logdump("argv0 = rmail\n");
                    204: 
                    205:        asuser [0] = '\0';
                    206:        signal(SIGCLD, catchchild);
                    207:        signal(SIGINT, catchintr);
                    208:        signal(SIGPIPE, catchpipe);
                    209:        while ((c = getopt(argc, argv, "a:f:mpqrv")) != EOF) {
                    210:                switch(c) {
                    211:                case 'f':
                    212:                        if (!callmermail)
                    213:                                mailbox = optarg;
                    214:                        break;
                    215:                case 'a':
                    216:                        strcpy(asuser, optarg);
                    217:                        break;
                    218:                case 'm':
                    219:                        mflag++;
                    220:                        break;
                    221:                case 'p':
                    222:                        pflag++;
                    223:                        break;
                    224:                case 'q':
                    225:                        qflag++;
                    226:                        break;
                    227:                case 'r':
                    228:                        rflag++;
                    229:                        break;
                    230:                case 'v':
                    231:                        fprintf(stderr, "mail, ver. %s\n", revnop());
                    232:                        verbflag++;
                    233:                        break;
                    234:                default:
                    235:                        usage();
                    236:                }
                    237:        }
                    238:        if (callmermail) 
                    239:                verbflag = mflag = pflag = rflag = 0;
                    240:        setname();
                    241:        if (optind < argc) {
                    242:                qflag = 1;
                    243:                if ( send2(stdin, &argv[optind], (fsize_t)0,
                    244:                                                 (fsize_t)MAXLONG, 1) != 0 )
                    245:                        rmexit(1);
                    246:        } else {
                    247:                if ( ! pflag)
                    248:                        callmexmail = 0;
                    249:        }
                    250:        rmexit(0);
                    251: }
                    252: 
                    253: /*
                    254:  * Setup all the identities for the current user.
                    255:  */
                    256: setname()
                    257: {
                    258:        register struct passwd *pwp;
                    259:        register char *np;
                    260:        extern struct passwd * getpwnam();
                    261: 
                    262:        if (strlen(asuser) > 0) {
                    263:                if((pwp = getpwnam(asuser)) == NULL)
                    264:                        merr("No such user %s.\n", asuser);
                    265:                myuid = pwp -> pw_uid;
                    266:        } else          
                    267:                myuid = getuid();
                    268:        if ((pwp = getpwuid(myuid)) == NULL)
                    269:                merr("Who are you?\n");
                    270:        np = pwp->pw_name;
                    271:        mygid = pwp->pw_gid;
                    272:        strcat(spoolname, np);
                    273:        strcpy(myname, np);
                    274:        strcpy(myfullname, pwp->pw_gecos);
                    275:        strcpy(mymbox, pwp->pw_dir);
                    276:        strcat(mymbox, "/mbox");
                    277:        mktemp(templ);
                    278: 
                    279:        if ((editname=getenv("EDITOR"))==NULL)
                    280:                editname = "/bin/ed";
                    281: 
                    282:        if ( ((scatname=getenv("PAGER")) != NULL) &&
                    283:             (strlen(scatname) == 0) )
                    284:                scatname = NULL;
                    285: 
                    286:        if ((askcc=getenv("ASKCC")) != NULL)
                    287:                if ( strcmp(askcc, "YES") )
                    288:                        askcc = NULL;
                    289: }
                    290: 
                    291: /*
                    292:  * Lock the appropriately-numbered mailbox
                    293:  * (numbered by user-number) from multiple
                    294:  * accesses. There is a (small) race here
                    295:  * which will be overlooked for now.
                    296:  */
                    297: char   *lockname;
                    298: 
                    299: mlock(uid)
                    300: int uid;
                    301: {
                    302:        register int fd;
                    303:        static char lock[32];
                    304: 
                    305:        lockname = lock;
                    306:        sprintf(lock, "/tmp/maillock%d", uid);
                    307: 
                    308:        while ( (access(lockname, AEXISTS)) == 0 ){
                    309:                sprintf(BOBerrmsg, "{%d} sleeping(1)\n",getpid());
                    310:                logdump(BOBerrmsg);
                    311:                sleep(1);
                    312:        }
                    313: 
                    314:        if ((fd = creat(lockname, 0)) >= 0){
                    315:                close(fd);
                    316:                return(0);
                    317:        }else{
                    318:                return(1);
                    319:        }
                    320: }
                    321: 
                    322: /*
                    323:  * Unlock the currently-set lock (by `mlock')
                    324:  * also called from rmexit.
                    325:  */
                    326: munlock()
                    327: {
                    328:        if (lockname != NULL)
                    329:                unlink(lockname);
                    330:        lockname = NULL;
                    331: }
                    332: 
                    333: /*
                    334:  * Errors, usage, and exit removing
                    335:  * any tempfiles left around.
                    336:  */
                    337: mmsg(x)
                    338: {
                    339:        fprintf(stderr, "%r", &x);
                    340: }
                    341: 
                    342: merr(x, s)
                    343: char *x, *s;
                    344: {
                    345:        mmsg(x, s);
                    346:        logdump("merr: ");
                    347:        logdump(x, s);
                    348:        rmexit(1);
                    349: }
                    350: 
                    351: rmexit(s)
                    352: int s;
                    353: {
                    354:        if (temp != NULL)
                    355:                unlink(temp);
                    356: 
                    357:        /* only unlock the mailbox if we are exiting normally. Remember,
                    358:         * the box may have been locked by another process.
                    359:         */
                    360: 
                    361:        if(s == 0)
                    362:                munlock(); 
                    363: 
                    364:        sprintf(BOBerrmsg,"{%d} About to exit, status = 0x%04x\n", getpid(),s);
                    365:        logdump(BOBerrmsg);
                    366:        logclose();
                    367: 
                    368:        exit(s);
                    369: }
                    370: 
                    371: /*
                    372:  * Catch interrupts, taking the
                    373:  * appropriate action based on
                    374:  * the `-q' option.
                    375:  */
                    376: int    intrflag;               /* On when interrupt sent       */
                    377: int    pipeflag;               /* On when broken pipe caught   */
                    378: 
                    379: catchintr()
                    380: {
                    381:        logdump("Caught SIGINT\n");
                    382:        if (qflag)
                    383:                rmexit(1);
                    384:        intrflag = 1;
                    385:        signal(SIGINT, catchintr);
                    386: }
                    387: 
                    388: void catchchild()
                    389: {
                    390:        logdump("Caught SIGCLD\n");
                    391:        signal(SIGCLD, catchchild);
                    392: }
                    393: 
                    394: catchpipe()
                    395: {
                    396:        logdump("Caught SIGPIPE\n");
                    397:        pipeflag = 1;
                    398:        signal(SIGPIPE, catchpipe);
                    399: }
                    400: 
                    401: intcheck()
                    402: {
                    403:        if (intrflag || pipeflag) {
                    404:                if (intrflag){
                    405:                        putc('\n', stdout);
                    406:                        sprintf(BOBerrmsg,"{%d} lmail caught interrupt signal\n",
                    407:                                getpid());
                    408:                }else{
                    409:                        sprintf(BOBerrmsg,"{%d} lmail caught broken pipe signal", 
                    410:                                getpid());
                    411:                }
                    412: 
                    413:                logdump(BOBerrmsg);
                    414: 
                    415:                intrflag = pipeflag = 0;
                    416:                return (1);
                    417:        }
                    418:        return (0);
                    419: }
                    420: 
                    421: char   *
                    422: revnop()
                    423: {
                    424:        register        char *cp;
                    425:        register        char c;
                    426:        static          char revnobuf[32];
                    427: 
                    428:        if ((cp = index(rcsrev, ' ')) != NULL) {
                    429:                while (((c = *++cp) == ' ') && (c != '\0'))
                    430:                        ;
                    431:                strcpy(revnobuf, cp);
                    432:                if ((cp = index(revnobuf, ' ')) != NULL)
                    433:                        *cp = '\0';
                    434:                return (revnobuf);
                    435:        } else
                    436:                return("OOPS");
                    437: }
                    438: 
                    439: 
                    440: /* close any unwanted file descriptors that we may have inheritted */
                    441: 
                    442: close_fds()
                    443: {
                    444: 
                    445: int i;
                    446: 
                    447:        for(i = fileno(stderr) +1  ; i < _NFILE ; i++){
                    448:                close(i);
                    449:        }
                    450: }

unix.superglobalmegacorp.com

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