Annotation of coherent/d/usr/bin/elvis/virec.c, revision 1.1

1.1     ! root        1: /* virec.c */
        !             2: 
        !             3: /* This file contains the file recovery program */
        !             4: 
        !             5: /* Author:
        !             6:  *     Steve Kirkendall
        !             7:  *     16820 SW Tallac Way
        !             8:  *     Beaverton, OR 97006
        !             9:  *     [email protected], or ...uunet!tektronix!psueea!jove!kirkenda
        !            10:  */
        !            11: 
        !            12: 
        !            13: #include "config.h"
        !            14: #include <stdio.h>
        !            15: #include <ctype.h>
        !            16: #include "vi.h"
        !            17: #if TOS
        !            18: # include <stat.h>
        !            19: #else
        !            20: # if OSK
        !            21: #  include "osk.h"
        !            22: # else
        !            23: #  include <sys/stat.h>
        !            24: # endif
        !            25: #endif
        !            26: 
        !            27: extern char    *getenv();
        !            28: struct stat    stbuf;
        !            29: BLK            hdr;
        !            30: BLK            text;
        !            31: 
        !            32: /* the name of the directory where tmp files are stored. */
        !            33: char o_directory[30] = TMPDIR;
        !            34: 
        !            35: char   *progname;
        !            36: 
        !            37: main(argc, argv)
        !            38:        int     argc;
        !            39:        char    **argv;
        !            40: {
        !            41:        char    *tmp;
        !            42:        void recover();
        !            43: #if MSDOS || TOS
        !            44:        char **wildexpand();
        !            45:        argv = wildexpand(&argc, argv);
        !            46: #endif
        !            47:        progname = argv[0];
        !            48:        /* set the o_directory variable */
        !            49:        if ((tmp = getenv("TMP"))       /* yes, ASSIGNMENT! */
        !            50:         || (tmp = getenv("TEMP")))     /* yes, ASSIGNMENT! */
        !            51:        {
        !            52:                strcpy(o_directory, tmp);
        !            53:        }
        !            54:        if (argc >= 3 && !strcmp(argv[1], "-d"))
        !            55:        {
        !            56:                strcpy(o_directory, argv[2]);
        !            57:                argc -= 2;
        !            58:                argv += 2;
        !            59:        }
        !            60:        /* process the arguments */
        !            61:        if (argc < 2)
        !            62:        {
        !            63:                /* maybe stdin comes from a file? */
        !            64:                if (isatty(0))
        !            65:                {
        !            66:                        fprintf(stderr, "usage: %s [-d tmpdir] lostfile...\n", progname);
        !            67:                }
        !            68:                else if (read(0, &hdr, (unsigned)BLKSIZE) != BLKSIZE)
        !            69:                {
        !            70:                        fprintf(stderr, "couldn't get header\n");
        !            71:                }
        !            72:                else
        !            73:                {
        !            74:                        copytext(0, stdout);
        !            75:                }
        !            76:        }
        !            77:        else
        !            78:        {
        !            79:                while (--argc > 0)
        !            80:                {
        !            81:                        recover(*++argv);
        !            82:                }
        !            83:        }
        !            84:        exit(0);
        !            85: }
        !            86: 
        !            87: 
        !            88: /* This function recovers a single file */
        !            89: void recover(filename)
        !            90:        char    *filename;
        !            91: {
        !            92:        char            tmpname[100];
        !            93:        int             tmpfd;
        !            94:        FILE            *fp;
        !            95:        long            mtime;
        !            96:        int             i, j;
        !            97:        int             sum;    /* used for calculating a checksum for this */
        !            98:        char            *scan;
        !            99: 
        !           100:        /* get the file's status info */
        !           101:        if (stat(filename, &stbuf) < 0)
        !           102:        {
        !           103:                /* if serious error, give up on this file */
        !           104:                if (errno != ENOENT)
        !           105:                {
        !           106:                        perror(filename);
        !           107:                        return;
        !           108:                }
        !           109: 
        !           110:                /* else fake it for a new file */
        !           111:                stat(".", &stbuf);
        !           112: #if OSK
        !           113:                stbuf.st_mode = S_IREAD;
        !           114: #else
        !           115:                stbuf.st_mode = S_IFREG;
        !           116: #endif
        !           117:                stbuf.st_mtime = 0L;
        !           118:        }
        !           119: 
        !           120:        /* generate a checksum from the file's name */
        !           121:        for (sum = 0, scan = filename + strlen(filename);
        !           122:             --scan >= filename && (isascii(*scan) && isalnum(*scan) || *scan == '.');
        !           123:             sum = sum + *scan)
        !           124:        {
        !           125:        }
        !           126:        sum &= 0xf;
        !           127: 
        !           128:        /* find the tmp file */
        !           129: #if MSDOS || TOS
        !           130:        /* MS-Dos doesn't allow multiple slashes, but supports drives
        !           131:         * with current directories.
        !           132:         * This relies on TMPNAME beginning with "%s\\"!!!!
        !           133:         */
        !           134:        strcpy(tmpname, o_directory);
        !           135:        if ((i = strlen(tmpname)) && !strchr(":/\\", tmpname[i-1]))
        !           136:                tmpname[i++]=SLASH;
        !           137:        sprintf(tmpname+i, TMPNAME+3, sum, stbuf.st_ino, stbuf.st_dev);
        !           138: #else
        !           139:        sprintf(tmpname, TMPNAME, o_directory, sum, stbuf.st_ino, stbuf.st_dev);
        !           140: #endif
        !           141:        tmpfd = open(tmpname, O_RDONLY | O_BINARY);
        !           142:        if (tmpfd < 0)
        !           143:        {
        !           144:                perror(tmpname);
        !           145:                return;
        !           146:        }
        !           147: 
        !           148:        /* make sure the file hasn't been modified more recently */
        !           149:        mtime = stbuf.st_mtime;
        !           150:        fstat(tmpfd, &stbuf);
        !           151:        if (stbuf.st_mtime < mtime)
        !           152:        {
        !           153:                printf("\"%s\" has been modified more recently than its recoverable version\n", filename);
        !           154:                puts("Do you still want to recover it?\n");
        !           155:                puts("\ty - Yes, discard the current version and recover it.\n");
        !           156:                puts("\tn - No, discard the recoverable version and keep the current version\n");
        !           157:                puts("\tq - Quit without doing anything for this file.\n");
        !           158:                puts("Enter y, n, or q --> ");
        !           159:                fflush(stdout);
        !           160:                for (;;)
        !           161:                {
        !           162:                        switch (getchar())
        !           163:                        {
        !           164:                          case 'y':
        !           165:                          case 'Y':
        !           166:                                goto BreakBreak;
        !           167: 
        !           168:                          case 'n':
        !           169:                          case 'N':
        !           170:                                close(tmpfd);
        !           171:                                unlink(tmpname);
        !           172:                                return;
        !           173: 
        !           174:                          case 'q':
        !           175:                          case 'Q':
        !           176:                                close(tmpfd);
        !           177:                                return;
        !           178:                        }
        !           179:                }
        !           180: BreakBreak:;
        !           181:        }
        !           182: 
        !           183:        /* make sure this tmp file is intact */
        !           184:        if (read(tmpfd, &hdr, (unsigned)BLKSIZE) != BLKSIZE)
        !           185:        {
        !           186:                fprintf(stderr, "%s: bad header in tmp file\n", filename);
        !           187:                close(tmpfd);
        !           188:                unlink(tmpname);
        !           189:                return;
        !           190:        }
        !           191:        for (i = j = 1; i < MAXBLKS && hdr.n[i]; i++)
        !           192:        {
        !           193:                if (hdr.n[i] > j)
        !           194:                {
        !           195:                        j = hdr.n[i];
        !           196:                }
        !           197:        }
        !           198:        lseek(tmpfd, (long)j * (long)BLKSIZE, 0);
        !           199:        if (read(tmpfd, &text, (unsigned)BLKSIZE) != BLKSIZE)
        !           200:        {
        !           201:                fprintf(stderr, "%s: bad data block in tmp file\n", filename);
        !           202:                close(tmpfd);
        !           203:                unlink(tmpname);
        !           204:                return;
        !           205:        }
        !           206: 
        !           207:        /* open the normal text file for writing */
        !           208:        fp = fopen(filename, "w");
        !           209:        if (!fp)
        !           210:        {
        !           211:                perror(filename);
        !           212:                close(tmpfd);
        !           213:                return;
        !           214:        }
        !           215: 
        !           216:        /* copy the text */
        !           217:        copytext(tmpfd, fp);
        !           218: 
        !           219:        /* cleanup */
        !           220:        close(tmpfd);
        !           221:        fclose(fp);
        !           222:        unlink(tmpname);
        !           223: }
        !           224: 
        !           225: 
        !           226: /* This function moves text from the tmp file to the normal file */
        !           227: copytext(tmpfd, fp)
        !           228:        int     tmpfd;  /* fd of the tmp file */
        !           229:        FILE    *fp;    /* the stream to write it to */
        !           230: {
        !           231:        int     i;
        !           232: 
        !           233:        /* write the data blocks to the normal text file */
        !           234:        for (i = 1; i < MAXBLKS && hdr.n[i]; i++)
        !           235:        {
        !           236:                lseek(tmpfd, (long)hdr.n[i] * (long)BLKSIZE, 0);
        !           237:                read(tmpfd, &text, (unsigned)BLKSIZE);
        !           238:                fputs(text.c, fp);
        !           239:        }
        !           240: }
        !           241: 
        !           242: #if MSDOS || TOS
        !           243: #define                WILDCARD_NO_MAIN
        !           244: #include       "wildcard.c"
        !           245: #endif

unix.superglobalmegacorp.com

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