Annotation of coherent/d/bin/mail/lmail/lmail.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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