Annotation of 43BSD/contrib/jove/recover.c, revision 1.1.1.1

1.1       root        1: /*************************************************************************
                      2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
                      3:  * provided to you without charge for use only on a licensed Unix        *
                      4:  * system.  You may copy JOVE provided that this notice is included with *
                      5:  * the copy.  You may not sell copies of this program or versions        *
                      6:  * modified for use on microcomputer systems, unless the copies are      *
                      7:  * included with a Unix system distribution and the source is provided.  *
                      8:  *************************************************************************/
                      9: 
                     10: /* Recovers JOVE files after a system/editor crash.
                     11:    Usage: recover [-d directory] [-syscrash]
                     12:    The -syscrash option is specified in /etc/rc and what it does it
                     13:    move all the jove tmp files from TMP_DIR to REC_DIR.
                     14: 
                     15:    The -d option lets you specify the directory to search for tmp files when
                     16:    the default isn't the right one.
                     17: 
                     18:    Look in Makefile to change the default directories. */
                     19: 
                     20: #include <stdio.h>     /* Do stdio first so it doesn't override OUR
                     21:                           definitions. */
                     22: #undef EOF
                     23: #undef BUFSIZ
                     24: #undef putchar
                     25: 
                     26: #include "jove.h"
                     27: #include "temp.h"
                     28: #include "rec.h"
                     29: #include <signal.h>
                     30: #include <sys/file.h>
                     31: #include <sys/stat.h>
                     32: #include <sys/dir.h>
                     33: 
                     34: #ifndef L_SET
                     35: #      define L_SET    0
                     36: #      define L_INCR   1
                     37: #endif
                     38: 
                     39: char   blk_buf[BUFSIZ];
                     40: int    nleft;
                     41: FILE   *ptrs_fp;
                     42: int    data_fd;
                     43: struct rec_head        Header;
                     44: char   datafile[40],
                     45:        pntrfile[40];
                     46: long   Nchars,
                     47:        Nlines;
                     48: char   tty[] = "/dev/tty";
                     49: int    UserID,
                     50:        Verbose = 0;
                     51: 
                     52: struct file_pair {
                     53:        char    *file_data,
                     54:                *file_rec;
                     55: #define INSPECTED      01
                     56:        int     file_flags;
                     57:        struct file_pair        *file_next;
                     58: } *First = 0,
                     59:   *Last = 0;
                     60: 
                     61: struct rec_entry       *buflist[100] = {0};
                     62: 
                     63: #ifndef BSD4_2
                     64: 
                     65: typedef struct {
                     66:        int     d_fd;           /* File descriptor for this directory */
                     67: } DIR;
                     68: 
                     69: DIR *
                     70: opendir(dir)
                     71: char   *dir;
                     72: {
                     73:        DIR     *dp = (DIR *) malloc(sizeof *dp);
                     74: 
                     75:        if ((dp->d_fd = open(dir, 0)) == -1)
                     76:                return NULL;
                     77:        return dp;
                     78: }
                     79: 
                     80: closedir(dp)
                     81: DIR    *dp;
                     82: {
                     83:        (void) close(dp->d_fd);
                     84:        free(dp);
                     85: }
                     86: 
                     87: struct direct *
                     88: readdir(dp)
                     89: DIR    *dp;
                     90: {
                     91:        static struct direct    dir;
                     92: 
                     93:        do
                     94:                if (read(dp->d_fd, &dir, sizeof dir) != sizeof dir)
                     95:                        return NULL;
                     96:        while (dir.d_ino == 0);
                     97: 
                     98:        return &dir;
                     99: }
                    100: 
                    101: #endif BSD4_2
                    102: 
                    103: /* Get a line at `tl' in the tmp file into `buf' which should be LBSIZE
                    104:    long. */
                    105: 
                    106: char *
                    107: getline(tl, buf)
                    108: disk_line      tl;
                    109: char   *buf;
                    110: {
                    111:        register char   *bp,
                    112:                        *lp;
                    113:        register int    nl;
                    114: 
                    115:        lp = buf;
                    116:        bp = getblock(tl);
                    117:        nl = nleft;
                    118:        tl &= ~OFFMSK;
                    119: 
                    120:        while (*lp++ = *bp++) {
                    121:                if (--nl == 0) {
                    122:                        /* += INCRMT moves tl to the next block in
                    123:                           the tmp file. */
                    124:                        bp = getblock(tl += INCRMT);
                    125:                        nl = nleft;
                    126:                }
                    127:        }
                    128: }
                    129: 
                    130: char *
                    131: getblock(atl)
                    132: disk_line      atl;
                    133: {
                    134:        int     bno,
                    135:                off;
                    136:        static int      curblock = -1;
                    137: 
                    138:        bno = (atl >> OFFBTS) & BLKMSK;
                    139:        off = (atl << SHFT) & LBTMSK;
                    140:        nleft = BUFSIZ - off;
                    141: 
                    142:        if (bno != curblock) {
                    143:                lseek(data_fd, (long) bno * BUFSIZ, L_SET);
                    144:                read(data_fd, blk_buf, BUFSIZ);
                    145:                curblock = bno;
                    146:        }
                    147:        return blk_buf + off;
                    148: }
                    149: 
                    150: char *
                    151: copystr(s)
                    152: char   *s;
                    153: {
                    154:        char    *str;
                    155: 
                    156:        str = malloc(strlen(s) + 1);
                    157:        strcpy(str, s);
                    158: 
                    159:        return str;
                    160: }
                    161: 
                    162: /* Scandir returns the number of entries or -1 if the directory cannoot
                    163:    be opened or malloc fails. */
                    164: 
                    165: scandir(dir, nmptr, qualify, sorter)
                    166: char   *dir;
                    167: struct direct  ***nmptr;
                    168: int    (*qualify)();
                    169: struct direct  *(*sorter)();
                    170: {
                    171:        DIR     *dirp;
                    172:        struct direct   *entry,
                    173:                        **ourarray;
                    174:        int     nalloc = 10,
                    175:                nentries = 0;
                    176: 
                    177:        if ((dirp = opendir(dir)) == NULL)
                    178:                return -1;
                    179:        ourarray = (struct direct **) malloc(nalloc * sizeof (struct direct *));
                    180:        while ((entry = readdir(dirp)) != NULL) {
                    181:                if (qualify != 0 && (*qualify)(entry) == 0)
                    182:                        continue;
                    183:                if (nentries == nalloc) {
                    184:                        ourarray = (struct direct **) realloc(ourarray, (nalloc += 10) * sizeof (struct direct));
                    185:                        if (ourarray == NULL)
                    186:                                return -1;
                    187:                }
                    188:                ourarray[nentries] = (struct direct *) malloc(sizeof *entry);
                    189:                *ourarray[nentries] = *entry;
                    190:                nentries++;
                    191:        }
                    192:        closedir(dirp);
                    193:        if (nentries != nalloc)
                    194:                ourarray = (struct direct **) realloc(ourarray,
                    195:                                        (nentries * sizeof (struct direct)));
                    196:        if (sorter != 0)
                    197:                qsort(ourarray, nentries, sizeof (struct direct **), sorter);
                    198:        *nmptr = ourarray;
                    199: 
                    200:        return nentries;
                    201: }
                    202: 
                    203: alphacomp(a, b)
                    204: struct direct  **a,
                    205:                **b;
                    206: {
                    207:        return strcmp((*a)->d_name, (*b)->d_name);
                    208: }
                    209: 
                    210: char   *CurDir;
                    211: 
                    212: /* Scan the DIRNAME directory for jove tmp files, and make a linked list
                    213:    out of them. */
                    214: 
                    215: get_files(dirname)
                    216: char   *dirname;
                    217: {
                    218:        int     add_name();
                    219:        struct direct   **nmptr;
                    220: 
                    221:        CurDir = dirname;
                    222:        scandir(dirname, &nmptr, add_name, (int (*)())0);
                    223: }
                    224: 
                    225: add_name(dp)
                    226: struct direct  *dp;
                    227: {
                    228:        char    dfile[128],
                    229:                rfile[128];
                    230:        struct file_pair        *fp;
                    231:        struct rec_head         header;
                    232:        int     fd;
                    233: 
                    234:        if (strncmp(dp->d_name, REC_BASE, strlen(REC_BASE)) != 0)
                    235:                return 0;
                    236:        /* If we get here, we found a "recover" tmp file, so now
                    237:           we look for the corresponding "data" tmp file.  First,
                    238:           though, we check to see whether there is anything in
                    239:           the "recover" file.  If it's 0 length, there's no point
                    240:           in saving its name. */
                    241:        (void) sprintf(rfile, "%s/%s", CurDir, dp->d_name);
                    242:        (void) sprintf(dfile, "%s/jove%s", CurDir, dp->d_name + strlen(REC_BASE));
                    243:        if ((fd = open(rfile, 0)) != -1) {
                    244:                if ((read(fd, (char *) &header, sizeof header) != sizeof header)) {
                    245:                        close(fd);
                    246:                        return 0;
                    247:                } else
                    248:                        close(fd);
                    249:        }
                    250:        if (access(dfile, 0) != 0) {
                    251:                fprintf(stderr, "recover: can't find the data file for %s/%s\n", TMP_DIR, dp->d_name);
                    252:                fprintf(stderr, "so deleting...\n");
                    253:                (void) unlink(rfile);
                    254:                (void) unlink(dfile);
                    255:                return 0;
                    256:        }
                    257:        /* If we get here, we've found both files, so we put them
                    258:           in the list. */
                    259:        fp = (struct file_pair *) malloc (sizeof *fp);
                    260:        if ((char *) fp == 0) {
                    261:                fprintf(stderr, "recover: cannot malloc for file_pair.\n");
                    262:                exit(-1);
                    263:        }
                    264:        fp->file_data = copystr(dfile);
                    265:        fp->file_rec = copystr(rfile);
                    266:        fp->file_flags = 0;
                    267:        fp->file_next = First;
                    268:        First = fp;
                    269: 
                    270:        return 1;
                    271: }
                    272: 
                    273: options()
                    274: {
                    275:        printf("Options are:\n");
                    276:        printf("        ?               list options.\n");
                    277:        printf("        get             get a buffer to a file.\n");
                    278:        printf("        list            list known buffers.\n");
                    279:        printf("        print           print a buffer to terminal.\n");
                    280:        printf("        quit            quit and delete jove tmp files.\n");
                    281:        printf("        restore         restore all buffers.\n");
                    282: }
                    283: 
                    284: /* Returns a legitimate buffer # */
                    285: 
                    286: struct rec_entry **
                    287: getsrc()
                    288: {
                    289:        char    name[128];
                    290:        int     number;
                    291: 
                    292:        for (;;) {
                    293:                tellme("Which buffer ('?' for list)? ", name);
                    294:                if (name[0] == '?')
                    295:                        list();
                    296:                else if (name[0] == '\0')
                    297:                        return 0;
                    298:                else if ((number = atoi(name)) > 0 && number <= Header.Nbuffers)
                    299:                        return &buflist[number];
                    300:                else {
                    301:                        int     i;
                    302: 
                    303:                        for (i = 1; i <= Header.Nbuffers; i++)
                    304:                                if (strcmp(buflist[i]->r_bname, name) == 0)
                    305:                                        return &buflist[i];
                    306:                        printf("%s: unknown buffer.\n", name);
                    307:                }
                    308:        }
                    309: }
                    310: 
                    311: /* Get a destination file name. */
                    312: 
                    313: static char *
                    314: getdest()
                    315: {
                    316:        static char     filebuf[256];
                    317: 
                    318:        tellme("Output file: ", filebuf);
                    319:        if (filebuf[0] == '\0')
                    320:                return 0;
                    321:        return filebuf;
                    322: }
                    323: 
                    324: #include "ctype.h"
                    325: 
                    326: char *
                    327: readword(buf)
                    328: char   *buf;
                    329: {
                    330:        int     c;
                    331:        char    *bp = buf;
                    332: 
                    333:        while (index(" \t\n", c = getchar()))
                    334:                ;
                    335: 
                    336:        do {
                    337:                if (index(" \t\n", c))
                    338:                        break;
                    339:                *bp++ = c;
                    340:        } while ((c = getchar()) != EOF);
                    341:        *bp = 0;
                    342: 
                    343:        return buf;
                    344: }
                    345: 
                    346: tellme(quest, answer)
                    347: char   *quest,
                    348:        *answer;
                    349: {
                    350:        if (stdin->_cnt <= 0) {
                    351:                printf("%s", quest);
                    352:                fflush(stdout);
                    353:        }
                    354:        readword(answer);
                    355: }
                    356: 
                    357: /* Print the specified file to strandard output. */
                    358: 
                    359: jmp_buf        int_env;
                    360: 
                    361: catch()
                    362: {
                    363:        longjmp(int_env, 1);
                    364: }
                    365: 
                    366: restore()
                    367: {
                    368:        register int    i;
                    369:        char    tofile[100],
                    370:                answer[30];
                    371:        int     nrecovered = 0;
                    372: 
                    373:        for (i = 1; i <= Header.Nbuffers; i++) {
                    374:                (void) sprintf(tofile, "#%s", buflist[i]->r_bname);
                    375: tryagain:
                    376:                printf("Restoring %s to %s, okay?", buflist[i]->r_bname,
                    377:                                                     tofile);
                    378:                tellme(" ", answer);
                    379:                switch (answer[0]) {
                    380:                case 'y':
                    381:                        break;
                    382: 
                    383:                case 'n':
                    384:                        continue;
                    385: 
                    386:                default:
                    387:                        tellme("What file should I use instead? ", tofile);
                    388:                        goto tryagain;
                    389:                }
                    390:                get(&buflist[i], tofile);
                    391:                nrecovered++;
                    392:        }
                    393:        printf("Recovered %d buffers.\n", nrecovered);
                    394: }
                    395: 
                    396: get(src, dest)
                    397: struct rec_entry       **src;
                    398: char   *dest;
                    399: {
                    400:        FILE    *outfile;
                    401: 
                    402:        if (src == 0 || dest == 0)
                    403:                return;
                    404:        (void) signal(SIGINT, catch);
                    405:        if (setjmp(int_env) == 0) {
                    406:                if ((outfile = fopen(dest, "w")) == NULL) {
                    407:                        printf("recover: cannot create %s.\n", dest);
                    408:                        return;
                    409:                }
                    410:                seekto(src - buflist);
                    411:                if (dest != tty)
                    412:                        printf("\"%s\"", dest);
                    413:                dump_file(outfile);
                    414:        } else
                    415:                printf("\nAborted!\n");
                    416:        fclose(outfile);
                    417:        if (dest != tty)
                    418:                printf(" %ld lines, %ld characters.\n", Nlines, Nchars);
                    419:        (void) signal(SIGINT, SIG_DFL);
                    420: }
                    421: 
                    422: char **
                    423: scanvec(args, str)
                    424: register char  **args,
                    425:                *str;
                    426: {
                    427:        while (*args) {
                    428:                if (strcmp(*args, str) == 0)
                    429:                        return args;
                    430:                args++;
                    431:        }
                    432:        return 0;
                    433: }
                    434: 
                    435: read_rec(recptr)
                    436: struct rec_entry       *recptr;
                    437: {
                    438:        if (fread((char *) recptr, sizeof *recptr, 1, ptrs_fp) != 1)
                    439:                fprintf(stderr, "recover: cannot read record.\n");
                    440: }
                    441: 
                    442: seekto(which)
                    443: {
                    444:        struct rec_entry        rec;
                    445: 
                    446:        fseek(ptrs_fp, (long) (sizeof Header), L_SET);
                    447:        
                    448:        while (which-- > 1) {
                    449:                read_rec(&rec);
                    450:                if (fseek(ptrs_fp, (long) rec.r_nlines * sizeof (disk_line),
                    451:                        L_INCR) == -1)
                    452:                        printf("recover: improper fseek!\n");
                    453:        }
                    454: }
                    455: 
                    456: makblist()
                    457: {
                    458:        int     i;
                    459: 
                    460:        for (i = 1; i <= Header.Nbuffers; i++) {
                    461:                seekto(i);
                    462:                if (buflist[i] == 0)
                    463:                        buflist[i] = (struct rec_entry *) malloc (sizeof (struct rec_entry));
                    464:                read_rec(buflist[i]);
                    465:        }
                    466:        if (buflist[i]) {
                    467:                free((char *) buflist[i]);
                    468:                buflist[i] = 0;
                    469:        }
                    470: }
                    471: 
                    472: disk_line
                    473: getaddr(fp)
                    474: register FILE  *fp;
                    475: {
                    476:        register int    nchars = sizeof (disk_line);
                    477:        disk_line       addr;
                    478:        register char   *cp = (char *) &addr;
                    479: 
                    480:        while (--nchars >= 0)
                    481:                *cp++ = getc(fp);
                    482: 
                    483:        return addr;
                    484: }
                    485: 
                    486: dump_file(out)
                    487: FILE   *out;
                    488: {
                    489:        struct rec_entry        record;
                    490:        register int    nlines;
                    491:        register disk_line      daddr;
                    492:        char    buf[BUFSIZ];
                    493: 
                    494:        read_rec(&record);
                    495:        nlines = record.r_nlines;
                    496:        Nchars = Nlines = 0L;
                    497:        while (--nlines >= 0) {
                    498:                daddr = getaddr(ptrs_fp);
                    499:                getline(daddr, buf);
                    500:                Nlines++;
                    501:                Nchars += 1 + strlen(buf);
                    502:                fputs(buf, out);
                    503:                if (nlines > 0)
                    504:                        fputc('\n', out);
                    505:        }
                    506:        if (out != stdout)
                    507:                fclose(out);
                    508: }
                    509: 
                    510: /* List all the buffers. */
                    511: 
                    512: list()
                    513: {
                    514:        int     i;
                    515: 
                    516:        for (i = 1; i <= Header.Nbuffers; i++)
                    517:                printf("%d) buffer %s  \"%s\" (%d lines)\n", i,
                    518:                        buflist[i]->r_bname,
                    519:                        buflist[i]->r_fname,
                    520:                        buflist[i]->r_nlines);
                    521: }
                    522: 
                    523: doit(fp)
                    524: struct file_pair       *fp;
                    525: {
                    526:        char    answer[30];
                    527:        char    *datafile = fp->file_data,
                    528:                *pntrfile = fp->file_rec;
                    529: 
                    530:        ptrs_fp = fopen(pntrfile, "r");
                    531:        if (ptrs_fp == NULL) {
                    532:                if (Verbose)
                    533:                        fprintf(stderr, "recover: cannot read rec file (%s).\n", pntrfile);
                    534:                return 0;
                    535:        }
                    536:        fread((char *) &Header, sizeof Header, 1, ptrs_fp);
                    537:        if (Header.Uid != UserID)
                    538:                return 0;
                    539: 
                    540:        /* Don't ask about JOVE's that are still running ... */
                    541: #ifdef KILL0
                    542:        if (kill(Header.Pid, 0) == 0)
                    543:                return 0;
                    544: #else
                    545: #ifdef LSRHS
                    546:        if (pexist(Header.Pid))
                    547:                return 0;
                    548: #endif LSRHS
                    549: #endif KILL0
                    550: 
                    551:        if (Header.Nbuffers == 0) {
                    552:                printf("There are no modified buffers in %s; should I delete the tmp file?", pntrfile);
                    553:                ask_del(" ", fp);
                    554:                return 1;
                    555:        }
                    556:                
                    557:        if (Header.Nbuffers < 0) {
                    558:                fprintf(stderr, "recover: %s doesn't look like a jove file.\n", pntrfile);
                    559:                ask_del("Should I delete it? ", fp);
                    560:                return 1;       /* We'll, we sort of found something. */
                    561:        }
                    562:        printf("Found %d buffer%s last updated: %s",
                    563:                Header.Nbuffers,
                    564:                Header.Nbuffers != 1 ? "s" : "",
                    565:                ctime(&Header.UpdTime));
                    566:        data_fd = open(datafile, 0);
                    567:        if (data_fd == -1) {
                    568:                fprintf(stderr, "recover: but I can't read the data file (%s).\n", datafile);
                    569:                ask_del("Should I delete the tmp files? ", fp);
                    570:                return 1;
                    571:        }
                    572:        makblist();
                    573: 
                    574:        for (;;) {
                    575:                tellme("(Type '?' for options): ", answer);
                    576:                switch (answer[0]) {
                    577:                case '\0':
                    578:                        continue;
                    579: 
                    580:                case '?':
                    581:                        options();
                    582:                        break;
                    583: 
                    584:                case 'l':
                    585:                        list();
                    586:                        break;
                    587: 
                    588:                case 'p':
                    589:                        get(getsrc(), tty);
                    590:                        break;
                    591: 
                    592:                case 'q':
                    593:                        ask_del("Shall I delete the tmp files? ", fp);
                    594:                        return 1;
                    595: 
                    596:                case 'g':
                    597:                    {   /* So it asks for src first. */
                    598:                        char    *dest;
                    599:                        struct rec_entry        **src;
                    600: 
                    601:                        if ((src = getsrc()) == 0)
                    602:                                break;
                    603:                        dest = getdest();
                    604:                        get(src, dest);
                    605:                        break;
                    606:                    }
                    607: 
                    608:                case 'r':
                    609:                        restore();
                    610:                        break;
                    611: 
                    612:                default:
                    613:                        printf("I don't know how to \"%s\"!\n", answer);
                    614:                        break;
                    615:                }
                    616:        }
                    617: }
                    618: 
                    619: ask_del(prompt, fp)
                    620: char   *prompt;
                    621: struct file_pair       *fp;
                    622: {
                    623:        char    yorn[20];
                    624: 
                    625:        tellme(prompt, yorn);
                    626:        if (yorn[0] == 'y')
                    627:                del_files(fp);
                    628: }
                    629: 
                    630: del_files(fp)
                    631: struct file_pair       *fp;
                    632: {
                    633:        (void) unlink(fp->file_data);
                    634:        (void) unlink(fp->file_rec);
                    635: }
                    636: 
                    637: savetmps()
                    638: {
                    639:        struct file_pair        *fp;
                    640:        int     status,
                    641:                pid;
                    642: 
                    643:        if (strcmp(TMP_DIR, REC_DIR) == 0)
                    644:                return;         /* Files are moved to the same place. */
                    645:        get_files(TMP_DIR);
                    646:        for (fp = First; fp != 0; fp = fp->file_next) {
                    647:                switch (pid = fork()) {
                    648:                case -1:
                    649:                        fprintf(stderr, "recover: can't fork\n!");
                    650:                        exit(-1);
                    651: 
                    652:                case 0:
                    653:                        execl("/bin/cp", "cp", fp->file_data, fp->file_rec, REC_DIR, 0);
                    654:                        fprintf(stderr, "recover: cannot execl /bin/cp.\n");
                    655:                        exit(-1);
                    656: 
                    657:                default:
                    658:                        while (wait(&status) != pid)
                    659:                                ;
                    660:                        if (status != 0)
                    661:                                fprintf(stderr, "recover: non-zero status (%d) returned from copy.\n", status);
                    662:                }
                    663:        }
                    664: }
                    665: 
                    666: lookup(dir)
                    667: char   *dir;
                    668: {
                    669:        struct file_pair        *fp;
                    670:        struct rec_head         header;
                    671:        char    yorn[20];
                    672:        int     nfound = 0,
                    673:                this_one;
                    674: 
                    675:        get_files(dir);
                    676:        for (fp = First; fp != 0; fp = fp->file_next) {
                    677:                nfound += doit(fp);
                    678:                if (ptrs_fp)
                    679:                        (void) fclose(ptrs_fp);
                    680:                if (data_fd > 0)
                    681:                        (void) close(data_fd);
                    682:        }
                    683:        return nfound;
                    684: }
                    685: 
                    686: main(argc, argv)
                    687: int    argc;
                    688: char   *argv[];
                    689: {
                    690:        int     nfound;
                    691:        char    **argvp;
                    692: 
                    693:        UserID = getuid();
                    694: 
                    695:        if (scanvec(argv, "-help")) {
                    696:                printf("recover: usage: recover [-d directory] [-syscrash]\n");
                    697:                printf("Use \"recover\" after JOVE has died for some\n");
                    698:                printf("unknown reason.\n\n");
                    699:                printf("Use \"recover -syscrash\" when the system is in the process\n");
                    700:                printf("of rebooting.  This is done automatically at reboot time\n");
                    701:                printf("and so most of you don't have to worry about that.\n\n");
                    702:                printf("Use \"recover -d directory\" when the tmp files are store\n");
                    703:                printf("in DIRECTORY instead of the default one (%s).\n", TMP_DIR);
                    704:                exit(0);
                    705:        }
                    706:        if (scanvec(argv, "-v"))
                    707:                Verbose++;
                    708:        if (scanvec(argv, "-syscrash")) {
                    709:                printf("Recovering jove files ... ");
                    710:                savetmps();
                    711:                printf("Done.\n");
                    712:                exit(0);
                    713:        }
                    714:        if (argvp = scanvec(argv, "-uid"))
                    715:                UserID = atoi(argvp[1]);
                    716:        if (argvp = scanvec(argv, "-d"))
                    717:                nfound = lookup(argvp[1]);
                    718:        else {
                    719:                if ((nfound = lookup(REC_DIR)) ||
                    720:                    (nfound = lookup(TMP_DIR)))
                    721:                        ;
                    722:        }
                    723:        if (nfound == 0)
                    724:                printf("There's nothing to recover.\n");
                    725: }

unix.superglobalmegacorp.com

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