🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: vmsnet.sources
Article #65

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

#65
From: goathunter
Date: Tue, 01 Sep 1992 22:48
1547 lines
49586 bytes
Submitted-by: goathunter@wkuvx1.bitnet
Posting-number: Volume 3, Issue 125
Archive-name: zip_unzip/part03

-+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+
X    /* same test as in zipbare() in crypt.c: */
X    if ((UWORD)(c `7C (b<<8)) != (pInfo->ExtLocHdr? lrec.last_mod_file_time
V :
X        (UWORD)(lrec.crc32 >> 16)))
X        return -1;  /* bad */
X
X    /* password OK:  decrypt current buffer contents before leaving */
X    for (n = (longint)incnt > csize ? (int)csize : incnt, p = inptr; n--; p+
V+)
X        *p = (byte) DECRYPT(*p);
X    return 0;       /* OK */
X
X`7D /* end function testp() */
X
X#endif /* CRYPT */
X
X
X
X
X
X/*******************************/
X/*  Function ReadMemoryByte()  */
X/*******************************/
X
Xint ReadMemoryByte(x)   /* return PK-type error code */
X    UWORD *x;
X`7B
X    if (mem_i_offset < mem_i_size) `7B
X        *x = (UWORD) mem_i_buffer`5Bmem_i_offset++`5D;
X        return 8;
X    `7D else
X        return 0;
X`7D
X
X
X
X
X
X/****************************/
X/*  Function FlushMemory()  */
X/****************************/
X
Xint FlushMemory()   /* return PK-type error code */
X`7B
X    if (outcnt == 0)
X        return 0;
X
X    if (mem_o_offset + outcnt <= mem_o_size) `7B
X        memcpy((char *)(mem_o_buffer+mem_o_offset), (char *)outbuf, outcnt);
X        mem_o_offset += outcnt;
X        return 0;
X    `7D else
X        return 50;
X`7D
X
X
X
X
X
X/***************************/
X/*  Function memextract()  */   /* extract compressed extra field block */
X/***************************/
X
Xint memextract(tgt, tgtsize, src, srcsize)  /* return 0 if success, 1 if not
V */
X    byte *tgt, *src;
X    ULONG tgtsize, srcsize;
X`7B
X    UWORD method, error = 0;
X    ULONG crc, oldcrc;
X
X    method = makeword(src);
X    crc = makelong(src+2);
X
X    mem_i_buffer = src + 2 + 4;      /* method and crc */
X    mem_i_size   = srcsize - 2 - 4;
X    mem_i_offset = 0;
X `20
X    mem_o_buffer = tgt;
X    mem_o_size   = tgtsize;
X    mem_o_offset = 0;
X
X    mem_mode = 1;
X
X    bits_left = 0;
X    bitbuf = 0L;
X    outpos = 0L;
X    outcnt = 0;
X    outptr = outbuf;
X    zipeof = 0;
X
X    switch (method) `7B
X        case STORED:
X            memcpy(tgt, src + 2 + 4, (extent) (srcsize - 2 - 4));
X            break;
X        case DEFLATED:
X            inflate();
X            FlushOutput();
X            break;
X        default:
X            fprintf(stderr,
X              "warning:  unsupported extra field compression type--skipping\
Vn");
X            error = 1;   /* GRR:  this should be passed on up via SetEAs() *
V/
X            break;
X    `7D
X
X    mem_mode = 0;
X
X    if (!error) `7B
X        oldcrc = crc32val;
X        crc32val = 0xFFFFFFFFL;
X        UpdateCRC((unsigned char *) mem_o_buffer, (int) mem_o_size);
X        crc32val = (`7Ecrc32val) & 0xFFFFFFFFL;
X
X        if (crc32val != crc) `7B
X            printf("(Bad extra field CRC %08lx, should be %08lx)\n", crc32va
Vl,
X              crc);
X            error = 1;
X        `7D
X        crc32val = oldcrc; /* grrr ... this ugly kludge should be fixed */
X    `7D
X
X    return error;
X`7D
$ CALL UNPACK [.UNZIP50]EXTRACT.C;1 241729109
$ create 'f'
X/*--------------------------------------------------------------------------
V-
X
X  file_io.c
X
X  This file contains routines for doing direct input/output, file-related
X  sorts of things.  Most of the system-specific code for unzip is contained
X  here, including the non-echoing password code for decryption (bottom).
X
X  --------------------------------------------------------------------------
V-*/
X
X
X#ifndef __GO32__
X#  define const
X#endif
X
X#define FILE_IO_C
X#include "unzip.h"
X
X#ifdef  MSWIN
X#  include "wizunzip.h"
X#endif
X
X
X/************************************/
X/*  File_IO Local Prototypes, etc.  */
X/************************************/
X
X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
X   static int dos2unix __((unsigned char *buf, int len));
X   int CR_flag = 0;      /* when last char of buffer == CR (for dos2unix())
V */
X#endif
X
X#ifdef OS2
X   extern int   longname;          /* set in mapname.c */
X   extern char  longfilename`5B`5D;
X#endif
X
X#ifdef CRYPT
X#  if (defined(DOS_OS2) `7C`7C defined(VMS))
X#    define MSVMS
X#    ifdef DOS_OS2
X#      ifdef __EMX__
X#        define getch() _read_kbd(0, 1, 0)
X#      else
X#        ifdef __GO32__
X#          include <pc.h>
X#          define getch() getkey()
X#        else /* !__GO32__ */
X#          include <conio.h>
X#        endif /* ?__GO32__ */
X#      endif
X#    else /* !DOS_OS2 */
X#      define getch() getc(stderr)
X#      define OFF 0   /* for echo control */
X#      define ON 1
X#      define echoff(f) echo(OFF)
X#      define echon()   echo(ON)
X#      include <descrip.h>
X#      include <iodef.h>
X#      include <ttdef.h>
X#      if !defined(SS$_NORMAL)
X#        define SS$_NORMAL 1   /* only thing we need from <ssdef.h> */
X#      endif
X#    endif /* ?DOS_OS2 */
X#  else /* !(DOS_OS2 `7C`7C VMS) */
X#    ifdef TERMIO       /* Amdahl, Cray, all SysV? */
X#      ifdef CONVEX
X#        include <sys/termios.h>
X#        include <sgtty.h>
X#      else /* !CONVEX */
X#        ifdef LINUX
X#          include <termios.h>
X#        else /* !LINUX */
X#          include <sys/termio.h>
X#        endif /* ?LINUX */
X#        define sgttyb termio
X#        define sg_flags c_lflag
X#      endif /* ?CONVEX */
X       int ioctl OF((int, int, voidp *));
X#      define GTTY(f,s) ioctl(f,TCGETA,(voidp *)s)
X#      define STTY(f,s) ioctl(f,TCSETAW,(voidp *)s)
X#    else /* !TERMIO */
X#      if (!defined(MINIX) && !defined(__386BSD__))
X#        include <sys/ioctl.h>
X#      endif /* !MINIX && !__386BSD__ */
X#      include <sgtty.h>
X#      ifdef __386BSD__
X#        define GTTY(f, s) ioctl(f, TIOCGETP, (voidp *) s)
X#        define STTY(f, s) ioctl(f, TIOCSETP, (voidp *) s)
X#      else /* !__386BSD__ */
X#        define GTTY gtty
X#        define STTY stty
X         int gtty OF((int, struct sgttyb *));
X         int stty OF((int, struct sgttyb *));
X#      endif /* ?__386BSD__ */
X#    endif /* ?TERMIO */
X     int isatty OF((int));
X     char *ttyname OF((int));
X#    if (defined(PROTO) && !defined(__GNUC__) && !defined(_AIX))
X       int open (char *, int, ...);
X#    endif
X     int close OF((int));
X     int read OF((int, voidp *, int));
X#  endif /* ?(DOS_OS2 `7C`7C VMS) */
X#endif /* CRYPT */
X
X
X
X
X
X/******************************/
X/* Function open_input_file() */
X/******************************/
X
Xint open_input_file()    /* return non-zero if open failed */
X`7B
X    /*
X     *  open the zipfile for reading and in BINARY mode to prevent cr/lf
X     *  translation, which would corrupt the bitstreams
X     */
X
X#ifdef VMS
X    zipfd = open(zipfn, O_RDONLY, 0, "ctx=stm");
X#else /* !VMS */
X#ifdef UNIX
X    zipfd = open(zipfn, O_RDONLY);
X#else /* !UNIX */
X#ifdef MACOS
X    zipfd = open(zipfn, 0);
X#else /* !MACOS */
X    zipfd = open(zipfn, O_RDONLY `7C O_BINARY);
X#endif /* ?MACOS */
X#endif /* ?UNIX */
X#endif /* ?VMS */
X    if (zipfd < 1) `7B
X        fprintf(stderr, "error:  can't open zipfile `5B %s `5D\n", zipfn);
X        return (1);
X    `7D
X    return 0;
X`7D
X
X
X
X
X
X/**********************/
X/* Function readbuf() */
X/**********************/
X
Xint readbuf(buf, size)
X    char *buf;
X    register unsigned size;
X`7B                               /* return number of bytes read into buf */
X    register int count;
X    int n;
X
X    n = size;
X    while (size) `7B
X        if (incnt == 0) `7B
X            if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) <= 0)
X                return (n-size);
X            /* buffer ALWAYS starts on a block boundary:  */
X            cur_zipfile_bufstart += INBUFSIZ;
X            inptr = inbuf;
X        `7D
X        count = MIN(size, (unsigned)incnt);
X        memcpy(buf, inptr, count);
X        buf += count;
X        inptr += count;
X        incnt -= count;
X        size -= count;
X    `7D
X    return (n);
X`7D
X
X
X
X
X
X#ifndef VMS   /* for VMS use code in vms.c (old VMS code below is retained
X               * in case of problems...will be removed in a later release) *
V/
X
X/*********************************/
X/* Function create_output_file() */
X/*********************************/
X
Xint create_output_file()         /* return non-0 if creat failed */
X`7B
X/*--------------------------------------------------------------------------
V-
X    Create the output file with appropriate permissions.  If we've gotten to
X    this point and the file still exists, we have permission to blow it away
V.
X  --------------------------------------------------------------------------
V-*/
X
X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
X    CR_flag = 0;   /* hack to get CR at end of buffer working */
X#endif
X
X#if (defined(UNIX) && !defined(AMIGA))
X    `7B
X        int mask;
X
X#ifndef VMS
X        if (!stat(filename, &statbuf) && (unlink(filename) < 0)) `7B
X            fprintf(stderr, "\n%s:  cannot delete old copy\n", filename);
X            return 1;
X        `7D
X#       define EXTRA_ARGS
X#else /* VMS */
X#       define EXTRA_ARGS   ,"rfm=stmlf","rat=cr"
X#endif /* ?VMS */
X
X        mask = umask(0);   /* now know that we own it */
X        outfd = creat(filename, 0xffff & pInfo->unix_attr  EXTRA_ARGS);
X        umask(mask);                                            /* VMS, Unix
V */
X    `7D
X#else /* !UNIX `7C`7C AMIGA */  /* file permissions set after file closed */
X#ifndef MACOS
X    outfd = creat(filename, S_IWRITE `7C S_IREAD);     /* DOS, OS2, Mac, Ami
Vga */
X#else /* MACOS */
X    `7B
X        short fDataFork=TRUE;
X        MACINFO mi;
X        OSErr err;
X
X        fMacZipped = FALSE;
X        CtoPstr(filename);
X        if (extra_field &&
X            (lrec.extra_field_length > sizeof(MACINFOMIN)) &&
X            (lrec.extra_field_length <= sizeof(MACINFO))) `7B
X            BlockMove(extra_field, &mi, lrec.extra_field_length);
X            if ((makeword((byte *)&mi.header) == 1992) &&
X                (makeword((byte *)&mi.data) ==
X                  lrec.extra_field_length-sizeof(ZIP_EXTRA_HEADER)) &&
X                (mi.signature == 'JLEE')) `7B
X                gostCreator = mi.finfo.fdCreator;
X                gostType = mi.finfo.fdType;
X                fDataFork = (mi.flags & 1) ? TRUE : FALSE;
X                fMacZipped = true;
X                /* If it was Zipped w/Mac version, the filename has either *
V/
X                /* a 'd' or 'r' appended.  Remove the d/r when unzipping */
X                filename`5B0`5D-=1;
X            `7D
X        `7D
X        if (!fMacZipped) `7B
X            if (!aflag)
X                gostType = gostCreator = '\?\?\?\?';
X            else `7B
X#ifdef THINK_C
X                gostCreator = 'KAHL';
X#else
X#ifdef MCH_MACINTOSH
X                gostCreator = 'Manx';
X#else
X                gostCreator = 'MPS ';
X#endif
X#endif
X                gostType = 'TEXT';
X            `7D
X        `7D
X        PtoCstr(filename);
X
X        outfd = creat(filename, 0);
X        if (fMacZipped) `7B
X            CtoPstr(filename);
X            if (hfsflag) `7B
X                HParamBlockRec   hpbr;
X   `20
X                hpbr.fileParam.ioNamePtr = (StringPtr)filename;
X                hpbr.fileParam.ioVRefNum = gnVRefNum;
X                hpbr.fileParam.ioDirID = glDirID;
X                hpbr.fileParam.ioFlFndrInfo = mi.finfo;
X                hpbr.fileParam.ioFlCrDat = mi.lCrDat;
X                hpbr.fileParam.ioFlMdDat = mi.lMdDat;
X                err = PBHSetFInfo(&hpbr, 0);
X            `7D else `7B
X                err = SetFInfo((StringPtr)filename , 0, &mi.finfo);
X            `7D
X            PtoCstr(filename);
X        `7D
X        if (outfd != -1)
X            outfd = open(filename, (fDataFork)? 1 : 2);
X    `7D
X#endif /* ?MACOS */
X#endif /* ?(UNIX && !AMIGA) */
X
X    if (outfd < 1) `7B
X        fprintf(stderr, "\n%s:  cannot create\n", filename);
X        return 1;
X    `7D
X
X/*--------------------------------------------------------------------------
V-
X    If newly created file is in text mode and should be binary (to disable
X    automatic CR/LF translations), either close it and reopen as binary or
X    else change the mode to binary (DOS, OS/2).
X  --------------------------------------------------------------------------
V-*/
X
X#if (!defined(UNIX) && !defined(MACOS))
X    if (!aflag) `7B
X#ifdef DOS_OS2
X        if (setmode(outfd, O_BINARY) == -1) `7B
X#else /* !DOS_OS2 */
X        close(outfd);
X        if ((outfd = open(filename, O_RDWR `7C O_BINARY)) < 1) `7B
X#endif /* ?DOS_OS2 */
X            fprintf(stderr, "Can't make output file binary:  %s\n", filename
V);
X            return 1;
X        `7D
X    `7D
X#endif /* !UNIX && !MACOS */
X
X    return 0;
X`7D
X
X#endif /* !VMS */
X
X
X
X
X
X/****************************/
X/* Function FillBitBuffer() */
X/****************************/
X
Xint FillBitBuffer()
X`7B
X    /*
X     * Fill bitbuf, which is 32 bits.  This function is only used by the
X     * READBIT and PEEKBIT macros (which are used by all of the uncompressio
Vn
X     * routines).
X     */
X    UWORD temp;
X
X    zipeof = 1;
X    while (bits_left < 25 && ReadByte(&temp) == 8)
X    `7B
X      bitbuf `7C= (ULONG)temp << bits_left;
X      bits_left += 8;
X      zipeof = 0;
X    `7D
X    return 0;
X`7D
X
X
X
X
X
X/***********************/
X/* Function ReadByte() */
X/***********************/
X
Xint ReadByte(x)
X    UWORD *x;
X`7B
X    /*
X     * read a byte; return 8 if byte available, 0 if not
X     */
X
X    if (mem_mode)
X        return ReadMemoryByte(x);
X
X    if (csize-- <= 0)
X        return 0;
X
X    if (incnt == 0) `7B
X        if ((incnt = read(zipfd, (char *)inbuf, INBUFSIZ)) <= 0)
X            return 0;
X        /* buffer ALWAYS starts on a block boundary:  */
X        cur_zipfile_bufstart += INBUFSIZ;
X        inptr = inbuf;
X#ifdef CRYPT
X        if (pInfo->encrypted) `7B
X            byte *p;
X            int n, t;
X
X            for (n = (longint)incnt > csize + 1 ? (int)csize + 1 : incnt,
X                 p = inptr; n--; p++)
X                *p = (byte) DECRYPT(*p);
X        `7D
X#endif /* CRYPT */
X    `7D
X    *x = *inptr++;
X    --incnt;
X    return 8;
X`7D
X
X
X
X
X
X#ifndef VMS   /* for VMS use code in vms.c */
X
X/**************************/
X/* Function FlushOutput() */
X/**************************/
X
Xint FlushOutput()
X`7B
X    /*
X     * flush contents of output buffer; return PK-type error code
X     */
X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
X    int saved_ctrlZ = FALSE;
X#endif
X    int len;
X
X
X    if (mem_mode) `7B
X        int rc = FlushMemory();
X        outpos += outcnt;
X        outcnt = 0;
X        outptr = outbuf;
X        return rc;
X    `7D
X
X    if (disk_full) `7B
X        outpos += outcnt;   /* fake emptied buffer */
X        outcnt = 0;
X        outptr = outbuf;
X        return 50;          /* ignore rest of this file */
X    `7D
X
X    if (outcnt) `7B
X        UpdateCRC(outbuf, outcnt);
X
X        if (!tflag) `7B
X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
X            if (aflag) `7B
X                if (outbuf`5Boutcnt-1`5D == CTRLZ) `7B
X                    --outcnt;
X                    saved_ctrlZ = TRUE;
X                `7D
X                len = dos2unix(outbuf, outcnt);
X            `7D else
X#endif /* !DOS_OS2 `7C`7C MSWIN */
X                len = outcnt;
X#ifdef MACOS
X            if ((giCursor+1) >> 2 != (giCursor>>2))
X                SetCursor( *rghCursor`5B((giCursor+1)>>2)&0x03`5D );
X            giCursor = (giCursor+1) & 15;
X#endif /* MACOS */
X#ifdef MSWIN
X            /* if writing to console vs. actual file, write to Msg Window */
X            if (cflag)
X                WriteBufferToMsgWin(outout, len, FALSE);
X            else if (_lwrite(outfd, outout, len) != (UINT)len)
X#else /* !MSWIN */
X            if (write(outfd, (char *)outout, len) != len)
X#endif /* ?MSWIN */
X#ifdef DOS_OS2
X                if (!cflag)           /* `5EZ treated as EOF, removed with -
Vc */
X#else /* !DOS_OS2 */
X#ifdef MINIX
X                if (errno == EFBIG)
X                    if (write(fd, outout, len/2) != len/2  `7C`7C
X                        write(fd, outout+len/2, len/2) != len/2)
X#endif /* MINIX */
X#endif /* ?DOS_OS2 */
X                `7B
X                    /* GRR: add test for force_flag when has its own switch
V */
X                    fprintf(stderr,
X                      "\n%s:  write error (disk full?).  Continue? (y/n/`5EC
V) ",
X                      filename);
X                    FFLUSH   /* for Amiga and Mac MPW */
X#ifdef MSWIN
X                    disk_full = 2;
X#else /* !MSWIN */
X                    fgets(answerbuf, 9, stdin);
X                    if (*answerbuf == 'y')   /* stop writing to this file */
X                        disk_full = 1;       /*  (outfd bad?), but new OK */
X                    else
X                        disk_full = 2;       /* no:  exit program */
X#endif /* ?MSWIN */
X                    return 50;    /* 50:  disk full */
X                `7D
X        `7D
X        outpos += outcnt;
X        outcnt = 0;
X        outptr = outbuf;
X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
X        if (saved_ctrlZ) `7B
X            *outptr++ = CTRLZ;
X            ++outcnt;
X        `7D
X#endif /* !DOS_OS2 `7C`7C MSWIN */
X    `7D
X    return 0;                   /* 0:  no error */
X`7D
X
X#endif /* !VMS */
X
X
X
X
X
X#if (!defined(DOS_OS2) `7C`7C defined(MSWIN))
X
X/***********************/
X/* Function dos2unix() */
X/***********************/
X
Xstatic int dos2unix(buf, len)   /* GRR:  rewrite for generic text conversion
Vs */
X    unsigned char *buf;
X    int len;
X`7B
X    int new_len;
X    int i;
X#ifdef MSWIN
X    unsigned char __far *walker;
X#else /* !MSWIN */
X    unsigned char *walker;
X#endif /* ?MSWIN */
X
X    new_len = len;
X    walker = outout;
X#ifdef MACOS
X    /*
X     * Mac wants to strip LFs instead CRs from CRLF pairs
X     */
X    if (CR_flag && *buf == LF) `7B
X        buf++;
X        new_len--;
X        len--;
X        CR_flag = buf`5Blen`5D == CR;
X    `7D
X    else
X        CR_flag = buf`5Blen - 1`5D == CR;
X    for (i = 0; i < len; i += 1) `7B
X        *walker++ = ascii_to_native(*buf);
X        if (*buf == LF) walker`5B-1`5D = CR;
X        if (*buf++ == CR && *buf == LF) `7B
X            new_len--;
X            buf++;
X            i++;
X        `7D
X    `7D
X#else /* !MACOS */
X    if (CR_flag && *buf != LF)
X        *walker++ = ascii_to_native(CR);
X    CR_flag = buf`5Blen - 1`5D == CR;
X    for (i = 0; i < len; i += 1) `7B
X        *walker++ = ascii_to_native(*buf);
X        if (*buf++ == CR && *buf == LF) `7B
X            new_len--;
X            walker`5B-1`5D = ascii_to_native(*buf++);
X            i++;
X        `7D
X    `7D
X    /*
X     * If the last character is a CR, then "ignore it" for now...
X     */
X    if (walker`5B-1`5D == ascii_to_native(CR))
X        new_len--;
X#endif /* ?MACOS */
X    return new_len;
X`7D
X
X#endif /* !DOS_OS2 `7C`7C MSWIN */
X
X
X
X
X
X#ifdef __GO32__
X
Xvoid _dos_setftime(int fd, UWORD dosdate, UWORD dostime)
X`7B
X    asm("pushl %ebx");
X    asm("movl %0, %%ebx": : "g" (fd));
X    asm("movl %0, %%ecx": : "g" (dostime));
X    asm("movl %0, %%edx": : "g" (dosdate));
X    asm("movl $0x5701, %eax");
X    asm("int $0x21");
X    asm("popl %ebx");
X`7D
X
Xvoid _dos_setfileattr(char *name, int attr)
X`7B
X    asm("movl %0, %%edx": : "g" (name));
X    asm("movl %0, %%ecx": : "g" (attr));
X    asm("movl $0x4301, %eax");
X    asm("int $0x21");
X`7D
X
X#endif /* __GO32__ */
X
X
X
X
X
X#ifdef DOS_OS2
X
X/**************************************/
X/* Function set_file_time_and_close() */
X/**************************************/
X
Xvoid set_file_time_and_close()
X /*
X  * MS-DOS AND OS/2 VERSION (Mac, Unix/VMS versions are below)
X  *
X  * Set the output file date/time stamp according to information from the
X  * zipfile directory record for this member, then close the file and set
X  * its permissions (archive, hidden, read-only, system).  Aside from closin
Vg
X  * the file, this routine is optional (but most compilers support it).
X  */
X`7B
X/*--------------------------------------------------------------------------
V-
X    Allocate local variables needed by OS/2 and Turbo C.
X  --------------------------------------------------------------------------
V-*/
X
X#ifdef __TURBOC__
X
X    union `7B
X        struct ftime ft;        /* system file time record */
X        struct `7B
X            UWORD ztime;        /* date and time words */
X            UWORD zdate;        /* .. same format as in .ZIP file */
X        `7D zt;
X    `7D td;
X
X#endif                          /* __TURBOC__ */
X
X/*--------------------------------------------------------------------------
V-
X     Do not attempt to set the time stamp on standard output.
X  --------------------------------------------------------------------------
V-*/
X
X    if (cflag) `7B
X        close(outfd);
X        return;
X    `7D
X
X/*--------------------------------------------------------------------------
V-
X    Copy and/or convert time and date variables, if necessary; then set the
X    file time/date.
X  --------------------------------------------------------------------------
V-*/
X
X#ifndef OS2
X#ifdef __TURBOC__
X    td.zt.ztime = lrec.last_mod_file_time;
X    td.zt.zdate = lrec.last_mod_file_date;
X    setftime(outfd, &td.ft);
X#else /* !__TURBOC__ */
X#ifdef WIN32
X    `7B
X        FILETIME ft;     /* 64-bit value made up of two 32 bit `5Blow & high
V`5D */
X        WORD wDOSDate;   /* for vconvertin from DOS date to Windows NT */
X        WORD wDOSTime;
X        HANDLE hFile;    /* file handle (defined in Windows NT) */
X
X        wDOSTime = (WORD) lrec.last_mod_file_time;
X        wDOSDate = (WORD) lrec.last_mod_file_date;
X
X        /* The DosDateTimeToFileTime() function converts a DOS date/time
X         * into a 64 bit Windows NT file time */
X        DosDateTimeToFileTime(wDOSDate, wDOSTime, &ft);
X
X        /* Close the file and then re-open it using the Win32
X         * CreateFile call, so that the file can be created
X         * with GENERIC_WRITE access, otherwise the SetFileTime
X         * call will fail. */
X        close(outfd);
X
X        hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
X             FILE_ATTRIBUTE_NORMAL, NULL);
X
X        if (!SetFileTime(hFile, NULL, NULL, &ft))
X            printf("\nSetFileTime failed: %d\n", GetLastError());
X        CloseHandle(hFile);
X        return;
X    `7D
X#else /* !WIN32 */
X    _dos_setftime(outfd, lrec.last_mod_file_date, lrec.last_mod_file_time);
X#endif /* ?WIN32 */
X#endif /* ?__TURBOC__ */
X#endif /* ?OS2 */
X
X/*--------------------------------------------------------------------------
V-
X    And finally we can close the file...at least everybody agrees on how to
X    do *this*.  I think...  Oh yeah, also change the mode according to the
X    stored file attributes, since we didn't do that when we opened the dude.
X  --------------------------------------------------------------------------
V-*/
X
X    close(outfd);
X
X#ifdef OS2
X    SetPathInfo(filename, lrec.last_mod_file_date,
X                          lrec.last_mod_file_time, pInfo->dos_attr);
X    if (extra_field)
X        SetEAs(filename, extra_field);
X    if (longname)
X        SetLongNameEA(filename, longfilename);
X#else /* !OS2 */
X#ifdef __TURBOC__
X    if (_chmod(filename, 1, pInfo->dos_attr) != pInfo->dos_attr)
X        fprintf(stderr, "\nwarning:  file attributes may not be correct\n");
X#else /* !__TURBOC__ */
X#ifdef WIN32
X    /* Attempt to set the file attributes.  SetFileAttributes returns
X     * FALSE (0) if unsucessful, in which case print an error message,
X     * with error value returned from GetLastError call. */
X    pInfo->dos_attr = pInfo->dos_attr & 0x7F;
X
X    if (!(SetFileAttributes(filename, pInfo->dos_attr)))
X        fprintf(stderr, "\nwarning (%d): could not set file attributes\n",
X          GetLastError());
X#else /* !WIN32 */
X    _dos_setfileattr(filename, pInfo->dos_attr);
X#endif /* ?WIN32 */
X#endif /* ?__TURBOC__ */
X#endif /* ?OS2 */
X
X`7D /* end function set_file_time_and_close() (DOS, OS/2) */
X
X
X
X
X
X#else                           /* !DOS_OS2 */
X#ifdef MACOS                    /* Mac */
X
X/**************************************/
X/* Function set_file_time_and_close() */
X/**************************************/
X
Xvoid set_file_time_and_close()
X /*
X  * MAC VERSION
X  */
X`7B
X    long m_time;
X    DateTimeRec dtr;
X    ParamBlockRec pbr;
X    HParamBlockRec hpbr;
X    OSErr err;
X
X    if (outfd != 1) `7B
X        close(outfd);
X
X        /*
X         * Macintosh bases all file modification times on the number of seco
Vnds
X         * elapsed since Jan 1, 1904, 00:00:00.  Therefore, to maintain
X         * compatibility with MS-DOS archives, which date from Jan 1, 1980,
X         * with NO relation to GMT, the following conversions must be made:
X         *      the Year (yr) must be incremented by 1980;
X         *      and converted to seconds using the Mac routine Date2Secs(),
X         *      almost similar in complexity to the Unix version :-)
X         *                                     J. Lee
X         */
X
X        dtr.year = (((lrec.last_mod_file_date >> 9) & 0x7f) + 1980);
X        dtr.month = ((lrec.last_mod_file_date >> 5) & 0x0f);
X        dtr.day = (lrec.last_mod_file_date & 0x1f);
X
X        dtr.hour = ((lrec.last_mod_file_time >> 11) & 0x1f);
X        dtr.minute = ((lrec.last_mod_file_time >> 5) & 0x3f);
X        dtr.second = ((lrec.last_mod_file_time & 0x1f) * 2);
X
X        Date2Secs(&dtr, (unsigned long *)&m_time);
X        CtoPstr(filename);
X        if (hfsflag) `7B
X            hpbr.fileParam.ioNamePtr = (StringPtr)filename;
X            hpbr.fileParam.ioVRefNum = gnVRefNum;
X            hpbr.fileParam.ioDirID = glDirID;
X            hpbr.fileParam.ioFDirIndex = 0;
X            err = PBHGetFInfo(&hpbr, 0L);
X            hpbr.fileParam.ioFlMdDat = m_time;
X            if ( !fMacZipped )
X                hpbr.fileParam.ioFlCrDat = m_time;
X            hpbr.fileParam.ioDirID = glDirID;
X            if (err == noErr)
X                err = PBHSetFInfo(&hpbr, 0L);
X            if (err != noErr)
X                printf("error:  can't set the time for %s\n", filename);
X        `7D else `7B
X            pbr.fileParam.ioNamePtr = (StringPtr)filename;
X            pbr.fileParam.ioVRefNum = pbr.fileParam.ioFVersNum =
X              pbr.fileParam.ioFDirIndex = 0;
X            err = PBGetFInfo(&pbr, 0L);
X            pbr.fileParam.ioFlMdDat = pbr.fileParam.ioFlCrDat = m_time;
X            if (err == noErr)
X                err = PBSetFInfo(&pbr, 0L);
X            if (err != noErr)
X                printf("error:  can't set the time for %s\n", filename);
X        `7D
X
X        /* set read-only perms if needed */
X        if ((err == noErr) && !(pInfo->unix_attr & S_IWRITE)) `7B
X            if (hfsflag) `7B
X                hpbr.fileParam.ioNamePtr = (StringPtr)filename;
X                hpbr.fileParam.ioVRefNum = gnVRefNum;
X                hpbr.fileParam.ioDirID = glDirID;
X                err = PBHSetFLock(&hpbr, 0);
X            `7D else
X                err = SetFLock((ConstStr255Param)filename, 0);
X        `7D
X        PtoCstr(filename);
X    `7D
X`7D
X
X
X
X
X
X#else /* !MACOS... */
X#if (!defined(MTS) && !defined(VMS))   /* && !MTS (can't do) && !VMS: only o
Vne
X                                  * left is UNIX (for VMS use code in vms.c)
V */
X
X/**************************************/
X/* Function set_file_time_and_close() */
X/**************************************/
X
Xvoid set_file_time_and_close()
X /*
X  * UNIX VERSION (MS-DOS & OS/2, Mac versions are above)
X  */
X`7B
X    static short yday`5B`5D=`7B0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
V 304, 334`7D;
X    long m_time;
X    int yr, mo, dy, hh, mm, ss, leap, days=0;
X    struct utimbuf `7B
X        time_t actime;          /* new access time */
X        time_t modtime;         /* new modification time */
X    `7D tp;
X#ifdef AMIGA
X#   define YRBASE  1978         /* in AmigaDos, counting begins 01-Jan-1978
V */
X    struct DateStamp myadate;
X/*  extern char *_TZ;   no longer used? */
X#else /* !AMIGA */
X#   define YRBASE  1970
X#ifdef BSD
X#ifndef __386BSD__
X    static struct timeb tbp;
X#endif /* !__386BSD__ */
X#else /* !BSD */
X    extern long timezone;
X#endif /* ?BSD */
X#endif /* ?AMIGA */
X
X
X    /*
X     * Close the file *before* setting its time under Unix and AmigaDos.
X     */
X#ifdef AMIGA
X    if (cflag)                  /* can't set time on stdout */
X        return;
X    close(outfd);
X#else /* !AMIGA */
X    close(outfd);
X    if (cflag)                  /* can't set time on stdout */
X        return;
X#endif /* ?AMIGA */
X
X    /*
X     * These date conversions look a little weird, so I'll explain.
X     * UNIX bases all file modification times on the number of seconds
X     * elapsed since Jan 1, 1970, 00:00:00 GMT.  Therefore, to maintain
X     * compatibility with MS-DOS archives, which date from Jan 1, 1980,
X     * with NO relation to GMT, the following conversions must be made:
X     *      the Year (yr) must be incremented by 10;
X     *      the Date (dy) must be decremented by 1;
X     *      and the whole mess must be adjusted by TWO factors:
X     *          relationship to GMT (ie.,Pacific Time adds 8 hrs.),
X     *          and whether or not it is Daylight Savings Time.
X     * Also, the usual conversions must take place to account for leap years
V,
X     * etc.
X     *                                     C. Seaman
X     */
X
X    /* dissect date */
X    yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + (1980 - YRBASE);
X    mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
X    dy = (lrec.last_mod_file_date & 0x1f) - 1;
X
X    /* dissect time */
X    hh = (lrec.last_mod_file_time >> 11) & 0x1f;
X    mm = (lrec.last_mod_file_time >> 5) & 0x3f;
X    ss = (lrec.last_mod_file_time & 0x1f) * 2;
X
X    /* leap = # of leap years from BASE up to but not including current year
V */
X    leap = ((yr + YRBASE - 1) / 4);   /* leap year base factor */
X
X    /* How many days from BASE to this year? (& add expired days this year)
V */
X    days = (yr * 365) + (leap - 492) + yday`5Bmo`5D;
X
X    /* if year is a leap year and month is after February, add another day *
V/
X    if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
X        ++days;                 /* OK through 2199 */
X
X#ifdef AMIGA
X/*  _TZ = getenv("TZ"); does Amiga not have TZ and tzset() after all? */
X    myadate.ds_Days   =   days+dy-2;   /* off by one? */
X    myadate.ds_Minute =   hh*60+mm;
X    myadate.ds_Tick   =   ss*TICKS_PER_SECOND;
X
X    if (!(SetFileDate(filename, &myadate)))
X        fprintf(stderr, "error:  can't set the time for %s\n", filename);
X
X#else /* !AMIGA */
X    /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
X    m_time = ((days + dy) * 86400) + (hh * 3600) + (mm * 60) + ss;
X
X#ifdef BSD
X#ifndef __386BSD__
X    ftime(&tbp);
X    m_time += tbp.timezone * 60L;
X#endif
X/* #elif WIN32
X * don't do anything right now (esp. since "elif" is not legal for old cc's
V */
X#else /* !BSD */
X    tzset();                    /* set `60timezone' */
X    m_time += timezone;         /* account for timezone differences */
X#endif /* ?BSD */
X
X#ifdef __386BSD__
X    m_time += localtime(&m_time)->tm_gmtoff;
X#else
X    if (localtime(&m_time)->tm_isdst)
X        m_time -= 60L * 60L;    /* adjust for daylight savings time */
X#endif
X
X    tp.actime = m_time;         /* set access time */
X    tp.modtime = m_time;        /* set modification time */
X
X    /* set the time stamp on the file */
X    if (utime(filename, &tp))
X        fprintf(stderr, "error:  can't set the time for %s\n", filename);
X#endif /* ?AMIGA */
X`7D
X
X#endif /* !MTS && !VMS */
X#endif /* ?MACOS */
X#endif /* ?DOS_OS2 */
X
X
X
X
X
X/************************/
X/*  Function handler()  */
X/************************/
X
Xvoid handler(signal)   /* upon interrupt, turn on echo and exit cleanly */
X    int signal;
X`7B
X#if (defined(SIGBUS) `7C`7C defined(SIGSEGV))
X    static char *corrupt = "error:  zipfile probably corrupt\n";
X#endif
X
X#ifndef DOS_OS2
X#ifdef CRYPT
X    echon();
X#endif /* CRYPT */
X    putc('\n', stderr);
X#endif /* !DOS_OS2 */
X#ifdef SIGBUS
X    if (signal == SIGBUS) `7B
X        fprintf(stderr, corrupt);
X        exit(3);
X    `7D
X#endif /* SIGBUS */
X#ifdef SIGSEGV
X    if (signal == SIGSEGV) `7B
X        fprintf(stderr, corrupt);
X        exit(3);
X    `7D
X#endif /* SIGSEGV */
X    exit(0);
X`7D
X
X
X
X
X
X/*******************************/
X/*  Non-echoing password code  */
X/*******************************/
X
X#ifdef CRYPT
X#ifndef DOS_OS2
X#ifdef VMS
X
Xint echo(opt)
X    int opt;
X`7B
X/*--------------------------------------------------------------------------
V-
X    Based on VMSmunch.c, which in turn was based on Joe Meadows' file.c code
V.
X  --------------------------------------------------------------------------
V-
X     * For VMS v5.x:
X     *   IO$_SENSEMODE/SETMODE info:  Programming, Vol. 7A, System Programmi
Vng,
X     *     I/O User's: Part I, sec. 8.4.1.1, 8.4.3, 8.4.5, 8.6
X     *   sys$assign(), sys$qio() info:  Programming, Vol. 4B, System Service
Vs,
X     *     System Services Reference Manual, pp. sys-23, sys-379
X     *   fixed-length descriptor info:  Programming, Vol. 3, System Services
V,
X     *     Intro to System Routines, sec. 2.9.2
X     * GRR, 15 Aug 91
X  --------------------------------------------------------------------------
V-*/
X    static struct dsc$descriptor_s DevDesc =
X        `7B9, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$INPUT"`7D;
X     /* `7Bdsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer`7D; */
X    static short           DevChan, iosb`5B4`5D;
X    static long            i, status;
X    static unsigned long   oldmode`5B2`5D, newmode`5B2`5D;   /* each = 8 byt
Ves */
X `20
X
X/*--------------------------------------------------------------------------
V-
X    Assign a channel to standard input.
X  --------------------------------------------------------------------------
V-*/
X
X    status = sys$assign(&DevDesc, &DevChan, 0, 0);
X    if (!(status & 1))
X        return status;
X
X/*--------------------------------------------------------------------------
V-
X    Use sys$qio and the IO$_SENSEMODE function to determine the current tty
X    status (for password reading, could use IO$_READVBLK function instead,
X    but echo on/off will be more general).
X  --------------------------------------------------------------------------
V-*/
X
X    status = sys$qio(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0,
X                     oldmode, 8, 0, 0, 0, 0);
X    if (!(status & 1))
X        return status;
X    status = iosb`5B0`5D;
X    if (!(status & 1))
X        return status;
X
X/*--------------------------------------------------------------------------
V-
X    Copy old mode into new-mode buffer, then modify to be either NOECHO or
X    ECHO (depending on function argument opt).
X  --------------------------------------------------------------------------
V-*/
X
X    newmode`5B0`5D = oldmode`5B0`5D;
X    newmode`5B1`5D = oldmode`5B1`5D;
X    if (opt == OFF)
X        newmode`5B1`5D `7C= TT$M_NOECHO;                      /* set NOECHO
V bit */
X    else
X        newmode`5B1`5D &= `7E((unsigned long) TT$M_NOECHO);   /* clear NOECH
VO bit */
X
X/*--------------------------------------------------------------------------
V-
X    Use the IO$_SETMODE function to change the tty status.
X  --------------------------------------------------------------------------
V-*/
X
X    status = sys$qio(0, DevChan, IO$_SETMODE, &iosb, 0, 0,
X                     newmode, 8, 0, 0, 0, 0);
X    if (!(status & 1))
X        return status;
X    status = iosb`5B0`5D;
X    if (!(status & 1))
X        return status;
X
X/*--------------------------------------------------------------------------
V-
X    Deassign the sys$input channel by way of clean-up, then exit happily.
X  --------------------------------------------------------------------------
V-*/
X
X    status = sys$dassgn(DevChan);
X    if (!(status & 1))
X        return status;
X
X    return SS$_NORMAL;   /* we be happy */
X
X`7D /* end function echo() */
X
X
X
X
X
X#else /* !VMS */
X
Xstatic int echofd=(-1);       /* file descriptor whose echo is off */
X
Xvoid echoff(f)
X    int f;                    /* file descriptor for which to turn echo off
V */
X/* Turn echo off for file descriptor f.  Assumes that f is a tty device. */
X`7B
X    struct sgttyb sg;         /* tty device structure */
X
X    echofd = f;
X    GTTY(f, &sg);             /* get settings */
X    sg.sg_flags &= `7EECHO;     /* turn echo off */
X    STTY(f, &sg);
X`7D
X
X
X
Xvoid echon()
X/* Turn echo back on for file descriptor echofd. */
X`7B
X    struct sgttyb sg;         /* tty device structure */
X
X    if (echofd != -1) `7B
X        GTTY(echofd, &sg);    /* get settings */
X        sg.sg_flags `7C= ECHO;  /* turn echo on */
X        STTY(echofd, &sg);
X        echofd = -1;
X    `7D
X`7D
X
X#endif /* ?VMS */
X#endif /* !DOS_OS2 */
X
X
X
X
X
Xchar *getp(m, p, n)
X    char *m;                  /* prompt for password */
X    char *p;                  /* return value: line input */
X    int n;                    /* bytes available in p`5B`5D */
X/* Get a password of length n-1 or less into *p using the prompt *m.
X   The entered password is not echoed.  Return p on success, NULL on
X   failure (can't get controlling tty). */
X`7B
X    char c;                   /* one-byte buffer for read() to use */
X    int i;                    /* number of characters input */
X    char *w;                  /* warning on retry */
X
X#ifndef DOS_OS2
X#ifndef VMS
X    int f;                    /* file decsriptor for tty device */
X
X    /* turn off echo on tty */
X    if (!isatty(2))
X        return NULL;          /* error if not tty */
X    if ((f = open(ttyname(2), 0, 0)) == -1)
X        return NULL;
X#endif /* !VMS */
X    echoff(f);                /* turn echo off */
X#endif /* !DOS_OS2 */
X
X    /* get password */
X    w = "";
X    do `7B
X#ifdef VMS   /* bug:  VMS adds '\n' to NULL fputs (apparently) */
X        if (*w)
X#endif /* VMS */
X            fputs(w, stderr); /* warning if back again */
X        fputs(m, stderr);     /* prompt */
X        fflush(stderr);
X        i = 0;
X        do `7B                  /* read line, keeping n */
X#ifdef MSVMS
X            if ((c = (char)getch()) == '\r')
X                c = '\n';
X#else /* !MSVMS */
X            read(f, &c, 1);
X#endif /* ?MSVMS */
X            if (i < n)
X                p`5Bi++`5D = c;
X        `7D while (c != '\n');
X        putc('\n', stderr);  fflush(stderr);
X        w = "(line too long--try again)\n";
X    `7D while (p`5Bi-1`5D != '\n');
X    p`5Bi-1`5D = 0;               /* terminate at newline */
X
X#ifndef DOS_OS2
X    echon();                  /* turn echo back on */
X#ifndef VMS
X    close(f);
X#endif /* !VMS */
X#endif /* !DOS_OS2 */
X
X    /* return pointer to password */
X    return p;
X`7D
X
X#endif /* CRYPT */
$ CALL UNPACK [.UNZIP50]FILE_IO.C;1 828092931
$ create 'f'
X.TH FUNZIP 1 "19 Aug 92 (v1.3)"
X.SH NAME
Xfunzip \- extract from a ZIP archive file as a filter
X.SH SYNOPSIS
X`5B...`5D  `7C  \fBfunzip\fP `5B password `5D  `7C  `5B...`5D
X.SH ARGUMENTS
X.IP `5B\fIpassword\fP`5D \w'`5B\fIpassword\fP`5D'u+2m
XOptional password to be used if ZIP archive is encrypted.  Decryption
Xmay not be supported at some sites.  See DESCRIPTION for more details.
X.PD
X.SH DESCRIPTION
X.I FUnZip
Xacts as a filter; that is, it assumes that a ZIP archive is being piped into
Xstandard input, and it extracts the first member from the archive to stdout.
XGiven the limitation on single-member extraction, \fIFUnZip\fP is most
Xuseful in conjunction with a secondary archiver program such as tar(1).
XThe following section includes an example illustrating this usage in the
Xcase of disk backups to tape.
X.PD
X.SH EXAMPLES
XTo use \fIFUnZip\fP to extract the first member file of the archive test.zip
Xand to pipe it into more(1):
X.PP
X.IP "\t\fIfunzip\fP < test.zip `7C more"
X.PP
XTo use \fIFUnZip\fP to test the first member file of test.zip (any errors
Xwill be reported on standard error):
X.PP
X.IP "\t\fIfunzip\fP < test.zip > /dev/null"
X.PP
XTo use \fIZip\fP and \fIFUnZip\fP in place of compress(1) and zcat(1) for
Xtape backups:
X.PP
X.IP "\ttar cf \- . `7C \fIzip\fP \-7 `7C dd of=/dev/nrst0 obs=8k"
X.IP "\tdd if=/dev/nrst0 ibs=8k `7C \fIfunzip\fP `7C tar xf \-"
X.PP
X(where, for example, nrst0 is a SCSI tape drive).
X.PD
X.SH LIMITATIONS
XThere is presently no way to extract any member but the first from a ZIP
Xarchive.  This would be useful in the case where a ZIP archive is included
Xwithin another archive.
X.PP
XAn alternate mechanism for passing the password to \fIFUnZip\fP would
Xbe preferable to putting it on the command line.
X.PP
X\fIFUnZip\fP would be useful under OS/2, too.
X.PP
XThe functionality of \fIFUnZip\fP should be included in \fIUnZip\fP
Xdirectly (future release).
X.PD
X.SH SEE ALSO
Xunzip(1), zip(1), zipcloak(1), zipinfo(1), zipnote(1), zipsplit(1)
X.PD
X.SH AUTHOR
XMark Adler (Info-ZIP)
X.PD
$ CALL UNPACK [.UNZIP50]FUNZIP.1;1 1063803495
$ create 'f'
X/* funzip.c -- Not copyrighted 1992 by Mark Adler
X   version 1.3, 16 August 1992 */
X
X
X/* You can do whatever you like with this source file, though I would
X   prefer that if you modify it and redistribute it that you include
X   comments to that effect with your name and the date.  Thank you.
X
X   History:
X   vers    date          who           what
X   ----  ---------  --------------  ------------------------------------
X    1.0  13 Aug 92  M. Adler        really simple unzip filter.
X    1.1  13 Aug 92  M. Adler        cleaned up somewhat, give help if
X                                    stdin not redirected, warn if more
X                                    zip file entries after the first.
X    1.2  15 Aug 92  M. Adler        added check of lengths for stored
X                                    entries, added more help.
X    1.3  16 Aug 92  M. Adler        removed redundant #define's, added
X                                    decryption.
X
X */
X
X
X/*
X
X   All funzip does is take a zip file from stdin and decompress the
X   first entry to stdout.  The entry has to be either deflated or
X   stored.  If the entry is encrypted, then the decryption password
X   must be supplied on the command line as the first argument.
X
X   funzip needs to be linked with inflate.o compiled from the unzip
X   source.  If decryption is desired, then it needs to be compiled
X   with -DCRYPT and linked also with crypt.o.
X
X */
X
X#include "unzip.h"
X
X/* enforce binary i/o if recognized */
X#ifdef __STDC__
X#  define FOPR "rb"
X#  define FOPW "w+b"
X#else
X#  define FOPR "r"
X#  define FOPW "w+"
X#endif
X
X/* PKZIP header definitions */
X#define LOCSIG 0x04034b50L      /* four byte lead-in (lsb first) */
X#define LOCFLG 6                /* offset of bit flag */
X#define  CRPFLG 1               /*  bit for encrypted entry */
X#define  EXTFLG 8               /*  bit for extended local header */
X#define LOCHOW 8                /* offset of compression method */
X#define LOCTIM 10               /* file mod time (for decryption) */
X#define LOCCRC 14               /* offset of crc */
X#define LOCSIZ 18               /* offset of compressed size */
X#define LOCLEN 22               /* offset of uncompressed length */
X#define LOCFIL 26               /* offset of file name field length */
X#define LOCEXT 28               /* offset of extra field length */
X#define LOCHDR 30               /* size of local header, including sig */
X#define EXTHDR 16               /* size of extended local header, inc sig */
X
X/* Macros for getting two byte and four byte header values */
X#define SH(p) ((UWORD)(byte)((p)`5B0`5D) `7C ((UWORD)(byte)((p)`5B1`5D) << 8
V))
X#define LG(p) ((ULONG)(SH(p)) `7C ((ULONG)(SH((p)+2)) << 16))
X
X/* Function prototypes */
XULONG updcrc OF((byte *, int));
Xint inflate_entry OF((void));
Xvoid err OF((int, char *));
Xvoid main OF((int, char **));
X
X/* Globals */
XFILE *in, *out;                 /* input and output files */
Xunion work area;                /* inflate sliding window */
Xbyte *outbuf;                   /* malloc'ed output buffer */
Xbyte *outptr;                   /* points to next byte in output buffer */
Xint outcnt;                     /* bytes in output buffer */
XULONG outsiz;                   /* total bytes written to out */
Xint decrypt;                    /* flag to turn on decryption */
Xchar *key;                      /* not used--needed to link crypt.c */
X
X/* Masks for inflate.c */
XUWORD mask_bits`5B`5D = `7B
X    0x0000,
X    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
X    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
X`7D;
X
X
X/* Table of CRC-32's of all single byte values (made by makecrc.c) */
XULONG crc_32_tab`5B`5D = `7B
X  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
X  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
X  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
X  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
X  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
X  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
X  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
X  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
X  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
X  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
X  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
X  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
X  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
X  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
X  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
X  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
X  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
X  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
X  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
X  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
X  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
X  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
X  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
X  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
X  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
X  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
X  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
X  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
X  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
X  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
X  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
X  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
X  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
X  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+-+-+-+-+-+-+-+-  END  OF PART 3 +-+-+-+-+-+-+-+-
Technical Details
Message-ID: <8009589@MVB.SAIC.COM>
Path: arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!news.acns.nwu.edu!network.ucsd.edu!mvb.saic.com!vmsnet-sources

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!news.acns.nwu.edu!network.ucsd.edu!mvb.saic.com!vmsnet-sources
From: goathunter@wkuvx1.bitnet
Newsgroups: vmsnet.sources
Subject: Zip v1.9 & UnZip v5.0, part 03/22
Message-ID: <8009589@MVB.SAIC.COM>
Date: Tue, 01 Sep 1992 22:48:58 GMT
Organization: Western Kentucky University, Bowling Green, KY
Lines: 1547
Approved: Mark.Berryman@Mvb.Saic.Com