🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: vmsnet.sources
Article #80

Zip v1.9 & UnZip v5.0, part 11/22

#80
From: goathunter
Date: Tue, 01 Sep 1992 22:51
1332 lines
49780 bytes
Submitted-by: goathunter@wkuvx1.bitnet
Posting-number: Volume 3, Issue 133
Archive-name: zip_unzip/part11

-+-+-+-+-+-+-+-+ START OF PART 11 -+-+-+-+-+-+-+-+
X                if ((ascii_to_native(*inptr) == 'P')  &&
X                     !strncmp((char *)inptr, end_central_sig, 4)) `7B
X                    incnt -= inptr - inbuf;
X                    return 0;   /* found it! */
X                `7D               /* ...otherwise fall through & fail */
X
X/*--------------------------------------------------------------------------
V-
X    Zipfile is longer than INBUFSIZ:  may need to loop.  Start with short
X    block at end of zipfile (if not TOO short).
X  --------------------------------------------------------------------------
V-*/
X
X    `7D else `7B
X        if ((tail_len = ziplen % INBUFSIZ) > ECREC_SIZE) `7B
X            cur_zipfile_bufstart = lseek(zipfd, ziplen-tail_len, SEEK_SET);
X            if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)tail_len)) !
V=
X                 (int)tail_len)
X                goto fail;      /* shut up; it's expedient. */
X
X            /* 'P' must be at least 22 bytes from end of zipfile */
X            for (inptr = inbuf+(int)tail_len-22;  inptr >= inbuf;  --inptr)
X                if ((ascii_to_native(*inptr) == 'P')  &&
X                     !strncmp((char *)inptr, end_central_sig, 4)) `7B
X                    incnt -= inptr - inbuf;
X                    return 0;   /* found it */
X                `7D               /* ...otherwise search next block */
X            strncpy((char *)hold, (char *)inbuf, 3);    /* sig may span bloc
Vk
X                                                           boundary */
X        `7D else `7B
X            cur_zipfile_bufstart = ziplen - tail_len;
X        `7D
X
X    /*----------------------------------------------------------------------
V-
X        Loop through blocks of zipfile data, starting at the end and going
X        toward the beginning.  Need only check last 65557 bytes of zipfile:
X        comment may be up to 65535 bytes long, end-of-central-directory rec-
X        ord is 18 bytes (shouldn't hardcode this number, but what the hell:
X        already did so above (22=18+4)), and sig itself is 4 bytes.
X      ----------------------------------------------------------------------
V-*/
X
X        numblks = (int)
X                  ((MIN(ziplen,65557L) - tail_len + (INBUFSIZ-1)) / INBUFSIZ
V);
X        /*          =amount to search=   ==done==   ==rounding==    =blksiz=
V */
X
X        for (i = 1;  i <= numblks;  ++i) `7B
X            cur_zipfile_bufstart -= INBUFSIZ;
X            lseek(zipfd, cur_zipfile_bufstart, SEEK_SET);
X            if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) != INBUFSIZ)
X                break;          /* fall through and fail */
X
X            for (inptr = inbuf+INBUFSIZ-1;  inptr >= inbuf;  --inptr)
X                if ((ascii_to_native(*inptr) == 'P')  &&
X                     !strncmp((char *)inptr, end_central_sig, 4)) `7B
X                    incnt -= inptr - inbuf;
X                    return 0;   /* found it */
X                `7D
X            strncpy((char *)hold, (char *)inbuf, 3);    /* sig may span bloc
Vk
X                                                           boundary */
X        `7D
X
X    `7D /* end if (ziplen > INBUFSIZ) */
X
X/*--------------------------------------------------------------------------
V-
X    Searched through whole region where signature should be without finding
X    it.  Print informational message and die a horrible death.
X  --------------------------------------------------------------------------
V-*/
X
Xfail:
X#ifdef MSWIN
X    MessageBeep(1);
X#endif
X
X    fprintf(stderr, "\nFile:  %s\n\n\
X     End-of-central-directory signature not found.  Either this file is not\
Vn\
X     a zipfile, or it constitutes one disk of a multi-part archive.  In the\
Vn\
X     latter case the central directory and zipfile comment will be found on\
Vn\
X     the last disk(s) of this archive.\n", zipfn);
X    return 1;
X
X`7D /* end function find_end_central_dir() */
X
X
X
X
X
X/***************************************/
X/*  Function process_end_central_dir() */
X/***************************************/
X
Xint process_end_central_dir()    /* return PK-type error code */
X`7B
X    ec_byte_rec byterec;
X    int error=0;
X
X
X/*--------------------------------------------------------------------------
V-
X    Read the end-of-central-directory record and do any necessary machine-
X    type conversions (byte ordering, structure padding compensation) by
X    reading data into character array, then copying to struct.
X  --------------------------------------------------------------------------
V-*/
X
X    if (readbuf((char *) byterec, ECREC_SIZE+4) <= 0)
X        return 51;
X
X    ecrec.number_this_disk =
X        makeword(&byterec`5BNUMBER_THIS_DISK`5D);
X    ecrec.num_disk_with_start_central_dir =
X        makeword(&byterec`5BNUM_DISK_WITH_START_CENTRAL_DIR`5D);
X    ecrec.num_entries_centrl_dir_ths_disk =
X        makeword(&byterec`5BNUM_ENTRIES_CENTRL_DIR_THS_DISK`5D);
X    ecrec.total_entries_central_dir =
X        makeword(&byterec`5BTOTAL_ENTRIES_CENTRAL_DIR`5D);
X    ecrec.size_central_directory =
X        makelong(&byterec`5BSIZE_CENTRAL_DIRECTORY`5D);
X    ecrec.offset_start_central_directory =
X        makelong(&byterec`5BOFFSET_START_CENTRAL_DIRECTORY`5D);
X    ecrec.zipfile_comment_length =
X        makeword(&byterec`5BZIPFILE_COMMENT_LENGTH`5D);
X
X/*--------------------------------------------------------------------------
V-
X    Get the zipfile comment, if any, and print it out.  (Comment may be up
X    to 64KB long.  May the fleas of a thousand camels infest the armpits of
X    anyone who actually takes advantage of this fact.)  Then position the
X    file pointer to the beginning of the central directory and fill buffer.
X  --------------------------------------------------------------------------
V-*/
X
X#ifdef MSWIN
X    cchComment = ecrec.zipfile_comment_length; /* save for comment button */
X    if (ecrec.zipfile_comment_length && zflag) `7B
X#else /* !MSWIN */
X    if (ecrec.zipfile_comment_length && !quietflg) `7B
X        if (!zflag)
X          printf("`5B%s`5D comment:\n", zipfn);
X#endif /* ?MSWIN */
X        if (do_string(ecrec.zipfile_comment_length,DISPLAY)) `7B
X            fprintf(stderr, "\ncaution:  zipfile comment truncated\n");
X            error = 1;          /* 1:  warning error */
X        `7D
X    `7D
X
X    return error;
X
X`7D /* end function process_end_central_dir() */
X
X
X
X
X
X/* also referenced in UpdateListBox() in updatelb.c (Windows version) */
Xchar *Headers`5B`5D`5B2`5D = `7B
X    `7B" Length    Date    Time    Name",
X     " ------    ----    ----    ----"`7D,
X    `7B" Length  Method   Size  Ratio   Date    Time   CRC-32     Name",
X     " ------  ------   ----  -----   ----    ----   ------     ----"`7D
X`7D;
X
X/*************************/
X/* Function list_files() */
X/*************************/
X
Xint list_files()    /* return PK-type error code */
X`7B
X    char **fnamev;
X    int do_this_file=FALSE, ratio, error, error_in_archive=0;
X    int which_hdr=(vflag>1), date_format;
X    UWORD j, yr, mo, dy, hh, mm, members=0;
X    ULONG tot_csize=0L, tot_ucsize=0L;
X#ifdef OS2
X    ULONG tot_easize=0L, tot_eafiles=0L, ea_size;
X#endif
X#ifdef MSWIN
X    PSTR psLBEntry;  /* list box entry */
X#endif
X    min_info info;
X    static char *method`5BNUM_METHODS+1`5D =
X        `7B"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
X         "Implode", "Token", "Deflate", unkn`7D;
X
X
X
X/*--------------------------------------------------------------------------
V-
X    Unlike extract_or_test_files(), this routine confines itself to the cen-
X    tral directory.  Thus its structure is somewhat simpler, since we can do
X    just a single loop through the entire directory, listing files as we go.
X
X    So to start off, print the heading line and then begin main loop through
X    the central directory.  The results will look vaguely like the following
V:
X
X  Length  Method   Size  Ratio   Date    Time   CRC-32     Name ("`5E" ==> c
Vase
X  ------  ------   ----  -----   ----    ----   ------     ----   conversion
V)
X   44004  Implode  13041  71%  11-02-89  19:34  8b4207f7   Makefile.UNIX
X    3438  Shrunk    2209  36%  09-15-90  14:07  a2394fd8  `5Edos-file.ext
X  --------------------------------------------------------------------------
V-*/
X
X    pInfo = &info;
X    date_format = dateformat();
X
X#ifndef MSWIN
X    if (quietflg < 2)
X        if (U_flag)
X            printf("%s\n%s\n", Headers`5Bwhich_hdr`5D`5B0`5D, Headers`5Bwhic
Vh_hdr`5D`5B1`5D);
X        else
X            printf("%s (\"`5E\" ==> case\n%s   conversion)\n",`20
X              Headers`5Bwhich_hdr`5D`5B0`5D, Headers`5Bwhich_hdr`5D`5B1`5D);
X#endif /* !MSWIN */
X
X    for (j = 0; j < ecrec.total_entries_central_dir; ++j) `7B
X
X        if (readbuf(sig, 4) <= 0)
X            return 51;          /* 51:  unexpected EOF */
X        if (strncmp(sig, central_hdr_sig, 4)) `7B  /* just to make sure */
X            fprintf(stderr, CentSigMsg, j);  /* sig not found */
X            fprintf(stderr, ReportMsg);   /* check binary transfers */
X            return 3;           /* 3:  error in zipfile */
X        `7D
X        if ((error = process_cdir_file_hdr()) != 0)  /* (sets pInfo->lcflag)
V */
X            return error;       /* only 51 (EOF) defined */
X
X        /*
X         * We could DISPLAY the filename instead of storing (and possibly tr
Vun-
X         * cating, in the case of a very long name) and printing it, but tha
Vt
X         * has the disadvantage of not allowing case conversion--and it's ni
Vce
X         * to be able to see in the listing precisely how you have to type e
Vach
X         * filename in order for unzip to consider it a match.  Speaking of
X         * which, if member names were specified on the command line, check
V in
X         * with match() to see if the current file is one of them, and make
V a
X         * note of it if it is.
X         */
X
X        if ((error = do_string(crec.filename_length, FILENAME)) != 0) `7B
X            error_in_archive = error;  /*             `5E--(uses pInfo->lcfl
Vag) */
X            if (error > 1)      /* fatal:  can't continue */
X                return error;
X        `7D
X        if (extra_field != (byte *)NULL)
X            free(extra_field);
X        extra_field = (byte *)NULL;
X        if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0)
V `7B
X            error_in_archive = error; `20
X            if (error > 1)      /* fatal:  can't continue */
X                return error;
X        `7D
X        if (!process_all_files) `7B   /* check if specified on command line
V */
X            do_this_file = FALSE;
X            fnamev = fnv;       /* don't destroy permanent filename ptr */
X            for (--fnamev; *++fnamev;)
X                if (match(filename, *fnamev)) `7B
X                    do_this_file = TRUE;
X                    break;      /* found match, so stop looping */
X                `7D
X        `7D
X        /*
X         * If current file was specified on command line, or if no names wer
Ve
X         * specified, do the listing for this file.  Otherwise, get rid of t
Vhe
X         * file comment and go back for the next file.
X         */
X
X        if (process_all_files `7C`7C do_this_file) `7B
X
X            yr = (((crec.last_mod_file_date >> 9) & 0x7f) + 80) % (unsigned)
V100;
X            mo = (crec.last_mod_file_date >> 5) & 0x0f;
X            dy = crec.last_mod_file_date & 0x1f;
X
X            /* twist date so it displays according to national convention */
X            switch (date_format) `7B
X                case DF_YMD:
X                    hh = mo; mo = yr; yr = dy; dy = hh; break;
X                case DF_DMY:
X                    hh = mo; mo = dy; dy = hh;
X            `7D
X            hh = (crec.last_mod_file_time >> 11) & 0x1f;
X            mm = (crec.last_mod_file_time >> 5) & 0x3f;
X
X            csize = (longint) crec.compressed_size;
X            ucsize = (longint) crec.uncompressed_size;
X            if (crec.general_purpose_bit_flag & 1)
X                csize -= 12;    /* if encrypted, don't count encrypt hdr */
X
X            ratio = (ucsize == 0) ? 0 :   /* .zip can have 0-length members
V */
X                ((ucsize > 2000000L) ?    /* risk signed overflow if mult. *
V/
X                (int) ((ucsize-csize) / (ucsize/1000L)) + 5 :   /* big */
X                (int) ((1000L*(ucsize-csize)) / ucsize) + 5);   /* small */
X
X#if 0       /* GRR/Euro:  add this?  define p above */
X#if (defined(DOS_OS2) `7C`7C (defined(UNIX) && !defined(VMS)))
X            for (p = filename;  *p;  ++p)
X                if (!isprint(*p))
X                    *p = '?';  /* change non-printable chars to '?' */
X#endif /* DOS_OS2 `7C`7C UNIX */
X#endif /* 0 */
X
X#ifdef MSWIN
X#ifdef NEED_EARLY_REDRAW
X            /* turn on listbox redrawing just before adding last line */
X            if (j == (ecrec.total_entries_central_dir-1))
X                (void)SendMessage(hWndList, WM_SETREDRAW, TRUE, 0L);
X#endif /* NEED_EARLY_REDRAW */
X            psLBEntry =
X              (PSTR)LocalAlloc(LMEM_FIXED, FILNAMSIZ+LONG_FORM_FNAME_INX);
X            switch (which_hdr) `7B
X                case 0:   /* short form */
X                    OemToAnsi(filename, filename);  /* translate to ANSI */
X                    wsprintf(psLBEntry, "%7ld  %02u-%02u-%02u  %02u:%02u  %c
V%s",
X                      (long)ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'`5E'
V:' '),
X                      (LPSTR)filename);
X                    SendMessage(hWndList, LB_ADDSTRING, 0,
X                      (LONG)(LPSTR)psLBEntry);
X                    break;
X                case 1:   /* verbose */
X                    OemToAnsi(filename, filename);  /* translate to ANSI */
X                    wsprintf(psLBEntry,`20
X                 "%7ld  %-7s%7ld %3d%%  %02u-%02u-%02u  %02u:%02u  %08lx  %c
V%s",
X                      (long)ucsize, (LPSTR)method`5Bmethnum`5D, (long)csize,
X                      ratio/10, mo, dy, yr, hh, mm, (unsigned long)crec.crc3
V2,
X                      (pInfo->lcflag?'`5E':' '), (LPSTR)filename);
X                    SendMessage(hWndList, LB_ADDSTRING, 0,
X                      (LONG)(LPSTR)psLBEntry);
X            `7D
X            LocalFree((HANDLE)psLBEntry);
X#else /* !MSWIN */
X            switch (which_hdr) `7B
X                case 0:   /* short form */
X                    printf("%7ld  %02u-%02u-%02u  %02u:%02u  %c%s\n",
X                      ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'`5E':' '),
X                      filename);
X                    break;
X                case 1:   /* verbose */
X                    printf(
X              "%7ld  %-7s%7ld %3d%%  %02u-%02u-%02u  %02u:%02u  %08lx  %c%s\
Vn",
X                      ucsize, method`5Bmethnum`5D, csize, ratio/10, mo, dy,
V yr,
X                      hh, mm, crec.crc32, (pInfo->lcflag?'`5E':' '), filenam
Ve);
X            `7D
X#endif /* ?MSWIN */
X
X            error = do_string(crec.file_comment_length, (QCOND? DISPLAY:SKIP
V));
X            if (error) `7B
X                error_in_archive = error;  /* might be just warning */
X                if (error > 1)  /* fatal */
X                    return error;
X            `7D
X            tot_ucsize += (ULONG) ucsize;
X            tot_csize += (ULONG) csize;
X            ++members;
X#ifdef OS2
X            if ((ea_size = SizeOfEAs(extra_field)) != 0) `7B
X                tot_easize += ea_size;
X                tot_eafiles++;
X            `7D
X#endif
X        `7D else `7B        /* not listing this file */
X            SKIP_(crec.file_comment_length)
X        `7D
X    `7D                   /* end for-loop (j: files in central directory) */
X
X/*--------------------------------------------------------------------------
V-
X    Print footer line and totals (compressed size, uncompressed size, number
X    of members in zipfile).
X  --------------------------------------------------------------------------
V-*/
X
X    ratio = (tot_ucsize == 0) ?`20
X        0 : ((tot_ucsize > 4000000L) ?   /* risk unsigned overflow if mult.
V */
X        (int) ((tot_ucsize - tot_csize) / (tot_ucsize/1000L)) + 5 :
X        (int) ((tot_ucsize - tot_csize) * 1000L / tot_ucsize) + 5);
X
X    if (quietflg < 2) `7B
X#ifdef MSWIN
X        /* Display just the totals since the dashed lines get displayed
X         * in UpdateListBox(). Get just enough space to display total.
X         */
X        switch (which_hdr) `7B
X            case 0:         /* short */
X                wsprintf(lpumb->szTotalsLine, "%7lu                    %-7u"
V,`20
X                  (ULONG)tot_ucsize, members);
X                break;
X            case 1:         /* verbose */
X                wsprintf(lpumb->szTotalsLine,`20
X                  "%7lu         %7lu %3d%%                              %-7u
V",`20
X                  (ULONG)tot_ucsize, (ULONG)tot_csize, ratio / 10, members);
X                break;
X        `7D
X#else /* !MSWIN */
X        switch (which_hdr) `7B
X        case 0:         /* short */
X            printf("%s\n%7lu                    %-7u\n",
X                   " ------                    -------",
X                   tot_ucsize, members);
X            break;
X        case 1:         /* verbose */
X            printf(
X              "%s\n%7lu         %7lu %3d%%                              %-7u
V\n",
X              " ------          ------  ---                              ---
V----",
X              tot_ucsize, tot_csize, ratio / 10, members);
X        `7D
X#endif /* ?MSWIN */
X#ifdef OS2
X        if (tot_eafiles && tot_easize)
X            printf("\n%ld file%s %ld bytes of EA's attached.\n", tot_eafiles
V,`20
X              tot_eafiles == 1 ? " has" : "s have a total of", tot_easize);
X#endif
X    `7D
X/*--------------------------------------------------------------------------
V-
X    Double check that we're back at the end-of-central-directory record.
X  --------------------------------------------------------------------------
V-*/
X
X    readbuf(sig, 4);
X    if (strncmp(sig, end_central_sig, 4)) `7B     /* just to make sure again
V */
X        fprintf(stderr, EndSigMsg);  /* didn't find end-of-central-dir sig *
V/
X/*      fprintf(stderr, ReportMsg);   */
X        error_in_archive = 1;        /* 1:  warning error */
X    `7D
X    return error_in_archive;
X
X`7D /* end function list_files() */
X
X
X
X
X
X/**************************************/
X/*  Function process_cdir_file_hdr()  */
X/**************************************/
X
Xint process_cdir_file_hdr()    /* return PK-type error code */
X`7B
X    cdir_byte_hdr byterec;
X
X
X/*--------------------------------------------------------------------------
V-
X    Read the next central directory entry and do any necessary machine-type
X    conversions (byte ordering, structure padding compensation--do so by
X    copying the data from the array into which it was read (byterec) to the
X    usable struct (crec)).
X  --------------------------------------------------------------------------
V-*/
X
X    if (readbuf((char *) byterec, CREC_SIZE) <= 0)
X        return 51;   /* 51:  unexpected EOF */
X
X    crec.version_made_by`5B0`5D = byterec`5BC_VERSION_MADE_BY_0`5D;
X    crec.version_made_by`5B1`5D = byterec`5BC_VERSION_MADE_BY_1`5D;
X    crec.version_needed_to_extract`5B0`5D = byterec`5BC_VERSION_NEEDED_TO_EX
VTRACT_0`5D;
X    crec.version_needed_to_extract`5B1`5D = byterec`5BC_VERSION_NEEDED_TO_EX
VTRACT_1`5D;
X
X    crec.general_purpose_bit_flag =
X        makeword(&byterec`5BC_GENERAL_PURPOSE_BIT_FLAG`5D);
X    crec.compression_method =
X        makeword(&byterec`5BC_COMPRESSION_METHOD`5D);
X    crec.last_mod_file_time =
X        makeword(&byterec`5BC_LAST_MOD_FILE_TIME`5D);
X    crec.last_mod_file_date =
X        makeword(&byterec`5BC_LAST_MOD_FILE_DATE`5D);
X    crec.crc32 =
X        makelong(&byterec`5BC_CRC32`5D);
X    crec.compressed_size =
X        makelong(&byterec`5BC_COMPRESSED_SIZE`5D);
X    crec.uncompressed_size =
X        makelong(&byterec`5BC_UNCOMPRESSED_SIZE`5D);
X    crec.filename_length =
X        makeword(&byterec`5BC_FILENAME_LENGTH`5D);
X    crec.extra_field_length =
X        makeword(&byterec`5BC_EXTRA_FIELD_LENGTH`5D);
X    crec.file_comment_length =
X        makeword(&byterec`5BC_FILE_COMMENT_LENGTH`5D);
X    crec.disk_number_start =
X        makeword(&byterec`5BC_DISK_NUMBER_START`5D);
X    crec.internal_file_attributes =
X        makeword(&byterec`5BC_INTERNAL_FILE_ATTRIBUTES`5D);
X    crec.external_file_attributes =
X        makelong(&byterec`5BC_EXTERNAL_FILE_ATTRIBUTES`5D);  /* LONG, not wo
Vrd! */
X    crec.relative_offset_local_header =
X        makelong(&byterec`5BC_RELATIVE_OFFSET_LOCAL_HEADER`5D);
X
X    pInfo->hostnum = MIN(crec.version_made_by`5B1`5D, NUM_HOSTS);
X/*  extnum = MIN(crec.version_needed_to_extract`5B1`5D, NUM_HOSTS); */
X    methnum = MIN(crec.compression_method, NUM_METHODS);
X    if (methnum == NUM_METHODS)
X        sprintf(unkn, "Unk:%03d", crec.compression_method);
X
X/*--------------------------------------------------------------------------
V-
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  --------------------------------------------------------------------------
V-*/
X
X    pInfo->lcflag = 0;
X    if (!U_flag)   /* as long as user hasn't specified case-preservation */
X        switch (pInfo->hostnum) `7B
X            case DOS_OS2_FAT_:
X        /*  case VMS_:              VMS Zip converts filenames to lowercase
V */
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                pInfo->lcflag = 1;  /* convert filename to lowercase */
X                break;
X
X            default:                /* AMIGA_, UNIX_, (ATARI_), OS2_HPFS_, *
V/
X                break;              /*   MAC_, (Z_SYSTEM_):  no conversion *
V/
X        `7D
X
X    return 0;
X
X`7D /* end function process_cdir_file_hdr() */
X
X
X
X
X
X/***************************************/
X/*  Function process_local_file_hdr()  */
X/***************************************/
X
Xint process_local_file_hdr()    /* return PK-type error code */
X`7B
X    local_byte_hdr byterec;
X
X
X/*--------------------------------------------------------------------------
V-
X    Read the next local file header and do any necessary machine-type con-
X    versions (byte ordering, structure padding compensation--do so by copy-
X    ing the data from the array into which it was read (byterec) to the
X    usable struct (lrec)).
X  --------------------------------------------------------------------------
V-*/
X
X    if (readbuf((char *) byterec, LREC_SIZE) <= 0)
X        return 51;   /* 51:  unexpected EOF */
X
X    lrec.version_needed_to_extract`5B0`5D = byterec`5BL_VERSION_NEEDED_TO_EX
VTRACT_0`5D;
X    lrec.version_needed_to_extract`5B1`5D = byterec`5BL_VERSION_NEEDED_TO_EX
VTRACT_1`5D;
X
X    lrec.general_purpose_bit_flag = makeword(&byterec`5BL_GENERAL_PURPOSE_BI
VT_FLAG`5D);
X    lrec.compression_method = makeword(&byterec`5BL_COMPRESSION_METHOD`5D);
X    lrec.last_mod_file_time = makeword(&byterec`5BL_LAST_MOD_FILE_TIME`5D);
X    lrec.last_mod_file_date = makeword(&byterec`5BL_LAST_MOD_FILE_DATE`5D);
X    lrec.crc32 = makelong(&byterec`5BL_CRC32`5D);
X    lrec.compressed_size = makelong(&byterec`5BL_COMPRESSED_SIZE`5D);
X    lrec.uncompressed_size = makelong(&byterec`5BL_UNCOMPRESSED_SIZE`5D);
X    lrec.filename_length = makeword(&byterec`5BL_FILENAME_LENGTH`5D);
X    lrec.extra_field_length = makeword(&byterec`5BL_EXTRA_FIELD_LENGTH`5D);
X
X    csize = (longint) lrec.compressed_size;
X    ucsize = (longint) lrec.uncompressed_size;
X
X    if ((lrec.general_purpose_bit_flag & 8) != 0) `7B
X        /* Can't trust local header, use central directory: */
X      lrec.crc32 = pInfo->crc;
X        lrec.compressed_size = pInfo->compr_size;
X        csize = (longint) lrec.compressed_size;
X    `7D
X
X    return 0;                 /* 0:  no error */
X
X`7D /* end function process_local_file_hdr() */
$ CALL UNPACK [.UNZIP50]UNZIP.C;1 157894339
$ create 'f'
X
XUNZIP(1)                 USER COMMANDS                   UNZIP(1)
X
XNAME
X     unzip - list/test/extract from a ZIP archive file
X
XSYNOPSIS
X     unzip `5B -cflptuvxz`5BajnoqUV`5D `5D file`5B.zip`5D `5Bfilespec ...`5D
X
XARGUMENTS
X     file`5B.zip`5D  Path of the ZIP archive.  The suffix `60`60.zip'' is
X                 applied  if  the  file specified does not exist.
X                 Note that self-extracting  ZIP  files  are  sup-
X                 ported;  just  specify the `60`60.exe'' suffix your-
X                 self.
X
X     `5Bfilespec`5D  An optional list of archive members to  be  pro-
X                 cessed.  Expressions may be used to match multi-
X                 ple members; be sure to quote  expressions  that
X                 contain  characters interpreted by the operating
X                 system.  See  DESCRIPTION   (below)   for   more
X                 details.
X
XOPTIONS
X     -c  extract files to stdout/screen (`60`60CRT'')
X     -f  freshen existing files (replace if newer); create none
X     -l  list archive files (short format)
X     -p  extract files to pipe; no informational messages
X     -t  test archive files
X     -u  update existing files; create new ones if needed
X     -v  list archive files (verbose format)
X     -x  extract files in archive (default)
X     -z  display only the archive comment
X
XMODIFIERS
X     -a  convert to MS-DOS textfile format (CR  LF),  Mac  format
X         (CR),  Unix/VMS  format  (LF),  OR from ASCII to EBCDIC,
X         depending on your system (only use for TEXT files!)
X     -j  junk paths (don't recreate  archive's  directory  struc-
X         ture)
X     -n  never overwrite existing files; don't prompt
X     -o  OK to overwrite files without prompting
X     -q  perform operations quietly (-qq => even quieter)
X     -s  `5BOS/2,  MS-DOS`5D  allow  spaces   in   filenames   (e.g.,
X         `60`60EA DATA. SF'')
X     -U  leave filenames uppercase if created under MS-DOS,  VMS,
X         etc.
X     -V  retain (VMS) file version numbers
X     -X  `5BVMS`5D  restore  owner/protection   info   (may   require
X         privileges)
X
XDESCRIPTION
X     UnZip will list, test, or extract from a ZIP  archive,  com-
X     monly  found on MSDOS systems.  Archive member extraction is
X     implied by the absence of the -c,  -p,  -t,  -l,  -v  or  -z
X
XInfo-ZIP          Last change: 21 Aug 92 (v5.0)                 1
X
XUNZIP(1)                 USER COMMANDS                   UNZIP(1)
X
X     options.    All  archive  members  are  processed  unless  a
X     filespec is provided to specify  a  subset  of  the  archive
X     members.   The  filespec  is similar to an egrep expression,
X     and may contain:
X
X     *      matches a sequence of 0 or more characters
X     ?      matches exactly 1 character
X     \nnn   matches the character having octal code nnn
X     `5B...`5D  matches any single character found inside the  brack-
X            ets; ranges are specified by a beginning character, a
X            hyphen, and an ending character.  If  an  exclamation
X            point  or  a  carat  (`60!'  or  `60`5E')  follows the left
X            bracket, then the range of characters matched is com-
X            plemented  with  respect  to  the ASCII character set
X            (that is, anything except the characters  inside  the
X            brackets is considered a match).
X
XENVIRONMENT OPTIONS
X     UnZip's default behavior may be modified via options  placed
X     in  an  environment  variable.   This  can  be done with any
X     option, but it is probably most useful with the -q,  -o,  or
X     -n modifiers:  in order to make UnZip quieter by default, or
X     to make it always overwrite or never overwrite files  as  it
X     extracts them.  For example, to make UnZip act as quietly as
X     possible, only reporting errors, one would use  one  of  the
X     following commands:
X
X           setenv UNZIP -qq           Unix C shell
X
X           UNZIP=-qq; export UNZIP    Unix Bourne shell
X
X           set UNZIP=-qq              OS/2 or MS-DOS
X
X           define UNZIP_OPTS "-qq"    VMS (quotes for LOWERCASE)
X
X     Environment options are, in effect, considered  to  be  just
X     like  any  other  command-line options, except that they are
X     effectively the first options on the command line.  To over-
X     ride  an  environment option, one may use the `60`60minus opera-
X     tor'' to remove it.  For instance, to override  one  of  the
X     quiet-flags in the example above, use the command
X
X           unzip --q`5Bother options`5D zipfile
X
X     The first hyphen is the normal  switch  character,  and  the
X     second  is  a  minus sign, acting on the q option.  Thus the
X     effect here is to cancel a single quantum of quietness.   To
X     cancel both quiet flags, two (or more) minuses may be used:
X
X           unzip -x--q zipfile
X
XInfo-ZIP          Last change: 21 Aug 92 (v5.0)                 2
X
XUNZIP(1)                 USER COMMANDS                   UNZIP(1)
X
X     or
X
X           unzip ---qx zipfile
X
X     (the two are equivalent).  This may seem awkward or  confus-
X     ing,  but it is reasonably intuitive:  just ignore the first
X     hyphen and go from there.  It is also  consistent  with  the
X     behavior of Unix nice(1).
X
XEXAMPLES
X     To  use  UnZip  to  extract  all  members  of  the   archive
X     letters.zip, creating any directories as necessary:
X
X           unzip letters
X
X     To extract all members of letters.zip to the current  direc-
X     tory:
X
X           unzip -j letters
X
X     To test letters.zip, printing only a summary  message  indi-
X     cating whether the archive is OK or not:
X
X           unzip -tq letters
X
X     To extract to standard output  all  members  of  letters.zip
X     whose  names  end  in `60`60.tex'', converting to the local end-
X     of-line convention and piping the output into more(1):
X
X           unzip -ca letters \*.tex `7C more
X
X     (The backslash before the asterisk is only required  if  the
X     shell  expands  wildcards,  as  in Unix; double quotes could
X     have been used instead, as in the source example below.)  To
X     extract  the  binary  file paper1.dvi to standard output and
X     pipe it to a printing program:
X
X           unzip -p articles paper1.dvi `7C dvips
X
X     To extract all FORTRAN and C source  files--*.f,  *.c,  *.h,
X     Makefile  (the  double quotes are necessary only in Unix and
X     only if globbing is turned on):
X
X           unzip source.zip "*.`5Bfch`5D" Makefile
X
X     To extract only newer versions of the files already  in  the
X     current  directory,  without  querying (NOTE:  be careful of
X     unzipping in one timezone a zipfile created in  another--ZIP
X     archives  contain  no  timezone information, and a `60`60newer''
X     file from an eastern timezone may, in fact, be older):
X
XInfo-ZIP          Last change: 21 Aug 92 (v5.0)                 3
X
XUNZIP(1)                 USER COMMANDS                   UNZIP(1)
X
X           unzip -fo sources
X
X     To extract newer  versions  of  the  files  already  in  the
X     current  directory and to create any files not already there
X     (same caveat as previous example):
X
X           unzip -uo sources
X
X     In the last five examples, assume that UNZIP  or  UNZIP_OPTS
X     is set to -q.  To do a singly quiet listing:
X
X           unzip -l file
X
X     To do a doubly quiet listing:
X
X           unzip -ql file
X
X     To do a standard listing:
X
X           unzip --ql file
X
X     or
X
X           unzip -l-q file
X
X     or
X
X           unzip -l--q file
X
X     (extra minuses don't hurt).
X
XTIPS
X     The current maintainer, being a lazy  sort,  finds  it  very
X     useful to define an alias `60`60tt'' for `60`60unzip -tq''.  One may
X     then simply type `60`60tt zipfile'' to test the  archive,  some-
X     thing  which  one  ought  make  a habit of doing.  With luck
X     UnZip will report `60`60No  errors  detected  in  zipfile.zip,''
X     after which one may breathe a sigh of relief.
X
XSEE ALSO
X     funzip(1),  zip(1),  zipcloak(1),  zipinfo(1),   zipnote(1),
X     zipsplit(1)
X
XAUTHORS
X     Samuel H. Smith, Carl Mascott, David P. Kirschbaum, Greg  R.
X     Roelofs,  Mark  Adler,  Kai  Uwe  Rommel, Igor Mandrichenko,
X     Johnny Lee, Jean-loup Gailly; Glenn  Andrews,  Joel  Aycock,
X     Allan  Bjorklund,  James  Birdsall,  Wim Bonner, John Cowan,
X     Frank da Cruz, Bill Davidsen, Arjan de Vet, James Dugal, Jim
X     Dumser,  Mark  Edwards, David Feinleib, Mike Freeman, Hunter
X     Goatley, Robert Heath, Dave  Heiland,  Larry  Jones,  Kjetil
X     J`7Bob  Kemp, J. Kercheval, Alvin Koh, Bo Kullmar, Johnny Lee,
X
XInfo-ZIP          Last change: 21 Aug 92 (v5.0)                 4
X
XUNZIP(1)                 USER COMMANDS                   UNZIP(1)
X
X     Warner Losh, Fulvio Marino, Gene McManus, Joe Meadows,  Mike
X     O'Carroll,  Humberto  Ortiz-Zuazaga,  Piet W. Plomp, Antonio
X     Querubin Jr., Steve Salisbury,  Georg  Sassen,  Jon  Saxton,
X     Hugh Schmidt, Martin Schulz, Charles Scripter, Chris Seaman,
X     Richard Seay, Alex Sergejew, Cliff Stanford,  Onno  van  der
X     Linden, Jim Van Zandt, Antoine Verheijen, Paul Wells.
X
XVERSIONS
X     v1.2  15 Mar 89  Samuel H. Smith
X     v2.0   9 Sep 89  Samuel H. Smith
X     v2.x  fall 1989  many Usenet contributors
X     v3.0   1 May 90  Info-ZIP (DPK, consolidator)
X     v3.1  15 Aug 90  Info-ZIP (DPK, consolidator)
X     v4.0   1 Dec 90  Info-ZIP (GRR, maintainer)
X     v4.1  12 May 91  Info-ZIP
X     v4.2  20 Mar 92  Info-ZIP (zip-bugs subgroup; GRR, maint.)
X     v5.0  21 Aug 92  Info-ZIP (zip-bugs subgroup; GRR, maint.)
X
XInfo-ZIP          Last change: 21 Aug 92 (v5.0)                 5
X
$ CALL UNPACK [.UNZIP50]UNZIP.DOC;1 1762853046
$ create 'f'
X/*--------------------------------------------------------------------------
V-
X
X  unzip.h
X
X  This header file is used by all of the unzip source files.  Its contents
X  are divided into seven more-or-less separate sections:  predefined macros,
X  OS-dependent includes, (mostly) OS-independent defines, typedefs, function
V`20
X  prototypes (or "prototypes," in the case of non-ANSI compilers), macros,`2
V0
X  and global-variable declarations.
X
X  --------------------------------------------------------------------------
V-*/
X
X
X
X/*****************************************/
X/*  Predefined, Machine-specific Macros  */
X/*****************************************/
X
X#if (defined(__GO32__) && defined(unix))   /* DOS extender */
X#  undef unix
X#endif
X
X#if (defined(unix) && !defined(UNIX))
X#  define UNIX
X#endif /* unix && !UNIX */
X
X/* Much of the following is swiped from zip's tailor.h: */
X
X/* define MSDOS for Turbo C (unless OS/2) and Power C as well as Microsoft C
V */
X#ifdef __POWERC
X#  define __TURBOC__
X#  define MSDOS
X#endif /* __POWERC */
X#if (defined(__TURBOC__) && defined(__MSDOS__) && !defined(MSDOS))
X#  define MSDOS
X#endif
X
X/* use prototypes and ANSI libraries if __STDC__, or Microsoft or Borland C,
X * or Silicon Graphics, or Convex, or IBM C Set/2, or GNU gcc under emx, or
X * or Watcom C, or Macintosh, or Windows NT.
X */
X#if (__STDC__ `7C`7C defined(MSDOS) `7C`7C defined(sgi) `7C`7C defined(CONVE
VX))
X#  ifndef PROTO
X#    define PROTO
X#  endif
X#  define MODERN
X#endif
X#if (defined(__IBMC__) `7C`7C defined(__EMX__) `7C`7C defined(__WATCOMC__))
X#  ifndef PROTO
X#    define PROTO
X#  endif
X#  define MODERN
X#endif
X#if (defined(THINK_C) `7C`7C defined(MPW) `7C`7C defined(WIN32))
X#  ifndef PROTO
X#    define PROTO
X#  endif
X#  define MODERN
X#endif
X
X/* turn off prototypes if requested */
X#if (defined(NOPROTO) && defined(PROTO))
X#  undef PROTO
X#endif
X
X/* used to remove arguments in function prototypes for non-ANSI C */
X#ifdef PROTO
X#  define OF(a) a
X#else /* !PROTO */
X#  define OF(a) ()
X#endif /* ?PROTO */
X
X#if (defined(ultrix) `7C`7C defined(bsd4_2) `7C`7C defined(sun) `7C`7C defin
Ved(pyr))
X#  if (!defined(BSD) && !defined(__SYSTEM_FIVE) && !defined(SYSV))
X#    define BSD
X#  endif /* !BSD && !__SYSTEM_FIVE && !SYSV */
X#endif /* ultrix `7C`7C bsd4_2 `7C`7C sun `7C`7C pyr */
X
X#if (defined(CONVEX) `7C`7C defined(CRAY) `7C`7C defined(__SYSTEM_FIVE))
X#  ifndef TERMIO
X#    define TERMIO
X#  endif /* !TERMIO */
X#endif /* CONVEX `7C`7C CRAY `7C`7C __SYSTEM_FIVE */
X
X#ifdef pyr  /* Pyramid */
X#  ifndef ZMEM
X#    define ZMEM
X#  endif /* !ZMEM */
X#endif /* pyr */
X
X#ifdef CRAY
X#  ifdef ZMEM
X#    undef ZMEM
X#  endif /* ZMEM */
X#endif /* CRAY */
X
X/* the i386 test below is to catch SCO Unix (which has redefinition
X * warnings if param.h is included), but it probably doesn't hurt if
X * other 386 Unixes get nailed, too...except now that 386BSD and BSDI
X * exist.  Sigh.  <sys/param.h> is mostly included for "BSD", I think.
X * `5BAn alternate fix for SCO Unix is below.`5D
X */
X#if (defined(MINIX) `7C`7C (defined(i386) && defined(unix)))
X#  define NO_PARAM_H
X#endif /* MINIX `7C`7C (i386 && unix) */
X
X
X
X
X
X/***************************/
X/*  OS-Dependent Includes  */
X/***************************/
X
X#ifndef MINIX            /* Minix needs it after all the other includes (?)
V */
X#  include <stdio.h>
X#endif
X#include <ctype.h>       /* skip for VMS, to use tolower() function? */
X#include <errno.h>       /* used in mapname() */
X#ifndef NO_ERRNO
X#  define DECLARE_ERRNO  /* everybody except MSC 6.0, SCO cc, Watcom C/386 *
V/
X#endif /* !NO_ERRNO */
X#ifdef VMS
X#  include <types.h>     /* (placed up here instead of in VMS section below
V */
X#  include <stat.h>      /* because types.h is used in some other headers) *
V/
X#else /* !VMS */
X#  if !defined(THINK_C) && !defined(MPW)
X#    include <sys/types.h>                 /* off_t, time_t, dev_t, ... */
X#    include <sys/stat.h>
X#  endif /* !THINK_C && !MPW */
X#endif /* ?VMS */
X
X#ifdef MODERN
X#  if (!defined(M_XENIX) && !(defined(__GNUC__) && defined(sun)))
X#    include <stddef.h>
X#  endif
X#  if (!defined(__GNUC__) && !defined(apollo))   /* both define __STDC__ */
X#    include <stdlib.h>    /* standard library prototypes, malloc(), etc. */
X#  else
X#    ifdef __EMX__
X#      include <stdlib.h>  /* emx IS gcc but has stdlib.h */
X#    endif
X#  endif
X#  include <string.h>      /* defines strcpy, strcmp, memcpy, etc. */
X   typedef size_t extent;
X   typedef void voidp;
X#else /* !MODERN */
X   char *malloc();
X   char *strchr(), *strrchr();
X   long lseek();
X   typedef unsigned int extent;
X#  define void int
X   typedef char voidp;
X#endif /* ?MODERN */
X
X/* this include must be down here for SysV.4, for some reason... */
X#include <signal.h>      /* used in unzip.c, file_io.c */
X
X
X
X/*--------------------------------------------------------------------------
V-
X    Next, a word from our Unix (mostly) sponsors:
X  --------------------------------------------------------------------------
V-*/
X
X#ifdef UNIX
X#  ifdef AMIGA
X#    include <libraries/dos.h>
X#  else /* !AMIGA */
X#    ifndef NO_PARAM_H
X#if 0  /* `5BGRR: this is an alternate fix for SCO's redefinition bug`5D */
X#      ifdef NGROUPS_MAX
X#        undef NGROUPS_MAX     /* SCO bug:  defined again in <param.h> */
X#      endif /* NGROUPS_MAX */
X#endif /* 0 */
X#      include <sys/param.h>   /* conflict with <sys/types.h>, some systems?
V */
X#    endif /* !NO_PARAM_H */
X#  endif /* ?AMIGA */
X
X#  ifndef BSIZE
X#    ifdef MINIX
X#      define BSIZE   1024
X#    else /* !MINIX */
X#      define BSIZE   DEV_BSIZE  /* assume common for all Unix systems */
X#    endif /* ?MINIX */
X#  endif
X
X#  ifndef BSD
X#    if (!defined(AMIGA) && !defined(MINIX))
X#      define NO_MKDIR           /* for mapname() */
X#    endif /* !AMIGA && !MINIX */
X#    include <time.h>
X     struct tm *gmtime(), *localtime();
X#  else   /* BSD */
X#    include <sys/time.h>
X#    include <sys/timeb.h>
X#    ifdef _AIX
X#      include <time.h>
X#    endif
X#  endif
X
X#else   /* !UNIX */
X#  define BSIZE   512               /* disk block size */
X#endif /* ?UNIX */
X
X#if (defined(V7) `7C`7C defined(BSD))
X#  define strchr    index
X#  define strrchr   rindex
X#endif
X
X/*--------------------------------------------------------------------------
V-
X    And now, our MS-DOS and OS/2 corner:
X  --------------------------------------------------------------------------
V-*/
X
X#ifdef __TURBOC__
X#  define DOS_OS2
X#  include <sys/timeb.h>      /* for structure ftime
V                        */
X#  ifndef __BORLANDC__        /* there appears to be a bug (?) in Borland's
V */
X#    include <mem.h>          /*   MEM.H related to __STDC__ and far poin-
V  */
X#  endif                      /*   ters. (dpk)  `5Bmem.h included for memcpy
V`5D */
X#  include <dos.h>            /* for REGS macro (at least for Turbo C 2.0)
V  */
X#else                         /* NOT Turbo C (or Power C)...
V                */
X#  ifdef MSDOS                /*   but still MS-DOS, so we'll assume it's
V   */
X#    ifndef MSC               /*   Microsoft's compiler and fake the ID, if
V */
X#      define MSC             /*   necessary (it is in 5.0; apparently not
V  */
X#    endif                    /*   in 5.1 and 6.0)
V                          */
X#    include <dos.h>          /* for _dos_setftime()
V                        */
X#  endif
X#endif
X
X#if (defined(__IBMC__) && defined(__OS2__))
X#  define DOS_OS2
X#  define S_IFMT 0xF000
X#  define timezone _timezone
X#endif
X
X#ifdef __WATCOMC__
X#  define DOS_OS2
X#  define __32BIT__
X#  ifdef DECLARE_ERRNO
X#    undef DECLARE_ERRNO
X#  endif
X#  undef far
X#  define far
X#endif
X
X#ifdef __EMX__
X#  define DOS_OS2
X#  define __32BIT__
X#  define far
X#endif /* __EMX__ */
X
X#ifdef MSC                    /* defined for all versions of MSC now
V         */
X#  define DOS_OS2             /* Turbo C under DOS, MSC under DOS or OS/2
V    */
X#  if (defined(_MSC_VER) && (_MSC_VER >= 600))    /* new with 5.1 or 6.0 ...
V */
X#    undef DECLARE_ERRNO      /* errno is now a function in a dynamic link
V   */
X#  endif                      /*   library (or something)--incompatible with
V */
X#endif                        /*   the usual "extern int errno" declaration
V  */
X
X#ifdef DOS_OS2                /* defined for all MS-DOS and OS/2 compilers
V   */
X#  include <io.h>             /* lseek(), open(), setftime(), dup(), creat()
V */
X#  include <time.h>           /* localtime() */
X#endif
X
X#ifdef OS2                    /* defined for all OS/2 compilers */
X#  ifdef isupper
X#    undef isupper
X#  endif
X#  ifdef tolower
X#    undef tolower
X#  endif
X#  define isupper(x)   IsUpperNLS((unsigned char)(x))
X#  define tolower(x)   ToLowerNLS((unsigned char)(x))
X#endif
X
X#ifdef WIN32
X#  include <io.h>             /* read(), open(), etc. */
X#  include <time.h>
X#  include <memory.h>
X#  include <direct.h>         /* mkdir() */
X#  ifdef FILE_IO_C
X#    include <fcntl.h>
X#    include <conio.h>
X#    include <sys\types.h>
X#    include <sys\utime.h>
X#    include <windows.h>
X#    define DOS_OS2
X#    define getch() getchar()
X#  endif
X#endif
X
X/*--------------------------------------------------------------------------
V-
X    Followed by some VMS (mostly) stuff:
X  --------------------------------------------------------------------------
V-*/
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#  include <rms.h>
X#  define _MAX_PATH NAM$C_MAXRSS  /* to define FILNAMSIZ below */
X#  define UNIX                    /* can share most of same code from now on
V */
X#  define RETURN    return_VMS    /* VMS interprets return codes incorrectly
V */
X#else /* !VMS */
X#  ifndef THINK_C
X#    define RETURN  return        /* only used in main() */
X#  else
X#    define RETURN(v) `7B int n;\
X                        n = (v);\
X                        fprintf(stderr, "\npress <return> to continue ");\
X                        while (getc(stdin) != '\n');\
X                        putc('\n', stderr);\
X                        InitCursor();\
X                        goto start;\
X                      `7D
X#  endif
X#  ifdef V7
X#    define O_RDONLY  0
X#    define O_WRONLY  1
X#    define O_RDWR    2
X#  else /* !V7 */
X#    ifdef MTS
X#      include <sys/file.h>     /* MTS uses this instead of fcntl.h */
X#      include <timeb.h>
X#      include <time.h>
X#    else /* !MTS */
X#      ifdef COHERENT           /* Coherent 3.10/Mark Williams C */
X#        include <sys/fcntl.h>
X#        define SHORT_NAMES
X#        define tzset  settz
X#      else /* !COHERENT */
X#        include <fcntl.h>      /* O_BINARY for open() w/o CR/LF translation
V */
X#      endif /* ?COHERENT */
X#    endif /* ?MTS */
X#  endif /* ?V7 */
X#endif /* ?VMS */
X
X#if (defined(MSDOS) `7C`7C defined(VMS))
X#  define DOS_VMS
X#endif
X
X/*--------------------------------------------------------------------------
V-
X    And some Mac stuff for good measure:
X  --------------------------------------------------------------------------
V-*/
X
X#ifdef THINK_C
X#  define MACOS
X#  ifndef __STDC__            /* if Think C hasn't defined __STDC__ ... */
X#    define __STDC__ 1        /*   make sure it's defined: it needs it */
X#  else /* __STDC__ defined */
X#    if !__STDC__             /* sometimes __STDC__ is defined as 0; */
X#      undef __STDC__         /*   it needs to be 1 or required header */
X#      define __STDC__ 1      /*   files are not properly included. */
X#    endif /* !__STDC__ */
X#  endif /* ?defined(__STDC__) */
X#endif /* THINK_C */
X
X#ifdef MPW
X#  define MACOS
X#  include <Errors.h>
X#  include <Files.h>
X#  include <Memory.h>
X#  include <Quickdraw.h>
X#  include <ToolUtils.h>
X#  define CtoPstr c2pstr
X#  define PtoCstr p2cstr
X#  ifdef CR
X#    undef  CR
X#  endif
X#endif /* MPW */
X
X#ifdef MACOS
X#  define open(x,y) macopen(x,y, gnVRefNum, glDirID)
X#  define close macclose
X#  define read macread
X#  define write macwrite
X#  define lseek maclseek
X#  define creat(x,y) maccreat(x, gnVRefNum, glDirID, gostCreator, gostType)
X#  define stat(x,y) macstat(x,y,gnVRefNum, glDirID)
X
X#  ifndef isascii
X#    define isascii(c) ((unsigned char)(c) <= 0x3F)
X#  endif
X
X#  include "macstat.h"
X
Xtypedef struct _ZipExtraHdr `7B
X    unsigned short header;    /*    2 bytes */
X    unsigned short data;      /*    2 bytes */
X`7D ZIP_EXTRA_HEADER;
X
Xtypedef struct _MacInfoMin `7B
X    unsigned short header;    /*    2 bytes */
X    unsigned short data;      /*    2 bytes */
X    unsigned long signature;  /*    4 bytes */
X    FInfo finfo;              /*   16 bytes */
X    unsigned long lCrDat;     /*    4 bytes */
X    unsigned long lMdDat;     /*    4 bytes */
X    unsigned long flags ;     /*    4 bytes */
X    unsigned long lDirID;     /*    4 bytes */
X                              /*------------*/
X`7D MACINFOMIN;                 /* = 40 bytes for size of data */
X
Xtypedef struct _MacInfo `7B
X    unsigned short header;    /*    2 bytes */
X    unsigned short data;      /*    2 bytes */
+-+-+-+-+-+-+-+-  END  OF PART 11 +-+-+-+-+-+-+-+-
Technical Details
Message-ID: <8009648@MVB.SAIC.COM>
Path: arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!agate!dog.ee.lbl.gov!network.ucsd.edu!mvb.saic.com!vmsnet-sources

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!agate!dog.ee.lbl.gov!network.ucsd.edu!mvb.saic.com!vmsnet-sources
From: goathunter@wkuvx1.bitnet
Newsgroups: vmsnet.sources
Subject: Zip v1.9 & UnZip v5.0, part 11/22
Message-ID: <8009648@MVB.SAIC.COM>
Date: Tue, 01 Sep 1992 22:51:38 GMT
Organization: Western Kentucky University, Bowling Green, KY
Lines: 1332
Approved: Mark.Berryman@Mvb.Saic.Com