Annotation of 41BSD/cmd/mail.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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