home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hall of Fame
/
HallofFameCDROM.cdr
/
proglc
/
zoo141_c.lzh
/
FIZ.C
< prev
next >
Wrap
C/C++ Source or Header
|
1987-02-07
|
6KB
|
202 lines
/* fiz.c */
/*
The contents of this file are hereby released to the public domain.
-- Rahul Dhesi 1987/02/06
*/
/*
Searches for all directory entries in an archive and prints their
offsets. Zoo 1.41 and later may then be asked to extract a specific
file by supplying the offset of the file.
*/
#include "options.h"
#include <stdio.h>
#include "various.h"
#include "zoofns.h"
#include "portable.h" /* I/O definitions */
#include "zoo.h"
#ifdef LINT_ARGS
void prtctrl (char *);
void prtch (unsigned int);
#else
void prtctrl ();
void prtch ();
#endif
main(argc,argv)
register int argc;
register char **argv;
{
char *zooname; /* name of archive to be read */
FILE *zoo_file; /* the archive opened as a FILE */
int column; /* column currently printing */
int state; /* to keep track of how much of tag seen */
int inch; /* char just read from archive */
static char usage1[] = "Fiz 1.0 (1987/01/30) public domain Zoo archive repair utility by Rahul Dhesi\n";
static char usage2[] = "Usage: fiz archive[.zoo] (\"fiz -h\" for help)\n";
#ifdef SETBUF
/* set stdout to unbuffered */
setbuf (stdout, NULL);
#endif
if (argc < 2) {
printf("%s%s", usage1, usage2);
exit (1);
}
if (strcmp(argv[1],"-h") == 0)
goto givehelp;
zooname = argv[1];
/* Add default extension if none supplied */
{
char *p, *q;
p = zooname + strlen(zooname); /* point to last char */
while (p != zooname && *p != EXT_CH)
--p;
/* either found EXT_CH or reached beginning of zooname */
if (*p != EXT_CH) {
q = malloc(strlen(zooname) + strlen(EXT_DFLT) + 2);
if (q == NULL) {
printf("Fiz: Ran out of memory.\n");
exit(1);
}
strcpy(q, zooname);
strcat(q, EXT_DFLT);
zooname = q;
}
}
zoo_file = fopen (zooname, FRDSTR);
if (zoo_file == NULL) {
printf("Fiz: FATAL: Could not open %s.\n", zooname);
exit(1);
}
#define NOTHING 1
#define CHAR_1 0xdc
#define CHAR_2 0xa7
#define CHAR_3 0xc4
#define CHAR_4 0xfd
column = 0;
state = NOTHING;
while ((inch = getc(zoo_file)) != EOF) {
inch = inch & 0xff;
if (state == NOTHING && inch == CHAR_1)
state = CHAR_1;
else if (state == CHAR_1 && inch == CHAR_2)
state = CHAR_2;
else if (state == CHAR_2 && inch == CHAR_3)
state = CHAR_3;
else if (state == CHAR_3 && inch == CHAR_4)
state = CHAR_4;
else
state = NOTHING;
if (state == CHAR_4) { /* found tag */
long save_pos;
struct direntry direntry;
save_pos = ftell(zoo_file);
fseek(zoo_file, save_pos-4L, 0); /* back to tag pos */
frd_dir(&direntry, zoo_file); /* read dir entry */
printf("****************\n");
printf ("%8lu: ", save_pos-4L);
if (direntry.dirlen > 0) {
printf ("[");
prtctrl (direntry.dirname);
printf ("]");
}
printf(" [");
prtctrl (direntry.fname);
printf ("]");
if (direntry.namlen > 0) {
printf (" [");
prtctrl (direntry.lfname);
printf ("]");
}
if (direntry.dir_crc != 0)
printf (" [*bad CRC*]");
printf ("\n");
fseek (zoo_file, save_pos, 0); /* try again from there */
}
}
exit (0); /* don't fall through */
givehelp:
printf ("Fiz is used to help you recover data from a damaged archive. Fiz\n");
printf ("searches the specified archive and prints the position (a decimal\n");
printf ("number) of each directory entry found and the directory name and\n");
printf ("filename associated with it.\n\n");
printf ("Make a record of the output of Fiz by redirecting it to a file. Then\n");
printf ("use Zoo version 1.41 or higher to list or extract files in the\n");
printf ("damaged archives starting at a chosen position. For example, you can\n");
printf ("start extracting files from archive \"badarc.zoo\" at position 1098\n");
printf ("with the command\n\n");
printf (" zoo x@1098 badarc\n\n");
printf ("Zoo will ignore the first 1097 bytes of the damaged archive and you\n");
printf ("should be able to recover the undamaged files from the rest of the\n");
printf ("archive.\n\n");
printf ("The position supplied to Zoo should have been obtained from Fiz and\n");
printf ("must correspond to an undamaged directory entry in the archive.\n");
exit(1);
}
/*
prtctrl() prints a string with all unprintable characters converted
to printable form. To avoid the program running astray trying to
print damaged data, no more than MAXPRT characters are printed.
Characters with the 8th bit set are printed preceded with ~. Control
characters are printed preceded with ^. Both ~ and ^ may preced
the character if a control character has the 8th bit set.
*/
#define MAXPRT 50
void prtctrl (str)
char *str;
{
unsigned int ch;
int count;
count = 0;
while (count < MAXPRT && *str != '\0') {
ch = (unsigned) *str;
prtch(ch);
str++;
count++;
}
}
/*
Does the actual character printing for prtctrl()
*/
void prtch(ch)
unsigned int ch;
{
/* assumes ASCII character set */
if (ch < ' ') { /* ^@ through ^_ */
printf("^%c", ch + 0x40);
} else if (ch == 0x7f) { /* DEL */
printf("^?");
} else if (ch > 0x7f) { /* 8th bit set */
printf("~"); /* .. so precede with ~ */
prtch(ch & 0x7f); /* slick recursive call */
} else
printf("%c", ch); /* plain char */
}