Annotation of coherent/b/bin/unzip/unzip.c, revision 1.1.1.1

1.1       root        1: /*---------------------------------------------------------------------------
                      2: 
                      3:   unzip.c
                      4: 
                      5:   UnZip - a zipfile extraction utility.  See below for make instructions, or
                      6:   read the comments in Makefile and the various Contents files for more de-
                      7:   tailed explanations.  To report a bug, send a *complete* description to
                      8:   [email protected]; include machine type, operating system and version,
                      9:   compiler and version, and reasonably detailed error messages or problem
                     10:   report.  To join Info-ZIP, send a message to [email protected].
                     11: 
                     12:   UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
                     13:   which in turn was almost a complete rewrite of version 3.x.  For a detailed
                     14:   revision history, see UnzpHist.zip at Info-ZIP headquarters (below).  For a 
                     15:   (partial) list of the many (near infinite) contributors, see "CONTRIBS" in
                     16:   the UnZip source distribution.
                     17: 
                     18:   ---------------------------------------------------------------------------
                     19: 
                     20:   To compile (partial instructions):
                     21: 
                     22:      under Unix (cc):  make <system name>
                     23:        (type "make list" for a list of valid names, or read Makefile for 
                     24:        details.  "make unzip" works for most systems.  If you have a NEW
                     25:        system, not covered by any of the existing targets, send FULL infor-
                     26:        mation--hardware, OS, versions, etc.--to [email protected])
                     27: 
                     28:      under MS-DOS (MSC, Turbo C, or Borland C++):  use the makefiles or
                     29:        project files in the MSDOS sub-archive; edit or otherwise modify
                     30:        as appropriate.  For MSC, use NMAKE.
                     31: 
                     32:      under MS Windows 3.x:  get wunz12sr.{zip | zoo | whatever} and use
                     33:        the included makefile
                     34: 
                     35:      under OS/2 (MSC, gcc, IBM C Set/2, Watcom C):  make -f makefile.os2
                     36:        (from OS2 sub-archive; for MSC, use NMAKE)
                     37: 
                     38:      under VMS (VAX C or GNU C):  @make_unzip_vaxc  or  @make_unzip_gcc
                     39:        (from VMS sub-archive; can also use MMS or MAKE/VMS; see VMS.notes)
                     40: 
                     41:      under Macintosh OS:  Double click on unzip.make.  Press <Command>-M.
                     42:        (from MAC sub-archive)
                     43: 
                     44:      under Windows NT:  use makefile.nt (from NT sub-archive)
                     45: 
                     46:      under AmigaDOS:  try one of the makefiles in the AMIGA sub-archive;
                     47:        may need some work yet...
                     48: 
                     49:      under Atari TOS:  needs considerable work yet...
                     50: 
                     51:   ---------------------------------------------------------------------------
                     52: 
                     53:   Version:  unz50p1.{tar.Z | zip | zoo} for Unix, VMS, OS/2, MS-DOS, Windows,
                     54:               Windows NT, Macintosh and Amiga.  Decryption requires sources
                     55:               in zcrypt19.zip, and Windows (not NT) support requires sources
                     56:               in wunz12sr.zip.  See accompanying file "Where" in the main
                     57:               source distribution for ftp, uucp and mail-server sites.
                     58:   Copyrights:  see accompanying file "COPYING" in UnZip source distribution.
                     59: 
                     60:   ---------------------------------------------------------------------------*/
                     61: 
                     62: 
                     63: 
                     64: 
                     65: 
                     66: #include "unzip.h"               /* includes, defines, and macros */
                     67: #ifdef MSWIN
                     68: #  include "wizunzip.h"          /* see History.500 for version history */
                     69: #endif
                     70: 
                     71: #define VERSION  "5.0p1 of 12 January 1993"
                     72: /* #define VERSION  "v5.0p BETA of 8-21-92" */   /* internal beta level */
                     73: #define PAKFIX   /* temporary(?) solution to PAK-created zipfiles */
                     74: 
                     75: 
                     76: 
                     77: 
                     78: 
                     79: /**********************/
                     80: /*  Global Variables  */
                     81: /**********************/
                     82: 
                     83: int aflag=0;          /* -a: do ASCII to EBCDIC translation, or CR-LF  */
                     84:                       /*     to CR or LF conversion of extracted files */
                     85: /* int bflag=0; RESERVED for -b: extract as binary */
                     86: int cflag=0;          /* -c: output to stdout */
                     87: int fflag=0;          /* -f: "freshen" (extract only newer files) */
                     88: int jflag=0;          /* -j: junk pathnames */
                     89: int overwrite_none=0; /* -n: never overwrite files (no prompting) */
                     90: int overwrite_all=0;  /* -o: OK to overwrite files without prompting */
                     91: int force_flag=0;     /* (shares -o for now): force to override errors, etc. */
                     92: int quietflg=0;       /* -q: produce a lot less output */
                     93: #ifdef DOS_OS2
                     94:    int sflag=1;       /* -s: allow spaces (blanks) in filenames */
                     95: #endif /* DOS_OS2 */
                     96: int tflag=0;          /* -t: test */
                     97: int uflag=0;          /* -u: "update" (extract only newer & brand-new files) */
                     98: static int U_flag=0;  /* -U: leave filenames in upper or mixed case */
                     99: static int vflag=0;   /* -v: view directory (only used in unzip.c) */
                    100: int V_flag=0;         /* -V: don't strip VMS version numbers */
                    101: #ifdef VMS
                    102:    int secinf=0;      /* -X: keep owner/protection */
                    103: #endif /* VMS */
                    104: int zflag=0;          /* -z: display only the archive comment */
                    105: int process_all_files=0;
                    106: 
                    107: longint csize;        /* used by list_files(), ReadByte(): must be signed */
                    108: longint ucsize;       /* used by list_files(), unReduce(), explode() */
                    109: 
                    110: char *fnames[2] = {"*", NULL};   /* default filenames vector */
                    111: char **fnv = fnames;
                    112: char sig[5];
                    113: char answerbuf[10];
                    114: 
                    115: min_info info[DIR_BLKSIZ], *pInfo=info;
                    116: 
                    117: #ifdef OS2
                    118:    int longname;              /* used in extract.c, mapname.c and file_io.c */
                    119:    char longfilename[FILNAMSIZ];
                    120: #endif /* OS2 */
                    121: 
                    122: #ifdef CRYPT
                    123:    char *key = (char *)NULL;  /* password with which to decrypt data, or NULL */
                    124: #endif /* CRYPT */
                    125: 
                    126: /*---------------------------------------------------------------------------
                    127:     unShrink/unReduce/explode/inflate working storage and globals:
                    128:   ---------------------------------------------------------------------------*/
                    129: 
                    130: union work area;              /* see unzip.h for the definition of work */
                    131: ULONG crc32val;
                    132: 
                    133: UWORD mask_bits[] = {
                    134:     0x0000,
                    135:     0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
                    136:     0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
                    137: };
                    138: 
                    139: /*---------------------------------------------------------------------------
                    140:     Input file variables:
                    141:   ---------------------------------------------------------------------------*/
                    142: 
                    143: byte *inbuf, *inptr;     /* input buffer (any size is legal) and pointer */
                    144: int incnt;
                    145: 
                    146: ULONG bitbuf;
                    147: int bits_left;
                    148: boolean zipeof;
                    149: 
                    150: int zipfd;               /* zipfile file handle */
                    151: #ifdef MSWIN
                    152:    char *zipfn;
                    153: #else
                    154:    char zipfn[FILNAMSIZ];
                    155: #endif
                    156: 
                    157: char local_hdr_sig[5] = "\120";    /* remaining signature bytes come later   */
                    158: char central_hdr_sig[5] = "\120";  /*  (must initialize at runtime so unzip  */
                    159: char end_central_sig[5] = "\120";  /*  executable won't look like a zipfile) */
                    160: /* char extd_local_sig[5] = "\120";  NOT USED YET */
                    161: 
                    162: cdir_file_hdr crec;      /* used in unzip.c, extract.c, misc.c */
                    163: local_file_hdr lrec;     /* used in unzip.c, extract.c */
                    164: ecdir_rec ecrec;         /* used in unzip.c, extract.c */
                    165: struct stat statbuf;     /* used by main(), mapped_name(), check_for_newer() */
                    166: 
                    167: longint extra_bytes = 0;        /* used in unzip.c, misc.c */
                    168: longint cur_zipfile_bufstart;   /* extract_or_test_files, readbuf, ReadByte */
                    169:   
                    170: #ifdef MACOS
                    171:    short  gnVRefNum;
                    172:    long  glDirID;
                    173:    OSType  gostCreator;
                    174:    OSType  gostType;
                    175:    boolean  fMacZipped;
                    176:    boolean  macflag;
                    177:    CursHandle  rghCursor[4];    /* status cursors */
                    178:    short  giCursor = 0;
                    179: #endif
                    180: 
                    181: /*---------------------------------------------------------------------------
                    182:     Output stream variables:
                    183:   ---------------------------------------------------------------------------*/
                    184: 
                    185: byte *outbuf;                   /* buffer for rle look-back */
                    186: byte *outptr;
                    187: #ifdef MSWIN
                    188:    byte __far *outout;
                    189:    char *filename;
                    190: #else /* !MSWIN */
                    191:    byte *outout;                /* scratch pad for ASCII-native trans */
                    192:    char filename[FILNAMSIZ];
                    193: #endif /* ?MSWIN */
                    194: byte *extra_field = (byte *)NULL;  /* used by VMS, Mac and OS/2 versions */
                    195: longint outpos;                 /* absolute position in outfile */
                    196: int outcnt;                     /* current position in outbuf */
                    197: int outfd;
                    198: int mem_mode = 0;
                    199: int disk_full;
                    200: 
                    201: /*---------------------------------------------------------------------------
                    202:     unzip.c static global variables (visible only within this file):
                    203:   ---------------------------------------------------------------------------*/
                    204: 
                    205: static byte *hold;
                    206: static char unkn[10];
                    207: static longint ziplen;
                    208: static UWORD methnum;
                    209: 
                    210: /*---------------------------------------------------------------------------
                    211:     unzip.c repeated error messages (we use all of these at least twice)
                    212:   ---------------------------------------------------------------------------*/
                    213: 
                    214: char *EndSigMsg = "\nwarning:\
                    215:   didn't find end-of-central-dir signature at end of central dir.\n";
                    216: char *CentSigMsg =
                    217:   "error:  expected central file header signature not found (file #%u).\n";
                    218: char *SeekMsg =
                    219:   "error:  attempt to seek before beginning of zipfile\n%s";
                    220: 
                    221: #ifdef VMS
                    222: char *ReportMsg = "\
                    223:   (please check that you have transferred or created the zipfile in the\n\
                    224:   appropriate BINARY mode--this includes ftp, Kermit, AND unzip'd zipfiles)\n";
                    225: #else /* !VMS */
                    226: char *ReportMsg = "\
                    227:   (please check that you have transferred or created the zipfile in the\n\
                    228:   appropriate BINARY mode and that you have compiled unzip properly)\n";
                    229: #endif /* ?VMS */
                    230: 
                    231: 
                    232: #ifdef MSWIN
                    233: /* MS Windows Setup  and Take-Down functions bracket calls to 
                    234:  * process_zipfile().
                    235:  * These functions allocate and free the necessary buffers, set and clear
                    236:  * any global variables so that  process_zipfile()  can be called multiple
                    237:  * times in the same session of WizUnzip. You'll recognize some of the 
                    238:  * code from main() in SetUpToProcessZipFile().
                    239:  */
                    240: HANDLE hOutBuf;
                    241: HANDLE hOutOut;   /* added 04/03/92 for version 1.1 */
                    242: HANDLE hInBuf;
                    243: HANDLE hZipFN;
                    244: HANDLE hFileName;
                    245: 
                    246: BOOL FSetUpToProcessZipFile(int ncflag, int ntflag, int nvflag, int nUflag, 
                    247:        int nzflag, int ndflag, int noflag, int naflag, int argc,
                    248:        LPSTR lpszZipFN, PSTR *FNV)
                    249: {
                    250:     /* clear all global flags -- need to or not. */
                    251: 
                    252:     tflag = vflag=cflag=aflag=U_flag=quietflg=zflag = 0;
                    253:     overwrite_all=overwrite_none=0;
                    254:     fnv = &fnames[0];       /* assign default file name vector */
                    255: 
                    256:     cflag = ncflag ; overwrite_all = noflag;
                    257:     tflag = ntflag ; vflag = nvflag; zflag = nzflag; U_flag = nUflag;
                    258:     aflag = naflag;
                    259:     sflag = 1;
                    260: 
                    261:     local_hdr_sig[0] = central_hdr_sig[0] = end_central_sig[0] = '\120';
                    262:     local_hdr_sig[1] = central_hdr_sig[1] = end_central_sig[1] = '\0';
                    263: 
                    264:     if (!(hZipFN = LocalAlloc(LMEM_MOVEABLE, FILNAMSIZ)))
                    265:         return FALSE;
                    266: 
                    267:     zipfn = (char *)LocalLock(hZipFN);
                    268:     lstrcpy(zipfn, lpszZipFN);
                    269:     if (stat(zipfn, &statbuf) || (statbuf.st_mode & S_IFMT) == S_IFDIR)
                    270:         strcat(zipfn, ZSUFX);
                    271: 
                    272:     if (stat(zipfn, &statbuf)) {  /* try again */
                    273:         fprintf(stderr, "error:  can't find zipfile [ %s ]\n", zipfn);
                    274:         return TRUE;              /* 9:  file not found */
                    275:     } else
                    276:         ziplen = statbuf.st_size;
                    277: 
                    278:     if (argc != 0) {
                    279:         fnv = FNV;
                    280:         process_all_files = FALSE;
                    281:     } else
                    282:         process_all_files = TRUE;       /* for speed */
                    283: 
                    284: /*---------------------------------------------------------------------------
                    285:     Okey dokey, we have everything we need to get started.  Let's roll.
                    286:   ---------------------------------------------------------------------------*/
                    287: 
                    288:     if (hInBuf = LocalAlloc(LMEM_MOVEABLE, INBUFSIZ+4)) {  /* 4 extra: hold[] */
                    289:         inbuf = (byte *) LocalLock(hInBuf);
                    290:         WinAssert(inbuf);
                    291:     }
                    292:     if (hOutBuf = LocalAlloc(LMEM_MOVEABLE, OUTBUFSIZ+1)) {  /* extra: ASCIIZ */
                    293:         outbuf = (byte *)LocalLock(hOutBuf);
                    294:         WinAssert(outbuf);
                    295:         if (aflag) {   /* if LF => CR,LF translation */
                    296:             if (hOutOut = GlobalAlloc(GMEM_MOVEABLE,OUTBUFSIZ)) {
                    297:                 outout = (byte _far *)GlobalLock(hOutOut);
                    298:                 WinAssert(outout);
                    299:             }
                    300:         } else    /* no translation; just re-use output buffer */
                    301:             outout = (byte _far *)outbuf;  /*  point to outbuf */
                    302:     }
                    303:     if ( hFileName = LocalAlloc(LMEM_MOVEABLE, FILNAMSIZ)) {
                    304:         filename = (char *)LocalLock(hFileName);
                    305:         WinAssert(filename);
                    306:     }
                    307: 
                    308:     if ((inbuf == NULL) || (outbuf == NULL) || (outout == NULL) ||
                    309:         (zipfn == NULL) || (filename == NULL))
                    310:         return FALSE;
                    311: 
                    312:     hold = &inbuf[INBUFSIZ];   /* to check for boundary-spanning signatures */
                    313: 
                    314:     return TRUE;    /* set up was OK */
                    315: }
                    316: 
                    317: void TakeDownFromProcessZipFile(void)
                    318: {
                    319:     if (inbuf) {
                    320:         LocalUnlock(hInBuf);
                    321:         inbuf = NULL;
                    322:     }
                    323:     if (hInBuf)
                    324:         hInBuf = LocalFree(hInBuf);
                    325: 
                    326:     if (outbuf) {
                    327:         LocalUnlock(hOutBuf);
                    328:         outbuf = NULL;
                    329:     }
                    330:     if (hOutBuf)
                    331:         hOutBuf = LocalFree(hOutBuf);
                    332: 
                    333:     if (aflag && outout)    /* if doing LF => CR,LF translation */
                    334:         GlobalUnlock(hOutOut);
                    335:     outout = NULL;          /* free now, translation or not     */
                    336:     if (hOutOut)
                    337:         hOutOut = GlobalFree(hOutOut);  /* mark buffer as freed */
                    338: 
                    339:     if (zipfn) {
                    340:         LocalUnlock(hZipFN);
                    341:         zipfn = NULL;
                    342:     }
                    343:     if (hZipFN)
                    344:         hZipFN = LocalFree(hZipFN);
                    345: 
                    346:     if (filename) {
                    347:         LocalUnlock(hFileName);
                    348:         filename = NULL;
                    349:     }
                    350:     if (hFileName)
                    351:         hFileName = LocalFree(hFileName);
                    352: }
                    353: 
                    354: #else /* !MSWIN */
                    355: 
                    356: /******************/
                    357: /*  Main program  */
                    358: /******************/
                    359: 
                    360: int main(argc, argv)   /* return PK-type error code (except under VMS) */
                    361:     int argc;
                    362:     char *argv[];
                    363: {
                    364:     char *s;
                    365:     int c, error=FALSE, negative=0;
                    366: 
                    367: 
                    368: /*---------------------------------------------------------------------------
                    369:     Macintosh initialization code.
                    370:   ---------------------------------------------------------------------------*/
                    371: 
                    372: #ifdef MACOS
                    373: #ifdef THINK_C
                    374: #   include <console.h>
                    375:     static char *argstr[30], args[30*64];
                    376:     Point p;
                    377:     SFTypeList sfT;
                    378:     EventRecord theEvent;
                    379:     short eMask;
                    380:     SFReply fileRep;
                    381: #endif /* THINK_C */
                    382:     int a;
                    383: 
                    384:     for (a = 0;  a < 4;  ++a)
                    385:         rghCursor[a] = GetCursor(a+128);
                    386:     giCursor = 0;
                    387: 
                    388:     area.Slide = (byte *)calloc(8193, sizeof(short)+sizeof(char)+sizeof(char));
                    389:     area.shrink.Prefix_of = (short *)area.Slide;
                    390:     area.shrink.Suffix_of = area.Slide + (sizeof(short)*(HSIZE+1));
                    391:     area.shrink.Stack = area.Slide + (sizeof(short) + sizeof(char))*(HSIZE+1);
                    392: 
                    393: #ifdef THINK_C   
                    394:     for (a = 0;  a < 30;  ++a)
                    395:         argstr[a] = &args[a*64];
                    396: start:
                    397:     tflag=vflag=cflag=aflag=jflag=U_flag=quietflg=fflag=uflag=zflag = 0;
                    398:     local_hdr_sig[1] = central_hdr_sig[1] = end_central_sig[1] = '\0';
                    399: /*  extd_local_sig[1] = '\0';  */
                    400:     error = FALSE;
                    401: 
                    402:     argc = ccommand(&argv);
                    403:     SetPt(&p, 40, 40);
                    404: 
                    405:     SFGetFile(p, "\pSpecify ZIP file:", 0L, -1, sfT, 0L, &fileRep);
                    406:     if (fileRep.good) {
                    407:         macfstest(fileRep.vRefNum);
                    408:         ResolveMacVol(fileRep.vRefNum, &gnVRefNum, &glDirID, NULL);
                    409:         for (a = 1;  a < argc;  ++a)
                    410:             if (argv[a][0] == '-')
                    411:                 BlockMove(argv[a], argstr[a], (strlen(argv[a]) > 63) ? 64 :
                    412:                    strlen(argv[a])+1);
                    413:             else
                    414:                 break;
                    415:         PtoCstr((char *)fileRep.fName);
                    416:         strcpy(argstr[a], (char *)fileRep.fName);
                    417:         for (;  a < argc;  ++a)
                    418:             BlockMove(argv[a], argstr[a+1], (strlen(argv[a]) > 63) ? 64 :
                    419:                strlen(argv[a])+1);
                    420:         ++argc;
                    421:         argv = argstr;
                    422: 
                    423:         if (hfsflag == FALSE)  /* can't support directories:  junk pathnames */
                    424:             jflag = 1;
                    425:     }
                    426: #endif /* THINK_C */
                    427: #endif /* MACOS */
                    428: 
                    429: /*---------------------------------------------------------------------------
                    430:     Set signal handler for restoring echo, warn of zipfile corruption, etc.
                    431:   ---------------------------------------------------------------------------*/
                    432: 
                    433:     signal(SIGINT, handler);
                    434:     signal(SIGTERM, handler);
                    435: #ifdef SIGBUS
                    436:     signal(SIGBUS, handler);
                    437: #endif
                    438: #ifdef SIGSEGV
                    439:     signal(SIGSEGV, handler);
                    440: #endif
                    441: 
                    442: /*---------------------------------------------------------------------------
                    443:     Debugging info for checking on structure padding:
                    444:   ---------------------------------------------------------------------------*/
                    445: 
                    446: #ifdef DEBUG_STRUC
                    447:     printf("local_file_hdr size: %X\n",
                    448:            sizeof(local_file_hdr));
                    449:     printf("local_byte_hdr size: %X\n",
                    450:            sizeof(local_byte_hdr));
                    451:     printf("actual size of local headers: %X\n", LREC_SIZE);
                    452: 
                    453:     printf("central directory header size: %X\n",
                    454:            sizeof(cdir_file_hdr));
                    455:     printf("central directory byte header size: %X\n",
                    456:            sizeof(cdir_byte_hdr));
                    457:     printf("actual size of central dir headers: %X\n", CREC_SIZE);
                    458: 
                    459:     printf("end central dir record size: %X\n",
                    460:            sizeof(ecdir_rec));
                    461:     printf("end central dir byte record size: %X\n",
                    462:            sizeof(ec_byte_rec));
                    463:     printf("actual size of end-central-dir record: %X\n", ECREC_SIZE);
                    464: #endif /* DEBUG_STRUC */
                    465: 
                    466: /*---------------------------------------------------------------------------
                    467:     Put environment-variable options into the queue, then rip through any
                    468:     command-line options lurking about...
                    469:   ---------------------------------------------------------------------------*/
                    470: 
                    471:     envargs(&argc, &argv, ENV_UNZIP);
                    472: 
                    473:     while (--argc > 0 && (*++argv)[0] == '-') {
                    474:         s = argv[0] + 1;
                    475:         while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
                    476:             switch (c) {
                    477:                 case ('-'):
                    478:                     ++negative;
                    479:                     break;
                    480:                 case ('a'):
                    481:                     if (negative)
                    482:                         aflag = FALSE, negative = 0;
                    483:                     else
                    484:                         aflag = TRUE;
                    485:                     break;
                    486: #if 0
                    487:                 case ('b'):    /* force binary mode */
                    488:                     if (negative)
                    489:                         bflag = FALSE, negative = 0;
                    490:                     else
                    491:                         bflag = TRUE;
                    492:                     break;
                    493: #endif
                    494:                 case ('c'):
                    495:                     if (negative) {
                    496:                         cflag = FALSE, negative = 0;
                    497: #ifdef NATIVE
                    498:                         aflag = FALSE;
                    499: #endif
                    500:                     } else {
                    501:                         cflag = TRUE;
                    502: #ifdef NATIVE
                    503:                         aflag = TRUE;  /* so you can read it on the screen */
                    504: #endif
                    505:                     }
                    506:                     break;
                    507:                 case ('d'):    /* re-create directory structure (default) */
                    508:                     if (negative)
                    509:                         jflag = TRUE, negative = 0;
                    510:                     break;
                    511:                 case ('e'):    /* just ignore -e, -x options (extract) */
                    512:                     break;
                    513:                 case ('f'):    /* "freshen" (extract only newer files) */
                    514:                     if (negative)
                    515:                         fflag = uflag = FALSE, negative = 0;
                    516:                     else
                    517:                         fflag = uflag = TRUE;
                    518:                     break;
                    519:                 case ('j'):    /* junk pathnames/directory structure */
                    520:                     if (negative)
                    521:                         jflag = FALSE, negative = 0;
                    522:                     else
                    523:                         jflag = TRUE;
                    524:                     break;
                    525:                 case ('l'):
                    526:                     if (negative) {
                    527:                         vflag = MAX(vflag-negative,0);
                    528:                         negative = 0;
                    529:                     } else
                    530:                         ++vflag;
                    531:                     break;
                    532:                 case ('n'):    /* don't overwrite any files */
                    533:                     if (negative)
                    534:                         overwrite_none = FALSE, negative = 0;
                    535:                     else
                    536:                         overwrite_none = TRUE;
                    537:                     break;
                    538:                 case ('o'):    /* OK to overwrite files without prompting */
                    539:                     if (negative) {
                    540:                         overwrite_all = MAX(overwrite_all-negative,0);
                    541:                         force_flag = MAX(force_flag-negative,0);
                    542:                         negative = 0;
                    543:                     } else {
                    544:                         ++overwrite_all;
                    545:                         ++force_flag;  /* (share -o for now) force to cont. */
                    546:                     }
                    547:                     break;
                    548:                 case ('p'):    /* pipes:  stdout, no tranlation, no messages */
                    549:                     if (negative) {
                    550:                         cflag = FALSE;
                    551:                         quietflg = MAX(quietflg-999,0);
                    552:                         negative = 0;
                    553:                     } else {
                    554:                         cflag = TRUE;
                    555:                         quietflg += 999;
                    556:                     }
                    557:                     break;
                    558:                 case ('q'):    /* quiet:  fewer comments/messages */
                    559:                     if (negative) {
                    560:                         quietflg = MAX(quietflg-negative,0);
                    561:                         negative = 0;
                    562:                     } else
                    563:                         ++quietflg;
                    564:                     break;
                    565: #ifdef DOS_OS2
                    566:                 case ('s'):    /* spaces in filenames:  allow by default */
                    567:                     if (negative)
                    568:                         sflag = TRUE, negative = 0;
                    569:                     else
                    570:                         sflag = FALSE;
                    571:                     break;
                    572: #endif
                    573:                 case ('t'):
                    574:                     if (negative)
                    575:                         tflag = FALSE, negative = 0;
                    576:                     else
                    577:                         tflag = TRUE;
                    578:                     break;
                    579:                 case ('U'):    /* Uppercase (don't convert to all-lower) */
                    580:                     if (negative)
                    581:                         U_flag = FALSE, negative = 0;
                    582:                     else
                    583:                         U_flag = TRUE;
                    584:                     break;
                    585:                 case ('u'):    /* update (extract only new and newer files) */
                    586:                     if (negative)
                    587:                         uflag = FALSE, negative = 0;
                    588:                     else
                    589:                         uflag = TRUE;
                    590:                     break;
                    591:                 case ('V'):    /* Version (retain VMS/DEC-20 file versions) */
                    592:                     if (negative)
                    593:                         V_flag = FALSE, negative = 0;
                    594:                     else
                    595:                         V_flag = TRUE;
                    596:                     break;
                    597:                 case ('v'):    /* verbose */
                    598:                     if (negative) {
                    599:                         vflag = MAX(vflag-negative,0);
                    600:                         negative = 0;
                    601:                     } else if (vflag)
                    602:                         ++vflag;
                    603:                     else
                    604:                         vflag = 2;
                    605:                     break;
                    606: #ifdef VMS
                    607:                 case ('X'):   /* restore owner/protection info (need privs?) */
                    608:                     if (negative)
                    609:                         secinf = FALSE, negative = 0;
                    610:                     else
                    611:                         secinf = TRUE;
                    612:                     break;
                    613: #endif /* VMS */
                    614:                 case ('x'):    /* extract:  default */
                    615:                     break;
                    616:                 case ('z'):    /* display only the archive comment */
                    617:                     if (negative) {
                    618:                         zflag = MAX(zflag-negative,0);
                    619:                         negative = 0;
                    620:                     } else
                    621:                         ++zflag;
                    622:                     break;
                    623:                 default:
                    624:                     error = TRUE;
                    625:                     break;
                    626: 
                    627:             } /* end switch */
                    628:         } /* end while (not end of argument string) */
                    629:     } /* end while (not done with switches) */
                    630: 
                    631: /*---------------------------------------------------------------------------
                    632:     Make sure we aren't trying to do too many things here.  [This seems like
                    633:     kind of a brute-force way to do things; but aside from that, isn't the
                    634:     -a option useful when listing the directory (i.e., for reading zipfile
                    635:     comments)?  It's a modifier, not an action in and of itself, so perhaps
                    636:     it should not be included in the test--certainly, in the case of zipfile
                    637:     testing, it can just be ignored.]
                    638:   ---------------------------------------------------------------------------*/
                    639: 
                    640:     if ((aflag && tflag) || (aflag && vflag) || (cflag && tflag) ||
                    641:         (cflag && uflag) || (cflag && vflag) || (tflag && uflag) ||
                    642:         (tflag && vflag) || (uflag && vflag) || (fflag && overwrite_none)) {
                    643:         fprintf(stderr, "error:\
                    644:   -at, -av, -ct, -cu, -cv, -fn, -tu, -tv, -uv combinations not allowed\n");
                    645:         error = TRUE;
                    646:     }
                    647:     if (quietflg && zflag)
                    648:         quietflg = 0;
                    649:     if (overwrite_all && overwrite_none) {
                    650:         fprintf(stderr, "caution:  both -n and -o specified; ignoring -o\n");
                    651:         overwrite_all = FALSE;
                    652:     }
                    653:     if ((argc-- == 0) || error)
                    654:         RETURN(usage(error));
                    655: 
                    656: /*---------------------------------------------------------------------------
                    657:     Now get the zipfile name from the command line and see if it exists as a
                    658:     regular (non-directory) file.  If not, append the ".zip" suffix.  We don't
                    659:     immediately check to see if this results in a good name, but we will do so
                    660:     later.  In the meantime, see if there are any member filespecs on the com-
                    661:     mand line, and if so, set the filename pointer to point at them.
                    662:   ---------------------------------------------------------------------------*/
                    663: 
                    664:     strcpy(zipfn, *argv++);
                    665:     if (stat(zipfn, &statbuf) || (statbuf.st_mode & S_IFMT) == S_IFDIR)
                    666:         strcat(zipfn, ZSUFX);
                    667: #if (defined(UNIX) && !defined(VMS)) /* Unix executables have no extension-- */
                    668:     else if (statbuf.st_mode & S_IXUSR)  /* might find zip, not zip.zip; etc */
                    669:         fprintf(stderr, "\nnote:  file [ %s ] may be an executable\n\n", zipfn);
                    670: #endif /* UNIX && !VMS */
                    671: 
                    672:     if (stat(zipfn, &statbuf)) {/* try again */
                    673:         fprintf(stderr, "error:  can't find zipfile [ %s ]\n", zipfn);
                    674:         RETURN(9);              /* 9:  file not found */
                    675:     } else
                    676:         ziplen = statbuf.st_size;
                    677: 
                    678:     if (argc != 0) {
                    679:         fnv = argv;
                    680:         process_all_files = FALSE;
                    681:     } else
                    682:         process_all_files = TRUE;       /* for speed */
                    683: 
                    684: /*---------------------------------------------------------------------------
                    685:     Okey dokey, we have everything we need to get started.  Let's roll.
                    686:   ---------------------------------------------------------------------------*/
                    687: 
                    688:     inbuf = (byte *) malloc(INBUFSIZ + 4);     /* 4 extra for hold[] (below) */
                    689:     outbuf = (byte *) malloc(OUTBUFSIZ + 1);   /* 1 extra for string termin. */
                    690: #ifndef DOS_OS2
                    691:     if (aflag)                  /* if need an ascebc scratch, */
                    692:         outout = (byte *) malloc(OUTBUFSIZ);
                    693:     else                        /*  allocate it... */
                    694: #endif /* !DOS_OS2 */
                    695:         outout = outbuf;        /*  else just point to outbuf */
                    696: 
                    697:     if ((inbuf == (byte *)NULL) || (outbuf == (byte *)NULL) ||
                    698:         (outout == (byte *)NULL)) {
                    699:         fprintf(stderr, "error:  can't allocate unzip buffers\n");
                    700:         RETURN(4);              /* 4-8:  insufficient memory */
                    701:     }
                    702:     hold = &inbuf[INBUFSIZ];    /* to check for boundary-spanning signatures */
                    703: 
                    704:     RETURN(process_zipfile());  /* keep passing errors back... */
                    705: 
                    706: } /* end main() */
                    707: 
                    708: 
                    709: 
                    710: 
                    711: 
                    712: /**********************/
                    713: /*  Function usage()  */
                    714: /**********************/
                    715: 
                    716: int usage(error)   /* return PK-type error code */
                    717:     int error;
                    718: {
                    719: #ifdef NATIVE
                    720: #ifdef EBCDIC
                    721:     char *astring = "-a  convert ASCII to EBCDIC";
                    722: #else /* !EBCDIC */
                    723:     char *astring = "-a  convert ASCII to native chars";
                    724: #endif /* ?EBCDIC */
                    725: /*  char *astring = "-a  convert ASCII to " NATIVE;  (ANSI C concatenation)  */
                    726:     char *loc_str = "";
                    727: #else /* !NATIVE */
                    728: #ifdef DOS_OS2
                    729:     char *astring = "-a  convert text (LF => CR LF)";
                    730:     char *loc_str = "-s  spaces in filenames => _";
                    731: #else /* !DOS_OS2 */
                    732: #ifdef MACOS
                    733:     char *astring = "-a  convert text (CR LF => CR)";
                    734:     char *loc_str = "";
                    735: #else /* !MACOS:  UNIX, VMS */
                    736:     char *astring = "-a  convert text (CR LF => LF)";
                    737: #ifdef VMS
                    738:     char *loc_str = "-X  restore owner/protection info";
                    739: #else /* !VMS */
                    740:     char *loc_str = "";
                    741: #endif /* ?VMS */
                    742: #endif /* ?MACOS */
                    743: #endif /* ?DOS_OS2 */
                    744: #endif /* ?NATIVE */
                    745:     FILE *usagefp;
                    746: 
                    747: 
                    748: /*---------------------------------------------------------------------------
                    749:     If user requested usage, send it to stdout; else send to stderr.
                    750:   ---------------------------------------------------------------------------*/
                    751: 
                    752:     if (error)
                    753:         usagefp = (FILE *) stderr;
                    754:     else
                    755:         usagefp = (FILE *) stdout;
                    756: 
                    757:     fprintf(usagefp, "\
                    758: UnZip %s, by Info-ZIP.  Portions (c) 1989 by S. H. Smith.\n\
                    759: Bug reports ONLY to zip-bugs%%[email protected]; see README for detail\
                    760: s\n\n", VERSION);
                    761: 
                    762:     fprintf(usagefp, "\
                    763: Usage: unzip [ -options[modifiers] ] file[.zip] [filespec...]\n\
                    764:   -x  extract files (default)                -l  list files (short format)\n\
                    765:   -c  extract files to stdout/screen (CRT)   -v  list files (verbose format)\n\
                    766:   -f  freshen existing files, create none    -p  extract to pipe, no messages\n\
                    767:   -u  update files, create if necessary      -t  test archive integrity\n\
                    768:                                              -z  display archive comment\n\
                    769: modifiers:\n\
                    770:   -n  never overwrite existing files         %s\n", loc_str);
                    771:     fprintf(usagefp, "\
                    772:   -o  overwrite files WITHOUT prompting      %s\n\
                    773:   -j  junk paths (don't make directories)    -U  don't make names lowercase\n\
                    774:   -q  quiet mode (-qq => quieter)            -V  retain VMS version numbers\
                    775: \n\n\
                    776: Examples: (See manual for more information)\n\
                    777:   unzip data1 ReadMe   => extracts file ReadMe from zipfile data1.zip\n\
                    778:   unzip -p foo | more  => send contents of foo.zip via pipe into program more\n\
                    779:   unzip -fo foo        => quietly replace existing files if archive files newer\
                    780: \n", astring);
                    781: 
                    782: #ifdef VMS
                    783:     fprintf(usagefp, "\
                    784:   unzip \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS\
                    785: \n");
                    786: #endif
                    787: 
                    788:     if (error)
                    789:         return 10;    /* 10:  bad or illegal parameters specified */
                    790:     else
                    791:         return 0;     /* just wanted usage screen: no error */
                    792: 
                    793: } /* end function usage() */
                    794: 
                    795: #endif /* ?MSWIN */
                    796: 
                    797: 
                    798: 
                    799: 
                    800: /********************************/
                    801: /*  Function process_zipfile()  */
                    802: /********************************/
                    803: 
                    804: int process_zipfile()    /* return PK-type error code */
                    805: {
                    806:     int error=0, error_in_archive;
                    807:     longint real_ecrec_offset, expect_ecrec_offset;
                    808: 
                    809: 
                    810: /*---------------------------------------------------------------------------
                    811:     Open the zipfile for reading and in BINARY mode to prevent CR/LF trans-
                    812:     lation, which would corrupt the bitstreams.
                    813:   ---------------------------------------------------------------------------*/
                    814: 
                    815: #ifdef VMS
                    816:     if (check_format())         /* check for variable-length format */
                    817:         return 2;               /* 2:  error in zipfile */
                    818: #endif /* VMS */
                    819: 
                    820:     if (open_input_file())      /* this should never happen, given the */
                    821:         return 9;               /*   stat() test in main(), but... */
                    822: 
                    823: /*---------------------------------------------------------------------------
                    824:     Reconstruct the various PK signature strings, and find and process the
                    825:     end-of-central-directory header.
                    826:   ---------------------------------------------------------------------------*/
                    827: 
                    828:     strcat(local_hdr_sig, LOCAL_HDR_SIG);
                    829:     strcat(central_hdr_sig, CENTRAL_HDR_SIG);
                    830:     strcat(end_central_sig, END_CENTRAL_SIG);
                    831: /*  strcat(extd_local_sig, EXTD_LOCAL_SIG);  */
                    832: 
                    833:     if (find_end_central_dir()) {   /* not found; nothing to do */
                    834:         close(zipfd);
                    835:         return 2;                   /* 2:  error in zipfile */
                    836:     }
                    837: 
                    838:     real_ecrec_offset = cur_zipfile_bufstart+(inptr-inbuf);
                    839: #ifdef TEST
                    840:     printf("\n  found end-of-central-dir signature at offset %ld (%.8lXh)\n",
                    841:       real_ecrec_offset, real_ecrec_offset);
                    842:     printf("    from beginning of file; offset %d (%.4Xh) within block\n",
                    843:       inptr-inbuf, inptr-inbuf);
                    844: #endif
                    845: 
                    846:     if ((error_in_archive = process_end_central_dir()) > 1) {
                    847:         close(zipfd);
                    848:         return error_in_archive;
                    849:     }
                    850: 
                    851:     if (zflag) {
                    852:         close(zipfd);
                    853:         return 0;
                    854:     }
                    855: 
                    856: /*---------------------------------------------------------------------------
                    857:     Test the end-of-central-directory info for incompatibilities and incon-
                    858:     sistencies.
                    859:   ---------------------------------------------------------------------------*/
                    860: 
                    861: #ifndef PAKFIX
                    862:     if (ecrec.number_this_disk == 0) {
                    863: #else /* PAKFIX */
                    864:     error = ((ecrec.number_this_disk == 1) &&
                    865:              (ecrec.num_disk_with_start_central_dir == 1));
                    866:     if ((ecrec.number_this_disk == 0) || error) {
                    867:         if (error) {
                    868:             fprintf(stderr,
                    869:      "\n     Warning:  zipfile claims to be disk 2 of a two-part archive;\n\
                    870:      attempting to process anyway.  If no further errors occur, this\n\
                    871:      archive was probably created by PAK v2.51 or earlier.  This bug\n\
                    872:      was reported to NoGate in March 1991 and was supposed to have been\n\
                    873:      fixed by mid-1991; as of mid-1992 it still hadn't been.\n\n");
                    874:             error_in_archive = 1;  /* 1:  warning */
                    875:         }
                    876: #endif /* ?PAKFIX */
                    877:         expect_ecrec_offset = ecrec.offset_start_central_directory +
                    878:                               ecrec.size_central_directory;
                    879:         if ((extra_bytes = real_ecrec_offset - expect_ecrec_offset) < 0) {
                    880:             fprintf(stderr, "\nerror:  missing %ld bytes in zipfile (\
                    881: attempting to process anyway)\n\n", -extra_bytes);
                    882:             error_in_archive = 2;       /* 2:  (weak) error in zipfile */
                    883:         } else if (extra_bytes > 0) {
                    884:             if ((ecrec.offset_start_central_directory == 0) &&
                    885:                 (ecrec.size_central_directory != 0))   /* zip 1.5 -go bug */
                    886:             {
                    887:                 fprintf(stderr, "\nerror:  NULL central directory offset (\
                    888: attempting to process anyway)\n\n");
                    889:                 ecrec.offset_start_central_directory = extra_bytes;
                    890:                 extra_bytes = 0;
                    891:                 error_in_archive = 2;   /* 2:  (weak) error in zipfile */
                    892:             } else {
                    893:                 fprintf(stderr, "\nwarning:  extra %ld bytes at beginning or\
                    894:  within zipfile\n          (attempting to process anyway)\n\n", extra_bytes);
                    895:                 error_in_archive = 1;   /* 1:  warning error */
                    896:             }
                    897:         }
                    898: 
                    899:     /*-----------------------------------------------------------------------
                    900:         Check for empty zipfile and exit now if so.
                    901:       -----------------------------------------------------------------------*/
                    902: 
                    903:         if (expect_ecrec_offset == 0L  &&  ecrec.size_central_directory == 0) {
                    904:             fprintf(stderr, "warning:  zipfile is empty\n");
                    905:             close(zipfd);
                    906:             return (error_in_archive > 1)? error_in_archive : 1;
                    907:         }
                    908: 
                    909:     /*-----------------------------------------------------------------------
                    910:         Compensate for missing or extra bytes, and seek to where the start
                    911:         of central directory should be.  If header not found, uncompensate
                    912:         and try again (necessary for at least some Atari archives created
                    913:         with STZIP, as well as archives created by J.H. Holm's ZIPSPLIT).
                    914:       -----------------------------------------------------------------------*/
                    915: 
                    916:         LSEEK( ecrec.offset_start_central_directory )
                    917:         if ((readbuf(sig, 4) <= 0) || strncmp(sig, central_hdr_sig, 4)) {
                    918:             longint tmp = extra_bytes;
                    919: 
                    920:             extra_bytes = 0;
                    921:             LSEEK( ecrec.offset_start_central_directory )
                    922:             if ((readbuf(sig, 4) <= 0) || strncmp(sig, central_hdr_sig, 4)) {
                    923:                 fprintf(stderr,
                    924:             "error:  start of central directory not found; zipfile corrupt.\n");
                    925:                 fprintf(stderr, ReportMsg);
                    926:                 close(zipfd);
                    927:                 return 3;           /* 3:  severe error in zipfile */
                    928:             }
                    929:             fprintf(stderr, "error:  reported length of central directory is \
                    930: %d bytes too\n        long (Atari STZIP zipfile?  J.H. Holm ZIPSPLIT zipfile?)\
                    931: .\n        Compensating...\n\n", -tmp);
                    932:             error_in_archive = 2;   /* 2:  (weak) error in zipfile */
                    933:         }
                    934: 
                    935:     /*-----------------------------------------------------------------------
                    936:         Seek to the start of the central directory one last time, since we
                    937:         have just read the first entry's signature bytes; then list, extract
                    938:         or test member files as instructed, and close the zipfile.
                    939:       -----------------------------------------------------------------------*/
                    940: 
                    941:         LSEEK( ecrec.offset_start_central_directory )
                    942:         if (vflag)
                    943:             error = list_files();               /* LIST 'EM */
                    944:         else
                    945:             error = extract_or_test_files();    /* EXTRACT OR TEST 'EM */
                    946:         if (error > error_in_archive)   /* don't overwrite stronger error */
                    947:             error_in_archive = error;   /*  with (for example) a warning */
                    948:     } else {
                    949:         fprintf(stderr, "\nerror:  zipfile is part of multi-disk archive \
                    950: (sorry, not supported).\n");
                    951:     /*  fprintf(stderr, "Please report to [email protected]\n");  */
                    952:         error_in_archive = 11;  /* 11:  no files found */
                    953:     }
                    954: 
                    955:     close(zipfd);
                    956:     return error_in_archive;
                    957: 
                    958: } /* end function process_zipfile() */
                    959: 
                    960: 
                    961: 
                    962: 
                    963: 
                    964: /************************************/
                    965: /*  Function find_end_central_dir() */
                    966: /************************************/
                    967: 
                    968: int find_end_central_dir()   /* return 0 if found, 1 otherwise */
                    969: {
                    970:     int i, numblks;
                    971:     longint tail_len;
                    972: 
                    973: 
                    974: 
                    975: /*---------------------------------------------------------------------------
                    976:     Treat case of short zipfile separately.
                    977:   ---------------------------------------------------------------------------*/
                    978: 
                    979:     if (ziplen <= INBUFSIZ) {
                    980:         lseek(zipfd, 0L, SEEK_SET);
                    981:         if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)ziplen)) ==
                    982:              (int)ziplen)
                    983: 
                    984:             /* 'P' must be at least 22 bytes from end of zipfile */
                    985:             for (inptr = inbuf+(int)ziplen-22;  inptr >= inbuf;  --inptr)
                    986:                 if ((ascii_to_native(*inptr) == 'P')  &&
                    987:                      !strncmp((char *)inptr, end_central_sig, 4)) {
                    988:                     incnt -= inptr - inbuf;
                    989:                     return 0;   /* found it! */
                    990:                 }               /* ...otherwise fall through & fail */
                    991: 
                    992: /*---------------------------------------------------------------------------
                    993:     Zipfile is longer than INBUFSIZ:  may need to loop.  Start with short
                    994:     block at end of zipfile (if not TOO short).
                    995:   ---------------------------------------------------------------------------*/
                    996: 
                    997:     } else {
                    998:         if ((tail_len = ziplen % INBUFSIZ) > ECREC_SIZE) {
                    999:             cur_zipfile_bufstart = lseek(zipfd, ziplen-tail_len, SEEK_SET);
                   1000:             if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)tail_len)) !=
                   1001:                  (int)tail_len)
                   1002:                 goto fail;      /* shut up; it's expedient. */
                   1003: 
                   1004:             /* 'P' must be at least 22 bytes from end of zipfile */
                   1005:             for (inptr = inbuf+(int)tail_len-22;  inptr >= inbuf;  --inptr)
                   1006:                 if ((ascii_to_native(*inptr) == 'P')  &&
                   1007:                      !strncmp((char *)inptr, end_central_sig, 4)) {
                   1008:                     incnt -= inptr - inbuf;
                   1009:                     return 0;   /* found it */
                   1010:                 }               /* ...otherwise search next block */
                   1011:             strncpy((char *)hold, (char *)inbuf, 3);    /* sig may span block
                   1012:                                                            boundary */
                   1013:         } else {
                   1014:             cur_zipfile_bufstart = ziplen - tail_len;
                   1015:         }
                   1016: 
                   1017:     /*-----------------------------------------------------------------------
                   1018:         Loop through blocks of zipfile data, starting at the end and going
                   1019:         toward the beginning.  Need only check last 65557 bytes of zipfile:
                   1020:         comment may be up to 65535 bytes long, end-of-central-directory rec-
                   1021:         ord is 18 bytes (shouldn't hardcode this number, but what the hell:
                   1022:         already did so above (22=18+4)), and sig itself is 4 bytes.
                   1023:       -----------------------------------------------------------------------*/
                   1024: 
                   1025:         numblks = (int)
                   1026:                   ((MIN(ziplen,65557L) - tail_len + (INBUFSIZ-1)) / INBUFSIZ);
                   1027:         /*          =amount to search=   ==done==   ==rounding==    =blksiz= */
                   1028: 
                   1029:         for (i = 1;  i <= numblks;  ++i) {
                   1030:             cur_zipfile_bufstart -= INBUFSIZ;
                   1031:             lseek(zipfd, cur_zipfile_bufstart, SEEK_SET);
                   1032:             if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) != INBUFSIZ)
                   1033:                 break;          /* fall through and fail */
                   1034: 
                   1035:             for (inptr = inbuf+INBUFSIZ-1;  inptr >= inbuf;  --inptr)
                   1036:                 if ((ascii_to_native(*inptr) == 'P')  &&
                   1037:                      !strncmp((char *)inptr, end_central_sig, 4)) {
                   1038:                     incnt -= inptr - inbuf;
                   1039:                     return 0;   /* found it */
                   1040:                 }
                   1041:             strncpy((char *)hold, (char *)inbuf, 3);    /* sig may span block
                   1042:                                                            boundary */
                   1043:         }
                   1044: 
                   1045:     } /* end if (ziplen > INBUFSIZ) */
                   1046: 
                   1047: /*---------------------------------------------------------------------------
                   1048:     Searched through whole region where signature should be without finding
                   1049:     it.  Print informational message and die a horrible death.
                   1050:   ---------------------------------------------------------------------------*/
                   1051: 
                   1052: fail:
                   1053: #ifdef MSWIN
                   1054:     MessageBeep(1);
                   1055: #endif
                   1056: 
                   1057:     fprintf(stderr, "\nFile:  %s\n\n\
                   1058:      End-of-central-directory signature not found.  Either this file is not\n\
                   1059:      a zipfile, or it constitutes one disk of a multi-part archive.  In the\n\
                   1060:      latter case the central directory and zipfile comment will be found on\n\
                   1061:      the last disk(s) of this archive.\n", zipfn);
                   1062:     return 1;
                   1063: 
                   1064: } /* end function find_end_central_dir() */
                   1065: 
                   1066: 
                   1067: 
                   1068: 
                   1069: 
                   1070: /***************************************/
                   1071: /*  Function process_end_central_dir() */
                   1072: /***************************************/
                   1073: 
                   1074: int process_end_central_dir()    /* return PK-type error code */
                   1075: {
                   1076:     ec_byte_rec byterec;
                   1077:     int error=0;
                   1078: 
                   1079: 
                   1080: /*---------------------------------------------------------------------------
                   1081:     Read the end-of-central-directory record and do any necessary machine-
                   1082:     type conversions (byte ordering, structure padding compensation) by
                   1083:     reading data into character array, then copying to struct.
                   1084:   ---------------------------------------------------------------------------*/
                   1085: 
                   1086:     if (readbuf((char *) byterec, ECREC_SIZE+4) <= 0)
                   1087:         return 51;
                   1088: 
                   1089:     ecrec.number_this_disk =
                   1090:         makeword(&byterec[NUMBER_THIS_DISK]);
                   1091:     ecrec.num_disk_with_start_central_dir =
                   1092:         makeword(&byterec[NUM_DISK_WITH_START_CENTRAL_DIR]);
                   1093:     ecrec.num_entries_centrl_dir_ths_disk =
                   1094:         makeword(&byterec[NUM_ENTRIES_CENTRL_DIR_THS_DISK]);
                   1095:     ecrec.total_entries_central_dir =
                   1096:         makeword(&byterec[TOTAL_ENTRIES_CENTRAL_DIR]);
                   1097:     ecrec.size_central_directory =
                   1098:         makelong(&byterec[SIZE_CENTRAL_DIRECTORY]);
                   1099:     ecrec.offset_start_central_directory =
                   1100:         makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
                   1101:     ecrec.zipfile_comment_length =
                   1102:         makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
                   1103: 
                   1104: /*---------------------------------------------------------------------------
                   1105:     Get the zipfile comment, if any, and print it out.  (Comment may be up
                   1106:     to 64KB long.  May the fleas of a thousand camels infest the armpits of
                   1107:     anyone who actually takes advantage of this fact.)  Then position the
                   1108:     file pointer to the beginning of the central directory and fill buffer.
                   1109:   ---------------------------------------------------------------------------*/
                   1110: 
                   1111: #ifdef MSWIN
                   1112:     cchComment = ecrec.zipfile_comment_length; /* save for comment button */
                   1113:     if (ecrec.zipfile_comment_length && zflag) {
                   1114: #else /* !MSWIN */
                   1115:     if (ecrec.zipfile_comment_length && !quietflg) {
                   1116:         if (!zflag)
                   1117:           printf("[%s] comment:\n", zipfn);
                   1118: #endif /* ?MSWIN */
                   1119:         if (do_string(ecrec.zipfile_comment_length,DISPLAY)) {
                   1120:             fprintf(stderr, "\ncaution:  zipfile comment truncated\n");
                   1121:             error = 1;          /* 1:  warning error */
                   1122:         }
                   1123:     }
                   1124: 
                   1125:     return error;
                   1126: 
                   1127: } /* end function process_end_central_dir() */
                   1128: 
                   1129: 
                   1130: 
                   1131: 
                   1132: 
                   1133: /* also referenced in UpdateListBox() in updatelb.c (Windows version) */
                   1134: char *Headers[][2] = {
                   1135:     {" Length    Date    Time    Name",
                   1136:      " ------    ----    ----    ----"},
                   1137:     {" Length  Method   Size  Ratio   Date    Time   CRC-32     Name",
                   1138:      " ------  ------   ----  -----   ----    ----   ------     ----"}
                   1139: };
                   1140: 
                   1141: /*************************/
                   1142: /* Function list_files() */
                   1143: /*************************/
                   1144: 
                   1145: int list_files()    /* return PK-type error code */
                   1146: {
                   1147:     char **fnamev;
                   1148:     int do_this_file=FALSE, ratio, error, error_in_archive=0;
                   1149:     int which_hdr=(vflag>1), date_format;
                   1150:     UWORD j, yr, mo, dy, hh, mm, members=0;
                   1151:     ULONG tot_csize=0L, tot_ucsize=0L;
                   1152: #ifdef OS2
                   1153:     ULONG tot_easize=0L, tot_eafiles=0L, ea_size;
                   1154: #endif
                   1155: #ifdef MSWIN
                   1156:     PSTR psLBEntry;  /* list box entry */
                   1157: #endif
                   1158:     min_info info;
                   1159:     static char *method[NUM_METHODS+1] =
                   1160:         {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
                   1161:          "Implode", "Token", "Deflate", unkn};
                   1162: 
                   1163: 
                   1164: 
                   1165: /*---------------------------------------------------------------------------
                   1166:     Unlike extract_or_test_files(), this routine confines itself to the cen-
                   1167:     tral directory.  Thus its structure is somewhat simpler, since we can do
                   1168:     just a single loop through the entire directory, listing files as we go.
                   1169: 
                   1170:     So to start off, print the heading line and then begin main loop through
                   1171:     the central directory.  The results will look vaguely like the following:
                   1172: 
                   1173:   Length  Method   Size  Ratio   Date    Time   CRC-32     Name ("^" ==> case
                   1174:   ------  ------   ----  -----   ----    ----   ------     ----   conversion)
                   1175:    44004  Implode  13041  71%  11-02-89  19:34  8b4207f7   Makefile.UNIX
                   1176:     3438  Shrunk    2209  36%  09-15-90  14:07  a2394fd8  ^dos-file.ext
                   1177:   ---------------------------------------------------------------------------*/
                   1178: 
                   1179:     pInfo = &info;
                   1180:     date_format = dateformat();
                   1181: 
                   1182: #ifndef MSWIN
                   1183:     if (quietflg < 2)
                   1184:         if (U_flag)
                   1185:             printf("%s\n%s\n", Headers[which_hdr][0], Headers[which_hdr][1]);
                   1186:         else
                   1187:             printf("%s (\"^\" ==> case\n%s   conversion)\n", 
                   1188:               Headers[which_hdr][0], Headers[which_hdr][1]);
                   1189: #endif /* !MSWIN */
                   1190: 
                   1191:     for (j = 0; j < ecrec.total_entries_central_dir; ++j) {
                   1192: 
                   1193:         if (readbuf(sig, 4) <= 0)
                   1194:             return 51;          /* 51:  unexpected EOF */
                   1195:         if (strncmp(sig, central_hdr_sig, 4)) {  /* just to make sure */
                   1196:             fprintf(stderr, CentSigMsg, j);  /* sig not found */
                   1197:             fprintf(stderr, ReportMsg);   /* check binary transfers */
                   1198:             return 3;           /* 3:  error in zipfile */
                   1199:         }
                   1200:         if ((error = process_cdir_file_hdr()) != 0)  /* (sets pInfo->lcflag) */
                   1201:             return error;       /* only 51 (EOF) defined */
                   1202: 
                   1203:         /*
                   1204:          * We could DISPLAY the filename instead of storing (and possibly trun-
                   1205:          * cating, in the case of a very long name) and printing it, but that
                   1206:          * has the disadvantage of not allowing case conversion--and it's nice
                   1207:          * to be able to see in the listing precisely how you have to type each
                   1208:          * filename in order for unzip to consider it a match.  Speaking of
                   1209:          * which, if member names were specified on the command line, check in
                   1210:          * with match() to see if the current file is one of them, and make a
                   1211:          * note of it if it is.
                   1212:          */
                   1213: 
                   1214:         if ((error = do_string(crec.filename_length, FILENAME)) != 0) {
                   1215:             error_in_archive = error;  /*             ^--(uses pInfo->lcflag) */
                   1216:             if (error > 1)      /* fatal:  can't continue */
                   1217:                 return error;
                   1218:         }
                   1219:         if (extra_field != (byte *)NULL)
                   1220:             free(extra_field);
                   1221:         extra_field = (byte *)NULL;
                   1222:         if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0) {
                   1223:             error_in_archive = error;  
                   1224:             if (error > 1)      /* fatal:  can't continue */
                   1225:                 return error;
                   1226:         }
                   1227:         if (!process_all_files) {   /* check if specified on command line */
                   1228:             do_this_file = FALSE;
                   1229:             fnamev = fnv;       /* don't destroy permanent filename ptr */
                   1230:             for (--fnamev; *++fnamev;)
                   1231:                 if (match(filename, *fnamev)) {
                   1232:                     do_this_file = TRUE;
                   1233:                     break;      /* found match, so stop looping */
                   1234:                 }
                   1235:         }
                   1236:         /*
                   1237:          * If current file was specified on command line, or if no names were
                   1238:          * specified, do the listing for this file.  Otherwise, get rid of the
                   1239:          * file comment and go back for the next file.
                   1240:          */
                   1241: 
                   1242:         if (process_all_files || do_this_file) {
                   1243: 
                   1244:             yr = (((crec.last_mod_file_date >> 9) & 0x7f) + 80) % (unsigned)100;
                   1245:             mo = (crec.last_mod_file_date >> 5) & 0x0f;
                   1246:             dy = crec.last_mod_file_date & 0x1f;
                   1247: 
                   1248:             /* twist date so it displays according to national convention */
                   1249:             switch (date_format) {
                   1250:                 case DF_YMD:
                   1251:                     hh = mo; mo = yr; yr = dy; dy = hh; break;
                   1252:                 case DF_DMY:
                   1253:                     hh = mo; mo = dy; dy = hh;
                   1254:             }
                   1255:             hh = (crec.last_mod_file_time >> 11) & 0x1f;
                   1256:             mm = (crec.last_mod_file_time >> 5) & 0x3f;
                   1257: 
                   1258:             csize = (longint) crec.compressed_size;
                   1259:             ucsize = (longint) crec.uncompressed_size;
                   1260:             if (crec.general_purpose_bit_flag & 1)
                   1261:                 csize -= 12;    /* if encrypted, don't count encrypt hdr */
                   1262: 
                   1263:             ratio = (ucsize == 0) ? 0 :   /* .zip can have 0-length members */
                   1264:                 ((ucsize > 2000000L) ?    /* risk signed overflow if mult. */
                   1265:                 (int) ((ucsize-csize) / (ucsize/1000L)) + 5 :   /* big */
                   1266:                 (int) ((1000L*(ucsize-csize)) / ucsize) + 5);   /* small */
                   1267: 
                   1268: #if 0       /* GRR/Euro:  add this?  define p above */
                   1269: #if (defined(DOS_OS2) || (defined(UNIX) && !defined(VMS)))
                   1270:             for (p = filename;  *p;  ++p)
                   1271:                 if (!isprint(*p))
                   1272:                     *p = '?';  /* change non-printable chars to '?' */
                   1273: #endif /* DOS_OS2 || UNIX */
                   1274: #endif /* 0 */
                   1275: 
                   1276: #ifdef MSWIN
                   1277: #ifdef NEED_EARLY_REDRAW
                   1278:             /* turn on listbox redrawing just before adding last line */
                   1279:             if (j == (ecrec.total_entries_central_dir-1))
                   1280:                 (void)SendMessage(hWndList, WM_SETREDRAW, TRUE, 0L);
                   1281: #endif /* NEED_EARLY_REDRAW */
                   1282:             psLBEntry =
                   1283:               (PSTR)LocalAlloc(LMEM_FIXED, FILNAMSIZ+LONG_FORM_FNAME_INX);
                   1284:             switch (which_hdr) {
                   1285:                 case 0:   /* short form */
                   1286:                     OemToAnsi(filename, filename);  /* translate to ANSI */
                   1287:                     wsprintf(psLBEntry, "%7ld  %02u-%02u-%02u  %02u:%02u  %c%s",
                   1288:                       (long)ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'^':' '),
                   1289:                       (LPSTR)filename);
                   1290:                     SendMessage(hWndList, LB_ADDSTRING, 0,
                   1291:                       (LONG)(LPSTR)psLBEntry);
                   1292:                     break;
                   1293:                 case 1:   /* verbose */
                   1294:                     OemToAnsi(filename, filename);  /* translate to ANSI */
                   1295:                     wsprintf(psLBEntry, 
                   1296:                  "%7ld  %-7s%7ld %3d%%  %02u-%02u-%02u  %02u:%02u  %08lx  %c%s",
                   1297:                       (long)ucsize, (LPSTR)method[methnum], (long)csize,
                   1298:                       ratio/10, mo, dy, yr, hh, mm, (unsigned long)crec.crc32,
                   1299:                       (pInfo->lcflag?'^':' '), (LPSTR)filename);
                   1300:                     SendMessage(hWndList, LB_ADDSTRING, 0,
                   1301:                       (LONG)(LPSTR)psLBEntry);
                   1302:             }
                   1303:             LocalFree((HANDLE)psLBEntry);
                   1304: #else /* !MSWIN */
                   1305:             switch (which_hdr) {
                   1306:                 case 0:   /* short form */
                   1307:                     printf("%7ld  %02u-%02u-%02u  %02u:%02u  %c%s\n",
                   1308:                       ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'^':' '),
                   1309:                       filename);
                   1310:                     break;
                   1311:                 case 1:   /* verbose */
                   1312:                     printf(
                   1313:               "%7ld  %-7s%7ld %3d%%  %02u-%02u-%02u  %02u:%02u  %08lx  %c%s\n",
                   1314:                       ucsize, method[methnum], csize, ratio/10, mo, dy, yr,
                   1315:                       hh, mm, crec.crc32, (pInfo->lcflag?'^':' '), filename);
                   1316:             }
                   1317: #endif /* ?MSWIN */
                   1318: 
                   1319:             error = do_string(crec.file_comment_length, (QCOND? DISPLAY:SKIP));
                   1320:             if (error) {
                   1321:                 error_in_archive = error;  /* might be just warning */
                   1322:                 if (error > 1)  /* fatal */
                   1323:                     return error;
                   1324:             }
                   1325:             tot_ucsize += (ULONG) ucsize;
                   1326:             tot_csize += (ULONG) csize;
                   1327:             ++members;
                   1328: #ifdef OS2
                   1329:             if ((ea_size = SizeOfEAs(extra_field)) != 0) {
                   1330:                 tot_easize += ea_size;
                   1331:                 tot_eafiles++;
                   1332:             }
                   1333: #endif
                   1334:         } else {        /* not listing this file */
                   1335:             SKIP_(crec.file_comment_length)
                   1336:         }
                   1337:     }                   /* end for-loop (j: files in central directory) */
                   1338: 
                   1339: /*---------------------------------------------------------------------------
                   1340:     Print footer line and totals (compressed size, uncompressed size, number
                   1341:     of members in zipfile).
                   1342:   ---------------------------------------------------------------------------*/
                   1343: 
                   1344:     ratio = (tot_ucsize == 0) ? 
                   1345:         0 : ((tot_ucsize > 4000000L) ?   /* risk unsigned overflow if mult. */
                   1346:         (int) ((tot_ucsize - tot_csize) / (tot_ucsize/1000L)) + 5 :
                   1347:         (int) ((tot_ucsize - tot_csize) * 1000L / tot_ucsize) + 5);
                   1348: 
                   1349:     if (quietflg < 2) {
                   1350: #ifdef MSWIN
                   1351:         /* Display just the totals since the dashed lines get displayed
                   1352:          * in UpdateListBox(). Get just enough space to display total.
                   1353:          */
                   1354:         switch (which_hdr) {
                   1355:             case 0:         /* short */
                   1356:                 wsprintf(lpumb->szTotalsLine, "%7lu                    %-7u", 
                   1357:                   (ULONG)tot_ucsize, members);
                   1358:                 break;
                   1359:             case 1:         /* verbose */
                   1360:                 wsprintf(lpumb->szTotalsLine, 
                   1361:                   "%7lu         %7lu %3d%%                              %-7u", 
                   1362:                   (ULONG)tot_ucsize, (ULONG)tot_csize, ratio / 10, members);
                   1363:                 break;
                   1364:         }
                   1365: #else /* !MSWIN */
                   1366:         switch (which_hdr) {
                   1367:         case 0:         /* short */
                   1368:             printf("%s\n%7lu                    %-7u\n",
                   1369:                    " ------                    -------",
                   1370:                    tot_ucsize, members);
                   1371:             break;
                   1372:         case 1:         /* verbose */
                   1373:             printf(
                   1374:               "%s\n%7lu         %7lu %3d%%                              %-7u\n",
                   1375:               " ------          ------  ---                              -------",
                   1376:               tot_ucsize, tot_csize, ratio / 10, members);
                   1377:         }
                   1378: #endif /* ?MSWIN */
                   1379: #ifdef OS2
                   1380:         if (tot_eafiles && tot_easize)
                   1381:             printf("\n%ld file%s %ld bytes of EA's attached.\n", tot_eafiles, 
                   1382:               tot_eafiles == 1 ? " has" : "s have a total of", tot_easize);
                   1383: #endif
                   1384:     }
                   1385: /*---------------------------------------------------------------------------
                   1386:     Double check that we're back at the end-of-central-directory record.
                   1387:   ---------------------------------------------------------------------------*/
                   1388: 
                   1389:     readbuf(sig, 4);
                   1390:     if (strncmp(sig, end_central_sig, 4)) {     /* just to make sure again */
                   1391:         fprintf(stderr, EndSigMsg);  /* didn't find end-of-central-dir sig */
                   1392: /*      fprintf(stderr, ReportMsg);   */
                   1393:         error_in_archive = 1;        /* 1:  warning error */
                   1394:     }
                   1395:     return error_in_archive;
                   1396: 
                   1397: } /* end function list_files() */
                   1398: 
                   1399: 
                   1400: 
                   1401: 
                   1402: 
                   1403: /**************************************/
                   1404: /*  Function process_cdir_file_hdr()  */
                   1405: /**************************************/
                   1406: 
                   1407: int process_cdir_file_hdr()    /* return PK-type error code */
                   1408: {
                   1409:     cdir_byte_hdr byterec;
                   1410: 
                   1411: 
                   1412: /*---------------------------------------------------------------------------
                   1413:     Read the next central directory entry and do any necessary machine-type
                   1414:     conversions (byte ordering, structure padding compensation--do so by
                   1415:     copying the data from the array into which it was read (byterec) to the
                   1416:     usable struct (crec)).
                   1417:   ---------------------------------------------------------------------------*/
                   1418: 
                   1419:     if (readbuf((char *) byterec, CREC_SIZE) <= 0)
                   1420:         return 51;   /* 51:  unexpected EOF */
                   1421: 
                   1422:     crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
                   1423:     crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1];
                   1424:     crec.version_needed_to_extract[0] = byterec[C_VERSION_NEEDED_TO_EXTRACT_0];
                   1425:     crec.version_needed_to_extract[1] = byterec[C_VERSION_NEEDED_TO_EXTRACT_1];
                   1426: 
                   1427:     crec.general_purpose_bit_flag =
                   1428:         makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
                   1429:     crec.compression_method =
                   1430:         makeword(&byterec[C_COMPRESSION_METHOD]);
                   1431:     crec.last_mod_file_time =
                   1432:         makeword(&byterec[C_LAST_MOD_FILE_TIME]);
                   1433:     crec.last_mod_file_date =
                   1434:         makeword(&byterec[C_LAST_MOD_FILE_DATE]);
                   1435:     crec.crc32 =
                   1436:         makelong(&byterec[C_CRC32]);
                   1437:     crec.compressed_size =
                   1438:         makelong(&byterec[C_COMPRESSED_SIZE]);
                   1439:     crec.uncompressed_size =
                   1440:         makelong(&byterec[C_UNCOMPRESSED_SIZE]);
                   1441:     crec.filename_length =
                   1442:         makeword(&byterec[C_FILENAME_LENGTH]);
                   1443:     crec.extra_field_length =
                   1444:         makeword(&byterec[C_EXTRA_FIELD_LENGTH]);
                   1445:     crec.file_comment_length =
                   1446:         makeword(&byterec[C_FILE_COMMENT_LENGTH]);
                   1447:     crec.disk_number_start =
                   1448:         makeword(&byterec[C_DISK_NUMBER_START]);
                   1449:     crec.internal_file_attributes =
                   1450:         makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]);
                   1451:     crec.external_file_attributes =
                   1452:         makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]);  /* LONG, not word! */
                   1453:     crec.relative_offset_local_header =
                   1454:         makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]);
                   1455: 
                   1456:     pInfo->hostnum = MIN(crec.version_made_by[1], NUM_HOSTS);
                   1457: /*  extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS); */
                   1458:     methnum = MIN(crec.compression_method, NUM_METHODS);
                   1459:     if (methnum == NUM_METHODS)
                   1460:         sprintf(unkn, "Unk:%03d", crec.compression_method);
                   1461: 
                   1462: /*---------------------------------------------------------------------------
                   1463:     Set flag for lowercase conversion of filename, depending on which OS the
                   1464:     file is coming from.  This section could be ifdef'd if some people have
                   1465:     come to love DOS uppercase filenames under Unix...but really, guys, get
                   1466:     a life. :)  NOTE THAT ALL SYSTEM NAMES NOW HAVE TRAILING UNDERSCORES!!!
                   1467:     This is to prevent interference with compiler command-line defines such
                   1468:     as -DUNIX, for example, which are then used in "#ifdef UNIX" constructs.
                   1469:   ---------------------------------------------------------------------------*/
                   1470: 
                   1471:     pInfo->lcflag = 0;
                   1472:     if (!U_flag)   /* as long as user hasn't specified case-preservation */
                   1473:         switch (pInfo->hostnum) {
                   1474:             case DOS_OS2_FAT_:
                   1475:         /*  case VMS_:              VMS Zip converts filenames to lowercase */
                   1476:             case VM_CMS_:           /* all caps? */
                   1477:             case CPM_:              /* like DOS, right? */
                   1478:         /*  case ATARI_:            ? */
                   1479:         /*  case Z_SYSTEM_:         ? */
                   1480:         /*  case TOPS20_:           (if we had such a thing...) */
                   1481:                 pInfo->lcflag = 1;  /* convert filename to lowercase */
                   1482:                 break;
                   1483: 
                   1484:             default:                /* AMIGA_, UNIX_, (ATARI_), OS2_HPFS_, */
                   1485:                 break;              /*   MAC_, (Z_SYSTEM_):  no conversion */
                   1486:         }
                   1487: 
                   1488:     return 0;
                   1489: 
                   1490: } /* end function process_cdir_file_hdr() */
                   1491: 
                   1492: 
                   1493: 
                   1494: 
                   1495: 
                   1496: /***************************************/
                   1497: /*  Function process_local_file_hdr()  */
                   1498: /***************************************/
                   1499: 
                   1500: int process_local_file_hdr()    /* return PK-type error code */
                   1501: {
                   1502:     local_byte_hdr byterec;
                   1503: 
                   1504: 
                   1505: /*---------------------------------------------------------------------------
                   1506:     Read the next local file header and do any necessary machine-type con-
                   1507:     versions (byte ordering, structure padding compensation--do so by copy-
                   1508:     ing the data from the array into which it was read (byterec) to the
                   1509:     usable struct (lrec)).
                   1510:   ---------------------------------------------------------------------------*/
                   1511: 
                   1512:     if (readbuf((char *) byterec, LREC_SIZE) <= 0)
                   1513:         return 51;   /* 51:  unexpected EOF */
                   1514: 
                   1515:     lrec.version_needed_to_extract[0] = byterec[L_VERSION_NEEDED_TO_EXTRACT_0];
                   1516:     lrec.version_needed_to_extract[1] = byterec[L_VERSION_NEEDED_TO_EXTRACT_1];
                   1517: 
                   1518:     lrec.general_purpose_bit_flag = makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]);
                   1519:     lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]);
                   1520:     lrec.last_mod_file_time = makeword(&byterec[L_LAST_MOD_FILE_TIME]);
                   1521:     lrec.last_mod_file_date = makeword(&byterec[L_LAST_MOD_FILE_DATE]);
                   1522:     lrec.crc32 = makelong(&byterec[L_CRC32]);
                   1523:     lrec.compressed_size = makelong(&byterec[L_COMPRESSED_SIZE]);
                   1524:     lrec.uncompressed_size = makelong(&byterec[L_UNCOMPRESSED_SIZE]);
                   1525:     lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
                   1526:     lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
                   1527: 
                   1528:     csize = (longint) lrec.compressed_size;
                   1529:     ucsize = (longint) lrec.uncompressed_size;
                   1530: 
                   1531:     if ((lrec.general_purpose_bit_flag & 8) != 0) {
                   1532:         /* Can't trust local header, use central directory: */
                   1533:       lrec.crc32 = pInfo->crc;
                   1534:         lrec.compressed_size = pInfo->compr_size;
                   1535:         csize = (longint) lrec.compressed_size;
                   1536:     }
                   1537: 
                   1538:     return 0;                 /* 0:  no error */
                   1539: 
                   1540: } /* end function process_local_file_hdr() */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.