home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1710 / virec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  3.9 KB  |  215 lines

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