Annotation of 43BSD/contrib/jove/recover.c, revision 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.