home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-07-11 | 47.6 KB | 1,619 lines |
- Newsgroups: alt.sources
- Subject: zoo 2.1 source part 02/15
- Message-ID: <12768@bsu-cs.bsu.edu>
- From: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
- Date: 10 Jul 91 08:48:26 GMT
-
- Checksum: 837499929 (verify with "brik -cv")
- Submitted-by: dhesi@bsu-cs.bsu.edu
- Archive-name: zoo210/part02
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is part 02 of zoo210
- # ============= comment.c ==============
- if test -f 'comment.c' -a X"$1" != X"-c"; then
- echo 'x - skipping comment.c (File already exists)'
- else
- echo 'x - extracting comment.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'comment.c' &&
- #ifndef LINT
- static char sccsid[]="@(#) comment.c 2.14 88/01/24 12:42:13";
- #endif /* LINT */
- X
- /*
- Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- (C) Copyright 1988 Rahul Dhesi -- All rights reserved
- */
- X
- #include "options.h"
- #include "portable.h"
- /* comment() */
- /* Updates comments */
- X
- /* buffer size for any one comment line */
- #define COMMENT_LINE_SIZE 76
- X
- #define MAX_COMMENT_SIZE 32767
- #include "zooio.h"
- #include "various.h"
- X
- #ifndef NOSIGNAL
- #include <signal.h>
- #endif
- X
- #include "zoo.h"
- #include "zoofns.h"
- #include "errors.i"
- X
- void show_comment PARMS ((struct direntry *, ZOOFILE, int, char *));
- void get_comment PARMS ((struct direntry *, ZOOFILE, char *));
- int needed PARMS ((char *, struct direntry *, struct zoo_header *));
- X
- void comment(zoo_path, option)
- char *zoo_path, *option;
- {
- #ifndef NOSIGNAL
- T_SIGNAL (*oldsignal)();
- #endif
- ZOOFILE zoo_file; /* stream for open archive */
- long next_ptr; /* pointers to within archive */
- long this_dir_offset; /* pointers to within archive */
- struct direntry direntry; /* directory entry */
- struct zoo_header zoo_header;
- int matched = 0; /* any files matched? */
- unsigned int zoo_date, zoo_time; /* for restoring archive timestamp */
- char whichname[PATHSIZE]; /* which name to use */
- #ifdef ZOOCOMMENT
- int acmt = 0; /* if changing archive comment */
- #endif
- X
- /* on entry option points to first letter */
- option++; /* skip 'c' */
- #ifdef ZOOCOMMENT
- while (*option != '\0') {
- X if (*option == 'A') {
- X acmt++; /* changing archive comment */
- X option++;
- X } else
- X prterror ('f', inv_option, *option);
- }
- #else
- if (*option != '\0')
- X prterror ('f', inv_option, *option);
- #endif /* ZOOCOMMENT */
- X
- if ((zoo_file = zooopen (zoo_path, Z_RDWR)) == NOFILE)
- X prterror ('f', could_not_open, zoo_path);
- X
- /* save archive timestamp */
- #ifdef GETUTIME
- getutime (zoo_path, &zoo_date, &zoo_time);
- #else
- gettime (zoo_file, &zoo_date, &zoo_time);
- #endif
- X
- /* read header and rewrite with updated version numbers, but ask user to pack
- archive first if archive comment is to be added and header type is 0 */
- #ifdef ZOOCOMMENT
- if (acmt)
- X rwheader (&zoo_header, zoo_file, 0);
- else
- X rwheader (&zoo_header, zoo_file, 1);
- #else
- rwheader (&zoo_header, zoo_file, 1);
- #endif
- X
- #ifdef ZOOCOMMENT
- /* if archive comment being added, handle it and return */
- if (acmt) {
- X void do_acmt PARMS ((struct zoo_header *, ZOOFILE, char *));
- X do_acmt (&zoo_header, zoo_file, zoo_path);
- #ifdef NIXTIME
- X zooclose (zoo_file);
- X setutime (zoo_path, zoo_date, zoo_time); /* restore timestamp */
- #else
- X settime (zoo_file, zoo_date, zoo_time); /* restore timestamp */
- X zooclose (zoo_file);
- #endif
- X return;
- }
- #endif /* ZOOCOMMENT */
- X
- /* Loop through and add comments for matching files */
- while (1) {
- X this_dir_offset = zootell (zoo_file); /* save pos'n of this dir entry */
- X readdir (&direntry, zoo_file, 1); /* read directory entry */
- X next_ptr = direntry.next; /* ptr to next dir entry */
- X
- X /* exit on end of directory chain or end of file */
- X if (next_ptr == 0L || feof(stdin))
- X break;
- X
- X strcpy (whichname, fullpath (&direntry)); /* full pathname */
- X add_version (whichname, &direntry); /* add version suffix */
- X /* add comments for matching non-deleted files */
- X if (!direntry.deleted && needed (whichname, &direntry, &zoo_header)) {
- X matched++;
- X show_comment (&direntry, zoo_file, 1, whichname);
- X get_comment (&direntry, zoo_file, whichname);
- X zooseek (zoo_file, this_dir_offset, 0);
- #ifndef NOSIGNAL
- X oldsignal = signal (SIGINT, SIG_IGN);
- #endif
- X fwr_dir (&direntry, zoo_file);
- #ifndef NOSIGNAL
- X signal (SIGINT, oldsignal);
- #endif
- X }
- X zooseek (zoo_file, next_ptr, 0); /* ..seek to next dir entry */
- } /* end while */
- X
- #ifdef NIXTIME
- zooclose (zoo_file);
- setutime (zoo_path, zoo_date, zoo_time); /* restore timestamp */
- #else
- settime (zoo_file, zoo_date, zoo_time); /* restore timestamp */
- zooclose (zoo_file);
- #endif
- X
- if (!matched)
- X printf ("Zoo: %s", no_match);
- } /* comment */
- X
- /* show_comment() */
- /* shows comment on screen. If show=1, says "Current comment is..." */
- X
- void show_comment (direntry, zoo_file, show, name)
- struct direntry *direntry;
- ZOOFILE zoo_file;
- int show;
- char *name; /* name of file for which comment is being added */
- {
- X if (direntry->cmt_size != 0) {
- X unsigned int i;
- X char ch;
- X int newline = 1;
- X zooseek (zoo_file, direntry->comment, 0);
- X if (show)
- X printf ("Current comment for %s is:\n", name);
- X for (i = 0; i < direntry->cmt_size; i++) {/* show it */
- X ch = zgetc (zoo_file) & 0x7f; /* 7 bits only */
- X if (newline)
- X printf (" |"); /* indent and mark comment lines thus */
- X zputchar (ch);
- X if (ch == '\n')
- X newline = 1;
- X else
- X newline = 0;
- X }
- X if (!newline) /* always terminate with newline */
- X zputchar ('\n');
- X }
- } /* show_comment() */
- X
- X
- /* get_comment() */
- /* Shows user old comment and updates it */
- X
- /* INPUT:
- X direntry points to current directory entry.
- X zoo_file is archive file.
- X this_path is full pathname of file being updated/added.
- X
- X OUTPUT:
- X Comment is added to file and supplied directory entry is updated
- X with comment size and seek position but directory entry is
- X not written to file. Exceptions: If RETURN is hit as first line,
- X previous comment is left unchanged. If /END is hit, previous
- X comment is superseded, even if new comment is null.
- */
- X
- char cmt_prompt[]="[Enter %scomment for %s then type /END]\n";
- X
- void get_comment (direntry, zoo_file, this_path) /* update comment */
- register struct direntry *direntry;
- ZOOFILE zoo_file;
- char *this_path;
- {
- X unsigned int line_count = 0; /* count of new comment lines */
- X
- X zooseek (zoo_file, 0L, 2); /* ready to append new comment */
- #if 0
- X fprintf (stderr, "[Enter comment for %s then type /END]\n", this_path);
- #else
- X fprintf (stderr, cmt_prompt, "", this_path);
- #endif
- X while (1) {
- X char cmt_line[COMMENT_LINE_SIZE];
- X int cmt_size;
- X if (fgets (cmt_line, sizeof(cmt_line), stdin) == NULL)
- X break;
- X line_count++;
- X if (line_count == 1) { /* first line typed */
- X if (!strcmp (cmt_line, "\n")) /* exit if first line blank */
- X break;
- X direntry->comment = zootell (zoo_file);
- X direntry->cmt_size = 0;
- X }
- X if (!str_icmp (cmt_line, "/end\n"))
- X break;
- X cmt_size = strlen (cmt_line);
- X if (MAX_COMMENT_SIZE - direntry->cmt_size > cmt_size) {
- X direntry->cmt_size += (unsigned int) cmt_size;
- X if (zoowrite (zoo_file, cmt_line, cmt_size) < cmt_size)
- X prterror ('f', disk_full);
- X }
- X } /* end while */
- } /* get_comment() */
- X
- #ifdef ZOOCOMMENT
- /*
- do_acmt() updates archive comment by showing it to user and
- requesting a new one. Typed input terminates as with file comment,
- i.e., empty initial line leaves comment unchanged, case-insensitive
- "/end" terminates input comment.
- */
- void do_acmt (zoo_header, zoo_file, zoo_path)
- struct zoo_header *zoo_header;
- ZOOFILE zoo_file;
- char *zoo_path;
- {
- X unsigned int line_count = 0; /* count of new comment lines */
- X void show_acmt PARMS ((struct zoo_header *, ZOOFILE, int));
- X
- X show_acmt (zoo_header, zoo_file, 1); /* show current archive comment */
- X zooseek (zoo_file, 0L, 2); /* ready to append new comment */
- #if 0
- X fprintf (stderr, "[Enter archive comment for %s then type /END]\n",
- X zoo_path);
- #else
- X fprintf (stderr, cmt_prompt, "archive ", zoo_path);
- #endif
- X
- X while (1) {
- X char cmt_line[COMMENT_LINE_SIZE];
- X int cmt_size;
- X if (fgets (cmt_line, sizeof(cmt_line), stdin) == NULL)
- X break;
- X line_count++;
- X if (line_count == 1) { /* first line typed */
- X if (!strcmp (cmt_line, "\n")) /* exit if first line blank */
- X break;
- X zoo_header->acmt_pos = zootell (zoo_file);
- X zoo_header->acmt_len = 0;
- X }
- X if (!str_icmp (cmt_line, "/end\n"))
- X break;
- X cmt_size = strlen (cmt_line);
- X if (MAX_COMMENT_SIZE - zoo_header->acmt_len > cmt_size) {
- X zoo_header->acmt_len += (unsigned int) cmt_size;
- X if (zoowrite (zoo_file, cmt_line, cmt_size) < cmt_size)
- X prterror ('f', disk_full);
- X }
- X } /* end while */
- X zooseek (zoo_file, 0L, 0); /* seek back to beginning */
- X fwr_zooh (zoo_header, zoo_file); /* write update zoo_header */
- } /* do_acmt() */
- #endif /* ZOOCOMMENT */
- X
- /* Prints archive comment. If show==1, says "Current archive comment is:" */
- void show_acmt (zoo_header, zoo_file, show)
- struct zoo_header *zoo_header;
- ZOOFILE zoo_file;
- int show;
- {
- X if (zoo_header->zoo_start != FIXED_OFFSET && zoo_header->acmt_len > 0) {
- X unsigned int i;
- X char ch;
- X int newline = 1;
- X zooseek (zoo_file, zoo_header->acmt_pos, 0);
- X if (show)
- X printf ("Current archive comment is:\n");
- X for (i = 0; i < zoo_header->acmt_len; i++) {/* show it */
- X ch = zgetc (zoo_file) & 0x7f; /* 7 bits only */
- X if (newline)
- X printf (">> "); /* indent and mark comment lines thus */
- X zputchar (ch);
- X if (ch == '\n')
- X newline = 1;
- X else
- X newline = 0;
- X }
- X if (!newline) /* always terminate with newline */
- X zputchar ('\n');
- X }
- } /* show_acmt() */
- SHAR_EOF
- chmod 0644 comment.c ||
- echo 'restore of comment.c failed'
- Wc_c="`wc -c < 'comment.c'`"
- test 9595 -eq "$Wc_c" ||
- echo 'comment.c: original size 9595, current size' "$Wc_c"
- fi
- # ============= crcdefs.c ==============
- if test -f 'crcdefs.c' -a X"$1" != X"-c"; then
- echo 'x - skipping crcdefs.c (File already exists)'
- else
- echo 'x - extracting crcdefs.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'crcdefs.c' &&
- #ifndef LINT
- static char sccsid[]="@(#) crcdefs.c 2.1 87/12/25 12:21:58";
- #endif /* LINT */
- X
- #include "options.h"
- X
- /*
- Global definitions for CRC calculation. I claim no copyright over
- the contents of this file.
- X
- X -- Rahul Dhesi 1987/08/27
- */
- X
- unsigned int crccode;
- unsigned int crctab[] = {
- X 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
- X 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
- X 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0F00, 0xcFc1, 0xce81, 0x0e40,
- X 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
- X 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
- X 0x1e00, 0xdec1, 0xdF81, 0x1F40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
- X 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
- X 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
- X 0xF001, 0x30c0, 0x3180, 0xF141, 0x3300, 0xF3c1, 0xF281, 0x3240,
- X 0x3600, 0xF6c1, 0xF781, 0x3740, 0xF501, 0x35c0, 0x3480, 0xF441,
- X 0x3c00, 0xFcc1, 0xFd81, 0x3d40, 0xFF01, 0x3Fc0, 0x3e80, 0xFe41,
- X 0xFa01, 0x3ac0, 0x3b80, 0xFb41, 0x3900, 0xF9c1, 0xF881, 0x3840,
- X 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
- X 0xee01, 0x2ec0, 0x2F80, 0xeF41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
- X 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
- X 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
- X 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
- X 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
- X 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaF01, 0x6Fc0, 0x6e80, 0xae41,
- X 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
- X 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
- X 0xbe01, 0x7ec0, 0x7F80, 0xbF41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
- X 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
- X 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
- X 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
- X 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
- X 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5F00, 0x9Fc1, 0x9e81, 0x5e40,
- X 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
- X 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
- X 0x4e00, 0x8ec1, 0x8F81, 0x4F40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
- X 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
- X 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
- };
- SHAR_EOF
- chmod 0644 crcdefs.c ||
- echo 'restore of crcdefs.c failed'
- Wc_c="`wc -c < 'crcdefs.c'`"
- test 2446 -eq "$Wc_c" ||
- echo 'crcdefs.c: original size 2446, current size' "$Wc_c"
- fi
- # ============= debug.h ==============
- if test -f 'debug.h' -a X"$1" != X"-c"; then
- echo 'x - skipping debug.h (File already exists)'
- else
- echo 'x - extracting debug.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'debug.h' &&
- /* @(#) debug.h 2.1 87/12/25 12:22:02 */
- X
- /*
- The contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/11/14
- X
- defines conditional function calls
- X
- Usage: The statement
- X
- X debug((printf("y = %d\n", y)))
- X
- may be placed anywhere where two or more statements could be used. It will
- print the value of y at that point.
- X
- Conditional compilation:
- X
- X if DEBUG is defined
- X define the macro debug(X) to execute statement X
- X else
- X define the macro debug(X) to be null
- X endif
- */
- X
- #ifdef DEBUG
- #define debug(x) x;
- #else
- #define debug(x)
- #endif
- X
- SHAR_EOF
- chmod 0644 debug.h ||
- echo 'restore of debug.h failed'
- Wc_c="`wc -c < 'debug.h'`"
- test 615 -eq "$Wc_c" ||
- echo 'debug.h: original size 615, current size' "$Wc_c"
- fi
- # ============= decode.c ==============
- if test -f 'decode.c' -a X"$1" != X"-c"; then
- echo 'x - skipping decode.c (File already exists)'
- else
- echo 'x - extracting decode.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'decode.c' &&
- /*$Source: /usr/home/dhesi/zoo/RCS/decode.c,v $*/
- /*$Id: decode.c,v 1.6 91/07/09 01:39:49 dhesi Exp $*/
- /***********************************************************
- X decode.c
- X
- Adapted from "ar" archiver written by Haruhiko Okumura.
- ***********************************************************/
- X
- #include "options.h"
- #include "zoo.h"
- #include "ar.h"
- #include "lzh.h"
- X
- extern int decoded; /* from huf.c */
- X
- static int j; /* remaining bytes to copy */
- X
- void decode_start()
- {
- X huf_decode_start();
- X j = 0;
- X decoded = 0;
- }
- X
- /*
- decodes; returns no. of chars decoded
- */
- X
- int decode(count, buffer)
- uint count;
- uchar buffer[];
- X /* The calling function must keep the number of
- X bytes to be processed. This function decodes
- X either 'count' bytes or 'DICSIZ' bytes, whichever
- X is smaller, into the array 'buffer[]' of size
- X 'DICSIZ' or more.
- X Call decode_start() once for each new file
- X before calling this function. */
- {
- X static uint i;
- X uint r, c;
- X
- X r = 0;
- X while (--j >= 0) {
- X buffer[r] = buffer[i];
- X i = (i + 1) & (DICSIZ - 1);
- X if (++r == count)
- X return r;
- X }
- X for ( ; ; ) {
- X c = decode_c();
- X if (decoded)
- X return r;
- X if (c <= UCHAR_MAX) {
- X buffer[r] = c;
- X if (++r == count)
- X return r;
- X } else {
- X j = c - (UCHAR_MAX + 1 - THRESHOLD);
- X i = (r - decode_p() - 1) & (DICSIZ - 1);
- X while (--j >= 0) {
- X buffer[r] = buffer[i];
- X i = (i + 1) & (DICSIZ - 1);
- X if (++r == count)
- X return r;
- X }
- X }
- X }
- }
- SHAR_EOF
- chmod 0644 decode.c ||
- echo 'restore of decode.c failed'
- Wc_c="`wc -c < 'decode.c'`"
- test 1444 -eq "$Wc_c" ||
- echo 'decode.c: original size 1444, current size' "$Wc_c"
- fi
- # ============= descrip.mms ==============
- if test -f 'descrip.mms' -a X"$1" != X"-c"; then
- echo 'x - skipping descrip.mms (File already exists)'
- else
- echo 'x - extracting descrip.mms (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'descrip.mms' &&
- # derived from: @(#) descrip.mms 2.2 88/01/09 12:10:49
- # $Source: /usr/home/dhesi/zoo/RCS/descrip.mms,v $
- # $Id: descrip.mms,v 1.9 91/07/07 14:58:21 dhesi Exp $
- #Make Zoo for VAX/VMS
- #
- #The contents of this makefile are hereby released to the public domain.
- # -- Rahul Dhesi 1991/07/06
- X
- CC = cc
- CFLAGS =
- EXTRA = /define=(BIG_MEM,NDEBUG,VMS)
- ldswitch =
- X
- #List of all object files created for Zoo
- ZOOOBJS = addbfcrc.obj, addfname.obj, basename.obj, comment.obj, -
- X crcdefs.obj, decode.obj, encode.obj, getfile.obj, huf.obj, -
- X io.obj, lzc.obj, lzd.obj, lzh.obj, machine.obj, makelist.obj, -
- X maketbl.obj, maketree.obj, misc.obj, misc2.obj, needed.obj, -
- X nextfile.obj, options.obj, parse.obj, portable.obj, prterror.obj, -
- X version.obj, vmstime.obj, zoo.obj, zooadd.obj, zooadd2.obj, -
- X zoodel.obj, zooext.obj, zoolist.obj, zoopack.obj
- X
- FIZOBJS = fiz.obj, addbfcrc.obj, portable.obj, crcdefs.obj
- X
- BILFOBJS = bilf.obj
- X
- .c.obj :
- X $(CC) $(CFLAGS) $(EXTRA) $*.c
- X
- zoo.exe : $(ZOOOBJS)
- X link/executable=zoo.exe $(ldswitch) $(ZOOOBJS), options/opt
- X
- # bigger but perhaps more (less?) portable across machines --
- # no shared libraries
- zoobig.exe : $(ZOOOBJS)
- X link/executable=zoobig.exe $(ldswitch) $(ZOOOBJS)
- X
- fiz : $(FIZOBJS)
- X link/executable=fiz.exe $(ldswitch) $(FIZOBJS), options/opt
- X
- bilf : $(BILFOBJS)
- X link/executable=bilf.exe $(ldswitch) $(BILFOBJS), options/opt
- X
- #######################################################################
- # DEPENDENCIES -- not guaranteed to be up-to-date
- #######################################################################
- X
- addbfcrc.obj : options.h
- addfname.obj : options.h various.h zoo.h zoofns.h zooio.h
- addfname.obj : zoomem.h
- basename.obj : assert.h debug.h options.h parse.h various.h
- basename.obj : zoo.h zoofns.h zooio.h
- comment.obj : errors.i options.h portable.h various.h
- comment.obj : zoo.h zoofns.h zooio.h
- crcdefs.obj : options.h
- decode.obj : ar.h lzh.h options.h zoo.h
- encode.obj : ar.h errors.i lzh.h
- encode.obj : options.h zoo.h
- fiz.obj : options.h portable.h various.h zoo.h zoofns.h
- fiz.obj : zooio.h
- getfile.obj : options.h various.h zoo.h zoofns.h zooio.h
- getfile.obj : zoomem.h
- huf.obj : ar.h errors.i lzh.h options.h zoo.h
- io.obj : ar.h errors.i lzh.h options.h portable.h zoo.h
- io.obj : zooio.h
- lzc.obj : assert.h debug.h lzconst.h options.h various.h
- lzc.obj : zoo.h zoofns.h zooio.h zoomem.h
- lzd.obj : assert.h debug.h lzconst.h options.h various.h
- lzd.obj : zoo.h zoofns.h zooio.h zoomem.h
- lzh.obj : ar.h errors.i options.h zoo.h
- machine.obj : options.h various.h zoo.h zoofns.h zooio.h
- makelist.obj : assert.h debug.h errors.i options.h
- makelist.obj : portable.h various.h zoo.h zoofns.h zooio.h
- maketbl.obj : ar.h lzh.h options.h zoo.h
- maketree.obj : ar.h lzh.h options.h zoo.h
- misc.obj : errors.i options.h portable.h various.h zoo.h zoofns.h zooio.h
- misc2.obj : errors.i options.h portable.h various.h zoo.h
- misc2.obj : zoofns.h zooio.h zoomem.h
- msdos.obj : errors.i options.h zoo.h zoofns.h zooio.h
- needed.obj : debug.h options.h portable.h various.h zoo.h
- needed.obj : zoofns.h zooio.h
- nextfile.obj : options.h various.h zoo.h
- options.obj : errors.i options.h various.h zoo.h zoofns.h
- options.obj : zooio.h
- parse.obj : assert.h options.h parse.h various.h zoo.h
- parse.obj : zoofns.h zooio.h
- portable.obj : assert.h debug.h machine.h options.h
- portable.obj : portable.h various.h zoo.h zoofns.h zooio.h
- prterror.obj : options.h various.h
- prterror.obj : zoofns.h zooio.h
- zoo.obj : errors.i options.h various.h zoo.h zoofns.h
- zoo.obj : zooio.h zoomem.h
- zooadd.obj : debug.h errors.i options.h parse.h portable.h
- zooadd.obj : various.h zoo.h zoofns.h zooio.h zoomem.h
- zooadd2.obj : assert.h debug.h errors.i options.h parse.h
- zooadd2.obj : various.h zoo.h zoofns.h zooio.h
- zoodel.obj : errors.i options.h portable.h various.h zoo.h zoofns.h zooio.h
- zooext.obj : errors.i machine.h options.h parse.h portable.h various.h zoo.h
- zooext.obj : zoofns.h zooio.h
- zoofilt.obj : options.h
- zoolist.obj : errors.i options.h portable.h various.h zoo.h
- zoolist.obj : zoofns.h zooio.h zoomem.h
- zoopack.obj : errors.i options.h portable.h various.h
- zoopack.obj : zoo.h zoofns.h zooio.h
- SHAR_EOF
- chmod 0644 descrip.mms ||
- echo 'restore of descrip.mms failed'
- Wc_c="`wc -c < 'descrip.mms'`"
- test 4173 -eq "$Wc_c" ||
- echo 'descrip.mms: original size 4173, current size' "$Wc_c"
- fi
- # ============= encode.c ==============
- if test -f 'encode.c' -a X"$1" != X"-c"; then
- echo 'x - skipping encode.c (File already exists)'
- else
- echo 'x - extracting encode.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'encode.c' &&
- /*$Source: /usr/home/dhesi/zoo/RCS/encode.c,v $*/
- /*$Id: encode.c,v 1.41 91/07/09 01:39:47 dhesi Exp $*/
- X
- /*
- Adapted from "ar" archiver written by Haruhiko Okumura.
- */
- X
- #include "options.h"
- #include "zoo.h"
- #include "ar.h"
- #include "lzh.h"
- X
- extern void prterror();
- extern char *out_buf_adr;
- X
- #include <assert.h>
- X
- #ifdef ANSI_HDRS
- # include <stdlib.h>
- # include <string.h>
- #endif
- X
- #include "errors.i"
- X
- FILE *lzh_infile;
- FILE *lzh_outfile;
- X
- /*
- sliding dictionary with percolating update
- */
- X
- #define PERCOLATE 1
- #define NIL 0
- #define MAX_HASH_VAL (3 * DICSIZ + (DICSIZ / 512 + 1) * UCHAR_MAX)
- X
- typedef short node;
- X
- static uchar *text, *childcount;
- static node pos, matchpos, avail,
- X *position, *parent, *prev, *next = NULL;
- static int remainder, matchlen;
- X
- #if MAXMATCH <= (UCHAR_MAX + 1)
- X static uchar *level;
- # define T_LEVEL uchar *
- #else
- X static ushort *level;
- # define T_LEVEL ushort *
- #endif
- X
- static void allocate_memory()
- {
- X if (next != NULL) return;
- X /* text = (uchar *) malloc(DICSIZ * 2 + MAXMATCH); */
- X text = (uchar *) out_buf_adr; /* reuse I/O buffer used elsewhere */
- X level = (T_LEVEL) malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*level));
- X childcount = (uchar *)malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*childcount));
- #ifdef PERCOLATE
- X position = (node *) malloc((DICSIZ + UCHAR_MAX + 1) * sizeof(*position));
- #else
- X position = (node *) malloc(DICSIZ * sizeof(*position));
- #endif
- X parent = (node *) malloc(DICSIZ * 2 * sizeof(*parent));
- X prev = (node *) malloc(DICSIZ * 2 * sizeof(*prev));
- X next = (node *) malloc((MAX_HASH_VAL + 1) * sizeof(*next));
- X if (next == NULL) prterror('f', no_memory);
- }
- X
- static void init_slide()
- {
- X node i;
- X
- X for (i = DICSIZ; i <= DICSIZ + UCHAR_MAX; i++) {
- X level[i] = 1;
- #ifdef PERCOLATE
- X position[i] = NIL; /* sentinel */
- #endif
- X }
- X for (i = DICSIZ; i < DICSIZ * 2; i++) parent[i] = NIL;
- X avail = 1;
- X for (i = 1; i < DICSIZ - 1; i++) next[i] = i + 1;
- X next[DICSIZ - 1] = NIL;
- X for (i = DICSIZ * 2; i <= MAX_HASH_VAL; i++) next[i] = NIL;
- }
- X
- #define HASH(p, c) ((p) + ((c) << (DICBIT - 9)) + DICSIZ * 2)
- X
- static node child(q, c)
- node q;
- uchar c;
- X /* q's child for character c (NIL if not found) */
- {
- X node r;
- X
- X r = next[HASH(q, c)];
- X parent[NIL] = q; /* sentinel */
- X while (parent[r] != q) r = next[r];
- X return r;
- }
- X
- static void makechild(q, c, r)
- node q;
- uchar c;
- node r;
- X /* Let r be q's child for character c. */
- {
- X node h, t;
- X
- X h = HASH(q, c);
- X t = next[h]; next[h] = r; next[r] = t;
- X prev[t] = r; prev[r] = h;
- X parent[r] = q; childcount[q]++;
- }
- X
- void split(old)
- node old;
- {
- X node new, t;
- X
- X new = avail; avail = next[new]; childcount[new] = 0;
- X t = prev[old]; prev[new] = t; next[t] = new;
- X t = next[old]; next[new] = t; prev[t] = new;
- X parent[new] = parent[old];
- X level[new] = matchlen;
- X position[new] = pos;
- X makechild(new, text[matchpos + matchlen], old);
- X makechild(new, text[pos + matchlen], pos);
- }
- X
- static void insert_node()
- {
- X node q, r, j, t;
- X uchar c, *t1, *t2;
- X
- X if (matchlen >= 4) {
- X matchlen--;
- X r = (matchpos + 1) | DICSIZ;
- X while ((q = parent[r]) == NIL) r = next[r];
- X while (level[q] >= matchlen) {
- X r = q; q = parent[q];
- X }
- #ifdef PERCOLATE
- X t = q;
- X while (position[t] < 0) {
- X position[t] = pos; t = parent[t];
- X }
- X if (t < DICSIZ) position[t] = pos | PERC_FLAG;
- #else
- X t = q;
- X while (t < DICSIZ) {
- X position[t] = pos; t = parent[t];
- X }
- #endif
- X } else {
- X q = text[pos] + DICSIZ; c = text[pos + 1];
- X if ((r = child(q, c)) == NIL) {
- X makechild(q, c, pos); matchlen = 1;
- X return;
- X }
- X matchlen = 2;
- X }
- X for ( ; ; ) {
- X if (r >= DICSIZ) {
- X j = MAXMATCH; matchpos = r;
- X } else {
- X j = level[r];
- X matchpos = position[r] & ~PERC_FLAG;
- X }
- X if (matchpos >= pos) matchpos -= DICSIZ;
- X t1 = &text[pos + matchlen]; t2 = &text[matchpos + matchlen];
- X while (matchlen < j) {
- X if (*t1 != *t2) { split(r); return; }
- X matchlen++; t1++; t2++;
- X }
- X if (matchlen >= MAXMATCH) break;
- X position[r] = pos;
- X q = r;
- X if ((r = child(q, *t1)) == NIL) {
- X makechild(q, *t1, pos); return;
- X }
- X matchlen++;
- X }
- X t = prev[r]; prev[pos] = t; next[t] = pos;
- X t = next[r]; next[pos] = t; prev[t] = pos;
- X parent[pos] = q; parent[r] = NIL;
- X next[r] = pos; /* special use of next[] */
- }
- X
- static void delete_node()
- {
- #ifdef PERCOLATE
- X node q, r, s, t, u;
- #else
- X node r, s, t, u;
- #endif
- X
- X if (parent[pos] == NIL) return;
- X r = prev[pos]; s = next[pos];
- X next[r] = s; prev[s] = r;
- X r = parent[pos]; parent[pos] = NIL;
- X if (r >= DICSIZ || --childcount[r] > 1) return;
- #ifdef PERCOLATE
- X t = position[r] & ~PERC_FLAG;
- #else
- X t = position[r];
- #endif
- X if (t >= pos) t -= DICSIZ;
- #ifdef PERCOLATE
- X s = t; q = parent[r];
- X while ((u = position[q]) & PERC_FLAG) {
- X u &= ~PERC_FLAG; if (u >= pos) u -= DICSIZ;
- X if (u > s) s = u;
- X position[q] = (s | DICSIZ); q = parent[q];
- X }
- X if (q < DICSIZ) {
- X if (u >= pos) u -= DICSIZ;
- X if (u > s) s = u;
- X position[q] = s | DICSIZ | PERC_FLAG;
- X }
- #endif
- X s = child(r, text[t + level[r]]);
- X t = prev[s]; u = next[s];
- X next[t] = u; prev[u] = t;
- X t = prev[r]; next[t] = s; prev[s] = t;
- X t = next[r]; prev[t] = s; next[s] = t;
- X parent[s] = parent[r]; parent[r] = NIL;
- X next[r] = avail; avail = r;
- }
- X
- static void get_next_match()
- {
- X int n;
- X
- X remainder--;
- X if (++pos == DICSIZ * 2) {
- #ifdef CHECK_BREAK
- X check_break();
- #endif
- X (void) MOVE_LEFT((char *) &text[0], (char *) &text[DICSIZ], DICSIZ + MAXMATCH);
- X n = fread_crc(&text[DICSIZ + MAXMATCH], DICSIZ, lzh_infile);
- X remainder += n; pos = DICSIZ;
- #ifdef SHOW_DOTS
- X (void) putc('.', stderr);
- X (void) fflush(stderr);
- #endif
- X }
- X delete_node(); insert_node();
- }
- X
- /* read from infile, compress, write to outfile */
- void encode(infile, outfile)
- FILE *infile;
- FILE *outfile;
- {
- X int lastmatchlen;
- X node lastmatchpos;
- X
- X /* make input/output files visible to other functions */
- X lzh_infile = infile;
- X lzh_outfile = outfile;
- X
- X allocate_memory(); init_slide(); huf_encode_start();
- X remainder = fread_crc(&text[DICSIZ], DICSIZ + MAXMATCH, lzh_infile);
- #ifdef SHOW_DOTS
- X (void) putc('.', stderr);
- X (void) fflush(stderr);
- #endif
- X matchlen = 0;
- X pos = DICSIZ; insert_node();
- X if (matchlen > remainder) matchlen = remainder;
- X while (remainder > 0 && ! unpackable) {
- X lastmatchlen = matchlen; lastmatchpos = matchpos;
- X get_next_match();
- X if (matchlen > remainder) matchlen = remainder;
- X if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
- #if 0
- X d1log("%c", text[pos-1]);
- #endif
- X output(text[pos - 1], 0);
- X } else {
- #if 0
- X (void) putc('.', stderr); (void) fflush(stderr);
- #endif
- X
- #if 0
- X {
- X int i;
- X d1log("\nlastmatchlen=%d, pos=%d, lastmatchpos=%d",
- X lastmatchlen, pos, lastmatchpos);
- X d1log("\n[%d: ", (int) lastmatchlen);
- X for (i = 0; i < lastmatchlen; i++)
- X d1log("%c", text[lastmatchpos + i]);
- X d1log("]\n");
- X }
- #endif
- X
- X output((uint) (lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD)),
- X (uint) ((pos - lastmatchpos - 2) & (DICSIZ - 1)));
- X while (--lastmatchlen > 0) get_next_match();
- X if (matchlen > remainder) matchlen = remainder;
- X }
- X }
- X huf_encode_end();
- }
- X
- #ifdef NEED_MEMMOVE
- /* like memmove, but for moving stuff LEFT (downwards in memory) only!! */
- void move_left(dest, src, len)
- char *dest;
- char *src;
- int len;
- {
- X while (len-- > 0)
- X *dest++ = *src++;
- }
- #endif /* NEED_MEMMOVE */
- SHAR_EOF
- chmod 0644 encode.c ||
- echo 'restore of encode.c failed'
- Wc_c="`wc -c < 'encode.c'`"
- test 7292 -eq "$Wc_c" ||
- echo 'encode.c: original size 7292, current size' "$Wc_c"
- fi
- # ============= errors.i ==============
- if test -f 'errors.i' -a X"$1" != X"-c"; then
- echo 'x - skipping errors.i (File already exists)'
- else
- echo 'x - extracting errors.i (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'errors.i' &&
- /* @(#) errors.i 2.4 88/01/31 12:32:46 */
- X
- /*
- The contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/11/14
- */
- X
- /* defines all the errors as externs. Declarations must be
- equivalent to those in prterror.c */
- X
- /* These declarations must be equivalent to those in prterror.c */
- extern char no_match[];
- extern char failed_consistency[];
- extern char invalid_header[];
- extern char internal_error[];
- extern char disk_full[];
- extern char bad_directory[];
- extern char no_memory[];
- extern char too_many_files[];
- extern char packfirst[];
- extern char garbled[];
- extern char start_ofs[];
- X
- #ifndef OOZ
- extern char wrong_version[];
- extern char cant_process[];
- extern char option_ignored[];
- extern char inv_option[];
- extern char bad_crc[];
- #endif
- X
- extern char could_not_open[];
- X
- SHAR_EOF
- chmod 0644 errors.i ||
- echo 'restore of errors.i failed'
- Wc_c="`wc -c < 'errors.i'`"
- test 825 -eq "$Wc_c" ||
- echo 'errors.i: original size 825, current size' "$Wc_c"
- fi
- # ============= file.fix ==============
- if test -f 'file.fix' -a X"$1" != X"-c"; then
- echo 'x - skipping file.fix (File already exists)'
- else
- echo 'x - extracting file.fix (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'file.fix' &&
- X Making the "file" command recognize zoo archives
- X
- Zoo archives have the following magic number: Beginning at offset 20
- decimal, there are four bytes with the values 0xdc, 0xa7, 0xc4, and
- 0xfd. (But if you call the first byte of a zoo archive byte 1, then
- the magic bytes will be bytes 21 through 24.)
- X
- To make the "file" command identify zoo archives, changes can be made
- as follows.
- X
- 4.3BSD: See the context diff near the end of this document, suitable
- for application with the "patch" utility, that works with the 4.3BSD
- "file" command on a VAX-11/785. I don't know if this will also work
- under 4.2BSD or with any other implementation of the "file" command
- or on any other CPU.
- X
- System V Release 2 (as exemplified by Microport System V/AT): At the
- end of the file "/etc/magic", add the following line:
- X
- 20 long 0xfdc4a7dc zoo archive
- X
- This should work on a little-endian machine, in which the long value
- 0xfdc4a7dc is stored with the least-significant byte first. For a big-
- endian machine, you will probably need to replace it with 0xdca7c4fd.
- This assumes that long occupies 4 bytes. If not, use a data type name
- that is exactly 4 bytes.
- X
- =====
- Changes needed to make the 4.3BSD "file" command recognize zoo
- archives. Known to work on a VAX-11/785.
- X
- *** file.c.old Thu Mar 6 19:34:29 1986
- --- file.c Sat Feb 21 19:28:52 1987
- ***************
- *** 172,181 ****
- --- 172,187 ----
- X case 070707:
- X printf("cpio data\n");
- X return;
- X }
- X
- + if (buf[20] == (char) 0xdc && buf[21] == (char) 0xa7 &&
- + buf[22] == (char) 0xc4 && buf[23] == (char) 0xfd) {
- + printf ("zoo archive\n");
- + return;
- + }
- +
- X if (buf[0] == '#' && buf[1] == '!' && shellscript(buf+2, &mbuf))
- X return;
- X if (buf[0] == '\037' && buf[1] == '\235') {
- X if (buf[2]&0x80)
- X printf("block ");
- SHAR_EOF
- chmod 0644 file.fix ||
- echo 'restore of file.fix failed'
- Wc_c="`wc -c < 'file.fix'`"
- test 1814 -eq "$Wc_c" ||
- echo 'file.fix: original size 1814, current size' "$Wc_c"
- fi
- # ============= fiz.1 ==============
- if test -f 'fiz.1' -a X"$1" != X"-c"; then
- echo 'x - skipping fiz.1 (File already exists)'
- else
- echo 'x - extracting fiz.1 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fiz.1' &&
- .\" @(#) fiz.1 1.2 88/01/31 23:22:04
- .\"
- .\" For formatting with nroff:
- .\" nroff -man fiz.1
- .\"
- .TH FIZ 1 "Jan 31, 1988"
- .SH NAME
- fiz \- analyze damaged zoo archive for data revovery
- .SH SYNOPSIS
- .I fiz
- .RB archive[ .zoo ]
- .SH DESCRIPTION
- .I Fiz
- is used to analyze damaged
- .I zoo
- archives and locate directory entries and file data in them.
- The current version of
- .I fiz
- is 2.0 and it is meant to be used in conjunction with
- .I zoo
- version 2.0.
- .I Fiz
- makes no assumptions about archive structure. Instead, it simply
- searches the entire subject archive for tag values
- that mark the locations of directory entries and file data.
- In a
- .I zoo
- archive, a
- .I directory entry
- contains information about a stored file such as its name, whether
- compressed or not, and its timestamp. The
- .I file data
- are the actual data for the archived file, and may be
- either the original data, or the result of compressing the file.
- .PP
- For each directory entry found,
- .I fiz
- prints where in the archive it is located, the directory path and
- filename(s) found in it, whether the directory entry appears
- to be corrupted (indicated by [*CRC Error*]), and the value of
- the pointer to the file data that is found in the directory entry.
- For each block of file data found in the archive,
- .I fiz
- prints where in the archive the block begins. In the case of
- an undamaged archive, the pointer to file data found in
- a directory entry will correspond to where
- .I fiz
- actually locates the data. Here is some sample output from
- .I fiz:
- .PP
- .nf
- ****************
- X 2526: DIR [changes] ==> 95
- X 2587: DATA
- ****************
- X 3909: DIR [copyrite] ==> 1478
- X 3970: DATA
- X 4769: DATA
- ****************
- .fi
- .sp 1
- In such output,
- .B DIR
- indicates where
- .I fiz
- found a directory entry in the archive, and
- .B DATA
- indicates where
- .I fiz
- found file data in the archive. Filenames located by
- .I fiz
- are enclosed in square brackets, and the notation
- "==> 95" indicates that the directory entry found by
- .I fiz
- at position 2526 has a file data pointer to
- position 95. In actuality,
- .I fiz
- found file data at positions 2587, 3970, and
- 4769. Since
- .I fiz
- found only two directory entries, and each directory entry corresponds
- to one file, one of the file data positions is an artifact.
- .PP
- Once the locations of directory entries and file data are found, the
- .B @
- modifier to
- .I "zoo's"
- archive list and extract commands can be used and
- the archive contents selectively listed or extracted,
- skipping the damaged portion. This is further described
- in the documentation for
- .I zoo(1).
- .PP
- In the above case, commands to try giving to
- .I zoo
- might be
- .B x@2526,2587
- (extract beginning at position 2526, and get file data
- from position 2587),
- .B x@3090,3970
- (extract at 3090, get data from 3970)
- and
- .B x@3909,4769
- (extract at 3909, get data from 4769). Once a correctly-matched
- directory entry/file data pair is found,
- .I zoo
- will in most cases synchronize with and correctly extract all files
- subsequently found in the archive. Trial and error should allow
- all undamaged files to be extracted.
- Also note that self-extracting archives created using
- .I sez
- (the Self-Extracting
- .I Zoo
- utility for MS-DOS), which are normally executed on an MS-DOS
- system for extraction, can
- be extracted on non-MSDOS systems in a similar way.
- .PP
- .SH "SEE ALSO"
- zoo(1)
- .SH BUGS
- Random byte patterns can occasionally be incorrectly recognized
- as tag values. This occurs very rarely, however, and trial
- and error will usually permit all undamaged data to be
- extracted.
- .SH DIAGNOSTICS
- .I Fiz
- always exits with a status code of 0.
- .SH "FUTURE DIRECTIONS"
- Automation of data recovery from a damaged archive is potentially
- achievable. However, since damaged archives occur only rarely,
- .I fiz
- as it currently stands is unlikely to change much in the
- near future.
- .SH AUTHOR
- Rahul Dhesi
- SHAR_EOF
- chmod 0644 fiz.1 ||
- echo 'restore of fiz.1 failed'
- Wc_c="`wc -c < 'fiz.1'`"
- test 3849 -eq "$Wc_c" ||
- echo 'fiz.1: original size 3849, current size' "$Wc_c"
- fi
- # ============= fiz.c ==============
- if test -f 'fiz.c' -a X"$1" != X"-c"; then
- echo 'x - skipping fiz.c (File already exists)'
- else
- echo 'x - extracting fiz.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fiz.c' &&
- #ifndef LINT
- static char sccsid[]="@(#) fiz.c 2.6 88/01/31 23:23:50";
- #endif /* LINT */
- X
- /*
- The contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1987/02/06
- */
- X
- /*
- 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.
- */
- X
- #include "options.h"
- #include "zooio.h"
- #include "various.h"
- #include "zoofns.h"
- #include "portable.h" /* I/O definitions */
- #include "zoo.h"
- X
- void prtctrl ();
- void prtch ();
- X
- main(argc,argv)
- register int argc;
- register char **argv;
- {
- X char *zooname; /* name of archive to be read */
- X ZOOFILE zoo_file; /* the archive being examined opened for read */
- X int state; /* to keep track of how much of tag seen */
- X int inch; /* char just read from archive */
- X
- X static char usage1[] = "Fiz 2.0 (1987/02/01) public domain Zoo archive repair utility by Rahul Dhesi\n";
- X static char usage2[] = "Usage: fiz archive[.zoo] (\"fiz -h\" for help)\n";
- X
- #ifdef SETBUF
- /* set stdout to unbuffered */
- setbuf (stdout, (char *) NULL);
- #endif
- X
- X if (argc < 2) {
- X printf("%s%s", usage1, usage2);
- X exit (1);
- X }
- X
- X if (strcmp(argv[1],"-h") == 0)
- X goto givehelp;
- X
- X zooname = argv[1];
- X
- X /* Add default extension if none supplied */
- X {
- X char *p, *q;
- X p = zooname + strlen(zooname); /* point to last char */
- X while (p != zooname && *p != EXT_CH)
- X --p;
- X /* either found EXT_CH or reached beginning of zooname */
- X if (*p != EXT_CH) {
- X q = malloc(strlen(zooname) + strlen(EXT_DFLT) + 2);
- X if (q == NULL) {
- X printf("Fiz: Ran out of memory.\n");
- X exit(1);
- X }
- X strcpy(q, zooname);
- X strcat(q, EXT_DFLT);
- X zooname = q;
- X }
- X }
- X
- X zoo_file = zooopen (zooname, Z_READ);
- X if (zoo_file == NOFILE) {
- X printf("Fiz: FATAL: Could not open %s.\n", zooname);
- X exit(1);
- X }
- X
- #ifdef DOUBLE_SECRET
- X { void oh_well(void); oh_well(); }
- #endif
- X
- #define NOSTATE 1
- #define HDR_1 0xdc
- #define HDR_2 0xa7
- #define HDR_3 0xc4
- #define HDR_4 0xfd
- X
- #define DAT_1 '@'
- #define DAT_2 ')'
- #define DAT_3 '#'
- #define DAT_4 '('
- X
- /* finite state machine implemented here by hand */
- X
- X state = NOSTATE;
- X while ((inch = zgetc(zoo_file)) != EOF) {
- X inch = inch & 0xff;
- X if (state == NOSTATE) {
- X if (inch == HDR_1)
- X state = HDR_1;
- X else if (inch == DAT_1)
- X state = DAT_1;
- X } else if (state == HDR_1 && inch == HDR_2)
- X state = HDR_2;
- X else if (state == HDR_2 && inch == HDR_3)
- X state = HDR_3;
- X else if (state == HDR_3 && inch == HDR_4)
- X state = HDR_4;
- X else if (state == DAT_1 && inch == DAT_2)
- X state = DAT_2;
- X else if (state == DAT_2 && inch == DAT_3)
- X state = DAT_3;
- X else if (state == DAT_3 && inch == DAT_4)
- X state = DAT_4;
- X else
- X state = NOSTATE;
- X
- X if (state == HDR_4) { /* found archive tag */
- X long save_pos;
- X struct direntry direntry;
- X save_pos = zootell(zoo_file);
- X zooseek(zoo_file, save_pos-4L, 0); /* back to tag pos */
- X frd_dir(&direntry, zoo_file); /* read dir entry */
- X printf("****************\n");
- X
- X printf ("%8lu: DIR ", save_pos-4L);
- X
- X if (direntry.dirlen > 0) {
- X printf ("[");
- X prtctrl (direntry.dirname);
- X printf ("]");
- X }
- X
- X printf(" [");
- X prtctrl (direntry.fname);
- X printf ("]");
- X
- X if (direntry.namlen > 0) {
- X printf (" [");
- X prtctrl (direntry.lfname);
- X printf ("]");
- X }
- X printf (" ==> %4lu", direntry.offset);
- X if (direntry.dir_crc != 0)
- X printf (" [*bad CRC*]");
- X printf ("\n");
- X fseek (zoo_file, save_pos, 0); /* try again from there */
- X } else if (state == DAT_4) { /* file data */
- X printf ("%8lu: DATA\n", zootell(zoo_file) + 1);
- X }
- X }
- exit (0); /* don't fall through */
- X
- givehelp:
- X
- /*
- vi macros:
- to add printf:
- :s/^.*$/printf("&\\n");/
- To remove printf:
- :s/^printf("\(.*\)\\n");/\1/
- */
- printf("Fiz is used to help you recover data from a damaged archive. Fiz searches\n");
- printf("the specified archive for directory entries and stored files, and prints the\n");
- printf("position of each one found. Each directory entry contains a number that\n");
- printf("represents the location in the archive where the file is stored; fiz also\n");
- printf("prints this position. All numbers printed are decimal numbers.\n\n");
- X
- printf("Use Zoo version 2.00 or higher to list or extract files in the damaged\n");
- printf("archive starting at a position identified by fiz. For example, you can\n");
- printf("start extracting files from archive \"badarc.zoo\" at position 1098 with the\n");
- printf("command:\n\n");
- X
- printf(" zoo x@1098 badarc\n\n");
- X
- printf("Zoo will ignore the first 1098 bytes of the damaged archive and you should be\n");
- printf("able to recover the undamaged files from the rest of the archive. You can\n");
- printf("also manually specify where to look for the file data with a command like\n\n");
- X
- printf(" zoo x@1098,1153\n\n");
- X
- printf("which tells zoo to use the directory entry at position 1098, but to get the\n");
- printf("actual file data from position 1153 (and not from where the directory entry\n");
- printf("says the data ought to be). See the manuals for fiz and zoo for more details.\n");
- X
- exit (0);
- }
- X
- /*
- 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
- X
- void prtctrl (str)
- char *str;
- {
- X unsigned int ch;
- X int count;
- X count = 0;
- X
- X while (count < MAXPRT && *str != '\0') {
- X ch = (unsigned) *str;
- X prtch(ch);
- X str++;
- X count++;
- X }
- }
- X
- /*
- Does the actual character printing for prtctrl()
- */
- void prtch(ch)
- unsigned int ch;
- {
- X /* assumes ASCII character set */
- X if (ch < ' ') { /* ^@ through ^_ */
- X printf("^%c", ch + 0x40);
- X } else if (ch == 0x7f) { /* DEL */
- X printf("^?");
- X } else if (ch > 0x7f) { /* 8th bit set */
- X printf("~"); /* .. so precede with ~ */
- X prtch(ch & 0x7f); /* slick recursive call */
- X } else
- X printf("%c", ch); /* plain char */
- }
- SHAR_EOF
- chmod 0644 fiz.c ||
- echo 'restore of fiz.c failed'
- Wc_c="`wc -c < 'fiz.c'`"
- test 6784 -eq "$Wc_c" ||
- echo 'fiz.c: original size 6784, current size' "$Wc_c"
- fi
- # ============= fiz.man ==============
- if test -f 'fiz.man' -a X"$1" != X"-c"; then
- echo 'x - skipping fiz.man (File already exists)'
- else
- echo 'x - extracting fiz.man (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fiz.man' &&
- X
- X
- X
- FIZ(1) **IX Programmer's Manual FIZ(1)
- X
- X
- X
- NAME
- X fiz - analyze damaged zoo archive for data revovery
- X
- SYNOPSIS
- X fiz archive[.zoo]
- X
- DESCRIPTION
- X Fiz is used to analyze damaged zoo archives and locate
- X directory entries and file data in them. The current ver-
- X sion of fiz is 2.0 and it is meant to be used in conjunction
- X with zoo version 2.0. Fiz makes no assumptions about
- X archive structure. Instead, it simply searches the entire
- X subject archive for tag values that mark the locations of
- X directory entries and file data. In a zoo archive, a direc-
- X tory entry contains information about a stored file such as
- X its name, whether compressed or not, and its timestamp. The
- X file data are the actual data for the archived file, and may
- X be either the original data, or the result of compressing
- X the file.
- X
- X For each directory entry found, fiz prints where in the
- X archive it is located, the directory path and filename(s)
- X found in it, whether the directory entry appears to be cor-
- X rupted (indicated by [*CRC Error*]), and the value of the
- X pointer to the file data that is found in the directory
- X entry. For each block of file data found in the archive,
- X fiz prints where in the archive the block begins. In the
- X case of an undamaged archive, the pointer to file data found
- X in a directory entry will correspond to where fiz actually
- X locates the data. Here is some sample output from fiz:
- X
- X ****************
- X 2526: DIR [changes] ==> 95
- X 2587: DATA
- X ****************
- X 3909: DIR [copyrite] ==> 1478
- X 3970: DATA
- X 4769: DATA
- X ****************
- X
- X In such output, DIR indicates where fiz found a directory
- X entry in the archive, and DATA indicates where fiz found
- X file data in the archive. Filenames located by fiz are
- X enclosed in square brackets, and the notation "==> 95"
- X indicates that the directory entry found by fiz at position
- X 2526 has a file data pointer to position 95. In actuality,
- X fiz found file data at positions 2587, 3970, and 4769.
- X Since fiz found only two directory entries, and each direc-
- X tory entry corresponds to one file, one of the file data
- X positions is an artifact.
- X
- X
- X
- X
- X
- Printed 2/7/88 Jan 31, 1988 1
- X
- X
- X
- X
- X
- X
- FIZ(1) **IX Programmer's Manual FIZ(1)
- X
- X
- X
- X Once the locations of directory entries and file data are
- X found, the @ modifier to zoo's archive list and extract com-
- X mands can be used and the archive contents selectively
- X listed or extracted, skipping the damaged portion. This is
- X further described in the documentation for zoo(1).
- X
- X In the above case, commands to try giving to zoo might be
- X x@2526,2587 (extract beginning at position 2526, and get
- X file data from position 2587), x@3090,3970 (extract at 3090,
- X get data from 3970) and x@3909,4769 (extract at 3909, get
- X data from 4769). Once a correctly-matched directory
- X entry/file data pair is found, zoo will in most cases syn-
- X chronize with and correctly extract all files subsequently
- X found in the archive. Trial and error should allow all
- X undamaged files to be extracted. Also note that self-
- X extracting archives created using sez (the Self-Extracting
- X Zoo utility for MS-DOS), which are normally executed on an
- X MS-DOS system for extraction, can be extracted on non-MSDOS
- X systems in a similar way.
- X
- SEE ALSO
- X zoo(1)
- X
- BUGS
- X Random byte patterns can occasionally be incorrectly recog-
- X nized as tag values. This occurs very rarely, however, and
- X trial and error will usually permit all undamaged data to be
- X extracted.
- X
- DIAGNOSTICS
- X Fiz always exits with a status code of 0.
- X
- FUTURE DIRECTIONS
- X Automation of data recovery from a damaged archive is poten-
- X tially achievable. However, since damaged archives occur
- X only rarely, fiz as it currently stands is unlikely to
- X change much in the near future.
- X
- AUTHOR
- X Rahul Dhesi
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- Printed 2/7/88 Jan 31, 1988 2
- X
- X
- X
- SHAR_EOF
- chmod 0644 fiz.man ||
- echo 'restore of fiz.man failed'
- Wc_c="`wc -c < 'fiz.man'`"
- test 4227 -eq "$Wc_c" ||
- echo 'fiz.man: original size 4227, current size' "$Wc_c"
- fi
- true || echo 'restore of generic.c failed'
- echo End of part 2, continue with part 3
- exit 0
-