Annotation of 42BSD/bin/mail.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)mail.c     4.21 (Berkeley) 11/1/83";
                      3: #endif
                      4: 
                      5: #include <ctype.h>
                      6: #include <stdio.h>
                      7: #include <pwd.h>
                      8: #include <utmp.h>
                      9: #include <signal.h>
                     10: #include <sys/types.h>
                     11: #include <sys/stat.h>
                     12: #include <setjmp.h>
                     13: #include <sysexits.h>
                     14: 
                     15: #define SENDMAIL       "/usr/lib/sendmail"
                     16: 
                     17: 
                     18: /*copylet flags */
                     19:        /*remote mail, add rmtmsg */
                     20: #define REMOTE 1
                     21:        /* zap header and trailing empty line */
                     22: #define ZAP    3
                     23: #define ORDINARY 2
                     24: #define        FORWARD 4
                     25: #define        LSIZE   256
                     26: #define        MAXLET  300     /* maximum number of letters */
                     27: #define        MAILMODE (~0600)                /* mode of created mail */
                     28: 
                     29: char   line[LSIZE];
                     30: char   resp[LSIZE];
                     31: struct let {
                     32:        long    adr;
                     33:        char    change;
                     34: } let[MAXLET];
                     35: int    nlet    = 0;
                     36: char   lfil[50];
                     37: long   iop, time();
                     38: char   *getenv();
                     39: char   *index();
                     40: char   lettmp[] = "/tmp/maXXXXX";
                     41: char   maildir[] = "/usr/spool/mail/";
                     42: char   mailfile[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
                     43: char   dead[] = "dead.letter";
                     44: char   *netname = "vax";
                     45: char   forwmsg[] = " forwarded\n";
                     46: FILE   *tmpf;
                     47: FILE   *malf;
                     48: char   *my_name;
                     49: char   *getlogin();
                     50: struct passwd  *getpwuid();
                     51: int    error;
                     52: int    changed;
                     53: int    forward;
                     54: char   from[] = "From ";
                     55: long   ftell();
                     56: int    delete();
                     57: char   *ctime();
                     58: int    flgf;
                     59: int    flgp;
                     60: int    delflg = 1;
                     61: int    hseqno;
                     62: jmp_buf        sjbuf;
                     63: int    rmail;
                     64: 
                     65: main(argc, argv)
                     66: char **argv;
                     67: {
                     68:        register i;
                     69:        char sobuf[BUFSIZ];
                     70: 
                     71:        setbuf(stdout, sobuf);
                     72:        mktemp(lettmp);
                     73:        unlink(lettmp);
                     74:        my_name = getlogin();
                     75:        if (my_name == NULL || strlen(my_name) == 0) {
                     76:                struct passwd *pwent;
                     77:                pwent = getpwuid(getuid());
                     78:                if (pwent==NULL)
                     79:                        my_name = "???";
                     80:                else
                     81:                        my_name = pwent->pw_name;
                     82:        }
                     83:        if(setjmp(sjbuf)) done();
                     84:        for (i=SIGHUP; i<=SIGTERM; i++)
                     85:                setsig(i, delete);
                     86:        tmpf = fopen(lettmp, "w");
                     87:        if (tmpf == NULL) {
                     88:                fprintf(stderr, "mail: cannot open %s for writing\n", lettmp);
                     89:                done();
                     90:        }
                     91:        if (argv[0][0] == 'r')
                     92:                rmail++;
                     93:        if (argv[0][0] != 'r' &&        /* no favors for rmail*/
                     94:           (argc == 1 || argv[1][0] == '-' && !any(argv[1][1], "rhd")))
                     95:                printmail(argc, argv);
                     96:        else
                     97:                bulkmail(argc, argv);
                     98:        done();
                     99: }
                    100: 
                    101: setsig(i, f)
                    102: int i;
                    103: int (*f)();
                    104: {
                    105:        if(signal(i, SIG_IGN)!=SIG_IGN)
                    106:                signal(i, f);
                    107: }
                    108: 
                    109: any(c, str)
                    110:        register int c;
                    111:        register char *str;
                    112: {
                    113: 
                    114:        while (*str)
                    115:                if (c == *str++)
                    116:                        return(1);
                    117:        return(0);
                    118: }
                    119: 
                    120: printmail(argc, argv)
                    121: char **argv;
                    122: {
                    123:        int flg, i, j, print;
                    124:        char *p, *getarg();
                    125:        struct stat statb;
                    126: 
                    127:        setuid(getuid());
                    128:        cat(mailfile, maildir, my_name);
                    129:        if (stat(mailfile, &statb) >= 0
                    130:            && (statb.st_mode & S_IFMT) == S_IFDIR) {
                    131:                strcat(mailfile, "/");
                    132:                strcat(mailfile, my_name);
                    133:        }
                    134:        for (; argc>1; argv++, argc--) {
                    135:                if (argv[1][0]=='-') {
                    136:                        if (argv[1][1]=='q')
                    137:                                delflg = 0;
                    138:                        else if (argv[1][1]=='p') {
                    139:                                flgp++;
                    140:                                delflg = 0;
                    141:                        } else if (argv[1][1]=='f') {
                    142:                                if (argc>=3) {
                    143:                                        strcpy(mailfile, argv[2]);
                    144:                                        argv++;
                    145:                                        argc--;
                    146:                                }
                    147:                        } else if (argv[1][1]=='r') {
                    148:                                forward = 1;
                    149:                        } else if (argv[1][1]=='h') {
                    150:                                forward = 1;
                    151:                        } else {
                    152:                                fprintf(stderr, "mail: unknown option %c\n", argv[1][1]);
                    153:                                done();
                    154:                        }
                    155:                } else
                    156:                        break;
                    157:        }
                    158:        malf = fopen(mailfile, "r");
                    159:        if (malf == NULL) {
                    160:                fprintf(stdout, "No mail.\n");
                    161:                return;
                    162:        }
                    163:        lock(mailfile);
                    164:        copymt(malf, tmpf);
                    165:        fclose(malf);
                    166:        fclose(tmpf);
                    167:        unlock();
                    168:        tmpf = fopen(lettmp, "r");
                    169: 
                    170:        changed = 0;
                    171:        print = 1;
                    172:        for (i = 0; i < nlet; ) {
                    173:                j = forward ? i : nlet - i - 1;
                    174:                if(setjmp(sjbuf)) {
                    175:                        print=0;
                    176:                } else {
                    177:                        if (print)
                    178:                                copylet(j, stdout, ORDINARY);
                    179:                        print = 1;
                    180:                }
                    181:                if (flgp) {
                    182:                        i++;
                    183:                        continue;
                    184:                }
                    185:                setjmp(sjbuf);
                    186:                fprintf(stdout, "? ");
                    187:                fflush(stdout);
                    188:                if (fgets(resp, LSIZE, stdin) == NULL)
                    189:                        break;
                    190:                switch (resp[0]) {
                    191: 
                    192:                default:
                    193:                        fprintf(stderr, "usage\n");
                    194:                case '?':
                    195:                        print = 0;
                    196:                        fprintf(stderr, "q\tquit\n");
                    197:                        fprintf(stderr, "x\texit without changing mail\n");
                    198:                        fprintf(stderr, "p\tprint\n");
                    199:                        fprintf(stderr, "s[file]\tsave (default mbox)\n");
                    200:                        fprintf(stderr, "w[file]\tsame without header\n");
                    201:                        fprintf(stderr, "-\tprint previous\n");
                    202:                        fprintf(stderr, "d\tdelete\n");
                    203:                        fprintf(stderr, "+\tnext (no delete)\n");
                    204:                        fprintf(stderr, "m user\tmail to user\n");
                    205:                        fprintf(stderr, "! cmd\texecute cmd\n");
                    206:                        break;
                    207: 
                    208:                case '+':
                    209:                case 'n':
                    210:                case '\n':
                    211:                        i++;
                    212:                        break;
                    213:                case 'x':
                    214:                        changed = 0;
                    215:                case 'q':
                    216:                        goto donep;
                    217:                case 'p':
                    218:                        break;
                    219:                case '^':
                    220:                case '-':
                    221:                        if (--i < 0)
                    222:                                i = 0;
                    223:                        break;
                    224:                case 'y':
                    225:                case 'w':
                    226:                case 's':
                    227:                        flg = 0;
                    228:                        if (resp[1] != '\n' && resp[1] != ' ') {
                    229:                                printf("illegal\n");
                    230:                                flg++;
                    231:                                print = 0;
                    232:                                continue;
                    233:                        }
                    234:                        if (resp[1] == '\n' || resp[1] == '\0') {
                    235:                                p = getenv("HOME");
                    236:                                if(p != 0)
                    237:                                        cat(resp+1, p, "/mbox");
                    238:                                else
                    239:                                        cat(resp+1, "", "mbox");
                    240:                        }
                    241:                        for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) {
                    242:                                malf = fopen(lfil, "a");
                    243:                                if (malf == NULL) {
                    244:                                        fprintf(stdout, "mail: cannot append to %s\n", lfil);
                    245:                                        flg++;
                    246:                                        continue;
                    247:                                }
                    248:                                copylet(j, malf, resp[0]=='w'? ZAP: ORDINARY);
                    249:                                fclose(malf);
                    250:                        }
                    251:                        if (flg)
                    252:                                print = 0;
                    253:                        else {
                    254:                                let[j].change = 'd';
                    255:                                changed++;
                    256:                                i++;
                    257:                        }
                    258:                        break;
                    259:                case 'm':
                    260:                        flg = 0;
                    261:                        if (resp[1] == '\n' || resp[1] == '\0') {
                    262:                                i++;
                    263:                                continue;
                    264:                        }
                    265:                        if (resp[1] != ' ') {
                    266:                                printf("invalid command\n");
                    267:                                flg++;
                    268:                                print = 0;
                    269:                                continue;
                    270:                        }
                    271:                        for (p = resp+1; (p = getarg(lfil, p)) != NULL; )
                    272:                                if (!sendrmt(j, lfil, "/bin/mail"))     /* couldn't send it */
                    273:                                        flg++;
                    274:                        if (flg)
                    275:                                print = 0;
                    276:                        else {
                    277:                                let[j].change = 'd';
                    278:                                changed++;
                    279:                                i++;
                    280:                        }
                    281:                        break;
                    282:                case '!':
                    283:                        system(resp+1);
                    284:                        printf("!\n");
                    285:                        print = 0;
                    286:                        break;
                    287:                case 'd':
                    288:                        let[j].change = 'd';
                    289:                        changed++;
                    290:                        i++;
                    291:                        if (resp[1] == 'q')
                    292:                                goto donep;
                    293:                        break;
                    294:                }
                    295:        }
                    296:    donep:
                    297:        if (changed)
                    298:                copyback();
                    299: }
                    300: 
                    301: copyback()     /* copy temp or whatever back to /usr/spool/mail */
                    302: {
                    303:        register i, n, c;
                    304:        int new = 0;
                    305:        struct stat stbuf;
                    306: 
                    307:        signal(SIGINT, SIG_IGN);
                    308:        signal(SIGHUP, SIG_IGN);
                    309:        signal(SIGQUIT, SIG_IGN);
                    310:        lock(mailfile);
                    311:        stat(mailfile, &stbuf);
                    312:        if (stbuf.st_size != let[nlet].adr) {   /* new mail has arrived */
                    313:                malf = fopen(mailfile, "r");
                    314:                if (malf == NULL) {
                    315:                        fprintf(stdout, "mail: can't re-read %s\n", mailfile);
                    316:                        done();
                    317:                }
                    318:                fseek(malf, let[nlet].adr, 0);
                    319:                fclose(tmpf);
                    320:                tmpf = fopen(lettmp, "a");
                    321:                fseek(tmpf, let[nlet].adr, 0);
                    322:                while ((c = fgetc(malf)) != EOF)
                    323:                        fputc(c, tmpf);
                    324:                fclose(malf);
                    325:                fclose(tmpf);
                    326:                tmpf = fopen(lettmp, "r");
                    327:                let[++nlet].adr = stbuf.st_size;
                    328:                new = 1;
                    329:        }
                    330:        malf = fopen(mailfile, "w");
                    331:        if (malf == NULL) {
                    332:                fprintf(stderr, "mail: can't rewrite %s\n", lfil);
                    333:                done();
                    334:        }
                    335:        n = 0;
                    336:        for (i = 0; i < nlet; i++)
                    337:                if (let[i].change != 'd') {
                    338:                        copylet(i, malf, ORDINARY);
                    339:                        n++;
                    340:                }
                    341:        fclose(malf);
                    342:        if (new)
                    343:                fprintf(stdout, "new mail arrived\n");
                    344:        unlock();
                    345: }
                    346: 
                    347: copymt(f1, f2) /* copy mail (f1) to temp (f2) */
                    348: FILE *f1, *f2;
                    349: {
                    350:        long nextadr;
                    351: 
                    352:        nlet = nextadr = 0;
                    353:        let[0].adr = 0;
                    354:        while (fgets(line, LSIZE, f1) != NULL) {
                    355:                if (isfrom(line))
                    356:                        let[nlet++].adr = nextadr;
                    357:                nextadr += strlen(line);
                    358:                fputs(line, f2);
                    359:        }
                    360:        let[nlet].adr = nextadr;        /* last plus 1 */
                    361: }
                    362: 
                    363: copylet(n, f, type)
                    364:        FILE *f;
                    365: {
                    366:        int ch;
                    367:        long k;
                    368: 
                    369:        fseek(tmpf, let[n].adr, 0);
                    370:        k = let[n+1].adr - let[n].adr;
                    371:        while(k-- > 1 && (ch=fgetc(tmpf))!='\n')
                    372:                if(type!=ZAP) fputc(ch,f);
                    373:        if(type==REMOTE) {
                    374:                char hostname[32];
                    375:                gethostname(hostname, sizeof (hostname));
                    376:                fprintf(f, " remote from %s\n", hostname);
                    377:        } else if (type==FORWARD)
                    378:                fprintf(f, forwmsg);
                    379:        else if(type==ORDINARY)
                    380:                fputc(ch,f);
                    381:        while(k-->1)
                    382:                fputc(ch=fgetc(tmpf), f);
                    383:        if(type!=ZAP || ch!= '\n')
                    384:                fputc(fgetc(tmpf), f);
                    385: }
                    386: 
                    387: isfrom(lp)
                    388: register char *lp;
                    389: {
                    390:        register char *p;
                    391: 
                    392:        for (p = from; *p; )
                    393:                if (*lp++ != *p++)
                    394:                        return(0);
                    395:        return(1);
                    396: }
                    397: 
                    398: bulkmail(argc, argv)
                    399: char **argv;
                    400: {
                    401:        char truename[100];
                    402:        int first;
                    403:        register char *cp;
                    404:        int gaver = 0;
                    405:        char *newargv[1000];
                    406:        register char **ap;
                    407:        register char **vp;
                    408:        int dflag;
                    409: 
                    410:        dflag = 0;
                    411:        if (argc < 1)
                    412:                fprintf(stderr, "puke\n");
                    413:        for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++)
                    414:        {
                    415:                if (ap[0][0] == '-' && ap[0][1] == 'd')
                    416:                        dflag++;
                    417:        }
                    418:        if (!dflag)
                    419:        {
                    420:                /* give it to sendmail, rah rah! */
                    421:                unlink(lettmp);
                    422:                ap = newargv+1;
                    423:                if (rmail)
                    424:                        *ap-- = "-s";
                    425:                *ap = "-sendmail";
                    426:                setuid(getuid());
                    427:                execv(SENDMAIL, ap);
                    428:                perror(SENDMAIL);
                    429:                exit(EX_UNAVAILABLE);
                    430:        }
                    431: 
                    432:        truename[0] = 0;
                    433:        line[0] = '\0';
                    434: 
                    435:        /*
                    436:         * When we fall out of this, argv[1] should be first name,
                    437:         * argc should be number of names + 1.
                    438:         */
                    439: 
                    440:        while (argc > 1 && *argv[1] == '-') {
                    441:                cp = *++argv;
                    442:                argc--;
                    443:                switch (cp[1]) {
                    444:                case 'r':
                    445:                        if (argc <= 0) {
                    446:                                usage();
                    447:                                done();
                    448:                        }
                    449:                        gaver++;
                    450:                        strcpy(truename, argv[1]);
                    451:                        fgets(line, LSIZE, stdin);
                    452:                        if (strcmpn("From", line, 4) == 0)
                    453:                                line[0] = '\0';
                    454:                        argv++;
                    455:                        argc--;
                    456:                        break;
                    457: 
                    458:                case 'h':
                    459:                        if (argc <= 0) {
                    460:                                usage();
                    461:                                done();
                    462:                        }
                    463:                        hseqno = atoi(argv[1]);
                    464:                        argv++;
                    465:                        argc--;
                    466:                        break;
                    467: 
                    468:                case 'd':
                    469:                        break;
                    470:                
                    471:                default:
                    472:                        usage();
                    473:                        done();
                    474:                }
                    475:        }
                    476:        if (argc <= 1) {
                    477:                usage();
                    478:                done();
                    479:        }
                    480:        if (gaver == 0)
                    481:                strcpy(truename, my_name);
                    482:        /*
                    483:        if (argc > 4 && strcmp(argv[1], "-r") == 0) {
                    484:                strcpy(truename, argv[2]);
                    485:                argc -= 2;
                    486:                argv += 2;
                    487:                fgets(line, LSIZE, stdin);
                    488:                if (strcmpn("From", line, 4) == 0)
                    489:                        line[0] = '\0';
                    490:        } else
                    491:                strcpy(truename, my_name);
                    492:        */
                    493:        time(&iop);
                    494:        fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop));
                    495:        iop = ftell(tmpf);
                    496:        flgf = 1;
                    497:        for (first = 1;; first = 0) {
                    498:                if (first && line[0] == '\0' && fgets(line, LSIZE, stdin) == NULL)
                    499:                        break;
                    500:                if (!first && fgets(line, LSIZE, stdin) == NULL)
                    501:                        break;
                    502:                if (line[0] == '.' && line[1] == '\n' && isatty(fileno(stdin)))
                    503:                        break;
                    504:                if (isfrom(line))
                    505:                        fputs(">", tmpf);
                    506:                fputs(line, tmpf);
                    507:                flgf = 0;
                    508:        }
                    509:        fputs("\n", tmpf);
                    510:        nlet = 1;
                    511:        let[0].adr = 0;
                    512:        let[1].adr = ftell(tmpf);
                    513:        fclose(tmpf);
                    514:        if (flgf)
                    515:                return;
                    516:        tmpf = fopen(lettmp, "r");
                    517:        if (tmpf == NULL) {
                    518:                fprintf(stderr, "mail: cannot reopen %s for reading\n", lettmp);
                    519:                return;
                    520:        }
                    521:        while (--argc > 0) {
                    522:                if (!sendmail(0, *++argv, truename))
                    523:                        error++;
                    524:        }
                    525:        if (error && safefile(dead)) {
                    526:                setuid(getuid());
                    527:                malf = fopen(dead, "w");
                    528:                if (malf == NULL) {
                    529:                        fprintf(stdout, "mail: cannot open %s\n", dead);
                    530:                        fclose(tmpf);
                    531:                        return;
                    532:                }
                    533:                copylet(0, malf, ZAP);
                    534:                fclose(malf);
                    535:                fprintf(stdout, "Mail saved in %s\n", dead);
                    536:        }
                    537:        fclose(tmpf);
                    538: }
                    539: 
                    540: sendrmt(n, name, rcmd)
                    541: char *name;
                    542: char *rcmd;
                    543: {
                    544:        FILE *rmf, *popen();
                    545:        register char *p;
                    546:        char rsys[64], cmd[64];
                    547:        register local, pid;
                    548:        int sts;
                    549: 
                    550:        local = 0;
                    551:        if (index(name, '^')) {
                    552:                while (p = index(name, '^'))
                    553:                        *p = '!';
                    554:                if (strncmp(name, "researc", 7)) {
                    555:                        strcpy(rsys, "research");
                    556:                        if (*name != '!')
                    557:                                --name;
                    558:                        goto skip;
                    559:                }
                    560:        }
                    561:        if (*name=='!')
                    562:                name++;
                    563:        for(p=rsys; *name!='!'; *p++ = *name++)
                    564:                if (*name=='\0') {
                    565:                        local++;
                    566:                        break;
                    567:                }
                    568:        *p = '\0';
                    569:        if ((!local && *name=='\0') || (local && *rsys=='\0')) {
                    570:                fprintf(stdout, "null name\n");
                    571:                return(0);
                    572:        }
                    573: skip:
                    574:        if ((pid = fork()) == -1) {
                    575:                fprintf(stderr, "mail: can't create proc for remote\n");
                    576:                return(0);
                    577:        }
                    578:        if (pid) {
                    579:                while (wait(&sts) != pid) {
                    580:                        if (wait(&sts)==-1)
                    581:                                return(0);
                    582:                }
                    583:                return(!sts);
                    584:        }
                    585:        setuid(getuid());
                    586:        if (local)
                    587:                sprintf(cmd, "%s %s", rcmd, rsys);
                    588:        else {
                    589:                if (index(name+1, '!'))
                    590:                        sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1);
                    591:                else
                    592:                        sprintf(cmd, "uux - %s!rmail %s", rsys, name+1);
                    593:        }
                    594:        if ((rmf=popen(cmd, "w")) == NULL)
                    595:                exit(1);
                    596:        copylet(n, rmf, local ? !strcmp(rcmd, "/bin/mail") ? FORWARD : ORDINARY : REMOTE);
                    597:        exit(pclose(rmf) != 0);
                    598: }
                    599: 
                    600: usage()
                    601: {
                    602: 
                    603:        fprintf(stderr, "Usage: mail [ -f ] people . . .\n");
                    604:        error = EX_USAGE;
                    605: }
                    606: 
                    607: #include <sys/socket.h>
                    608: #include <netinet/in.h>
                    609: #include <netdb.h>
                    610: struct sockaddr_in biffaddr;
                    611: 
                    612: sendmail(n, name, fromaddr)
                    613: int n;
                    614: char *name;
                    615: char *fromaddr;
                    616: {
                    617:        char file[100];
                    618:        register char *p;
                    619:        register mask;
                    620:        struct passwd *pw, *getpwnam();
                    621:        struct stat statb;
                    622:        char buf[128];
                    623:        int f;
                    624:        struct hostent *hp = NULL;
                    625:        struct servent *sp = NULL;
                    626: 
                    627:        for(p=name; *p!='!'&&*p!='^' &&*p!='\0'; p++)
                    628:                ;
                    629:        if (*p == '!'|| *p=='^')
                    630:                return(sendrmt(n, name, 0));
                    631:        if ((pw = getpwnam(name)) == NULL) {
                    632:                fprintf(stdout, "mail: can't send to %s\n", name);
                    633:                return(0);
                    634:        }
                    635:        cat(file, maildir, name);
                    636:        if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) {
                    637:                strcat(file, "/");
                    638:                strcat(file, name);
                    639:        }
                    640:        mask = umask(MAILMODE);
                    641:        if (!safefile(file))
                    642:                return(0);
                    643:        lock(file);
                    644:        malf = fopen(file, "a");
                    645:        umask(mask);
                    646:        if (malf == NULL) {
                    647:                unlock();
                    648:                fprintf(stdout, "mail: cannot append to %s\n", file);
                    649:                return(0);
                    650:        }
                    651:        chown(file, pw->pw_uid, pw->pw_gid);
                    652:        {
                    653:                hp = gethostbyname("localhost");
                    654:                sp = getservbyname("biff", "udp");
                    655:                if (hp && sp) {
                    656:                        f = socket(AF_INET, SOCK_DGRAM, 0, 0);
                    657:                        sprintf(buf, "%s@%d\n", name, ftell(malf)); 
                    658:                }
                    659:        }
                    660:        copylet(n, malf, ORDINARY);
                    661:        fclose(malf);
                    662:        if (hp && sp) {
                    663:                biffaddr.sin_family = hp->h_addrtype;
                    664:                bcopy(hp->h_addr, &biffaddr.sin_addr, hp->h_length);
                    665:                biffaddr.sin_port = sp->s_port;
                    666:                sendto(f, buf, strlen(buf)+1, 0, &biffaddr, sizeof (biffaddr));
                    667:                close(f);
                    668:        }
                    669:        unlock();
                    670:        return(1);
                    671: }
                    672: 
                    673: delete(i)
                    674: {
                    675:        setsig(i, delete);
                    676:        fprintf(stderr, "\n");
                    677:        if(delflg)
                    678:                longjmp(sjbuf, 1);
                    679:        done();
                    680: }
                    681: 
                    682: /*
                    683:  * Lock the specified mail file by setting the file mailfile.lock.
                    684:  * We must, of course, be careful to unlink the lock file by a call
                    685:  * to unlock before we stop.  The algorithm used here is to see if
                    686:  * the lock exists, and if it does, to check its modify time.  If it
                    687:  * is older than 30 seconds, we assume error and set our own file.
                    688:  * Otherwise, we wait for 5 seconds and try again.
                    689:  */
                    690: 
                    691: char   *maillock       = ".lock";              /* Lock suffix for mailname */
                    692: char   *lockname       = "/usr/spool/mail/tmXXXXXX";
                    693: char   locktmp[30];                            /* Usable lock temporary */
                    694: char   curlock[50];                            /* Last used name of lock */
                    695: int    locked;                                 /* To note that we locked it */
                    696: 
                    697: lock(file)
                    698: char *file;
                    699: {
                    700:        register int f;
                    701:        struct stat sbuf;
                    702:        long curtime;
                    703:        int statfailed;
                    704: 
                    705:        if (locked || flgf)
                    706:                return(0);
                    707:        strcpy(curlock, file);
                    708:        strcat(curlock, maillock);
                    709:        strcpy(locktmp, lockname);
                    710:        mktemp(locktmp);
                    711:        unlink(locktmp);
                    712:        statfailed = 0;
                    713:        for (;;) {
                    714:                f = lock1(locktmp, curlock);
                    715:                if (f == 0) {
                    716:                        locked = 1;
                    717:                        return(0);
                    718:                }
                    719:                if (stat(curlock, &sbuf) < 0) {
                    720:                        if (statfailed++ > 5)
                    721:                                return(-1);
                    722:                        sleep(5);
                    723:                        continue;
                    724:                }
                    725:                statfailed = 0;
                    726:                time(&curtime);
                    727:                if (curtime < sbuf.st_ctime + 30) {
                    728:                        sleep(5);
                    729:                        continue;
                    730:                }
                    731:                unlink(curlock);
                    732:        }
                    733: }
                    734: 
                    735: /*
                    736:  * Remove the mail lock, and note that we no longer
                    737:  * have it locked.
                    738:  */
                    739: 
                    740: unlock()
                    741: {
                    742: 
                    743:        unlink(curlock);
                    744:        locked = 0;
                    745: }
                    746: 
                    747: /*
                    748:  * Attempt to set the lock by creating the temporary file,
                    749:  * then doing a link/unlink.  If it fails, return -1 else 0
                    750:  */
                    751: 
                    752: lock1(tempfile, name)
                    753:        char tempfile[], name[];
                    754: {
                    755:        register int fd;
                    756: 
                    757:        fd = creat(tempfile, 0);
                    758:        if (fd < 0)
                    759:                return(-1);
                    760:        close(fd);
                    761:        if (link(tempfile, name) < 0) {
                    762:                unlink(tempfile);
                    763:                return(-1);
                    764:        }
                    765:        unlink(tempfile);
                    766:        return(0);
                    767: }
                    768: 
                    769: done()
                    770: {
                    771:        if(locked)
                    772:                unlock();
                    773:        unlink(lettmp);
                    774:        unlink(locktmp);
                    775:        exit(error);
                    776: }
                    777: 
                    778: cat(to, from1, from2)
                    779: char *to, *from1, *from2;
                    780: {
                    781:        int i, j;
                    782: 
                    783:        j = 0;
                    784:        for (i=0; from1[i]; i++)
                    785:                to[j++] = from1[i];
                    786:        for (i=0; from2[i]; i++)
                    787:                to[j++] = from2[i];
                    788:        to[j] = 0;
                    789: }
                    790: 
                    791: char *getarg(s, p)     /* copy p... into s, update p */
                    792: register char *s, *p;
                    793: {
                    794:        while (*p == ' ' || *p == '\t')
                    795:                p++;
                    796:        if (*p == '\n' || *p == '\0')
                    797:                return(NULL);
                    798:        while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
                    799:                *s++ = *p++;
                    800:        *s = '\0';
                    801:        return(p);
                    802: }
                    803: 
                    804: safefile(f)
                    805:        char *f;
                    806: {
                    807:        struct stat statb;
                    808: 
                    809:        if (lstat(f, &statb) < 0)
                    810:                return (1);
                    811:        if (statb.st_nlink != 1 || (statb.st_mode & S_IFMT) == S_IFLNK) {
                    812:                fprintf(stderr, "mail: %s has more than one link or is a symbolic link\n", f);
                    813:                return (0);
                    814:        }
                    815:        return (1);
                    816: }

unix.superglobalmegacorp.com

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