[comp.sources.misc] v19i097: unzip - Portable unzip v4.1, Part02/06

kirsch@usasoc.soc.mil (David Kirschbaum) (05/20/91)

Submitted-by: David Kirschbaum <kirsch@usasoc.soc.mil>
Posting-number: Volume 19, Issue 97
Archive-name: unzip/part02
Supersedes: unzip-3.1: Volume 14, Issue 102-106

#! /bin/sh
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  ./v41/VMS/fjndef.h ./v41/unzip.c.2 ./v41/unzip.h
# Wrapped by kent@sparky on Sun May 19 19:40:39 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 2 (of 6)."'
if test -f './v41/VMS/fjndef.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./v41/VMS/fjndef.h'\"
else
  echo shar: Extracting \"'./v41/VMS/fjndef.h'\" \(684 characters\)
  sed "s/^X//" >'./v41/VMS/fjndef.h' <<'END_OF_FILE'
X/* This header file was created by Joe Meadows, and is not copyrighted
X   in any way. No guarantee is made as to the accuracy of the contents
X   of this header file. This header file was last modified on Sep. 22th,
X   1987. (Modified to include this statement) */
X
X#define FJN$M_ONLY_RU 1
X#define FJN$M_RUJNL 2
X#define FJN$M_BIJNL 4
X#define FJN$M_AIJNL 8
X#define FJN$M_ATJNL 16
X#define FJN$M_NEVER_RU 32
X#define FJN$M_JOURNAL_FILE 64
X#define FJN$S_FJNDEF 1
Xstruct fjndef  {
X  unsigned fjn$v_only_ru : 1;
X  unsigned fjn$v_rujnl : 1;
X  unsigned fjn$v_bijnl : 1;
X  unsigned fjn$v_aijnl : 1;
X  unsigned fjn$v_atjnl : 1;
X  unsigned fjn$v_never_ru : 1;
X  unsigned fjn$v_journal_file:1;
X} ;
END_OF_FILE
  if test 684 -ne `wc -c <'./v41/VMS/fjndef.h'`; then
    echo shar: \"'./v41/VMS/fjndef.h'\" unpacked with wrong size!
  fi
  # end of './v41/VMS/fjndef.h'
fi
if test -f './v41/unzip.c.2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./v41/unzip.c.2'\"
else
  echo shar: Extracting \"'./v41/unzip.c.2'\" \(22093 characters\)
  sed "s/^X//" >'./v41/unzip.c.2' <<'END_OF_FILE'
X    less the end-of-central-directory record was on this disk, and we would
X    not have gotten to this routine unless this is also the disk on which
X    the central directory starts.  In practice, this had better be the ONLY
X    disk in the archive, but maybe someday we'll add multi-disk support.
X  ---------------------------------------------------------------------------*/
X
X    members_remaining = ecrec.total_entries_central_dir;
X    while (members_remaining) {
X        j = 0;
X
X        /*
X         * Loop through files in central directory, storing offsets, file
X         * attributes, and case-conversion flags until block size is reached.
X         */
X
X        while (members_remaining && (j < DIR_BLKSIZ)) {
X            --members_remaining;
X
X            if (readbuf(sig, 4) <= 0) {
X                error_in_archive = 51;  /* 51:  unexpected EOF */
X                members_remaining = 0;  /* ...so no more left to do */
X                break;
X            }
X            if (strncmp(sig, CENTRAL_HDR_SIG, 4)) {  /* just to make sure */
X                fprintf(stderr, CentSigMsg, j);  /* sig not found */
X                fprintf(stderr, ReportMsg);   /* report to info-zip */
X                error_in_archive = 3;   /* 3:  error in zipfile */
X                members_remaining = 0;  /* ...so no more left to do */
X                break;
X            }
X            /* (sets lcflag)-------v  */
X            if ((error = process_central_file_header()) != 0) {
X                error_in_archive = error;   /* only 51 (EOF) defined */
X                members_remaining = 0;  /* ...so no more left to do */
X                break;
X            }
X            if ((error = do_string(crec.filename_length, FILENAME)) != 0) {
X                if (error > error_in_archive)
X                    error_in_archive = error;
X                if (error > 1) {  /* fatal:  no more left to do */
X                    fprintf(stderr, FilNamMsg, filename, "central");
X                    members_remaining = 0;
X                    break;
X                }
X            }
X            if ((error = do_string(crec.extra_field_length, SKIP)) != 0) {
X                if (error > error_in_archive)
X                    error_in_archive = error;
X                if (error > 1) {  /* fatal */
X                    fprintf(stderr, ExtFieldMsg, filename, "central");
X                    members_remaining = 0;
X                    break;
X                }
X            }
X            if ((error = do_string(crec.file_comment_length, SKIP)) != 0) {
X                if (error > error_in_archive)
X                    error_in_archive = error;
X                if (error > 1) {  /* fatal */
X                    fprintf(stderr, "\n%s:  bad file comment length\n",
X                            filename);
X                    members_remaining = 0;
X                    break;
X                }
X            }
X            if (process_all_files) {
X                if (crec.general_purpose_bit_flag & 1) {
X                    fprintf(stderr, CryptMsg, filename);  /* encrypted: skip */
X                    error_in_archive = 1;       /* 1:  warning error */
X                } else {
X                    ULONG tmp = ULONG_(crec.external_file_attributes);
X
X                    switch (hostnum) {
X                        case UNIX_:
X                          info[j].f_attr = tmp >> 16;
X                          break;
X                        case DOS_OS2_FAT_:
X                          tmp = (!(tmp & 1)) << 1;   /* read-only bit */
X                          info[j].f_attr = 0444 | tmp<<6 | tmp<<3 | tmp;
X#ifdef UNIX
X                          umask((int)(tmp = umask(0)));
X                          info[j].f_attr &= ~tmp;
X#endif
X                          break;
X                        case MAC_:
X                          tmp &= 1;   /* read-only bit */
X                          info[j].f_attr = tmp;
X                          break;
X                        default:
X                          info[j].f_attr = 0666;
X                          break;
X                    }
X                    info[j].lcflag = lcflag;
X                    info[j++].offset = (longint)
X                        ULONG_(crec.relative_offset_local_header);
X                }
X            } else {
X                fnamev = fnv;   /* don't destroy permanent filename pointer */
X                for (--fnamev; *++fnamev;)
X                    if (match(filename, *fnamev)) {
X                        if (crec.version_needed_to_extract[0] > UNZIP_VERSION) {
X                            fprintf(stderr, "%s:  requires compatibility with\
X version %u.%u to extract\n       (this handles %u.%u)--skipping.\n", filename,
X                                crec.version_needed_to_extract[0] / 10,
X                                crec.version_needed_to_extract[0] % 10,
X                                UNZIP_VERSION / 10, UNZIP_VERSION % 10);
X                            error_in_archive = 1;       /* 1:  warning error */
X                        } else if (crec.general_purpose_bit_flag & 1) {
X                            fprintf(stderr, CryptMsg, filename);  /* encrypt */
X                            error_in_archive = 1;       /* 1:  warning error */
X                        } else {
X                            ULONG tmp = ULONG_(crec.external_file_attributes);
X
X                            switch (hostnum) {
X                                case UNIX_:
X                                  info[j].f_attr = tmp >> 16;
X                                  break;
X                                case DOS_OS2_FAT_:
X                                  tmp = (!(tmp & 1)) << 1;  /* read-only bit */
X                                  info[j].f_attr = 0444 | tmp<<6 | tmp<<3 | tmp;
X#ifdef UNIX
X                                  umask((int)(tmp = umask(0)));
X                                  info[j].f_attr &= ~tmp;
X#endif
X                                  break;
X                                case MAC_:
X                                  tmp &= 1;   /* read-only bit */
X                                  info[j].f_attr = tmp;
X                                  break;
X                                default:
X                                  info[j].f_attr = 0666;
X                                  break;
X                            }
X                            info[j].lcflag = lcflag;
X                            info[j++].offset = (longint)
X                                ULONG_(crec.relative_offset_local_header);
X                        }
X                        break;  /* found match for filename, so stop looping */
X
X                    }   /* end if (match), for-loop (fnamev) */
X            }           /* end if (process_all_files) */
X        }               /* end while-loop (adding files to current block) */
X
X        /* save position in central directory so can come back later */
X        cd_bufstart = cur_zipfile_bufstart;
X        cd_inptr = inptr;
X        cd_incnt = incnt;
X
X        /*
X         * Loop through files in block, extracting or testing each one.
X         */
X
X        for (i = 0; i < j; ++i) {
X            /*
X             * if the target position is not within the current input buffer
X             * (either haven't yet read far enough, or (maybe) skipping back-
X             * ward) skip to the target position and reset readbuf().
X             */
X
X            /* LSEEK(info[i].offset):  */
X            inbuf_offset = info[i].offset % INBUFSIZ;
X            bufstart = info[i].offset - inbuf_offset;
X
X            if (bufstart != cur_zipfile_bufstart) {
X                cur_zipfile_bufstart = lseek(zipfd, bufstart, SEEK_SET);
X                if ((incnt = read(zipfd,inbuf,INBUFSIZ)) <= 0) {
X                    fprintf(stderr, OffsetMsg, filename, "lseek");
X                    error_in_archive = 3;   /* 3:  error in zipfile, but */
X                    continue;               /*  can still do next file   */
X                }
X                inptr = inbuf + inbuf_offset;
X                incnt -= inbuf_offset;
X            } else {
X                incnt += (inptr-inbuf) - inbuf_offset;
X                inptr = inbuf + inbuf_offset;
X            }
X            lcflag = info[i].lcflag;
X            f_attr = info[i].f_attr;
X
X            /* should be in proper position now, so check for sig */
X            if (readbuf(sig, 4) <= 0) {
X                fprintf(stderr, OffsetMsg, filename, "EOF");  /* bad offset */
X                error_in_archive = 3;   /* 3:  error in zipfile */
X                continue;       /* but can still do next one */
X            }
X            if (strncmp(sig, LOCAL_HDR_SIG, 4)) {
X                fprintf(stderr, OffsetMsg, filename,
X                        "can't find local header sig");   /* bad offset */
X                error_in_archive = 3;
X                continue;
X            }
X            if ((error = process_local_file_header()) != 0) {
X                fprintf(stderr, "\n%s:  bad local header\n", filename);
X                error_in_archive = error;       /* only 51 (EOF) defined */
X                continue;       /* can still do next one */
X            }
X            if ((error = do_string(lrec.filename_length, FILENAME)) != 0) {
X                if (error > error_in_archive)
X                    error_in_archive = error;
X                if (error > 1) {
X                    fprintf(stderr, FilNamMsg, filename, "local");
X                    continue;   /* go on to next one */
X                }
X            }
X            if ((error = do_string(lrec.extra_field_length, SKIP)) != 0) {
X                if (error > error_in_archive)
X                    error_in_archive = error;
X                if (error > 1) {
X                    fprintf(stderr, ExtFieldMsg, filename, "local");
X                    continue;   /* go on */
X                }
X            }
X            if ((error = extract_or_test_member()) != 0)
X                if (error > error_in_archive)
X                    error_in_archive = error;       /* ...and keep going */
X
X        }                       /* end for-loop (i:  files in current block) */
X
X        /*
X         * Jump back to where we were in the central directory, then go and do
X         * the next batch of files.
X         */
X
X        cur_zipfile_bufstart = lseek(zipfd, cd_bufstart, SEEK_SET);
X        read(zipfd, inbuf, INBUFSIZ);   /* were already there ==> no error */
X        inptr = cd_inptr;
X        incnt = cd_incnt;
X
X#ifdef TEST
X        printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
X        printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
X          cur_zipfile_bufstart);
X        printf("inptr-inbuf = %d\n", inptr-inbuf);
X        printf("incnt = %d\n\n", incnt);
X#endif
X
X    }           /* end while-loop (blocks of files in central directory) */
X
X/*---------------------------------------------------------------------------
X    Double check that we're back at the end-of-central-directory record, and
X    print quick summary of results, if we were just testing the archive.  We
X    send the summary to stdout so that people doing the testing in the back-
X    ground and redirecting to a file can just do a "tail" on the output file.
X  ---------------------------------------------------------------------------*/
X
X    readbuf(sig, 4);
X    if (strncmp(sig, END_CENTRAL_SIG, 4)) {     /* just to make sure again */
X        fprintf(stderr, EndSigMsg);  /* didn't find end-of-central-dir sig */
X        fprintf(stderr, ReportMsg);  /* report to info-zip */
X        if (!error_in_archive)       /* don't overwrite stronger error */
X            error_in_archive = 1;    /* 1:  warning error */
X    }
X    if (tflag && (quietflg == 1)) {
X        if (error_in_archive)
X            printf("At least one error was detected in the archive.\n");
X        else if (process_all_files)
X            printf("No errors detected.\n");
X        else
X            printf("No errors detected in the tested files.\n");
X    }
X    return (error_in_archive);
X
X}       /* end function extract_or_test_files() */
X
X
X
X
X
X/**************************************/
X/*  Function extract_or_test_member() */
X/**************************************/
X
Xint extract_or_test_member()
X/* return PK-type error code */
X{
X    int error = 0;
X    UWORD b;
X
X
X
X/*---------------------------------------------------------------------------
X    Initialize variables, buffers, etc.
X  ---------------------------------------------------------------------------*/
X
X    bits_left = 0;
X    bitbuf = 0;
X    outpos = 0L;
X    outcnt = 0;
X    outptr = outbuf;
X    zipeof = 0;
X    crc32val = 0xFFFFFFFFL;
X
X    memset(outbuf, 0, OUTBUFSIZ);
X    if (aflag)                  /* if we have a scratchpad, clear it out */
X        memset(outout, 0, OUTBUFSIZ);
X
X    if (tflag) {
X        if (!quietflg) {
X            fprintf(stdout, "  Testing: %-12s ", filename);
X            fflush(stdout);
X        }
X    } else {
X        if (cflag)              /* output to stdout (copy of it) */
X#ifdef MACOS
X            outfd = 1;
X#else
X            outfd = dup(1);
X#endif
X        else {
X            if ((error = mapped_name()) > 1)  /* member name conversion error */
X                return (2);     /* 2:  (weak) error in zipfile */
X            if (create_output_file())   /* output to file:  read/write perms */
X                return (50);    /* 50:  disk full */
X        }
X    }                           /* endif (!tflag) */
X
X/*---------------------------------------------------------------------------
X    Unpack the file.
X  ---------------------------------------------------------------------------*/
X
X    switch (lrec.compression_method) {
X
X    case STORED:
X        if (!tflag && QCOND) {
X            fprintf(stdout, " Extracting: %-12s ", filename);
X            if (cflag)
X                fprintf(stdout, "\n");
X            fflush(stdout);
X        }
X        while (ReadByte(&b))
X            OUTB(b);
X        break;
X
X    case SHRUNK:
X        if (!tflag && QCOND) {
X            fprintf(stdout, "UnShrinking: %-12s ", filename);
X            if (cflag)
X                fprintf(stdout, "\n");
X            fflush(stdout);
X        }
X        unShrink();
X        break;
X
X    case REDUCED1:
X    case REDUCED2:
X    case REDUCED3:
X    case REDUCED4:
X        if (!tflag && QCOND) {
X            fprintf(stdout, "  Expanding: %-12s ", filename);
X            if (cflag)
X                fprintf(stdout, "\n");
X            fflush(stdout);
X        }
X        unReduce();
X        break;
X
X    case IMPLODED:
X        if (!tflag && QCOND) {
X            fprintf(stdout, "  Exploding: %-12s ", filename);
X            if (cflag)
X                fprintf(stdout, "\n");
X            fflush(stdout);
X        }
X        unImplode();
X        break;
X
X    default:
X        fprintf(stderr, "%s:  unknown compression method\n", filename);
X        /* close and delete file before return?? */
X        return (1);             /* 1:  warning error */
X    }
X
X/*---------------------------------------------------------------------------
X    Write the last partial buffer, if any; set the file date and time; and
X    close the file (not necessarily in that order).  Then make sure CRC came
X    out OK and print result.  [Note:  crc32val must be logical-ANDed with
X    32 bits of 1's, or else machines whose longs are bigger than 32 bits will
X    report bad CRCs (because of the upper bits being filled with 1's instead
X    of 0's).]
X  ---------------------------------------------------------------------------*/
X
X    if (FlushOutput())
X        return (50);            /* 50:  disk full */
X
X    if (!tflag)
X#if defined(VMS) || defined(MTS)/* VMS already set file time; MTS can't */
X        close(outfd);
X#else
X        set_file_time_and_close();
X#endif
X
X    if ((crc32val = ((~crc32val) & 0xFFFFFFFFL)) != ULONG_(lrec.crc32)) {
X        /* if quietflg is set we haven't output the filename yet, do it */
X        if (quietflg)
X            printf("%-12s: ", filename);
X        fprintf(stdout, " Bad CRC %08lx  (should be %08lx)\n", crc32val,
X                ULONG_(lrec.crc32));
X        return (1);             /* 1:  warning error */
X    } else if (tflag) {
X        if (!quietflg)
X            fprintf(stdout, " OK\n");
X    } else {
X        if (QCOND)
X            fprintf(stdout, "\n");
X    }
X
X    return (error);
X
X}       /* end function extract_or_test_member() */
X
X
X
X
X
X/*******************************************/
X/*  Function process_central_file_header() */
X/*******************************************/
X
Xint process_central_file_header()
X/* return PK-type error code */
X{
X#ifdef NOTINT16
X    central_directory_byte_header byterec;
X#endif
X
X
X
X/*---------------------------------------------------------------------------
X    Read the next central directory entry and do any necessary machine-type
X    conversions (byte ordering, structure padding compensation--in the latter
X    case, copy the data from the array into which it was read (byterec) to
X    the usable struct (crec)).
X  ---------------------------------------------------------------------------*/
X
X#ifndef NOTINT16
X    if (readbuf((char *) &crec, CREC_SIZE) <= 0)
X        return (51);
X
X#else  /* NOTINT16 */
X    if (readbuf((char *) byterec, CREC_SIZE) <= 0)
X        return (51);            /* 51:  unexpected EOF */
X
X    crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
X    crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1];
X    crec.version_needed_to_extract[0] = byterec[C_VERSION_NEEDED_TO_EXTRACT_0];
X    crec.version_needed_to_extract[1] = byterec[C_VERSION_NEEDED_TO_EXTRACT_1];
X
X    crec.general_purpose_bit_flag =
X        makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
X    crec.compression_method =
X        makeword(&byterec[C_COMPRESSION_METHOD]);
X    crec.last_mod_file_time =
X        makeword(&byterec[C_LAST_MOD_FILE_TIME]);
X    crec.last_mod_file_date =
X        makeword(&byterec[C_LAST_MOD_FILE_DATE]);
X    crec.crc32 =
X        makelong(&byterec[C_CRC32]);
X    crec.compressed_size =
X        makelong(&byterec[C_COMPRESSED_SIZE]);
X    crec.uncompressed_size =
X        makelong(&byterec[C_UNCOMPRESSED_SIZE]);
X    crec.filename_length =
X        makeword(&byterec[C_FILENAME_LENGTH]);
X    crec.extra_field_length =
X        makeword(&byterec[C_EXTRA_FIELD_LENGTH]);
X    crec.file_comment_length =
X        makeword(&byterec[C_FILE_COMMENT_LENGTH]);
X    crec.disk_number_start =
X        makeword(&byterec[C_DISK_NUMBER_START]);
X    crec.internal_file_attributes =
X        makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]);
X    crec.external_file_attributes =
X        makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]); /* LONG, not word! */
X    crec.relative_offset_local_header =
X        makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]);
X#endif  /* NOTINT16 */
X
X    hostnum = min(crec.version_made_by[1], NUM_HOSTS);
X/*  extnum = min( crec.version_needed_to_extract[1], NUM_HOSTS ); */
X    methnum = min(crec.compression_method, NUM_METHODS);
X
X/*---------------------------------------------------------------------------
X    Set flag for lowercase conversion of filename, depending on which OS the
X    file is coming from.  This section could be ifdef'd if some people have
X    come to love DOS uppercase filenames under Unix...but really, guys, get
X    a life. :)  NOTE THAT ALL SYSTEM NAMES NOW HAVE TRAILING UNDERSCORES!!!
X    This is to prevent interference with compiler command-line defines such
X    as -DUNIX, for example, which are then used in "#ifdef UNIX" constructs.
X  ---------------------------------------------------------------------------*/
X
X    lcflag = FALSE;
X    if (!Uflag)                 /* as long as user hasn't specified
X                                 * case-preservation */
X        switch (hostnum) {
X        case DOS_OS2_FAT_:
X        case VMS_:
X        case VM_CMS_:           /* all caps? */
X        case CPM_:              /* like DOS, right? */
X/*      case ATARI_:            ??? */
X/*      case Z_SYSTEM_:         ??? */
X/*      case TOPS20_:           (if we had such a thing...) */
X
X            lcflag = TRUE;      /* convert filename to lowercase */
X            break;
X
X        default:                /* AMIGA_, UNIX_, (ATARI_), OS2_HPFS_, */
X            break;              /*   MAC_, (Z_SYSTEM_):  no conversion */
X        }
X
X    return (0);
X
X}       /* end function process_central_file_header() */
X
X
X
X
X
X/*****************************************/
X/*  Function process_local_file_header() */
X/*****************************************/
X
Xint process_local_file_header()
X/* return PK-type error code */
X{
X#ifdef NOTINT16
X    local_byte_header byterec;
X#endif
X
X
X
X/*---------------------------------------------------------------------------
X    Read the next local file header and do any necessary machine-type con-
X    versions (byte ordering, structure padding compensation--in the latter
X    case, copy the data from the array into which it was read (byterec) to
X    the usable struct (lrec)).
X  ---------------------------------------------------------------------------*/
X
X#ifndef NOTINT16
X    if (readbuf((char *) &lrec, LREC_SIZE) <= 0)
X        return (51);
X
X#else /* NOTINT16 */
X    if (readbuf((char *) byterec, LREC_SIZE) <= 0)
X        return (51);            /* 51:  unexpected EOF */
X
X    lrec.version_needed_to_extract[0] = byterec[L_VERSION_NEEDED_TO_EXTRACT_0];
X    lrec.version_needed_to_extract[1] = byterec[L_VERSION_NEEDED_TO_EXTRACT_1];
X
X    lrec.general_purpose_bit_flag = makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]);
X    lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]);
X    lrec.last_mod_file_time = makeword(&byterec[L_LAST_MOD_FILE_TIME]);
X    lrec.last_mod_file_date = makeword(&byterec[L_LAST_MOD_FILE_DATE]);
X    lrec.crc32 = makelong(&byterec[L_CRC32]);
X    lrec.compressed_size = makelong(&byterec[L_COMPRESSED_SIZE]);
X    lrec.uncompressed_size = makelong(&byterec[L_UNCOMPRESSED_SIZE]);
X    lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
X    lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
X#endif  /* NOTINT16 */
X
X    csize = (longint) ULONG_(lrec.compressed_size);
X    ucsize = (longint) ULONG_(lrec.uncompressed_size);
X
X    return (0);                 /* 0:  no error */
X
X}       /* end function process_local_file_header() */
END_OF_FILE
  if test 22093 -ne `wc -c <'./v41/unzip.c.2'`; then
    echo shar: \"'./v41/unzip.c.2'\" unpacked with wrong size!
  fi
  # end of './v41/unzip.c.2'
fi
if test -f './v41/unzip.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./v41/unzip.h'\"
else
  echo shar: Extracting \"'./v41/unzip.h'\" \(28924 characters\)
  sed "s/^X//" >'./v41/unzip.h' <<'END_OF_FILE'
X/*---------------------------------------------------------------------------
X
X  unzip.h
X
X  This header file is used by all of the unzip source files.  Its contents
X  are divided into six more-or-less separate sections:  OS-dependent includes,
X  (mostly) OS-independent defines, typedefs, function prototypes (or "proto-
X  types," in the case of non-ANSI compilers), macros, and global-variable
X  declarations.
X
X  ---------------------------------------------------------------------------*/
X
X
X
X/***************************/
X/*  OS-Dependent Includes  */
X/***************************/
X
X#include <stdio.h>       /* this is your standard header for all C compiles */
X#include <ctype.h>
X#include <errno.h>       /* used in mapped_name() */
X#define DECLARE_ERRNO    /* everybody except MSC 6.0 */
X#ifdef VMS               /* sigh...you just KNEW someone had to break this.  */
X#  include <types.h>     /*  (placed up here instead of in VMS section below */
X#  include <stat.h>      /*   because types.h is used in some other headers) */
X#else  /* almost everybody */
X#  if defined(THINK_C) || defined(MPW) /* for Macs */
X#    include <stddef.h>
X#  else
X#    include <sys/types.h> /* off_t, time_t, dev_t, ... */
X#    include <sys/stat.h>  /* Everybody seems to need this. */
X#  endif
X#endif                   /*   This include file defines
X                          *     #define S_IREAD 0x0100  (owner may read)
X                          *     #define S_IWRITE 0x0080 (owner may write)
X                          *   as used in the creat() standard function.  Must
X                          *   be included AFTER sys/types.h for most systems.
X                          */
X
X
X/*---------------------------------------------------------------------------
X    Next, a word from our Unix (mostly) sponsors:
X  ---------------------------------------------------------------------------*/
X
X#ifdef UNIX               /* On some systems sys/param.h partly duplicates   */
X#  include <sys/param.h>  /*  the contents of sys/types.h, so you don't need */
X                          /*  (and can't use) sys/types.h. (or param.h???)   */
X#  ifndef BSIZE
X#    define BSIZE   DEV_BSIZE   /* assume common for all Unix systems */
X#  endif
X
X#  ifndef BSD
X#    define NO_MKDIR            /* for mapped_name() */
X#    include <time.h>
X     struct tm *gmtime(), *localtime();
X#  else   /* BSD */
X#    include <sys/time.h>
X#    include <sys/timeb.h>
X#  endif
X
X#else   /* !UNIX */
X#  define BSIZE   512           /* disk block size */
X#endif
X
X#if defined(V7) || defined(BSD)
X#  define strchr    index
X#  define strrchr   rindex
X#endif
X
X/*---------------------------------------------------------------------------
X    And now, our MS-DOS and OS/2 corner:
X  ---------------------------------------------------------------------------*/
X
X#ifdef __TURBOC__
X#  define DOS_OS2             /* Turbo C under DOS, MSC under DOS or OS2    */
X#  include <sys/timeb.h>      /* for structure ftime                        */
X#  include <mem.h>            /* for memcpy()                               */
X#else                         /* NOT Turbo C...                             */
X#  ifdef MSDOS                /*   but still MS-DOS, so we'll assume it's   */
X#    ifndef MSC               /*   Microsoft's compiler and fake the ID, if */
X#      define MSC             /*   necessary (it is in 5.0; apparently not  */
X#    endif                    /*   in 5.1 and 6.0)                          */
X#    include <dos.h>          /* _dos_setftime()                            */
X#  endif
X#  ifdef OS2                  /* stuff for DOS and OS/2 family version */
X#    ifndef MSC
X#      define MSC
X#    endif
X#    include <os2.h>          /* DosQFileInfo(), DosSetFileInfo()? */
X#  endif
X#endif
X
X#ifdef MSC                    /* defined for all versions of MSC now         */
X#  define DOS_OS2             /* Turbo C under DOS, MSC under DOS or OS/2    */
X#  ifndef __STDC__            /* MSC 5.0 and 5.1 aren't truly ANSI-standard, */
X#    define __STDC__          /*   but they understand prototypes...so       */
X#  endif                      /*   they're close enough for our purposes     */
X#  if defined(_MSC_VER) && (_MSC_VER >= 600)      /* new with 5.1 or 6.0 ... */
X#    undef DECLARE_ERRNO      /* errno is now a function in a dynamic link   */
X#  endif                      /*   library (or something)--incompatible with */
X#endif                        /*   the usual "extern int errno" declaration  */
X
X#ifdef DOS_OS2                /* defined for both Turbo C, MSC */
X#  include <io.h>             /* lseek(), open(), setftime(), dup(), creat() */
X#endif
X
X/*---------------------------------------------------------------------------
X    Followed by some VMS (mostly) stuff:
X  ---------------------------------------------------------------------------*/
X
X#ifdef VMS
X#  include <time.h>             /* the usual non-BSD time functions */
X#  include <file.h>             /* same things as fcntl.h has */
X#  define UNIX                  /* can share most of same code from now on */
X#  define RETURN   return_VMS   /* VMS interprets return codes incorrectly */
X#else
X#  define RETURN   return       /* only used in main() */
X#  ifdef V7
X#    define O_RDONLY  0
X#    define O_WRONLY  1
X#    define O_RDWR    2
X#  else
X#    ifdef MTS
X#      include <sys/file.h>     /* MTS uses this instead of fcntl.h */
X#    else
X#      include <fcntl.h>
X#    endif
X#  endif
X#endif
X/*
X *   fcntl.h (above):   This include file defines
X *                        #define O_BINARY 0x8000  (no cr-lf translation)
X *                      as used in the open() standard function.
X */
X
X/*---------------------------------------------------------------------------
X    And some Mac stuff for good measure:
X  ---------------------------------------------------------------------------*/
X
X#ifdef THINK_C
X#  define MACOS
X#  define NOTINT16
X#  ifndef __STDC__            /* THINK_C isn't truly ANSI-standard, */
X#    define __STDC__          /*   but it understands prototypes...so */
X#  endif                      /*   it's close enough for our purposes */
X#  include <time.h>
X#  include <unix.h>
X#  include "macstat.h"
X#endif
X#ifdef MPW                    /* not tested yet - should be easy enough tho */
X#  define MACOS
X#  define NOTINT16
X#  include <time.h>
X#  include <fcntl.h>
X#  include "macstat.h"
X#endif
X
X/*---------------------------------------------------------------------------
X    And finally, some random extra stuff:
X  ---------------------------------------------------------------------------*/
X
X#ifdef __STDC__
X#  include <stdlib.h>      /* standard library prototypes, malloc(), etc. */
X#  include <string.h>      /* defines strcpy, strcmp, memcpy, etc. */
X#else
X   char *malloc();
X   char *strchr(), *strrchr();
X   long lseek();
X#endif
X
X
X
X
X
X/*************/
X/*  Defines  */
X/*************/
X
X#define INBUFSIZ          BUFSIZ   /* same as stdio uses */
X#define DIR_BLKSIZ        64       /* number of directory entries per block
X                                    *  (should fit in 4096 bytes, usually) */
X#define FILNAMSIZ         (1025)
X#ifdef MTS
X#  undef FILENAME_MAX              /* the MTS value is too low: use default */
X#endif
X#ifndef FILENAME_MAX               /* make sure FILENAME_MAX always exists  */
X#  define FILENAME_MAX    (FILNAMSIZ - 1)
X#endif
X#ifdef ZIPINFO
X#  define OUTBUFSIZ       BUFSIZ   /* zipinfo needs less than unzip does    */
X#else
X#  define OUTBUFSIZ       0x2000   /* unImplode needs power of 2, >= 0x2000 */
X#endif
X
X#define ZSUFX             ".zip"
X#define CENTRAL_HDR_SIG   "\120\113\001\002"   /* the infamous "PK" */
X#define LOCAL_HDR_SIG     "\120\113\003\004"   /*  signature bytes  */
X#define END_CENTRAL_SIG   "\120\113\005\006"
X
X#define SKIP              0    /* choice of activities for do_string() */
X#define DISPLAY           1
X#define FILENAME          2
X
X#define DOS_OS2_FAT_      0    /* version_made_by codes (central dir) */
X#define AMIGA_            1
X#define VMS_              2    /* MAKE SURE THESE ARE NOT DEFINED ON     */
X#define UNIX_             3    /* THE RESPECTIVE SYSTEMS!!  (Like, for   */
X#define VM_CMS_           4    /* instance, "UNIX":  CFLAGS = -O -DUNIX) */
X#define ATARI_            5
X#define OS2_HPFS_         6
X#define MAC_              7
X#define Z_SYSTEM_         8
X#define CPM_              9
X/* #define TOPS20_   10  (we're going to need this soon...)  */
X#define NUM_HOSTS         10   /* index of last system + 1 */
X
X#define STORED            0    /* compression methods */
X#define SHRUNK            1
X#define REDUCED1          2
X#define REDUCED2          3
X#define REDUCED3          4
X#define REDUCED4          5
X#define IMPLODED          6
X#define NUM_METHODS       7    /* index of last method + 1 */
X/* don't forget to update list_files() appropriately if NUM_METHODS changes */
X
X#ifndef MACOS
X#  define TRUE            1    /* sort of obvious */
X#  define FALSE           0
X#endif
X
X#define UNZIP_VERSION   11     /* compatible with PKUNZIP 1.1 */
X
X#ifndef UNZIP_OS               /* not used yet, but will need for Zip  */
X#  ifdef UNIX                  /* (could be defined in Makefile or...) */
X#    define UNZIP_OS    UNIX_
X#  endif
X#  ifdef DOS_OS2
X#    define UNZIP_OS    DOS_OS2_FAT_
X#  endif
X#  ifdef VMS
X#    define UNZIP_OS    VMS_
X#  endif
X#  ifdef MTS
X#    define UNZIP_OS    UNIX_
X#  endif
X#  ifdef MACOS
X#    define UNZIP_OS    MAC_
X#  endif
X#  ifndef UNZIP_OS             /* still not defined:  default setting */
X#    define UNZIP_OS    UNKNOWN
X#  endif
X#endif
X
X/*---------------------------------------------------------------------------
X    Macros for accessing the ULONG header fields.  When NOTINT16 is *not*
X    defined, these fields are allocated as arrays of char within the structs.
X    This prevents 32-bit compilers from padding the structs so that ULONGs
X    start on 4-byte boundaries (this will not work on machines that can ONLY
X    access ULONGs if they start on 4-byte boundaries).  If NOTINT16 *is*
X    defined, however, the original data are individually copied into working
X    structs consisting of UWORDs and ULONGs (which may therefore be padded
X    arbitrarily), so the ULONGs are accessed normally.
X  ---------------------------------------------------------------------------*/
X
X#ifdef NOTINT16
X#  define ULONG_(X)   X
X#else
X#  define ULONG_(X)   (*((ULONG *) (X)))
X#endif
X
X/*---------------------------------------------------------------------------
X    True sizes of the various headers, as defined by Phil Katz--so it is not
X    likely that these will ever change.  But if they do, make sure both these
X    defines AND the typedefs below get updated accordingly.
X  ---------------------------------------------------------------------------*/
X
X#define LREC_SIZE     26    /* lengths of local file headers, central */
X#define CREC_SIZE     42    /*  directory headers, and the end-of-    */
X#define ECREC_SIZE    18    /*  central-dir record, respectively      */
X
X
X#define MAX_BITS      13                 /* used in unShrink() */
X#define HSIZE         (1 << MAX_BITS)    /* size of global work area */
X
X#define LF   10   /* '\n' on ASCII machines.  Must be 10 due to EBCDIC */
X#define CR   13   /* '\r' on ASCII machines.  Must be 13 due to EBCDIC */
X
X#ifdef EBCDIC
X#  define ascii_to_native(c)   ebcdic[(c)]
X#endif
X
X#ifndef SEEK_SET        /* These should all be declared in stdio.h!  But   */
X#  define SEEK_SET  0   /*  since they're not (in many cases), do so here. */
X#  define SEEK_CUR  1
X#  define SEEK_END  2
X#endif
X
X
X
X
X
X/**************/
X/*  Typedefs  */
X/**************/
X
Xtypedef unsigned char    byte;       /* code assumes UNSIGNED bytes */
Xtypedef long             longint;
Xtypedef unsigned short   UWORD;
Xtypedef unsigned long    ULONG;
Xtypedef char             boolean;
X
X/*---------------------------------------------------------------------------
X    Zipfile layout declarations.  If these headers ever change, make sure the
X    ??REC_SIZE defines (above) change with them!
X  ---------------------------------------------------------------------------*/
X
X#ifdef NOTINT16
X
X   typedef byte   local_byte_header[ LREC_SIZE ];
X#      define L_VERSION_NEEDED_TO_EXTRACT_0     0
X#      define L_VERSION_NEEDED_TO_EXTRACT_1     1
X#      define L_GENERAL_PURPOSE_BIT_FLAG        2
X#      define L_COMPRESSION_METHOD              4
X#      define L_LAST_MOD_FILE_TIME              6
X#      define L_LAST_MOD_FILE_DATE              8
X#      define L_CRC32                           10
X#      define L_COMPRESSED_SIZE                 14
X#      define L_UNCOMPRESSED_SIZE               18
X#      define L_FILENAME_LENGTH                 22
X#      define L_EXTRA_FIELD_LENGTH              24
X
X   typedef byte   central_directory_byte_header[ CREC_SIZE ];
X#      define C_VERSION_MADE_BY_0               0
X#      define C_VERSION_MADE_BY_1               1
X#      define C_VERSION_NEEDED_TO_EXTRACT_0     2
X#      define C_VERSION_NEEDED_TO_EXTRACT_1     3
X#      define C_GENERAL_PURPOSE_BIT_FLAG        4
X#      define C_COMPRESSION_METHOD              6
X#      define C_LAST_MOD_FILE_TIME              8
X#      define C_LAST_MOD_FILE_DATE              10
X#      define C_CRC32                           12
X#      define C_COMPRESSED_SIZE                 16
X#      define C_UNCOMPRESSED_SIZE               20
X#      define C_FILENAME_LENGTH                 24
X#      define C_EXTRA_FIELD_LENGTH              26
X#      define C_FILE_COMMENT_LENGTH             28
X#      define C_DISK_NUMBER_START               30
X#      define C_INTERNAL_FILE_ATTRIBUTES        32
X#      define C_EXTERNAL_FILE_ATTRIBUTES        34
X#      define C_RELATIVE_OFFSET_LOCAL_HEADER    38
X
X   typedef byte   end_central_byte_record[ ECREC_SIZE+4 ];
X/*     define SIGNATURE                         0   space-holder only */
X#      define NUMBER_THIS_DISK                  4
X#      define NUM_DISK_WITH_START_CENTRAL_DIR   6
X#      define NUM_ENTRIES_CENTRL_DIR_THS_DISK   8
X#      define TOTAL_ENTRIES_CENTRAL_DIR         10
X#      define SIZE_CENTRAL_DIRECTORY            12
X#      define OFFSET_START_CENTRAL_DIRECTORY    16
X#      define ZIPFILE_COMMENT_LENGTH            20
X
X
X   typedef struct local_file_header {                 /* LOCAL */
X       byte version_needed_to_extract[2];
X       UWORD general_purpose_bit_flag;
X       UWORD compression_method;
X       UWORD last_mod_file_time;
X       UWORD last_mod_file_date;
X       ULONG crc32;
X       ULONG compressed_size;
X       ULONG uncompressed_size;
X       UWORD filename_length;
X       UWORD extra_field_length;
X   } local_file_header;
X
X   typedef struct central_directory_file_header {     /* CENTRAL */
X       byte version_made_by[2];
X       byte version_needed_to_extract[2];
X       UWORD general_purpose_bit_flag;
X       UWORD compression_method;
X       UWORD last_mod_file_time;
X       UWORD last_mod_file_date;
X       ULONG crc32;
X       ULONG compressed_size;
X       ULONG uncompressed_size;
X       UWORD filename_length;
X       UWORD extra_field_length;
X       UWORD file_comment_length;
X       UWORD disk_number_start;
X       UWORD internal_file_attributes;
X       ULONG external_file_attributes;
X       ULONG relative_offset_local_header;
X   } central_directory_file_header;
X
X   typedef struct end_central_dir_record {            /* END CENTRAL */
X       UWORD number_this_disk;
X       UWORD num_disk_with_start_central_dir;
X       UWORD num_entries_centrl_dir_ths_disk;
X       UWORD total_entries_central_dir;
X       ULONG size_central_directory;
X       ULONG offset_start_central_directory;
X       UWORD zipfile_comment_length;
X   } end_central_dir_record;
X
X
X#else   /* !NOTINT16:  read data directly into the structure we'll be using */
X
X
X   typedef struct local_file_header {                 /* LOCAL */
X       byte version_needed_to_extract[2];
X       UWORD general_purpose_bit_flag;
X       UWORD compression_method;
X       UWORD last_mod_file_time;
X       UWORD last_mod_file_date;
X       byte crc32[4];
X       byte compressed_size[4];
X       byte uncompressed_size[4];
X       UWORD filename_length;
X       UWORD extra_field_length;
X   } local_file_header;
X
X   typedef struct central_directory_file_header {     /* CENTRAL */
X       byte version_made_by[2];
X       byte version_needed_to_extract[2];
X       UWORD general_purpose_bit_flag;
X       UWORD compression_method;
X       UWORD last_mod_file_time;
X       UWORD last_mod_file_date;
X       byte crc32[4];
X       byte compressed_size[4];
X       byte uncompressed_size[4];
X       UWORD filename_length;
X       UWORD extra_field_length;
X       UWORD file_comment_length;
X       UWORD disk_number_start;
X       UWORD internal_file_attributes;
X       byte external_file_attributes[4];
X       byte relative_offset_local_header[4];
X   } central_directory_file_header;
X
X   typedef struct end_central_dir_record {            /* END CENTRAL */
X       byte _sig_[4];  /* space-holder only */
X       UWORD number_this_disk;
X       UWORD num_disk_with_start_central_dir;
X       UWORD num_entries_centrl_dir_ths_disk;
X       UWORD total_entries_central_dir;
X       byte size_central_directory[4];
X       byte offset_start_central_directory[4];
X       UWORD zipfile_comment_length;
X   } end_central_dir_record;
X
X#endif  /* !NOTINT16 */
X
X
X
X
X
X/*************************/
X/*  Function Prototypes  */
X/*************************/
X
X#ifndef __              /* This amusing little construct was swiped without  */
X#  ifdef __STDC__       /*  permission from the fine folks at Cray Research, */
X#    define __(X)   X   /*  Inc.  Should probably give them a call and see   */
X#  else                 /*  if they mind, but....  Then again, I can't think */
X#    define __(X)   ()  /*  of any other way to do this, so maybe it's an    */
X#  endif                /*  algorithm?  Whatever, thanks to CRI.  (Note:     */
X#endif                  /*  keep interior stuff parenthesized.)              */
X/*
X * Toad Hall Note:  Not to worry:  I've seen this somewhere else too,
X * so obviously it's been stolen more than once.
X * That makes it public domain, right?
X */
X
X/*---------------------------------------------------------------------------
X    Functions in nunzip.c:
X  ---------------------------------------------------------------------------*/
X
Xvoid   usage                         __( (void) );
Xint    process_zipfile               __( (void) );
Xint    find_end_central_dir          __( (void) );
Xint    process_end_central_dir       __( (void) );
Xint    list_files                    __( (void) );
Xint    extract_or_test_files         __( (void) );
Xint    extract_or_test_member        __( (void) );
Xint    process_central_file_header   __( (void) );
Xint    process_local_file_header     __( (void) );
X
X/*---------------------------------------------------------------------------
X    Functions in file_io.c:
X  ---------------------------------------------------------------------------*/
X
Xint    change_zipfile_attributes __( (int zip_error) );
Xint    open_input_file           __( (void) );
Xint    readbuf                   __( (char *buf, register unsigned size) );
Xint    create_output_file        __( (void) );
Xint    FillBitBuffer             __( (register int bits) );
Xint    ReadByte                  __( (UWORD *x) );
Xint    FlushOutput               __( (void) );
X/*
X * static int   WriteBuffer       __( (int fd, unsigned char *buf, int len) );
X * static int   dos2unix          __( (unsigned char *buf, int len) );
X */
Xvoid   set_file_time_and_close   __( (void) );
X
X/*---------------------------------------------------------------------------
X    Macintosh file_io functions:
X  ---------------------------------------------------------------------------*/
X
X#ifdef MACOS
Xvoid   macfstest                 __( (int vrefnum, int wd) );
X/*
X * static int   IsHFSDisk        __( (int wAppVRefNum) );
X */
Xint    mkdir                     __( (char *path, int mode) );
Xvoid   SetMacVol                 __( (char *pch, short wVRefNum) );
X#endif
X
X/*---------------------------------------------------------------------------
X    Uncompression functions (all internal compression routines, enclosed in
X    comments below, are prototyped in their respective files and are invisi-
X    ble to external functions):
X  ---------------------------------------------------------------------------*/
X
Xvoid   unImplode                __( (void) );                  /* unimplod.c */
X/*
X * static void   ReadLengths     __( (sf_tree *tree) );
X * static void   SortLengths     __( (sf_tree *tree) );
X * static void   GenerateTrees   __( (sf_tree *tree, sf_node *nodes) );
X * static void   LoadTree        __( (sf_tree *tree, int treesize, sf_node *nodes) );
X * static void   LoadTrees       __( (void) );
X * static void   ReadTree        __( (register sf_node *nodes, int *dest) );
X */
X
Xvoid   unReduce                 __( (void) );                  /* unreduce.c */
X/*
X * static void   LoadFollowers   __( (void) );
X */
X
Xvoid   unShrink                 __( (void) );                  /* unshrink.c */
X/*
X * static void   partial_clear   __( (void) );
X */
X
X/*---------------------------------------------------------------------------
X    Functions in match.c, mapname.c, and misc.c:
X  ---------------------------------------------------------------------------*/
X
Xint       match         __( (char *string, char *pattern) );      /* match.c */
X/*
X * static BOOLEAN   do_list      __( (register char *string, char *pattern) );
X * static void      list_parse   __( (char **patp, char *lowp, char *highp) );
X * static char      nextch       __( (char **patp) );
X */
X
Xint       mapped_name   __( (void) );                           /* mapname.c */
X
Xvoid      UpdateCRC     __( (register unsigned char *s, register int len) );
Xint       do_string     __( (unsigned int len, int option) );      /* misc.c */
XUWORD     makeword      __( (byte *b) );                           /* misc.c */
XULONG     makelong      __( (byte *sig) );                         /* misc.c */
Xvoid      return_VMS    __( (int zip_error) );                     /* misc.c */
X#ifdef ZMEM
X   char   *memset       __( (register char *buf, register char init, register unsigned int len) );
X   char   *memcpy       __( (register char *dst, register char *src, register unsigned int len) );
X#endif      /* These guys MUST be ifdef'd because their definition  */
X            /*  conflicts with the standard one.  Others (makeword, */
X            /*  makelong, return_VMS) don't matter.                 */
X
X
X
X
X
X/************/
X/*  Macros  */
X/************/
X
X#ifndef min    /* MSC defines this in stdlib.h */
X#  define min(a,b)   ((a) < (b) ? (a) : (b))
X#endif
X
X
X#define LSEEK(abs_offset) {longint request=(abs_offset), inbuf_offset=request%INBUFSIZ, bufstart=request-inbuf_offset;\
X   if(bufstart!=cur_zipfile_bufstart) {cur_zipfile_bufstart=lseek(zipfd,bufstart,SEEK_SET);\
X   if((incnt=read(zipfd,inbuf,INBUFSIZ))<=0) return(51); inptr=inbuf+inbuf_offset; incnt-=inbuf_offset;\
X   }else {incnt+=(inptr-inbuf)-inbuf_offset; inptr=inbuf+inbuf_offset; }}
X
X/*
X *  Seek to the block boundary of the block which includes abs_offset,
X *  then read block into input buffer and set pointers appropriately.
X *  If block is already in the buffer, just set the pointers.  This macro
X *  is used by process_end_central_dir (unzip.c) and do_string (misc.c).
X *  A slightly modified version is embedded within extract_or_test_files
X *  (unzip.c).  ReadByte and readbuf (file_io.c) are compatible.
X *
X *  macro LSEEK( abs_offset )
X *    {
X *      longint   request = abs_offset;
X *      longint   inbuf_offset = request % INBUFSIZ;
X *      longint   bufstart = request - inbuf_offset;
X *
X *      if (bufstart != cur_zipfile_bufstart) {
X *          cur_zipfile_bufstart = lseek(zipfd, bufstart, SEEK_SET);
X *          if ((incnt = read(zipfd,inbuf,INBUFSIZ)) <= 0)
X *              return(51);
X *          inptr = inbuf + inbuf_offset;
X *          incnt -= inbuf_offset;
X *      } else {
X *          incnt += (inptr-inbuf) - inbuf_offset;
X *          inptr = inbuf + inbuf_offset;
X *      }
X *    }
X *
X */
X
X
X#define OUTB(intc) { *outptr++=intc; if (++outcnt==OUTBUFSIZ) FlushOutput(); }
X
X/*
X *  macro OUTB(intc)
X *  {
X *      *outptr++=intc;
X *      if (++outcnt==OUTBUFSIZ)
X *          FlushOutput();
X *  }
X *
X */
X
X
X#define READBIT(nbits,zdest) { if (nbits <= bits_left) { zdest = (int)(bitbuf & mask_bits[nbits]); bitbuf >>= nbits; bits_left -= nbits; } else zdest = FillBitBuffer(nbits);}
X
X/*
X * macro READBIT(nbits,zdest)
X *  {
X *      if (nbits <= bits_left) {
X *          zdest = (int)(bitbuf & mask_bits[nbits]);
X *          bitbuf >>= nbits;
X *          bits_left -= nbits;
X *      } else
X *          zdest = FillBitBuffer(nbits);
X *  }
X *
X */
X
X
X#define NUKE_CRs(buf,len) {register int i,j; for (i=j=0; j<len; (buf)[i++]=(buf)[j++]) if ((buf)[j]=='\r') ++j; len=i;}
X
X/*
X *  Remove all the ASCII carriage returns from buffer buf (length len),
X *  shortening as necessary (note that len gets modified in the process,
X *  so it CANNOT be an expression).  This macro is intended to be used
X *  BEFORE A_TO_N(); hence the check for CR instead of '\r'.  NOTE:  The
X *  if-test gets performed one time too many, but it doesn't matter.
X *
X *  macro NUKE_CRs( buf, len )
X *    {
X *      register int   i, j;
X *
X *      for ( i = j = 0  ;  j < len  ;  (buf)[i++] = (buf)[j++] )
X *        if ( (buf)[j] == CR )
X *          ++j;
X *      len = i;
X *    }
X *
X */
X
X
X#define TOLOWER(str1,str2) {char *ps1,*ps2; ps1=(str1)-1; ps2=(str2); while(*++ps1) *ps2++=(isupper(*ps1))?tolower(*ps1):*ps1; *ps2='\0';}
X
X/*
X *  Copy the zero-terminated string in str1 into str2, converting any
X *  uppercase letters to lowercase as we go.  str2 gets zero-terminated
X *  as well, of course.  str1 and str2 may be the same character array.
X *
X *  macro TOLOWER( str1, str2 )
X *    {
X *      register char   *ps1, *ps2;
X *
X *      ps1 = (str1) - 1;
X *      ps2 = (str2);
X *      while ( *++ps1 )
X *        *ps2++ = (isupper(*ps1)) ?  tolower(*ps1)  :  *ps1;
X *      *ps2='\0';
X *    }
X *
X *  NOTES:  This macro makes no assumptions about the characteristics of
X *    the tolower() function or macro (beyond its existence), nor does it
X *    make assumptions about the structure of the character set (i.e., it
X *    should work on EBCDIC machines, too).  The fact that either or both
X *    of isupper() and tolower() may be macros has been taken into account;
X *    watch out for "side effects" (in the C sense) when modifying this
X *    macro.
X */
X
X
X#ifndef ascii_to_native
X
X#  define ascii_to_native(c)   (c)
X#  define A_TO_N(str1)
X
X#else
X
X#  define NATIVE   /* Used in main() for '-a' and '-c'. */
X#  define A_TO_N(str1) { register unsigned char *ps1; for (ps1 = str1; *ps1; ps1++) *ps1 = (ascii_to_native(*ps1)); }
X
X/*
X *   Translate the zero-terminated string in str1 from ASCII to the native
X *   character set. The translation is performed in-place and uses the
X *   ascii_to_native macro to translate each character.
X *
X *   macro A_TO_N( str1 )
X *     {
X *	 register unsigned char *ps1;
X *
X *	 for ( ps1 = str1; *ps1; ps1++ )
X *	   *ps1 = ( ascii_to_native( *ps1 ) );
X *     }
X *
X *   NOTE: Using the ascii_to_native macro means that is it the only part of
X *     unzip which knows which translation table (if any) is actually in use
X *     to produce the native character set. This makes adding new character
X *     set translation tables easy insofar as all that is needed is an
X *     appropriate ascii_to_native macro definition and the translation
X *     table itself. Currently, the only non-ASCII native character set
X *     implemented is EBCDIC but this may not always be so.
X */
X
X#endif
X
X
X
X
X
X/*************/
X/*  Globals  */
X/*************/
X
X   extern int       tflag;
X/* extern int       vflag;    (only used in unzip.c)  */
X   extern int       cflag;
X   extern int       aflag;
X   extern int       dflag;
X   extern int       Uflag;
X   extern int       V_flag;
X#ifdef MACOS
X   extern int       hfsflag;
X#endif
X   extern int       lcflag;
X   extern unsigned  f_attr;
X   extern longint   csize;
X   extern longint   ucsize;
X
X   extern short     prefix_of[];
X#ifdef MACOS
X   extern byte      *suffix_of;
X   extern byte      *stack;
X#else
X   extern byte      suffix_of[];
X   extern byte      stack[];
X#endif
X   extern ULONG     crc32val;
X   extern UWORD     mask_bits[];
X
X   extern byte      *inbuf;
X   extern byte      *inptr;
X   extern int       incnt;
X   extern UWORD     bitbuf;
X   extern int       bits_left;
X   extern boolean   zipeof;
X   extern int       zipfd;
X   extern char      zipfn[];
X   extern local_file_header   lrec;
X   extern struct stat         statbuf;
X   extern longint   cur_zipfile_bufstart;
X
X   extern byte      *outbuf;
X   extern byte      *outptr;
X   extern byte      *outout;
X   extern longint   outpos;
X   extern int       outcnt;
X   extern int       outfd;
X   extern char      filename[];
X
X#ifdef DECLARE_ERRNO
X   extern int       errno;
X#endif
X
X#ifdef EBCDIC
X   extern byte      ebcdic[];
X#endif
END_OF_FILE
  if test 28924 -ne `wc -c <'./v41/unzip.h'`; then
    echo shar: \"'./v41/unzip.h'\" unpacked with wrong size!
  fi
  # end of './v41/unzip.h'
fi
echo shar: End of archive 2 \(of 6\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.