home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / elvis_1.4.tar.Z / elvis_1.4.tar / virec.c < prev    next >
C/C++ Source or Header  |  1990-12-06  |  5KB  |  246 lines

  1. /* virec.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    14407 SW Teal Blvd. #C
  6.  *    Beaverton, OR 97005
  7.  *    kirkenda@cs.pdx.edu
  8.  */
  9.  
  10. /* This file contains the file recovery program */
  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
  246.