Annotation of 43BSDTahoe/new/jove/recover.c, revision 1.1

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

unix.superglobalmegacorp.com

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