home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / d / elvis / Source / c / virecover < prev   
Encoding:
Text File  |  1990-03-08  |  3.2 KB  |  180 lines

  1. /* This file contains the file recovery program */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    16820 SW Tallac Way
  6.  *    Beaverton, OR 97006
  7.  *    kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda
  8.  */
  9.  
  10.  
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <stdio.h>
  14. #include "vi.h"
  15.  
  16. struct stat    stbuf;
  17. BLK        hdr;
  18. BLK        text;
  19.  
  20. main(argc, argv)
  21.     int    argc;
  22.     char    **argv;
  23. {
  24.     if (argc < 2)
  25.     {
  26.         /* maybe stdin comes from a file? */
  27.         if (fstat(0, &stbuf) < 0 || (S_IFMT & stbuf.st_mode) != S_IFREG)
  28.         {
  29.             fprintf(stderr, "usage: %s lostfile...\n", argv[0]);
  30.         }
  31.         else if (read(0, &hdr, BLKSIZE) != BLKSIZE)
  32.         {
  33.             fprintf(stderr, "couldn't get header\n");
  34.         }
  35.         else
  36.         {
  37.             copytext(0, stdout);
  38.         }
  39.     }
  40.     else
  41.     {
  42.         while (--argc > 0)
  43.         {
  44.             recover(*++argv);
  45.         }
  46.     }
  47. }
  48.  
  49.  
  50. /* This function recovers a single file */
  51. recover(filename)
  52.     char    *filename;
  53. {
  54.     char        tmpname[100];
  55.     int        tmpfd;
  56.     FILE        *fp;
  57.     long        mtime;
  58.     int        i, j;
  59.  
  60.     /* get the file's status info */
  61.     if (stat(filename, &stbuf) < 0)
  62.     {
  63.         /* if serious error, give up on this file */
  64.         if (errno != ESRCH)
  65.         {
  66.             perror(filename);
  67.             return;
  68.         }
  69.  
  70.         /* else fake it for a new file */
  71.         stat(".", &stbuf);
  72.         stbuf.st_mode = S_IFREG;
  73.         stbuf.st_mtime = 0L;
  74.     }
  75.  
  76.     /* find the tmp file */
  77.     sprintf(tmpname, TMPNAME, 1, 1);
  78.     tmpfd = open(tmpname, O_RDONLY);
  79.     if (tmpfd < 0)
  80.     {
  81.         sprintf(tmpname, "tmp file for %s", filename);
  82.         perror(tmpname);
  83.         return;
  84.     }
  85.  
  86.     /* make sure the file hasn't been modified more recently */
  87.     mtime = stbuf.st_mtime;
  88.     fstat(tmpfd, &stbuf);
  89.     if (stbuf.st_mtime < mtime)
  90.     {
  91.         printf("\
  92. \"%s\" has been modified more recently than its recoverable version\n\
  93. Do you still want to recover it?\n\
  94. \ty - Yes, discard the current version and recover it.\n\
  95. \tn - No, discard the recoverable version and keep the current version\n\
  96. \tq - Quit without doing anything for this file.\n\
  97. Enter y, n, or q --> ", filename);
  98.         fflush(stdout);
  99.         for (;;)
  100.         {
  101.             switch (getchar())
  102.             {
  103.               case 'y':
  104.               case 'Y':
  105.                 goto BreakBreak;
  106.  
  107.               case 'n':
  108.               case 'N':
  109.                 close(tmpfd);
  110.                 unlink(tmpname);
  111.                 return;
  112.  
  113.               case 'q':
  114.               case 'Q':
  115.                 close(tmpfd);
  116.                 return;
  117.             }
  118.         }
  119. BreakBreak:;
  120.     }
  121.  
  122.     /* make sure this tmp file is intact */
  123.     if (read(tmpfd, &hdr, BLKSIZE) != BLKSIZE)
  124.     {
  125.         fprintf(stderr, "%s: bad header in tmp file\n", filename);
  126.         close(tmpfd);
  127.         unlink(tmpname);
  128.         return;
  129.     }
  130.     for (i = j = 1; i < MAXBLKS && hdr.n[i]; i++)
  131.     {
  132.         if (hdr.n[i] > j)
  133.         {
  134.             j = hdr.n[i];
  135.         }
  136.     }
  137.     lseek(tmpfd, (long)j * (long)BLKSIZE, 0);
  138.     if (read(tmpfd, &text, BLKSIZE) != BLKSIZE)
  139.     {
  140.         fprintf(stderr, "%s: bad data block in tmp file\n", filename);
  141.         close(tmpfd);
  142.         unlink(tmpname);
  143.         return;
  144.     }
  145.  
  146.     /* open the normal text file for writing */
  147.     fp = fopen(filename, "w");
  148.     if (!fp)
  149.     {
  150.         perror(filename);
  151.         close(tmpfd);
  152.         return;
  153.     }
  154.  
  155.     /* copy the text */
  156.     copytext(tmpfd, fp);
  157.  
  158.     /* cleanup */
  159.     close(tmpfd);
  160.     fclose(fp);
  161.     unlink(tmpname);
  162. }
  163.  
  164.  
  165. /* This function moves text from the tmp file to the normal file */
  166. copytext(tmpfd, fp)
  167.     int    tmpfd;    /* fd of the tmp file */
  168.     FILE    *fp;    /* the stream to write it to */
  169. {
  170.     int    i;
  171.  
  172.     /* write the data blocks to the normal text file */
  173.     for (i = 1; i < MAXBLKS && hdr.n[i]; i++)
  174.     {
  175.         lseek(tmpfd, (long)hdr.n[i] * (long)BLKSIZE, 0);
  176.         read(tmpfd, &text, BLKSIZE);
  177.         fputs(text.c, fp);
  178.     }
  179. }
  180.