home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / zoo141_c.lzh / FIZ.C < prev    next >
C/C++ Source or Header  |  1987-02-07  |  6KB  |  202 lines

  1. /* fiz.c */
  2. /*
  3. The contents of this file are hereby released to the public domain.
  4.  
  5.                                    -- Rahul Dhesi 1987/02/06
  6. */
  7.  
  8. /*
  9. Searches for all directory entries in an archive and prints their
  10. offsets.  Zoo 1.41 and later may then be asked to extract a specific
  11. file by supplying the offset of the file.
  12. */
  13.  
  14. #include "options.h"
  15. #include <stdio.h>
  16. #include "various.h"
  17. #include "zoofns.h"
  18. #include "portable.h"         /* I/O definitions */
  19. #include "zoo.h"
  20.  
  21. #ifdef LINT_ARGS
  22. void prtctrl (char *);
  23. void prtch (unsigned int);
  24. #else
  25. void prtctrl ();
  26. void prtch ();
  27. #endif
  28.  
  29. main(argc,argv)
  30. register int argc;
  31. register char **argv;
  32. {
  33.    char *zooname;          /* name of archive to be read */
  34.    FILE *zoo_file;         /* the archive opened as a FILE */
  35.    int column;             /* column currently printing */
  36.    int state;              /* to keep track of how much of tag seen */
  37.    int inch;               /* char just read from archive */
  38.  
  39.    static char usage1[] = "Fiz 1.0 (1987/01/30) public domain Zoo archive repair utility by Rahul Dhesi\n";
  40.    static char usage2[] = "Usage:  fiz archive[.zoo]  (\"fiz -h\" for help)\n";
  41.  
  42. #ifdef SETBUF
  43. /* set stdout to unbuffered */
  44. setbuf (stdout, NULL);
  45. #endif
  46.  
  47.    if (argc < 2) {
  48.       printf("%s%s", usage1, usage2);
  49.       exit (1);
  50.    }
  51.  
  52.    if (strcmp(argv[1],"-h") == 0)
  53.       goto givehelp;
  54.  
  55.    zooname = argv[1];
  56.  
  57.    /* Add default extension if none supplied */
  58.    {
  59.       char *p, *q;
  60.       p = zooname + strlen(zooname);         /* point to last char */
  61.       while (p != zooname && *p != EXT_CH)
  62.          --p;
  63.       /* either found EXT_CH or reached beginning of zooname */
  64.       if (*p != EXT_CH) {
  65.          q = malloc(strlen(zooname) + strlen(EXT_DFLT) + 2);
  66.          if (q == NULL) {
  67.             printf("Fiz:  Ran out of memory.\n");
  68.             exit(1);
  69.          }
  70.          strcpy(q, zooname);
  71.          strcat(q, EXT_DFLT);
  72.          zooname = q;
  73.       }
  74.    }
  75.  
  76.    zoo_file = fopen (zooname, FRDSTR);
  77.    if (zoo_file == NULL) {
  78.       printf("Fiz:  FATAL:  Could not open %s.\n", zooname);
  79.       exit(1);
  80.    }
  81.  
  82. #define  NOTHING  1
  83. #define  CHAR_1   0xdc
  84. #define  CHAR_2   0xa7
  85. #define  CHAR_3   0xc4
  86. #define  CHAR_4   0xfd
  87.  
  88.    column = 0;
  89.    state = NOTHING;
  90.    while ((inch = getc(zoo_file)) != EOF) {
  91.       inch = inch & 0xff;
  92.       if (state == NOTHING && inch == CHAR_1)
  93.          state = CHAR_1;
  94.       else if (state == CHAR_1 && inch == CHAR_2)
  95.          state = CHAR_2;
  96.       else if (state == CHAR_2 && inch == CHAR_3)
  97.          state = CHAR_3;
  98.       else if (state == CHAR_3 && inch == CHAR_4)
  99.          state = CHAR_4;
  100.       else
  101.          state = NOTHING;
  102.  
  103.       if (state == CHAR_4) {           /* found tag */
  104.          long save_pos;
  105.          struct direntry direntry;
  106.          save_pos = ftell(zoo_file);
  107.          fseek(zoo_file, save_pos-4L, 0);          /* back to tag pos */
  108.          frd_dir(&direntry, zoo_file);             /* read dir entry */
  109.          printf("****************\n");
  110.  
  111.          printf ("%8lu:  ", save_pos-4L);
  112.  
  113.          if (direntry.dirlen > 0) {
  114.             printf ("[");
  115.             prtctrl (direntry.dirname);
  116.             printf ("]");
  117.          }
  118.  
  119.          printf(" [");
  120.          prtctrl (direntry.fname);
  121.          printf ("]");
  122.  
  123.          if (direntry.namlen > 0) {
  124.             printf (" [");
  125.             prtctrl (direntry.lfname);
  126.             printf ("]");
  127.          }
  128.          if (direntry.dir_crc != 0)
  129.             printf (" [*bad CRC*]");
  130.          printf ("\n");
  131.          fseek (zoo_file, save_pos, 0);         /* try again from there */
  132.       }
  133.    }
  134. exit (0);      /* don't fall through */
  135.  
  136. givehelp:
  137.  
  138.    printf ("Fiz is used to help you recover data from a damaged archive.  Fiz\n");
  139.    printf ("searches the specified archive and prints the position (a decimal\n");
  140.    printf ("number) of each directory entry found and the directory name and\n");
  141.    printf ("filename associated with it.\n\n");
  142.  
  143.    printf ("Make a record of the output of Fiz by redirecting it to a file.  Then\n");
  144.    printf ("use Zoo version 1.41 or higher to list or extract files in the\n");
  145.    printf ("damaged archives starting at a chosen position.  For example, you can\n");
  146.    printf ("start extracting files from archive \"badarc.zoo\" at position 1098\n");
  147.    printf ("with the command\n\n");
  148.  
  149.    printf ("     zoo x@1098 badarc\n\n");
  150.  
  151.    printf ("Zoo will ignore the first 1097 bytes of the damaged archive and you\n"); 
  152.    printf ("should be able to recover the undamaged files from the rest of the\n");
  153.    printf ("archive.\n\n");
  154.    printf ("The position supplied to Zoo should have been obtained from Fiz and\n");
  155.    printf ("must correspond to an undamaged directory entry in the archive.\n");
  156.  
  157.    exit(1);
  158. }
  159.  
  160. /*
  161. prtctrl() prints a string with all unprintable characters converted
  162. to printable form.  To avoid the program running astray trying to
  163. print damaged data, no more than MAXPRT characters are printed.
  164. Characters with the 8th bit set are printed preceded with ~.  Control
  165. characters are printed preceded with ^.  Both ~ and ^ may preced
  166. the character if a control character has the 8th bit set.
  167. */
  168. #define  MAXPRT      50
  169.  
  170. void prtctrl (str)
  171. char *str;
  172. {
  173.    unsigned int ch;
  174.    int count;
  175.    count = 0;
  176.  
  177.    while (count < MAXPRT && *str != '\0') {
  178.       ch = (unsigned) *str;
  179.       prtch(ch);
  180.       str++;
  181.       count++;
  182.    }
  183. }
  184.  
  185. /*
  186. Does the actual character printing for prtctrl()
  187. */
  188. void prtch(ch)
  189. unsigned int ch;
  190. {
  191.    /* assumes ASCII character set */
  192.    if (ch < ' ') {                        /* ^@ through ^_ */
  193.       printf("^%c", ch + 0x40);
  194.    } else if (ch == 0x7f) {               /* DEL */
  195.       printf("^?");
  196.    } else if (ch > 0x7f) {                /* 8th bit set */
  197.       printf("~");                        /* .. so precede with ~ */
  198.       prtch(ch & 0x7f);                   /* slick recursive call */
  199.    } else
  200.       printf("%c", ch);                   /* plain char */
  201. }
  202.