Annotation of coherent/d/usr/bin/elvis/virec.c, revision 1.1.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.