home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-07-11 | 35.3 KB | 1,102 lines |
- Newsgroups: alt.sources
- Subject: zoo 2.1 source part 15/15
- Message-ID: <12782@bsu-cs.bsu.edu>
- From: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
- Date: 10 Jul 91 12:05:22 GMT
-
- Checksum: 1510081511 (verify with "brik -cv")
- Submitted-by: dhesi@bsu-cs.bsu.edu
- Archive-name: zoo210/part15
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is part 15 of zoo210
- # ============= zoolist.c ==============
- if test -f 'zoolist.c' -a X"$1" != X"-c"; then
- echo 'x - skipping zoolist.c (File already exists)'
- else
- echo 'x - extracting zoolist.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'zoolist.c' &&
- #ifndef LINT
- /* derived from: zoolist.c 2.27 88/08/15 11:03:16 */
- static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zoolist.c,v $\n\
- $Id: zoolist.c,v 1.4 91/07/09 01:54:16 dhesi Exp $";
- #endif /* LINT */
- X
- /*
- If TRACE_LIST is defined, any list command may be followed
- by 'D' to show verbose information about each directory
- entry in the archive. Do not define both TRACE_LIST and
- TRACE_IO else a symbol conflict will occur and in any case
- duplicate information will be dumped.
- */
- X
- /* #define TRACE_LIST */
- X
- /*
- Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- (C) Copyright 1988 Rahul Dhesi -- All rights reserved
- */
- #include "options.h"
- #include "portable.h"
- #include "zoomem.h" /* to get ZOOCOUNT */
- X
- /* Lists files in archive */
- #include "zoo.h"
- #include "errors.i"
- #include "zooio.h"
- #include "various.h"
- #include "zoofns.h"
- X
- #ifdef TRACE_LIST
- void show_dir PARMS ((struct direntry *direntry));
- static int trace_list = 0;
- #endif /* TRACE_LIST */
- X
- static char tot_fmt[] = "%8lu %3u%% %8lu %4d file";
- static char tot_line[] =
- X /* "------------ -------- --- -------- --------- --------\n"; */
- X "-------- --- -------- --------- --------\n";
- X
- static char dbl_percent[] = "Archive %s: %s";
- X
- extern int quiet; /* assumed initialized to zero */
- X
- void show_comment PARMS((struct direntry *, ZOOFILE, int, char *));
- int ver_too_high PARMS((struct zoo_header *));
- int needed PARMS((char *, struct direntry *, struct zoo_header *));
- void printtz PARMS((int));
- X
- void zoolist (argv, option, argc)
- char **argv, *option;
- int argc;
- {
- char whichname[PATHSIZE]; /* which name to use */
- char *this_zoo; /* currently matched archive name */
- register ZOOFILE zoo_file;
- char *flist[ZOOCOUNT]; /* list of ptrs to input archive names */
- int fptr; /* will point to within list of archive names */
- X
- struct direntry direntry;
- struct zoo_header zoo_header;
- int size_factor;
- unsigned long tot_org_siz = 0L, tot_siz_now = 0L;
- int tot_sf;
- int file_count = 0;
- int del_count = 0; /* number of deleted entries */
- int bad_pack; /* 1 if packing method is unknown */
- static char *month_list="000JanFebMarAprMayJunJulAugSepOctNovDec";
- static char dashes[] = "------------\n";
- int year, month, day, hours, min, sec;
- int list_deleted = 0; /* list deleted files too */
- int fast = 0; /* fast list */
- long fiz_ofs = 0; /* offset where to start */
- long dat_ofs = 0; /* ... data offset of file data */
- int verb_list = 0; /* if verbose listing needed */
- int show_name = 0; /* if archive name to be included in listing */
- int show_crc = 0; /* if crc should be listed */
- int zoocount = 1; /* number of archives to list */
- int biglist = 0; /* multiarchive listing */
- int one_col = 0; /* one column listing requested */
- int showdir = 0; /* show directory name in fast listing */
- int longest; /* length of longest archive name */
- int talking; /* opposite of quiet */
- int column = 0; /* for column printing */
- int first_ever = 1; /* first time ever -- very special case */
- int neednl = 0; /* whether to print a newline */
- int need_acmt = 0; /* show archive comment */
- int show_gen = 0; /* show generation count */
- int genson = 1; /* enable/disable generations */
- #ifdef FATTR
- int show_mode = 0; /* show file protection */
- #endif
- int first_dir = 1; /* if first direntry -- to adjust dat_ofs */
- X
- while (*option) {
- X switch (*option) {
- X case 'a': show_name++; break;
- #ifdef TRACE_LIST
- X case 'D': trace_list++; break;
- #endif /* TRACE_LIST */
- X case 'd': list_deleted++; break;
- X case 'f': fast++; break;
- X case 'g': show_gen++; break;
- X case '/': showdir++; break;
- X case 'A':
- X case 'v': need_acmt++; break;
- X case 'V': need_acmt++; /* fall through */
- X case 'c': verb_list++; break;
- X case 'C': show_crc++; break;
- X case 'l': break;
- X case 'L': biglist++; zoocount = argc; break;
- #ifdef FATTR
- X case 'm': show_mode++; break;
- #endif
- X case '1': one_col++; break;
- X case '+': genson = 1; break;
- X case '-': genson = 0; break;
- X /* following code same as in zooext.c */
- X case '@': /* if @m,n specified, fiz_ofs = m, dat_ofs = n */
- X {
- X char *comma_pos;
- X ++option;
- X comma_pos = strchr(option, ',');
- X if (comma_pos != NULL) {
- X dat_ofs = calc_ofs (comma_pos + 1);
- X *comma_pos = '\0';
- X }
- X fiz_ofs = calc_ofs(option);
- X goto no_more;
- X }
- X case 'q': quiet++; break;
- X default:
- X prterror ('w', option_ignored, *option);
- X }
- X option++;
- }
- X
- no_more: /* come from exit from while loop above */
- X
- if (fast && show_name) { /* don't allow 'a' with 'f' */
- X show_name = 0;
- X prterror ('w', option_ignored, 'a');
- }
- X
- talking = !quiet; /* for convenience */
- X
- #ifdef WILDCARD
- X /* For each archive name supplied, if it is not a char range and
- X does not contain a dot, append "*.zoo". */
- X {
- X int i;
- X for (i = 0; i < argc; i++) {
- X if (strchr (nameptr (argv[i]), EXT_CH) == NULL &&
- X !match_half (nameptr (argv[0]), "?-?"))
- X argv[i] = newcat (argv[i], "*.zoo");
- X }
- X }
- #endif
- X
- makelist (zoocount, argv, flist, ZOOCOUNT-2, (char *) NULL,".","..", &longest);
- /* ^argc ^argv ^list_pointer ^max_no_files ^exclude */
- X
- for (fptr = 0; (this_zoo = flist[fptr]) != NULL; fptr++) {
- X int ercount; /* count of errors */
- X int entrycount; /* count of directory entries */
- X int expl_deleted; /* explain what D means */
- X int expl_comment; /* explain what comment means */
- X int expl_ver; /* Explain what V means */
- X int expl_star; /* Explain what * means */
- X int first_time; /* first time through loop for an archive */
- X
- X ercount = entrycount = del_count =
- X expl_deleted = expl_comment = expl_ver = expl_star = 0;
- X
- X if (talking)
- X column = 0; /* if quiet, names will run together */
- X
- X first_time = 1;
- X
- #ifndef WILDCARD
- X /* Add default extension if none supplied */
- X if (strchr (nameptr (this_zoo), EXT_CH) == NULL)
- X this_zoo = newcat (this_zoo, EXT_DFLT);
- #endif
- X
- X zoo_file = zooopen (this_zoo, Z_READ);
- X
- X if (zoo_file == NOFILE) {
- X prterror ('e', could_not_open, this_zoo);
- X continue;
- X } else if (!show_name && talking)
- X printf ("\nArchive %s:\n", this_zoo);
- X
- if (fiz_ofs != 0L) { /* if offset specified, start there */
- X prterror ('m', start_ofs, fiz_ofs, dat_ofs);
- X zooseek (zoo_file, fiz_ofs, 0);
- } else {
- X if (frd_zooh (&zoo_header, zoo_file) == -1 ||
- X zoo_header.zoo_tag != ZOO_TAG) {
- X prterror ('e', dbl_percent, this_zoo, invalid_header);
- X goto loop_end;
- X }
- #if 0
- X if (talking && (!show_name || verb_list || need_acmt))
- #else
- X if (need_acmt && talking)
- #endif
- X {
- X void show_acmt PARMS ((struct zoo_header *, ZOOFILE, int));
- X show_acmt (&zoo_header, zoo_file, 0); /* show archive comment */
- X }
- X
- X /* Seek to the beginning of the first directory entry */
- X if (zooseek (zoo_file, zoo_header.zoo_start, 0) != 0) {
- X ercount++;
- X prterror ('e', dbl_percent, this_zoo, bad_directory);
- X goto loop_end;
- X }
- X if (!show_name && ver_too_high (&zoo_header)) {
- X ercount++;
- X if (ercount < 2)
- X prterror ('M', wrong_version,
- X zoo_header.major_ver, zoo_header.minor_ver);
- X }
- } /* end if (fiz_ofs !- 0L) */
- X
- X /* Now we print information about each file in the archive */
- X
- X if (!show_name) { /* initialize for each file only if not disk catalog */
- X tot_org_siz = 0L;
- X tot_siz_now = 0L;
- X file_count = 0;
- X del_count = 0;
- X }
- X
- X while (1) {
- X if (readdir (&direntry, zoo_file, 0) == -1) {
- X prterror ('F', dbl_percent, this_zoo, bad_directory);
- X goto givesummary;
- X }
- X if (direntry.zoo_tag != ZOO_TAG) {
- X long currpos, zoolength;
- X prterror ('F', dbl_percent, this_zoo, invalid_header);
- X if ((currpos = zootell (zoo_file)) != -1L)
- X if (zooseek (zoo_file, 0L, 2) == 0)
- X if ((zoolength = zootell (zoo_file)) != -1L)
- X printf (cant_process, zoolength - currpos);
- X goto givesummary;
- X }
- X
- X if (direntry.next == 0L) /* EXIT on end of chain */
- X break;
- X else
- X entrycount++; /* Number of directory entries */
- X /* first direntry read, change dat_ofs from abs. pos. to rel. offset */
- X if (first_dir && dat_ofs != 0) {
- X dat_ofs -= direntry.offset;
- X first_dir = 0;
- X }
- X direntry.next += dat_ofs; /* allow for user-specified offset */
- X if (direntry.comment != 0L)
- X direntry.comment += dat_ofs; /* so show_comment finds it */
- X
- X if (direntry.deleted)
- X ++del_count;
- X
- #ifdef TRACE_LIST
- X if (trace_list)
- X show_dir (&direntry);
- #endif /* TRACE_LIST */
- X
- X /* Into `whichname' put the filename to display. Use long filename if
- X it exists, else use short filename. */
- X strcpy (whichname, fullpath (&direntry));
- X if (zoo_header.vdata & VFL_ON)
- X add_version (whichname, &direntry); /* add version suffix */
- #ifdef DEBUG
- X printf("matching against [%s] and [%s]\n",
- X nameptr(whichname), whichname);
- #endif
- X
- X if ( ( (list_deleted && direntry.deleted) ||
- X (list_deleted < 2 && !direntry.deleted)
- X )
- X && (biglist || needed(whichname, &direntry, &zoo_header))) {
- X /* if generations forced off, then strip added version field */
- X if (!genson) { /* HORRENDOUSLY INEFFICIENT AND REPETITIOUS */
- X char *ver_pos;
- X ver_pos = findlast (whichname, VER_DISPLAY);
- X if (ver_pos != NULL)
- X *ver_pos = '\0';
- X }
- X
- X file_count++;
- X
- X if (direntry.packing_method > MAX_PACK) {
- X bad_pack = 1;
- X expl_ver = 1;
- X } else
- X bad_pack = 0;
- X
- X size_factor = cfactor (direntry.org_size, direntry.size_now);
- X
- X year = ((unsigned int) direntry.date >> 9) & 0x7f;
- X month = ((unsigned int) direntry.date >> 5) & 0x0f;
- X day = direntry.date & 0x1f;
- X
- X hours = ((unsigned int) direntry.time >> 11)& 0x1f;
- X min = ((unsigned int) direntry.time >> 5) & 0x3f;
- X sec = ((unsigned int) direntry.time & 0x1f) * 2;
- X
- X /* Alignment in columns is a horrendously complex undertaking. */
- X
- X if (fast) {
- X int space_left;
- X int namelen;
- X int next_col;
- #if 0
- X if ( (quiet && !first_ever || !first_time) && one_col)
- X fputchar ('\n');
- X first_ever = 0;
- #endif
- X /* If we are showing directories, whichname already contains the
- X full pathname string. Else we only use the filename as follows:
- X long filename if possible, else short filename */
- X if (!showdir) {
- X strcpy (whichname,
- X (direntry.namlen != 0) ? direntry.lfname : direntry.fname);
- X if (genson && zoo_header.vdata & VFL_ON)
- X add_version (whichname, &direntry); /* add version suffix */
- X }
- X namelen = strlen (whichname);
- X
- #define MARGIN 78
- #define COL_WIDTH 16
- #if 1
- X /* if not enough space left, move to next line */
- X if (!one_col && column != 0) {
- X space_left = MARGIN - column;
- X if (namelen > space_left) {
- X neednl = 1;
- X column = 0;
- X }
- X }
- #endif
- X if ( (quiet && !first_ever || !first_time) && (neednl || one_col))
- X printf ("\n");
- X first_ever = 0;
- X neednl = 0;
- X
- X printf("%s", whichname);
- X fflush (stdout);
- X /* move to next column stop */
- X column += namelen;
- X next_col = ((column + (COL_WIDTH - 1)) / COL_WIDTH) * COL_WIDTH;
- X if (next_col - column < 2) /* need at least 2 spaces */
- X next_col += COL_WIDTH;
- X if (next_col > MARGIN) {
- X neednl = 1;
- X column = 0;
- X } else {
- X if (!one_col)
- X printf ("%*s", (next_col - column), " ");
- X column = next_col;
- X }
- X
- X } else {
- X if (talking && first_time && !show_name) {/*print archive header */
- X printf ("Length CF Size Now Date Time\n");
- X printf (tot_line);
- X }
- X printf ("%8lu %3u%% %8lu %2d %-.3s %02d %02d:%02d:%02d",
- X direntry.org_size,
- X size_factor, direntry.size_now,
- X day, &month_list[month*3],
- X (day && month) ? (year+80) % 100 : 0,
- X hours, min, sec);
- X tot_org_siz += direntry.org_size;
- X tot_siz_now += direntry.size_now;
- #ifdef GETTZ
- X printtz ((int) direntry.tz); /* show timezone */
- #else
- X printf (" ");
- #endif
- X
- X if (show_crc)
- X printf ("%04x ", direntry.file_crc);
- X if (show_gen) {
- X if (direntry.vflag & VFL_ON)
- X printf ("%2dg ", direntry.vflag & VFL_GEN);
- X else
- X printf ("--g ");
- X }
- X
- X if (direntry.cmt_size) {
- X expl_comment++;
- X printf ("C");
- X } else
- X printf (" ");
- X
- X if (direntry.deleted) {
- X expl_deleted++;
- X printf ("D");
- X } else
- X printf (" ");
- X if (list_deleted)
- X printf (" ");
- X if (show_name)
- X printf ("%-*s ", longest, this_zoo);
- X
- #ifdef FATTR
- X if (show_mode) {
- X if (direntry.fattr == 0)
- X printf ("--- ");
- X else if ((direntry.fattr >> 22) == 1)
- X printf ("%03o ", direntry.fattr & 0x1ff);
- X else
- X printf ("??? ");
- X }
- #endif /* FATTR */
- X
- X /* new code to get around a common compiler bug */
- X printf ("%s", whichname);
- X if (direntry.dir_crc != 0) {
- X expl_star++;
- X printf ("*");
- X }
- X
- X if (bad_pack)
- X printf (" (V%d.%d)", direntry.major_ver, direntry.minor_ver);
- X printf ("\n");
- X }
- X first_time = 0;
- X
- X /* if verbose listing requested show any comment. f overrrides v */
- X if (verb_list && !fast)
- X show_comment (&direntry, zoo_file, 0, (char *) NULL);
- X } /* end if (lots of conditions) */
- X
- X /* ..seek to next dir entry */
- X zooseek (zoo_file, direntry.next, 0);
- X } /* end while */
- X
- X givesummary:
- X
- X if (fast && talking) {
- X if (file_count) {
- X if (del_count || (show_gen && zoo_header.type > 0))
- X printf ("\n-----\n");
- X else
- X fputchar ('\n');
- X }
- X if (del_count)
- X printf ("%d deleted.\n", del_count);
- X if (show_gen && zoo_header.type > 0) {
- X printf ("Generation limit %u",
- X zoo_header.vdata & VFL_GEN);
- X if ((zoo_header.vdata & VFL_ON) == 0)
- X printf (" (off).\n");
- X else
- X printf (".\n");
- X }
- X } /* end if (fast && talking) */
- X
- X if (talking && !show_name) {
- X if (!fast && file_count) {
- X tot_sf = cfactor (tot_org_siz, tot_siz_now);
- X printf (tot_line);
- X
- X printf (tot_fmt, tot_org_siz, tot_sf, tot_siz_now, file_count);
- X if (file_count > 1)
- X printf ("s\n");
- X else
- X printf ("\n");
- X
- X if (del_count || expl_ver || expl_deleted || expl_comment ||
- X expl_star || (show_gen && (zoo_header.type > 0)))
- X printf (dashes);
- X }
- X
- X if (!fast) {
- X if (del_count) {
- X if (expl_deleted)
- X printf ("D: deleted file.\n");
- X else {
- X if (del_count == 1)
- X printf ("There is 1 deleted file.\n");
- X else
- X printf ("There are %d deleted files.\n", del_count);
- X }
- X }
- X }
- X if (expl_comment && !fast && !verb_list)
- X printf ("C: file has attached comment.\n");
- X if (expl_ver && !fast)
- X printf ("V: minimum version of Zoo needed to extract this file.\n");
- X if (expl_star && !fast)
- X printf ("*: directory entry may be corrupted.\n");
- X if (!file_count)
- X printf ("Zoo: %s", no_match);
- X
- X if (!entrycount && !fiz_ofs)
- X printf ("(The archive is empty.)\n");
- X if (show_gen && (zoo_header.type > 0) && !fast) {
- X printf ("Archive generation limit is %u",
- X zoo_header.vdata & VFL_GEN);
- X if ((zoo_header.vdata & VFL_ON) == 0)
- X printf (" (generations off).\n");
- X else
- X printf (".\n");
- X }
- X } /* end if (talking && !show_name) */
- loop_end: /* jump here on badly structured archive */
- X zooclose (zoo_file);
- } /* end for */
- X
- if (talking && show_name) {
- X if (file_count) {
- X tot_sf = cfactor (tot_org_siz, tot_siz_now);
- X printf (tot_line);
- X printf (tot_fmt, tot_org_siz, tot_sf, tot_siz_now, file_count);
- X if (file_count > 1)
- X printf ("s\n");
- X else
- X printf ("\n");
- X }
- } else if (fast && quiet)
- X fputchar ('\n');
- X
- X
- if (!file_count)
- X zooexit (1); /* Consider it an error if there were no files */
- } /* zoolist() */
- X
- #ifdef GETTZ
- void printtz (file_tz)
- int file_tz;
- {
- X long gettz();
- X int diff_tz; /* timezone difference */
- X if (file_tz == NO_TZ) /* if no timezone stored ..*/
- X printf (" "); /* .. just pad with blanks */
- X else {
- X diff_tz = (file_tz / 4) - (int) (gettz() / 3600);
- X if (diff_tz == 0)
- X printf (" "); /* print nothing if same */
- X else if (diff_tz > 0) /* else print signed difference */
- X printf ("+%1d ", diff_tz);
- X else
- X printf ("-%1d ", -diff_tz);
- X }
- }
- #endif
- X
- /*
- FOLLOWING CODE IS FOR DEBUGGING ONLY. IT IS COMPILED IN ONLY
- IF THE SYMBOL TRACE_LIST IS DEFINED
- */
- X
- #ifdef TRACE_LIST
- /* code copied from portable.c near end */
- /* dump contents of directory entry */
- void show_dir (direntry)
- struct direntry *direntry;
- {
- X printf ("Directory entry for file [%s][%s]:\n",
- X direntry->fname, direntry->lfname);
- X printf ("tag = [%8lx] type = [%d] PM = [%d] Next = [%8lx] Offset = [%8lx]\n",
- X direntry->zoo_tag, (int) direntry->type,
- X (int) direntry->packing_method, direntry->next,
- X direntry->offset);
- X printf ("Orig size = [%ld] Size now = [%ld] dmaj_v.dmin_v = [%d.%d]\n",
- X direntry->org_size, direntry->size_now,
- X (int) direntry->major_ver, (int) direntry->minor_ver);
- X printf ("Struc = [%d] DEL = [%d] comment_offset = [%8lx] cmt_size = [%d]\n",
- X (int) direntry->struc, (int) direntry->deleted, direntry->comment,
- X direntry->cmt_size);
- X printf ("var_dir_len = [%d] TZ = [%d] dir_crc = [%4x]\n",
- X direntry->var_dir_len, (int) direntry->tz, direntry->dir_crc);
- X printf ("system_id = [%d] dirlen = [%d] namlen = [%d] fattr=[%24lx]\n",
- X direntry->system_id, direntry->dirlen, direntry->namlen, direntry->fattr);
- X printf ("vflag = [%4x] version_no = [%4x]\n",
- X direntry->vflag, direntry->version_no);
- X if (direntry->dirlen > 0)
- X printf ("dirname = [%s]\n", direntry->dirname);
- X printf ("---------\n");
- }
- #endif /* TRACE_IO */
- SHAR_EOF
- chmod 0644 zoolist.c ||
- echo 'restore of zoolist.c failed'
- Wc_c="`wc -c < 'zoolist.c'`"
- test 18884 -eq "$Wc_c" ||
- echo 'zoolist.c: original size 18884, current size' "$Wc_c"
- fi
- # ============= zoomem.h ==============
- if test -f 'zoomem.h' -a X"$1" != X"-c"; then
- echo 'x - skipping zoomem.h (File already exists)'
- else
- echo 'x - extracting zoomem.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'zoomem.h' &&
- /* derived from: zoomem.h 2.1 87/12/25 12:26:18 */
- /* $Path$ */
- /* $Id: zoomem.h,v 1.3 91/07/09 01:43:06 dhesi Exp $ */
- X
- /*
- (C) Copyright 1991 Rahul Dhesi -- All rights reserved
- X
- Defines parameters used for memory allocation.
- */
- X
- /* ZOOCOUNT is the number of archive names that may be matched by the
- archive filespec specified for a list.
- X
- MAXADD is the number of filenames that may be added to an archive
- at one go. The total number of files that an archive may contain
- is not determined by MAXADD but is determined by available memory.
- */
- X
- #ifdef SMALL_MEM
- #define ZOOCOUNT (30)
- #define MAXADD (100)
- #endif
- X
- #ifdef MED_MEM
- #define ZOOCOUNT (50)
- #define MAXADD (200)
- #endif
- X
- #ifdef BIG_MEM
- #define ZOOCOUNT (400)
- #define MAXADD (4000)
- #endif
- X
- /* Customizable sizes */
- #ifdef SPEC_MEM
- #define ZOOCOUNT (100)
- #define MAXADD (400)
- #endif
- X
- extern char *out_buf_adr; /* global I/O buffer */
- X
- /*************************************************************/
- /* DO NOT CHANGE THE REST OF THIS FILE. */
- /*************************************************************/
- X
- /*
- The main I/O buffer (called in_buf_adr in zoo.c) is reused
- in several places.
- */
- X
- #define IN_BUF_SIZE 8192
- #define OUT_BUF_SIZE 8192
- X
- /* MEM_BLOCK_SIZE must be no less than (2 * DICSIZ + MAXMATCH)
- (see ar.h and lzh.h for values). The buffer of this size will
- also hold an input buffer of IN_BUF_SIZE and an output buffer
- of OUT_BUF_SIZE. FUDGE is a fudge factor, to keep some spare and
- avoid off-by-one errors. */
- X
- #define FUDGE 8
- #define MEM_BLOCK_SIZE (8192 + 8192 + 256 + 8)
- X
- SHAR_EOF
- chmod 0644 zoomem.h ||
- echo 'restore of zoomem.h failed'
- Wc_c="`wc -c < 'zoomem.h'`"
- test 1639 -eq "$Wc_c" ||
- echo 'zoomem.h: original size 1639, current size' "$Wc_c"
- fi
- # ============= zoopack.c ==============
- if test -f 'zoopack.c' -a X"$1" != X"-c"; then
- echo 'x - skipping zoopack.c (File already exists)'
- else
- echo 'x - extracting zoopack.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'zoopack.c' &&
- #ifndef LINT
- /* derived from: @(#) zoopack.c 2.16 88/08/22 15:51:20 */
- /*$Source: /usr/home/dhesi/zoo/RCS/zoopack.c,v $*/
- /*$Id: zoopack.c,v 1.5 91/07/09 01:54:17 dhesi Exp $*/
- static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zoopack.c,v $\n\
- $Id: zoopack.c,v 1.5 91/07/09 01:54:17 dhesi Exp $";
- #endif /* LINT */
- X
- /*
- Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- (C) Copyright 1988 Rahul Dhesi -- All rights reserved
- */
- #include "options.h"
- /* Packs an archive. The sequence is:
- X 1. Copy all files from current archive to new one.
- X 2. If the user didn't want a backup, delete the old archive
- X else rename it to same name with extension of .BAK.
- X 3. Rename temporary archive to old name.
- */
- X
- /* define this to make packing noisless */
- #define QUIETPACK 1
- X
- X
- #include "portable.h"
- #include "zooio.h"
- #include "various.h"
- #include "zoo.h"
- #include "zoofns.h"
- #include "errors.i"
- #ifndef NOSIGNAL
- #include <signal.h>
- #endif
- X
- char *mktemp PARMS((char *));
- X
- struct zoo_header zoo_header = {
- X TEXT,
- X ZOO_TAG,
- X (long) SIZ_ZOOH,
- X (long) (-SIZ_ZOOH),
- X MAJOR_VER,
- X MINOR_VER,
- X H_TYPE,
- X 0L, /* comment position */
- X 0, /* comment length */
- X GEN_DEFAULT /* generations */
- };
- char file_leader[] = FILE_LEADER;
- extern int quiet;
- int break_hit;
- X
- int ver_too_high PARMS((struct zoo_header *));
- X
- void zoopack(zoo_path, option)
- char *zoo_path, *option;
- {
- char temp_file[PATHSIZE];
- static char xes[]="XXXXXX"; /* template for temp file */
- X
- #ifndef NOSIGNAL
- T_SIGNAL (*oldsignal)();
- #endif
- register ZOOFILE zoo_file; /* archive */
- ZOOFILE new_file; /* destination archive */
- long next_ptr; /* pointer to within archive */
- long new_dir_pos; /* ditto */
- struct direntry direntry; /* directory entry */
- struct zoo_header old_zoo_header; /* just for reading old header */
- int status; /* error status */
- int nobackup = 0; /* keep backup */
- int force = 0; /* force overwrite of old backup */
- int extcount = 0; /* how many files moved */
- char backup_name[PATHSIZE]; /* name of backup */
- int bad_header = 0; /* if archive has bad header */
- int latest_date = 0; /* latest date on any file moved */
- int latest_time = 0; /* ...likewise */
- int curr_dir = 0; /* create backup in curr dir */
- static char partial_msg[] =
- X "Partially packed archive left in %s.\n";
- X
- #ifdef FATTR
- unsigned long zoofattr; /* zoo archive protection */
- int setfattr PARMS ((char *, unsigned long));
- unsigned long getfattr /* params below */
- # ifdef FATTR_FNAME
- X PARMS ((char *));
- # else
- X PARMS ((ZOOFILE));
- # endif /* FATTR_FNAME */
- #endif /* FATTR */
- X
- while (*option) {
- X switch (*option) {
- X case 'P': force++; break;
- X case 'E': nobackup++; break;
- X case 'q': quiet++; break;
- X case '.': curr_dir++; break;
- X default:
- X prterror ('f', inv_option, *option);
- X }
- X option++;
- }
- if (force == 1) /* force only if P was doubled */
- X force--;
- X
- zoo_path = addext (zoo_path, EXT_DFLT); /* add default extension */
- X
- /* Create a backup name by replacing any extension by backup extension. */
- strcpy (backup_name, zoo_path);
- {
- X char *temp;
- X if ((temp = strrchr (backup_name,EXT_CH)) != 0) /* if dot found */
- X strcpy (temp, BACKUP_EXT); /* replace old extension */
- X else
- X strcat (backup_name, BACKUP_EXT); /* else just append */
- }
- X
- /*
- Open original archive for read-write access. Although we will only
- read from it and never write to it, we want to avoid packing an
- archive that is read-only, since presumably the user didn't want
- to risk changing it in any way.
- */
- zoo_file = zooopen(zoo_path, Z_RDWR);
- X
- if (zoo_file == NOFILE)
- X prterror ('f', could_not_open, zoo_path);
- X
- /* If possible, save protection code of old archive for propagation to new */
- #ifdef FATTR
- # ifdef FATTR_FNAME
- X zoofattr = getfattr (zoo_path);
- # else
- X zoofattr = getfattr (zoo_file);
- # endif /* FATTR_FNAME */
- #endif /* FATTR */
- X
- /* Read the header of the old archive. */
- frd_zooh(&old_zoo_header, zoo_file);
- X
- if ((old_zoo_header.zoo_start + old_zoo_header.zoo_minus) != 0L) {
- X prterror ('w', failed_consistency);
- X ++bad_header; /* remember for future error message */
- }
- X
- /* Refuse to pack it if its version number is higher than we can accept */
- if (ver_too_high (&old_zoo_header))
- X prterror ('f', wrong_version, old_zoo_header.major_ver,
- X old_zoo_header.minor_ver);
- X
- /* Now see if the archive already exists with the backup extension. If so,
- X give an error message and abort. However, we skip this test if the user
- X specified overwriting the backup */
- X
- if (!force) {
- X if (exists (backup_name))
- X prterror ('f', "File %s already exists. Delete it or use PP option.\n",
- X backup_name);
- }
- X
- /*
- Open the new archive by a temporary name. If not otherwise specified,
- we open the new archive in the same directory as the original. But if
- the curr_dir switch was given, we just put XXXXXX into temp_file.
- */
- if (!curr_dir) {
- X strcpy (temp_file, zoo_path); /* original archive name */
- X *nameptr (temp_file) = '\0'; /* ... minus original filename */
- X strcat (temp_file, xes); /* ... plus XXXXXX */
- } else {
- X strcpy (temp_file, xes);
- }
- mktemp (temp_file); /* ... and make unique */
- new_file = zoocreate (temp_file);
- if (new_file == NOFILE)
- X prterror ('f', "Could not create temporary file %s.\n", temp_file);
- X
- /*
- If old_zoo_header greater than type 0, we update zoo_header as follows:
- new archive comment will be just after archive header; zoo_start will
- point to just beyond archive comment. But if old_zoo_header is of
- type 0, we leave zoo_header unchanged. However, we always
- unconditionally update the header type to be type H_TYPE.
- (Note: zoo_header.type is initialized to H_TYPE in the
- global declaration of zoo_header.)
- */
- if (old_zoo_header.type > 0) {
- X zoo_header.zoo_start = SIZ_ZOOH + old_zoo_header.acmt_len;
- X zoo_header.zoo_minus = -zoo_header.zoo_start;
- X zoo_header.acmt_pos = SIZ_ZOOH; /* new comment just after header */
- X zoo_header.acmt_len = old_zoo_header.acmt_len;
- X zoo_header.vdata = old_zoo_header.vdata;
- } else /* keep generations off if using old format archive */
- X zoo_header.vdata &= (~VFL_ON);
- X
- /* Write the header of the new archive, updated with our own data */
- fwr_zooh (&zoo_header, new_file);
- X
- /* copy archive comment */
- if (old_zoo_header.acmt_len != 0) {
- X zooseek (zoo_file, old_zoo_header.acmt_pos, 0); /* find archive comment */
- X getfile (zoo_file, new_file, (long) zoo_header.acmt_len, 0); /* copy it */
- }
- X
- /* WARNING: CHECK FOR SEEK BEYOND END OF FILE */
- zooseek (new_file, zoo_header.zoo_start, 0); /* position to add files */
- X
- zooseek (zoo_file, old_zoo_header.zoo_start, 0); /* seek to where data begins */
- X
- /* Now we loop through the old archive's files and add each to the new
- archive. The only changes needed are to update the .next and .offset
- fields of the directory entry. */
- X
- while (1) {
- X frd_dir(&direntry, zoo_file);
- X if (direntry.zoo_tag != ZOO_TAG) {
- X long currpos, zoolength;
- X prterror ('F', bad_directory);
- X if (bad_header) { /* bad headers means don't save temp file */
- X zooclose (new_file);
- X unlink (temp_file);
- X } else {
- X writenull (new_file, MAXDIRSIZE); /* write final null entry */
- X printf (partial_msg, temp_file);
- X if ((currpos = ftell (zoo_file)) != -1L)
- X if (zooseek (zoo_file, 0L, 2) == 0)
- X if ((zoolength = ftell (zoo_file)) != -1L)
- X printf (cant_process, zoolength - currpos);
- X }
- X zooexit (1);
- X }
- X if (direntry.next == 0L) { /* END OF CHAIN */
- X break; /* EXIT on end of chain */
- X }
- X next_ptr = direntry.next; /* ptr to next dir entry */
- X
- X if (!direntry.deleted) {
- #ifdef QUIETPACK
- /* nothing */
- #else
- X prterror ('m', "%-14s -- ",
- X direntry.namlen > 0 ? direntry.lfname : direntry.fname);
- #endif
- X
- X if (zooseek (zoo_file, direntry.offset, 0) == -1L) {
- X prterror ('f', "Could not seek to file data.\n");
- X } else {
- X extcount++; /* update count of files extracted */
- X
- X /* write a directory entry for this file */
- X new_dir_pos = zootell (new_file); /* new direntry pos in new archive */
- X
- X /*
- X Write a null directory entry to preserve integrity in case of
- X program being interrupted. Note: I don't think it is
- X necessary to save direntry.next but I haven't checked.
- X */
- X {
- X long oldnext;
- X oldnext = direntry.next;
- X direntry.next = 0L;
- X fwr_dir(&direntry, new_file);
- X direntry.next = oldnext;
- X }
- X
- X zooseek (zoo_file, direntry.offset, 0); /* where to start copying */
- X /* Write file leader and remember position of new file data */
- X (void) zoowrite (new_file, file_leader, SIZ_FLDR);
- X direntry.offset = zootell (new_file);
- X status = getfile (zoo_file, new_file, direntry.size_now, 0);
- X /* if no error copy any comment attached to file */
- X if (status == 0 && direntry.cmt_size != 0) {
- X zooseek (zoo_file, direntry.comment, 0); /* seek to old comment */
- X direntry.comment = zootell (new_file); /* location of new comment */
- X status = getfile (zoo_file, new_file,
- X (long) direntry.cmt_size, 0);
- X }
- X
- X if (status != 0) {
- X if (status == 1) {
- X memerr(0);
- X } else
- X if (status == 2 || status == 3) {
- X prterror ('F', disk_full);
- X printf (partial_msg, temp_file);
- X zooexit (1);
- X } else
- X prterror ('f', internal_error);
- X } else {
- X if (latest_date < direntry.date ||
- X (latest_date == direntry.date &&
- X latest_time < direntry.time)) {
- X latest_date = direntry.date;
- X latest_time = direntry.time;
- X }
- X }
- X direntry.next = zootell (new_file);
- X zooseek (new_file, new_dir_pos, 0); /* position to write direntry */
- X
- X break_hit = 0;
- #ifndef NOSIGNAL
- X oldsignal = signal (SIGINT, SIG_IGN);
- X if (oldsignal != SIG_IGN)
- X signal (SIGINT, handle_break);
- #endif
- X
- X /* Bug fix thanks to Mark Alexander */
- X if (fwr_dir (&direntry, new_file) != -1 &&
- X zoowrite (new_file, file_leader, SIZ_FLDR) == SIZ_FLDR) {
- #ifdef QUIETPACK
- X /* prterror ('M', "."); */ ;
- #else
- X prterror ('M', "moved\n");
- #endif
- X } else
- X prterror ('f', "Write to temporary packed archive %s failed.\n", temp_file);
- #ifndef NOSIGNAL
- X signal (SIGINT, oldsignal);
- #endif
- X if (break_hit)
- X zooexit (1);
- X zooseek (new_file, direntry.next, 0); /* back to end of new archive */
- X } /* end if (lseek ... */
- X } /* end if (!direntry.deleted) */
- X
- zooseek (zoo_file, next_ptr, 0); /* ..seek to next dir entry */
- } /* end while */
- X
- zooclose (zoo_file);
- X
- /* write a final null entry */
- writenull (new_file, MAXDIRSIZE);
- X
- #ifdef NIXTIME
- zooclose (new_file);
- setutime (temp_file, latest_date, latest_time);
- #else
- settime (new_file, latest_date, latest_time); /* adjust its time */
- zooclose (new_file);
- #endif
- X
- /* Important note: At this point, it is assumed that the archive was
- X packed and written to a new file without error. If control reaches
- X here without the new archive having been written properly, then
- X loss of data due to deletion of the original file could occur. In
- X other words, if something went wrong, execution MUST NOT reach here. */
- X
- if (extcount == 0) {
- X unlink (temp_file);
- X prterror ('m', "No files moved.\n");
- } else {
- X /* (a) if user requested, delete original, else rename it to
- X *.bak. (b) rename temp file to same base name as zoo_file. */
- X
- #ifdef QUIETPACK
- X /* prterror('M', "\n"); */
- #endif
- X
- X unlink (backup_name); /* remove any previous backup in any case */
- X if (nobackup)
- X unlink (zoo_path);
- X else
- X chname (backup_name, zoo_path);
- X
- X /* if we are packing into current directory, we will rename temp file
- X to same basename but without the preceding pathname */
- X if (curr_dir)
- X zoo_path = nameptr (zoo_path); /* strip pathname */
- X
- X
- X if (chname (zoo_path, temp_file)) {
- X prterror ('w', "Renaming error. Packed archive is now in %s.\n", temp_file);
- X zooexit (1);
- X }
- X
- /*
- Set protection on packed archive -- after renaming, since some
- OSs might not allow renaming of read-only files
- */
- #ifdef FATTR
- X setfattr (zoo_path, zoofattr);
- #endif /* FATTR */
- X
- } /* end if */
- X
- } /* end zoopack() */
- X
- /* handle_break() */
- /* Sets break_hit to 1 when called */
- T_SIGNAL handle_break()
- {
- #ifndef NOSIGNAL
- X signal (SIGINT, SIG_IGN); /* ignore future control ^Cs for now */
- X break_hit = 1;
- #endif
- }
- SHAR_EOF
- chmod 0644 zoopack.c ||
- echo 'restore of zoopack.c failed'
- Wc_c="`wc -c < 'zoopack.c'`"
- test 13324 -eq "$Wc_c" ||
- echo 'zoopack.c: original size 13324, current size' "$Wc_c"
- fi
- exit 0
-