From: dhesi@bsu-cs.bsu.edu (Rahul Dhesi) Newsgroups: alt.sources Subject: zoo 2.1 source part 07/15 Message-ID: <12774@bsu-cs.bsu.edu> Date: 10 Jul 91 10:04:21 GMT Checksum: 3482471535 (verify with "brik -cv") Submitted-by: dhesi@bsu-cs.bsu.edu Archive-name: zoo210/part07 ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is part 07 of zoo210 # ============= options.h ============== if test -f 'options.h' -a X"$1" != X"-c"; then echo 'x - skipping options.h (File already exists)' else echo 'x - extracting options.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'options.h' && /* @(#) options.h 2.22 88/08/24 15:27:36 */ X /* The contents of this file are hereby released to the public domain. X -- Rahul Dhesi 1991/07/06 X For documentation about this file, see options.doc. */ X #define ZOO /* always defined */ #define PORTABLE /* always defined */ #define ZOOCOMMENT /* always defined */ X X /***********************************************************************/ /* SYSTEM V (should be compatible with most releases) */ /***********************************************************************/ X #ifdef SYS_V #define FILTER #define IO_MACROS #define EXISTS(f) (access(f, 00) == 0) #define FNLIMIT 14 #define CHEKDIR #define NIXTIME #define NIXFNAME #define NEEDCTYP #define NOENUM #define REN_LINK #define SETBUF #define GETTZ #define FATTR #define T_SIGNAL void #define VARARGS #define NEED_MEMMOVE /* #define NEED_MEMCPY */ #define T_UINT16 unsigned short /* must be 16 bit unsigned */ #define HAVE_ISATTY /* #define NEED_VPRINTF */ #endif /* SYS_V */ X /***********************************************************************/ /* Turbo C++ 1.0 under MS-DOS */ /***********************************************************************/ X #ifdef TURBOC #undef PORTABLE #define ANSI_HDRS #define USE_ASCII #define SPECINIT #define SPECEXIT #define PURIFY #define DISK_CH ':' #define IGNORECASE #define WILDCARD "*.*" #define FOLD #define FORCESLASH #define FNLIMIT 12 #define CUR_DIR "." #define PATH_SEP ":/\\" #define EXT_SEP ":/\\." #define SETMODE /* 0x8000 and 0x4000 taken from for Turbo C */ #define MODE_BIN(f) setmode(fileno(f), 0x8000) #define MODE_TEXT(f) setmode(fileno(f), 0x4000) #define NEED_STDIO #define ANSI_PROTO #define VOIDPTR void * #define REN_STDC #define STDARG #define T_UINT16 unsigned short /* must be 16 bit unsigned */ /* #define UNBUF_IO */ /* #define UNBUF_LIMIT 512 */ #define T_SIGNAL void #define DIRECT_CONVERT #define STDARG #define CHECK_BREAK #define check_break kbhit #define HAVE_ISATTY #ifdef PORTABLE /* for testing only */ # define SPECNEXT # define NIXTIME # undef WILDCARD #endif #endif /* TURBOC */ X /***********************************************************************/ /* Older BSD 4.3 and most derivatives */ /***********************************************************************/ X #ifdef BSD4_3 #define NOSTRCHR /* not really needed for 4.3BSD */ #define FILTER #define IO_MACROS #define EXISTS(f) (access(f, 00) == 0) #define FNLIMIT 1023 #define CHEKDIR #define NIXTIME #define NIXFNAME #define NEEDCTYP #define NOENUM #define REN_STDC #define SETBUF #define GETTZ #define FATTR #define T_SIGNAL int #define VARARGS #define NEED_MEMMOVE #define T_UINT16 unsigned short /* must be 16 bit unsigned */ #define HAVE_ISATTY #define NEED_VPRINTF /* older BSDs only; newer ones have vprintf */ #endif /* BSD4_3 */ X /* Ultrix 4.1 */ #ifdef ULTRIX #define NO_STDIO_FN /* avoid declaring certain stdio functions */ #define NOSTRCHR /* needed? */ #define FILTER #define IO_MACROS #define EXISTS(f) (access(f, 00) == 0) #define FNLIMIT 1023 #define CHEKDIR #define NIXTIME #define NIXFNAME #define NEEDCTYP #define NOENUM #define REN_STDC #define SETBUF #define GETTZ #define FATTR #define T_SIGNAL void #define VARARGS #define NEED_MEMMOVE #define T_UINT16 unsigned short /* must be 16 bit unsigned */ #define HAVE_ISATTY /* #define NEED_VPRINTF */ #define BSD4_3 /* for I/O definitions */ #endif /* ULTRIX */ X /***********************************************************************/ /* Newer BSD 4.4 (projected) */ /***********************************************************************/ X #ifdef BSD4_4 /* #define NOSTRCHR */ #define FILTER #define IO_MACROS #define EXISTS(f) (access(f, 00) == 0) #define FNLIMIT 1023 #define CHEKDIR #define NIXTIME #define NIXFNAME #define NEEDCTYP /* #define NOENUM */ #define REN_STDC #define SETBUF #define GETTZ #define FATTR #define T_SIGNAL void /* #define VARARGS */ /* #define NEED_MEMMOVE */ #define T_UINT16 unsigned short /* must be 16 bit unsigned */ #define HAVE_ISATTY /* #define NEED_VPRINTF */ #endif /* BSD4_4 */ X /***********************************************************************/ /* VAX/VMS version 5.3 or so */ /***********************************************************************/ X #ifdef VMS X /* Select VMS pre-4.6 or later next line. Pre-4.6 library does not have rename() and memset() so zoo defines its own; 4.6 has these, so we must use them, else VMS library functions will conflict with our own. */ # if 0 /* Make this 1 for VMS version 4.5 or earlier */ # define NEED_VMS_RENAME /* used in vms.c */ # define NEED_MEMSET # endif #define REN_STDC #define IO_MACROS #define SPEC_WILD #define EXT_ANYWAY #define VER_CH ';' #define SPECEXIT #define CHEKUDIR #define FNLIMIT 78 #define DIR_SEP '.' /* separates dir fields */ #define DISK_CH ':' #define DIR_LBRACK "[" /* left bracketing symbol dir dir name */ #define PATH_CH "]" #define PATH_SEP ":]" #define EXT_SEP ":]." #define CUR_DIR "." #define NIXTIME #define NEEDCTYP #define NOENUM #define IGNORECASE #define SPECMOD #define SPECNEXT #define WILDCARD "*.*" #define FOLD #define NO_STDIO_FN #define T_SIGNAL void #define T_UINT16 unsigned short /* must be 16 bit unsigned */ #define VARARGS #endif /* VMS */ X /***********************************************************************/ /* AMIGA, SOME VERSION -- NOT TESTED, MAY NEED PORTING */ /***********************************************************************/ X #ifdef MCH_AMIGA #define PURIFY #define DISK_CH ':' #define SPECNEXT #define WILDCARD "*" #define IGNORECASE #define FNLIMIT 30 #define NEEDCTYP #define CUR_DIR "." #define PATH_SEP ":/" #define EXT_SEP ":/." #define NOSIGNAL #define REN_STDC #define NOENUM #define SETBUF #define CHEKUDIR #define GETUTIME #define NIXTIME #endif X /***********************************************************************/ /* GENERIC **IX SYSTEM -- GOOD STARTING POINT FOR YOURS */ /***********************************************************************/ X #ifdef GENERIC /* #define SPECNEXT */ /* #define IGNORECASE */ #define FNLIMIT 14 #define NEEDCTYP #define CUR_DIR "." #define PATH_SEP "/" #define EXT_SEP "/." /* #define NOSIGNAL */ /* REN_LINK is UNIX-specific. Can't find a generic rename() function */ #define REN_LINK #define NOENUM /* #define SETBUF */ #define CHEKDIR #define NIXTIME #define HAVE_ISATTY #define NEED_MEMMOVE #endif /* GENERIC */ X X /***********************************************************************/ /* REST OF THIS FILE SHOULD NOT NEED ANY CHANGES */ /***********************************************************************/ X /***********************************************************************/ /* Common filename conventions for **IX systems */ /***********************************************************************/ X #ifdef NIXFNAME #define CUR_DIR "." #define PATH_SEP "/" #define EXT_CH '.' #define EXT_SEP "/." #define EXT_DFLT ".zoo" #endif X /* Compensate for strchr/index differences */ #ifdef NOSTRCHR #define strchr index #define strrchr rindex #endif X /* let non-**IX lints under **IX work (see makefile) */ #ifdef CROSS_LINT # undef ANSI_HDRS # undef ANSI_PROTO # ifdef STDARG # undef STDARG # define VARARGS # endif /* STDARG */ #endif X /* assume certain defaults */ #ifndef VOIDPTR # define VOIDPTR char * #endif X #ifndef VER_DISPLAY # define VER_DISPLAY ";" #endif #ifndef VER_INPUT # define VER_INPUT ":;" #endif #ifndef PATH_CH # define PATH_CH "/" #endif #ifndef EXT_CH # define EXT_CH '.' #endif #ifndef EXT_DFLT # define EXT_DFLT ".zoo" #endif X #ifndef STDARG # ifndef VARARGS # define VARARGS # endif #endif X #ifndef T_SIGNAL # define T_SIGNAL int #endif X #ifdef STDARG # ifdef VARARGS # include "DO NOT DEFINE BOTH STDARG AND VARARGS" # endif #endif X /* We supply a default for T_UINT16 if it is not defined. But this value is critical, so we compile in a runtime check. */ X #ifndef T_UINT16 # define T_UINT16 unsigned short # define CHECK_TUINT /* will do runtime check for correct size */ #endif X /* ANSI compatibility in declarations -- see zoofns.h for usage */ #ifndef PARMS # ifdef ANSI_PROTO # define PARMS(x) x # else # define PARMS(x) () # endif #endif SHAR_EOF chmod 0644 options.h || echo 'restore of options.h failed' Wc_c="`wc -c < 'options.h'`" test 8466 -eq "$Wc_c" || echo 'options.h: original size 8466, current size' "$Wc_c" fi # ============= options.opt ============== if test -f 'options.opt' -a X"$1" != X"-c"; then echo 'x - skipping options.opt (File already exists)' else echo 'x - extracting options.opt (Text)' sed 's/^X//' << 'SHAR_EOF' > 'options.opt' && sys$share:vaxcrtl.exe/share SHAR_EOF chmod 0644 options.opt || echo 'restore of options.opt failed' Wc_c="`wc -c < 'options.opt'`" test 28 -eq "$Wc_c" || echo 'options.opt: original size 28, current size' "$Wc_c" fi # ============= parse.c ============== if test -f 'parse.c' -a X"$1" != X"-c"; then echo 'x - skipping parse.c (File already exists)' else echo 'x - extracting parse.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parse.c' && #ifndef LINT static char sccsid[]="@(#) parse.c 2.1 87/12/25 12:24:10"; #endif /* LINT */ X /* The contents of this file are hereby released to the public domain. X X -- Rahul Dhesi 1986/11/14 X */ X #include "options.h" #include "zoo.h" #include "zooio.h" #include "various.h" #include "zoofns.h" X #include "parse.h" #include "assert.h" X /* parse() accepts a filename and return its component parts in a structure. The component parts are: disk drive, path prefix, root name of filename, and extension. X If DISK_CH is not defined, it is assumed that filenames may be preceded with a disk prefix terminated by the character DISK_CH. The first character of the disk prefix, followed by DISK_CH, is returned in the drive field. X If the symbol DISK_CH is defined, a null string is returned in the disk field. */ void parse (path_st, fname) register struct path_st *path_st; char *fname; { X char tempname[LFNAMESIZE]; /* working copy of supplied fname */ X char *namep; /* points to relevant part of tempname */ X X char *p; X strcpy (tempname, fname); X #ifdef DEBUG printf ("parse: supplied name is [%s].\n", tempname); #endif X #ifndef DISK_CH X path_st->drive[0] = '\0'; X namep = tempname; /* points to pathname+filename */ #else X path_st->drive[0] = '\0'; X p = strchr (tempname, DISK_CH); /* point to first ':' */ X X if (p != NULL) { X path_st->drive[0] = *tempname;/* use only first char of drive name */ X path_st->drive[1] = DISK_CH; X path_st->drive[2] = '\0'; X namep = ++p; /* point to pathname+filename */ X } else { X path_st->drive[0] = '\0'; X namep = tempname; /* points to pathname+filename */ X } #endif /* end of not DISK_CH */ X X /* Note: findlast() finds last occurrence in the subject string of X any one of a set of chars */ X X /* save the long filename */ X p = findlast (namep, PATH_SEP); X X /* if path separator found, copy next char onwards; else entire string */ X strncpy (path_st->lfname, X (p != NULL) ? p+1 : namep, X LFNAMESIZE); X path_st->lfname[LFNAMESIZE-1] = '\0'; /* force null termination */ X #ifdef DEBUG printf ("parse: path = [%s] long filename = [%s]\n", X namep, path_st->lfname); #endif X /* Separate out the extension */ p = findlast (namep, EXT_SEP); /* look for . or / */ if (p != NULL && *p != EXT_CH) /* found .? */ X p = NULL; /* ... if not, ignore / */ X #ifdef DEBUG if (p == NULL) X printf ("parse: no extension found for [%s]\n", namep); else X printf ("parse: extension for [%s] is [%s]\n", namep, p); #endif X X path_st->ext[0] = '\0'; /* assume no extension */ X if (p != NULL) { /* found extension */ X strncpy (path_st->ext, (p+1), EXTLEN); /* save extension */ X path_st->ext[EXTLEN] = '\0'; /* force termination */ X *p = '\0'; /* null out extension */ X } X X /* separate out root of filename if any */ X p = findlast (namep, PATH_SEP); X X if (p != NULL) { X ++p; X strncpy (path_st->fname, p, ROOTSIZE); /* save filename */ X *p = '\0'; /* null out filename */ X } else { X strncpy (path_st->fname, namep, ROOTSIZE); X *namep = '\0'; /* null out filename */ X } X path_st->fname[ROOTSIZE] = '\0'; /* force termination */ X X /* what remains, whether null or not, is the path prefix */ X path_st->dir[0] = '\0'; /* in case *namep is '\0' */ X X strncpy (path_st->dir, namep, PATHSIZE); X X /* remove trailing path-separater from directory name, but don't X remove it if it is also the leading separater */ X { X int n; X n = strlen(path_st->dir); X if (n != 1) X path_st->dir[n-1] = '\0'; X } X #ifdef DEBUG printf ("parse: path prefix = [%s].\n", namep); #endif X /* if extension is null, and if long filename contains more than X ROOTSIZE characters, transfer some of them to extension */ X if (path_st->ext[0] == '\0' && strlen(path_st->lfname) > ROOTSIZE) { X strncpy(path_st->ext, &path_st->lfname[ROOTSIZE], EXTLEN); X path_st->ext[3] = '\0'; X } } X /*******************/ /* findlast() finds last occurrence in provided string of any of the characters except the null character in the provided set. X If found, return value is pointer to character found, else it is NULL. */ X char *findlast (str, set) register char *str; /* subject string */ char *set; /* set of characters to look for */ X { X register char *p; X X if (str == NULL || set == NULL || *str == '\0' || *set == '\0') X return (NULL); X X p = lastptr (str); /* pointer to last char of string */ X assert(p != NULL); X X while (p != str && strchr (set, *p) == NULL) { X --p; X } X X /* either p == str or we found a character or both */ X if (strchr (set, *p) == NULL) X return (NULL); X else X return (p); } X /*******************/ /* lastptr() returns a pointer to the last non-null character in the string, if any. If the string is null it returns NULL */ X char *lastptr (str) register char *str; /* string in which to find last char */ { X register char *p; X if (str == NULL) X prterror ('f', "lastptr: received null pointer\n"); X if (*str == '\0') X return (NULL); X p = str; X while (*p != '\0') /* find trailing null char */ X ++p; X --p; /* point to just before it */ X return (p); } SHAR_EOF chmod 0644 parse.c || echo 'restore of parse.c failed' Wc_c="`wc -c < 'parse.c'`" test 5640 -eq "$Wc_c" || echo 'parse.c: original size 5640, current size' "$Wc_c" fi # ============= parse.h ============== if test -f 'parse.h' -a X"$1" != X"-c"; then echo 'x - skipping parse.h (File already exists)' else echo 'x - extracting parse.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parse.h' && /* @(#) parse.h 2.1 87/12/25 12:24:15 */ X /* The contents of this file are hereby released to the public domain. X X -- Rahul Dhesi 1986/11/14 */ X /* defines structure used in call to parse() */ #define XTRA 2 /* extra space to avoid off-by-one errors */ X X struct path_st { X char drive[2+1+XTRA]; /* drive name */ X char dir[PATHSIZE+1+XTRA]; /* path prefix */ X char fname[8+1+XTRA]; /* root name of filename */ X char lfname[LFNAMESIZE+1+XTRA]; /* long filename */ X char ext[EXTLEN+1+XTRA]; /* extension */ }; X #ifdef LINT_ARGS void parse (struct path_st *, char *); #else void parse(); #endif SHAR_EOF chmod 0644 parse.h || echo 'restore of parse.h failed' Wc_c="`wc -c < 'parse.h'`" test 704 -eq "$Wc_c" || echo 'parse.h: original size 704, current size' "$Wc_c" fi # ============= portable.c ============== if test -f 'portable.c' -a X"$1" != X"-c"; then echo 'x - skipping portable.c (File already exists)' else echo 'x - extracting portable.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'portable.c' && #ifndef LINT /* @(#) portable.c 2.24 88/08/24 01:22:06 */ static char sccsid[]="@(#) portable.c 2.24 88/08/24 01:22:06"; #endif /* LINT */ X #include "options.h" /* Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved (C) Copyright 1988 Rahul Dhesi -- All rights reserved */ /********************** portable.c contains functions needed to make Zoo portable to various implementations of C. X Note: Provided a 2's complement machine is used, all functions in this file are themselves machine-independent and need not be changed when implementing Zoo on a different machine. Some code will choke on 1's complement machines--I think. X For machine-dependent declarations see files "machine.h" and "options.h". X For machine-dependent functions see file "machine.c" */ X #include "zoo.h" #include "zooio.h" X #include "various.h" #include "zoofns.h" X #include "machine.h" #include "debug.h" #include "assert.h" X #ifdef NEEDCTYP #include /* for tolower() */ #endif X #include "portable.h" X #ifdef TRACE_IO extern int verbose; #endif X /* Functions defined for use within this file only. */ long to_long PARMS((BYTE[])); int to_int PARMS((BYTE[])); void b_to_zooh PARMS((struct zoo_header *, BYTE[])); void b_to_dir PARMS((struct direntry *, BYTE[])); int dir_to_b PARMS((BYTE[], struct direntry *)); void zooh_to_b PARMS((BYTE[], struct zoo_header *)); void splitlong PARMS((BYTE[], long)); void splitint PARMS((BYTE[], int)); X #ifdef TRACE_IO void show_h PARMS ((struct zoo_header *)); void show_dir PARMS ((struct direntry *)); #endif /* TRACE_IO */ X extern unsigned int crccode; X /************************************************************************/ /* I/O functions */ /************************************************************************/ X /* some functions get defined only if they aren't already macros */ X #ifndef zooread int zooread (file, buffer, count) ZOOFILE file; char *buffer; int count; { return (fread (buffer, 1, count, file)); } #endif /* zooread */ X #ifndef FIZ #ifndef zoowrite int zoowrite (file, buffer, count) ZOOFILE file; char *buffer; int count; { X if (file == NULLFILE) X return (count); X else X return (fwrite (buffer, 1, count, file)); } #endif /* zoowrite */ X ZOOFILE zoocreate (fname) char *fname; { return ((ZOOFILE) fopen (fname, Z_NEW)); } X #endif /* FIZ */ X #ifndef zooseek long zooseek (file, offset, whence) ZOOFILE file; long offset; int whence; { return (fseek (file, offset, whence)); } #endif /* zooseek */ X ZOOFILE zooopen (fname, option) char *fname; char *option; { return ((ZOOFILE) fopen (fname, option)); } X #ifndef zootell long zootell (file) ZOOFILE file; { return ftell (file); } #endif /* zootell */ X int zooclose (file) ZOOFILE file; { return fclose (file); } X /********************** low_ch() is a macro that returns a lowercased char; it may be used with any char, whether or not it is uppercase. It will be used below by one or two functions. */ X #define low_ch(c) (isupper(c) ? tolower(c) : c) X /************************************************************************/ /*** Following are functions that make up for various implementations ***/ /*** of C not having certain library routines. ***/ /************************************************************************/ X #ifndef FIZ /********************** str_lwr() converts a string to lowercase and returns a pointer to the string */ char *str_lwr (str) char *str; { X register char *s; X s = str; X while (*s != '\0') { X *s = toascii(*s); X *s = low_ch(*s); X s++; X } X return (str); } X /********************** str_icmp() compares strings just like strcmp() but it does it without regard to case. */ int str_icmp (s1, s2) register char *s1, *s2; { X for ( ; low_ch(*s1) == low_ch(*s2); s1++, s2++) X if (*s1 == '\0') X return(0); X return(low_ch(*s1) - low_ch(*s2)); } X #ifdef NEED_MEMSET /********************** memset() it sets the first "count" bytes of "dest" to the character "c" and returns a pointer to "dest". */ VOIDPTR memset (dest, c, count) register VOIDPTR dest; int c; unsigned count; { X register unsigned i; X for (i = 0; i < count; i++) { X *((char *) (dest + i)) = c; X } X return dest; } #endif /* NEED_MEMSET */ X #ifdef NEED_MEMCPY /********************** memcpy() copies "count" bytes from "src" to "dest" and returns a pointer to "dest". Not necessarily safe for overlapping moves. */ X VOIDPTR memcpy(dest, src, count) register VOIDPTR dest; register VOIDPTR src; unsigned count; { X VOIDPTR savedest = dest; X while (count > 0) { X *((char *) dest++) = *((char *) src++); X count--; X } } #endif /* NEED_MEMCPY */ X #ifndef FPUTCHAR /********************** fputchar() writes a character to stdout. It is identical to putchar but is a function, not a macro. */ int fputchar (c) int c; { X return (fputc(c, stdout)); } #endif /* FPUTCHAR */ #endif /* FIZ */ X /***********************************************************************/ /*** Following are declarations and functions that are written in a ***/ /*** machine-independent way but they implement machine-dependent ***/ /*** activities ***/ /***********************************************************************/ X #ifndef DIRECT_CONVERT /********************** to_long() converts four consecutive bytes, in order of increasing significance, to a long integer. It is used to make Zoo independent of the byte order of the system. */ long to_long(data) BYTE data[]; { X return (long) ((unsigned long) data[0] | ((unsigned long) data[1] << 8) | X ((unsigned long) data[2] << 16) | ((unsigned long) data[3] << 24)); } X #ifndef FIZ /******************** splitlong() converts a long integer to four consecutive BYTEs in order of increasing significance. */ void splitlong(bytes, bigword) BYTE bytes[]; long bigword; { X int i; X for (i = 0; i < 4; i++) { X bytes[i] = bigword & 0xff; X bigword = (unsigned long) bigword >> 8; X } } #endif /* FIZ */ X /******************* splitint() converts an integer to two consecutive BYTEs in order of increasing significance. */ void splitint(bytes, word) BYTE bytes[]; int word; { X bytes[0] = word & 0xff; X word = (unsigned int) word >> 8; X bytes[1] = word & 0xff; } X /********************** to_int() converts two consecutive bytes, in order of increasing significance, to an integer, in a machine-independent manner */ int to_int(data) BYTE data[]; { X return (int) ((unsigned int) data[0] | ((unsigned int) data[1] << 8)); } X #else /* else of ifndef DIRECT_CONVERT */ X long to_long(data) BYTE data[]; { X return ( * (long *) data ); } X #ifndef FIZ /******************** splitlong() converts a long integer to four consecutive BYTEs in order of increasing significance. */ void splitlong(bytes, bigword) BYTE bytes[]; long bigword; { X * (long *) bytes = bigword; } #endif /* FIZ */ X /******************* splitint() converts an integer to two consecutive BYTEs in order of increasing significance. */ void splitint(bytes, word) BYTE bytes[]; int word; { X * (int *) bytes = word; } X /********************** to_int() converts two consecutive bytes, in order of increasing significance, to an integer. */ int to_int(data) BYTE data[]; { X return (*(int *) data); } X #endif /* ifndef DIRECT_CONVERT .. else ... */ X #ifndef FIZ /********************** Function frd_zooh() reads the header of a Zoo archive in a machine- independent manner, from a ZOOFILE. */ int frd_zooh(zoo_header, zoo_file) struct zoo_header *zoo_header; ZOOFILE zoo_file; { X int status; X BYTE bytes[SIZ_ZOOH]; /* canonical header representation */ #ifdef TRACE_IO X if (verbose) { X printf("At file position [%8lx] ", ftell(zoo_file)); X } #endif X status = zooread (zoo_file, (char *) bytes, SIZ_ZOOH); X b_to_zooh (zoo_header, bytes); /* convert array to structure */ #ifdef TRACE_IO X if (verbose) { X printf("frd_zooh: reading\n"); X show_h(zoo_header); X } #endif X if (status < MINZOOHSIZ) X return (-1); X else X return (0); } #endif /* FIZ */ X /********************** Function frd_dir() reads a directory entry in a machine-independent manner, from a ZOOFILE. */ int frd_dir(direntry, zoo_file) struct direntry *direntry; ZOOFILE zoo_file; { X int status; X BYTE bytes[MAXDIRSIZE]; /* big enough to hold variable part too */ X X /* To simplify things, we read the maximum possible size of the X directory entry including the variable size and discard what is not X needed */ #ifdef TRACE_IO X if (verbose) { X printf("At file position [%8lx] ", ftell(zoo_file)); X } #endif X status = zooread (zoo_file, (char *) bytes, MAXDIRSIZE); X if (status < SIZ_DIR) X return (-1); X b_to_dir (direntry, bytes); #ifdef TRACE_IO X if (verbose) { X printf("frd_dir: reading\n"); X show_dir(direntry); X } #endif X return (0); } X #ifndef FIZ /*********************** Function fwr_dir() writes a directory entry in a machine-independent manner to a ZOOFILE. Return value is -1 on error, else 0. */ int fwr_dir(direntry, zoo_file) struct direntry *direntry; ZOOFILE zoo_file; { X int size; X BYTE bytes[MAXDIRSIZE]; X assert (direntry->type <= 2); X size = dir_to_b (bytes, direntry); #ifdef TRACE_IO X if (verbose) { X printf("At file position [%8lx] ", ftell(zoo_file)); X printf("fwr_dir: writing\n"); X show_dir(direntry); X } #endif X X if (zoowrite (zoo_file, (char *) bytes, size) != size) X return (-1); X else X return (0); } X /*********************** Function fwr_zooh() writes an archive header in a machine-independent manner to a ZOOFILE. Return value is -1 if error else 0. */ int fwr_zooh(zoo_header, zoo_file) struct zoo_header *zoo_header; ZOOFILE zoo_file; { X BYTE bytes[SIZ_ZOOH]; /* was SIZ_DIR -- probably a typo */ X int hsize; /* how much to write -- depends on header type */ X hsize = MINZOOHSIZ; /* in case it's an old type 0 header */ X if (zoo_header->type > 0) /* but if it's a newer header... */ X hsize = SIZ_ZOOH; /* ...size of new type 1 header */ X zooh_to_b (bytes, zoo_header); X if (zoowrite (zoo_file, (char *) bytes, hsize) != hsize) X return (-1); X else X return (0); } X /*********************** b_to_zooh() converts an array of BYTE to a zoo_header structure. */ void b_to_zooh (zoo_header, bytes) struct zoo_header *zoo_header; BYTE bytes[]; { X int i; X for (i = 0; i < SIZ_TEXT; i++) /* copy text */ X zoo_header->text[i] = bytes[TEXT_I + i]; X zoo_header->zoo_tag = to_long(&bytes[ZTAG_I]); /* copy zoo_tag */ X zoo_header->zoo_start = to_long(&bytes[ZST_I]); /* copy zoo_start */ X zoo_header->zoo_minus = to_long(&bytes[ZSTM_I]); X zoo_header->major_ver = bytes[MAJV_I]; /* copy versions */ X zoo_header->minor_ver = bytes[MINV_I]; X /* default is no archive comment and a header type of 0 */ X zoo_header->type = 0; X zoo_header->acmt_pos = 0L; X zoo_header->acmt_len = 0; X zoo_header->vdata = 0; X if (zoo_header->zoo_start != FIXED_OFFSET) { /* if newer header */ X zoo_header->type = bytes[HTYPE_I]; X zoo_header->acmt_pos = to_long(&bytes[ACMTPOS_I]); X zoo_header->acmt_len = to_int(&bytes[ACMTLEN_I]); X zoo_header->vdata = bytes[HVDATA_I]; X } } X /*********************** zooh_to_b() converts a zoo_header structure to an array of BYTE. */ void zooh_to_b (bytes, zoo_header) struct zoo_header *zoo_header; BYTE bytes[]; { X int i; X for (i = 0; i < SIZ_TEXT; i++) /* copy text */ X bytes[TEXT_I + i] = zoo_header->text[i]; X splitlong (&bytes[ZTAG_I], zoo_header->zoo_tag); X splitlong (&bytes[ZST_I], zoo_header->zoo_start); X splitlong (&bytes[ZSTM_I], zoo_header->zoo_minus); X bytes[MAJV_I] = zoo_header->major_ver; /* copy versions */ X bytes[MINV_I] = zoo_header->minor_ver; X bytes[HTYPE_I] = zoo_header->type; /* header type */ X if (zoo_header->type > 0) { X splitlong (&bytes[ACMTPOS_I], zoo_header->acmt_pos); /* comment posn */ X splitint (&bytes[ACMTLEN_I], zoo_header->acmt_len); /* comment len */ X bytes[HVDATA_I] = zoo_header->vdata; /* version data */ X } } /* zooh_to_b() */ X /************************ dir_to_b() converts a directory entry structure to an array of BYTE. */ int dir_to_b (bytes, direntry) struct direntry *direntry; BYTE bytes[]; { X int i; X int cursize; X int fixsize; X int totalsize; X splitlong(&bytes[DTAG_I], direntry->zoo_tag); X bytes[DTYP_I] = direntry->type ; X bytes[PKM_I] = direntry->packing_method ; X splitlong(&bytes[NXT_I], direntry->next); X splitlong(&bytes[OFS_I], direntry->offset); X splitint(&bytes[DAT_I], direntry->date); X splitint(&bytes[TIM_I], direntry->time); X splitint(&bytes[CRC_I], direntry->file_crc); X splitlong(&bytes[ORGS_I], direntry->org_size); X splitlong(&bytes[SIZNOW_I], direntry->size_now); X bytes[DMAJ_I] = direntry->major_ver; X bytes[DMIN_I] = direntry->minor_ver; X bytes[DEL_I] = direntry->deleted; X bytes[STRUC_I] = direntry->struc; X splitlong(&bytes[CMT_I], direntry->comment); X splitint(&bytes[CMTSIZ_I], direntry->cmt_size); X for (i = 0; i < FNM_SIZ; i++) X bytes[FNAME_I + i] = direntry->fname[i]; X bytes[TZ_I] = NO_TZ; /* assume unknown */ X bytes[NAMLEN_I] = 0; X bytes[DIRLEN_I] = 0; X X cursize = SIZ_DIR; /* to count size of directory */ X fixsize = SIZ_DIR; /* size of fixed part */ X assert (direntry->type <= 2); X if (direntry->type == 2) { /* handle stuff relevant to type 2 */ X cursize = SIZ_DIRL; X fixsize = SIZ_DIRL; X bytes[TZ_I] = direntry->tz; X assert(direntry->namlen < 256 && direntry->namlen >= 0); X cursize += 2; /* space for namlen and dirlen */ X if (direntry->namlen != 0) { X bytes[NAMLEN_I] = direntry->namlen; X for (i = 0; i < direntry->namlen; i++) X bytes[LFNAME_I+i] = direntry->lfname[i]; X cursize += direntry->namlen; X } X assert(direntry->dirlen < 256 && direntry->dirlen >= 0); X if (direntry->dirlen != 0) { X bytes[DIRLEN_I] = direntry->dirlen; X for (i = 0; i < direntry->dirlen; i++) X bytes[cursize+i] = direntry->dirname[i]; X cursize += direntry->dirlen; X } X /* Can't store system id if no namlen & dirlen...BUG!...now fixed. X Fortunately, system_id was always 0 so far so it probably X got interpreted as namlen=0 and dirlen=0 (2 bytes) */ X splitint(&bytes[cursize], direntry->system_id); X cursize += 2; X bytes[cursize] = direntry->fattr & 0xff; /* byte 0 */ X splitint(&bytes[cursize+1], (int) (direntry->fattr >> 8)); /* 1 & 2 */ X cursize += 3; X bytes[cursize] = (direntry->vflag & 0xff); /* version flag */ X splitint(&bytes[cursize+1], direntry->version_no); /* version number */ X cursize += 3; X } X X splitint(&bytes[VARDIRLEN_I], direntry->var_dir_len); X assert(cursize == X ((bytes[DIRLEN_I] > 0 || bytes[NAMLEN_I] > 0) ? 2 : 0) + X fixsize + bytes[DIRLEN_I] + bytes[NAMLEN_I] X ); X X /* total size of dir entry is size of fixed part + size of var. part */ X totalsize = fixsize + direntry->var_dir_len; X X /* Do CRC assuming CRC field is zero, and stuff CRC into field. */ X splitint(&bytes[DCRC_I], 0); /* fill with zeroes */ X crccode = 0; X /* avoid mixing pointers to signed and unsigned char */ X addbfcrc((char *) bytes, totalsize); /* update CRC */ X splitint(&bytes[DCRC_I], crccode); X X /* return total length of directory entry */ X return (totalsize); X } /* dir_to_b() */ #endif /* FIZ */ X /* b_to_dir() converts bytes to directory entry structure. The CRC of the directory bytes, if any, is checked and a zero or nonzero value is returned in direntry->dir_crc according as the check is good or bad */ X void b_to_dir(direntry, bytes) struct direntry *direntry; BYTE bytes[]; { X int i; X int sysid_offs; /* temp variable */ X unsigned int savecrc; X direntry->zoo_tag = to_long(&bytes[DTAG_I]); X direntry->type = bytes[DTYP_I]; X direntry->packing_method = bytes[PKM_I]; X direntry->next = to_long(&bytes[NXT_I]); X direntry->offset = to_long(&bytes[OFS_I]); X direntry->date = to_int(&bytes[DAT_I]); X direntry->time = to_int(&bytes[TIM_I]); X direntry->file_crc = to_int(&bytes[CRC_I]); X direntry->org_size = to_long(&bytes[ORGS_I]); X direntry->size_now = to_long(&bytes[SIZNOW_I]); X direntry->major_ver = bytes[DMAJ_I]; X direntry->minor_ver = bytes[DMIN_I]; X direntry->deleted = bytes[DEL_I]; X direntry->struc = bytes[STRUC_I]; X direntry->comment = to_long(&bytes[CMT_I]); X direntry->cmt_size = to_int(&bytes[CMTSIZ_I]); X /* for now, versions not implemented */ X direntry->vflag = 0; X direntry->version_no = 0; X for (i = 0; i < FNM_SIZ; i++) X direntry->fname[i] = bytes[FNAME_I + i]; X X /* start by assuming variable part is zero bytes */ X direntry->var_dir_len = direntry->dir_crc = 0; X direntry->namlen = direntry->dirlen = 0; X direntry->lfname[0] = direntry->dirname[0] = '\0'; X direntry->tz = NO_TZ; /* assume unknown */ X direntry->system_id = SYSID_NIX; /* default system_id if not present */ X direntry->fattr = NO_FATTR; /* assume none */ X X assert (direntry->type <= 2); X if (direntry->type == 2) { X direntry->var_dir_len = to_int(&bytes[VARDIRLEN_I]); X assert(direntry->var_dir_len <= MAXDIRSIZE); X if (direntry->var_dir_len > MAXDIRSIZE) X direntry->var_dir_len = MAXDIRSIZE; X direntry->tz = bytes[TZ_I]; X if (direntry->var_dir_len > 0) X direntry->namlen = bytes[NAMLEN_I]; X if (direntry->var_dir_len > 1) X direntry->dirlen = bytes[DIRLEN_I]; X for (i = 0; i < direntry->namlen; i++) X direntry->lfname[i] = bytes[LFNAME_I + i]; X for (i = 0; i < direntry->dirlen; i++) X direntry->dirname[i] = bytes[DIRNAME_I + direntry->namlen + i]; X sysid_offs = DIRNAME_I + direntry->namlen + i; /* offset of system id */ X if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 2) { X direntry->system_id = to_int(&bytes[sysid_offs]); X } X if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 4) { X direntry->fattr = ((unsigned long) bytes[sysid_offs + 2]) | X ((unsigned long) bytes[sysid_offs + 3] << 8) | X ((unsigned long) bytes[sysid_offs + 4] << 16); X } X if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 7) { X direntry->vflag = bytes[sysid_offs + 5]; X direntry->version_no = to_int(&bytes[sysid_offs + 6]); X } X /* do CRC calculation */ X savecrc = (unsigned int) to_int(&bytes[DCRC_I]); X crccode = 0; X splitint(&bytes[DCRC_I], 0); X addbfcrc((char *) bytes, SIZ_DIRL + direntry->var_dir_len); X direntry->dir_crc = crccode - savecrc; X } } X #ifdef FILTER #define TWOBYTES 2 /* better than literal 2; figure out why */ X /* rdint() reads two bytes from standard input in archive order */ int rdint (val) unsigned int *val; { X BYTE bytes[TWOBYTES]; X if (zooread (STDIN, bytes, TWOBYTES) == TWOBYTES) { X *val = to_int(bytes); X return (0); X } else X return (1); } X /* wrint() writes an unsigned int to standard output in archive order */ int wrint (val) unsigned int val; { X BYTE bytes[TWOBYTES]; X splitint (bytes, val); X if (zoowrite (STDOUT, bytes, TWOBYTES) == TWOBYTES) X return (0); X else X return (1); } #endif /* FILTER */ X #ifdef TRACE_IO /* dump contents of archive header */ void show_h (zoo_header) struct zoo_header *zoo_header; { X int i; X printf ("Header text:\n"); X for (i = 0; i < SIZ_TEXT; i++) { /* ASSUMES ASCII TEXT */ X int c; X c = zoo_header->text[i]; X if (c >= ' ' && c < 0x7f) X putchar (c); X else { X putchar ('^'); X putchar (i & 0x40); X } X } X putchar('\n'); X printf ("zoo_tag = [%8lx] zoo_start = [%8lx] zoo_minus = [%8lx]\n", X zoo_header->zoo_tag, zoo_header->zoo_start, X zoo_header->zoo_minus); X printf ("major_ver.minor_ver = [%d.%d]\n", X zoo_header->major_ver, zoo_header->minor_ver); X if (zoo_header->zoo_start != FIXED_OFFSET) { X printf ("type = [%d] ", zoo_header->type); X printf ("acmt_pos = [%8lx] acmt_len = [%4x] vdata = [%2x]", X zoo_header->acmt_pos, zoo_header->acmt_len, zoo_header->vdata); X printf ("\n"); X } X printf ("---------\n"); } X /* 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 portable.c || echo 'restore of portable.c failed' Wc_c="`wc -c < 'portable.c'`" test 21613 -eq "$Wc_c" || echo 'portable.c: original size 21613, current size' "$Wc_c" fi # ============= portable.h ============== if test -f 'portable.h' -a X"$1" != X"-c"; then echo 'x - skipping portable.h (File already exists)' else echo 'x - extracting portable.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'portable.h' && /* @(#) portable.h 2.3 87/12/26 12:25:49 */ /* @(#) portable.h 2.4 88/08/24 00:56:43 */ X /* Definitions for portable I/O X The contents of this file are hereby released to the public domain. X X -- Rahul Dhesi 1986/11/14 X X X X DEFINITIONS IN THIS FILE X Symbols: X Z_WRITE, Z_READ, and Z_RDWR are the parameters to supply to zooopen() and to open an existing file for write, read, and read-write respectively. Z_NEW is the parameter to supply to zoocreate() to open an existing file or create a new file for write and read. The file must be opened in binary format, with no newline translation of any kind. X Macros or functions: X zgetc(x) reads a character from ZOOFILE x. zputc(c, f) writes a character to a ZOOFILE x. zputchar(c) writes a character c to standard output. MKDIR(x) creates a directory x. */ X /* Borland's Turbo C. */ #ifdef TURBOC /* options for zooopen(), zoocreate() */ #define Z_WRITE "r+b" #define Z_READ "rb" #define Z_RDWR "r+b" #define Z_NEW "w+b" #define zgetc(x) getc(x) #define zputc(c, f) putc(c, f) #define zputchar(c) putchar(c) #define MKDIR(x) mkdir(x) int mkdir PARMS((char *)); #endif X /* Microsoft C 3.0 */ #ifdef MSC /* options for zooopen(), zoocreate() */ #define Z_WRITE "r+b" #define Z_READ "rb" #define Z_RDWR "r+b" #define Z_NEW "w+b" #define zgetc(x) getc(x) #define zputc(c, f) putc(c, f) #define zputchar(c) putchar(c) #define MKDIR(x) mkdir(x) int mkdir (char *); #endif X #ifdef VMS #define Z_WRITE "r+" #define Z_READ "r" #define Z_RDWR "r+" #define Z_NEW "w+b" #define zgetc(x) getc(x) #define zputc(c, f) putc(c, f) #define zputchar(c) putchar(c) #define MKDIR(x) vmsmkdir (x, 0) #endif X #ifdef GENERIC /* **IX I/O, but MKDIR() is a no-operation */ #define NIX_IO /* standard **IX I/O */ #define MKDIR(x) #endif X /* **IX System V release 2.1 */ #ifdef SYS_V #define NIX_IO /* standard **IX I/O */ #define MKDIR(x) mkdir(x) /* define this in sysv.c */ #endif X /* Xenix */ #ifdef XENIX #define NIX_IO /* standard **IX I/O */ #endif X /* 4.3BSD */ #ifdef BSD4_3 #define NIX_IO /* standard **IX I/O */ #define MKDIR(x) mkdir(x, 0777) #endif X /* Amiga */ #ifdef MCH_AMIGA # include "MCH_AMIGA NEEDS REVISION" #endif X /* Standard **IX I/O definitions */ #ifdef NIX_IO /* options for zooopen(), zoocreate() */ #define Z_WRITE "r+" #define Z_READ "r" #define Z_RDWR "r+" #define Z_NEW "w+" #define zgetc(x) getc(x) #define zputc(c, f) putc(c, f) #define zputchar(c) putchar(c) #endif /* NIX_IO */ SHAR_EOF chmod 0644 portable.h || echo 'restore of portable.h failed' Wc_c="`wc -c < 'portable.h'`" test 2657 -eq "$Wc_c" || echo 'portable.h: original size 2657, current size' "$Wc_c" fi true || echo 'restore of prterror.c failed' echo End of part 7, continue with part 8 exit 0