Annotation of 40BSD/cmd/berknet/v6mail.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Version 6 Cory mail--
                      3:  *     a clean and simple mail program
                      4:  *     machine and version independent
                      5:  *             Eric Schmidt
                      6:  *     must run as setuid root to chown the destination mailbox
                      7:  *     if NOTROOT defined, doesn't need to run as root
                      8:  *     
                      9:  *     DON'T CHANGE THIS CODE
                     10:  *             bitch to "csvax:schmidt" instead
                     11:  */
                     12: 
                     13: /*
                     14:  * mail command usage
                     15:  *     mail [-yn]
                     16:  *             prints your mail
                     17:  *     mail people
                     18:  *             sends standard input to people
                     19:  *
                     20:  *     mail -r fromaddr people
                     21:  *             sends mail from the network
                     22:  *
                     23:  *     mail -d people
                     24:  *             don't call delivermail, send mail directly
                     25:  *     mail msgs
                     26:  *             send to "msgs"
                     27:  *     mail filename
                     28:  *             mail to filename instead of user (must be at least one /)
                     29:  *     mail -D
                     30:  *             delete the invokers mailbox (more efficient than 
                     31:  *                     mail -n >/dev/null)
                     32:  */
                     33: 
                     34: /*
                     35:  *     bugs:
                     36:  *             Ingres 11/70 multiple names/uid?
                     37:  *     additions:
                     38:  *             Save? type 'x' - doesn't unlink the mail file
                     39:  */
                     40: # include <whoami.h>
                     41: # include <stdio.h>
                     42: # include "mach.h"
                     43: 
                     44: # ifdef RAND
                     45: 
                     46: /* for all machines at RAND */
                     47: # define MAILMODE 644
                     48: 
                     49: # endif
                     50: 
                     51: # ifdef NOSC
                     52: 
                     53: /* for all machines at NOSC */
                     54: # define MAILMODE 644
                     55: 
                     56: # endif
                     57: 
                     58: # ifdef BERKELEY
                     59: /* for Berkeley */
                     60: /* for each machine */
                     61: # ifdef A
                     62: # define MAILMODE 0600
                     63: # define MSGSCMD "/usr/bin/eecs/msgs"
                     64: # endif
                     65: 
                     66: # ifdef B
                     67: # define MSGSCMD "/usr/bin/eecs/msgs"
                     68: # define MAILMODE 0600
                     69: # endif
                     70: 
                     71: # ifdef C
                     72: # define MSGSCMD "/usr/bin/eecs/msgs"
                     73: # define MAILMODE 0600
                     74: # endif
                     75: 
                     76: # ifdef D
                     77: # define MSGSCMD "/usr/bin/eecs/msgs"
                     78: # define MAILMODE 0600
                     79: # endif
                     80: 
                     81: # ifdef E
                     82: # define MAILMODE 0600
                     83: # define MSGSCMD "/usr/bin/eecs/msgs"
                     84: # endif
                     85: 
                     86: # ifdef ING70
                     87: # define MAILMODE 0666
                     88: # define MSGSCMD "/usr/bin/msgs"
                     89: # define NOTROOT
                     90: # endif
                     91: 
                     92: # ifdef INGVAX
                     93: # define MAILMODE 0644
                     94: # define MSGSCMD "/usr/ucb/msgs"
                     95: # endif
                     96: 
                     97: # ifdef VIRUS
                     98: # define MAILMODE 0644
                     99: # define MSGSCMD "/usr/bin/msgs"
                    100: # endif
                    101: 
                    102: # ifdef IMAGE
                    103: # define MAILMODE 0644
                    104: # define MSGSCMD "/usr/bin/msgs"
                    105: # endif
                    106: 
                    107: # ifdef ESVAX
                    108: # define MAILMODE 0644
                    109: # define MSGSCMD "/usr/ucb/msgs"
                    110: # endif
                    111: 
                    112: # ifdef Q
                    113: # define MAILMODE 0600
                    114: # define MSGSCMD "/usr/bin/eecs/msgs"
                    115: # endif
                    116: 
                    117: # ifdef SRC
                    118: # define MAILMODE 0600
                    119: # define MSGSCMD "/usr/bin/msgs"
                    120: # endif
                    121: 
                    122: # ifdef MATHSTAT
                    123: # define MAILMODE 0600
                    124: # define MSGSCMD "/usr/bin/msgs"
                    125: # endif
                    126: 
                    127: # ifdef CSVAX
                    128: # define MAILMODE 0644
                    129: # define MSGSCMD "/usr/ucb/msgs"
                    130: # endif
                    131: 
                    132: # ifdef ONYX
                    133: # define MAILMODE 0644
                    134: # define MSGSCMD "/usr/ucb/bin/msgs"
                    135: # endif
                    136: 
                    137: # ifdef CORY
                    138: # define MAILMODE 0600
                    139: # define MSGSCMD "/usr/bin/eecs/msgs"
                    140: # endif
                    141: 
                    142: # ifdef EECS40
                    143: # define MAILMODE 0644
                    144: # define MSGSCMD "/usr/bin/msgs"
                    145: # endif
                    146: /* end of berkeley defsn */
                    147: 
                    148: # endif
                    149: /* end of per-machine ifdefs */
                    150: 
                    151: # ifdef USRMAIL
                    152: # define MAILDIR "/usr/mail"
                    153: # else
                    154: # define MAILDIR "/usr/spool/mail"
                    155: # endif
                    156: 
                    157: char   lettmp[]  = "/tmp/MaXXXXX";     /* keep letter before sending it */
                    158: char   preptmp[] = "/tmp/mbXXXXX";     /* if prepending msg, use this file */
                    159: int    chew;                           /* if true, strip extra from lines */
                    160: int    dflag;                          /* if true, don't call delivermail */
                    161: char   shopcnt[30] = "0";              /* hop count parameter for rmt mail */
                    162: int    errs;                           /* no of errs in sending */
                    163: char   deleteonly;                     /* if true, just delete mailbox */
                    164: char   remname[50];                    /* if non-empty, from line extra */
                    165: 
                    166: char _sobuf[BUFSIZ];
                    167: main(argc, argv)
                    168: char **argv;
                    169: {
                    170:        register int myuid;
                    171:        int delexit();
                    172:        char namebuf[128], *sn = NULL, logindir[60];
                    173:        struct passwd *pwd;
                    174: 
                    175:        setbuf(stdout,_sobuf);
                    176:        mktemp(lettmp);
                    177:        mktemp(preptmp);
                    178:        unlink(lettmp);
                    179:        unlink(preptmp);
                    180:        myuid = getuid();
                    181:        logindir[0] = 0;
                    182:        sn = getlogin();
                    183:        if(sn == NULL || *sn == 0 || *sn == ' '){
                    184:                pwd = getpwuid(myuid);          /* will read passwd file */
                    185:                if(pwd != NULL){
                    186:                        sn = pwd->pw_name;
                    187:                        strcpy(logindir,pwd->pw_dir);
                    188:                }
                    189:                if(sn == NULL){
                    190:                        fprintf(stderr,"Who are you?\n");
                    191:                        delexit(EX_OSFILE);
                    192:                }
                    193:        }
                    194:        strcpy(namebuf,sn);
                    195:        if (argc < 2)
                    196:                goto hitit;
                    197:        for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++)
                    198:        switch(argv[0][1]) {
                    199:                case 'y':
                    200:                case 'n':
                    201:                        argc++, argv--;
                    202: hitit:
                    203:                        printmail(argc, argv, namebuf,logindir);
                    204:                        delexit(EX_OK);
                    205: 
                    206:                case 'r':       /* one-arg -r--   -r addr */
                    207:                        if (argc < 2)
                    208:                                continue;
                    209:                        /* ignore -r if not network or root */
                    210:                        if (strcmp("network", namebuf) == 0 || myuid == 0 ||
                    211:                            strcmp("uucp", namebuf) == 0 || index(argv[1], '!') != NULL) {
                    212:                                strcpy(namebuf,argv[1]);
                    213:                                chew++;         /* eat From lines */
                    214:                        }
                    215:                        else strcpy(remname, argv[1]);
                    216:                        argc--, argv++;
                    217:                        continue;
                    218:                case 'h':       /* hop count - used by network */
                    219:                        if(argc < 2) continue;
                    220:                        strcpy(shopcnt,argv[1]);
                    221:                        argc--, argv++;
                    222:                        continue;
                    223:                case 'd':       /* really deliver this message */
                    224:                        dflag++;
                    225:                        continue;
                    226:                case 'D':       /* only delete the invokers mailbox */
                    227:                        deleteonly++;
                    228:                        goto hitit;             /* delete mail box, thats all */
                    229:        }
                    230:        /* if we are already ignoring signals, catch sigint */
                    231:        if(signal(SIGINT,SIG_IGN) != SIG_IGN)
                    232:                signal(SIGINT, delexit);
                    233:        argc++, argv--;
                    234:        bulkmail(argc, argv, namebuf);
                    235:        delexit(EX_OK);
                    236: }
                    237: 
                    238: printmail(argc, argv, name, logindir)
                    239: char **argv;
                    240: char *name, *logindir;
                    241: {
                    242:        register int c;
                    243:        FILE *fdin;
                    244:        char sfnmail[60], mbox[120];
                    245:        struct stat statbuf;
                    246: 
                    247: # ifdef OLDMAIL
                    248:        if(logindir[0] == 0){
                    249:                pwd = getpwuid(getuid());
                    250:                if(pwd == NULL){
                    251:                        fprintf(stderr,"Can't get directory\n");
                    252:                        exit(EX_OSFILE);
                    253:                }
                    254:                strcpy(logindir, pwd->pw_dir);
                    255:        }
                    256:        sprintf(sfnmail,"%s/.mail",logindir);
                    257: # else
                    258:        sprintf(sfnmail,"%s/%s",MAILDIR,name);
                    259: # endif
                    260:        if(deleteonly){
                    261:                remove(sfnmail);
                    262:                return;
                    263:        }
                    264:        if (stat(sfnmail, &statbuf)>=0 && statbuf.st_nlink==1 &&
                    265:                getsize(&statbuf) > 0L && (fdin = fopen(sfnmail, "r")) != NULL){
                    266:                getput(fdin, stdout);
                    267:                fclose(fdin);
                    268:                fflush(stdout);
                    269:                c = 'y';
                    270:                if (argc<2) {
                    271:                        if(isatty(0)){
                    272:                                printf("Save(y-n) ?");
                    273:                                fflush(stdout);
                    274:                                c = getchar();
                    275:                        }
                    276:                } else
                    277:                        c = argv[1][1];
                    278:                if (!any(c, "xyn"))
                    279:                        delexit(EX_OK);
                    280:                if (c == 'y') {
                    281:                        sprintf(mbox,"%s/mbox",logindir);
                    282:                        if (accesss(mbox)) {
                    283:                                printf("Saved mail in 'mbox'\n");
                    284:                                if(insert(sfnmail, mbox, getuid(),getgid()))
                    285:                                        remove(sfnmail);
                    286:                        }
                    287:                        else printf("In wrong directory\n");
                    288:                }
                    289:                else if(c != 'x') remove(sfnmail);
                    290:        } else
                    291:                printf("No mail.\n");
                    292: }
                    293: 
                    294: bulkmail(argc, argv, from)
                    295: char **argv, *from;
                    296: {
                    297:        extern int errno;
                    298:        char linebuf[BUFSIZ];
                    299:        char *getdate();
                    300:        FILE *fdout;
                    301: 
                    302: # ifdef DELIVERM
                    303:        /*
                    304:        **  Ship off to delivermail if appropriate (and possible)
                    305:        */
                    306: 
                    307:        if (!dflag)
                    308:        {
                    309:                argv[0] = "-delivermail";
                    310:                argv[argc] = 0;
                    311:                execv("/etc/delivermail", argv);
                    312:                /* oops...  better just deliver it. */
                    313:                fprintf(stderr, "Not using delivermail\n");
                    314:                errno = 0;
                    315:                argv[argc] = (char *)-1;
                    316:        }
                    317: # endif
                    318: 
                    319:        fdout = fopen(lettmp, "w");
                    320:        if (fdout == NULL) {
                    321:                perror(lettmp);
                    322:                delexit(EX_OSFILE);
                    323:        }
                    324:        /*
                    325:         * If delivering mail from the network via mail -r,
                    326:         * Strip the leading line and throw it away, as long
                    327:         * as it begins with "From ..." (and preserve the date if poss.)
                    328:         */
                    329:        if (chew) {
                    330:                fgets(linebuf,BUFSIZ,stdin);
                    331:                if(strncmp(linebuf,"From ",5) != 0){
                    332:                        fline(fdout,NULL,from);
                    333:                        fprintf(fdout,"%s", linebuf);
                    334:                }
                    335:                else fline(fdout,getdate(linebuf),from);
                    336:        }
                    337:        else fline(fdout,NULL,from);
                    338:        if(remname[0]) fprintf(fdout,"(from %s)\n",remname);
                    339: 
                    340:        /* on the image machine, promt with subj */
                    341:        if(getput(stdin,fdout) == 0)
                    342:                delexit(EX_OSERR);
                    343:        putc('\n',fdout);
                    344:        fclose(fdout);
                    345:        while (--argc > 0)
                    346:                sendto(*++argv,from);
                    347:        delexit(errs);
                    348: }
                    349: /* print from line, with date date, if date = NULL, compute it */
                    350: fline(fdout,date,from)
                    351: FILE *fdout;
                    352: char *date;
                    353: char *from;
                    354: {
                    355:        int tbuf[2];
                    356: 
                    357:        if(date == NULL){
                    358:                time(tbuf);
                    359:                date = ctime(tbuf);
                    360:        }
                    361:        fprintf(fdout,"From %s  %s", from, date);
                    362: }
                    363: /* look over linebuf and return ptr to date, NULL if error */
                    364: char *getdate(linebuf)
                    365: char *linebuf;
                    366: {
                    367:        register char *s;
                    368:        s = linebuf;
                    369:        while(*s){
                    370:                if(strncmp(s," Sun ",5) == 0
                    371:                || strncmp(s," Mon ",5) == 0
                    372:                || strncmp(s," Tue ",5) == 0
                    373:                || strncmp(s," Wed ",5) == 0
                    374:                || strncmp(s," Thu ",5) == 0
                    375:                || strncmp(s," Fri ",5) == 0
                    376:                || strncmp(s," Sat ",5) == 0)
                    377:                        return(++s);
                    378:                s++;
                    379:        }
                    380:        return(NULL);
                    381: }
                    382: 
                    383: sendto(person, fromaddr)
                    384: char *person;
                    385: char *fromaddr;
                    386: {
                    387:        static int saved = 0;
                    388:        register int hisuid, hisgid;
                    389:        char sfnmail[60], logindir[60];
                    390:        struct passwd *pwd;
                    391: 
                    392:        stripmach(&person);
                    393:        if(person[0] == ':')person++;
                    394:        /* delivermail provides these services */
                    395:        if(any(':',person)
                    396: # ifdef MSGSCMD
                    397:                || strcmp(person,"msgs") == 0
                    398: # endif
                    399:                ){
                    400:                int pid;
                    401:                int pidchild;
                    402: 
                    403:                while((pid = fork()) == -1)sleep(2);
                    404:                if (pid < 0) {
                    405:                        perror("fork");
                    406:                        goto assback;
                    407:                }
                    408:                if (pid == 0) {
                    409:                        fclose(stdin);
                    410:                        freopen(lettmp,"r",stdin);
                    411:                        setuid(getuid());       /* insure no security hole*/
                    412:                        if (strcmp(person,"msgs") != 0) {
                    413:                                execl("/usr/net/bin/sendberkmail",
                    414:                                "sendberkmail", "-t",person,"-f",fromaddr,
                    415:                                "-h",shopcnt,0);
                    416:                                perror("/usr/net/bin/sendberkmail");
                    417:                        }
                    418: # ifdef MSGSCMD
                    419:                        else {
                    420:                                execl(MSGSCMD, "msgs", "-s", 0);
                    421:                                perror(MSGSCMD);
                    422:                        }
                    423: # endif
                    424:                        exit(EX_UNAVAILABLE);
                    425:                }
                    426:                for (;;) {
                    427:                        register int rcode = wait(&pidchild);
                    428:                        if (rcode == -1)
                    429:                                goto assback;
                    430:                        if (rcode == pid)
                    431:                                break;
                    432:                }
                    433:                if ((pidchild & 0377) != 0 || (pidchild >> 8) != 0)
                    434:                        goto assback;
                    435:                return;
                    436:        }
                    437: 
                    438:        if(!any('/',person)){
                    439:        /* if name has no / in it, we assume it is a user's name */
                    440: # ifdef HPASSWD
                    441:                hisuid = uidfromsn(person);
                    442: # else
                    443:                pwd = getpwnam(person);
                    444:                if(pwd != NULL){
                    445:                        hisuid = guid(pwd->pw_uid,pwd->pw_gid);
                    446:                        hisgid = pwd->pw_gid;
                    447:                        strcpy(logindir,pwd->pw_dir);
                    448:                }
                    449:                else hisuid = -1;
                    450: # endif
                    451:                if(hisuid == -1){
                    452:        assback:
                    453:                        fflush(stdout);
                    454:                        fprintf(stderr,"Can't send to %s.\n", person);
                    455:                        errs++;
                    456:                        if (isatty(0) && saved==0) {
                    457:                                saved++;
                    458:                                if (accesss("dead.letter")) {
                    459:                                        printf("Letter saved in 'dead.letter'\n");
                    460:                                        insert(lettmp, "dead.letter",
                    461:                                                getuid(),getgid());
                    462:                                } else
                    463:                                        printf("In wrong directory\n");
                    464:                        }
                    465:                        return;
                    466:                }
                    467: # ifdef OLDMAIL
                    468:                sprintf(sfnmail,"%s/.mail",logindir);
                    469: # else
                    470:                sprintf(sfnmail,"%s/%s",MAILDIR,person);
                    471: # endif
                    472:                lock(sfnmail);
                    473:                insert(lettmp, sfnmail, hisuid, hisgid);
                    474:                unlock();
                    475:                }
                    476:        else {          /* it has / in it, "person" is a file */
                    477:                if(accesss(person)){
                    478:                        lock(person);
                    479:                        insert(lettmp, person, -1, -1);
                    480:                        unlock();
                    481:                }
                    482:                else
                    483:                        fprintf(stderr,"Can't access %s\n",person);
                    484:        }
                    485: }
                    486: 
                    487: /* return 1 if success, 0 otherwise */
                    488: insert(from, to, uid, gid)
                    489: char *from, *to;
                    490: {
                    491: # ifdef V6
                    492:        return(prepend(from,to,uid, gid));
                    493: # else
                    494:        return(append(from,to,uid, gid));
                    495: # endif
                    496: }
                    497: /* return 1 if success, 0 otherwise */
                    498: append(from,to,uid, gid)
                    499: char *from, *to;
                    500: {
                    501:        register FILE *fdin, *fdout;
                    502:        int ret;
                    503:        struct stat statbuf;
                    504: /* biff ... */
                    505:        char *rindex();
                    506:        char *cp;
                    507:        char buf[100];
                    508:        int f;
                    509: /* end biff */
                    510:        if (stat(to, &statbuf) >= 0 && (statbuf.st_mode&S_IFDIR) != 0) {
                    511:                fprintf(stderr, "Exotic destination %s\n", to);
                    512:                errs++;
                    513:                return(0);
                    514:        }
                    515:        if ((fdout = fopen(to, "a")) == NULL) {
                    516:                perror(to);
                    517:                errs++;
                    518:                return(0);
                    519:        }
                    520: # ifndef NOTROOT
                    521:        if(uid != -1)mchown(to, uid, gid);
                    522: # endif
                    523:        if(uid != -1)chmod(to, MAILMODE);
                    524:        if ((fdin = fopen(from, "r")) == NULL) {
                    525:                perror(from);
                    526:                return(0);
                    527:        }
                    528:        {
                    529:                f = open("/dev/mail", 1);
                    530:                cp = rindex(to, '/');
                    531:                if (cp) {
                    532:                        sprintf(buf, "%s@%d\n", cp+1, ftell(fdout)); 
                    533:                }
                    534:        }
                    535:        ret = getput(fdin,fdout);
                    536:        fclose(fdin);
                    537:        fclose(fdout);
                    538: /* biff */
                    539:        if (cp && f >= 0) {
                    540:                write(f, buf, strlen(buf)+1);
                    541:                close(f);
                    542:        }
                    543: /* end biff */
                    544:        return(ret);
                    545: }
                    546: 
                    547: /* return 1 if success, 0 otherwise */
                    548: prepend(from, to, uid, gid)
                    549: char *from, *to;
                    550: {
                    551:        register int (*sig)();
                    552:        struct stat statbuf;
                    553:        FILE *fdout, *fdin;
                    554:        int ret;
                    555: 
                    556:        if (stat(to, &statbuf) >= 0 && (statbuf.st_mode&S_IFDIR) != 0) {
                    557:                fprintf(stderr, "Exotic destination %s\n", to);
                    558:                goto badexit;
                    559:        }
                    560:        unlink(preptmp);
                    561:        if ((fdout = fopen(preptmp, "w")) == NULL) {
                    562:                perror("mail");
                    563:                goto badexit;
                    564:        }
                    565:        chmod(preptmp, MAILMODE);
                    566:        if ((fdin = fopen(from, "r")) == NULL) {
                    567:                perror("mail");
                    568:                goto badexit;
                    569:        }
                    570:        if(getput(fdin,fdout) == 0){
                    571:                perror("file i/o");
                    572:                goto badexit;
                    573:        }
                    574:        fclose(fdin);
                    575:        fdin = fopen(to, "r");
                    576:        /* ignore error since may not exist */
                    577:        if(fdin != NULL && getput(fdin,fdout) == 0){
                    578:                perror("file i/o");
                    579:                goto badexit;
                    580:        }
                    581:        if(fdin != NULL)fclose(fdin);
                    582:        fclose(fdout);
                    583:        sig = signal(SIGINT, SIG_IGN);
                    584:        remove(to);
                    585:        if ((fdout = fopen(to, "w")) == NULL) {
                    586:                perror(to);
                    587:                unlink(preptmp);
                    588:                signal(SIGINT, sig);
                    589:                goto badexit;
                    590:        }
                    591: # ifdef NOTROOT
                    592:        if(uid != -1)chmod(to,0666);
                    593: # else
                    594:        if(uid != -1)mchown(to, uid, gid);
                    595: # endif
                    596:        if(stat(to, &statbuf) < 0 || statbuf.st_nlink != 1) {
                    597:                fclose(fdout);
                    598:                signal(SIGINT, sig);
                    599:                goto badexit;
                    600:        }
                    601:        if ((fdin = fopen(preptmp, "r"))  == NULL) {
                    602:                perror("mail");
                    603:                signal(SIGINT, sig);
                    604:                goto badexit;
                    605:        }
                    606:        ret = getput(fdin,fdout);
                    607:        fclose(fdout);
                    608:        fclose(fdin);
                    609:        signal(SIGINT, sig);
                    610:        return(ret);
                    611: badexit:
                    612:        unlink(preptmp);
                    613:        errs++;
                    614:        return(0);
                    615: }
                    616: 
                    617: delexit(ex)
                    618: {
                    619:        unlink(lettmp);
                    620:        unlink(preptmp);
                    621:        exit(ex);
                    622: }
                    623: 
                    624: /* return 1 if ok, 0 otherwise */
                    625: getput(fdin, fdout)
                    626: register FILE *fdin, *fdout;
                    627: {
                    628:        extern int errno;
                    629:        register int c;
                    630: 
                    631:        while((c = getc(fdin)) != EOF) {
                    632:                errno = 0;
                    633:                putc(c,fdout);
                    634:                if(errno) {
                    635:                        perror("mail");
                    636:                        return(0);
                    637:                }
                    638:        }
                    639:        return(1);
                    640: }
                    641: 
                    642: accesss(s1)
                    643: register char *s1;
                    644: {
                    645:        struct stat statbuf;
                    646:                if(stat(s1,&statbuf)<0 || access(s1,2) == 0)
                    647:                return(1);
                    648:        return(0);
                    649: }
                    650: 
                    651: any(c, str)
                    652:        register char *str, c;
                    653: {
                    654:        register char *f;
                    655: 
                    656:        f = str;
                    657:        while (*f)
                    658:                if (c == *f++)
                    659:                        return(1);
                    660:        return(0);
                    661: }
                    662: char   locktmp[30];                            /* Usable lock temporary */
                    663: char   curlock[50];                            /* Last used name of lock */
                    664: int    locked;                                 /* To note that we locked it */
                    665: 
                    666: /*
                    667:  * Lock the specified mail file by setting the file mailfile.lock.
                    668:  * We must, of course, be careful to unlink the lock file by a call
                    669:  * to unlock before we stop.  The algorithm used here is to see if
                    670:  * the lock exists, and if it does, to check its modify time.  If it
                    671:  * is older than 30 seconds, we assume error and set our own file.
                    672:  * Otherwise, we wait for 5 seconds and try again.
                    673:  */
                    674: 
                    675: lock(file)
                    676: char *file;
                    677: {
                    678:        register int f;
                    679:        struct stat statbuf;
                    680:        long curtime;
                    681: /* 
                    682:    if using OLDMAIL, and NOTROOT, cann't lock since can't necessarily
                    683:    write on user's login directory
                    684: */
                    685: # ifdef OLDMAIL
                    686:        return;
                    687: # endif
                    688: 
                    689:        if (file == NULL) {
                    690:                printf("Locked = %d\n", locked);
                    691:                return(0);
                    692:        }
                    693:        if (locked)
                    694:                return(0);
                    695:        sprintf(curlock,"%s%s",file,".mail");
                    696:        sprintf(locktmp,"%s/tmXXXXXX",MAILDIR);
                    697:        mktemp(locktmp);
                    698:        unlink(locktmp);
                    699:        for (;;) {
                    700:                f = lock1(locktmp, curlock);
                    701:                if (f == 0) {
                    702:                        locked = 1;
                    703:                        return(0);
                    704:                }
                    705:                if (stat(curlock, &statbuf) < 0)
                    706:                        return(0);
                    707:                time(&curtime);
                    708:                if (curtime < statbuf.st_mtime + 30) {
                    709:                        sleep(5);
                    710:                        continue;
                    711:                }
                    712:                unlink(curlock);
                    713:        }
                    714: }
                    715: 
                    716: /*
                    717:  * Remove the mail lock, and note that we no longer
                    718:  * have it locked.
                    719:  */
                    720: 
                    721: unlock()
                    722: {
                    723: 
                    724:        if (locked)
                    725:                unlink(curlock);
                    726:        locked = 0;
                    727: }
                    728: 
                    729: /*
                    730:  * Attempt to set the lock by creating the temporary file,
                    731:  * then doing a link/unlink.  If it fails, return -1 else 0
                    732:  */
                    733: 
                    734: lock1(tempfile, name)
                    735:        char tempfile[], name[];
                    736: {
                    737:        int fno;
                    738: 
                    739:        fno = creat(tempfile, 0400);
                    740:        if (fno < 0)
                    741:                return(-1);
                    742:        close(fno);
                    743:        if (link(tempfile, name) < 0) {
                    744:                unlink(tempfile);
                    745:                return(-1);
                    746:        }
                    747:        unlink(tempfile);
                    748:        return(0);
                    749: }
                    750: 
                    751: /*
                    752:        stripfx(prefix string, pointer to string)
                    753: 
                    754:        takes a ptr to string and compares it to prefix string.
                    755:        may be called multiple times
                    756:        returns ":username"
                    757: */
                    758: stripfx(pfx, name)
                    759:        register char *pfx;
                    760:        register char **name;
                    761: {
                    762:        register char *cp = *name;
                    763: 
                    764:        while (*pfx && (*cp == *pfx || *cp == toupper(*pfx)))
                    765:                cp++, pfx++;
                    766:        if (*cp != ':' || *pfx != 0)
                    767:                return;
                    768:        *name = cp;
                    769: }
                    770: stripmach(pperson)
                    771: register char **pperson;
                    772: {
                    773: # ifdef RAND
                    774: /* for machines at RAND */
                    775: # ifdef GRAPHICS
                    776:        stripfx("g",pperson);
                    777:        stripfx("graphics",pperson);
                    778: # endif
                    779: # ifdef TP
                    780:        stripfx("t",pperson);
                    781:        stripfx("tp",pperson);
                    782: # endif
                    783: # ifdef VAX
                    784:        stripfx("v",pperson);
                    785:        stripfx("vax",pperson);
                    786: # endif
                    787: /* end of defns for Rand */
                    788: # endif
                    789: 
                    790: # ifdef NOSC
                    791: /* for machines at NOSC */
                    792: # ifdef ATTS
                    793:        stripfx("a",pperson);
                    794:        stripfx("atts",pperson);
                    795: # endif
                    796: # ifdef CCMM
                    797:        stripfx("c",pperson);
                    798:        stripfx("ccmm",pperson);
                    799: # endif
                    800: # ifdef MSSF
                    801:        stripfx("m",pperson);
                    802:        stripfx("mssf",pperson);
                    803: # endif
                    804: /* end of defns for NOSC */
                    805: # endif
                    806: 
                    807: # ifdef BERKELEY
                    808: 
                    809: /* for Berkeley */
                    810: # ifdef A
                    811:        stripfx("a",pperson);
                    812: # endif
                    813: # ifdef B
                    814:        stripfx("b",pperson);
                    815: # endif
                    816: # ifdef C
                    817:        stripfx("c",pperson);
                    818: # endif
                    819: # ifdef D
                    820:        stripfx("d",pperson);
                    821: # endif
                    822: # ifdef E
                    823:        stripfx("e",pperson);
                    824: # endif
                    825: # ifdef ING70
                    826:        stripfx("i",pperson);
                    827:        stripfx("ing70",pperson);
                    828:        stripfx("ingres",pperson);
                    829: # endif
                    830: # ifdef INGVAX
                    831:        stripfx("j",pperson);
                    832:        stripfx("ingvax",pperson);
                    833: # endif
                    834: # ifdef VIRUS
                    835:        stripfx("k",pperson);
                    836:        stripfx("virus",pperson);
                    837: # endif
                    838: # ifdef IMAGE
                    839:        stripfx("m",pperson);
                    840:        stripfx("image",pperson);
                    841: # endif
                    842: # ifdef ESVAX
                    843:        stripfx("o",pperson);
                    844:        stripfx("esvax",pperson);
                    845: # endif
                    846: # ifdef Q
                    847:        stripfx("q",pperson);
                    848: # endif
                    849: # ifdef SRC
                    850:        stripfx("s",pperson);
                    851:        stripfx("src",pperson);
                    852: # endif
                    853: # ifdef MATHSTAT
                    854:        stripfx("t",pperson);
                    855:        stripfx("mathstat",pperson);
                    856: # endif
                    857: # ifdef CSVAX
                    858:        stripfx("v",pperson);
                    859:        stripfx("vax",pperson);
                    860:        stripfx("csvax",pperson);
                    861: # endif
                    862: # ifdef CORY
                    863:        stripfx("y",pperson);
                    864:        stripfx("cory",pperson);
                    865: # endif
                    866: # ifdef EECS40
                    867:        stripfx("z",pperson);
                    868:        stripfx("eecs40",pperson);
                    869: # endif
                    870: /* end of berkeley defns */
                    871: # endif
                    872: }
                    873: /* 
                    874:    this removes the mail file sfn by either truncating it, as required
                    875:    on OLDMAIL systems, or unlinking it. If the unlink fails, we truncate it.
                    876: */
                    877: remove(sfn)
                    878: char *sfn;
                    879: {
                    880:        int i;
                    881: # ifdef OLDMAIL
                    882:        i = creat(sfn,0666);
                    883:        if(i >= 0)close(i);
                    884: # else
                    885:        if(unlink(sfn) < 0){
                    886:                i = creat(sfn,MAILMODE);
                    887:                if(i >= 0)close(i);
                    888:        }
                    889: # endif
                    890: }

unix.superglobalmegacorp.com

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