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

1.1       root        1: static char    *rcsrev = "$Revision: 1.1 $";
                      2: static char    *rcshdr =
                      3:        "$Header: /newbits/bin/mail/mail.c,v 1.1 91/02/04 10:42:40 bin Exp $";
                      4: /*
                      5:  * $Header: /newbits/bin/mail/mail.c,v 1.1 91/02/04 10:42:40 bin Exp $
                      6:  * $Log:       /newbits/bin/mail/mail.c,v $
                      7:  * Revision 1.1        91/02/04  10:42:40      bin
                      8:  * Initial revision
                      9:  * 
                     10:  * Revision 2.13       90/03/30  16:16:19      wgl
                     11:  * Correct seek pointer work within readmail.
                     12:  * 
                     13:  * Revision 2.12       90/03/12  14:19:08      wgl
                     14:  * New version of send doing aliases in a different place.
                     15:  * 
                     16:  * Revision 2.11       90/03/08  16:41:15      wgl
                     17:  * Add code to get signature file.
                     18:  * 
                     19:  * Revision 2.10       90/03/02  10:41:59      wgl
                     20:  * Add the -a flag so that uucp does not look like it is coming from
                     21:  * somewhere else.
                     22:  * 
                     23:  * Revision 2.9        90/03/01  11:17:19      wgl
                     24:  * Final conversion to rely soley on ^A^A as separators.
                     25:  * Effectively delete concept of m_hsize.
                     26:  * 
                     27:  * Revision 2.8        90/03/01  10:14:31      wgl
                     28:  * Go buy separators, not "From_" lines.
                     29:  * 
                     30:  * Revision 2.7        90/02/28  17:11:41      wgl
                     31:  * Add version print, add some changes to the message-id field.
                     32:  * 
                     33:  * Revision 2.6        90/02/28  16:42:09      wgl
                     34:  * Version number fakeout.
                     35:  * 
                     36:  * Revision 2.5        90/02/28  16:19:44      wgl
                     37:  * Try again to get versioin number right.
                     38:  * 
                     39:  * Revision 2.4        90/02/28  16:18:56      wgl
                     40:  * Get version number right.
                     41:  * 
                     42:  * Revision 2.3        90/02/28  16:04:59      wgl
                     43:  * Many changes; ripped out send.
                     44:  * Changes are to make it work with uucp and internet mail.
                     45:  * 
                     46:  * Revision 1.6        89/02/22  05:34:00      bin
                     47:  * Changes by rec to integrate with lauren's uumail.
                     48:  * 
                     49:  * Revision 1.5        88/09/01  14:49:01      bin
                     50:  * Source administration: Re-install declaration of getenv. 
                     51:  * It was inserted after epstein made his copy.
                     52:  * 
                     53:  * Revision 1.4        88/09/01  14:44:49      bin
                     54:  * Mark Epsteins changes for ASKCC and for message scrolling, and interrupt
                     55:  * handling during processing.
                     56:  * 
                     57:  * Revision 1.3        88/09/01  14:27:41      bin
                     58:  * declare getenv to get rid of integer pointer pun error message.
                     59:  * 
                     60:  * Revision 1.2        88/09/01  11:02:23      bin
                     61:  * Remove extra declaration of header which had rcs stuff in it.
                     62:  * 
                     63:  * Revision 1.1        88/09/01  10:55:34      bin
                     64:  * Initial revision
                     65:  * 
                     66:  */
                     67: /*
                     68:  * The mail command.
                     69:  * Coherent electronic postal system.
                     70:  * (NOTE: this command is written in such a way that
                     71:  * it assumed that it is setuid on execution to `root'.
                     72:  * All file accession is checked on this basis).
                     73:  * Modifications by rec january 1986 to include xmail.
                     74:  *              by epstein november 1987 to include CC:
                     75:  *              by epstein november 1987 to allow ^C exit to leave you in
                     76:  *                                       mail command processor
                     77:  *              by epstein november 1987 to substitute /usr/games/fortune
                     78:  *                                       for printing encrypted messages
                     79:  *             by rec february 1989 to tail to lauren weinstein's
                     80:  *                     mail for alias expansion and uucp queuing.
                     81:  *             by wgl January 1990 to handle uucp mail more directly.
                     82:  */
                     83: 
                     84: char   isummary[] = "\
                     85: \
                     86: Command summary:\n\
                     87:        d               Delete current message and print the next message\n\
                     88:        m [user ...]    Mail current message to each named 'user'\n\
                     89:        p               Print current message again\n\
                     90:        q               Quit and update the mailbox\n\
                     91:        r               Reverse direction of scan\n\
                     92:        s [file ...]    Save message in each named 'file'\n\
                     93:        t [user ...]    Mail standard input to each named 'user'\n\
                     94:        w [file ...]    Save message in each named 'file' without its header\n\
                     95:        x               Exit without updating mailbox\n\
                     96:        newline         Print the next message\n\
                     97:        .               Print current message again\n\
                     98:        +               Print the next message\n\
                     99:        -               Print the previous message\n\
                    100:        EOF             Put undeleted mail back into mailbox and quit\n\
                    101:        ?               Print this command summary\n\
                    102:        !command        Pass 'command' to the shell to execute\n\
                    103: If no 'file' is specified, 'mbox' in user's home directory is default.\n\
                    104: If no 'user' is specified, the invoking user is default.\n\
                    105: If the 'm', 'p', 't' commands are followed by an 'x',\n\
                    106: then the public key cryptosystem is applied to the message.\n\
                    107: \
                    108: ";
                    109: 
                    110: #include <stdio.h>
                    111: #include <pwd.h>
                    112: #include <sys/types.h>
                    113: #include <access.h>
                    114: #include <signal.h>
                    115: #include <sys/mdata.h>
                    116: #include <sys/stat.h>
                    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: int    mflag;                  /* `You have mail.' message to recipient */
                    128: int    rflag;                  /* Reverse order of print */
                    129: int    qflag;                  /* Exit after interrrupts */
                    130: int    pflag;                  /* Print mail */
                    131: int    verbflag;               /* verbose */
                    132: int    callmexmail;            /* Xmail modifier present */
                    133: int    callmermail;            /* rmail modifier present */
                    134: struct msg {
                    135:        struct msg *m_next;             /* Link to next message */
                    136:        struct msg *m_prev;             /* Link to previous message */
                    137:        int     m_flag;                 /* Flags - non-zero if deleted */
                    138:        int     m_hsize;                /* Size of header of message */
                    139:        fsize_t m_seek;                 /* Start position of message */
                    140:        fsize_t m_end;                  /* End of message */
                    141: };
                    142: struct msg     *m_first = NULL;        /* First message */
                    143: struct msg     *m_last = NULL;         /* Last message */
                    144: 
                    145: struct tm      *tp;
                    146: 
                    147: char   iusage[] = "Bad command--type '?' for command summary\n";
                    148: char   nombox[] = "No mailbox '%s'.\n";
                    149: char   nomail[] = "No mail.\n";
                    150: char   noperm[] = "Mailbox '%s' access denied.\n";
                    151: char   moerr[] = "Cannot open mailbox '%s'\n";
                    152: char   wrerr[] = "Write error on '%s'\n";
                    153: char   nosave[] = "Cannot save letter in '%s'\n";
                    154: 
                    155: FILE   *mfp;                           /* Mailbox stream */
                    156: int    myuid;                          /* User-id of mail user */
                    157: int    mygid;                          /* Group-id of mail user */
                    158: char   myname[25];                     /* User name */
                    159: char   myfullname[50];
                    160: char   mymbox[256];                    /* $HOME/mbox */
                    161: char   mydead[256];                    /* $HOME/dead.letter */
                    162: char   mysig[256];                     /* $HOME/dead.letter */
                    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   *askcc;                         /* Ask for CC: list? (YES/NO) */
                    176: 
                    177: fsize_t        ftell();
                    178: char   *getlogin();
                    179: char   *mktemp();
                    180: int    catchintr();
                    181: char   *malloc();
                    182: extern char    *rindex();
                    183: char   asuser [32];
                    184: main(argc, argv)
                    185: char *argv[];
                    186: {
                    187:        register char *ap;
                    188:        char    c;
                    189: 
                    190:        ap = argv[0];
                    191:        if (rindex (ap, '/') != NULL)
                    192:                ++ap;
                    193:        callmermail = (strcmp(ap, "rmail") == 0);
                    194:        callmexmail = (strcmp(ap, "xmail") == 0);
                    195:        asuser [0] = '\0';
                    196:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    197:                signal(SIGINT, catchintr);
                    198:        while ((c = getopt(argc, argv, "a:f:mpqrv")) != EOF) {
                    199:                switch(c) {
                    200:                case 'f':
                    201:                        if (!callmermail)
                    202:                                mailbox = optarg;
                    203:                        break;
                    204:                case 'a':
                    205:                        strcpy(asuser, optarg);
                    206:                        break;
                    207:                case 'm':
                    208:                        mflag++;
                    209:                        break;
                    210:                case 'p':
                    211:                        pflag++;
                    212:                        break;
                    213:                case 'q':
                    214:                        qflag++;
                    215:                        break;
                    216:                case 'r':
                    217:                        rflag++;
                    218:                        break;
                    219:                case 'v':
                    220:                        fprintf(stderr, "mail, ver. %s\n", revnop());
                    221:                        verbflag++;
                    222:                        break;
                    223:                default:
                    224:                        usage();
                    225:                }
                    226:        }
                    227:        if (callmermail) 
                    228:                verbflag = mflag = pflag = rflag = 0;
                    229:        setname();
                    230:        if (optind < argc) {
                    231:                qflag = 1;
                    232:                send2(stdin, &argv[optind], (fsize_t)0, (fsize_t)MAXLONG, 1);
                    233:        } else {
                    234:                if ( ! pflag)
                    235:                        callmexmail = 0;
                    236:                commands();
                    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:        strcpy(mydead, pwp->pw_dir);
                    266:        strcat(mydead, "/dead.letter");
                    267:        strcpy(mysig, pwp->pw_dir);
                    268:        strcat(mysig, "/.sig.mail");
                    269:        mktemp(templ);
                    270: 
                    271:        if ((editname=getenv("EDITOR"))==NULL)
                    272:                editname = "/bin/ed";
                    273: 
                    274:        if ((askcc=getenv("ASKCC")) != NULL)
                    275:                if ( strcmp(askcc, "YES") || !isatty(fileno(stdin)) )
                    276:                        askcc = NULL;
                    277: }
                    278: 
                    279: /*
                    280:  * Process mail's interactive commands
                    281:  * for reading/deleting/saving mail.
                    282:  */
                    283: commands()
                    284: {
                    285:        register struct msg *mp;
                    286:        struct msg *dest;
                    287:        register char **fnp;
                    288:        register FILE *fp;
                    289:        fsize_t seek;
                    290: 
                    291:        readmail();
                    292:        mprint(mp = rflag ? m_last : m_first);
                    293:        for (;;) {
                    294:                readmail();
                    295:                intcheck();
                    296:                if ( ! pflag) {
                    297:                        callmexmail = 0;
                    298:                        mmsg("? ");
                    299:                        if (fgets(cline, sizeof cline, stdin) == NULL) {
                    300:                                if (intcheck())
                    301:                                        continue;
                    302:                                break;
                    303:                        }
                    304:                }
                    305:                switch (cline[0]) {
                    306:                case 'd':
                    307:                        if (cline[1] != '\n')
                    308:                                goto usage;
                    309:                        mp->m_flag += 1;
                    310:                        goto advance;
                    311: 
                    312:                case 'm':
                    313:                case 't':
                    314:                        if (csplit(cline, args) == 1) {
                    315:                                args[1] = myname;
                    316:                                args[2] = NULL;
                    317:                        }
                    318:                        callmexmail = (cline[1] == 'x');
                    319:                        if (cline[0] == 'm') {
                    320:                                send2(mfp, args+1, mp->m_seek, mp->m_end - 3, 0);
                    321:                                fseek(mfp, mp->m_seek, 0);
                    322:                        } else
                    323:                                send2(stdin, args+1, 0L, (fsize_t)MAXLONG, 1);
                    324:                        break;
                    325: 
                    326:                case '.':
                    327:                case 'p':
                    328:                        if (cline[1] == 'x') {
                    329:                                callmexmail = 1;
                    330:                                if (cline[2] != '\n')
                    331:                                        goto usage;
                    332:                        } else if (cline[1] != '\n')
                    333:                                goto usage;
                    334:                        if (mprint(mp))
                    335:                                break;
                    336:                        goto advance;
                    337: 
                    338:                case 'q':
                    339:                        if (cline[1] != '\n')
                    340:                                goto usage;
                    341:                        mquit();
                    342:                        /* NOTREACHED */
                    343: 
                    344:                case 'r':
                    345:                        if (cline[1] != '\n')
                    346:                                goto usage;
                    347:                        rflag = ! rflag;
                    348:                        break;
                    349:                case 's':
                    350:                case 'w':
                    351:                        if (csplit(cline, args) == 1) {
                    352:                                args[1] = mymbox;
                    353:                                args[2] = NULL;
                    354:                        }
                    355:                        seek = mp->m_seek;
                    356:                        if (cline[0] == 'w')
                    357:                                seek += mp->m_hsize;
                    358:                        for (fnp = &args[1]; *fnp != NULL; fnp++) {
                    359:                                fp = NULL;
                    360:                                if (maccess(*fnp) < 0
                    361:                                 || (fp = fopen(*fnp, "a")) == NULL
                    362:                                 || mcopy(mfp, fp, seek, mp->m_end - 3, 0))
                    363:                                        mmsg(nosave, *fnp);
                    364:                                if (fp != NULL) {
                    365:                                        fclose(fp);
                    366:                                        chown(*fnp, myuid, mygid);
                    367:                                }
                    368:                        }
                    369:                        break;
                    370: 
                    371:                case 'x':
                    372:                        if (cline[1] != '\n')
                    373:                                goto usage;
                    374:                        rmexit(0);
                    375:                        /* NOTREACHED */
                    376: 
                    377:                case '!':
                    378:                        if (system(cline+1) == 127)
                    379:                                mmsg("Try again\n");
                    380:                        else
                    381:                                mmsg("!\n");
                    382:                        break;
                    383: 
                    384:                case '?':
                    385:                        mmsg(isummary);
                    386:                        break;
                    387: 
                    388:                case '-':
                    389:                        if (cline[1] != '\n')
                    390:                                goto usage;
                    391:                        dest = rflag ? m_last : m_first;
                    392:                        goto nextmsg;
                    393: 
                    394:                case '+':
                    395:                        if (cline[1] != '\n')
                    396:                                goto usage;
                    397:                case '\n':
                    398:                advance:
                    399:                        dest = rflag ? m_first : m_last;
                    400:                nextmsg:
                    401:                        do {
                    402:                                if (mp == dest) {
                    403:                                        if (pflag)
                    404:                                                return;
                    405:                                        mmsg("No more messages.\n");
                    406:                                        break;
                    407:                                }
                    408:                                mp = (dest==m_last) ? mp->m_next : mp->m_prev;
                    409:                        } while (mprint(mp) == 0);
                    410:                        break;
                    411: 
                    412:                default:
                    413:                usage:
                    414:                        mmsg(iusage);
                    415:                        break;
                    416:                }
                    417:        }
                    418:        putc('\n', stderr);
                    419:        mquit();
                    420: }
                    421: 
                    422: /*
                    423:  * Read through the mail-box file
                    424:  * constructing list of letters.
                    425:  * On subsequent calls, append any additional mail
                    426:  * and notify the user.
                    427:  */
                    428: readmail()
                    429: {
                    430:        register struct msg *mp;
                    431:        struct stat sb;
                    432:        static long m_last_end;
                    433:        fsize_t first;          /* to become ffsize_t */
                    434:        int datasw;
                    435: 
                    436:        if (m_first == NULL) {
                    437:                if (stat(mailbox, &sb) < 0)
                    438:                        merr(nombox, mailbox);
                    439:                if (sb.st_size == 0)
                    440:                        merr(nomail);
                    441:                if (access(mailbox, AREAD) < 0)
                    442:                        merr(noperm, mailbox);
                    443:                if ((mfp = fopen(mailbox, "r")) == NULL)
                    444:                        merr(moerr, mailbox);
                    445:                m_last_end = 0;
                    446:        } else {
                    447:                fstat(fileno(mfp), &sb);
                    448:                if (sb.st_size == m_last_end)
                    449:                        return;
                    450:                mmsg("More mail received.\n");
                    451:        }
                    452: 
                    453:        for(mlock(myuid);;) {
                    454:                fseek(mfp, m_last_end, 0);
                    455:                first = ftell(mfp);
                    456:                for (datasw = 0;
                    457:                     fgets(msgline, sizeof msgline, mfp) != NULL; ) {
                    458:                        if(!(datasw = strcmp("\1\1\n", msgline))) {
                    459:                                /* found message seperator */
                    460:                                mp = (struct msg *)malloc(sizeof(*mp));
                    461:                                mp->m_next = NULL;
                    462:                                mp->m_prev = m_last;
                    463:                                mp->m_flag = mp->m_hsize = 0;
                    464:                                mp->m_seek = first;
                    465:                                mp->m_end = first = m_last_end = ftell(mfp);
                    466:                                if (m_first == NULL)
                    467:                                        m_last = m_first = mp;
                    468:                                else
                    469:                                        m_last = m_last->m_next = mp;
                    470:                        }
                    471:                }
                    472: 
                    473:                if(!datasw)
                    474:                        break;
                    475: 
                    476:                /* unterminated data, patch and retry */
                    477:                fclose(mfp);
                    478:                if ((mfp = fopen(mailbox, "a")) == NULL)
                    479:                        merr(moerr, mailbox);
                    480:                fprintf(mfp, "\1\1\n"); /* terminate it */
                    481:                fclose(mfp);
                    482:                if ((mfp = fopen(mailbox, "r")) == NULL)
                    483:                        merr(moerr, mailbox);
                    484:                mmsg("Incomplete message found.\n");
                    485:        }
                    486:        munlock();
                    487: }
                    488: 
                    489: /*
                    490:  * Split a command line up into
                    491:  * argv (passed) and argc (returned).
                    492:  */
                    493: int
                    494: csplit(command, args)
                    495: char *command;
                    496: char **args;
                    497: {
                    498:        register char *cp;
                    499:        register char **ap;
                    500:        register int c;
                    501: 
                    502:        cp = command;
                    503:        ap = args;
                    504:        for (;;) {
                    505:                while ((c = *cp)==' ' || c=='\t')
                    506:                        *cp++ = '\0';
                    507:                if (*cp == '\n')
                    508:                        *cp = '\0';
                    509:                if (*cp == '\0')
                    510:                        break;
                    511:                *ap++ = cp;
                    512:                while ((c = *cp)!=' ' && c!='\t' && c!='\n' && c!='\0')
                    513:                        cp++;
                    514:        }
                    515:        *ap = NULL;
                    516:        return (ap - args);
                    517: }
                    518: 
                    519: /*
                    520:  * Lock the appropriately-numbered mailbox
                    521:  * (numbered by user-number) from multiple
                    522:  * accesses. There is a (small) race here
                    523:  * which will be overlooked for now.
                    524:  */
                    525: char   *lockname;
                    526: 
                    527: mlock(uid)
                    528: int uid;
                    529: {
                    530:        register int fd;
                    531:        static char lock[32];
                    532: 
                    533:        lockname = lock;
                    534:        sprintf(lock, "/tmp/maillock%d", uid);
                    535:        while (access(lockname, 0) == 0)
                    536:                sleep(1);
                    537:        if ((fd = creat(lockname, 0)) >= 0)
                    538:                close(fd);
                    539: }
                    540: 
                    541: /*
                    542:  * Unlock the currently-set lock (by `mlock')
                    543:  * also called from rmexit.
                    544:  */
                    545: munlock()
                    546: {
                    547:        if (lockname != NULL)
                    548:                unlink(lockname);
                    549:        lockname = NULL;
                    550: }
                    551: 
                    552: /*
                    553:  * Exit, after rewriting the
                    554:  * mailbox
                    555:  */
                    556: mquit()
                    557: {
                    558:        register struct msg *mp;
                    559:        register FILE *nfp;
                    560:        struct stat sb;
                    561: 
                    562:        readmail();
                    563:        mlock(myuid);
                    564:        if (mailbox != spoolname && maccess(mailbox) < 0)
                    565:                merr(noperm, mailbox);
                    566:        fstat(fileno(mfp), &sb);
                    567:        signal(SIGINT, SIG_IGN);
                    568:        unlink(mailbox);
                    569:        if ((nfp = fopen(mailbox, "w")) == NULL)
                    570:                merr("Cannot re-write '%s'\n", mailbox);
                    571:        chown(mailbox, sb.st_uid, sb.st_gid);
                    572:        chmod(mailbox, sb.st_mode&0777);
                    573:        for (mp = m_first; mp != NULL; mp = mp->m_next) {
                    574:                if (mp->m_flag == 0) {
                    575:                        if (mcopy(mfp, nfp, mp->m_seek, mp->m_end, 0)) 
                    576:                                merr(wrerr, mailbox);
                    577: /*                     else
                    578:                                fprintf(nfp, "\1\1\n"); */
                    579:                }
                    580:        }
                    581:        fclose(nfp);
                    582:        fclose(mfp);
                    583:        munlock();
                    584:        rmexit(0);
                    585: }
                    586: 
                    587: /*
                    588:  * Print the current message, given by
                    589:  * the message pointer (`mp').
                    590:  */
                    591: mprint(mp)
                    592: register struct msg *mp;
                    593: {
                    594:        FILE *xfp;
                    595:        if (mp->m_flag)
                    596:                return 0;
                    597:        if (callmexmail) {
                    598:                sprintf(cmdname, "xdecode");
                    599:                if ((xfp = popen(cmdname, "w")) == NULL) {
                    600:                        return 0;
                    601:                }
                    602:                mcopy(mfp, xfp, mp->m_seek+mp->m_hsize, mp->m_end, 1);
                    603:                pclose(xfp);
                    604:        } else {
                    605:                fseek(mfp, mp->m_seek, 0);
                    606:                if (fgets(msgline, sizeof msgline, mfp) != NULL &&
                    607:                    strncmp(msgline, "From xmail", 10) == 0) {
                    608:                        printf("From xmail\n");
                    609:                        system("/usr/games/fortune");
                    610:                        return(1);
                    611:                }
                    612:                mcopy(mfp, stdout, mp->m_seek, mp->m_end - 3, 1);
                    613:        }
                    614:        return (1);
                    615: }
                    616: 
                    617: /*
                    618:  *     Get additional users to receive message (CC:)
                    619:  */
                    620: 
                    621: char **
                    622: getcc(users)
                    623: register char **users;
                    624: {
                    625:        register char **ulist = args;
                    626:        static  char names[NCLINE];
                    627: 
                    628:        mmsg("CC: ");
                    629:        if ( fgets(names, sizeof names, stdin) == NULL )
                    630:                return(users);
                    631: 
                    632:        while (*users != NULL)
                    633:                *ulist++ = *users++;
                    634: 
                    635:        csplit(names, ulist);
                    636:        return(args);
                    637: }
                    638: 
                    639:        
                    640: /*
                    641:  * Errors, usage, and exit removing
                    642:  * any tempfiles left around.
                    643:  */
                    644: mmsg(x, s)
                    645: char *x, *s;
                    646: {
                    647:        fprintf(stderr, x, s);
                    648: }
                    649: 
                    650: merr(x, s)
                    651: char *x, *s;
                    652: {
                    653:        mmsg(x, s);
                    654:        rmexit(1);
                    655: }
                    656: 
                    657: rmexit(s)
                    658: int s;
                    659: {
                    660:        if (temp != NULL)
                    661:                unlink(temp);
                    662:        munlock();
                    663:        exit(s);
                    664: }
                    665: 
                    666: /*
                    667:  * Catch interrupts, taking the
                    668:  * appropriate action based on
                    669:  * the `-q' option.
                    670:  */
                    671: int    intflag;                /* On when interrupt sent */
                    672: 
                    673: catchintr()
                    674: {
                    675:        signal(SIGINT, SIG_IGN);
                    676:        if (qflag)
                    677:                rmexit(1);
                    678:        intflag = 1;
                    679:        signal(SIGINT, catchintr);
                    680: }
                    681: 
                    682: intcheck()
                    683: {
                    684:        if (intflag) {
                    685:                intflag = 0;
                    686:                putc('\n', stderr);
                    687:                return (1);
                    688:        }
                    689:        return (0);
                    690: }
                    691: 
                    692: /*
                    693:  * Call the system to execute a command line
                    694:  * which is passed as an argument.
                    695:  * Change the user id and group id.
                    696:  */
                    697: system(line)
                    698: char *line;
                    699: {
                    700:        int status, pid;
                    701:        register wpid;
                    702:        register int (*intfun)(), (*quitfun)();
                    703: 
                    704:        if ((pid = fork()) < 0)
                    705:                return (-1);
                    706:        if (pid == 0) {         /* Child */
                    707:                setuid(myuid);
                    708:                setgid(mygid);
                    709:                execl("/bin/sh", "sh", "-c", line, NULL);
                    710:                exit(0177);
                    711:        }
                    712:        intfun = signal(SIGINT, SIG_IGN);
                    713:        quitfun = signal(SIGQUIT, SIG_IGN);
                    714:        while ((wpid = wait(&status))!=pid && wpid>=0)
                    715:                ;
                    716:        if (wpid < 0)
                    717:                status = wpid;
                    718:        signal(SIGINT, intfun);
                    719:        signal(SIGQUIT, quitfun);
                    720:        return (status);
                    721: }
                    722: 
                    723: char   *
                    724: revnop()
                    725: {
                    726:        register        char *cp;
                    727:        register        char c;
                    728:        static          char revnobuf[32];
                    729: 
                    730:        if ((cp = index(rcsrev, ' ')) != NULL) {
                    731:                while (((c = *++cp) == ' ') && (c != '\0'))
                    732:                        ;
                    733:                strcpy(revnobuf, cp);
                    734:                if ((cp = index(revnobuf, ' ')) != NULL)
                    735:                        *cp = '\0';
                    736:                return (revnobuf);
                    737:        } else
                    738:                return("OOPS");
                    739: }

unix.superglobalmegacorp.com

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