JBoss Native SVN: r1490 - in trunk/build/install: installer and 3 other directories.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-03-31 08:15:21 -0400 (Mon, 31 Mar 2008)
New Revision: 1490
Added:
trunk/build/install/installer/
trunk/build/install/installer/NMAKEmakefile
trunk/build/install/installer/consts.h
trunk/build/install/installer/crc32.c
trunk/build/install/installer/crctab.c
trunk/build/install/installer/crypt.c
trunk/build/install/installer/crypt.h
trunk/build/install/installer/dhtml.c
trunk/build/install/installer/ebcdic.h
trunk/build/install/installer/extract.c
trunk/build/install/installer/fileio.c
trunk/build/install/installer/globals.c
trunk/build/install/installer/globals.h
trunk/build/install/installer/gui.c
trunk/build/install/installer/inflate.c
trunk/build/install/installer/inflate.h
trunk/build/install/installer/licenses/
trunk/build/install/installer/licenses/LICENSE
trunk/build/install/installer/main.c
trunk/build/install/installer/match.c
trunk/build/install/installer/process.c
trunk/build/install/installer/res/
trunk/build/install/installer/res/commonc.manifest
trunk/build/install/installer/res/jboss.ico
trunk/build/install/installer/res/jbosstop.bmp
trunk/build/install/installer/res/jbosstop.png
trunk/build/install/installer/res/lgpl.htm
trunk/build/install/installer/res/lgpl.rtf
trunk/build/install/installer/res/lgplmain.htm
trunk/build/install/installer/res/redhat.ico
trunk/build/install/installer/res/redhat16.png
trunk/build/install/installer/res/redhat32.png
trunk/build/install/installer/res/redhat48.png
trunk/build/install/installer/sinstall.h
trunk/build/install/installer/sinstall.rc
trunk/build/install/installer/ttyio.c
trunk/build/install/installer/ttyio.h
trunk/build/install/installer/unzip.c
trunk/build/install/installer/unzip.h
trunk/build/install/installer/unzpriv.h
trunk/build/install/installer/unzvers.h
trunk/build/install/installer/win32/
trunk/build/install/installer/win32/crc_i386.asm
trunk/build/install/installer/win32/crc_i386.c
trunk/build/install/installer/win32/crc_lcc.asm
trunk/build/install/installer/win32/nt.c
trunk/build/install/installer/win32/nt.h
trunk/build/install/installer/win32/w32cfg.h
trunk/build/install/installer/win32/win32.c
trunk/build/install/installer/zip.h
Log:
Add windows installer
Added: trunk/build/install/installer/NMAKEmakefile
===================================================================
--- trunk/build/install/installer/NMAKEmakefile (rev 0)
+++ trunk/build/install/installer/NMAKEmakefile 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,100 @@
+# Copyright(c) 2006 Red Hat Middleware, LLC,
+# and individual contributors as indicated by the @authors tag.
+# See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library in the file COPYING.LIB;
+# if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+# @author Mladen Turk
+#
+
+!IF !DEFINED(TARGET) || "$(TARGET)" == ""
+TARGET = GUI
+!ENDIF
+PROJECT = sinstall
+!include <..\..\NMAKEcommon.inc>
+
+!IF !DEFINED(SRCDIR) || "$(SRCDIR)" == ""
+SRCDIR = .
+!ENDIF
+
+CFLAGS = $(CFLAGS) -DSFX -DASM_CRC -DMAIN=MAIN -DNO_ZIPINFO=1
+
+LFLAGS = $(LFLAGS) user32.lib gdi32.lib winspool.lib comdlg32.lib comctl32.lib
+LFLAGS = $(LFLAGS) shlwapi.lib netapi32.lib shell32.lib ole32.lib urlmon.lib
+LFLAGS = $(LFLAGS) oleaut32.lib psapi.lib
+
+INCLUDES = -I$(SRCDIR)\win32
+
+PDBFLAGS = -Fo$(WORKDIR)\ -Fd$(WORKDIR)\$(PROJECT)-src
+OBJECTS = \
+ $(WORKDIR)\crc32.obj \
+ $(WORKDIR)\crc_i386.obj \
+ $(WORKDIR)\crctab.obj \
+ $(WORKDIR)\crypt.obj \
+ $(WORKDIR)\extract.obj \
+ $(WORKDIR)\fileio.obj \
+ $(WORKDIR)\globals.obj \
+ $(WORKDIR)\inflate.obj \
+ $(WORKDIR)\match.obj \
+ $(WORKDIR)\nt.obj \
+ $(WORKDIR)\process.obj \
+ $(WORKDIR)\ttyio.obj \
+ $(WORKDIR)\unzip.obj \
+ $(WORKDIR)\win32.obj \
+ $(WORKDIR)\gui.obj \
+ $(WORKDIR)\dhtml.obj \
+ $(WORKDIR)\main.obj
+
+OBJDEPS = $(SRCDIR)\*.h \
+ $(SRCDIR)\win32\*.h \
+ NMAKEmakefile
+
+BUILDLOC = $(PREFIX)\bin
+BUILDEXE = $(WORKDIR)\$(PROJECT).exe
+BUILDPDB = $(WORKDIR)\$(PROJECT).pdb
+BUILDRES = $(WORKDIR)\$(PROJECT).res
+BUILDMAN = $(BUILDEXE).manifest
+
+all : $(WORKDIR) $(BUILDEXE)
+
+$(BUILDLOC) :
+ @if not exist "$(BUILDLOC)\$(NULL)" mkdir "$(BUILDLOC)"
+
+$(WORKDIR) :
+ @$(MAKEWORKDIR)
+
+{$(SRCDIR)}.c{$(WORKDIR)}.obj:
+ $(CC) $(CFLAGS) $(INCLUDES) $(PDBFLAGS) $<
+
+{$(SRCDIR)\win32}.c{$(WORKDIR)}.obj:
+ $(CC) $(CFLAGS) $(INCLUDES) $(PDBFLAGS) $<
+
+$(BUILDRES): $(SRCDIR)/$(PROJECT).rc
+ $(RC) $(RCFLAGS) /i "$(SRCDIR)" /fo $(BUILDRES) $(SRCDIR)/$(PROJECT).rc
+
+$(OBJECTS): $(OBJDEPS)
+
+$(BUILDEXE): $(WORKDIR) $(OBJECTS) $(BUILDRES)
+ $(LINK) $(LFLAGS) $(OBJECTS) $(BUILDRES) $(LIBS) $(LDIRS) /pdb:$(BUILDPDB) /out:$(BUILDEXE)
+ IF EXIST $(BUILDMAN) \
+ mt -nologo -manifest $(BUILDMAN) -outputresource:$(BUILDEXE);1
+
+clean:
+ @$(CLEANTARGET)
+
+install: $(BUILDLOC) $(WORKDIR) $(BUILDEXE)
+ @xcopy "$(WORKDIR)\*.exe" "$(BUILDLOC)" /Y /Q
Property changes on: trunk/build/install/installer/NMAKEmakefile
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/consts.h
===================================================================
--- trunk/build/install/installer/consts.h (rev 0)
+++ trunk/build/install/installer/consts.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,54 @@
+/*
+ Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ consts.h
+
+ This file contains global, initialized variables that never change. It is
+ included by unzip.c and windll/windll.c.
+
+ ---------------------------------------------------------------------------*/
+
+
+/* And'ing with mask_bits[n] masks the lower n bits */
+ZCONST unsigned near mask_bits[17] = {
+ 0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+ZCONST char Far VersionDate[] = UZ_VERSION_DATE; /* now defined in unzvers.h */
+
+#ifndef SFX
+ ZCONST char Far EndSigMsg[] =
+ "\nnote: didn't find end-of-central-dir signature at end of central dir.\n";
+#endif
+
+ZCONST char Far CentSigMsg[] =
+ "error: expected central file header signature not found (file #%lu).\n";
+ZCONST char Far SeekMsg[] =
+ "error [%s]: attempt to seek before beginning of zipfile\n%s";
+ZCONST char Far FilenameNotMatched[] = "caution: filename not matched: %s\n";
+ZCONST char Far ExclFilenameNotMatched[] =
+ "caution: excluded filename not matched: %s\n";
+
+#ifdef VMS
+ ZCONST char Far ReportMsg[] = "\
+ (please check that you have transferred or created the zipfile in the\n\
+ appropriate BINARY mode--this includes ftp, Kermit, AND unzip'd zipfiles)\n";
+#else
+ ZCONST char Far ReportMsg[] = "\
+ (please check that you have transferred or created the zipfile in the\n\
+ appropriate BINARY mode and that you have compiled UnZip properly)\n";
+#endif
+
+#ifndef SFX
+ ZCONST char Far Zipnfo[] = "zipinfo";
+ ZCONST char Far CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n";
+#endif
Property changes on: trunk/build/install/installer/consts.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/crc32.c
===================================================================
--- trunk/build/install/installer/crc32.c (rev 0)
+++ trunk/build/install/installer/crc32.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,64 @@
+/*
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* $Id: crc32.c,v 1.5 1996/01/13 14:55:12 spc Exp $ */
+
+#define __CRC32_C /* identifies this source module */
+
+#include "zip.h"
+
+#ifndef USE_ZLIB
+#ifndef ASM_CRC
+
+#ifndef ZCONST
+# define ZCONST const
+#endif
+
+#ifdef CRC32
+# undef CRC32
+#endif
+#define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
+#define DO1(buf) crc = CRC32(crc, *buf++)
+#define DO2(buf) DO1(buf); DO1(buf)
+#define DO4(buf) DO2(buf); DO2(buf)
+#define DO8(buf) DO4(buf); DO4(buf)
+
+/* ========================================================================= */
+ulg crc32(crc, buf, len)
+ register ulg crc; /* crc shift register */
+ register ZCONST uch *buf; /* pointer to bytes to pump through */
+ extent len; /* number of bytes in buf[] */
+/* Run a set of bytes through the crc shift register. If buf is a NULL
+ pointer, then initialize the crc shift register contents instead.
+ Return the current crc in either case. */
+{
+ register ZCONST ulg near *crc_table;
+
+ if (buf == NULL) return 0L;
+
+ crc_table = get_crc_table();
+
+ crc = crc ^ 0xffffffffL;
+#ifndef NO_UNROLLED_LOOPS
+ while (len >= 8) {
+ DO8(buf);
+ len -= 8;
+ }
+#endif
+ if (len) do {
+ DO1(buf);
+ } while (--len);
+ return crc ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
+}
+#endif /* !ASM_CRC */
+#endif /* !USE_ZLIB */
Property changes on: trunk/build/install/installer/crc32.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/crctab.c
===================================================================
--- trunk/build/install/installer/crctab.c (rev 0)
+++ trunk/build/install/installer/crctab.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,227 @@
+/*
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* crctab.c -- supply the CRC table needed for CRC-32 calculations.
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* $Id: crctab.c,v 1.4 1996/01/08 14:55:12 jloup Exp $ */
+
+/*
+ Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The table is simply the CRC of all possible eight bit values. This is all
+ the information needed to generate CRC's on data a byte at a time for all
+ combinations of CRC register values and incoming bytes.
+*/
+
+#define __CRCTAB_C /* identifies this source module */
+
+#include "zip.h"
+
+#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
+
+#ifndef ZCONST
+# define ZCONST const
+#endif
+
+#ifdef DYNAMIC_CRC_TABLE
+
+/* =========================================================================
+ * Make the crc table. This function is needed only if you want to compute
+ * the table dynamically.
+ */
+
+local void make_crc_table OF((void));
+
+#if (defined(DYNALLOC_CRCTAB) && defined(REENTRANT))
+ error: Dynamic allocation of CRC table not safe with reentrant code.
+#endif /* DYNALLOC_CRCTAB && REENTRANT */
+
+#ifdef DYNALLOC_CRCTAB
+ local ulg near *crc_table = NULL;
+# if 0 /* not used, since sizeof("near *") <= sizeof(int) */
+ /* Use this section when access to a "local int" is faster than access to
+ a "local pointer" (e.g.: i86 16bit code with far pointers). */
+ local int crc_table_empty = 1;
+# define CRC_TABLE_IS_EMPTY (crc_table_empty != 0)
+# define MARK_CRCTAB_FILLED crc_table_empty = 0
+# define MARK_CRCTAB_EMPTY crc_table_empty = 1
+# else
+ /* Use this section on systems where the size of pointers and ints is
+ equal (e.g.: all 32bit systems). */
+# define CRC_TABLE_IS_EMPTY (crc_table == NULL)
+# define MARK_CRCTAB_FILLED crc_table = crctab_p
+# define MARK_CRCTAB_EMPTY crc_table = NULL
+# endif
+#else /* !DYNALLOC_CRCTAB */
+ local ulg near crc_table[256];
+ local int crc_table_empty = 1;
+# define CRC_TABLE_IS_EMPTY (crc_table_empty != 0)
+# define MARK_CRCTAB_FILLED crc_table_empty = 0
+#endif /* ?DYNALLOC_CRCTAB */
+
+
+local void make_crc_table()
+{
+ ulg c; /* crc shift register */
+ int n; /* counter for all possible eight bit values */
+ int k; /* byte being shifted into crc apparatus */
+#ifdef DYNALLOC_CRCTAB
+ ulg near *crctab_p; /* temporary pointer to allocated crc_table area */
+#else /* !DYNALLOC_CRCTAB */
+# define crctab_p crc_table
+#endif /* DYNALLOC_CRCTAB */
+
+#ifdef COMPUTE_XOR_PATTERN
+ /* This piece of code has been left here to explain how the XOR pattern
+ * used in the creation of the crc_table values can be recomputed.
+ * For production versions of this function, it is more efficient to
+ * supply the resultant pattern at compile time.
+ */
+ ulg xor; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static uch p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* make exclusive-or pattern from polynomial (0xedb88320L) */
+ xor = 0L;
+ for (i = 0; i < sizeof(p)/sizeof(uch); i++)
+ xor |= 1L << (31 - p[i]);
+#else
+# define xor 0xedb88320L
+#endif
+
+#ifdef DYNALLOC_CRCTAB
+ crctab_p = (ulg near *) nearmalloc (256*sizeof(ulg));
+ if (crctab_p == NULL) {
+ ziperr(ZE_MEM, "crc_table allocation");
+ }
+#endif /* DYNALLOC_CRCTAB */
+
+ for (n = 0; n < 256; n++) {
+ c = (ulg)n;
+ for (k = 8; k; k--)
+ c = c & 1 ? xor ^ (c >> 1) : c >> 1;
+ crctab_p[n] = c;
+ }
+ MARK_CRCTAB_FILLED;
+}
+
+#else /* !DYNAMIC_CRC_TABLE */
+
+#ifdef DYNALLOC_CRCTAB
+ error: Inconsistent flags, DYNALLOC_CRCTAB without DYNAMIC_CRC_TABLE.
+#endif
+
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+local ZCONST ulg near crc_table[256] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+};
+#endif /* ?DYNAMIC_CRC_TABLE */
+
+/* use "OF((void))" here to work around a Borland TC++ 1.0 problem */
+#ifdef USE_ZLIB
+ZCONST uLongf *get_crc_table OF((void))
+#else
+ZCONST ulg near *get_crc_table OF((void))
+#endif
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (CRC_TABLE_IS_EMPTY)
+ make_crc_table();
+#endif
+#ifdef USE_ZLIB
+ return (ZCONST uLongf *)crc_table;
+#else
+ return (ZCONST ulg near *)crc_table;
+#endif
+}
+
+#ifdef DYNALLOC_CRCTAB
+void free_crc_table()
+{
+ if (!CRC_TABLE_IS_EMPTY)
+ {
+ nearfree((ulg near *)crc_table);
+ MARK_CRCTAB_EMPTY;
+ }
+}
+#endif
+
+#endif /* !USE_ZLIB || USE_OWN_CRCTAB */
Property changes on: trunk/build/install/installer/crctab.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/crypt.c
===================================================================
--- trunk/build/install/installer/crypt.c (rev 0)
+++ trunk/build/install/installer/crypt.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,583 @@
+/*
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
+
+ This encryption/decryption source code for Info-Zip software was
+ originally written in Europe. The whole source package can be
+ freely distributed, including from the USA. (Prior to January 2000,
+ re-export from the US was a violation of US law.)
+
+ NOTE on copyright history:
+ Previous versions of this source package (up to version 2.8) were
+ not copyrighted and put in the public domain. If you cannot comply
+ with the Info-Zip LICENSE, you may want to look for one of those
+ public domain versions.
+ */
+
+/*
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+ */
+
+#define ZCRYPT_INTERNAL
+#include "zip.h"
+#include "crypt.h"
+#include "ttyio.h"
+
+#if CRYPT
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifdef ZIP
+ /* For the encoding task used in Zip (and ZipCloak), we want to initialize
+ the crypt algorithm with some reasonably unpredictable bytes, see
+ the crypthead() function. The standard rand() library function is
+ used to supply these `random' bytes, which in turn is initialized by
+ a srand() call. The srand() function takes an "unsigned" (at least 16bit)
+ seed value as argument to determine the starting point of the rand()
+ pseudo-random number generator.
+ This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
+ Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
+ as some (hopefully) nondeterministic bitmask. On many (most) systems,
+ we use some "process specific" number, as the PID or something similar,
+ but when nothing unpredictable is available, a fixed number may be
+ sufficient.
+ NOTE:
+ 1.) This implementation requires the availability of the following
+ standard UNIX C runtime library functions: time(), rand(), srand().
+ On systems where some of them are missing, the environment that
+ incorporates the crypt routines must supply suitable replacement
+ functions.
+ 2.) It is a very bad idea to use a second call to time() to set the
+ "Seed2" number! In this case, both "Seed1" and "Seed2" would be
+ (almost) identical, resulting in a (mostly) "zero" constant seed
+ number passed to srand().
+
+ The implementation environment defined in the "zip.h" header should
+ supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
+ most implementations of rand() and srand(), only the lower 16 bits are
+ significant!). An example that works on many systems would be
+ "#define ZCR_SEED2 (unsigned)getpid()".
+ The default definition for ZCR_SEED2 supplied below should be regarded
+ as a fallback to allow successful compilation in "beta state"
+ environments.
+ */
+# include <time.h> /* time() function supplies first part of crypt seed */
+ /* "last resort" source for second part of crypt seed pattern */
+# ifndef ZCR_SEED2
+# define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */
+# endif
+# ifdef GLOBAL /* used in Amiga system headers, maybe others too */
+# undef GLOBAL
+# endif
+# define GLOBAL(g) g
+#else /* !ZIP */
+# define GLOBAL(g) G.g
+#endif /* ?ZIP */
+
+
+#ifdef UNZIP
+ /* char *key = (char *)NULL; moved to globals.h */
+# ifndef FUNZIP
+ local int testp OF((__GPRO__ ZCONST uch *h));
+ local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
+# endif
+#endif /* UNZIP */
+
+#ifndef UNZIP /* moved to globals.h for UnZip */
+ local ulg keys[3]; /* keys defining the pseudo-random sequence */
+#endif /* !UNZIP */
+
+#ifndef Trace
+# ifdef CRYPT_DEBUG
+# define Trace(x) fprintf x
+# else
+# define Trace(x)
+# endif
+#endif
+
+#ifndef CRC_32_TAB
+# define CRC_32_TAB crc_32_tab
+#endif
+
+#define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
+
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+ */
+int decrypt_byte(__G)
+ __GDEF
+{
+ unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
+ * unpredictable manner on 16-bit systems; not a problem
+ * with any known compiler so far, though */
+
+ temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
+ return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/***********************************************************************
+ * Update the encryption keys with the next byte of plain text
+ */
+int update_keys(__G__ c)
+ __GDEF
+ int c; /* byte of plain text */
+{
+ GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c);
+ GLOBAL(keys[1]) += GLOBAL(keys[0]) & 0xff;
+ GLOBAL(keys[1]) = GLOBAL(keys[1]) * 134775813L + 1;
+ {
+ register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
+ GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift);
+ }
+ return c;
+}
+
+
+/***********************************************************************
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+void init_keys(__G__ passwd)
+ __GDEF
+ ZCONST char *passwd; /* password string with which to modify keys */
+{
+ GLOBAL(keys[0]) = 305419896L;
+ GLOBAL(keys[1]) = 591751049L;
+ GLOBAL(keys[2]) = 878082192L;
+ while (*passwd != '\0') {
+ update_keys(__G__ (int)*passwd);
+ passwd++;
+ }
+}
+
+
+#ifdef ZIP
+
+/***********************************************************************
+ * Write encryption header to file zfile using the password passwd
+ * and the cyclic redundancy check crc.
+ */
+void crypthead(passwd, crc, zfile)
+ ZCONST char *passwd; /* password string */
+ ulg crc; /* crc of file being encrypted */
+ FILE *zfile; /* where to write header */
+{
+ int n; /* index in random header */
+ int t; /* temporary */
+ int c; /* random byte */
+ int ztemp; /* temporary for zencoded value */
+ uch header[RAND_HEAD_LEN-2]; /* random header */
+ static unsigned calls = 0; /* ensure different random header each time */
+
+ /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+ * output of rand() to get less predictability, since rand() is
+ * often poorly implemented.
+ */
+ if (++calls == 1) {
+ srand((unsigned)time(NULL) ^ ZCR_SEED2);
+ }
+ init_keys(passwd);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++) {
+ c = (rand() >> 7) & 0xff;
+ header[n] = (uch)zencode(c, t);
+ }
+ /* Encrypt random header (last two bytes is high word of crc) */
+ init_keys(passwd);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++) {
+ ztemp = zencode(header[n], t);
+ putc(ztemp, zfile);
+ }
+ ztemp = zencode((int)(crc >> 16) & 0xff, t);
+ putc(ztemp, zfile);
+ ztemp = zencode((int)(crc >> 24) & 0xff, t);
+ putc(ztemp, zfile);
+}
+
+
+#ifdef UTIL
+
+/***********************************************************************
+ * Encrypt the zip entry described by z from file source to file dest
+ * using the password passwd. Return an error code in the ZE_ class.
+ */
+int zipcloak(z, source, dest, passwd)
+ struct zlist far *z; /* zip entry to encrypt */
+ FILE *source, *dest; /* source and destination files */
+ ZCONST char *passwd; /* password string */
+{
+ int c; /* input byte */
+ int res; /* result code */
+ ulg n; /* holds offset and counts size */
+ ush flag; /* previous flags */
+ int t; /* temporary */
+ int ztemp; /* temporary storage for zencode value */
+
+ /* Set encrypted bit, clear extended local header bit and write local
+ header to output file */
+ if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
+ z->off = n;
+ flag = z->flg;
+ z->flg |= 1, z->flg &= ~8;
+ z->lflg |= 1, z->lflg &= ~8;
+ z->siz += RAND_HEAD_LEN;
+ if ((res = putlocal(z, dest)) != ZE_OK) return res;
+
+ /* Initialize keys with password and write random header */
+ crypthead(passwd, z->crc, dest);
+
+ /* Skip local header in input file */
+ if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
+ SEEK_CUR)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+
+ /* Encrypt data */
+ for (n = z->siz - RAND_HEAD_LEN; n; n--) {
+ if ((c = getc(source)) == EOF) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ ztemp = zencode(c, t);
+ putc(ztemp, dest);
+ }
+ /* Skip extended local header in input file if there is one */
+ if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ if (fflush(dest) == EOF) return ZE_TEMP;
+ return ZE_OK;
+}
+
+/***********************************************************************
+ * Decrypt the zip entry described by z from file source to file dest
+ * using the password passwd. Return an error code in the ZE_ class.
+ */
+int zipbare(z, source, dest, passwd)
+ struct zlist far *z; /* zip entry to encrypt */
+ FILE *source, *dest; /* source and destination files */
+ ZCONST char *passwd; /* password string */
+{
+ int c0, c1; /* last two input bytes */
+ ulg offset; /* used for file offsets */
+ ulg size; /* size of input data */
+ int r; /* size of encryption header */
+ int res; /* return code */
+ ush flag; /* previous flags */
+
+ /* Save position and skip local header in input file */
+ if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
+ fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
+ SEEK_CUR)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ /* Initialize keys with password */
+ init_keys(passwd);
+
+ /* Decrypt encryption header, save last two bytes */
+ c1 = 0;
+ for (r = RAND_HEAD_LEN; r; r--) {
+ c0 = c1;
+ if ((c1 = getc(source)) == EOF) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ Trace((stdout, " (%02x)", c1));
+ zdecode(c1);
+ Trace((stdout, " %02x", c1));
+ }
+ Trace((stdout, "\n"));
+
+ /* If last two bytes of header don't match crc (or file time in the
+ * case of an extended local header), back up and just copy. For
+ * pkzip 2.0, the check has been reduced to one byte only.
+ */
+#ifdef ZIP10
+ if ((ush)(c0 | (c1<<8)) !=
+ (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
+#else
+ c0++; /* avoid warning on unused variable */
+ if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
+#endif
+ if (fseek(source, offset, SEEK_SET)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
+ return ZE_MISS;
+ }
+
+ /* Clear encrypted bit and local header bit, and write local header to
+ output file */
+ if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
+ z->off = offset;
+ flag = z->flg;
+ z->flg &= ~9;
+ z->lflg &= ~9;
+ z->siz -= RAND_HEAD_LEN;
+ if ((res = putlocal(z, dest)) != ZE_OK) return res;
+
+ /* Decrypt data */
+ for (size = z->siz; size; size--) {
+ if ((c1 = getc(source)) == EOF) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ zdecode(c1);
+ putc(c1, dest);
+ }
+ /* Skip extended local header in input file if there is one */
+ if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
+ return ferror(source) ? ZE_READ : ZE_EOF;
+ }
+ if (fflush(dest) == EOF) return ZE_TEMP;
+
+ return ZE_OK;
+}
+
+
+#else /* !UTIL */
+
+/***********************************************************************
+ * If requested, encrypt the data in buf, and in any case call fwrite()
+ * with the arguments to zfwrite(). Return what fwrite() returns.
+ */
+unsigned zfwrite(buf, item_size, nb, f)
+ zvoid *buf; /* data buffer */
+ extent item_size; /* size of each item in bytes */
+ extent nb; /* number of items */
+ FILE *f; /* file to write to */
+{
+ int t; /* temporary */
+
+ if (key != (char *)NULL) { /* key is the global password pointer */
+ ulg size; /* buffer size */
+ char *p = (char*)buf; /* steps through buffer */
+
+ /* Encrypt data in buffer */
+ for (size = item_size*(ulg)nb; size != 0; p++, size--) {
+ *p = (char)zencode(*p, t);
+ }
+ }
+ /* Write the buffer out */
+ return fwrite(buf, item_size, nb, f);
+}
+
+#endif /* ?UTIL */
+#endif /* ZIP */
+
+
+#if (defined(UNZIP) && !defined(FUNZIP))
+
+/***********************************************************************
+ * Get the password and set up keys for current zipfile member.
+ * Return PK_ class error.
+ */
+int decrypt(__G__ passwrd)
+ __GDEF
+ ZCONST char *passwrd;
+{
+ ush b;
+ int n, r;
+ uch h[RAND_HEAD_LEN];
+
+ Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
+
+ /* get header once (turn off "encrypted" flag temporarily so we don't
+ * try to decrypt the same data twice) */
+ GLOBAL(pInfo->encrypted) = FALSE;
+ defer_leftover_input(__G);
+ for (n = 0; n < RAND_HEAD_LEN; n++) {
+ b = NEXTBYTE;
+ h[n] = (uch)b;
+ Trace((stdout, " (%02x)", h[n]));
+ }
+ undefer_input(__G);
+ GLOBAL(pInfo->encrypted) = TRUE;
+
+ if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
+ GLOBAL(newzip) = FALSE;
+ if (passwrd != (char *)NULL) { /* user gave password on command line */
+ if (!GLOBAL(key)) {
+ if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
+ (char *)NULL)
+ return PK_MEM2;
+ strcpy(GLOBAL(key), passwrd);
+ GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */
+ }
+ } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
+ free(GLOBAL(key));
+ GLOBAL(key) = (char *)NULL;
+ }
+ }
+
+ /* if have key already, test it; else allocate memory for it */
+ if (GLOBAL(key)) {
+ if (!testp(__G__ h))
+ return PK_COOL; /* existing password OK (else prompt for new) */
+ else if (GLOBAL(nopwd))
+ return PK_WARN; /* user indicated no more prompting */
+ } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
+ return PK_MEM2;
+
+ /* try a few keys */
+ n = 0;
+ do {
+ r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
+ GLOBAL(zipfn), GLOBAL(filename));
+ if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */
+ free (GLOBAL(key));
+ GLOBAL(key) = NULL;
+ return PK_MEM2;
+ }
+ if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */
+ *GLOBAL(key) = '\0'; /* We try the NIL password, ... */
+ n = 0; /* and cancel fetch for this item. */
+ }
+ if (!testp(__G__ h))
+ return PK_COOL;
+ if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */
+ GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */
+ } while (n > 0);
+
+ return PK_WARN;
+
+} /* end function decrypt() */
+
+
+
+/***********************************************************************
+ * Test the password. Return -1 if bad, 0 if OK.
+ */
+local int testp(__G__ h)
+ __GDEF
+ ZCONST uch *h;
+{
+ int r;
+ char *key_translated;
+
+ /* On systems with "obscure" native character coding (e.g., EBCDIC),
+ * the first test translates the password to the "main standard"
+ * character coding. */
+
+#ifdef STR_TO_CP1
+ /* allocate buffer for translated password */
+ if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
+ return -1;
+ /* first try, test password translated "standard" charset */
+ r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
+#else /* !STR_TO_CP1 */
+ /* first try, test password as supplied on the extractor's host */
+ r = testkey(__G__ h, GLOBAL(key));
+#endif /* ?STR_TO_CP1 */
+
+#ifdef STR_TO_CP2
+ if (r != 0) {
+#ifndef STR_TO_CP1
+ /* now prepare for second (and maybe third) test with translated pwd */
+ if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
+ return -1;
+#endif
+ /* second try, password translated to alternate ("standard") charset */
+ r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
+#ifdef STR_TO_CP3
+ if (r != 0)
+ /* third try, password translated to another "standard" charset */
+ r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
+#endif
+#ifndef STR_TO_CP1
+ free(key_translated);
+#endif
+ }
+#endif /* STR_TO_CP2 */
+
+#ifdef STR_TO_CP1
+ free(key_translated);
+ if (r != 0) {
+ /* last resort, test password as supplied on the extractor's host */
+ r = testkey(__G__ h, GLOBAL(key));
+ }
+#endif /* STR_TO_CP1 */
+
+ return r;
+
+} /* end function testp() */
+
+
+local int testkey(__G__ h, key)
+ __GDEF
+ ZCONST uch *h; /* decrypted header */
+ ZCONST char *key; /* decryption password to test */
+{
+ ush b;
+#ifdef ZIP10
+ ush c;
+#endif
+ int n;
+ uch *p;
+ uch hh[RAND_HEAD_LEN]; /* decrypted header */
+
+ /* set keys and save the encrypted header */
+ init_keys(__G__ key);
+ memcpy(hh, h, RAND_HEAD_LEN);
+
+ /* check password */
+ for (n = 0; n < RAND_HEAD_LEN; n++) {
+ zdecode(hh[n]);
+ Trace((stdout, " %02x", hh[n]));
+ }
+
+ Trace((stdout,
+ "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n",
+ GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
+ GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
+ Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n",
+ GLOBAL(incnt),
+ GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
+
+ /* same test as in zipbare(): */
+
+#ifdef ZIP10 /* check two bytes */
+ c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
+ Trace((stdout,
+ " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
+ (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
+ if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
+ (ush)(GLOBAL(lrec.crc32) >> 16)))
+ return -1; /* bad */
+#else
+ b = hh[RAND_HEAD_LEN-1];
+ Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
+ b, (ush)(GLOBAL(lrec.crc32) >> 24),
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
+ if (b != (GLOBAL(pInfo->ExtLocHdr) ?
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
+ (ush)(GLOBAL(lrec.crc32) >> 24)))
+ return -1; /* bad */
+#endif
+ /* password OK: decrypt current buffer contents before leaving */
+ for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
+ (int)GLOBAL(csize) : GLOBAL(incnt),
+ p = GLOBAL(inptr); n--; p++)
+ zdecode(*p);
+ return 0; /* OK */
+
+} /* end function testkey() */
+
+#endif /* UNZIP && !FUNZIP */
+
+#else /* !CRYPT */
+
+/* something "externally visible" to shut up compiler/linker warnings */
+int zcr_dummy;
+
+#endif /* ?CRYPT */
Property changes on: trunk/build/install/installer/crypt.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/crypt.h
===================================================================
--- trunk/build/install/installer/crypt.h (rev 0)
+++ trunk/build/install/installer/crypt.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,175 @@
+/*
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ crypt.h (full version) by Info-ZIP. Last revised: [see CR_VERSION_DATE]
+
+ This encryption/decryption source code for Info-Zip software was
+ originally written in Europe. The whole source package can be
+ freely distributed, including from the USA. (Prior to January 2000,
+ re-export from the US was a violation of US law.)
+
+ NOTE on copyright history:
+ Previous versions of this source package (up to version 2.8) were
+ not copyrighted and put in the public domain. If you cannot comply
+ with the Info-Zip LICENSE, you may want to look for one of those
+ public domain versions.
+ */
+
+#ifndef __crypt_h /* don't include more than once */
+#define __crypt_h
+
+#ifdef CRYPT
+# undef CRYPT
+#endif
+/*
+ Logic of selecting "full crypt" code:
+ a) default behaviour:
+ - dummy crypt code when compiling UnZipSFX stub, to minimize size
+ - full crypt code when used to compile Zip, UnZip and fUnZip
+ b) USE_CRYPT defined:
+ - always full crypt code
+ c) NO_CRYPT defined:
+ - never full crypt code
+ NO_CRYPT takes precedence over USE_CRYPT
+ */
+#if defined(NO_CRYPT)
+# define CRYPT 0 /* dummy version */
+#else
+#if defined(USE_CRYPT)
+# define CRYPT 1 /* full version */
+#else
+#if !defined(SFX)
+# define CRYPT 1 /* full version for zip and main unzip*/
+#else
+# define CRYPT 0 /* dummy version for unzip sfx */
+#endif
+#endif /* ?USE_CRYPT */
+#endif /* ?NO_CRYPT */
+
+#if CRYPT
+/* full version */
+
+#ifdef CR_BETA
+# undef CR_BETA /* this is not a beta release */
+#endif
+
+#define CR_MAJORVER 2
+#define CR_MINORVER 9
+#ifdef CR_BETA
+# define CR_BETA_VER "a BETA"
+# define CR_VERSION_DATE "05 May 2000" /* last real code change */
+#else
+# define CR_BETA_VER ""
+# define CR_VERSION_DATE "05 May 2000" /* last public release date */
+# define CR_RELEASE
+#endif
+
+#ifndef __G /* UnZip only, for now (DLL stuff) */
+# define __G
+# define __G__
+# define __GDEF
+# define __GPRO void
+# define __GPRO__
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32)
+# ifndef DOS_OS2_W32
+# define DOS_OS2_W32
+# endif
+#endif
+
+#if defined(DOS_OS2_W32) || defined(__human68k__)
+# ifndef DOS_H68_OS2_W32
+# define DOS_H68_OS2_W32
+# endif
+#endif
+
+#if defined(VM_CMS) || defined(MVS)
+# ifndef CMS_MVS
+# define CMS_MVS
+# endif
+#endif
+
+/* To allow combining of Zip and UnZip static libraries in a single binary,
+ * the Zip and UnZip versions of the crypt core functions have to be named
+ * differently.
+ */
+#ifdef ZIP
+# ifdef REALLY_SHORT_SYMS
+# define decrypt_byte zdcrby
+# else
+# define decrypt_byte zp_decrypt_byte
+# endif
+# define update_keys zp_update_keys
+# define init_keys zp_init_keys
+#else /* !ZIP */
+# ifdef REALLY_SHORT_SYMS
+# define decrypt_byte dcrbyt
+# endif
+#endif /* ?ZIP */
+
+#define IZ_PWLEN 80 /* input buffer size for reading encryption key */
+#ifndef PWLEN /* for compatibility with previous zcrypt release... */
+# define PWLEN IZ_PWLEN
+#endif
+#define RAND_HEAD_LEN 12 /* length of encryption random header */
+
+/* the crc_32_tab array has to be provided externally for the crypt calculus */
+#ifndef CRC_32_TAB /* UnZip provides this in globals.h */
+# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
+ extern ZCONST ulg near *crc_32_tab;
+# else
+ extern ZCONST ulg Far *crc_32_tab;
+# endif
+#endif /* !CRC_32_TAB */
+
+/* encode byte c, using temp t. Warning: c must not have side effects. */
+#define zencode(c,t) (t=decrypt_byte(__G), update_keys(c), t^(c))
+
+/* decode byte c in place */
+#define zdecode(c) update_keys(__G__ c ^= decrypt_byte(__G))
+
+int decrypt_byte OF((__GPRO));
+int update_keys OF((__GPRO__ int c));
+void init_keys OF((__GPRO__ ZCONST char *passwd));
+
+#ifdef ZIP
+ void crypthead OF((ZCONST char *, ulg, FILE *));
+# ifdef UTIL
+ int zipcloak OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
+ int zipbare OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
+# else
+ unsigned zfwrite OF((zvoid *, extent, extent, FILE *));
+ extern char *key;
+# endif
+#endif /* ZIP */
+
+#if (defined(UNZIP) && !defined(FUNZIP))
+ int decrypt OF((__GPRO__ ZCONST char *passwrd));
+#endif
+
+#ifdef FUNZIP
+ extern int encrypted;
+# ifdef NEXTBYTE
+# undef NEXTBYTE
+# endif
+# define NEXTBYTE \
+ (encrypted? update_keys(__G__ getc(G.in)^decrypt_byte(__G)) : getc(G.in))
+#endif /* FUNZIP */
+
+#else /* !CRYPT */
+/* dummy version */
+
+#define zencode
+#define zdecode
+
+#define zfwrite fwrite
+
+#endif /* ?CRYPT */
+#endif /* !__crypt_h */
Property changes on: trunk/build/install/installer/crypt.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/dhtml.c
===================================================================
--- trunk/build/install/installer/dhtml.c (rev 0)
+++ trunk/build/install/installer/dhtml.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,259 @@
+/*
+ * SINSTALL - JBoss Installer
+ *
+ * Copyright(c) 2007 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#include "sinstall.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define HBUF_SIZE 8192
+#define MBUF_SIZE 4096
+
+static SHOWHTMLDIALOGEXFN *pfnShowHTMLDialog = NULL;
+
+typedef struct {
+ IMoniker *lpImk;
+ CHAR szReturnVal[HBUF_SIZE];
+} MC_HTML_DIALOG, *LPMC_HTML_DIALOG;
+
+typedef struct DHTML_THREAD_PARAMS {
+ BOOL bDone;
+ HWND hParent;
+ LPMC_HTML_DIALOG hHtmlDlg;
+ WCHAR szOptions[1024];
+ WCHAR szArguments[MBUF_SIZE];
+} DHTML_THREAD_PARAMS;
+
+static LPWSTR
+AnsiToWide(
+ LPCSTR szAnsi,
+ LPWSTR szWide,
+ DWORD dwLength)
+{
+
+ if (!szWide) {
+ dwLength = MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, NULL, 0);
+ if (dwLength == 0)
+ return NULL;
+ if (!(szWide = (LPWSTR)calloc(sizeof(WCHAR), (dwLength + 1))))
+ return NULL;
+ }
+ if (MultiByteToWideChar(CP_ACP, 0, szAnsi, -1,
+ szWide, dwLength))
+ return szWide;
+ else
+ return NULL;
+}
+
+static LPSTR
+WideToAnsi(
+ LPCWSTR szWide,
+ LPSTR szAnsi,
+ DWORD dwLength)
+{
+ if (!szAnsi) {
+ dwLength = WideCharToMultiByte(CP_ACP, 0, szWide, -1,
+ NULL, 0, NULL, NULL);
+ if (dwLength == 0)
+ return NULL;
+ if (!(szAnsi = (LPSTR)calloc(sizeof(CHAR), (dwLength + 1))))
+ return NULL;
+ }
+
+ if (WideCharToMultiByte(CP_ACP, 0, szWide, -1,
+ szAnsi, dwLength, NULL, NULL))
+ return szAnsi;
+ else
+ return NULL;
+
+}
+
+
+HANDLE
+DHTMLDialogInit(
+ HINSTANCE hResInstance,
+ LPCSTR szHtml)
+{
+ LPMC_HTML_DIALOG hDlg;
+ OLECHAR bstr[MAX_PATH];
+
+ hDlg = (LPMC_HTML_DIALOG)calloc(1, sizeof(MC_HTML_DIALOG));
+
+ if (!hDlg)
+ return INVALID_HANDLE_VALUE;
+
+ if (!gui_hMSHTML)
+ goto cleanup;
+ if (!pfnShowHTMLDialog)
+ pfnShowHTMLDialog = (SHOWHTMLDIALOGEXFN*)GetProcAddress(
+ gui_hMSHTML,
+ "ShowHTMLDialogEx");
+ if (!pfnShowHTMLDialog)
+ goto cleanup;
+
+ if (hResInstance) {
+ CHAR szTemp[MAX_PATH];
+ strcpy(szTemp, "res://");
+ GetModuleFileNameA(hResInstance, szTemp + strlen(szTemp),
+ ARRAYSIZE(szTemp) - strlen(szTemp));
+ if (*szHtml != '/')
+ strcat(szTemp, "/");
+ strcat(szTemp, szHtml);
+ AnsiToWide(szTemp, bstr, ARRAYSIZE(bstr));
+ }
+ else
+ AnsiToWide(szHtml, bstr, ARRAYSIZE(bstr));
+ CreateURLMoniker(NULL, bstr, &hDlg->lpImk);
+
+ if (!hDlg->lpImk)
+ goto cleanup;
+
+ return hDlg;
+cleanup:
+
+ free(hDlg);
+ return INVALID_HANDLE_VALUE;
+}
+
+void
+DHTMLDialogClose(
+ HANDLE hHtmlDlg)
+{
+
+ LPMC_HTML_DIALOG hDlg = (LPMC_HTML_DIALOG)hHtmlDlg;
+ if (IS_INVALID_HANDLE(hHtmlDlg))
+ return;
+ hDlg->lpImk->lpVtbl->Release(hDlg->lpImk);
+ free(hDlg);
+}
+
+static DWORD WINAPI
+dhtmlRunThread(LPVOID lpParam)
+{
+ DWORD rv = ERROR_SUCCESS;
+ HRESULT hr;
+ VARIANT varArgs, varReturn;
+ DHTML_THREAD_PARAMS *pD = (DHTML_THREAD_PARAMS *)lpParam;
+ LPMC_HTML_DIALOG hDlg = pD->hHtmlDlg;
+
+ if (IS_INVALID_HANDLE(pD->hHtmlDlg)) {
+ rv = ERROR_INVALID_HANDLE;
+ goto cleanup;
+ }
+ VariantInit(&varReturn);
+ varArgs.vt = VT_BSTR;
+ varArgs.bstrVal = SysAllocString(pD->szArguments);
+ hr = (*pfnShowHTMLDialog)(pD->hParent,
+ hDlg->lpImk,
+ HTMLDLG_MODAL | HTMLDLG_VERIFY,
+ &varArgs,
+ pD->szOptions,
+ &varReturn);
+ VariantClear(&varArgs);
+ if (SUCCEEDED(hr)) {
+ switch(varReturn.vt) {
+ case VT_BSTR:
+ WideToAnsi(varReturn.bstrVal, hDlg->szReturnVal, HBUF_SIZE);
+ break;
+ }
+ VariantClear(&varReturn);
+ rv = ERROR_SUCCESS;
+ }
+ else
+ rv = GetLastError();
+cleanup:
+ pD->bDone = TRUE;
+ ExitThread(rv);
+ return rv;
+}
+
+extern HICON gui_h16Icon;
+
+BOOL
+DHTMLDialogRun(
+ HWND hParent,
+ HANDLE hHtmlDlg,
+ LPCSTR szTitle,
+ DWORD dwWidth,
+ DWORD dwHeight,
+ LPCSTR szArguments)
+{
+ DWORD dwThreadId;
+ HANDLE hThread;
+ HWND hWnd = NULL;
+ DWORD i;
+ BOOL rv = FALSE;
+ DHTML_THREAD_PARAMS pD;
+
+
+ if (IS_INVALID_HANDLE(hHtmlDlg))
+ return FALSE;
+ pD.hParent = hParent;
+ pD.hHtmlDlg = hHtmlDlg;
+ swprintf(pD.szOptions,
+ L"scroll: no; help: no; dialogHeight: %dpx; dialogWidth: %dpx",
+ dwHeight, dwWidth);
+ AnsiToWide(szArguments, pD.szArguments,
+ ARRAYSIZE(pD.szArguments));
+
+ hThread = CreateThread(NULL,
+ 0,
+ dhtmlRunThread,
+ &pD,
+ 0,
+ &dwThreadId);
+ if (IS_INVALID_HANDLE(hThread))
+ return FALSE;
+
+ /* Hack to change the Icon of HTML Dialog */
+ for (i = 0; i < 1000; i++) {
+ if ((hWnd = FindWindowEx(hParent, NULL, NULL, szTitle))) {
+ SetClassLong(hWnd, GCL_HICONSM, (LONG)gui_h16Icon);
+ break;
+ }
+ if (pD.bDone)
+ break;
+ Sleep(1);
+ }
+ WaitForSingleObject(hThread, INFINITE);
+ if (GetExitCodeThread(hThread, &i) && i == 0) {
+ rv = TRUE;
+ }
+ CloseHandle(hThread);
+ return rv;
+}
+
+LPSTR
+DHTMLDialogResult(
+ HANDLE hHtmlDlg)
+{
+
+ LPMC_HTML_DIALOG hDlg = (LPMC_HTML_DIALOG)hHtmlDlg;
+ if (IS_INVALID_HANDLE(hHtmlDlg))
+ return NULL;
+
+ return hDlg->szReturnVal;
+}
Property changes on: trunk/build/install/installer/dhtml.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/ebcdic.h
===================================================================
--- trunk/build/install/installer/ebcdic.h (rev 0)
+++ trunk/build/install/installer/ebcdic.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,284 @@
+/*
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ ebcdic.h
+
+ The CECP 1047 (Extended de-facto EBCDIC) <-> ISO 8859-1 conversion tables,
+ from ftp://aix1.segi.ulg.ac.be/pub/docs/iso8859/iso8859.networking
+
+ NOTES:
+ <Paul_von_Behren(a)stortek.com> (OS/390 port 12/97)
+ These table no longer represent the standard mappings (for example in the
+ OS/390 iconv utility). In order to follow current standards I remapped
+ ebcdic x0a to ascii x15 and
+ ebcdic x85 to ascii x25 (and vice-versa)
+ Without these changes, newlines in auto-convert text files appeared
+ as literal \045.
+ I'm not sure what effect this remap would have on the MVS and CMS ports, so
+ I ifdef'd these changes. Hopefully these ifdef's can be removed when the
+ MVS/CMS folks test the new mappings.
+
+ Christian Spieler <spieler(a)ikp.tu-darmstadt.de>, 27-Apr-1998
+ The problem mentioned by Paul von Behren was already observed previously
+ on VM/CMS, during the preparation of the CMS&MVS port of UnZip 5.20 in
+ 1996. At that point, the ebcdic tables were not changed since they seemed
+ to be an adopted standard (to my knowledge, these tables are still used
+ as presented in mainfraime KERMIT). Instead, the "end-of-line" conversion
+ feature of Zip's and UnZip's "text-translation" mode was used to force
+ correct mappings between ASCII and EBCDIC newline markers.
+ Before interchanging the ASCII mappings of the EBCDIC control characters
+ "NL" 0x25 and "LF" 0x15 according to the OS/390 setting, we have to
+ make sure that EBCDIC 0x15 is never used as line termination.
+
+ ---------------------------------------------------------------------------*/
+
+#ifndef __ebcdic_h /* prevent multiple inclusions */
+#define __ebcdic_h
+
+
+#ifndef ZCONST
+# define ZCONST const
+#endif
+
+#ifdef EBCDIC
+#ifndef MTS /* MTS uses a slightly "special" EBCDIC code page */
+
+ZCONST uch ebcdic[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, /* 00 - 07 */
+#ifdef OS390
+ 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */
+#else
+ 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */
+#endif
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, /* 10 - 17 */
+ 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, /* 20 - 27 */
+ 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, /* 28 - 2F */
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* 30 - 37 */
+ 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, /* 38 - 3F */
+ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 40 - 47 */
+ 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, /* 48 - 4F */
+ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, /* 50 - 57 */
+ 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, /* 58 - 5F */
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60 - 67 */
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* 68 - 6F */
+ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, /* 70 - 77 */
+ 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, /* 78 - 7F */
+#ifdef OS390
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x06, 0x17, /* 80 - 87 */
+#else
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, /* 80 - 87 */
+#endif
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B, /* 88 - 8F */
+ 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, /* 90 - 97 */
+ 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF, /* 98 - 9F */
+ 0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5, /* A0 - A7 */
+ 0xBB, 0xB4, 0x9A, 0x8A, 0xB0, 0xCA, 0xAF, 0xBC, /* A8 - AF */
+ 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, /* B0 - B7 */
+ 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB, /* B8 - BF */
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, /* C0 - C7 */
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* C8 - CF */
+ 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, /* D0 - D7 */
+ 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xBA, 0xAE, 0x59, /* D8 - DF */
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, /* E0 - E7 */
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* E8 - EF */
+ 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, /* F0 - F7 */
+ 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF /* F8 - FF */
+};
+
+#if (defined(ZIP) || CRYPT)
+ZCONST uch ascii[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, /* 00 - 07 */
+ 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */
+#ifdef OS390
+ 0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, /* 10 - 17 */
+#else
+ 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, /* 10 - 17 */
+#endif
+ 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */
+#ifdef OS390
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, /* 20 - 27 */
+#else
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, /* 20 - 27 */
+#endif
+ 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, /* 28 - 2F */
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30 - 37 */
+ 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, /* 38 - 3F */
+ 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, /* 40 - 47 */
+ 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, /* 48 - 4F */
+ 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, /* 50 - 57 */
+ 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, /* 58 - 5F */
+ 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, /* 60 - 67 */
+ 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, /* 68 - 6F */
+ 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, /* 70 - 77 */
+ 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, /* 78 - 7F */
+ 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80 - 87 */
+ 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, /* 88 - 8F */
+ 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, /* 90 - 97 */
+ 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, /* 98 - 9F */
+ 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* A0 - A7 */
+ 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0x5B, 0xDE, 0xAE, /* A8 - AF */
+ 0xAC, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, /* B0 - B7 */
+ 0xBD, 0xBE, 0xDD, 0xA8, 0xAF, 0x5D, 0xB4, 0xD7, /* B8 - BF */
+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* C0 - C7 */
+ 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, /* C8 - CF */
+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, /* D0 - D7 */
+ 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, /* D8 - DF */
+ 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* E0 - E7 */
+ 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, /* E8 - EF */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* F0 - F7 */
+ 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F /* F8 - FF */
+};
+#endif /* ZIP || CRYPT */
+
+#else /* MTS */
+
+/*
+ * This is the MTS ASCII->EBCDIC translation table. It provides a 1-1
+ * translation from ISO 8859/1 8-bit ASCII to IBM Code Page 37 EBCDIC.
+ */
+
+ZCONST uch ebcdic[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, /* 00 - 07 */
+ 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, /* 10 - 17 */
+ 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, /* 20 - 27 */
+ 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, /* 28 - 2F */
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* 30 - 37 */
+ 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, /* 38 - 3F */
+ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 40 - 47 */
+ 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, /* 48 - 4F */
+ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, /* 50 - 57 */
+ 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, /* 58 - 5F */
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60 - 67 */
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* 68 - 6F */
+ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, /* 70 - 77 */
+ 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, /* 78 - 7F */
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, /* 80 - 87 */
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B, /* 88 - 8F */
+ 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, /* 90 - 97 */
+ 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF, /* 98 - 9F */
+ 0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5, /* A0 - A7 */
+ 0xBD, 0xB4, 0x9A, 0x8A, 0x5F, 0xCA, 0xAF, 0xBC, /* A8 - AF */
+ 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, /* B0 - B7 */
+ 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB, /* B8 - BF */
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, /* C0 - C7 */
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* C8 - CF */
+ 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, /* D0 - D7 */
+ 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xAD, 0xAE, 0x59, /* D8 - DF */
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, /* E0 - E7 */
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* E8 - EF */
+ 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, /* F0 - F7 */
+ 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF /* F8 - FF */
+};
+
+#if (defined(ZIP) || CRYPT)
+ZCONST uch ascii[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, /* 00 - 07 */
+ 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */
+ 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, /* 10 - 17 */
+ 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, /* 20 - 27 */
+ 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, /* 28 - 2F */
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30 - 37 */
+ 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, /* 38 - 3F */
+ 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, /* 40 - 47 */
+ 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, /* 48 - 4F */
+ 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, /* 50 - 57 */
+ 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAC, /* 58 - 5F */
+ 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, /* 60 - 67 */
+ 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, /* 68 - 6F */
+ 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, /* 70 - 77 */
+ 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, /* 78 - 7F */
+ 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80 - 87 */
+ 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, /* 88 - 8F */
+ 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, /* 90 - 97 */
+ 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, /* 98 - 9F */
+ 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* A0 - A7 */
+ 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0xDD, 0xDE, 0xAE, /* A8 - AF */
+ 0x5E, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, /* B0 - B7 */
+ 0xBD, 0xBE, 0x5B, 0x5D, 0xAF, 0xA8, 0xB4, 0xD7, /* B8 - BF */
+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* C0 - C7 */
+ 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, /* C8 - CF */
+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, /* D0 - D7 */
+ 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, /* D8 - DF */
+ 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* E0 - E7 */
+ 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, /* E8 - EF */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* F0 - F7 */
+ 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F /* F8 - FF */
+};
+#endif /* ZIP || CRYPT */
+
+#endif /* ?MTS */
+#endif /* EBCDIC */
+
+/*---------------------------------------------------------------------------
+
+ The following conversion tables translate between IBM PC CP 850
+ (OEM codepage) and the "Western Europe & America" Windows codepage 1252.
+ The Windows codepage 1252 contains the ISO 8859-1 "Latin 1" codepage,
+ with some additional printable characters in the range (0x80 - 0x9F),
+ that is reserved to control codes in the ISO 8859-1 character table.
+
+ The ISO <--> OEM conversion tables were constructed with the help
+ of the WIN32 (Win16?) API's OemToAnsi() and AnsiToOem() conversion
+ functions and have been checked against the CP850 and LATIN1 tables
+ provided in the MS-Kermit 3.14 distribution.
+
+ ---------------------------------------------------------------------------*/
+
+#ifdef IZ_ISO2OEM_ARRAY
+ZCONST uch Far iso2oem[] = {
+ 0x3F, 0x3F, 0x27, 0x9F, 0x22, 0x2E, 0xC5, 0xCE, /* 80 - 87 */
+ 0x5E, 0x25, 0x53, 0x3C, 0x4F, 0x3F, 0x3F, 0x3F, /* 88 - 8F */
+ 0x3F, 0x27, 0x27, 0x22, 0x22, 0x07, 0x2D, 0x2D, /* 90 - 97 */
+ 0x7E, 0x54, 0x73, 0x3E, 0x6F, 0x3F, 0x3F, 0x59, /* 98 - 9F */
+ 0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5, /* A0 - A7 */
+ 0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE, /* A8 - AF */
+ 0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA, /* B0 - B7 */
+ 0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, /* B8 - BF */
+ 0xB7, 0xB5, 0xB6, 0xC7, 0x8E, 0x8F, 0x92, 0x80, /* C0 - C7 */
+ 0xD4, 0x90, 0xD2, 0xD3, 0xDE, 0xD6, 0xD7, 0xD8, /* C8 - CF */
+ 0xD1, 0xA5, 0xE3, 0xE0, 0xE2, 0xE5, 0x99, 0x9E, /* D0 - D7 */
+ 0x9D, 0xEB, 0xE9, 0xEA, 0x9A, 0xED, 0xE8, 0xE1, /* D8 - DF */
+ 0x85, 0xA0, 0x83, 0xC6, 0x84, 0x86, 0x91, 0x87, /* E0 - E7 */
+ 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B, /* E8 - EF */
+ 0xD0, 0xA4, 0x95, 0xA2, 0x93, 0xE4, 0x94, 0xF6, /* F0 - F7 */
+ 0x9B, 0x97, 0xA3, 0x96, 0x81, 0xEC, 0xE7, 0x98 /* F8 - FF */
+};
+#endif /* IZ_ISO2OEM_ARRAY */
+
+#ifdef IZ_OEM2ISO_ARRAY
+ZCONST uch Far oem2iso[] = {
+ 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7, /* 80 - 87 */
+ 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5, /* 88 - 8F */
+ 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9, /* 90 - 97 */
+ 0xFF, 0xD6, 0xDC, 0xF8, 0xA3, 0xD8, 0xD7, 0x83, /* 98 - 9F */
+ 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA, /* A0 - A7 */
+ 0xBF, 0xAE, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB, /* A8 - AF */
+ 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xC1, 0xC2, 0xC0, /* B0 - B7 */
+ 0xA9, 0xA6, 0xA6, 0x2B, 0x2B, 0xA2, 0xA5, 0x2B, /* B8 - BF */
+ 0x2B, 0x2D, 0x2D, 0x2B, 0x2D, 0x2B, 0xE3, 0xC3, /* C0 - C7 */
+ 0x2B, 0x2B, 0x2D, 0x2D, 0xA6, 0x2D, 0x2B, 0xA4, /* C8 - CF */
+ 0xF0, 0xD0, 0xCA, 0xCB, 0xC8, 0x69, 0xCD, 0xCE, /* D0 - D7 */
+ 0xCF, 0x2B, 0x2B, 0xA6, 0x5F, 0xA6, 0xCC, 0xAF, /* D8 - DF */
+ 0xD3, 0xDF, 0xD4, 0xD2, 0xF5, 0xD5, 0xB5, 0xFE, /* E0 - E7 */
+ 0xDE, 0xDA, 0xDB, 0xD9, 0xFD, 0xDD, 0xAF, 0xB4, /* E8 - EF */
+ 0xAD, 0xB1, 0x3D, 0xBE, 0xB6, 0xA7, 0xF7, 0xB8, /* F0 - F7 */
+ 0xB0, 0xA8, 0xB7, 0xB9, 0xB3, 0xB2, 0xA6, 0xA0 /* F8 - FF */
+};
+#endif /* IZ_OEM2ISO_ARRAY */
+
+#if defined(THEOS) || defined(THEOS_SUPPORT)
+# include "theos/charconv.h"
+#endif
+
+#endif /* __ebcdic_h */
Property changes on: trunk/build/install/installer/ebcdic.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/extract.c
===================================================================
--- trunk/build/install/installer/extract.c (rev 0)
+++ trunk/build/install/installer/extract.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,2396 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ extract.c
+
+ This file contains the high-level routines ("driver routines") for extrac-
+ ting and testing zipfile members. It calls the low-level routines in files
+ explode.c, inflate.c, unreduce.c and unshrink.c.
+
+ Contains: extract_or_test_files()
+ store_info()
+ extract_or_test_entrylist()
+ extract_or_test_member()
+ TestExtraField()
+ test_compr_eb()
+ memextract()
+ memflush()
+ extract_izvms_block() (VMS or VMS_TEXT_CONV)
+ set_deferred_symlink() (SYMLINKS only)
+ fnfilter()
+
+ ---------------------------------------------------------------------------*/
+
+
+#define __EXTRACT_C /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+# ifdef POCKET_UNZIP
+# include "wince/intrface.h"
+# else
+# include "windll/windll.h"
+# endif
+#endif
+#include "crypt.h"
+
+#define GRRDUMP(buf,len) { \
+ int i, j; \
+ \
+ for (j = 0; j < (len)/16; ++j) { \
+ printf(" "); \
+ for (i = 0; i < 16; ++i) \
+ printf("%02x ", (uch)(buf)[i+(j<<4)]); \
+ printf("\n "); \
+ for (i = 0; i < 16; ++i) { \
+ char c = (char)(buf)[i+(j<<4)]; \
+ \
+ if (c == '\n') \
+ printf("\\n "); \
+ else if (c == '\r') \
+ printf("\\r "); \
+ else \
+ printf(" %c ", c); \
+ } \
+ printf("\n"); \
+ } \
+ if ((len) % 16) { \
+ printf(" "); \
+ for (i = j<<4; i < (len); ++i) \
+ printf("%02x ", (uch)(buf)[i]); \
+ printf("\n "); \
+ for (i = j<<4; i < (len); ++i) { \
+ char c = (char)(buf)[i]; \
+ \
+ if (c == '\n') \
+ printf("\\n "); \
+ else if (c == '\r') \
+ printf("\\r "); \
+ else \
+ printf(" %c ", c); \
+ } \
+ printf("\n"); \
+ } \
+}
+
+static int store_info OF((__GPRO));
+#ifdef SET_DIR_ATTRIB
+static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
+ ulg *pfilnum, ulg *pnum_bad_pwd, Z_OFF_T *pold_extra_bytes,
+ unsigned *pnum_dirs, direntry **pdirlist,
+ int error_in_archive));
+#else
+static int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,
+ ulg *pfilnum, ulg *pnum_bad_pwd, Z_OFF_T *pold_extra_bytes,
+ int error_in_archive));
+#endif
+static int extract_or_test_member OF((__GPRO));
+#ifndef SFX
+ static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len));
+ static int test_compr_eb OF((__GPRO__ uch *eb, unsigned eb_size,
+ unsigned compr_offset,
+ int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
+ uch *eb_ucptr, ulg eb_ucsize)));
+#endif
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+ static void decompress_bits OF((uch *outptr, unsigned needlen,
+ ZCONST uch *bitptr));
+#endif
+#ifdef SYMLINKS
+ static void set_deferred_symlink OF((__GPRO__ slinkentry *slnk_entry));
+#endif
+#ifdef SET_DIR_ATTRIB
+ static int Cdecl dircomp OF((ZCONST zvoid *a, ZCONST zvoid *b));
+#endif
+
+
+
+/*******************************/
+/* Strings used in extract.c */
+/*******************************/
+
+static ZCONST char Far VersionMsg[] =
+ " skipping: %-22s need %s compat. v%u.%u (can do v%u.%u)\n";
+static ZCONST char Far ComprMsgNum[] =
+ " skipping: %-22s unsupported compression method %u\n";
+#ifndef SFX
+ static ZCONST char Far ComprMsgName[] =
+ " skipping: %-22s `%s' method not supported\n";
+ static ZCONST char Far CmprNone[] = "store";
+ static ZCONST char Far CmprShrink[] = "shrink";
+ static ZCONST char Far CmprReduce[] = "reduce";
+ static ZCONST char Far CmprImplode[] = "implode";
+ static ZCONST char Far CmprTokenize[] = "tokenize";
+ static ZCONST char Far CmprDeflate[] = "deflate";
+ static ZCONST char Far CmprDeflat64[] = "deflate64";
+ static ZCONST char Far CmprDCLImplode[] = "DCL implode";
+ static ZCONST char Far *ComprNames[NUM_METHODS] = {
+ CmprNone, CmprShrink, CmprReduce, CmprReduce, CmprReduce, CmprReduce,
+ CmprImplode, CmprTokenize, CmprDeflate, CmprDeflat64, CmprDCLImplode
+ };
+#endif /* !SFX */
+static ZCONST char Far FilNamMsg[] =
+ "%s: bad filename length (%s)\n";
+#ifndef SFX
+ static ZCONST char Far WarnNoMemCFName[] =
+ "%s: warning, no memory for comparison with local header\n";
+ static ZCONST char Far LvsCFNamMsg[] =
+ "%s: mismatching \"local\" filename (%s),\n\
+ continuing with \"central\" filename version\n";
+#endif /* !SFX */
+static ZCONST char Far WrnStorUCSizCSizDiff[] =
+ "%s: ucsize %lu <> csize %lu for STORED entry\n\
+ continuing with \"compressed\" size value\n";
+static ZCONST char Far ExtFieldMsg[] =
+ "%s: bad extra field length (%s)\n";
+static ZCONST char Far OffsetMsg[] =
+ "file #%lu: bad zipfile offset (%s): %ld\n";
+static ZCONST char Far ExtractMsg[] =
+ "%8sing: %-22s %s%s";
+#ifndef SFX
+ static ZCONST char Far LengthMsg[] =
+ "%s %s: %ld bytes required to uncompress to %lu bytes;\n %s\
+ supposed to require %lu bytes%s%s%s\n";
+#endif
+
+static ZCONST char Far BadFileCommLength[] = "%s: bad file comment length\n";
+static ZCONST char Far LocalHdrSig[] = "local header sig";
+static ZCONST char Far BadLocalHdr[] = "file #%lu: bad local header\n";
+static ZCONST char Far AttemptRecompensate[] =
+ " (attempting to re-compensate)\n";
+#ifndef SFX
+ static ZCONST char Far BackslashPathSep[] =
+ "warning: %s appears to use backslashes as path separators\n";
+#endif
+static ZCONST char Far AbsolutePathWarning[] =
+ "warning: stripped absolute path spec from %s\n";
+static ZCONST char Far SkipVolumeLabel[] =
+ " skipping: %-22s %svolume label\n";
+
+#ifdef SET_DIR_ATTRIB /* messages of code for setting directory attributes */
+ static ZCONST char Far DirlistEntryNoMem[] =
+ "warning: cannot alloc memory for dir times/permissions/UID/GID\n";
+ static ZCONST char Far DirlistSortNoMem[] =
+ "warning: cannot alloc memory to sort dir times/perms/etc.\n";
+ static ZCONST char Far DirlistSetAttrFailed[] =
+ "warning: set times/attribs failed for %s\n";
+ static ZCONST char Far DirlistFailAttrSum[] =
+ " failed setting attrib/times for %lu dir entries";
+#endif
+
+#ifdef SYMLINKS /* messages of the deferred symlinks handler */
+ static ZCONST char Far SymLnkWarnNoMem[] =
+ "warning: deferred symlink (%s) failed:\n\
+ out of memory\n";
+ static ZCONST char Far SymLnkWarnInvalid[] =
+ "warning: deferred symlink (%s) failed:\n\
+ invalid placeholder file\n";
+ static ZCONST char Far SymLnkDeferred[] =
+ "finishing deferred symbolic links:\n";
+ static ZCONST char Far SymLnkFinish[] =
+ " %-22s -> %s\n";
+#endif
+
+#ifndef WINDLL
+ static ZCONST char Far ReplaceQuery[] =
+ "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";
+ static ZCONST char Far AssumeNone[] = " NULL\n(assuming [N]one)\n";
+ static ZCONST char Far NewNameQuery[] = "new name: ";
+ static ZCONST char Far InvalidResponse[] = "error: invalid response [%c]\n";
+#endif /* !WINDLL */
+
+static ZCONST char Far ErrorInArchive[] =
+ "At least one %serror was detected in %s.\n";
+static ZCONST char Far ZeroFilesTested[] =
+ "Caution: zero files tested in %s.\n";
+
+#ifndef VMS
+ static ZCONST char Far VMSFormatQuery[] =
+ "\n%s: stored in VMS format. Extract anyway? (y/n) ";
+#endif
+
+#if CRYPT
+ static ZCONST char Far SkipCannotGetPasswd[] =
+ " skipping: %-22s unable to get password\n";
+ static ZCONST char Far SkipIncorrectPasswd[] =
+ " skipping: %-22s incorrect password\n";
+ static ZCONST char Far FilesSkipBadPasswd[] =
+ "%lu file%s skipped because of incorrect password.\n";
+ static ZCONST char Far MaybeBadPasswd[] =
+ " (may instead be incorrect password)\n";
+#else
+ static ZCONST char Far SkipEncrypted[] =
+ " skipping: %-22s encrypted (not supported)\n";
+#endif
+
+static ZCONST char Far NoErrInCompData[] =
+ "No errors detected in compressed data of %s.\n";
+static ZCONST char Far NoErrInTestedFiles[] =
+ "No errors detected in %s for the %lu file%s tested.\n";
+static ZCONST char Far FilesSkipped[] =
+ "%lu file%s skipped because of unsupported compression or encoding.\n";
+
+static ZCONST char Far ErrUnzipFile[] = " error: %s%s %s\n";
+static ZCONST char Far ErrUnzipNoFile[] = "\n error: %s%s\n";
+static ZCONST char Far NotEnoughMem[] = "not enough memory to ";
+static ZCONST char Far InvalidComprData[] = "invalid compressed data to ";
+static ZCONST char Far Inflate[] = "inflate";
+
+#ifndef SFX
+ static ZCONST char Far Explode[] = "explode";
+#ifndef LZW_CLEAN
+ static ZCONST char Far Unshrink[] = "unshrink";
+#endif
+#endif
+
+#if (!defined(DELETE_IF_FULL) || !defined(HAVE_UNLINK))
+ static ZCONST char Far FileTruncated[] =
+ "warning: %s is probably truncated\n";
+#endif
+
+static ZCONST char Far FileUnknownCompMethod[] =
+ "%s: unknown compression method\n";
+static ZCONST char Far BadCRC[] = " bad CRC %08lx (should be %08lx)\n";
+
+ /* TruncEAs[] also used in OS/2 mapname(), close_outfile() */
+char ZCONST Far TruncEAs[] = " compressed EA data missing (%d bytes)%s";
+char ZCONST Far TruncNTSD[] =
+ " compressed WinNT security data missing (%d bytes)%s";
+
+#ifndef SFX
+ static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
+ EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
+ static ZCONST char Far InvalidComprDataEAs[] =
+ " invalid compressed data for EAs\n";
+# if (defined(WIN32) && defined(NTSD_EAS))
+ static ZCONST char Far InvalidSecurityEAs[] =
+ " EAs fail security check\n";
+# endif
+ static ZCONST char Far UnsuppNTSDVersEAs[] =
+ " unsupported NTSD EAs version %d\n";
+ static ZCONST char Far BadCRC_EAs[] = " bad CRC for extended attributes\n";
+ static ZCONST char Far UnknComprMethodEAs[] =
+ " unknown compression method for EAs (%u)\n";
+ static ZCONST char Far NotEnoughMemEAs[] =
+ " out of memory while inflating EAs\n";
+ static ZCONST char Far UnknErrorEAs[] =
+ " unknown error on extended attributes\n";
+#endif /* !SFX */
+
+static ZCONST char Far UnsupportedExtraField[] =
+ "\nerror: unsupported extra-field compression type (%u)--skipping\n";
+static ZCONST char Far BadExtraFieldCRC[] =
+ "error [%s]: bad extra-field CRC %08lx (should be %08lx)\n";
+
+
+
+
+
+/**************************************/
+/* Function extract_or_test_files() */
+/**************************************/
+
+int extract_or_test_files(__G) /* return PK-type error code */
+ __GDEF
+{
+ unsigned i, j;
+ Z_OFF_T cd_bufstart;
+ uch *cd_inptr;
+ int cd_incnt;
+ ulg filnum=0L, blknum=0L;
+ int reached_end, no_endsig_found;
+ int error, error_in_archive=PK_COOL;
+ int *fn_matched=NULL, *xn_matched=NULL;
+ unsigned members_processed;
+ ulg num_skipped=0L, num_bad_pwd=0L;
+ Z_OFF_T old_extra_bytes = 0L;
+#ifdef SET_DIR_ATTRIB
+ unsigned num_dirs=0;
+ direntry *dirlist=(direntry *)NULL, **sorted_dirlist=(direntry **)NULL;
+#endif
+
+/*---------------------------------------------------------------------------
+ The basic idea of this function is as follows. Since the central di-
+ rectory lies at the end of the zipfile and the member files lie at the
+ beginning or middle or wherever, it is not very desirable to simply
+ read a central directory entry, jump to the member and extract it, and
+ then jump back to the central directory. In the case of a large zipfile
+ this would lead to a whole lot of disk-grinding, especially if each mem-
+ ber file is small. Instead, we read from the central directory the per-
+ tinent information for a block of files, then go extract/test the whole
+ block. Thus this routine contains two small(er) loops within a very
+ large outer loop: the first of the small ones reads a block of files
+ from the central directory; the second extracts or tests each file; and
+ the outer one loops over blocks. There's some file-pointer positioning
+ stuff in between, but that's about it. Btw, it's because of this jump-
+ ing around that we can afford to be lenient if an error occurs in one of
+ the member files: we should still be able to go find the other members,
+ since we know the offset of each from the beginning of the zipfile.
+ ---------------------------------------------------------------------------*/
+
+ G.pInfo = G.info;
+
+#if CRYPT
+ G.newzip = TRUE;
+#endif
+#ifndef SFX
+ G.reported_backslash = FALSE;
+#endif
+
+ /* malloc space for check on unmatched filespecs (OK if one or both NULL) */
+ if (G.filespecs > 0 &&
+ (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != (int *)NULL)
+ for (i = 0; i < G.filespecs; ++i)
+ fn_matched[i] = FALSE;
+ if (G.xfilespecs > 0 &&
+ (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != (int *)NULL)
+ for (i = 0; i < G.xfilespecs; ++i)
+ xn_matched[i] = FALSE;
+
+/*---------------------------------------------------------------------------
+ Begin main loop over blocks of member files. We know the entire central
+ directory is on this disk: we would not have any of this information un-
+ less the end-of-central-directory record was on this disk, and we would
+ not have gotten to this routine unless this is also the disk on which
+ the central directory starts. In practice, this had better be the ONLY
+ disk in the archive, but we'll add multi-disk support soon.
+ ---------------------------------------------------------------------------*/
+
+ members_processed = 0;
+ no_endsig_found = FALSE;
+ reached_end = FALSE;
+ while (!reached_end) {
+ j = 0;
+#ifdef AMIGA
+ memzero(G.filenotes, DIR_BLKSIZ * sizeof(char *));
+#endif
+
+ /*
+ * Loop through files in central directory, storing offsets, file
+ * attributes, case-conversion and text-conversion flags until block
+ * size is reached.
+ */
+
+ while ((j < DIR_BLKSIZ)) {
+ G.pInfo = &G.info[j];
+
+ if (readbuf(__G__ G.sig, 4) == 0) {
+ error_in_archive = PK_EOF;
+ reached_end = TRUE; /* ...so no more left to do */
+ break;
+ }
+ if (strncmp(G.sig, central_hdr_sig, 4)) { /* is it a new entry? */
+ /* no new central directory entry
+ * -> is the number of processed entries compatible with the
+ * number of entries as stored in the end_central record?
+ */
+ if ((members_processed & (unsigned)0xFFFF) ==
+ (unsigned)G.ecrec.total_entries_central_dir) {
+ /* yes, so look if we ARE back at the end_central record
+ */
+ no_endsig_found =
+ (strncmp(G.sig, end_central_sig, 4) != 0);
+ } else {
+ /* no; we have found an error in the central directory
+ * -> report it and stop searching for more Zip entries
+ */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ReportMsg)));
+ error_in_archive = PK_BADERR;
+ }
+ reached_end = TRUE; /* ...so no more left to do */
+ break;
+ }
+ /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */
+ if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {
+ error_in_archive = error; /* only PK_EOF defined */
+ reached_end = TRUE; /* ...so no more left to do */
+ break;
+ }
+ if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
+ PK_COOL)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) { /* fatal: no more left to do */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FilNamMsg),
+ FnFilter1(G.filename), "central"));
+ reached_end = TRUE;
+ break;
+ }
+ }
+ if ((error = do_string(__G__ G.crec.extra_field_length,
+ EXTRA_FIELD)) != 0)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) { /* fatal */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExtFieldMsg),
+ FnFilter1(G.filename), "central"));
+ reached_end = TRUE;
+ break;
+ }
+ }
+#ifdef AMIGA
+ G.filenote_slot = j;
+ if ((error = do_string(__G__ G.crec.file_comment_length,
+ uO.N_flag ? FILENOTE : SKIP)) != PK_COOL)
+#else
+ if ((error = do_string(__G__ G.crec.file_comment_length, SKIP))
+ != PK_COOL)
+#endif
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) { /* fatal */
+ Info(slide, 0x421, ((char *)slide,
+ LoadFarString(BadFileCommLength),
+ FnFilter1(G.filename)));
+ reached_end = TRUE;
+ break;
+ }
+ }
+ if (G.process_all_files) {
+ if (store_info(__G))
+ ++j; /* file is OK; info[] stored; continue with next */
+ else
+ ++num_skipped;
+ } else {
+ int do_this_file;
+
+ if (G.filespecs == 0)
+ do_this_file = TRUE;
+ else { /* check if this entry matches an `include' argument */
+ do_this_file = FALSE;
+ for (i = 0; i < G.filespecs; i++)
+ if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
+ do_this_file = TRUE; /* ^-- ignore case or not? */
+ if (fn_matched)
+ fn_matched[i] = TRUE;
+ break; /* found match, so stop looping */
+ }
+ }
+ if (do_this_file) { /* check if this is an excluded file */
+ for (i = 0; i < G.xfilespecs; i++)
+ if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
+ do_this_file = FALSE; /* ^-- ignore case or not? */
+ if (xn_matched)
+ xn_matched[i] = TRUE;
+ break;
+ }
+ }
+ if (do_this_file) {
+ if (store_info(__G))
+ ++j; /* file is OK */
+ else
+ ++num_skipped; /* unsupp. compression or encryption */
+ }
+ } /* end if (process_all_files) */
+
+ members_processed++;
+
+ } /* end while-loop (adding files to current block) */
+
+ /* save position in central directory so can come back later */
+ cd_bufstart = G.cur_zipfile_bufstart;
+ cd_inptr = G.inptr;
+ cd_incnt = G.incnt;
+
+ /*-----------------------------------------------------------------------
+ Second loop: process files in current block, extracting or testing
+ each one.
+ -----------------------------------------------------------------------*/
+
+ error = extract_or_test_entrylist(__G__ j,
+ &filnum, &num_bad_pwd, &old_extra_bytes,
+#ifdef SET_DIR_ATTRIB
+ &num_dirs, &dirlist,
+#endif
+ error_in_archive);
+ if (error != PK_COOL) {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ /* ...and keep going (unless disk full or user break) */
+ if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
+ /* clear reached_end to signal premature stop ... */
+ reached_end = FALSE;
+ /* ... and cancel scanning the central directory */
+ break;
+ }
+ }
+
+
+ /*
+ * Jump back to where we were in the central directory, then go and do
+ * the next batch of files.
+ */
+
+#ifdef USE_STRM_INPUT
+ fseek((FILE *)G.zipfd, cd_bufstart, SEEK_SET);
+ G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart =
+ lseek(G.zipfd, cd_bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ read(G.zipfd, (char *)G.inbuf, INBUFSIZ); /* been here before... */
+ G.inptr = cd_inptr;
+ G.incnt = cd_incnt;
+ ++blknum;
+
+#ifdef TEST
+ printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);
+ printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,
+ cur_zipfile_bufstart);
+ printf("inptr-inbuf = %d\n", G.inptr-G.inbuf);
+ printf("incnt = %d\n\n", G.incnt);
+#endif
+
+ } /* end while-loop (blocks of files in central directory) */
+
+/*---------------------------------------------------------------------------
+ Process the list of deferred symlink extractions and finish up
+ the symbolic links.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SYMLINKS
+ if (G.slink_last != NULL) {
+ if (QCOND2)
+ Info(slide, 0, ((char *)slide, LoadFarString(SymLnkDeferred)));
+ while (G.slink_head != NULL) {
+ set_deferred_symlink(__G__ G.slink_head);
+ /* remove the processed entry from the chain and free its memory */
+ G.slink_last = G.slink_head;
+ G.slink_head = G.slink_last->next;
+ free(G.slink_last);
+ }
+ G.slink_last = NULL;
+ }
+#endif /* SYMLINKS */
+
+/*---------------------------------------------------------------------------
+ Go back through saved list of directories, sort and set times/perms/UIDs
+ and GIDs from the deepest level on up.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SET_DIR_ATTRIB
+ if (num_dirs > 0) {
+ sorted_dirlist = (direntry **)malloc(num_dirs*sizeof(direntry *));
+ if (sorted_dirlist == (direntry **)NULL) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(DirlistSortNoMem)));
+ while (dirlist != (direntry *)NULL) {
+ direntry *d = dirlist;
+
+ dirlist = dirlist->next;
+ free(d);
+ }
+ } else {
+ ulg ndirs_fail = 0;
+
+ if (num_dirs == 1)
+ sorted_dirlist[0] = dirlist;
+ else {
+ for (i = 0; i < num_dirs; ++i) {
+ sorted_dirlist[i] = dirlist;
+ dirlist = dirlist->next;
+ }
+ qsort((char *)sorted_dirlist, num_dirs, sizeof(direntry *),
+ dircomp);
+ }
+
+ Trace((stderr, "setting directory times/perms/attributes\n"));
+ for (i = 0; i < num_dirs; ++i) {
+ direntry *d = sorted_dirlist[i];
+
+ Trace((stderr, "dir = %s\n", d->fn));
+ if ((error = set_direc_attribs(__G__ d)) != PK_OK) {
+ ndirs_fail++;
+ Info(slide, 0x201, ((char *)slide,
+ LoadFarString(DirlistSetAttrFailed), d->fn));
+ if (!error_in_archive)
+ error_in_archive = error;
+ }
+ free(d);
+ }
+ free(sorted_dirlist);
+ if (!uO.tflag && QCOND2) {
+ if (ndirs_fail > 0)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(DirlistFailAttrSum), ndirs_fail));
+ }
+ }
+ }
+#endif /* SET_DIR_ATTRIB */
+
+/*---------------------------------------------------------------------------
+ Check for unmatched filespecs on command line and print warning if any
+ found. Free allocated memory. (But suppress check when central dir
+ scan was interrupted prematurely.)
+ ---------------------------------------------------------------------------*/
+
+ if (fn_matched) {
+ if (reached_end) for (i = 0; i < G.filespecs; ++i)
+ if (!fn_matched[i]) {
+#ifdef DLL
+ if (!G.redirect_data && !G.redirect_text)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FilenameNotMatched), G.pfnames[i]));
+ else
+ setFileNotFound(__G);
+#else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(FilenameNotMatched), G.pfnames[i]));
+#endif
+ if (error_in_archive <= PK_WARN)
+ error_in_archive = PK_FIND; /* some files not found */
+ }
+ free((zvoid *)fn_matched);
+ }
+ if (xn_matched) {
+ if (reached_end) for (i = 0; i < G.xfilespecs; ++i)
+ if (!xn_matched[i])
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExclFilenameNotMatched), G.pxnames[i]));
+ free((zvoid *)xn_matched);
+ }
+
+/*---------------------------------------------------------------------------
+ Now, all locally allocated memory has been released. When the central
+ directory processing has been interrupted prematurely, it is safe to
+ return immediately. All completeness checks and summary messages are
+ skipped in this case.
+ ---------------------------------------------------------------------------*/
+ if (!reached_end)
+ return error_in_archive;
+
+/*---------------------------------------------------------------------------
+ Double-check that we're back at the end-of-central-directory record, and
+ print quick summary of results, if we were just testing the archive. We
+ send the summary to stdout so that people doing the testing in the back-
+ ground and redirecting to a file can just do a "tail" on the output file.
+ ---------------------------------------------------------------------------*/
+
+#ifndef SFX
+ if (no_endsig_found) { /* just to make sure */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
+ if (!error_in_archive) /* don't overwrite stronger error */
+ error_in_archive = PK_WARN;
+ }
+#endif /* !SFX */
+ if (uO.tflag) {
+ ulg num = filnum - num_bad_pwd;
+
+ if (uO.qflag < 2) { /* GRR 930710: was (uO.qflag == 1) */
+ if (error_in_archive)
+ Info(slide, 0, ((char *)slide, LoadFarString(ErrorInArchive),
+ (error_in_archive == PK_WARN)? "warning-" : "", G.zipfn));
+ else if (num == 0L)
+ Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
+ G.zipfn));
+ else if (G.process_all_files && (num_skipped+num_bad_pwd == 0L))
+ Info(slide, 0, ((char *)slide, LoadFarString(NoErrInCompData),
+ G.zipfn));
+ else
+ Info(slide, 0, ((char *)slide, LoadFarString(NoErrInTestedFiles)
+ , G.zipfn, num, (num==1L)? "":"s"));
+ if (num_skipped > 0L)
+ Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipped),
+ num_skipped, (num_skipped==1L)? "":"s"));
+#if CRYPT
+ if (num_bad_pwd > 0L)
+ Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipBadPasswd)
+ , num_bad_pwd, (num_bad_pwd==1L)? "":"s"));
+#endif /* CRYPT */
+ } else if ((uO.qflag == 0) && !error_in_archive && (num == 0))
+ Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),
+ G.zipfn));
+ }
+
+ /* give warning if files not tested or extracted (first condition can still
+ * happen if zipfile is empty and no files specified on command line) */
+
+ if ((filnum == 0) && error_in_archive <= PK_WARN) {
+ if (num_skipped > 0L)
+ error_in_archive = IZ_UNSUP; /* unsupport. compression/encryption */
+ else
+ error_in_archive = PK_FIND; /* no files found at all */
+ }
+#if CRYPT
+ else if ((filnum == num_bad_pwd) && error_in_archive <= PK_WARN)
+ error_in_archive = IZ_BADPWD; /* bad passwd => all files skipped */
+#endif
+ else if ((num_skipped > 0L) && error_in_archive <= PK_WARN)
+ error_in_archive = IZ_UNSUP; /* was PK_WARN; Jean-loup complained */
+#if CRYPT
+ else if ((num_bad_pwd > 0L) && !error_in_archive)
+ error_in_archive = PK_WARN;
+#endif
+
+ return error_in_archive;
+
+} /* end function extract_or_test_files() */
+
+
+
+
+
+/***************************/
+/* Function store_info() */
+/***************************/
+
+static int store_info(__G) /* return 0 if skipping, 1 if OK */
+ __GDEF
+{
+#ifdef SFX
+# ifdef USE_DEFLATE64
+# define UNKN_COMPR \
+ (G.crec.compression_method!=STORED && G.crec.compression_method<DEFLATED \
+ && G.crec.compression_method>ENHDEFLATED)
+# else
+# define UNKN_COMPR \
+ (G.crec.compression_method!=STORED && G.crec.compression_method!=DEFLATED)
+# endif
+#else
+# ifdef COPYRIGHT_CLEAN /* no reduced files */
+# define UNKN_RED (G.crec.compression_method >= REDUCED1 && \
+ G.crec.compression_method <= REDUCED4)
+# else
+# define UNKN_RED FALSE /* reducing not unknown */
+# endif
+# ifdef LZW_CLEAN /* no shrunk files */
+# define UNKN_SHR (G.crec.compression_method == SHRUNK)
+# else
+# define UNKN_SHR FALSE /* unshrinking not unknown */
+# endif
+# ifdef USE_DEFLATE64
+# define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
+ G.crec.compression_method==TOKENIZED || \
+ G.crec.compression_method>ENHDEFLATED)
+# else
+# define UNKN_COMPR (UNKN_RED || UNKN_SHR || \
+ G.crec.compression_method==TOKENIZED || \
+ G.crec.compression_method>DEFLATED)
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Check central directory info for version/compatibility requirements.
+ ---------------------------------------------------------------------------*/
+
+ G.pInfo->encrypted = G.crec.general_purpose_bit_flag & 1; /* bit field */
+ G.pInfo->ExtLocHdr = (G.crec.general_purpose_bit_flag & 8) == 8; /* bit */
+ G.pInfo->textfile = G.crec.internal_file_attributes & 1; /* bit field */
+ G.pInfo->crc = G.crec.crc32;
+ G.pInfo->compr_size = G.crec.csize;
+ G.pInfo->uncompr_size = G.crec.ucsize;
+
+ switch (uO.aflag) {
+ case 0:
+ G.pInfo->textmode = FALSE; /* bit field */
+ break;
+ case 1:
+ G.pInfo->textmode = G.pInfo->textfile; /* auto-convert mode */
+ break;
+ default: /* case 2: */
+ G.pInfo->textmode = TRUE;
+ break;
+ }
+
+ if (G.crec.version_needed_to_extract[1] == VMS_) {
+ if (G.crec.version_needed_to_extract[0] > VMS_UNZIP_VERSION) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
+ FnFilter1(G.filename), "VMS",
+ G.crec.version_needed_to_extract[0] / 10,
+ G.crec.version_needed_to_extract[0] % 10,
+ VMS_UNZIP_VERSION / 10, VMS_UNZIP_VERSION % 10));
+ return 0;
+ }
+#ifndef VMS /* won't be able to use extra field, but still have data */
+ else if (!uO.tflag && !IS_OVERWRT_ALL) { /* if -o, extract anyway */
+ Info(slide, 0x481, ((char *)slide, LoadFarString(VMSFormatQuery),
+ FnFilter1(G.filename)));
+ fgets(G.answerbuf, 9, stdin);
+ if ((*G.answerbuf != 'y') && (*G.answerbuf != 'Y'))
+ return 0;
+ }
+#endif /* !VMS */
+ /* usual file type: don't need VMS to extract */
+ } else if (G.crec.version_needed_to_extract[0] > UNZIP_VERSION) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(VersionMsg),
+ FnFilter1(G.filename), "PK",
+ G.crec.version_needed_to_extract[0] / 10,
+ G.crec.version_needed_to_extract[0] % 10,
+ UNZIP_VERSION / 10, UNZIP_VERSION % 10));
+ return 0;
+ }
+
+ if UNKN_COMPR {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))) {
+#ifndef SFX
+ if (G.crec.compression_method < NUM_METHODS)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgName),
+ FnFilter1(G.filename),
+ LoadFarStringSmall(ComprNames[G.crec.compression_method])));
+ else
+#endif
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ComprMsgNum),
+ FnFilter1(G.filename),
+ G.crec.compression_method));
+ }
+ return 0;
+ }
+#if (!CRYPT)
+ if (G.pInfo->encrypted) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(SkipEncrypted),
+ FnFilter1(G.filename)));
+ return 0;
+ }
+#endif /* !CRYPT */
+
+#ifndef SFX
+ /* store a copy of the central header filename for later comparison */
+ if ((G.pInfo->cfilname = zfmalloc(strlen(G.filename) + 1)) == NULL) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(WarnNoMemCFName),
+ FnFilter1(G.filename)));
+ } else
+ zfstrcpy(G.pInfo->cfilname, G.filename);
+#endif /* !SFX */
+
+ /* map whatever file attributes we have into the local format */
+ mapattr(__G); /* GRR: worry about return value later */
+
+ G.pInfo->diskstart = G.crec.disk_number_start;
+ G.pInfo->offset = (Z_OFF_T)G.crec.relative_offset_local_header;
+ return 1;
+
+} /* end function store_info() */
+
+
+
+
+
+/******************************************/
+/* Function extract_or_test_entrylist() */
+/******************************************/
+
+static int extract_or_test_entrylist(__G__ numchunk,
+ pfilnum, pnum_bad_pwd, pold_extra_bytes,
+#ifdef SET_DIR_ATTRIB
+ pnum_dirs, pdirlist,
+#endif
+ error_in_archive) /* return PK-type error code */
+ __GDEF
+ unsigned numchunk;
+ ulg *pfilnum;
+ ulg *pnum_bad_pwd;
+ Z_OFF_T *pold_extra_bytes;
+#ifdef SET_DIR_ATTRIB
+ unsigned *pnum_dirs;
+ direntry **pdirlist;
+#endif
+ int error_in_archive;
+{
+ unsigned i;
+ int renamed, query;
+ int skip_entry;
+ Z_OFF_T bufstart, inbuf_offset, request;
+ int error, errcode;
+
+/* possible values for local skip_entry flag: */
+#define SKIP_NO 0 /* do not skip this entry */
+#define SKIP_Y_EXISTING 1 /* skip this entry, do not overwrite file */
+#define SKIP_Y_NONEXIST 2 /* skip this entry, do not create new file */
+
+ /*-----------------------------------------------------------------------
+ Second loop: process files in current block, extracting or testing
+ each one.
+ -----------------------------------------------------------------------*/
+
+ for (i = 0; i < numchunk; ++i) {
+ (*pfilnum)++; /* *pfilnum = i + blknum*DIR_BLKSIZ + 1; */
+ G.pInfo = &G.info[i];
+#ifdef NOVELL_BUG_FAILSAFE
+ G.dne = FALSE; /* assume file exists until stat() says otherwise */
+#endif
+
+ /* if the target position is not within the current input buffer
+ * (either haven't yet read far enough, or (maybe) skipping back-
+ * ward), skip to the target position and reset readbuf(). */
+
+ /* seek_zipf(__G__ pInfo->offset); */
+ request = G.pInfo->offset + G.extra_bytes;
+ inbuf_offset = request % INBUFSIZ;
+ bufstart = request - inbuf_offset;
+
+ Trace((stderr, "\ndebug: request = %ld, inbuf_offset = %ld\n",
+ (long)request, (long)inbuf_offset));
+ Trace((stderr,
+ "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
+ (long)bufstart, (long)G.cur_zipfile_bufstart));
+ if (request < 0) {
+ Info(slide, 0x401, ((char *)slide, LoadFarStringSmall(SeekMsg),
+ G.zipfn, LoadFarString(ReportMsg)));
+ error_in_archive = PK_ERR;
+ if (*pfilnum == 1 && G.extra_bytes != 0L) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(AttemptRecompensate)));
+ *pold_extra_bytes = G.extra_bytes;
+ G.extra_bytes = 0L;
+ request = G.pInfo->offset; /* could also check if != 0 */
+ inbuf_offset = request % INBUFSIZ;
+ bufstart = request - inbuf_offset;
+ Trace((stderr, "debug: request = %ld, inbuf_offset = %ld\n",
+ (long)request, (long)inbuf_offset));
+ Trace((stderr,
+ "debug: bufstart = %ld, cur_zipfile_bufstart = %ld\n",
+ (long)bufstart, (long)G.cur_zipfile_bufstart));
+ /* try again */
+ if (request < 0) {
+ Trace((stderr,
+ "debug: recompensated request still < 0\n"));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(SeekMsg),
+ G.zipfn, LoadFarString(ReportMsg)));
+ error_in_archive = PK_BADERR;
+ continue;
+ }
+ } else {
+ error_in_archive = PK_BADERR;
+ continue; /* this one hosed; try next */
+ }
+ }
+
+ if (bufstart != G.cur_zipfile_bufstart) {
+ Trace((stderr, "debug: bufstart != cur_zipfile_bufstart\n"));
+#ifdef USE_STRM_INPUT
+ fseek((FILE *)G.zipfd, bufstart, SEEK_SET);
+ G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart =
+ lseek(G.zipfd, bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+ *pfilnum, "lseek", (long)bufstart));
+ error_in_archive = PK_BADERR;
+ continue; /* can still do next file */
+ }
+ G.inptr = G.inbuf + (int)inbuf_offset;
+ G.incnt -= (int)inbuf_offset;
+ } else {
+ G.incnt += (int)(G.inptr-G.inbuf) - (int)inbuf_offset;
+ G.inptr = G.inbuf + (int)inbuf_offset;
+ }
+
+ /* should be in proper position now, so check for sig */
+ if (readbuf(__G__ G.sig, 4) == 0) { /* bad offset */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+ *pfilnum, "EOF", (long)request));
+ error_in_archive = PK_BADERR;
+ continue; /* but can still try next one */
+ }
+ if (strncmp(G.sig, local_hdr_sig, 4)) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(OffsetMsg),
+ *pfilnum, LoadFarStringSmall(LocalHdrSig), (long)request));
+ /*
+ GRRDUMP(G.sig, 4)
+ GRRDUMP(local_hdr_sig, 4)
+ */
+ error_in_archive = PK_ERR;
+ if ((*pfilnum == 1 && G.extra_bytes != 0L) ||
+ (G.extra_bytes == 0L && *pold_extra_bytes != 0L)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(AttemptRecompensate)));
+ if (G.extra_bytes) {
+ *pold_extra_bytes = G.extra_bytes;
+ G.extra_bytes = 0L;
+ } else
+ G.extra_bytes = *pold_extra_bytes; /* third attempt */
+ if (((error = seek_zipf(__G__ G.pInfo->offset)) != PK_OK) ||
+ (readbuf(__G__ G.sig, 4) == 0)) { /* bad offset */
+ if (error != PK_BADERR)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OffsetMsg), *pfilnum, "EOF",
+ (long)request));
+ error_in_archive = PK_BADERR;
+ continue; /* but can still try next one */
+ }
+ if (strncmp(G.sig, local_hdr_sig, 4)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OffsetMsg), *pfilnum,
+ LoadFarStringSmall(LocalHdrSig), (long)request));
+ error_in_archive = PK_BADERR;
+ continue;
+ }
+ } else
+ continue; /* this one hosed; try next */
+ }
+ if ((error = process_local_file_hdr(__G)) != PK_COOL) {
+ Info(slide, 0x421, ((char *)slide, LoadFarString(BadLocalHdr),
+ *pfilnum));
+ error_in_archive = error; /* only PK_EOF defined */
+ continue; /* can still try next one */
+ }
+ if ((error = do_string(__G__ G.lrec.filename_length, DS_FN_L)) !=
+ PK_COOL)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),
+ FnFilter1(G.filename), "local"));
+ continue; /* go on to next one */
+ }
+ }
+#ifndef SFX
+ if (G.pInfo->cfilname != (char Far *)NULL) {
+ if (zfstrcmp(G.pInfo->cfilname, G.filename) != 0) {
+# ifdef SMALL_MEM
+ char *temp_cfilnam = slide + (7 * (WSIZE>>3));
+
+ zfstrcpy((char Far *)temp_cfilnam, G.pInfo->cfilname);
+# define cFile_PrintBuf temp_cfilnam
+# else
+# define cFile_PrintBuf G.pInfo->cfilname
+# endif
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall2(LvsCFNamMsg),
+ FnFilter2(cFile_PrintBuf), FnFilter1(G.filename)));
+# undef cFile_PrintBuf
+ zfstrcpy(G.filename, G.pInfo->cfilname);
+ if (error_in_archive < PK_WARN)
+ error_in_archive = PK_WARN;
+ }
+ zffree(G.pInfo->cfilname);
+ G.pInfo->cfilname = (char Far *)NULL;
+ }
+#endif /* !SFX */
+ if (G.lrec.compression_method == STORED) {
+ ulg csiz_decrypted = G.lrec.csize;
+
+ if (G.pInfo->encrypted)
+ csiz_decrypted -= 12;
+ if (G.lrec.ucsize != csiz_decrypted) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall2(WrnStorUCSizCSizDiff),
+ FnFilter1(G.filename), G.lrec.ucsize, csiz_decrypted));
+ G.lrec.ucsize = csiz_decrypted;
+ if (error_in_archive < PK_WARN)
+ error_in_archive = PK_WARN;
+ }
+ }
+ if (G.extra_field != (uch *)NULL) {
+ free(G.extra_field);
+ G.extra_field = (uch *)NULL;
+ }
+ if ((error =
+ do_string(__G__ G.lrec.extra_field_length, EXTRA_FIELD)) != 0)
+ {
+ if (error > error_in_archive)
+ error_in_archive = error;
+ if (error > PK_WARN) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExtFieldMsg),
+ FnFilter1(G.filename), "local"));
+ continue; /* go on */
+ }
+ }
+
+#if CRYPT
+ if (G.pInfo->encrypted &&
+ (error = decrypt(__G__ uO.pwdarg)) != PK_COOL) {
+ if (error == PK_WARN) {
+ if (!((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2)))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(SkipIncorrectPasswd),
+ FnFilter1(G.filename)));
+ ++(*pnum_bad_pwd);
+ } else { /* (error > PK_WARN) */
+ if (error > error_in_archive)
+ error_in_archive = error;
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(SkipCannotGetPasswd),
+ FnFilter1(G.filename)));
+ }
+ continue; /* go on to next file */
+ }
+#endif /* CRYPT */
+
+ /*
+ * just about to extract file: if extracting to disk, check if
+ * already exists, and if so, take appropriate action according to
+ * fflag/uflag/overwrite_all/etc. (we couldn't do this in upper
+ * loop because we don't store the possibly renamed filename[] in
+ * info[])
+ */
+#ifdef DLL
+ if (!uO.tflag && !uO.cflag && !G.redirect_data)
+#else
+ if (!uO.tflag && !uO.cflag)
+#endif
+ {
+ renamed = FALSE; /* user hasn't renamed output file yet */
+
+startover:
+ query = FALSE;
+ skip_entry = SKIP_NO;
+ /* for files from DOS FAT, check for use of backslash instead
+ * of slash as directory separator (bug in some zipper(s); so
+ * far, not a problem in HPFS, NTFS or VFAT systems)
+ */
+#ifndef SFX
+ if (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/')) {
+ char *p=G.filename;
+
+ if (*p) do {
+ if (*p == '\\') {
+ if (!G.reported_backslash) {
+ Info(slide, 0x21, ((char *)slide,
+ LoadFarString(BackslashPathSep), G.zipfn));
+ G.reported_backslash = TRUE;
+ if (!error_in_archive)
+ error_in_archive = PK_WARN;
+ }
+ *p = '/';
+ }
+ } while (*PREINCSTR(p));
+ }
+#endif /* !SFX */
+
+ if (!renamed) {
+ /* remove absolute path specs */
+ if (G.filename[0] == '/') {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(AbsolutePathWarning),
+ FnFilter1(G.filename)));
+ if (!error_in_archive)
+ error_in_archive = PK_WARN;
+ do {
+ char *p = G.filename + 1;
+ do {
+ *(p-1) = *p;
+ } while (*p++ != '\0');
+ } while (G.filename[0] == '/');
+ }
+ }
+
+ /* mapname can create dirs if not freshening or if renamed */
+ error = mapname(__G__ renamed);
+ if ((errcode = error & ~MPN_MASK) != PK_OK &&
+ error_in_archive < errcode)
+ error_in_archive = errcode;
+ if ((errcode = error & MPN_MASK) > MPN_INF_TRUNC) {
+ if (errcode == MPN_CREATED_DIR) {
+#ifdef SET_DIR_ATTRIB
+ direntry *d_entry;
+
+ error = defer_dir_attribs(__G__ &d_entry);
+ if (d_entry == (direntry *)NULL) {
+ /* There may be no dir_attribs info available, or
+ * we have encountered a mem allocation error.
+ * In case of an error, report it and set program
+ * error state to warning level.
+ */
+ if (error) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(DirlistEntryNoMem)));
+ if (!error_in_archive)
+ error_in_archive = PK_WARN;
+ }
+ } else {
+ d_entry->next = (*pdirlist);
+ (*pdirlist) = d_entry;
+ ++(*pnum_dirs);
+ }
+#endif /* SET_DIR_ATTRIB */
+ } else if (errcode == MPN_VOL_LABEL) {
+#ifdef DOS_OS2_W32
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(SkipVolumeLabel),
+ FnFilter1(G.filename),
+ uO.volflag? "hard disk " : ""));
+#else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(SkipVolumeLabel),
+ FnFilter1(G.filename), ""));
+#endif
+ } else if (errcode > MPN_INF_SKIP &&
+ error_in_archive < PK_ERR)
+ error_in_archive = PK_ERR;
+ Trace((stderr, "mapname(%s) returns error code = %d\n",
+ FnFilter1(G.filename), error));
+ continue; /* go on to next file */
+ }
+
+#ifdef QDOS
+ QFilename(__G__ G.filename);
+#endif
+ switch (check_for_newer(__G__ G.filename)) {
+ case DOES_NOT_EXIST:
+#ifdef NOVELL_BUG_FAILSAFE
+ G.dne = TRUE; /* stat() says file DOES NOT EXIST */
+#endif
+ /* freshen (no new files): skip unless just renamed */
+ if (uO.fflag && !renamed)
+ skip_entry = SKIP_Y_NONEXIST;
+ break;
+ case EXISTS_AND_OLDER:
+#ifdef UNIXBACKUP
+ if (!uO.B_flag)
+#endif
+ {
+ if (IS_OVERWRT_NONE)
+ /* never overwrite: skip file */
+ skip_entry = SKIP_Y_EXISTING;
+ else if (!IS_OVERWRT_ALL)
+ query = TRUE;
+ }
+ break;
+ case EXISTS_AND_NEWER: /* (or equal) */
+#ifdef UNIXBACKUP
+ if ((!uO.B_flag && IS_OVERWRT_NONE) ||
+#else
+ if (IS_OVERWRT_NONE ||
+#endif
+ (uO.uflag && !renamed)) {
+ /* skip if update/freshen & orig name */
+ skip_entry = SKIP_Y_EXISTING;
+ } else {
+#ifdef UNIXBACKUP
+ if (!IS_OVERWRT_ALL && !uO.B_flag)
+#else
+ if (!IS_OVERWRT_ALL)
+#endif
+ query = TRUE;
+ }
+ break;
+ }
+ if (query) {
+#ifdef WINDLL
+ switch (G.lpUserFunctions->replace != NULL ?
+ (*G.lpUserFunctions->replace)(G.filename) :
+ IDM_REPLACE_NONE) {
+ case IDM_REPLACE_RENAME:
+ _ISO_INTERN(G.filename);
+ renamed = TRUE;
+ goto startover;
+ case IDM_REPLACE_ALL:
+ G.overwrite_mode = OVERWRT_ALWAYS;
+ /* FALL THROUGH, extract */
+ case IDM_REPLACE_YES:
+ break;
+ case IDM_REPLACE_NONE:
+ G.overwrite_mode = OVERWRT_NEVER;
+ /* FALL THROUGH, skip */
+ case IDM_REPLACE_NO:
+ skip_entry = SKIP_Y_EXISTING;
+ break;
+ }
+#else /* !WINDLL */
+ extent fnlen;
+reprompt:
+ Info(slide, 0x81, ((char *)slide,
+ LoadFarString(ReplaceQuery),
+ FnFilter1(G.filename)));
+ if (fgets(G.answerbuf, 9, stdin) == (char *)NULL) {
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(AssumeNone)));
+ *G.answerbuf = 'N';
+ if (!error_in_archive)
+ error_in_archive = 1; /* not extracted: warning */
+ }
+ switch (*G.answerbuf) {
+ case 'r':
+ case 'R':
+ do {
+ Info(slide, 0x81, ((char *)slide,
+ LoadFarString(NewNameQuery)));
+ fgets(G.filename, FILNAMSIZ, stdin);
+ /* usually get \n here: better check for it */
+ fnlen = strlen(G.filename);
+ if (lastchar(G.filename, fnlen) == '\n')
+ G.filename[--fnlen] = '\0';
+ } while (fnlen == 0);
+#ifdef WIN32 /* WIN32 fgets( ... , stdin) returns OEM coded strings */
+ _OEM_INTERN(G.filename);
+#endif
+ renamed = TRUE;
+ goto startover; /* sorry for a goto */
+ case 'A': /* dangerous option: force caps */
+ G.overwrite_mode = OVERWRT_ALWAYS;
+ /* FALL THROUGH, extract */
+ case 'y':
+ case 'Y':
+ break;
+ case 'N':
+ G.overwrite_mode = OVERWRT_NEVER;
+ /* FALL THROUGH, skip */
+ case 'n':
+ /* skip file */
+ skip_entry = SKIP_Y_EXISTING;
+ break;
+ default:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(InvalidResponse), *G.answerbuf));
+ goto reprompt; /* yet another goto? */
+ } /* end switch (*answerbuf) */
+#endif /* ?WINDLL */
+ } /* end if (query) */
+ if (skip_entry != SKIP_NO) {
+#ifdef WINDLL
+ if (skip_entry == SKIP_Y_EXISTING) {
+ /* report skipping of an existing entry */
+ Info(slide, 0, ((char *)slide,
+ ((IS_OVERWRT_NONE || !uO.uflag || renamed) ?
+ "Target file exists.\nSkipping %s\n" :
+ "Target file newer.\nSkipping %s\n"),
+ FnFilter1(G.filename)));
+ }
+#endif /* WINDLL */
+ continue;
+ }
+ } /* end if (extracting to disk) */
+
+#ifdef DLL
+ if ((G.statreportcb != NULL) &&
+ (*G.statreportcb)(__G__ UZ_ST_START_EXTRACT, G.zipfn,
+ G.filename, NULL)) {
+ return IZ_CTRLC; /* cancel operation by user request */
+ }
+#endif
+#ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
+ UserStop();
+#endif
+#ifdef AMIGA
+ G.filenote_slot = i;
+#endif
+ G.disk_full = 0;
+ if ((error = extract_or_test_member(__G)) != PK_COOL) {
+ if (error > error_in_archive)
+ error_in_archive = error; /* ...and keep going */
+#ifdef DLL
+ if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
+#else
+ if (G.disk_full > 1) {
+#endif
+ return error_in_archive; /* (unless disk full) */
+ }
+ }
+#ifdef DLL
+ if ((G.statreportcb != NULL) &&
+ (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
+ G.filename, (zvoid *)&G.lrec.ucsize)) {
+ return IZ_CTRLC; /* cancel operation by user request */
+ }
+#endif
+#ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
+ UserStop();
+#endif
+ } /* end for-loop (i: files in current block) */
+
+ return error_in_archive;
+
+} /* end function extract_or_test_entrylist() */
+
+
+
+
+
+/***************************************/
+/* Function extract_or_test_member() */
+/***************************************/
+
+static int extract_or_test_member(__G) /* return PK-type error code */
+ __GDEF
+{
+ char *nul="[empty] ", *txt="[text] ", *bin="[binary]";
+#ifdef CMS_MVS
+ char *ebc="[ebcdic]";
+#endif
+ register int b;
+ int r, error=PK_COOL;
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+ ulg wsize;
+#else
+# define wsize WSIZE
+#endif
+
+
+/*---------------------------------------------------------------------------
+ Initialize variables, buffers, etc.
+ ---------------------------------------------------------------------------*/
+
+ G.bits_left = 0;
+ G.bitbuf = 0L; /* unreduce and unshrink only */
+ G.zipeof = 0;
+ G.newfile = TRUE;
+ G.crc32val = CRCVAL_INITIAL;
+
+#ifdef SYMLINKS
+ /* if file came from Unix and is a symbolic link and we are extracting
+ * to disk, prepare to restore the link */
+ if (S_ISLNK(G.pInfo->file_attr) &&
+ (G.pInfo->hostnum == UNIX_ || G.pInfo->hostnum == ATARI_ ||
+ G.pInfo->hostnum == ATHEOS_ || G.pInfo->hostnum == BEOS_) &&
+ !uO.tflag && !uO.cflag && (G.lrec.ucsize > 0))
+ G.symlnk = TRUE;
+ else
+ G.symlnk = FALSE;
+#endif /* SYMLINKS */
+
+ if (uO.tflag) {
+ if (!uO.qflag)
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg), "test",
+ FnFilter1(G.filename), "", ""));
+ } else {
+#ifdef DLL
+ if (uO.cflag && !G.redirect_data)
+#else
+ if (uO.cflag)
+#endif
+ {
+#if (defined(OS2) && defined(__IBMC__) && (__IBMC__ >= 200))
+ G.outfile = freopen("", "wb", stdout); /* VAC++ ignores setmode */
+#else
+ G.outfile = stdout;
+#endif
+#ifdef DOS_FLX_NLM_OS2_W32
+#if (defined(__HIGHC__) && !defined(FLEXOS))
+ setmode(G.outfile, _BINARY);
+#else /* !(defined(__HIGHC__) && !defined(FLEXOS)) */
+ setmode(fileno(G.outfile), O_BINARY);
+#endif /* ?(defined(__HIGHC__) && !defined(FLEXOS)) */
+# define NEWLINE "\r\n"
+#else /* !DOS_FLX_NLM_OS2_W32 */
+# define NEWLINE "\n"
+#endif /* ?DOS_FLX_NLM_OS2_W32 */
+#ifdef VMS
+ if (open_outfile(__G)) /* VMS: required even for stdout! */
+ return PK_DISK;
+#endif
+ } else if (open_outfile(__G))
+ return PK_DISK;
+ }
+
+/*---------------------------------------------------------------------------
+ Unpack the file.
+ ---------------------------------------------------------------------------*/
+
+ defer_leftover_input(__G); /* so NEXTBYTE bounds check will work */
+ switch (G.lrec.compression_method) {
+ case STORED:
+ if (!uO.tflag && QCOND2) {
+#ifdef SYMLINKS
+ if (G.symlnk) /* can also be deflated, but rarer... */
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "link", FnFilter1(G.filename), "", ""));
+ else
+#endif /* SYMLINKS */
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "extract", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.lrec.ucsize == 0L? nul : (G.pInfo->textfile? txt :
+ bin)), uO.cflag? NEWLINE : ""));
+ }
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+ if (G.redirect_slide) {
+ wsize = G.redirect_size; redirSlide = G.redirect_buffer;
+ } else {
+ wsize = WSIZE; redirSlide = slide;
+ }
+#endif
+ G.outptr = redirSlide;
+ G.outcnt = 0L;
+ while ((b = NEXTBYTE) != EOF) {
+ *G.outptr++ = (uch)b;
+ if (++G.outcnt == wsize) {
+ error = flush(__G__ redirSlide, G.outcnt, 0);
+ G.outptr = redirSlide;
+ G.outcnt = 0L;
+ if (error != PK_COOL || G.disk_full) break;
+ }
+ }
+ if (G.outcnt) /* flush final (partial) buffer */
+ flush(__G__ redirSlide, G.outcnt, 0);
+ break;
+
+#ifndef SFX
+#ifndef LZW_CLEAN
+ case SHRUNK:
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ LoadFarStringSmall(Unshrink), FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+ if ((r = unshrink(__G)) != PK_COOL) {
+ if (r < PK_DISK) {
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipFile),
+ LoadFarString(NotEnoughMem),
+ LoadFarStringSmall2(Unshrink),
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile),
+ LoadFarString(NotEnoughMem),
+ LoadFarStringSmall2(Unshrink)));
+ }
+ error = r;
+ }
+ break;
+#endif /* !LZW_CLEAN */
+
+#ifndef COPYRIGHT_CLEAN
+ case REDUCED1:
+ case REDUCED2:
+ case REDUCED3:
+ case REDUCED4:
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "unreduc", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+ if ((r = unreduce(__G)) != PK_COOL) {
+ /* unreduce() returns only PK_COOL, PK_DISK, or IZ_CTRLC */
+ error = r;
+ }
+ break;
+#endif /* !COPYRIGHT_CLEAN */
+
+ case IMPLODED:
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "explod", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+ if (((r = explode(__G)) != 0) && (r != 5)) { /* treat 5 specially */
+ if (r < PK_DISK) {
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Explode),
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Explode)));
+ error = (r == 3)? PK_MEM3 : PK_ERR;
+ } else {
+ error = r;
+ }
+ }
+ if (r == 5) {
+ int warning = ((ulg)G.used_csize <= G.lrec.csize);
+
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(LengthMsg),
+ "", warning? "warning" : "error", G.used_csize,
+ G.lrec.ucsize, warning? " " : "", G.lrec.csize,
+ " [", FnFilter1(G.filename), "]"));
+ else
+ Info(slide, 0x401, ((char *)slide, LoadFarString(LengthMsg),
+ "\n", warning? "warning" : "error", G.used_csize,
+ G.lrec.ucsize, warning? " ":"", G.lrec.csize,
+ "", "", "."));
+ error = warning? PK_WARN : PK_ERR;
+ }
+ break;
+#endif /* !SFX */
+
+ case DEFLATED:
+#ifdef USE_DEFLATE64
+ case ENHDEFLATED:
+#endif
+ if (!uO.tflag && QCOND2) {
+ Info(slide, 0, ((char *)slide, LoadFarString(ExtractMsg),
+ "inflat", FnFilter1(G.filename),
+ (uO.aflag != 1 /* && G.pInfo->textfile==G.pInfo->textmode */)?
+ "" : (G.pInfo->textfile? txt : bin), uO.cflag? NEWLINE : ""));
+ }
+#ifndef USE_ZLIB /* zlib's function is called inflate(), too */
+# define UZinflate inflate
+#endif
+ if ((r = UZinflate(__G__
+ (G.lrec.compression_method == ENHDEFLATED)))
+ != 0) {
+ if (r < PK_DISK) {
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Inflate),
+ FnFilter1(G.filename)));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Inflate)));
+ error = (r == 3)? PK_MEM3 : PK_ERR;
+ } else {
+ error = r;
+ }
+ }
+ break;
+
+ default: /* should never get to this point */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FileUnknownCompMethod), FnFilter1(G.filename)));
+ /* close and delete file before return? */
+ undefer_input(__G);
+ return PK_WARN;
+
+ } /* end switch (compression method) */
+
+/*---------------------------------------------------------------------------
+ Close the file and set its date and time (not necessarily in that order),
+ and make sure the CRC checked out OK. Logical-AND the CRC for 64-bit
+ machines (redundant on 32-bit machines).
+ ---------------------------------------------------------------------------*/
+
+#ifdef VMS /* VMS: required even for stdout! (final flush) */
+ if (!uO.tflag) /* don't close NULL file */
+ close_outfile(__G);
+#else
+#ifdef DLL
+ if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
+ if (G.redirect_data)
+ FINISH_REDIRECT();
+ else
+ close_outfile(__G);
+ }
+#else
+ if (!uO.tflag && !uO.cflag) /* don't close NULL file or stdout */
+ close_outfile(__G);
+#endif
+#endif /* VMS */
+
+ /* GRR: CONVERT close_outfile() TO NON-VOID: CHECK FOR ERRORS! */
+
+
+ if (G.disk_full) { /* set by flush() */
+ if (G.disk_full > 1) {
+#if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
+ /* delete the incomplete file if we can */
+ if (unlink(G.filename) != 0)
+ Trace((stderr, "extract.c: could not delete %s\n",
+ FnFilter1(G.filename)));
+#else
+ /* warn user about the incomplete file */
+ Info(slide, 0x421, ((char *)slide, LoadFarString(FileTruncated),
+ FnFilter1(G.filename)));
+#endif
+ error = PK_DISK;
+ } else {
+ error = PK_WARN;
+ }
+ }
+
+ if (error > PK_WARN) {/* don't print redundant CRC error if error already */
+ undefer_input(__G);
+ return error;
+ }
+ if (G.crc32val != G.lrec.crc32) {
+ /* if quiet enough, we haven't output the filename yet: do it */
+ if ((uO.tflag && uO.qflag) || (!uO.tflag && !QCOND2))
+ Info(slide, 0x401, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ Info(slide, 0x401, ((char *)slide, LoadFarString(BadCRC), G.crc32val,
+ G.lrec.crc32));
+#if CRYPT
+ if (G.pInfo->encrypted)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeBadPasswd)));
+#endif
+ error = PK_ERR;
+ } else if (uO.tflag) {
+#ifndef SFX
+ if (G.extra_field) {
+ if ((r = TestExtraField(__G__ G.extra_field,
+ G.lrec.extra_field_length)) > error)
+ error = r;
+ } else
+#endif /* !SFX */
+ if (!uO.qflag)
+ Info(slide, 0, ((char *)slide, " OK\n"));
+ } else {
+ if (QCOND2 && !error) /* GRR: is stdout reset to text mode yet? */
+ Info(slide, 0, ((char *)slide, "\n"));
+ }
+
+ undefer_input(__G);
+ return error;
+
+} /* end function extract_or_test_member() */
+
+
+
+
+
+#ifndef SFX
+
+/*******************************/
+/* Function TestExtraField() */
+/*******************************/
+
+static int TestExtraField(__G__ ef, ef_len)
+ __GDEF
+ uch *ef;
+ unsigned ef_len;
+{
+ ush ebID;
+ unsigned ebLen;
+ unsigned eb_cmpr_offs = 0;
+ int r;
+
+ /* we know the regular compressed file data tested out OK, or else we
+ * wouldn't be here ==> print filename if any extra-field errors found
+ */
+ while (ef_len >= EB_HEADSIZE) {
+ ebID = makeword(ef);
+ ebLen = (unsigned)makeword(ef+EB_LEN);
+
+ if (ebLen > (ef_len - EB_HEADSIZE)) {
+ /* Discovered some extra field inconsistency! */
+ if (uO.qflag)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ Info(slide, 1, ((char *)slide, LoadFarString(InconsistEFlength),
+ ebLen, (ef_len - EB_HEADSIZE)));
+ return PK_ERR;
+ }
+
+ switch (ebID) {
+ case EF_OS2:
+ case EF_ACL:
+ case EF_MAC3:
+ case EF_BEOS:
+ case EF_ATHEOS:
+ switch (ebID) {
+ case EF_OS2:
+ case EF_ACL:
+ eb_cmpr_offs = EB_OS2_HLEN;
+ break;
+ case EF_MAC3:
+ if (ebLen >= EB_MAC3_HLEN &&
+ (makeword(ef+(EB_HEADSIZE+EB_FLGS_OFFS))
+ & EB_M3_FL_UNCMPR) &&
+ (makelong(ef+EB_HEADSIZE) == ebLen - EB_MAC3_HLEN))
+ eb_cmpr_offs = 0;
+ else
+ eb_cmpr_offs = EB_MAC3_HLEN;
+ break;
+ case EF_BEOS:
+ case EF_ATHEOS:
+ if (ebLen >= EB_BEOS_HLEN &&
+ (*(ef+(EB_HEADSIZE+EB_FLGS_OFFS)) & EB_BE_FL_UNCMPR) &&
+ (makelong(ef+EB_HEADSIZE) == ebLen - EB_BEOS_HLEN))
+ eb_cmpr_offs = 0;
+ else
+ eb_cmpr_offs = EB_BEOS_HLEN;
+ break;
+ }
+ if ((r = test_compr_eb(__G__ ef, ebLen, eb_cmpr_offs, NULL))
+ != PK_OK) {
+ if (uO.qflag)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ switch (r) {
+ case IZ_EF_TRUNC:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(TruncEAs),
+ ebLen-(eb_cmpr_offs+EB_CMPRHEADLEN), "\n"));
+ break;
+ case PK_ERR:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(InvalidComprDataEAs)));
+ break;
+ case PK_MEM3:
+ case PK_MEM4:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(NotEnoughMemEAs)));
+ break;
+ default:
+ if ((r & 0xff) != PK_ERR)
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnknErrorEAs)));
+ else {
+ ush m = (ush)(r >> 8);
+ if (m == DEFLATED) /* GRR KLUDGE! */
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(BadCRC_EAs)));
+ else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnknComprMethodEAs), m));
+ }
+ break;
+ }
+ return r;
+ }
+ break;
+
+ case EF_NTSD:
+ Trace((stderr, "ebID: %i / ebLen: %u\n", ebID, ebLen));
+ r = ebLen < EB_NTSD_L_LEN ? IZ_EF_TRUNC :
+ ((ef[EB_HEADSIZE+EB_NTSD_VERSION] > EB_NTSD_MAX_VER) ?
+ (PK_WARN | 0x4000) :
+ test_compr_eb(__G__ ef, ebLen, EB_NTSD_L_LEN, TEST_NTSD));
+ if (r != PK_OK) {
+ if (uO.qflag)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ switch (r) {
+ case IZ_EF_TRUNC:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(TruncNTSD),
+ ebLen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
+ break;
+#if (defined(WIN32) && defined(NTSD_EAS))
+ case PK_WARN:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(InvalidSecurityEAs)));
+ break;
+#endif
+ case PK_ERR:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(InvalidComprDataEAs)));
+ break;
+ case PK_MEM3:
+ case PK_MEM4:
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(NotEnoughMemEAs)));
+ break;
+ case (PK_WARN | 0x4000):
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnsuppNTSDVersEAs),
+ (int)ef[EB_HEADSIZE+EB_NTSD_VERSION]));
+ r = PK_WARN;
+ break;
+ default:
+ if ((r & 0xff) != PK_ERR)
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnknErrorEAs)));
+ else {
+ ush m = (ush)(r >> 8);
+ if (m == DEFLATED) /* GRR KLUDGE! */
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(BadCRC_EAs)));
+ else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(UnknComprMethodEAs), m));
+ }
+ break;
+ }
+ return r;
+ }
+ break;
+ case EF_PKVMS:
+ if (makelong(ef+EB_HEADSIZE) !=
+ crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
+ (extent)(ebLen-4)))
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(BadCRC_EAs)));
+ break;
+ case EF_PKW32:
+ case EF_PKUNIX:
+ case EF_ASIUNIX:
+ case EF_IZVMS:
+ case EF_IZUNIX:
+ case EF_VMCMS:
+ case EF_MVS:
+ case EF_SPARK:
+ case EF_TANDEM:
+ case EF_THEOS:
+ case EF_AV:
+ default:
+ break;
+ }
+ ef_len -= (ebLen + EB_HEADSIZE);
+ ef += (ebLen + EB_HEADSIZE);
+ }
+
+ if (!uO.qflag)
+ Info(slide, 0, ((char *)slide, " OK\n"));
+
+ return PK_COOL;
+
+} /* end function TestExtraField() */
+
+
+
+
+
+/******************************/
+/* Function test_compr_eb() */
+/******************************/
+
+#ifdef PROTO
+static int test_compr_eb(
+ __GPRO__
+ uch *eb,
+ unsigned eb_size,
+ unsigned compr_offset,
+ int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,
+ uch *eb_ucptr, ulg eb_ucsize))
+#else /* !PROTO */
+static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
+ __GDEF
+ uch *eb;
+ unsigned eb_size;
+ unsigned compr_offset;
+ int (*test_uc_ebdata)();
+#endif /* ?PROTO */
+{
+ ulg eb_ucsize;
+ uch *eb_ucptr;
+ int r;
+
+ if (compr_offset < 4) /* field is not compressed: */
+ return PK_OK; /* do nothing and signal OK */
+
+ if ((eb_size < (EB_UCSIZE_P + 4)) ||
+ ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
+ eb_size <= (compr_offset + EB_CMPRHEADLEN)))
+ return IZ_EF_TRUNC; /* no compressed data! */
+
+ if (
+#ifdef INT_16BIT
+ (((ulg)(extent)eb_ucsize) != eb_ucsize) ||
+#endif
+ (eb_ucptr = (uch *)malloc((extent)eb_ucsize)) == (uch *)NULL)
+ return PK_MEM4;
+
+ r = memextract(__G__ eb_ucptr, eb_ucsize,
+ eb + (EB_HEADSIZE + compr_offset),
+ (ulg)(eb_size - compr_offset));
+
+ if (r == PK_OK && test_uc_ebdata != NULL)
+ r = (*test_uc_ebdata)(__G__ eb, eb_size, eb_ucptr, eb_ucsize);
+
+ free(eb_ucptr);
+ return r;
+
+} /* end function test_compr_eb() */
+
+#endif /* !SFX */
+
+
+
+
+
+/***************************/
+/* Function memextract() */
+/***************************/
+
+int memextract(__G__ tgt, tgtsize, src, srcsize) /* extract compressed */
+ __GDEF /* extra field block; */
+ uch *tgt; /* return PK-type error */
+ ulg tgtsize; /* level */
+ ZCONST uch *src;
+ ulg srcsize;
+{
+ long old_csize=G.csize;
+ uch *old_inptr=G.inptr;
+ int old_incnt=G.incnt;
+ int r, error=PK_OK;
+ ush method;
+ ulg extra_field_crc;
+
+
+ method = makeword(src);
+ extra_field_crc = makelong(src+2);
+
+ /* compressed extra field exists completely in memory at this location: */
+ G.inptr = (uch *)src + (2 + 4); /* method and extra_field_crc */
+ G.incnt = (int)(G.csize = (long)(srcsize - (2 + 4)));
+ G.mem_mode = TRUE;
+ G.outbufptr = tgt;
+ G.outsize = tgtsize;
+
+ switch (method) {
+ case STORED:
+ memcpy((char *)tgt, (char *)G.inptr, (extent)G.incnt);
+ G.outcnt = G.csize; /* for CRC calculation */
+ break;
+ case DEFLATED:
+#ifdef USE_DEFLATE64
+ case ENHDEFLATED:
+#endif
+ G.outcnt = 0L;
+ if ((r = UZinflate(__G__ (method == ENHDEFLATED))) != 0) {
+ if (!uO.tflag)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile), r == 3?
+ LoadFarString(NotEnoughMem) :
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Inflate)));
+ error = (r == 3)? PK_MEM3 : PK_ERR;
+ }
+ if (G.outcnt == 0L) /* inflate's final FLUSH sets outcnt */
+ break;
+ break;
+ default:
+ if (uO.tflag)
+ error = PK_ERR | ((int)method << 8);
+ else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(UnsupportedExtraField), method));
+ error = PK_ERR; /* GRR: should be passed on up via SetEAs() */
+ }
+ break;
+ }
+
+ G.inptr = old_inptr;
+ G.incnt = old_incnt;
+ G.csize = old_csize;
+ G.mem_mode = FALSE;
+
+ if (!error) {
+ register ulg crcval = crc32(CRCVAL_INITIAL, tgt, (extent)G.outcnt);
+
+ if (crcval != extra_field_crc) {
+ if (uO.tflag)
+ error = PK_ERR | (DEFLATED << 8); /* kludge for now */
+ else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(BadExtraFieldCRC), G.zipfn, crcval,
+ extra_field_crc));
+ error = PK_ERR;
+ }
+ }
+ }
+ return error;
+
+} /* end function memextract() */
+
+
+
+
+
+/*************************/
+/* Function memflush() */
+/*************************/
+
+int memflush(__G__ rawbuf, size)
+ __GDEF
+ ZCONST uch *rawbuf;
+ ulg size;
+{
+ if (size > G.outsize)
+ /* Here, PK_DISK is a bit off-topic, but in the sense of marking
+ "overflow of output space", its use may be tolerated. */
+ return PK_DISK; /* more data than output buffer can hold */
+
+
+
+ memcpy((char *)G.outbufptr, (char *)rawbuf, (extent)size);
+ G.outbufptr += (unsigned int)size;
+ G.outsize -= size;
+ G.outcnt += size;
+
+ return 0;
+
+} /* end function memflush() */
+
+
+
+
+
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+
+/************************************/
+/* Function extract_izvms_block() */
+/************************************/
+
+/*
+ * Extracts block from p. If resulting length is less than needed, fill
+ * extra space with corresponding bytes from 'init'.
+ * Currently understands 3 formats of block compression:
+ * - Simple storing
+ * - Compression of zero bytes to zero bits
+ * - Deflation (see memextract())
+ * The IZVMS block data is returned in malloc'd space.
+ */
+uch *extract_izvms_block(__G__ ebdata, size, retlen, init, needlen)
+ __GDEF
+ ZCONST uch *ebdata;
+ unsigned size;
+ unsigned *retlen;
+ ZCONST uch *init;
+ unsigned needlen;
+{
+ uch *ucdata; /* Pointer to block allocated */
+ int cmptype;
+ unsigned usiz, csiz;
+
+ cmptype = (makeword(ebdata+EB_IZVMS_FLGS) & EB_IZVMS_BCMASK);
+ csiz = size - EB_IZVMS_HLEN;
+ usiz = (cmptype == EB_IZVMS_BCSTOR ?
+ csiz : makeword(ebdata+EB_IZVMS_UCSIZ));
+
+ if (retlen)
+ *retlen = usiz;
+
+ if ((ucdata = (uch *)malloc(MAX(needlen, usiz))) == NULL)
+ return NULL;
+
+ if (init && (usiz < needlen))
+ memcpy((char *)ucdata, (ZCONST char *)init, needlen);
+
+ switch (cmptype)
+ {
+ case EB_IZVMS_BCSTOR: /* The simplest case */
+ memcpy(ucdata, ebdata+EB_IZVMS_HLEN, usiz);
+ break;
+ case EB_IZVMS_BC00:
+ decompress_bits(ucdata, usiz, ebdata+EB_IZVMS_HLEN);
+ break;
+ case EB_IZVMS_BCDEFL:
+ memextract(__G__ ucdata, (ulg)usiz,
+ ebdata+EB_IZVMS_HLEN, (ulg)csiz);
+ break;
+ default:
+ free(ucdata);
+ ucdata = NULL;
+ }
+ return ucdata;
+
+} /* end of extract_izvms_block */
+
+
+
+
+
+/********************************/
+/* Function decompress_bits() */
+/********************************/
+/*
+ * Simple uncompression routine. The compression uses bit stream.
+ * Compression scheme:
+ *
+ * if (byte!=0)
+ * putbit(1),putbyte(byte)
+ * else
+ * putbit(0)
+ */
+static void decompress_bits(outptr, needlen, bitptr)
+ uch *outptr; /* Pointer into output block */
+ unsigned needlen; /* Size of uncompressed block */
+ ZCONST uch *bitptr; /* Pointer into compressed data */
+{
+ ulg bitbuf = 0;
+ int bitcnt = 0;
+
+#define _FILL { bitbuf |= (*bitptr++) << bitcnt;\
+ bitcnt += 8; \
+ }
+
+ while (needlen--)
+ {
+ if (bitcnt <= 0)
+ _FILL;
+
+ if (bitbuf & 1)
+ {
+ bitbuf >>= 1;
+ if ((bitcnt -= 1) < 8)
+ _FILL;
+ *outptr++ = (uch)bitbuf;
+ bitcnt -= 8;
+ bitbuf >>= 8;
+ }
+ else
+ {
+ *outptr++ = '\0';
+ bitcnt -= 1;
+ bitbuf >>= 1;
+ }
+ }
+} /* end function decompress_bits() */
+
+#endif /* VMS || VMS_TEXT_CONV */
+
+
+
+
+
+#ifdef SYMLINKS
+/***********************************/
+/* Function set_deferred_symlink() */
+/***********************************/
+
+static void set_deferred_symlink(__G__ slnk_entry)
+ __GDEF
+ slinkentry *slnk_entry;
+{
+ unsigned ucsize = slnk_entry->targetlen;
+ char *linkfname = slnk_entry->fname;
+ char *linktarget = (char *)malloc(ucsize+1);
+
+ if (!linktarget) {
+ Info(slide, 0x201, ((char *)slide,
+ LoadFarString(SymLnkWarnNoMem), FnFilter1(linkfname)));
+ return;
+ }
+ linktarget[ucsize] = '\0';
+ G.outfile = fopen(linkfname, FOPR); /* open link placeholder for reading */
+ /* Check that the following conditions are all fulfilled:
+ * a) the placeholder file exists,
+ * b) the placeholder file contains exactly "ucsize" bytes
+ * (read the expected placeholder content length + 1 extra byte, this
+ * should return the expected content length),
+ * c) the placeholder content matches the link target specification as
+ * stored in the symlink control structure.
+ */
+ if (!G.outfile ||
+ fread(linktarget, 1, ucsize+1, G.outfile) != (int)ucsize ||
+ strcmp(slnk_entry->target, linktarget))
+ {
+ Info(slide, 0x201, ((char *)slide,
+ LoadFarString(SymLnkWarnInvalid), FnFilter1(linkfname)));
+ free(linktarget);
+ fclose(G.outfile);
+ return;
+ }
+ fclose(G.outfile); /* close "data" file for good... */
+ unlink(linkfname); /* ...and delete it */
+ if (QCOND2)
+ Info(slide, 0, ((char *)slide, LoadFarString(SymLnkFinish),
+ FnFilter1(linkfname), FnFilter2(linktarget)));
+ if (symlink(linktarget, linkfname)) /* create the real link */
+ perror("symlink error");
+ free(linktarget);
+#ifdef SET_SYMLINK_ATTRIBS
+ set_symlnk_attribs(__G__ slnk_entry);
+#endif
+ return; /* can't set time on symlinks */
+
+} /* end function set_deferred_symlink() */
+#endif /* SYMLINKS */
+
+
+
+
+/*************************/
+/* Function fnfilter() */ /* here instead of in list.c for SFX */
+/*************************/
+
+char *fnfilter(raw, space) /* convert name to safely printable form */
+ ZCONST char *raw;
+ uch *space;
+{
+#ifndef NATIVE /* ASCII: filter ANSI escape codes, etc. */
+ ZCONST uch *r=(ZCONST uch *)raw;
+ uch *s=space;
+
+ while (*r) {
+#ifdef QDOS
+ if (qlflag & 2) {
+ if (*r == '/' || *r == '.') {
+ ++r;
+ *s++ = '_';
+ continue;
+ }
+ } else
+#endif
+ if (*r < 32) {
+ *s++ = '^', *s++ = (uch)(64 + *r++);
+ } else {
+#ifdef _MBCS
+ unsigned i;
+ for (i = CLEN(r); i > 0; i--)
+ *s++ = *r++;
+#else
+ *s++ = *r++;
+#endif
+ }
+ }
+ *s = '\0';
+
+#ifdef WINDLL
+ INTERN_TO_ISO((char *)space, (char *)space); /* translate to ANSI */
+#else
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ INTERN_TO_OEM((char *)space, (char *)space);
+#endif /* (WIN32 && !_WIN32_WCE) */
+#endif /* ?WINDLL */
+
+ return (char *)space;
+
+#else /* NATIVE: EBCDIC or whatever */
+ return (char *)raw;
+#endif
+
+} /* end function fnfilter() */
+
+
+
+
+#ifdef SET_DIR_ATTRIB
+/* must sort saved directories so can set perms from bottom up */
+
+/************************/
+/* Function dircomp() */
+/************************/
+
+static int Cdecl dircomp(a, b) /* used by qsort(); swiped from Zip */
+ ZCONST zvoid *a, *b;
+{
+ /* order is significant: this sorts in reverse order (deepest first) */
+ return strcmp((*(direntry **)b)->fn, (*(direntry **)a)->fn);
+ /* return namecmp((*(direntry **)b)->fn, (*(direntry **)a)->fn); */
+}
+
+
+
+#if 0 /* not used in Unix, but maybe for future OSes? */
+
+/************************/
+/* Function namecmp() */
+/************************/
+
+static int namecmp(s1, s2) /* [not] used by dircomp(); swiped from Zip */
+ ZCONST char *s1, *s2;
+{
+ int d;
+
+ for (;;) {
+ d = (int)(uch)case_map(*s1)
+ - (int)(uch)case_map(*s2);
+
+ if (d || *s1 == 0 || *s2 == 0)
+ return d;
+
+ s1++;
+ s2++;
+ }
+}
+
+#endif /* 0 */
+#endif /* SET_DIR_ATTRIB */
Property changes on: trunk/build/install/installer/extract.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/fileio.c
===================================================================
--- trunk/build/install/installer/fileio.c (rev 0)
+++ trunk/build/install/installer/fileio.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,2575 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ fileio.c
+
+ This file contains routines for doing direct but relatively generic input/
+ output, file-related sorts of things, plus some miscellaneous stuff. Most
+ of the stuff has to do with opening, closing, reading and/or writing files.
+
+ Contains: open_input_file()
+ open_outfile() (not: VMS, AOS/VS, CMSMVS, MACOS, TANDEM)
+ undefer_input()
+ defer_leftover_input()
+ readbuf()
+ readbyte()
+ fillinbuf()
+ seek_zipf()
+ flush() (non-VMS)
+ is_vms_varlen_txt() (non-VMS, VMS_TEXT_CONV only)
+ disk_error() (non-VMS)
+ UzpMessagePrnt()
+ UzpMessageNull() (DLL only)
+ UzpInput()
+ UzpMorePause()
+ UzpPassword() (non-WINDLL)
+ handler()
+ dos_to_unix_time() (non-VMS, non-VM/CMS, non-MVS)
+ check_for_newer() (non-VMS, non-OS/2, non-VM/CMS, non-MVS)
+ do_string()
+ makeword()
+ makelong()
+ str2iso() (CRYPT && NEED_STR2ISO, only)
+ str2oem() (CRYPT && NEED_STR2OEM, only)
+ memset() (ZMEM only)
+ memcpy() (ZMEM only)
+ zstrnicmp() (NO_STRNICMP only)
+ zstat() (REGULUS only)
+ plastchar() (_MBCS only)
+ uzmbschr() (_MBCS && NEED_UZMBSCHR, only)
+ uzmbsrchr() (_MBCS && NEED_UZMBSRCHR, only)
+ fLoadFarString() (SMALL_MEM only)
+ fLoadFarStringSmall() (SMALL_MEM only)
+ fLoadFarStringSmall2() (SMALL_MEM only)
+ zfstrcpy() (SMALL_MEM only)
+ zfstrcmp() (SMALL_MEM && !(SFX || FUNZIP) only)
+
+ ---------------------------------------------------------------------------*/
+
+
+#define __FILEIO_C /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+# ifdef POCKET_UNZIP
+# include "wince/intrface.h"
+# else
+# include "windll/windll.h"
+# endif
+# include <setjmp.h>
+#endif
+#include "crypt.h"
+#include "ttyio.h"
+
+/* setup of codepage conversion for decryption passwords */
+#if CRYPT
+# if (defined(CRYP_USES_ISO2OEM) && !defined(IZ_ISO2OEM_ARRAY))
+# define IZ_ISO2OEM_ARRAY /* pull in iso2oem[] table */
+# endif
+# if (defined(CRYP_USES_OEM2ISO) && !defined(IZ_OEM2ISO_ARRAY))
+# define IZ_OEM2ISO_ARRAY /* pull in oem2iso[] table */
+# endif
+#endif
+#include "ebcdic.h" /* definition/initialization of ebcdic[] */
+
+
+/*
+ Note: Under Windows, the maximum size of the buffer that can be used
+ with any of the *printf calls is 16,384, so win_fprintf was used to
+ feed the fprintf clone no more than 16K chunks at a time. This should
+ be valid for anything up to 64K (and probably beyond, assuming your
+ buffers are that big).
+*/
+#ifdef WINDLL
+# define WriteError(buf,len,strm) \
+ (win_fprintf(pG, strm, (extent)len, (char far *)buf) != (int)(len))
+#else /* !WINDLL */
+# ifdef USE_FWRITE
+# define WriteError(buf,len,strm) \
+ ((extent)fwrite((char *)(buf),1,(extent)(len),strm) != (extent)(len))
+# else
+# define WriteError(buf,len,strm) \
+ ((extent)write(fileno(strm),(char *)(buf),(extent)(len)) != (extent)(len))
+# endif
+#endif /* ?WINDLL */
+
+#if (defined(USE_DEFLATE64) && defined(__16BIT__))
+static int partflush OF((__GPRO__ uch *rawbuf, ulg size, int unshrink));
+#endif
+#ifdef VMS_TEXT_CONV
+static int is_vms_varlen_txt OF((__GPRO__ uch *ef_buf, unsigned ef_len));
+#endif
+static int disk_error OF((__GPRO));
+
+
+/****************************/
+/* Strings used in fileio.c */
+/****************************/
+
+static ZCONST char Far CannotOpenZipfile[] =
+ "error: cannot open zipfile [ %s ]\n %s\n";
+
+#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
+#if (!defined(TANDEM))
+#if (defined(ATH_BEO_THS_UNX) || defined(DOS_FLX_NLM_OS2_W32))
+ static ZCONST char Far CannotDeleteOldFile[] =
+ "error: cannot delete old %s\n";
+#ifdef UNIXBACKUP
+ static ZCONST char Far CannotRenameOldFile[] =
+ "error: cannot rename old %s\n";
+ static ZCONST char Far BackupSuffix[] = "~";
+#endif
+#endif /* ATH_BEO_THS_UNX || DOS_FLX_NLM_OS2_W32 */
+#ifdef NOVELL_BUG_FAILSAFE
+ static ZCONST char Far NovellBug[] =
+ "error: %s: stat() says does not exist, but fopen() found anyway\n";
+#endif
+ static ZCONST char Far CannotCreateFile[] = "error: cannot create %s\n";
+#endif /* !TANDEM */
+#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS */
+
+static ZCONST char Far ReadError[] = "error: zipfile read error\n";
+static ZCONST char Far FilenameTooLongTrunc[] =
+ "warning: filename too long--truncating.\n";
+static ZCONST char Far ExtraFieldTooLong[] =
+ "warning: extra field too long (%d). Ignoring...\n";
+
+#ifdef WINDLL
+ static ZCONST char Far DiskFullQuery[] =
+ "%s: write error (disk full?).\n";
+#else
+ static ZCONST char Far DiskFullQuery[] =
+ "%s: write error (disk full?). Continue? (y/n/^C) ";
+ static ZCONST char Far ZipfileCorrupt[] =
+ "error: zipfile probably corrupt (%s)\n";
+# ifdef SYMLINKS
+ static ZCONST char Far FileIsSymLink[] =
+ "%s exists and is a symbolic link%s.\n";
+# endif
+# ifdef MORE
+ static ZCONST char Far MorePrompt[] = "--More--(%lu)";
+# endif
+ static ZCONST char Far QuitPrompt[] =
+ "--- Press `Q' to quit, or any other key to continue ---";
+ static ZCONST char Far HidePrompt[] = /* "\r \r"; */
+ "\r \r";
+# if CRYPT
+# ifdef MACOS
+ /* SPC: are names on MacOS REALLY so much longer than elsewhere ??? */
+ static ZCONST char Far PasswPrompt[] = "[%s]\n %s password: ";
+# else
+ static ZCONST char Far PasswPrompt[] = "[%s] %s password: ";
+# endif
+ static ZCONST char Far PasswPrompt2[] = "Enter password: ";
+ static ZCONST char Far PasswRetry[] = "password incorrect--reenter: ";
+# endif /* CRYPT */
+#endif /* !WINDLL */
+
+
+
+
+
+/******************************/
+/* Function open_input_file() */
+/******************************/
+
+int open_input_file(__G) /* return 1 if open failed */
+ __GDEF
+{
+ /*
+ * open the zipfile for reading and in BINARY mode to prevent cr/lf
+ * translation, which would corrupt the bitstreams
+ */
+
+#ifdef VMS
+ G.zipfd = open(G.zipfn, O_RDONLY, 0, OPNZIP_RMS_ARGS);
+#else /* !VMS */
+#ifdef MACOS
+ G.zipfd = open(G.zipfn, 0);
+#else /* !MACOS */
+#ifdef CMS_MVS
+ G.zipfd = vmmvs_open_infile(__G);
+#else /* !CMS_MVS */
+#ifdef USE_STRM_INPUT
+ G.zipfd = fopen(G.zipfn, FOPR);
+#else /* !USE_STRM_INPUT */
+# ifdef O_BINARY
+ G.zipfd = open(G.zipfn, O_RDONLY | O_BINARY);
+# else
+ G.zipfd = open(G.zipfn, O_RDONLY);
+# endif
+#endif /* ?USE_STRM_INPUT */
+#endif /* ?CMS_MVS */
+#endif /* ?MACOS */
+#endif /* ?VMS */
+
+#ifdef USE_STRM_INPUT
+ if (G.zipfd == NULL)
+#else
+ /* if (G.zipfd < 0) */ /* no good for Windows CE port */
+ if (G.zipfd == -1)
+#endif
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CannotOpenZipfile),
+ G.zipfn, strerror(errno)));
+ return 1;
+ }
+ return 0;
+
+} /* end function open_input_file() */
+
+
+
+
+#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))
+#if (!defined(TANDEM))
+
+/***************************/
+/* Function open_outfile() */
+/***************************/
+
+int open_outfile(__G) /* return 1 if fail */
+ __GDEF
+{
+#ifdef DLL
+ if (G.redirect_data)
+ return (redirect_outfile(__G) == FALSE);
+#endif
+#ifdef QDOS
+ QFilename(__G__ G.filename);
+#endif
+#if (defined(DOS_FLX_NLM_OS2_W32) || defined(ATH_BEO_THS_UNX))
+#ifdef BORLAND_STAT_BUG
+ /* Borland 5.0's stat() barfs if the filename has no extension and the
+ * file doesn't exist. */
+ if (access(G.filename, 0) == -1) {
+ FILE *tmp = fopen(G.filename, "wb+");
+
+ /* file doesn't exist, so create a dummy file to keep stat() from
+ * failing (will be over-written anyway) */
+ fputc('0', tmp); /* just to have something in the file */
+ fclose(tmp);
+ }
+#endif /* BORLAND_STAT_BUG */
+#ifdef SYMLINKS
+ if (SSTAT(G.filename, &G.statbuf) == 0 || lstat(G.filename,&G.statbuf) == 0)
+#else
+ if (SSTAT(G.filename, &G.statbuf) == 0)
+#endif /* ?SYMLINKS */
+ {
+ Trace((stderr, "open_outfile: stat(%s) returns 0: file exists\n",
+ FnFilter1(G.filename)));
+#ifdef UNIXBACKUP
+ if (uO.B_flag) { /* do backup */
+ char *tname;
+ struct stat tmpstat;
+ int blen, flen, tlen;
+
+ blen = strlen(BackupSuffix);
+ flen = strlen(G.filename);
+ tlen = flen + blen + 6; /* includes space for 5 digits */
+ if (tlen >= FILNAMSIZ) { /* in case name is too long, truncate */
+ tname = (char *)malloc(FILNAMSIZ);
+ if (tname == NULL)
+ return 1; /* in case we run out of space */
+ tlen = FILNAMSIZ - 1 - blen;
+ strcpy(tname, G.filename); /* make backup name */
+ tname[tlen] = '\0';
+ if (flen > tlen) flen = tlen;
+ tlen = FILNAMSIZ;
+ } else {
+ tname = (char *)malloc(tlen);
+ if (tname == NULL)
+ return 1; /* in case we run out of space */
+ strcpy(tname, G.filename); /* make backup name */
+ }
+ strcpy(tname+flen, BackupSuffix);
+
+ if (IS_OVERWRT_ALL) {
+ /* If there is a previous backup file, delete it,
+ * otherwise the following rename operation may fail.
+ */
+ if (SSTAT(tname, &tmpstat) == 0)
+ unlink(tname);
+ } else {
+ /* Check if backupname exists, and, if it's true, try
+ * appending numbers of up to 5 digits to the BackupSuffix,
+ * until an unused name is found.
+ */
+ unsigned maxtail, i;
+ char *numtail = tname + flen + blen;
+
+ maxtail = 65535;
+ switch (tlen - flen - blen - 1) {
+ case 4: maxtail = 9999; break;
+ case 3: maxtail = 999; break;
+ case 2: maxtail = 99; break;
+ case 1: maxtail = 9; break;
+ case 0: maxtail = 0; break;
+ }
+ /* while filename exists */
+ for (i = 0; (i <= maxtail) && (SSTAT(tname, &tmpstat) == 0);)
+ sprintf(numtail,"%u", ++i);
+ }
+
+ if (rename(G.filename, tname) != 0) { /* move file */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotRenameOldFile), FnFilter1(G.filename)));
+ free(tname);
+ return 1;
+ }
+ Trace((stderr, "open_outfile: %s now renamed into %s\n",
+ FnFilter1(G.filename), FnFilter2(tname)));
+ free(tname);
+ } else
+#endif /* UNIXBACKUP */
+ {
+#ifdef DOS_FLX_OS2_W32
+ if (!(G.statbuf.st_mode & S_IWRITE)) {
+ Trace((stderr,
+ "open_outfile: existing file %s is read-only\n",
+ FnFilter1(G.filename)));
+ chmod(G.filename, S_IREAD | S_IWRITE);
+ Trace((stderr, "open_outfile: %s now writable\n",
+ FnFilter1(G.filename)));
+ }
+#endif /* DOS_FLX_OS2_W32 */
+#ifdef NLM
+ /* Give the file read/write permission (non-POSIX shortcut) */
+ chmod(G.filename, 0);
+#endif /* NLM */
+ if (unlink(G.filename) != 0) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotDeleteOldFile), FnFilter1(G.filename)));
+ return 1;
+ }
+ Trace((stderr, "open_outfile: %s now deleted\n",
+ FnFilter1(G.filename)));
+ }
+ }
+#endif /* DOS_FLX_NLM_OS2_W32 || ATH_BEO_THS_UNX */
+#ifdef RISCOS
+ if (SWI_OS_File_7(G.filename,0xDEADDEAD,0xDEADDEAD,G.lrec.ucsize)!=NULL) {
+ Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+ FnFilter1(G.filename)));
+ return 1;
+ }
+#endif /* RISCOS */
+#ifdef TOPS20
+ char *tfilnam;
+
+ if ((tfilnam = (char *)malloc(2*strlen(G.filename)+1)) == (char *)NULL)
+ return 1;
+ strcpy(tfilnam, G.filename);
+ upper(tfilnam);
+ enquote(tfilnam);
+ if ((G.outfile = fopen(tfilnam, FOPW)) == (FILE *)NULL) {
+ Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+ tfilnam));
+ free(tfilnam);
+ return 1;
+ }
+ free(tfilnam);
+#else /* !TOPS20 */
+#ifdef MTS
+ if (uO.aflag)
+ G.outfile = fopen(G.filename, FOPWT);
+ else
+ G.outfile = fopen(G.filename, FOPW);
+ if (G.outfile == (FILE *)NULL) {
+ Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
+ FnFilter1(G.filename)));
+ return 1;
+ }
+#else /* !MTS */
+#ifdef DEBUG
+ Info(slide, 1, ((char *)slide,
+ "open_outfile: doing fopen(%s) for reading\n", FnFilter1(G.filename)));
+ if ((G.outfile = fopen(G.filename, FOPR)) == (FILE *)NULL)
+ Info(slide, 1, ((char *)slide,
+ "open_outfile: fopen(%s) for reading failed: does not exist\n",
+ FnFilter1(G.filename)));
+ else {
+ Info(slide, 1, ((char *)slide,
+ "open_outfile: fopen(%s) for reading succeeded: file exists\n",
+ FnFilter1(G.filename)));
+ fclose(G.outfile);
+ }
+#endif /* DEBUG */
+#ifdef NOVELL_BUG_FAILSAFE
+ if (G.dne && ((G.outfile = fopen(G.filename, FOPR)) != (FILE *)NULL)) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NovellBug),
+ FnFilter1(G.filename)));
+ fclose(G.outfile);
+ return 1; /* with "./" fix in checkdir(), should never reach here */
+ }
+#endif /* NOVELL_BUG_FAILSAFE */
+ Trace((stderr, "open_outfile: doing fopen(%s) for writing\n",
+ FnFilter1(G.filename)));
+ if ((G.outfile = fopen(G.filename, FOPW)) == (FILE *)NULL) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CannotCreateFile),
+ FnFilter1(G.filename)));
+ return 1;
+ }
+ Trace((stderr, "open_outfile: fopen(%s) for writing succeeded\n",
+ FnFilter1(G.filename)));
+#endif /* !MTS */
+#endif /* !TOPS20 */
+
+#ifdef USE_FWRITE
+#ifdef DOS_NLM_OS2_W32
+ /* 16-bit MSC: buffer size must be strictly LESS than 32K (WSIZE): bogus */
+ setbuf(G.outfile, (char *)NULL); /* make output unbuffered */
+#else /* !DOS_NLM_OS2_W32 */
+#ifndef RISCOS
+#ifdef _IOFBF /* make output fully buffered (works just about like write()) */
+ setvbuf(G.outfile, (char *)slide, _IOFBF, WSIZE);
+#else
+ setbuf(G.outfile, (char *)slide);
+#endif
+#endif /* !RISCOS */
+#endif /* ?DOS_NLM_OS2_W32 */
+#endif /* USE_FWRITE */
+#ifdef OS2_W32
+ /* preallocate the final file size to prevent file fragmentation */
+ SetFileSize(G.outfile, G.lrec.ucsize);
+#endif
+ return 0;
+
+} /* end function open_outfile() */
+
+#endif /* !TANDEM */
+#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS */
+
+
+
+
+
+/*
+ * These functions allow NEXTBYTE to function without needing two bounds
+ * checks. Call defer_leftover_input() if you ever have filled G.inbuf
+ * by some means other than readbyte(), and you then want to start using
+ * NEXTBYTE. When going back to processing bytes without NEXTBYTE, call
+ * undefer_input(). For example, extract_or_test_member brackets its
+ * central section that does the decompression with these two functions.
+ * If you need to check the number of bytes remaining in the current
+ * file while using NEXTBYTE, check (G.csize + G.incnt), not G.csize.
+ */
+
+/****************************/
+/* function undefer_input() */
+/****************************/
+
+void undefer_input(__G)
+ __GDEF
+{
+ if (G.incnt > 0)
+ G.csize += G.incnt;
+ if (G.incnt_leftover > 0) {
+ /* We know that "(G.csize < MAXINT)" so we can cast G.csize to int:
+ * This condition was checked when G.incnt_leftover was set > 0 in
+ * defer_leftover_input(), and it is NOT allowed to touch G.csize
+ * before calling undefer_input() when (G.incnt_leftover > 0)
+ * (single exception: see read_byte()'s "G.csize <= 0" handling) !!
+ */
+ G.incnt = G.incnt_leftover + (int)G.csize;
+ G.inptr = G.inptr_leftover - (int)G.csize;
+ G.incnt_leftover = 0;
+ } else if (G.incnt < 0)
+ G.incnt = 0;
+} /* end function undefer_input() */
+
+
+
+
+
+/***********************************/
+/* function defer_leftover_input() */
+/***********************************/
+
+void defer_leftover_input(__G)
+ __GDEF
+{
+ if ((long)G.incnt > G.csize) {
+ /* (G.csize < MAXINT), we can safely cast it to int !! */
+ if (G.csize < 0L)
+ G.csize = 0L;
+ G.inptr_leftover = G.inptr + (int)G.csize;
+ G.incnt_leftover = G.incnt - (int)G.csize;
+ G.incnt = (int)G.csize;
+ } else
+ G.incnt_leftover = 0;
+ G.csize -= G.incnt;
+} /* end function defer_leftover_input() */
+
+
+
+
+
+/**********************/
+/* Function readbuf() */
+/**********************/
+
+unsigned readbuf(__G__ buf, size) /* return number of bytes read into buf */
+ __GDEF
+ char *buf;
+ register unsigned size;
+{
+ register unsigned count;
+ unsigned n;
+
+ n = size;
+ while (size) {
+ if (G.incnt <= 0) {
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0)
+ return (n-size);
+ else if (G.incnt < 0) {
+ /* another hack, but no real harm copying same thing twice */
+ (*G.message)((zvoid *)&G,
+ (uch *)LoadFarString(ReadError), /* CANNOT use slide */
+ (ulg)strlen(LoadFarString(ReadError)), 0x401);
+ return 0; /* discarding some data; better than lock-up */
+ }
+ /* buffer ALWAYS starts on a block boundary: */
+ G.cur_zipfile_bufstart += INBUFSIZ;
+ G.inptr = G.inbuf;
+ }
+ count = MIN(size, (unsigned)G.incnt);
+ memcpy(buf, G.inptr, count);
+ buf += count;
+ G.inptr += count;
+ G.incnt -= count;
+ size -= count;
+ }
+ return n;
+
+} /* end function readbuf() */
+
+
+
+
+
+/***********************/
+/* Function readbyte() */
+/***********************/
+
+int readbyte(__G) /* refill inbuf and return a byte if available, else EOF */
+ __GDEF
+{
+ if (G.mem_mode)
+ return EOF;
+ if (G.csize <= 0) {
+ G.csize--; /* for tests done after exploding */
+ G.incnt = 0;
+ return EOF;
+ }
+ if (G.incnt <= 0) {
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0) {
+ G.incnt = 0; /* do not allow negative value to affect stuff */
+ return EOF;
+ } else if (G.incnt < 0) { /* "fail" (abort, retry, ...) returns this */
+ /* another hack, but no real harm copying same thing twice */
+ (*G.message)((zvoid *)&G,
+ (uch *)LoadFarString(ReadError),
+ (ulg)strlen(LoadFarString(ReadError)), 0x401);
+ echon();
+#ifdef WINDLL
+ longjmp(dll_error_return, 1);
+#else
+ DESTROYGLOBALS();
+ EXIT(PK_BADERR); /* totally bailing; better than lock-up */
+#endif
+ }
+ G.cur_zipfile_bufstart += INBUFSIZ; /* always starts on block bndry */
+ G.inptr = G.inbuf;
+ defer_leftover_input(__G); /* decrements G.csize */
+ }
+
+#if CRYPT
+ if (G.pInfo->encrypted) {
+ uch *p;
+ int n;
+
+ /* This was previously set to decrypt one byte beyond G.csize, when
+ * incnt reached that far. GRR said, "but it's required: why?" This
+ * was a bug in fillinbuf() -- was it also a bug here?
+ */
+ for (n = G.incnt, p = G.inptr; n--; p++)
+ zdecode(*p);
+ }
+#endif /* CRYPT */
+
+ --G.incnt;
+ return *G.inptr++;
+
+} /* end function readbyte() */
+
+
+
+
+
+#ifdef USE_ZLIB
+
+/************************/
+/* Function fillinbuf() */
+/************************/
+
+int fillinbuf(__G) /* like readbyte() except returns number of bytes in inbuf */
+ __GDEF
+{
+ if (G.mem_mode ||
+ (G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+ return 0;
+ G.cur_zipfile_bufstart += INBUFSIZ; /* always starts on a block boundary */
+ G.inptr = G.inbuf;
+ defer_leftover_input(__G); /* decrements G.csize */
+
+#if CRYPT
+ if (G.pInfo->encrypted) {
+ uch *p;
+ int n;
+
+ for (n = G.incnt, p = G.inptr; n--; p++)
+ zdecode(*p);
+ }
+#endif /* CRYPT */
+
+ return G.incnt;
+
+} /* end function fillinbuf() */
+
+#endif /* USE_ZLIB */
+
+
+
+
+
+/************************/
+/* Function seek_zipf() */
+/************************/
+
+int seek_zipf(__G__ abs_offset)
+ __GDEF
+ Z_OFF_T abs_offset;
+{
+/*
+ * Seek to the block boundary of the block which includes abs_offset,
+ * then read block into input buffer and set pointers appropriately.
+ * If block is already in the buffer, just set the pointers. This function
+ * is used by do_seekable (process.c), extract_or_test_entrylist (extract.c)
+ * and do_string (fileio.c). Also, a slightly modified version is embedded
+ * within extract_or_test_entrylist (extract.c). readbyte() and readbuf()
+ * (fileio.c) are compatible. NOTE THAT abs_offset is intended to be the
+ * "proper offset" (i.e., if there were no extra bytes prepended);
+ * cur_zipfile_bufstart contains the corrected offset.
+ *
+ * Since seek_zipf() is never used during decompression, it is safe to
+ * use the slide[] buffer for the error message.
+ *
+ * returns PK error codes:
+ * PK_BADERR if effective offset in zipfile is negative
+ * PK_EOF if seeking past end of zipfile
+ * PK_OK when seek was successful
+ */
+ Z_OFF_T request = abs_offset + G.extra_bytes;
+ Z_OFF_T inbuf_offset = request % INBUFSIZ;
+ Z_OFF_T bufstart = request - inbuf_offset;
+
+ if (request < 0) {
+ Info(slide, 1, ((char *)slide, LoadFarStringSmall(SeekMsg),
+ G.zipfn, LoadFarString(ReportMsg)));
+ return(PK_BADERR);
+ } else if (bufstart != G.cur_zipfile_bufstart) {
+ Trace((stderr,
+ "fpos_zip: abs_offset = %ld, G.extra_bytes = %ld\n",
+ abs_offset, G.extra_bytes));
+#ifdef USE_STRM_INPUT
+ fseek(G.zipfd, bufstart, SEEK_SET);
+ G.cur_zipfile_bufstart = ftell(G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart = lseek(G.zipfd, bufstart, SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ Trace((stderr,
+ " request = %ld, (abs+extra) = %ld, inbuf_offset = %ld\n",
+ request, (abs_offset+G.extra_bytes), inbuf_offset));
+ Trace((stderr, " bufstart = %ld, cur_zipfile_bufstart = %ld\n",
+ bufstart, G.cur_zipfile_bufstart));
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0)
+ return(PK_EOF);
+ G.incnt -= (int)inbuf_offset;
+ G.inptr = G.inbuf + (int)inbuf_offset;
+ } else {
+ G.incnt += (G.inptr-G.inbuf) - (int)inbuf_offset;
+ G.inptr = G.inbuf + (int)inbuf_offset;
+ }
+ return(PK_OK);
+} /* end function seek_zipf() */
+
+
+
+
+
+#ifndef VMS /* for VMS use code in vms.c */
+
+/********************/
+/* Function flush() */ /* returns PK error codes: */
+/********************/ /* if cflag => always 0; PK_DISK if write error */
+
+int flush(__G__ rawbuf, size, unshrink)
+ __GDEF
+ uch *rawbuf;
+ ulg size;
+ int unshrink;
+#if (defined(USE_DEFLATE64) && defined(__16BIT__))
+{
+ int ret;
+
+ /* On 16-bit systems (MSDOS, OS/2 1.x), the standard C library functions
+ * cannot handle writes of 64k blocks at once. For these systems, the
+ * blocks to flush are split into pieces of 32k or less.
+ */
+ while (size > 0x8000L) {
+ ret = partflush(__G__ rawbuf, 0x8000L, unshrink);
+ if (ret != PK_OK)
+ return ret;
+ size -= 0x8000L;
+ rawbuf += (extent)0x8000;
+ }
+ return partflush(__G__ rawbuf, size, unshrink);
+} /* end function flush() */
+
+
+/************************/
+/* Function partflush() */ /* returns PK error codes: */
+/************************/ /* if cflag => always 0; PK_DISK if write error */
+
+static int partflush(__G__ rawbuf, size, unshrink)
+ __GDEF
+ uch *rawbuf; /* cannot be ZCONST, gets passed to (*G.message)() */
+ ulg size;
+ int unshrink;
+#endif /* USE_DEFLATE64 && __16BIT__ */
+{
+ register uch *p;
+ register uch *q;
+ uch *transbuf;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+ ulg transbufsiz;
+#endif
+ /* static int didCRlast = FALSE; moved to globals.h */
+
+
+/*---------------------------------------------------------------------------
+ Compute the CRC first; if testing or if disk is full, that's it.
+ ---------------------------------------------------------------------------*/
+
+ G.crc32val = crc32(G.crc32val, rawbuf, (extent)size);
+
+#ifdef DLL
+ if ((G.statreportcb != NULL) &&
+ (*G.statreportcb)(__G__ UZ_ST_IN_PROGRESS, G.zipfn, G.filename, NULL))
+ return IZ_CTRLC; /* cancel operation by user request */
+#endif
+
+ if (uO.tflag || size == 0L) /* testing or nothing to write: all done */
+ return PK_OK;
+
+ if (G.disk_full)
+ return PK_DISK; /* disk already full: ignore rest of file */
+
+/*---------------------------------------------------------------------------
+ Write the bytes rawbuf[0..size-1] to the output device, first converting
+ end-of-lines and ASCII/EBCDIC as needed. If SMALL_MEM or MED_MEM are NOT
+ defined, outbuf is assumed to be at least as large as rawbuf and is not
+ necessarily checked for overflow.
+ ---------------------------------------------------------------------------*/
+
+ if (!G.pInfo->textmode) { /* write raw binary data */
+ /* GRR: note that for standard MS-DOS compilers, size argument to
+ * fwrite() can never be more than 65534, so WriteError macro will
+ * have to be rewritten if size can ever be that large. For now,
+ * never more than 32K. Also note that write() returns an int, which
+ * doesn't necessarily limit size to 32767 bytes if write() is used
+ * on 16-bit systems but does make it more of a pain; however, because
+ * at least MSC 5.1 has a lousy implementation of fwrite() (as does
+ * DEC Ultrix cc), write() is used anyway.
+ */
+#ifdef DLL
+ if (G.redirect_data) {
+#ifdef NO_SLIDE_REDIR
+ if (writeToMemory(__G__ rawbuf, (extent)size)) return PK_ERR;
+#else
+ writeToMemory(__G__ rawbuf, (extent)size);
+#endif
+ } else
+#endif
+ if (!uO.cflag && WriteError(rawbuf, size, G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G, rawbuf, size, 0))
+ return PK_OK;
+ } else { /* textmode: aflag is true */
+ if (unshrink) {
+ /* rawbuf = outbuf */
+ transbuf = G.outbuf2;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+ transbufsiz = TRANSBUFSIZ;
+#endif
+ } else {
+ /* rawbuf = slide */
+ transbuf = G.outbuf;
+#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV))
+ transbufsiz = OUTBUFSIZ;
+ Trace((stderr, "\ntransbufsiz = OUTBUFSIZ = %u\n",
+ (unsigned)OUTBUFSIZ));
+#endif
+ }
+ if (G.newfile) {
+#ifdef VMS_TEXT_CONV
+ if (G.pInfo->hostnum == VMS_ && G.extra_field &&
+ is_vms_varlen_txt(__G__ G.extra_field,
+ G.lrec.extra_field_length))
+ G.VMS_line_state = 0; /* 0: ready to read line length */
+ else
+ G.VMS_line_state = -1; /* -1: don't treat as VMS text */
+#endif
+ G.didCRlast = FALSE; /* no previous buffers written */
+ G.newfile = FALSE;
+ }
+
+#ifdef VMS_TEXT_CONV
+ if (G.VMS_line_state >= 0)
+ {
+ p = rawbuf;
+ q = transbuf;
+ while ((extent)(p-rawbuf) < (extent)size) {
+ switch (G.VMS_line_state) {
+
+ /* 0: ready to read line length */
+ case 0:
+ G.VMS_line_length = 0;
+ if ((extent)(p-rawbuf) == (extent)size-1) {
+ /* last char */
+ G.VMS_line_length = (unsigned)(*p++);
+ G.VMS_line_state = 1;
+ } else {
+ G.VMS_line_length = makeword(p);
+ p += 2;
+ G.VMS_line_state = 2;
+ }
+ G.VMS_line_pad =
+ ((G.VMS_line_length & 1) != 0); /* odd */
+ break;
+
+ /* 1: read one byte of length, need second */
+ case 1:
+ G.VMS_line_length += ((unsigned)(*p++) << 8);
+ G.VMS_line_state = 2;
+ break;
+
+ /* 2: ready to read VMS_line_length chars */
+ case 2:
+ {
+ extent remaining = (extent)size+(rawbuf-p);
+ extent outroom;
+
+ if (G.VMS_line_length < remaining) {
+ remaining = G.VMS_line_length;
+ G.VMS_line_state = 3;
+ }
+
+ outroom = transbuf+(extent)transbufsiz-q;
+ if (remaining >= outroom) {
+ remaining -= outroom;
+ for (;outroom > 0; p++, outroom--)
+ *q++ = native(*p);
+#ifdef DLL
+ if (G.redirect_data) {
+ if (writeToMemory(__G__ transbuf,
+ (extent)(q-transbuf))) return PK_ERR;
+ } else
+#endif
+ if (!uO.cflag && WriteError(transbuf,
+ (extent)(q-transbuf), G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G,
+ transbuf, (ulg)(q-transbuf), 0))
+ return PK_OK;
+ q = transbuf;
+ /* fall through to normal case */
+ }
+ G.VMS_line_length -= remaining;
+ for (;remaining > 0; p++, remaining--)
+ *q++ = native(*p);
+ }
+ break;
+
+ /* 3: ready to PutNativeEOL */
+ case 3:
+ if (q > transbuf+(extent)transbufsiz-lenEOL) {
+#ifdef DLL
+ if (G.redirect_data) {
+ if (writeToMemory(__G__ transbuf,
+ (extent)(q-transbuf))) return PK_ERR;
+ } else
+#endif
+ if (!uO.cflag &&
+ WriteError(transbuf, (extent)(q-transbuf),
+ G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G,
+ transbuf, (ulg)(q-transbuf), 0))
+ return PK_OK;
+ q = transbuf;
+ }
+ PutNativeEOL
+ G.VMS_line_state = G.VMS_line_pad ? 4 : 0;
+ break;
+
+ /* 4: ready to read pad byte */
+ case 4:
+ ++p;
+ G.VMS_line_state = 0;
+ break;
+ }
+ } /* end while */
+
+ } else
+#endif /* VMS_TEXT_CONV */
+
+ /*-----------------------------------------------------------------------
+ Algorithm: CR/LF => native; lone CR => native; lone LF => native.
+ This routine is only for non-raw-VMS, non-raw-VM/CMS files (i.e.,
+ stream-oriented files, not record-oriented).
+ -----------------------------------------------------------------------*/
+
+ /* else not VMS text */ {
+ p = rawbuf;
+ if (*p == LF && G.didCRlast)
+ ++p;
+ G.didCRlast = FALSE;
+ for (q = transbuf; (extent)(p-rawbuf) < (extent)size; ++p) {
+ if (*p == CR) { /* lone CR or CR/LF: treat as EOL */
+ PutNativeEOL
+ if ((extent)(p-rawbuf) == (extent)size-1)
+ /* last char in buffer */
+ G.didCRlast = TRUE;
+ else if (p[1] == LF) /* get rid of accompanying LF */
+ ++p;
+ } else if (*p == LF) /* lone LF */
+ PutNativeEOL
+ else
+#ifndef DOS_FLX_OS2_W32
+ if (*p != CTRLZ) /* lose all ^Z's */
+#endif
+ *q++ = native(*p);
+
+#if (defined(SMALL_MEM) || defined(MED_MEM))
+# if (lenEOL == 1) /* don't check unshrink: both buffers small but equal */
+ if (!unshrink)
+# endif
+ /* check for danger of buffer overflow and flush */
+ if (q > transbuf+(extent)transbufsiz-lenEOL) {
+ Trace((stderr,
+ "p - rawbuf = %u q-transbuf = %u size = %lu\n",
+ (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
+ if (!uO.cflag && WriteError(transbuf,
+ (extent)(q-transbuf), G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G,
+ transbuf, (ulg)(q-transbuf), 0))
+ return PK_OK;
+ q = transbuf;
+ continue;
+ }
+#endif /* SMALL_MEM || MED_MEM */
+ }
+ }
+
+ /*-----------------------------------------------------------------------
+ Done translating: write whatever we've got to file (or screen).
+ -----------------------------------------------------------------------*/
+
+ Trace((stderr, "p - rawbuf = %u q-transbuf = %u size = %lu\n",
+ (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size));
+ if (q > transbuf) {
+#ifdef DLL
+ if (G.redirect_data) {
+ if (writeToMemory(__G__ transbuf, (extent)(q-transbuf)))
+ return PK_ERR;
+ } else
+#endif
+ if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf),
+ G.outfile))
+ return disk_error(__G);
+ else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf,
+ (ulg)(q-transbuf), 0))
+ return PK_OK;
+ }
+ }
+
+ return PK_OK;
+
+} /* end function flush() [resp. partflush() for 16-bit Deflate64 support] */
+
+
+
+
+
+#ifdef VMS_TEXT_CONV
+
+/********************************/
+/* Function is_vms_varlen_txt() */
+/********************************/
+
+static int is_vms_varlen_txt(__G__ ef_buf, ef_len)
+ __GDEF
+ uch *ef_buf; /* buffer containing extra field */
+ unsigned ef_len; /* total length of extra field */
+{
+ unsigned eb_id;
+ unsigned eb_len;
+ uch *eb_data;
+ unsigned eb_datlen;
+#define VMSREC_C_UNDEF 0
+#define VMSREC_C_VAR 2
+ uch vms_rectype = VMSREC_C_UNDEF;
+ uch vms_fileorg = 0;
+
+#define VMSPK_ITEMID 0
+#define VMSPK_ITEMLEN 2
+#define VMSPK_ITEMHEADSZ 4
+
+#define VMSATR_C_RECATTR 4
+#define VMS_FABSIG 0x42414656 /* "VFAB" */
+/* offsets of interesting fields in VMS fabdef structure */
+#define VMSFAB_B_RFM 31 /* record format byte */
+#define VMSFAB_B_ORG 29 /* file organization byte */
+
+ if (ef_len == 0 || ef_buf == NULL)
+ return FALSE;
+
+ while (ef_len >= EB_HEADSIZE) {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ Trace((stderr,
+ "is_vms_varlen_txt: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ switch (eb_id) {
+ case EF_PKVMS:
+ /* The PKVMS e.f. raw data part consists of:
+ * a) 4 bytes CRC checksum
+ * b) list of uncompressed variable-length data items
+ * Each data item is introduced by a fixed header
+ * - 2 bytes data type ID
+ * - 2 bytes <size> of data
+ * - <size> bytes of actual attribute data
+ */
+
+ /* get pointer to start of data and its total length */
+ eb_data = ef_buf+(EB_HEADSIZE+4);
+ eb_datlen = eb_len-4;
+
+ /* test the CRC checksum */
+ if (makelong(ef_buf+EB_HEADSIZE) !=
+ crc32(CRCVAL_INITIAL, eb_data, (extent)eb_datlen))
+ {
+ Info(slide, 1, ((char *)slide,
+ "[Warning: CRC error, discarding PKWARE extra field]\n"));
+ /* skip over the data analysis code */
+ break;
+ }
+
+ /* scan through the attribute data items */
+ while (eb_datlen > 4)
+ {
+ unsigned fldsize = makeword(&eb_data[VMSPK_ITEMLEN]);
+
+ /* check the item type word */
+ switch (makeword(&eb_data[VMSPK_ITEMID])) {
+ case VMSATR_C_RECATTR:
+ /* we have found the (currently only) interesting
+ * data item */
+ if (fldsize >= 1) {
+ vms_rectype = eb_data[VMSPK_ITEMHEADSZ] & 15;
+ vms_fileorg = eb_data[VMSPK_ITEMHEADSZ] >> 4;
+ }
+ break;
+ default:
+ break;
+ }
+ /* skip to next data item */
+ eb_datlen -= fldsize + VMSPK_ITEMHEADSZ;
+ eb_data += fldsize + VMSPK_ITEMHEADSZ;
+ }
+ break;
+
+ case EF_IZVMS:
+ if (makelong(ef_buf+EB_HEADSIZE) == VMS_FABSIG) {
+ if ((eb_data = extract_izvms_block(__G__
+ ef_buf+EB_HEADSIZE, eb_len,
+ &eb_datlen, NULL, 0))
+ != NULL)
+ {
+ if (eb_datlen >= VMSFAB_B_RFM+1) {
+ vms_rectype = eb_data[VMSFAB_B_RFM] & 15;
+ vms_fileorg = eb_data[VMSFAB_B_ORG] >> 4;
+ }
+ free(eb_data);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Skip this extra field block */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return (vms_rectype == VMSREC_C_VAR);
+
+} /* end function is_vms_varlen_txtfile() */
+
+#endif /* VMS_TEXT_CONV */
+
+
+
+
+/*************************/
+/* Function disk_error() */
+/*************************/
+
+static int disk_error(__G)
+ __GDEF
+{
+ /* OK to use slide[] here because this file is finished regardless */
+ Info(slide, 0x4a1, ((char *)slide, LoadFarString(DiskFullQuery),
+ FnFilter1(G.filename)));
+
+#ifndef WINDLL
+ fgets(G.answerbuf, 9, stdin);
+ if (*G.answerbuf == 'y') /* stop writing to this file */
+ G.disk_full = 1; /* (outfile bad?), but new OK */
+ else
+#endif
+ G.disk_full = 2; /* no: exit program */
+
+ return PK_DISK;
+
+} /* end function disk_error() */
+
+#endif /* !VMS */
+
+
+
+
+
+/*****************************/
+/* Function UzpMessagePrnt() */
+/*****************************/
+
+int UZ_EXP UzpMessagePrnt(pG, buf, size, flag)
+ zvoid *pG; /* globals struct: always passed */
+ uch *buf; /* preformatted string to be printed */
+ ulg size; /* length of string (may include nulls) */
+ int flag; /* flag bits */
+{
+ /* IMPORTANT NOTE:
+ * The name of the first parameter of UzpMessagePrnt(), which passes
+ * the "Uz_Globs" address, >>> MUST <<< be identical to the string
+ * expansion of the __G__ macro in the REENTRANT case (see globals.h).
+ * This name identity is mandatory for the LoadFarString() macro
+ * (in the SMALL_MEM case) !!!
+ */
+ int error;
+ uch *q=buf, *endbuf=buf+(unsigned)size;
+#ifdef MORE
+ uch *p=buf;
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ int islinefeed = FALSE;
+#endif
+#endif
+ FILE *outfp;
+
+
+/*---------------------------------------------------------------------------
+ These tests are here to allow fine-tuning of UnZip's output messages,
+ but none of them will do anything without setting the appropriate bit
+ in the flag argument of every Info() statement which is to be turned
+ *off*. That is, all messages are currently turned on for all ports.
+ To turn off *all* messages, use the UzpMessageNull() function instead
+ of this one.
+ ---------------------------------------------------------------------------*/
+
+#if (defined(OS2) && defined(DLL))
+ if (MSG_NO_DLL2(flag)) /* if OS/2 DLL bit is set, do NOT print this msg */
+ return 0;
+#endif
+#ifdef WINDLL
+ if (MSG_NO_WDLL(flag))
+ return 0;
+#endif
+#ifdef WINDLL
+ if (MSG_NO_WGUI(flag))
+ return 0;
+#endif
+/*
+#ifdef ACORN_GUI
+ if (MSG_NO_AGUI(flag))
+ return 0;
+#endif
+ */
+#ifdef DLL /* don't display message if data is redirected */
+ if (((Uz_Globs *)pG)->redirect_data &&
+ !((Uz_Globs *)pG)->redirect_text)
+ return 0;
+#endif
+
+ if (MSG_STDERR(flag) && !((Uz_Globs *)pG)->UzO.tflag)
+ outfp = (FILE *)stderr;
+ else
+ outfp = (FILE *)stdout;
+
+#ifdef QUERY_TRNEWLN
+ /* some systems require termination of query prompts with '\n' to force
+ * immediate display */
+ if (MSG_MNEWLN(flag)) { /* assumes writable buffer (e.g., slide[]) */
+ *endbuf++ = '\n'; /* with room for one more char at end of buf */
+ ++size; /* (safe assumption: only used for four */
+ } /* short queries in extract.c and fileio.c) */
+#endif
+
+ if (MSG_TNEWLN(flag)) { /* again assumes writable buffer: fragile... */
+ if ((!size && !((Uz_Globs *)pG)->sol) ||
+ (size && (endbuf[-1] != '\n')))
+ {
+ *endbuf++ = '\n';
+ ++size;
+ }
+ }
+
+#ifdef MORE
+# ifdef SCREENSIZE
+ /* room for --More-- and one line of overlap: */
+# if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ SCREENSIZE(&((Uz_Globs *)pG)->height, &((Uz_Globs *)pG)->width);
+# else
+ SCREENSIZE(&((Uz_Globs *)pG)->height, (int *)NULL);
+# endif
+ ((Uz_Globs *)pG)->height -= 2;
+# else
+ /* room for --More-- and one line of overlap: */
+ ((Uz_Globs *)pG)->height = SCREENLINES - 2;
+# if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ ((Uz_Globs *)pG)->width = SCREENWIDTH;
+# endif
+# endif
+#endif /* MORE */
+
+ if (MSG_LNEWLN(flag) && !((Uz_Globs *)pG)->sol) {
+ /* not at start of line: want newline */
+#ifdef OS2DLL
+ if (!((Uz_Globs *)pG)->redirect_text) {
+#endif
+ putc('\n', outfp);
+ fflush(outfp);
+#ifdef MORE
+ if (((Uz_Globs *)pG)->M_flag)
+ {
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ ((Uz_Globs *)pG)->chars = 0;
+#endif
+ ++((Uz_Globs *)pG)->numlines;
+ ++((Uz_Globs *)pG)->lines;
+ if (((Uz_Globs *)pG)->lines >= ((Uz_Globs *)pG)->height)
+ (*((Uz_Globs *)pG)->mpause)((zvoid *)pG,
+ LoadFarString(MorePrompt), 1);
+ }
+#endif /* MORE */
+ if (MSG_STDERR(flag) && ((Uz_Globs *)pG)->UzO.tflag &&
+ !isatty(1) && isatty(2))
+ {
+ /* error output from testing redirected: also send to stderr */
+ putc('\n', stderr);
+ fflush(stderr);
+ }
+#ifdef OS2DLL
+ } else
+ REDIRECTC('\n');
+#endif
+ ((Uz_Globs *)pG)->sol = TRUE;
+ }
+
+ /* put zipfile name, filename and/or error/warning keywords here */
+
+#ifdef MORE
+ if (((Uz_Globs *)pG)->M_flag
+#ifdef OS2DLL
+ && !((Uz_Globs *)pG)->redirect_text
+#endif
+ )
+ {
+ while (p < endbuf) {
+ if (*p == '\n') {
+#if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ islinefeed = TRUE;
+ } else if (SCREENLWRAP) {
+ if (*p == '\r') {
+ ((Uz_Globs *)pG)->chars = 0;
+ } else {
+# ifdef TABSIZE
+ if (*p == '\t')
+ ((Uz_Globs *)pG)->chars +=
+ (TABSIZE - (((Uz_Globs *)pG)->chars % TABSIZE));
+ else
+# endif
+ ++((Uz_Globs *)pG)->chars;
+
+ if (((Uz_Globs *)pG)->chars >= ((Uz_Globs *)pG)->width)
+ islinefeed = TRUE;
+ }
+ }
+ if (islinefeed) {
+ islinefeed = FALSE;
+ ((Uz_Globs *)pG)->chars = 0;
+#endif /* (SCREENWIDTH && SCREEN_LWRAP) */
+ ++((Uz_Globs *)pG)->numlines;
+ ++((Uz_Globs *)pG)->lines;
+ if (((Uz_Globs *)pG)->lines >= ((Uz_Globs *)pG)->height)
+ {
+ if ((error = WriteError(q, p-q+1, outfp)) != 0)
+ return error;
+ fflush(outfp);
+ ((Uz_Globs *)pG)->sol = TRUE;
+ q = p + 1;
+ (*((Uz_Globs *)pG)->mpause)((zvoid *)pG,
+ LoadFarString(MorePrompt), 1);
+ }
+ }
+ INCSTR(p);
+ } /* end while */
+ size = (ulg)(p - q); /* remaining text */
+ }
+#endif /* MORE */
+
+ if (size) {
+#ifdef OS2DLL
+ if (!((Uz_Globs *)pG)->redirect_text) {
+#endif
+ if ((error = WriteError(q, size, outfp)) != 0)
+ return error;
+ fflush(outfp);
+ if (MSG_STDERR(flag) && ((Uz_Globs *)pG)->UzO.tflag &&
+ !isatty(1) && isatty(2))
+ {
+ /* error output from testing redirected: also send to stderr */
+ if ((error = WriteError(q, size, stderr)) != 0)
+ return error;
+ fflush(stderr);
+ }
+#ifdef OS2DLL
+ } else { /* GRR: this is ugly: hide with macro */
+ if ((error = REDIRECTPRINT(q, size)) != 0)
+ return error;
+ }
+#endif /* OS2DLL */
+ ((Uz_Globs *)pG)->sol = (endbuf[-1] == '\n');
+ }
+ return 0;
+
+} /* end function UzpMessagePrnt() */
+
+
+
+
+
+#ifdef DLL
+
+/*****************************/
+/* Function UzpMessageNull() */ /* convenience routine for no output at all */
+/*****************************/
+
+int UZ_EXP UzpMessageNull(pG, buf, size, flag)
+ zvoid *pG; /* globals struct: always passed */
+ uch *buf; /* preformatted string to be printed */
+ ulg size; /* length of string (may include nulls) */
+ int flag; /* flag bits */
+{
+ return 0;
+
+} /* end function UzpMessageNull() */
+
+#endif /* DLL */
+
+
+
+
+
+/***********************/
+/* Function UzpInput() */ /* GRR: this is a placeholder for now */
+/***********************/
+
+int UZ_EXP UzpInput(pG, buf, size, flag)
+ zvoid *pG; /* globals struct: always passed */
+ uch *buf; /* preformatted string to be printed */
+ int *size; /* (address of) size of buf and of returned string */
+ int flag; /* flag bits (bit 0: no echo) */
+{
+ /* tell picky compilers to shut up about "unused variable" warnings */
+ pG = pG; buf = buf; flag = flag;
+
+ *size = 0;
+ return 0;
+
+} /* end function UzpInput() */
+
+
+
+
+
+#if (!defined(WINDLL) && !defined(MACOS))
+
+/***************************/
+/* Function UzpMorePause() */
+/***************************/
+
+void UZ_EXP UzpMorePause(pG, prompt, flag)
+ zvoid *pG; /* globals struct: always passed */
+ ZCONST char *prompt; /* "--More--" prompt */
+ int flag; /* 0 = any char OK; 1 = accept only '\n', ' ', q */
+{
+ uch c;
+
+/*---------------------------------------------------------------------------
+ Print a prompt and wait for the user to press a key, then erase prompt
+ if possible.
+ ---------------------------------------------------------------------------*/
+
+ if (!((Uz_Globs *)pG)->sol)
+ fprintf(stderr, "\n");
+ /* numlines may or may not be used: */
+ fprintf(stderr, prompt, ((Uz_Globs *)pG)->numlines);
+ fflush(stderr);
+ if (flag & 1) {
+ do {
+ c = (uch)FGETCH(0);
+ } while (
+#ifdef THEOS
+ c != 17 && /* standard QUIT key */
+#endif
+ c != '\r' && c != '\n' && c != ' ' && c != 'q' && c != 'Q');
+ } else
+ c = (uch)FGETCH(0);
+
+ /* newline was not echoed, so cover up prompt line */
+ fprintf(stderr, LoadFarString(HidePrompt));
+ fflush(stderr);
+
+ if (
+#ifdef THEOS
+ (c == 17) || /* standard QUIT key */
+#endif
+ (ToLower(c) == 'q')) {
+ DESTROYGLOBALS();
+ EXIT(PK_COOL);
+ }
+
+ ((Uz_Globs *)pG)->sol = TRUE;
+
+#ifdef MORE
+ /* space for another screen, enter for another line. */
+ if ((flag & 1) && c == ' ')
+ ((Uz_Globs *)pG)->lines = 0;
+#endif /* MORE */
+
+} /* end function UzpMorePause() */
+
+#endif /* !WINDLL && !MACOS */
+
+
+
+
+#ifndef WINDLL
+
+/**************************/
+/* Function UzpPassword() */
+/**************************/
+
+int UZ_EXP UzpPassword (pG, rcnt, pwbuf, size, zfn, efn)
+ zvoid *pG; /* pointer to UnZip's internal global vars */
+ int *rcnt; /* retry counter */
+ char *pwbuf; /* buffer for password */
+ int size; /* size of password buffer */
+ ZCONST char *zfn; /* name of zip archive */
+ ZCONST char *efn; /* name of archive entry being processed */
+{
+#if CRYPT
+ int r = IZ_PW_ENTERED;
+ char *m;
+ char *prompt;
+
+#ifndef REENTRANT
+ /* tell picky compilers to shut up about "unused variable" warnings */
+ pG = pG;
+#endif
+
+ if (*rcnt == 0) { /* First call for current entry */
+ *rcnt = 2;
+ if ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL) {
+ sprintf(prompt, LoadFarString(PasswPrompt),
+ FnFilter1(zfn), FnFilter2(efn));
+ m = prompt;
+ } else
+ m = (char *)LoadFarString(PasswPrompt2);
+ } else { /* Retry call, previous password was wrong */
+ (*rcnt)--;
+ prompt = NULL;
+ m = (char *)LoadFarString(PasswRetry);
+ }
+
+ m = getp(__G__ m, pwbuf, size);
+ if (prompt != (char *)NULL) {
+ free(prompt);
+ }
+ if (m == (char *)NULL) {
+ r = IZ_PW_ERROR;
+ }
+ else if (*pwbuf == '\0') {
+ r = IZ_PW_CANCELALL;
+ }
+ return r;
+
+#else /* !CRYPT */
+ /* tell picky compilers to shut up about "unused variable" warnings */
+ pG = pG; rcnt = rcnt; pwbuf = pwbuf; size = size; zfn = zfn; efn = efn;
+
+ return IZ_PW_ERROR; /* internal error; function should never get called */
+#endif /* ?CRYPT */
+
+} /* end function UzpPassword() */
+
+
+
+
+
+/**********************/
+/* Function handler() */
+/**********************/
+
+void handler(signal) /* upon interrupt, turn on echo and exit cleanly */
+ int signal;
+{
+ GETGLOBALS();
+
+#if !(defined(SIGBUS) || defined(SIGSEGV)) /* add a newline if not at */
+ (*G.message)((zvoid *)&G, slide, 0L, 0x41); /* start of line (to stderr; */
+#endif /* slide[] should be safe) */
+
+ echon();
+
+#ifdef SIGBUS
+ if (signal == SIGBUS) {
+ Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
+ "bus error"));
+ DESTROYGLOBALS();
+ EXIT(PK_BADERR);
+ }
+#endif /* SIGBUS */
+
+#ifdef SIGSEGV
+ if (signal == SIGSEGV) {
+ Info(slide, 0x421, ((char *)slide, LoadFarString(ZipfileCorrupt),
+ "segmentation violation"));
+ DESTROYGLOBALS();
+ EXIT(PK_BADERR);
+ }
+#endif /* SIGSEGV */
+
+ /* probably ctrl-C */
+ DESTROYGLOBALS();
+#if defined(AMIGA) && defined(__SASC)
+ _abort();
+#endif
+ EXIT(IZ_CTRLC); /* was EXIT(0), then EXIT(PK_ERR) */
+}
+
+#endif /* !WINDLL */
+
+
+
+
+#if (!defined(VMS) && !defined(CMS_MVS))
+#if (!defined(OS2) || defined(TIMESTAMP))
+
+#if (!defined(HAVE_MKTIME) || defined(WIN32))
+/* also used in amiga/filedate.c and win32/win32.c */
+ZCONST ush ydays[] =
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+#endif
+
+/*******************************/
+/* Function dos_to_unix_time() */ /* used for freshening/updating/timestamps */
+/*******************************/
+
+time_t dos_to_unix_time(dosdatetime)
+ ulg dosdatetime;
+{
+ time_t m_time;
+
+#ifdef HAVE_MKTIME
+
+ ZCONST time_t now = time(NULL);
+ struct tm *tm;
+# define YRBASE 1900
+
+ tm = localtime(&now);
+ tm->tm_isdst = -1; /* let mktime determine if DST is in effect */
+
+ /* dissect date */
+ tm->tm_year = ((int)(dosdatetime >> 25) & 0x7f) + (1980 - YRBASE);
+ tm->tm_mon = ((int)(dosdatetime >> 21) & 0x0f) - 1;
+ tm->tm_mday = ((int)(dosdatetime >> 16) & 0x1f);
+
+ /* dissect time */
+ tm->tm_hour = (int)((unsigned)dosdatetime >> 11) & 0x1f;
+ tm->tm_min = (int)((unsigned)dosdatetime >> 5) & 0x3f;
+ tm->tm_sec = (int)((unsigned)dosdatetime << 1) & 0x3e;
+
+ m_time = mktime(tm);
+ NATIVE_TO_TIMET(m_time) /* NOP unless MSC 7.0 or Macintosh */
+ TTrace((stderr, " final m_time = %lu\n", (ulg)m_time));
+
+#else /* !HAVE_MKTIME */
+
+ int yr, mo, dy, hh, mm, ss;
+#ifdef TOPS20
+# define YRBASE 1900
+ struct tmx *tmx;
+ char temp[20];
+#else /* !TOPS20 */
+# define YRBASE 1970
+ int leap;
+ unsigned days;
+ struct tm *tm;
+#if (!defined(MACOS) && !defined(RISCOS) && !defined(QDOS) && !defined(TANDEM))
+#ifdef WIN32
+ TIME_ZONE_INFORMATION tzinfo;
+ DWORD res;
+#else /* ! WIN32 */
+#ifndef BSD4_4 /* GRR: change to !defined(MODERN) ? */
+#if (defined(BSD) || defined(MTS) || defined(__GO32__))
+ struct timeb tbp;
+#else /* !(BSD || MTS || __GO32__) */
+#ifdef DECLARE_TIMEZONE
+ extern time_t timezone;
+#endif
+#endif /* ?(BSD || MTS || __GO32__) */
+#endif /* !BSD4_4 */
+#endif /* ?WIN32 */
+#endif /* !MACOS && !RISCOS && !QDOS && !TANDEM */
+#endif /* ?TOPS20 */
+
+
+ /* dissect date */
+ yr = ((int)(dosdatetime >> 25) & 0x7f) + (1980 - YRBASE);
+ mo = ((int)(dosdatetime >> 21) & 0x0f) - 1;
+ dy = ((int)(dosdatetime >> 16) & 0x1f) - 1;
+
+ /* dissect time */
+ hh = (int)((unsigned)dosdatetime >> 11) & 0x1f;
+ mm = (int)((unsigned)dosdatetime >> 5) & 0x3f;
+ ss = (int)((unsigned)dosdatetime & 0x1f) * 2;
+
+#ifdef TOPS20
+ tmx = (struct tmx *)malloc(sizeof(struct tmx));
+ sprintf (temp, "%02d/%02d/%02d %02d:%02d:%02d", mo+1, dy+1, yr, hh, mm, ss);
+ time_parse(temp, tmx, (char *)0);
+ m_time = time_make(tmx);
+ free(tmx);
+
+#else /* !TOPS20 */
+
+/*---------------------------------------------------------------------------
+ Calculate the number of seconds since the epoch, usually 1 January 1970.
+ ---------------------------------------------------------------------------*/
+
+ /* leap = # of leap yrs from YRBASE up to but not including current year */
+ leap = ((yr + YRBASE - 1) / 4); /* leap year base factor */
+
+ /* calculate days from BASE to this year and add expired days this year */
+ days = (yr * 365) + (leap - 492) + ydays[mo];
+
+ /* if year is a leap year and month is after February, add another day */
+ if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
+ ++days; /* OK through 2199 */
+
+ /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
+ m_time = (time_t)((unsigned long)(days + dy) * 86400L +
+ (unsigned long)hh * 3600L +
+ (unsigned long)(mm * 60 + ss));
+ /* - 1; MS-DOS times always rounded up to nearest even second */
+ TTrace((stderr, "dos_to_unix_time:\n"));
+ TTrace((stderr, " m_time before timezone = %lu\n", (ulg)m_time));
+
+/*---------------------------------------------------------------------------
+ Adjust for local standard timezone offset.
+ ---------------------------------------------------------------------------*/
+
+#if (!defined(MACOS) && !defined(RISCOS) && !defined(QDOS) && !defined(TANDEM))
+#ifdef WIN32
+ /* account for timezone differences */
+ res = GetTimeZoneInformation(&tzinfo);
+ if (res != TIME_ZONE_ID_INVALID)
+ {
+ m_time += 60*(tzinfo.Bias);
+#else /* !WIN32 */
+#if (defined(BSD) || defined(MTS) || defined(__GO32__))
+#ifdef BSD4_4
+ if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+ (m_time < (time_t)0x70000000L) )
+ m_time = U_TIME_T_MAX; /* saturate in case of (unsigned) overflow */
+ if (m_time < (time_t)0L) /* a converted DOS time cannot be negative */
+ m_time = S_TIME_T_MAX; /* -> saturate at max signed time_t value */
+ if ((tm = localtime(&m_time)) != (struct tm *)NULL)
+ m_time -= tm->tm_gmtoff; /* sec. EAST of GMT: subtr. */
+#else /* !(BSD4_4 */
+ ftime(&tbp); /* get `timezone' */
+ m_time += tbp.timezone * 60L; /* seconds WEST of GMT: add */
+#endif /* ?(BSD4_4 || __EMX__) */
+#else /* !(BSD || MTS || __GO32__) */
+ /* tzset was already called at start of process_zipfiles() */
+ /* tzset(); */ /* set `timezone' variable */
+#ifndef __BEOS__ /* BeOS DR8 has no timezones... */
+ m_time += timezone; /* seconds WEST of GMT: add */
+#endif
+#endif /* ?(BSD || MTS || __GO32__) */
+#endif /* ?WIN32 */
+ TTrace((stderr, " m_time after timezone = %lu\n", (ulg)m_time));
+
+/*---------------------------------------------------------------------------
+ Adjust for local daylight savings (summer) time.
+ ---------------------------------------------------------------------------*/
+
+#ifndef BSD4_4 /* (DST already added to tm_gmtoff, so skip tm_isdst) */
+ if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+ (m_time < (time_t)0x70000000L) )
+ m_time = U_TIME_T_MAX; /* saturate in case of (unsigned) overflow */
+ if (m_time < (time_t)0L) /* a converted DOS time cannot be negative */
+ m_time = S_TIME_T_MAX; /* -> saturate at max signed time_t value */
+ TIMET_TO_NATIVE(m_time) /* NOP unless MSC 7.0 or Macintosh */
+ if (((tm = localtime((time_t *)&m_time)) != NULL) && tm->tm_isdst)
+#ifdef WIN32
+ m_time += 60L * tzinfo.DaylightBias; /* adjust with DST bias */
+ else
+ m_time += 60L * tzinfo.StandardBias; /* add StdBias (normally 0) */
+#else
+ m_time -= 60L * 60L; /* adjust for daylight savings time */
+#endif
+ NATIVE_TO_TIMET(m_time) /* NOP unless MSC 7.0 or Macintosh */
+ TTrace((stderr, " m_time after DST = %lu\n", (ulg)m_time));
+#endif /* !BSD4_4 */
+#ifdef WIN32
+ }
+#endif
+#endif /* !MACOS && !RISCOS && !QDOS && !TANDEM */
+#endif /* ?TOPS20 */
+
+#endif /* ?HAVE_MKTIME */
+
+ if ( (dosdatetime >= DOSTIME_2038_01_18) &&
+ (m_time < (time_t)0x70000000L) )
+ m_time = U_TIME_T_MAX; /* saturate in case of (unsigned) overflow */
+ if (m_time < (time_t)0L) /* a converted DOS time cannot be negative */
+ m_time = S_TIME_T_MAX; /* -> saturate at max signed time_t value */
+
+ return m_time;
+
+} /* end function dos_to_unix_time() */
+
+#endif /* !OS2 || TIMESTAMP */
+#endif /* !VMS && !CMS_MVS */
+
+
+
+#if (!defined(VMS) && !defined(OS2) && !defined(CMS_MVS))
+
+/******************************/
+/* Function check_for_newer() */ /* used for overwriting/freshening/updating */
+/******************************/
+
+int check_for_newer(__G__ filename) /* return 1 if existing file is newer */
+ __GDEF /* or equal; 0 if older; -1 if doesn't */
+ char *filename; /* exist yet */
+{
+ time_t existing, archive;
+#ifdef USE_EF_UT_TIME
+ iztimes z_utime;
+#endif
+#ifdef AOS_VS
+ long dyy, dmm, ddd, dhh, dmin, dss;
+
+
+ dyy = (lrec.last_mod_dos_datetime >> 25) + 1980;
+ dmm = (lrec.last_mod_dos_datetime >> 21) & 0x0f;
+ ddd = (lrec.last_mod_dos_datetime >> 16) & 0x1f;
+ dhh = (lrec.last_mod_dos_datetime >> 11) & 0x1f;
+ dmin = (lrec.last_mod_dos_datetime >> 5) & 0x3f;
+ dss = (lrec.last_mod_dos_datetime & 0x1f) * 2;
+
+ /* under AOS/VS, file times can only be set at creation time,
+ * with the info in a special DG format. Make sure we can create
+ * it here - we delete it later & re-create it, whether or not
+ * it exists now.
+ */
+ if (!zvs_create(filename, (((ulg)dgdate(dmm, ddd, dyy)) << 16) |
+ (dhh*1800L + dmin*30L + dss/2L), -1L, -1L, (char *) -1, -1, -1, -1))
+ return DOES_NOT_EXIST;
+#endif /* AOS_VS */
+
+ Trace((stderr, "check_for_newer: doing stat(%s)\n", FnFilter1(filename)));
+ if (SSTAT(filename, &G.statbuf)) {
+ Trace((stderr,
+ "check_for_newer: stat(%s) returns %d: file does not exist\n",
+ FnFilter1(filename), SSTAT(filename, &G.statbuf)));
+#ifdef SYMLINKS
+ Trace((stderr, "check_for_newer: doing lstat(%s)\n",
+ FnFilter1(filename)));
+ /* GRR OPTION: could instead do this test ONLY if G.symlnk is true */
+ if (lstat(filename, &G.statbuf) == 0) {
+ Trace((stderr,
+ "check_for_newer: lstat(%s) returns 0: symlink does exist\n",
+ FnFilter1(filename)));
+ if (QCOND2 && !IS_OVERWRT_ALL)
+ Info(slide, 0, ((char *)slide, LoadFarString(FileIsSymLink),
+ FnFilter1(filename), " with no real file"));
+ return EXISTS_AND_OLDER; /* symlink dates are meaningless */
+ }
+#endif /* SYMLINKS */
+ return DOES_NOT_EXIST;
+ }
+ Trace((stderr, "check_for_newer: stat(%s) returns 0: file exists\n",
+ FnFilter1(filename)));
+
+#ifdef SYMLINKS
+ /* GRR OPTION: could instead do this test ONLY if G.symlnk is true */
+ if (lstat(filename, &G.statbuf) == 0 && S_ISLNK(G.statbuf.st_mode)) {
+ Trace((stderr, "check_for_newer: %s is a symbolic link\n",
+ FnFilter1(filename)));
+ if (QCOND2 && !IS_OVERWRT_ALL)
+ Info(slide, 0, ((char *)slide, LoadFarString(FileIsSymLink),
+ FnFilter1(filename), ""));
+ return EXISTS_AND_OLDER; /* symlink dates are meaningless */
+ }
+#endif /* SYMLINKS */
+
+ NATIVE_TO_TIMET(G.statbuf.st_mtime) /* NOP unless MSC 7.0 or Macintosh */
+
+#ifdef USE_EF_UT_TIME
+ /* The `Unix extra field mtime' should be used for comparison with the
+ * time stamp of the existing file >>>ONLY<<< when the EF info is also
+ * used to set the modification time of the extracted file.
+ */
+ if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+ G.tz_is_valid &&
+#endif
+ (ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0,
+ G.lrec.last_mod_dos_datetime, &z_utime, NULL)
+ & EB_UT_FL_MTIME))
+ {
+ TTrace((stderr, "check_for_newer: using Unix extra field mtime\n"));
+ existing = G.statbuf.st_mtime;
+ archive = z_utime.mtime;
+ } else {
+ /* round up existing filetime to nearest 2 seconds for comparison,
+ * but saturate in case of arithmetic overflow
+ */
+ existing = ((G.statbuf.st_mtime & 1) &&
+ (G.statbuf.st_mtime + 1 > G.statbuf.st_mtime)) ?
+ G.statbuf.st_mtime + 1 : G.statbuf.st_mtime;
+ archive = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+ }
+#else /* !USE_EF_UT_TIME */
+ /* round up existing filetime to nearest 2 seconds for comparison,
+ * but saturate in case of arithmetic overflow
+ */
+ existing = ((G.statbuf.st_mtime & 1) &&
+ (G.statbuf.st_mtime + 1 > G.statbuf.st_mtime)) ?
+ G.statbuf.st_mtime + 1 : G.statbuf.st_mtime;
+ archive = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+#endif /* ?USE_EF_UT_TIME */
+
+ TTrace((stderr, "check_for_newer: existing %lu, archive %lu, e-a %ld\n",
+ (ulg)existing, (ulg)archive, (long)(existing-archive)));
+
+ return (existing >= archive);
+
+} /* end function check_for_newer() */
+
+#endif /* !VMS && !OS2 && !CMS_MVS */
+
+
+
+
+
+/************************/
+/* Function do_string() */
+/************************/
+
+int do_string(__G__ length, option) /* return PK-type error code */
+ __GDEF
+ unsigned int length; /* without prototype, ush converted to this */
+ int option;
+{
+ unsigned comment_bytes_left;
+ unsigned int block_len;
+ int error=PK_OK;
+#ifdef AMIGA
+ char tmp_fnote[2 * AMIGA_FILENOTELEN]; /* extra room for squozen chars */
+#endif
+
+
+/*---------------------------------------------------------------------------
+ This function processes arbitrary-length (well, usually) strings. Four
+ major options are allowed: SKIP, wherein the string is skipped (pretty
+ logical, eh?); DISPLAY, wherein the string is printed to standard output
+ after undergoing any necessary or unnecessary character conversions;
+ DS_FN, wherein the string is put into the filename[] array after under-
+ going appropriate conversions (including case-conversion, if that is
+ indicated: see the global variable pInfo->lcflag); and EXTRA_FIELD,
+ wherein the `string' is assumed to be an extra field and is copied to
+ the (freshly malloced) buffer G.extra_field. The third option should
+ be OK since filename is dimensioned at 1025, but we check anyway.
+
+ The string, by the way, is assumed to start at the current file-pointer
+ position; its length is given by 'length'. So start off by checking the
+ length of the string: if zero, we're already done.
+ ---------------------------------------------------------------------------*/
+
+ if (!length)
+ return PK_COOL;
+
+ switch (option) {
+
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+ /*
+ * Special case: See if the comment begins with an autorun command line.
+ * Save that and display (or skip) the remainder.
+ */
+
+ case CHECK_AUTORUN:
+ case CHECK_AUTORUN_Q:
+ comment_bytes_left = length;
+ if (length >= 10)
+ {
+ block_len = readbuf(__G__ (char *)G.outbuf, 10);
+ if (block_len == 0)
+ return PK_EOF;
+ comment_bytes_left -= block_len;
+ G.outbuf[block_len] = '\0';
+ if (!strcmp((char *)G.outbuf, "$AUTORUN$>")) {
+ char *eol;
+ length -= 10;
+ block_len = readbuf(__G__ G.autorun_command,
+ MIN(length, sizeof(G.autorun_command)-1));
+ if (block_len == 0)
+ return PK_EOF;
+ comment_bytes_left -= block_len;
+ G.autorun_command[block_len] = '\0';
+ A_TO_N(G.autorun_command);
+ eol = strchr(G.autorun_command, '\n');
+ if (!eol)
+ eol = G.autorun_command + strlen(G.autorun_command) - 1;
+ length -= eol + 1 - G.autorun_command;
+ while (eol >= G.autorun_command && isspace(*eol))
+ *eol-- = '\0';
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ INTERN_TO_OEM(G.autorun_command, G.autorun_command);
+#endif /* (WIN32 && !_WIN32_WCE) */
+ }
+ }
+ if (option == CHECK_AUTORUN_Q) /* don't display the remainder */
+ length = 0;
+ /* seek to beginning of remaining part of comment -- rewind if */
+ /* displaying entire comment, or skip to end if discarding it */
+ seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+ (G.inptr - G.inbuf) + comment_bytes_left - length);
+ if (!length)
+ break;
+ /* FALL THROUGH... */
+#endif /* SFX && CHEAP_SFX_AUTORUN */
+
+ /*
+ * First normal case: print string on standard output. First set loop
+ * variables, then loop through the comment in chunks of OUTBUFSIZ bytes,
+ * converting formats and printing as we go. The second half of the
+ * loop conditional was added because the file might be truncated, in
+ * which case comment_bytes_left will remain at some non-zero value for
+ * all time. outbuf and slide are used as scratch buffers because they
+ * are available (we should be either before or in between any file pro-
+ * cessing).
+ */
+
+ case DISPLAY:
+ case DISPL_8:
+ comment_bytes_left = length;
+ block_len = OUTBUFSIZ; /* for the while statement, first time */
+ while (comment_bytes_left > 0 && block_len > 0) {
+ register uch *p = G.outbuf;
+ register uch *q = G.outbuf;
+
+ if ((block_len = readbuf(__G__ (char *)G.outbuf,
+ MIN((unsigned)OUTBUFSIZ, comment_bytes_left))) == 0)
+ return PK_EOF;
+ comment_bytes_left -= block_len;
+
+ /* this is why we allocated an extra byte for outbuf: terminate
+ * with zero (ASCIIZ) */
+ G.outbuf[block_len] = '\0';
+
+ /* remove all ASCII carriage returns from comment before printing
+ * (since used before A_TO_N(), check for CR instead of '\r')
+ */
+ while (*p) {
+ while (*p == CR)
+ ++p;
+ *q++ = *p++;
+ }
+ /* could check whether (p - outbuf) == block_len here */
+ *q = '\0';
+
+ if (option == DISPL_8) {
+ /* translate the text coded in the entry's host-dependent
+ "extended ASCII" charset into the compiler's (system's)
+ internal text code page */
+ Ext_ASCII_TO_Native((char *)G.outbuf, G.pInfo->hostnum,
+ G.pInfo->hostver, G.pInfo->HasUxAtt,
+ FALSE);
+#ifdef WINDLL
+ /* translate to ANSI (RTL internal codepage may be OEM) */
+ INTERN_TO_ISO((char *)G.outbuf, (char *)G.outbuf);
+#else /* !WINDLL */
+#if (defined(WIN32) && !defined(_WIN32_WCE))
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ INTERN_TO_OEM((char *)G.outbuf, (char *)G.outbuf);
+#endif /* (WIN32 && !_WIN32_WCE) */
+#endif /* ?WINDLL */
+ } else {
+ A_TO_N(G.outbuf); /* translate string to native */
+ }
+
+#ifdef WINDLL
+ /* ran out of local mem -- had to cheat */
+ win_fprintf((zvoid *)&G, stdout, length, (char *)G.outbuf);
+ win_fprintf((zvoid *)&G, stdout, 2, (char *)"\n\n");
+#else /* !WINDLL */
+#ifdef NOANSIFILT /* GRR: can ANSI be used with EBCDIC? */
+ (*G.message)((zvoid *)&G, G.outbuf, (ulg)(q-G.outbuf), 0);
+#else /* ASCII, filter out ANSI escape sequences and handle ^S (pause) */
+ p = G.outbuf - 1;
+ q = slide;
+ while (*++p) {
+ int pause = FALSE;
+
+ if (*p == 0x1B) { /* ASCII escape char */
+ *q++ = '^';
+ *q++ = '[';
+ } else if (*p == 0x13) { /* ASCII ^S (pause) */
+ pause = TRUE;
+ if (p[1] == LF) /* ASCII LF */
+ *q++ = *++p;
+ else if (p[1] == CR && p[2] == LF) { /* ASCII CR LF */
+ *q++ = *++p;
+ *q++ = *++p;
+ }
+ } else
+ *q++ = *p;
+ if ((unsigned)(q-slide) > WSIZE-3 || pause) { /* flush */
+ (*G.message)((zvoid *)&G, slide, (ulg)(q-slide), 0);
+ q = slide;
+ if (pause && G.extract_flag) /* don't pause for list/test */
+ (*G.mpause)((zvoid *)&G, LoadFarString(QuitPrompt), 0);
+ }
+ }
+ (*G.message)((zvoid *)&G, slide, (ulg)(q-slide), 0);
+#endif /* ?NOANSIFILT */
+#endif /* ?WINDLL */
+ }
+ /* add '\n' if not at start of line */
+ (*G.message)((zvoid *)&G, slide, 0L, 0x40);
+ break;
+
+ /*
+ * Second case: read string into filename[] array. The filename should
+ * never ever be longer than FILNAMSIZ-1 (1024), but for now we'll check,
+ * just to be sure.
+ */
+
+ case DS_FN:
+ case DS_FN_L:
+ if (length >= FILNAMSIZ) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FilenameTooLongTrunc)));
+ error = PK_WARN;
+ /* remember excess length in block_len */
+ block_len = length - (FILNAMSIZ - 1);
+ length = FILNAMSIZ - 1;
+ } else
+ /* no excess size */
+ block_len = 0;
+ if (readbuf(__G__ G.filename, length) == 0)
+ return PK_EOF;
+ G.filename[length] = '\0'; /* terminate w/zero: ASCIIZ */
+
+ /* translate the Zip entry filename coded in host-dependent "extended
+ ASCII" into the compiler's (system's) internal text code page */
+ Ext_ASCII_TO_Native(G.filename, G.pInfo->hostnum, G.pInfo->hostver,
+ G.pInfo->HasUxAtt, (option == DS_FN_L));
+
+ if (G.pInfo->lcflag) /* replace with lowercase filename */
+ STRLOWER(G.filename, G.filename);
+
+ if (G.pInfo->vollabel && length > 8 && G.filename[8] == '.') {
+ char *p = G.filename+8;
+ while (*p++)
+ p[-1] = *p; /* disk label, and 8th char is dot: remove dot */
+ }
+
+ if (!block_len) /* no overflow, we're done here */
+ break;
+
+ /*
+ * We truncated the filename, so print what's left and then fall
+ * through to the SKIP routine.
+ */
+ Info(slide, 0x401, ((char *)slide, "[ %s ]\n", FnFilter1(G.filename)));
+ length = block_len; /* SKIP the excess bytes... */
+ /* FALL THROUGH... */
+
+ /*
+ * Third case: skip string, adjusting readbuf's internal variables
+ * as necessary (and possibly skipping to and reading a new block of
+ * data).
+ */
+
+ case SKIP:
+ /* cur_zipfile_bufstart already takes account of extra_bytes, so don't
+ * correct for it twice: */
+ seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+ (G.inptr-G.inbuf) + length);
+ break;
+
+ /*
+ * Fourth case: assume we're at the start of an "extra field"; malloc
+ * storage for it and read data into the allocated space.
+ */
+
+ case EXTRA_FIELD:
+ if (G.extra_field != (uch *)NULL)
+ free(G.extra_field);
+ if ((G.extra_field = (uch *)malloc(length)) == (uch *)NULL) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ExtraFieldTooLong),
+ length));
+ /* cur_zipfile_bufstart already takes account of extra_bytes,
+ * so don't correct for it twice: */
+ seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+ (G.inptr-G.inbuf) + length);
+ } else
+ if (readbuf(__G__ (char *)G.extra_field, length) == 0)
+ return PK_EOF;
+ break;
+
+#ifdef AMIGA
+ /*
+ * Fifth case, for the Amiga only: take the comment that would ordinarily
+ * be skipped over, and turn it into a 79 character string that will be
+ * attached to the file as a "filenote" after it is extracted.
+ */
+
+ case FILENOTE:
+ if ((block_len = readbuf(__G__ tmp_fnote, (unsigned)
+ MIN(length, 2 * AMIGA_FILENOTELEN - 1))) == 0)
+ return PK_EOF;
+ if ((length -= block_len) > 0) /* treat remainder as in case SKIP: */
+ seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes
+ + (G.inptr - G.inbuf) + length);
+ /* convert multi-line text into single line with no ctl-chars: */
+ tmp_fnote[block_len] = '\0';
+ while ((short int) --block_len >= 0)
+ if ((unsigned) tmp_fnote[block_len] < ' ')
+ if (tmp_fnote[block_len+1] == ' ') /* no excess */
+ strcpy(tmp_fnote+block_len, tmp_fnote+block_len+1);
+ else
+ tmp_fnote[block_len] = ' ';
+ tmp_fnote[AMIGA_FILENOTELEN - 1] = '\0';
+ if (G.filenotes[G.filenote_slot])
+ free(G.filenotes[G.filenote_slot]); /* should not happen */
+ G.filenotes[G.filenote_slot] = NULL;
+ if (tmp_fnote[0]) {
+ if (!(G.filenotes[G.filenote_slot] = malloc(strlen(tmp_fnote)+1)))
+ return PK_MEM;
+ strcpy(G.filenotes[G.filenote_slot], tmp_fnote);
+ }
+ break;
+#endif /* AMIGA */
+
+ } /* end switch (option) */
+
+ return error;
+
+} /* end function do_string() */
+
+
+
+
+
+/***********************/
+/* Function makeword() */
+/***********************/
+
+ush makeword(b)
+ ZCONST uch *b;
+{
+ /*
+ * Convert Intel style 'short' integer to non-Intel non-16-bit
+ * host format. This routine also takes care of byte-ordering.
+ */
+ return (ush)((b[1] << 8) | b[0]);
+}
+
+
+
+
+
+/***********************/
+/* Function makelong() */
+/***********************/
+
+ulg makelong(sig)
+ ZCONST uch *sig;
+{
+ /*
+ * Convert intel style 'long' variable to non-Intel non-16-bit
+ * host format. This routine also takes care of byte-ordering.
+ */
+ return (((ulg)sig[3]) << 24)
+ + (((ulg)sig[2]) << 16)
+ + (((ulg)sig[1]) << 8)
+ + ((ulg)sig[0]);
+}
+
+
+
+#if CRYPT
+
+#ifdef NEED_STR2ISO
+/**********************/
+/* Function str2iso() */
+/**********************/
+
+char *str2iso(dst, src)
+ char *dst; /* destination buffer */
+ register ZCONST char *src; /* source string */
+{
+#ifdef INTERN_TO_ISO
+ INTERN_TO_ISO(src, dst);
+#else
+ register uch c;
+ register char *dstp = dst;
+
+ do {
+ c = (uch)foreign(*src++);
+ *dstp++ = (char)ASCII2ISO(c);
+ } while (c != '\0');
+#endif
+
+ return dst;
+}
+#endif /* NEED_STR2ISO */
+
+
+#ifdef NEED_STR2OEM
+/**********************/
+/* Function str2oem() */
+/**********************/
+
+char *str2oem(dst, src)
+ char *dst; /* destination buffer */
+ register ZCONST char *src; /* source string */
+{
+#ifdef INTERN_TO_OEM
+ INTERN_TO_OEM(src, dst);
+#else
+ register uch c;
+ register char *dstp = dst;
+
+ do {
+ c = (uch)foreign(*src++);
+ *dstp++ = (char)ASCII2OEM(c);
+ } while (c != '\0');
+#endif
+
+ return dst;
+}
+#endif /* NEED_STR2OEM */
+
+#endif /* CRYPT */
+
+
+#ifdef ZMEM /* memset/memcmp/memcpy for systems without either them or */
+ /* bzero/bcmp/bcopy */
+ /* (no known systems as of 960211) */
+
+/*********************/
+/* Function memset() */
+/*********************/
+
+zvoid *memset(buf, init, len)
+ register zvoid *buf; /* buffer location */
+ register int init; /* initializer character */
+ register unsigned int len; /* length of the buffer */
+{
+ zvoid *start;
+
+ start = buf;
+ while (len--)
+ *((char *)buf++) = (char)init;
+ return start;
+}
+
+
+
+/*********************/
+/* Function memcmp() */
+/*********************/
+
+int memcmp(b1, b2, len)
+ register ZCONST zvoid *b1;
+ register ZCONST zvoid *b2;
+ register unsigned int len;
+{
+ register int c;
+
+ if (len > 0) do {
+ if ((c = (int)(*((ZCONST unsigned char *)b1)++) -
+ (int)(*((ZCONST unsigned char *)b2)++)) != 0)
+ return c;
+ } while (--len > 0)
+ return 0;
+}
+
+
+
+/*********************/
+/* Function memcpy() */
+/*********************/
+
+zvoid *memcpy(dst, src, len)
+ register zvoid *dst;
+ register ZCONST zvoid *src;
+ register unsigned int len;
+{
+ zvoid *start;
+
+ start = dst;
+ while (len-- > 0)
+ *((char *)dst)++ = *((ZCONST char *)src)++;
+ return start;
+}
+
+#endif /* ZMEM */
+
+
+
+
+#ifdef NO_STRNICMP
+
+/************************/
+/* Function zstrnicmp() */
+/************************/
+
+int zstrnicmp(s1, s2, n)
+ register ZCONST char *s1, *s2;
+ register unsigned n;
+{
+ for (; n > 0; --n, ++s1, ++s2) {
+
+ if (ToLower(*s1) != ToLower(*s2))
+ /* test includes early termination of one string */
+ return (ToLower(*s1) < ToLower(*s2))? -1 : 1;
+
+ if (*s1 == '\0') /* both strings terminate early */
+ return 0;
+ }
+ return 0;
+}
+
+#endif /* NO_STRNICMP */
+
+
+
+
+#ifdef REGULUS /* returns the inode number on success(!)...argh argh argh */
+# undef stat
+
+/********************/
+/* Function zstat() */
+/********************/
+
+int zstat(p, s)
+ ZCONST char *p;
+ struct stat *s;
+{
+ return (stat((char *)p,s) >= 0? 0 : (-1));
+}
+
+#endif /* REGULUS */
+
+
+
+
+#ifdef _MBCS
+
+/* DBCS support for Info-ZIP's zip (mainly for japanese (-: )
+ * by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y(a)is.aist-nara.ac.jp)
+ * This code is public domain! Date: 1998/12/20
+ */
+
+/************************/
+/* Function plastchar() */
+/************************/
+
+char *plastchar(ptr, len)
+ ZCONST char *ptr;
+ extent len;
+{
+ unsigned clen;
+ ZCONST char *oldptr = ptr;
+ while(*ptr != '\0' && len > 0){
+ oldptr = ptr;
+ clen = CLEN(ptr);
+ ptr += clen;
+ len -= clen;
+ }
+ return (char *)oldptr;
+}
+
+
+#ifdef NEED_UZMBSCHR
+/***********************/
+/* Function uzmbschr() */
+/***********************/
+
+unsigned char *uzmbschr(str, c)
+ ZCONST unsigned char *str;
+ unsigned int c;
+{
+ while(*str != '\0'){
+ if (*str == c) {return (unsigned char *)str;}
+ INCSTR(str);
+ }
+ return NULL;
+}
+#endif /* NEED_UZMBSCHR */
+
+
+#ifdef NEED_UZMBSRCHR
+/************************/
+/* Function uzmbsrchr() */
+/************************/
+
+unsigned char *uzmbsrchr(str, c)
+ ZCONST unsigned char *str;
+ unsigned int c;
+{
+ unsigned char *match = NULL;
+ while(*str != '\0'){
+ if (*str == c) {match = (unsigned char *)str;}
+ INCSTR(str);
+ }
+ return match;
+}
+#endif /* NEED_UZMBSRCHR */
+#endif /* _MBCS */
+
+
+
+
+
+#ifdef SMALL_MEM
+
+/*******************************/
+/* Function fLoadFarString() */ /* (and friends...) */
+/*******************************/
+
+char *fLoadFarString(__GPRO__ const char Far *sz)
+{
+ (void)zfstrcpy(G.rgchBigBuffer, sz);
+ return G.rgchBigBuffer;
+}
+
+char *fLoadFarStringSmall(__GPRO__ const char Far *sz)
+{
+ (void)zfstrcpy(G.rgchSmallBuffer, sz);
+ return G.rgchSmallBuffer;
+}
+
+char *fLoadFarStringSmall2(__GPRO__ const char Far *sz)
+{
+ (void)zfstrcpy(G.rgchSmallBuffer2, sz);
+ return G.rgchSmallBuffer2;
+}
+
+
+
+
+#if (!defined(_MSC_VER) || (_MSC_VER < 600))
+/*************************/
+/* Function zfstrcpy() */ /* portable clone of _fstrcpy() */
+/*************************/
+
+char Far * Far zfstrcpy(char Far *s1, const char Far *s2)
+{
+ char Far *p = s1;
+
+ while ((*s1++ = *s2++) != '\0');
+ return p;
+}
+
+#if (!(defined(SFX) || defined(FUNZIP)))
+/*************************/
+/* Function zfstrcmp() */ /* portable clone of _fstrcmp() */
+/*************************/
+
+int Far zfstrcmp(const char Far *s1, const char Far *s2)
+{
+ int ret;
+
+ while ((ret = (int)(uch)*s1 - (int)(uch)*s2) == 0
+ && *s2 != '\0') {
+ ++s2; ++s1;
+ }
+ return ret;
+}
+#endif /* !(SFX || FUNZIP) */
+#endif /* !_MSC_VER || (_MSC_VER < 600) */
+
+#endif /* SMALL_MEM */
Property changes on: trunk/build/install/installer/fileio.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/globals.c
===================================================================
--- trunk/build/install/installer/globals.c (rev 0)
+++ trunk/build/install/installer/globals.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,215 @@
+/*
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ globals.c
+
+ Routines to allocate and initialize globals, with or without threads.
+
+ Contents: registerGlobalPointer()
+ deregisterGlobalPointer()
+ getGlobalPointer()
+ globalsCtor()
+
+ ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+#ifndef FUNZIP
+/* initialization of sigs is completed at runtime so unzip(sfx) executable
+ * won't look like a zipfile
+ */
+char central_hdr_sig[4] = {0, 0, 0x01, 0x02};
+char local_hdr_sig[4] = {0, 0, 0x03, 0x04};
+char end_central_sig[4] = {0, 0, 0x05, 0x06};
+/* extern char extd_local_sig[4] = {0, 0, 0x07, 0x08}; NOT USED YET */
+
+ZCONST char *fnames[2] = {"*", NULL}; /* default filenames vector */
+#endif
+
+
+#ifndef REENTRANT
+ Uz_Globs G;
+#else /* REENTRANT */
+
+# ifndef USETHREADID
+ Uz_Globs *GG;
+# else /* USETHREADID */
+# define THREADID_ENTRIES 0x40
+
+ int lastScan;
+ Uz_Globs *threadPtrTable[THREADID_ENTRIES];
+ ulg threadIdTable [THREADID_ENTRIES] = {
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* Make sure there are */
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* THREADID_ENTRIES 0s */
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ };
+
+ static ZCONST char Far TooManyThreads[] =
+ "error: more than %d simultaneous threads.\n\
+ Some threads are probably not calling DESTROYTHREAD()\n";
+ static ZCONST char Far EntryNotFound[] =
+ "error: couldn't find global pointer in table.\n\
+ Maybe somebody accidentally called DESTROYTHREAD() twice.\n";
+ static ZCONST char Far GlobalPointerMismatch[] =
+ "error: global pointer in table does not match pointer passed as\
+ parameter\n";
+
+static void registerGlobalPointer OF((__GPRO));
+
+
+
+static void registerGlobalPointer(__G)
+ __GDEF
+{
+ int scan=0;
+ ulg tid = GetThreadId();
+
+ while (threadIdTable[scan] && scan < THREADID_ENTRIES)
+ scan++;
+
+ if (scan == THREADID_ENTRIES) {
+ ZCONST char *tooMany = LoadFarString(TooManyThreads);
+ Info(slide, 0x421, ((char *)slide, tooMany, THREADID_ENTRIES));
+ free(pG);
+ EXIT(PK_MEM); /* essentially memory error before we've started */
+ }
+
+ threadIdTable [scan] = tid;
+ threadPtrTable[scan] = pG;
+ lastScan = scan;
+}
+
+
+
+void deregisterGlobalPointer(__G)
+ __GDEF
+{
+ int scan=0;
+ ulg tid = GetThreadId();
+
+
+ while (threadIdTable[scan] != tid && scan < THREADID_ENTRIES)
+ scan++;
+
+/*---------------------------------------------------------------------------
+ There are two things we can do if we can't find the entry: ignore it or
+ scream. The most likely reason for it not to be here is the user calling
+ this routine twice. Since this could cause BIG problems if any globals
+ are accessed after the first call, we'd better scream.
+ ---------------------------------------------------------------------------*/
+
+ if (scan == THREADID_ENTRIES || threadPtrTable[scan] != pG) {
+ ZCONST char *noEntry;
+ if (scan == THREADID_ENTRIES)
+ noEntry = LoadFarString(EntryNotFound);
+ else
+ noEntry = LoadFarString(GlobalPointerMismatch);
+ Info(slide, 0x421, ((char *)slide, noEntry));
+ EXIT(PK_WARN); /* programming error, but after we're all done */
+ }
+
+ threadIdTable [scan] = 0;
+ lastScan = scan;
+ free(threadPtrTable[scan]);
+}
+
+
+
+Uz_Globs *getGlobalPointer()
+{
+ int scan=0;
+ ulg tid = GetThreadId();
+
+ while (threadIdTable[scan] != tid && scan < THREADID_ENTRIES)
+ scan++;
+
+/*---------------------------------------------------------------------------
+ There are two things we can do if we can't find the entry: ignore it or
+ scream. The most likely reason for it not to be here is the user calling
+ this routine twice. Since this could cause BIG problems if any globals
+ are accessed after the first call, we'd better scream.
+ ---------------------------------------------------------------------------*/
+
+ if (scan == THREADID_ENTRIES) {
+ ZCONST char *noEntry = LoadFarString(EntryNotFound);
+ fprintf(stderr, noEntry); /* can't use Info w/o a global pointer */
+ EXIT(PK_ERR); /* programming error while still working */
+ }
+
+ return threadPtrTable[scan];
+}
+
+# endif /* ?USETHREADID */
+#endif /* ?REENTRANT */
+
+
+
+Uz_Globs *globalsCtor()
+{
+#ifdef REENTRANT
+ Uz_Globs *pG = (Uz_Globs *)malloc(sizeof(Uz_Globs));
+
+ if (!pG)
+ return (Uz_Globs *)NULL;
+#endif /* REENTRANT */
+
+ /* for REENTRANT version, G is defined as (*pG) */
+
+ memzero(&G, sizeof(Uz_Globs));
+
+#ifndef FUNZIP
+#ifdef CMS_MVS
+ uO.aflag=1;
+ uO.C_flag=1;
+#endif
+#ifdef TANDEM
+ uO.aflag=1; /* default to '-a' auto create Text Files as type 101 */
+#endif
+
+ uO.lflag=(-1);
+ G.wildzipfn = "";
+ G.pfnames = (char **)fnames;
+ G.pxnames = (char **)&fnames[1];
+ G.pInfo = G.info;
+ G.sol = TRUE; /* at start of line */
+
+ G.message = UzpMessagePrnt;
+ G.input = UzpInput; /* not used by anyone at the moment... */
+#if defined(WINDLL) || defined(MACOS)
+ G.mpause = NULL; /* has scrollbars: no need for pausing */
+#else
+ G.mpause = UzpMorePause;
+#endif
+ G.decr_passwd = UzpPassword;
+#endif /* !FUNZIP */
+
+#if (!defined(DOS_FLX_H68_NLM_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
+#if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
+ G.echofd = -1;
+#endif /* !(MACOS || ATARI || VMS) */
+#endif /* !(DOS_FLX_H68_NLM_OS2_W32 || AMIGA || RISCOS) */
+
+#ifdef SYSTEM_SPECIFIC_CTOR
+ SYSTEM_SPECIFIC_CTOR(__G);
+#endif
+
+#ifdef REENTRANT
+#ifdef USETHREADID
+ registerGlobalPointer(__G);
+#else
+ GG = &G;
+#endif /* ?USETHREADID */
+#endif /* REENTRANT */
+
+ return &G;
+}
Property changes on: trunk/build/install/installer/globals.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/globals.h
===================================================================
--- trunk/build/install/installer/globals.h (rev 0)
+++ trunk/build/install/installer/globals.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,430 @@
+/*
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ globals.h
+
+ There is usually no need to include this file since unzip.h includes it.
+
+ This header file is used by all of the UnZip source files. It contains
+ a struct definition that is used to "house" all of the global variables.
+ This is done to allow for multithreaded environments (OS/2, NT, Win95,
+ Unix) to call UnZip through an API without a semaphore. REENTRANT should
+ be defined for all platforms that require this.
+
+ GLOBAL CONSTRUCTOR AND DESTRUCTOR (API WRITERS READ THIS!!!)
+ ------------------------------------------------------------
+
+ No, it's not C++, but it's as close as we can get with K&R.
+
+ The main() of each process that uses these globals must include the
+ CONSTRUCTGLOBALS; statement. This will malloc enough memory for the
+ structure and initialize any variables that require it. This must
+ also be done by any API function that jumps into the middle of the
+ code.
+
+ The DESTROYGLOBALS(); statement should be inserted before EVERY "EXIT(n)".
+ Naturally, it also needs to be put before any API returns as well.
+ In fact, it's much more important in API functions since the process
+ will NOT end, and therefore the memory WON'T automatically be freed
+ by the operating system.
+
+ USING VARIABLES FROM THE STRUCTURE
+ ----------------------------------
+
+ All global variables must now be prefixed with `G.' which is either a
+ global struct (in which case it should be the only global variable) or
+ a macro for the value of a local pointer variable that is passed from
+ function to function. Yes, this is a pain. But it's the only way to
+ allow full reentrancy.
+
+ ADDING VARIABLES TO THE STRUCTURE
+ ---------------------------------
+
+ If you make the inclusion of any variables conditional, be sure to only
+ check macros that are GUARANTEED to be included in every module.
+ For instance, newzip and pwdarg are needed only if CRYPT is TRUE,
+ but this is defined after unzip.h has been read. If you are not careful,
+ some modules will expect your variable to be part of this struct while
+ others won't. This will cause BIG problems. (Inexplicable crashes at
+ strange times, car fires, etc.) When in doubt, always include it!
+
+ Note also that UnZipSFX needs a few variables that UnZip doesn't. However,
+ it also includes some object files from UnZip. If we were to conditionally
+ include the extra variables that UnZipSFX needs, the object files from
+ UnZip would not mesh with the UnZipSFX object files. Result: we just
+ include the UnZipSFX variables every time. (It's only an extra 4 bytes
+ so who cares!)
+
+ ADDING FUNCTIONS
+ ----------------
+
+ To support this new global struct, all functions must now conditionally
+ pass the globals pointer (pG) to each other. This is supported by 5 macros:
+ __GPRO, __GPRO__, __G, __G__ and __GDEF. A function that needs no other
+ parameters would look like this:
+
+ int extract_or_test_files(__G)
+ __GDEF
+ {
+ ... stuff ...
+ }
+
+ A function with other parameters would look like:
+
+ int memextract(__G__ tgt, tgtsize, src, srcsize)
+ __GDEF
+ uch *tgt, *src;
+ ulg tgtsize, srcsize;
+ {
+ ... stuff ...
+ }
+
+ In the Function Prototypes section of unzpriv.h, you should use __GPRO and
+ __GPRO__ instead:
+
+ int uz_opts OF((__GPRO__ int *pargc, char ***pargv));
+ int process_zipfiles OF((__GPRO));
+
+ Note that there is NO comma after __G__ or __GPRO__ and no semi-colon after
+ __GDEF. I wish there was another way but I don't think there is.
+
+
+ TESTING THE CODE
+ -----------------
+
+ Whether your platform requires reentrancy or not, you should always try
+ building with REENTRANT defined if any functions have been added. It is
+ pretty easy to forget a __G__ or a __GDEF and this mistake will only show
+ up if REENTRANT is defined. All platforms should run with REENTRANT
+ defined. Platforms that can't take advantage of it will just be paying
+ a performance penalty needlessly.
+
+ SIGNAL MADNESS
+ --------------
+
+ This whole pointer passing scheme falls apart when it comes to SIGNALs.
+ I handle this situation 2 ways right now. If you define USETHREADID,
+ UnZip will include a 64-entry table. Each entry can hold a global
+ pointer and thread ID for one thread. This should allow up to 64
+ threads to access UnZip simultaneously. Calling DESTROYGLOBALS()
+ will free the global struct and zero the table entry. If somebody
+ forgets to call DESTROYGLOBALS(), this table will eventually fill up
+ and UnZip will exit with an error message. A good way to test your
+ code to make sure you didn't forget a DESTROYGLOBALS() is to change
+ THREADID_ENTRIES to 3 or 4 in globals.c, making the table real small.
+ Then make a small test program that calls your API a dozen times.
+
+ Those platforms that don't have threads still need to be able to compile
+ with REENTRANT defined to test and see if new code is correctly written
+ to work either way. For these platforms, I simply keep a global pointer
+ called GG that points to the Globals structure. Good enough for testing.
+
+ I believe that NT has thread level storage. This could probably be used
+ to store a global pointer for the sake of the signal handler more cleanly
+ than my table approach.
+
+ ---------------------------------------------------------------------------*/
+
+#ifndef __globals_h
+#define __globals_h
+
+#ifdef USE_ZLIB
+# include "zlib.h"
+# ifdef zlib_version /* This name is used internally in unzip */
+# undef zlib_version /* and must not be defined as a macro. */
+# endif
+#endif
+
+
+/*************/
+/* Globals */
+/*************/
+
+typedef struct Globals {
+#ifdef DLL
+ zvoid *callerglobs; /* pointer to structure of pass-through global vars */
+#endif
+
+ /* command options of general use */
+ UzpOpts UzO; /* command options of general use */
+
+#ifndef FUNZIP
+ /* command options specific to the high level command line interface */
+#ifdef MORE
+ int M_flag; /* -M: built-in "more" function */
+#endif
+
+ /* internal flags and general globals */
+#ifdef MORE
+ int height; /* check for SIGWINCH, etc., eventually... */
+ int lines; /* count of lines displayed on current screen */
+# if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
+ int width;
+ int chars; /* count of screen characters in current line */
+# endif
+#endif /* MORE */
+#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+ int tz_is_valid; /* indicates that timezone info can be used */
+#endif
+ int noargs; /* did true command line have *any* arguments? */
+ unsigned filespecs; /* number of real file specifications to be matched */
+ unsigned xfilespecs; /* number of excluded filespecs to be matched */
+ int process_all_files;
+ int overwrite_mode; /* 0 - query, 1 - always, 2 - never */
+ int create_dirs; /* used by main(), mapname(), checkdir() */
+ int extract_flag;
+ int newzip; /* reset in extract.c; used in crypt.c */
+ Z_OFF_T real_ecrec_offset;
+ Z_OFF_T expect_ecrec_offset;
+ long csize; /* used by decompr. (NEXTBYTE): must be signed */
+ long used_csize; /* used by extract_or_test_member(), explode() */
+
+#ifdef DLL
+ int fValidate; /* true if only validating an archive */
+ int filenotfound;
+ int redirect_data; /* redirect data to memory buffer */
+ int redirect_text; /* redirect text output to buffer */
+# ifndef NO_SLIDE_REDIR
+ int redirect_slide; /* redirect decompression area to mem buffer */
+# if (defined(USE_DEFLATE64) && defined(INT_16BIT))
+ ulg _wsize; /* size of sliding window exceeds "unsigned" range */
+# else
+ unsigned _wsize; /* sliding window size can be hold in unsigned */
+# endif
+# endif
+ ulg redirect_size; /* size of redirected output buffer */
+ uch *redirect_buffer; /* pointer to head of allocated buffer */
+ uch *redirect_pointer; /* pointer past end of written data */
+# ifndef NO_SLIDE_REDIR
+ uch *redirect_sldptr; /* head of decompression slide buffer */
+# endif
+# ifdef OS2DLL
+ cbList(processExternally); /* call-back list */
+# endif
+#endif /* DLL */
+
+ char **pfnames;
+ char **pxnames;
+ char sig[4];
+ char answerbuf[10];
+ min_info info[DIR_BLKSIZ];
+ min_info *pInfo;
+#endif /* !FUNZIP */
+ union work area; /* see unzpriv.h for definition of work */
+
+#ifndef FUNZIP
+# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
+ ZCONST ulg near *crc_32_tab;
+# else
+ ZCONST ulg Far *crc_32_tab;
+# endif
+#endif
+ ulg crc32val; /* CRC shift reg. (was static in funzip) */
+
+#ifdef FUNZIP
+ FILE *in; /* file descriptor of compressed stream */
+#endif
+ uch *inbuf; /* input buffer (any size is OK) */
+ uch *inptr; /* pointer into input buffer */
+ int incnt;
+
+#ifndef FUNZIP
+ ulg bitbuf;
+ int bits_left; /* unreduce and unshrink only */
+ int zipeof;
+ char *argv0; /* used for NT and EXE_EXTENSION */
+ char *wildzipfn;
+ char *zipfn; /* GRR: WINDLL: must nuke any malloc'd zipfn... */
+#ifdef USE_STRM_INPUT
+ FILE *zipfd; /* zipfile file descriptor */
+#else
+ int zipfd; /* zipfile file handle */
+#endif
+ Z_OFF_T ziplen;
+ Z_OFF_T cur_zipfile_bufstart; /* extract_or_test, readbuf, ReadByte */
+ Z_OFF_T extra_bytes; /* used in unzip.c, misc.c */
+ uch *extra_field; /* Unix, VMS, Mac, OS/2, Acorn, ... */
+ uch *hold;
+
+ local_file_hdr lrec; /* used in unzip.c, extract.c */
+ cdir_file_hdr crec; /* used in unzip.c, extract.c, misc.c */
+ ecdir_rec ecrec; /* used in unzip.c, extract.c */
+ struct stat statbuf; /* used by main, mapname, check_for_newer */
+
+ int mem_mode;
+ uch *outbufptr; /* extract.c static */
+ ulg outsize; /* extract.c static */
+ int reported_backslash; /* extract.c static */
+ int disk_full;
+ int newfile;
+
+ int didCRlast; /* fileio static */
+ ulg numlines; /* fileio static: number of lines printed */
+ int sol; /* fileio static: at start of line */
+ int no_ecrec; /* process static */
+#ifdef SYMLINKS
+ int symlnk;
+ slinkentry *slink_head; /* pointer to head of symlinks list */
+ slinkentry *slink_last; /* pointer to last entry in symlinks list */
+#endif
+#ifdef NOVELL_BUG_FAILSAFE
+ int dne; /* true if stat() says file doesn't exist */
+#endif
+
+ FILE *outfile;
+ uch *outbuf;
+ uch *realbuf;
+
+#ifndef VMS /* if SMALL_MEM, outbuf2 is initialized in */
+ uch *outbuf2; /* process_zipfiles() (never changes); */
+#endif /* else malloc'd ONLY if unshrink and -a */
+#endif /* !FUNZIP */
+ uch *outptr;
+ ulg outcnt; /* number of chars stored in outbuf */
+#ifndef FUNZIP
+ char filename[FILNAMSIZ]; /* also used by NT for temporary SFX path */
+
+#ifdef CMS_MVS
+ char *tempfn; /* temp file used; erase on close */
+#endif
+
+ char *key; /* crypt static: decryption password or NULL */
+ int nopwd; /* crypt static */
+#endif /* !FUNZIP */
+ ulg keys[3]; /* crypt static: keys defining pseudo-random sequence */
+
+#if (!defined(DOS_FLX_H68_NLM_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
+#if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
+ int echofd; /* ttyio static: file descriptor whose echo is off */
+#endif /* !(MACOS || ATARI || VMS) */
+#endif /* !(DOS_FLX_H68_NLM_OS2_W32 || AMIGA || RISCOS) */
+
+ unsigned hufts; /* track memory usage */
+
+#ifdef USE_ZLIB
+ int inflInit; /* inflate static: zlib inflate() initialized */
+ z_stream dstrm; /* inflate global: decompression stream */
+#else
+ struct huft *fixed_tl; /* inflate static */
+ struct huft *fixed_td; /* inflate static */
+ unsigned fixed_bl, fixed_bd; /* inflate static */
+#ifdef USE_DEFLATE64
+ struct huft *fixed_tl64; /* inflate static */
+ struct huft *fixed_td64; /* inflate static */
+ unsigned fixed_bl64, fixed_bd64; /* inflate static */
+ struct huft *fixed_tl32; /* inflate static */
+ struct huft *fixed_td32; /* inflate static */
+ unsigned fixed_bl32, fixed_bd32; /* inflate static */
+ ZCONST ush *cplens; /* inflate static */
+ ZCONST uch *cplext; /* inflate static */
+ ZCONST uch *cpdext; /* inflate static */
+#endif
+ unsigned wp; /* inflate static: current position in slide */
+ ulg bb; /* inflate static: bit buffer */
+ unsigned bk; /* inflate static: bits count in bit buffer */
+#endif /* ?USE_ZLIB */
+
+#ifndef FUNZIP
+#ifdef SMALL_MEM
+ char rgchBigBuffer[512];
+ char rgchSmallBuffer[96];
+ char rgchSmallBuffer2[160]; /* boosted to 160 for local3[] in unzip.c */
+#endif
+
+ MsgFn *message;
+ InputFn *input;
+ PauseFn *mpause;
+ PasswdFn *decr_passwd;
+ StatCBFn *statreportcb;
+#ifdef WINDLL
+ LPUSERFUNCTIONS lpUserFunctions;
+#endif
+
+ int incnt_leftover; /* so improved NEXTBYTE does not waste input */
+ uch *inptr_leftover;
+
+#ifdef VMS_TEXT_CONV
+ unsigned VMS_line_length; /* so native VMS variable-length text files */
+ int VMS_line_state; /* are readable on other platforms */
+ int VMS_line_pad;
+#endif
+
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+ char autorun_command[FILNAMSIZ];
+#endif
+#endif /* !FUNZIP */
+
+#ifdef SYSTEM_SPECIFIC_GLOBALS
+ SYSTEM_SPECIFIC_GLOBALS
+#endif
+
+} Uz_Globs; /* end of struct Globals */
+
+
+/***************************************************************************/
+
+
+#ifdef FUNZIP
+# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
+ extern ZCONST ulg near crc_32_tab[256];
+# else
+ extern ZCONST ulg Far *crc_32_tab;
+# endif
+# define CRC_32_TAB crc_32_tab
+#else
+# define CRC_32_TAB G.crc_32_tab
+#endif
+
+
+Uz_Globs *globalsCtor OF((void));
+
+/* pseudo constant sigs; they are initialized at runtime so unzip executable
+ * won't look like a zipfile
+ */
+extern char local_hdr_sig[4];
+extern char central_hdr_sig[4];
+extern char end_central_sig[4];
+/* extern char extd_local_sig[4]; NOT USED YET */
+
+#ifdef REENTRANT
+# define G (*(Uz_Globs *)pG)
+# define __G pG
+# define __G__ pG,
+# define __GPRO Uz_Globs *pG
+# define __GPRO__ Uz_Globs *pG,
+# define __GDEF Uz_Globs *pG;
+# ifdef USETHREADID
+ extern int lastScan;
+ void deregisterGlobalPointer OF((__GPRO));
+ Uz_Globs *getGlobalPointer OF((void));
+# define GETGLOBALS() Uz_Globs *pG = getGlobalPointer()
+# define DESTROYGLOBALS() do {free_G_buffers(pG); \
+ deregisterGlobalPointer(pG);} while (0)
+# else
+ extern Uz_Globs *GG;
+# define GETGLOBALS() Uz_Globs *pG = GG
+# define DESTROYGLOBALS() do {free_G_buffers(pG); free(pG);} while (0)
+# endif /* ?USETHREADID */
+# define CONSTRUCTGLOBALS() Uz_Globs *pG = globalsCtor()
+#else /* !REENTRANT */
+ extern Uz_Globs G;
+# define __G
+# define __G__
+# define __GPRO void
+# define __GPRO__
+# define __GDEF
+# define GETGLOBALS()
+# define CONSTRUCTGLOBALS() globalsCtor()
+# define DESTROYGLOBALS()
+#endif /* ?REENTRANT */
+
+#define uO G.UzO
+
+#endif /* __globals_h */
Property changes on: trunk/build/install/installer/globals.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/gui.c
===================================================================
--- trunk/build/install/installer/gui.c (rev 0)
+++ trunk/build/install/installer/gui.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,241 @@
+/*
+ * SINSTALL - JBoss Installer
+ *
+ * Copyright(c) 2007 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#include "sinstall.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+HICON gui_h16Icon = NULL;
+HICON gui_h32Icon = NULL;
+HICON gui_h48Icon = NULL;
+HMODULE gui_hMSHTML = NULL;
+static HINSTANCE gui_hInstance = NULL;
+static HWND gui_hMainWnd = NULL;
+static HMODULE gui_hRichedit = NULL;
+
+static UINT gui_ucNumLines = 3;
+static CHAR gui_szWndClass[MAX_PATH];
+
+BOOL
+GuiInitialize()
+{
+ INITCOMMONCONTROLSEX stCmn;
+
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ gui_hInstance = GetModuleHandle(NULL);
+ stCmn.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ stCmn.dwICC = ICC_WIN95_CLASSES | ICC_USEREX_CLASSES |
+ ICC_COOL_CLASSES | ICC_NATIVEFNTCTL_CLASS |
+ ICC_INTERNET_CLASSES | ICC_PAGESCROLLER_CLASS |
+ ICC_BAR_CLASSES;
+
+ InitCommonControlsEx(&stCmn);
+ gui_hRichedit = LoadLibraryA("RICHED32.DLL");
+ gui_hMSHTML = LoadLibraryA("MSHTML.DLL");
+
+ gui_h16Icon = LoadImage(gui_hInstance, MAKEINTRESOURCE(IDI_MAINICON),
+ IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ gui_h32Icon = LoadImage(gui_hInstance, MAKEINTRESOURCE(IDI_MAINICON),
+ IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
+ gui_h48Icon = LoadImage(gui_hInstance, MAKEINTRESOURCE(IDI_RHELICON),
+ IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
+
+ SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
+ &gui_ucNumLines, 0);
+ return TRUE;
+}
+
+BOOL
+GuiTerminate()
+{
+ FreeLibrary(gui_hRichedit);
+ FreeLibrary(gui_hMSHTML);
+
+ return TRUE;
+}
+
+/**
+ * Load the resource string with the ID given, and return a
+ * pointer to it. Notice that the buffer is common memory so
+ * the string must be used before this call is made a second time.
+ */
+LPSTR
+GuiLoadResource(
+ UINT wID,
+ UINT nBuf)
+{
+ static CHAR szBuf[4][SIZ_BUFLEN];
+ if (nBuf > 3)
+ return "";
+ if (LoadStringA(gui_hInstance, wID, szBuf[nBuf], SIZ_BUFMAX) > 0)
+ return szBuf[nBuf];
+ else
+ return "";
+}
+
+void
+GuiCenterWindow(HWND hWnd)
+{
+ RECT rc, rw;
+ int cw, ch;
+ int px, py;
+
+ /* Get the Height and Width of the child window */
+ GetWindowRect(hWnd, &rc);
+ cw = rc.right - rc.left;
+ ch = rc.bottom - rc.top;
+
+ /* Get the limits of the 'workarea' */
+ if (!SystemParametersInfo(SPI_GETWORKAREA,
+ sizeof(RECT),
+ &rw,
+ 0)) {
+ rw.left = rw.top = 0;
+ rw.right = GetSystemMetrics(SM_CXSCREEN);
+ rw.bottom = GetSystemMetrics(SM_CYSCREEN);
+ }
+
+ /* Calculate new X and Y position*/
+ px = (rw.right - cw) / 2;
+ py = (rw.bottom - ch) / 2;
+ SetWindowPos(hWnd, HWND_TOP, px, py, 0, 0,
+ SWP_NOSIZE | SWP_SHOWWINDOW);
+}
+
+BOOL
+GuiBrowseForFolder(
+ HWND hWnd,
+ LPCSTR szTitle,
+ LPSTR szPath)
+{
+ BOOL rv = FALSE;
+
+ BROWSEINFO bi;
+ ITEMIDLIST *il , *ir;
+ LPMALLOC pMalloc;
+
+ memset(&bi, 0, sizeof(BROWSEINFO));
+ SHGetSpecialFolderLocation(hWnd, CSIDL_DRIVES, &il);
+
+ bi.lpszTitle = szTitle;
+ bi.pszDisplayName = szPath;
+ bi.hwndOwner = hWnd;
+ bi.ulFlags = BIF_USENEWUI;
+ bi.pidlRoot = il;
+
+ if ((ir = SHBrowseForFolder(&bi)) != NULL) {
+ SHGetPathFromIDList(ir, szPath);
+ rv = TRUE;
+ }
+ if (SHGetMalloc(&pMalloc)) {
+ pMalloc->lpVtbl->Free(pMalloc, il);
+ pMalloc->lpVtbl->Release(pMalloc);
+ }
+ return rv;
+}
+
+static void
+guiShellAbout(HWND hWnd)
+{
+ CHAR szApplication[512];
+
+ sprintf(szApplication , "About - %s#Windows",
+ GuiLoadResource(IDS_APPLICATION, 0));
+ ShellAboutA(hWnd, szApplication,
+ GuiLoadResource(IDS_APPDESCRIPTION, 1),
+ gui_h48Icon);
+}
+
+
+static LRESULT CALLBACK
+guiAboutDlgProc(
+ HWND hDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ static HWND hRich = NULL;
+ static POINT ptScroll;
+ HRSRC hRsrc;
+ HGLOBAL hGlob;
+ LPSTR szTxt;
+
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ GuiCenterWindow(hDlg);
+ hRich = GetDlgItem(hDlg, IDC_LICENSE);
+ hRsrc = FindResourceA(GetModuleHandleA(NULL),
+ MAKEINTRESOURCE(IDR_LICENSE), "RTF");
+ hGlob = LoadResource(GetModuleHandleA(NULL), hRsrc);
+ szTxt = (LPSTR)LockResource(hGlob);
+
+ SendMessageA(hRich, WM_SETTEXT, 0, (LPARAM)szTxt);
+ SetDlgItemText(hDlg, IDC_ABOUTAPP,
+ GuiLoadResource(IDS_APPFULLNAME, 0));
+ ptScroll.x = 0;
+ ptScroll.y = 0;
+ return TRUE;
+ break;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
+ EndDialog(hDlg, LOWORD(wParam));
+ return TRUE;
+ }
+ else if (LOWORD(wParam) == IAB_SYSINF)
+ guiShellAbout(hDlg);
+ break;
+ case WM_MOUSEWHEEL:
+ {
+ int nScroll, nLines;
+ if ((SHORT)HIWORD(wParam) < 0)
+ nScroll = gui_ucNumLines;
+ else
+ nScroll = gui_ucNumLines * (-1);
+ ptScroll.y += (nScroll * 11);
+ if (ptScroll.y < 0)
+ ptScroll.y = 0;
+ nLines = (int)SendMessage(hRich, EM_GETLINECOUNT,
+ 0, 0) + 1;
+ if (ptScroll.y / 11 > nLines)
+ ptScroll.y = nLines * 11;
+ SendMessage(hRich, EM_SETSCROLLPOS, 0, (LPARAM)&ptScroll);
+ }
+ break;
+
+ }
+ return FALSE;
+}
+
+void
+GuiAboutBox(HWND hWnd)
+{
+ DialogBox(gui_hInstance,
+ MAKEINTRESOURCE(IDD_ABOUTBOX),
+ hWnd,
+ (DLGPROC)guiAboutDlgProc);
+}
+
Property changes on: trunk/build/install/installer/gui.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/inflate.c
===================================================================
--- trunk/build/install/installer/inflate.c (rev 0)
+++ trunk/build/install/installer/inflate.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,1548 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* inflate.c -- by Mark Adler
+ version c17a, 04 Feb 2001 */
+
+
+/* Copyright history:
+ - Starting with UnZip 5.41 of 16-April-2000, this source file
+ is covered by the Info-Zip LICENSE cited above.
+ - Prior versions of this source file, found in UnZip source packages
+ up to UnZip 5.40, were put in the public domain.
+ The original copyright note by Mark Adler was:
+ "You can do whatever you like with this source file,
+ though I would prefer that if you modify it and
+ redistribute it that you include comments to that effect
+ with your name and the date. Thank you."
+
+ History:
+ vers date who what
+ ---- --------- -------------- ------------------------------------
+ a ~~ Feb 92 M. Adler used full (large, one-step) lookup table
+ b1 21 Mar 92 M. Adler first version with partial lookup tables
+ b2 21 Mar 92 M. Adler fixed bug in fixed-code blocks
+ b3 22 Mar 92 M. Adler sped up match copies, cleaned up some
+ b4 25 Mar 92 M. Adler added prototypes; removed window[] (now
+ is the responsibility of unzip.h--also
+ changed name to slide[]), so needs diffs
+ for unzip.c and unzip.h (this allows
+ compiling in the small model on MSDOS);
+ fixed cast of q in huft_build();
+ b5 26 Mar 92 M. Adler got rid of unintended macro recursion.
+ b6 27 Mar 92 M. Adler got rid of nextbyte() routine. fixed
+ bug in inflate_fixed().
+ c1 30 Mar 92 M. Adler removed lbits, dbits environment variables.
+ changed BMAX to 16 for explode. Removed
+ OUTB usage, and replaced it with flush()--
+ this was a 20% speed improvement! Added
+ an explode.c (to replace unimplod.c) that
+ uses the huft routines here. Removed
+ register union.
+ c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k.
+ c3 10 Apr 92 M. Adler reduced memory of code tables made by
+ huft_build significantly (factor of two to
+ three).
+ c4 15 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy().
+ worked around a Turbo C optimization bug.
+ c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing
+ the 32K window size for specialized
+ applications.
+ c6 31 May 92 M. Adler added some typecasts to eliminate warnings
+ c7 27 Jun 92 G. Roelofs added some more typecasts (444: MSC bug).
+ c8 5 Oct 92 J-l. Gailly added ifdef'd code to deal with PKZIP bug.
+ c9 9 Oct 92 M. Adler removed a memory error message (~line 416).
+ c10 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch,
+ removed old inflate, renamed inflate_entry
+ to inflate, added Mark's fix to a comment.
+ c10.5 14 Dec 92 M. Adler fix up error messages for incomplete trees.
+ c11 2 Jan 93 M. Adler fixed bug in detection of incomplete
+ tables, and removed assumption that EOB is
+ the longest code (bad assumption).
+ c12 3 Jan 93 M. Adler make tables for fixed blocks only once.
+ c13 5 Jan 93 M. Adler allow all zero length codes (pkzip 2.04c
+ outputs one zero length code for an empty
+ distance tree).
+ c14 12 Mar 93 M. Adler made inflate.c standalone with the
+ introduction of inflate.h.
+ c14b 16 Jul 93 G. Roelofs added (unsigned) typecast to w at 470.
+ c14c 19 Jul 93 J. Bush changed v[N_MAX], l[288], ll[28x+3x] arrays
+ to static for Amiga.
+ c14d 13 Aug 93 J-l. Gailly de-complicatified Mark's c[*p++]++ thing.
+ c14e 8 Oct 93 G. Roelofs changed memset() to memzero().
+ c14f 22 Oct 93 G. Roelofs renamed quietflg to qflag; made Trace()
+ conditional; added inflate_free().
+ c14g 28 Oct 93 G. Roelofs changed l/(lx+1) macro to pointer (Cray bug)
+ c14h 7 Dec 93 C. Ghisler huft_build() optimizations.
+ c14i 9 Jan 94 A. Verheijen set fixed_t{d,l} to NULL after freeing;
+ G. Roelofs check NEXTBYTE macro for EOF.
+ c14j 23 Jan 94 G. Roelofs removed Ghisler "optimizations"; ifdef'd
+ EOF check.
+ c14k 27 Feb 94 G. Roelofs added some typecasts to avoid warnings.
+ c14l 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines
+ to avoid bug in Encore compiler.
+ c14m 7 Jul 94 P. Kienitz modified to allow assembler version of
+ inflate_codes() (define ASM_INFLATECODES)
+ c14n 22 Jul 94 G. Roelofs changed fprintf to macro for DLL versions
+ c14o 23 Aug 94 C. Spieler added a newline to a debug statement;
+ G. Roelofs added another typecast to avoid MSC warning
+ c14p 4 Oct 94 G. Roelofs added (voidp *) cast to free() argument
+ c14q 30 Oct 94 G. Roelofs changed fprintf macro to MESSAGE()
+ c14r 1 Nov 94 G. Roelofs fixed possible redefinition of CHECK_EOF
+ c14s 7 May 95 S. Maxwell OS/2 DLL globals stuff incorporated;
+ P. Kienitz "fixed" ASM_INFLATECODES macro/prototype
+ c14t 18 Aug 95 G. Roelofs added UZinflate() to use zlib functions;
+ changed voidp to zvoid; moved huft_build()
+ and huft_free() to end of file
+ c14u 1 Oct 95 G. Roelofs moved G into definition of MESSAGE macro
+ c14v 8 Nov 95 P. Kienitz changed ASM_INFLATECODES to use a regular
+ call with __G__ instead of a macro
+ c15 3 Aug 96 M. Adler fixed bomb-bug on random input data (Adobe)
+ c15b 24 Aug 96 M. Adler more fixes for random input data
+ c15c 28 Mar 97 G. Roelofs changed USE_ZLIB fatal exit code from
+ PK_MEM2 to PK_MEM3
+ c16 20 Apr 97 J. Altman added memzero(v[]) in huft_build()
+ c16b 29 Mar 98 C. Spieler modified DLL code for slide redirection
+ c16c 04 Apr 99 C. Spieler fixed memory leaks when processing gets
+ stopped because of input data errors
+ c16d 05 Jul 99 C. Spieler take care of FLUSH() return values and
+ stop processing in case of errors
+ c17 31 Dec 00 C. Spieler added preliminary support for Deflate64
+ c17a 04 Feb 01 C. Spieler complete integration of Deflate64 support
+ c17b 16 Feb 02 C. Spieler changed type of "extra bits" arrays and
+ corresponding huft_buid() parameter e from
+ ush into uch, to save space
+ c17c 9 Mar 02 C. Spieler fixed NEEDBITS() "read beyond EOF" problem
+ with CHECK_EOF enabled
+ */
+
+
+/*
+ Inflate deflated (PKZIP's method 8 compressed) data. The compression
+ method searches for as much of the current string of bytes (up to a
+ length of 258) in the previous 32K bytes. If it doesn't find any
+ matches (of at least length 3), it codes the next byte. Otherwise, it
+ codes the length of the matched string and its distance backwards from
+ the current position. There is a single Huffman code that codes both
+ single bytes (called "literals") and match lengths. A second Huffman
+ code codes the distance information, which follows a length code. Each
+ length or distance code actually represents a base value and a number
+ of "extra" (sometimes zero) bits to get to add to the base value. At
+ the end of each deflated block is a special end-of-block (EOB) literal/
+ length code. The decoding process is basically: get a literal/length
+ code; if EOB then done; if a literal, emit the decoded byte; if a
+ length then get the distance and emit the referred-to bytes from the
+ sliding window of previously emitted data.
+
+ There are (currently) three kinds of inflate blocks: stored, fixed, and
+ dynamic. The compressor outputs a chunk of data at a time and decides
+ which method to use on a chunk-by-chunk basis. A chunk might typically
+ be 32K to 64K, uncompressed. If the chunk is uncompressible, then the
+ "stored" method is used. In this case, the bytes are simply stored as
+ is, eight bits per byte, with none of the above coding. The bytes are
+ preceded by a count, since there is no longer an EOB code.
+
+ If the data are compressible, then either the fixed or dynamic methods
+ are used. In the dynamic method, the compressed data are preceded by
+ an encoding of the literal/length and distance Huffman codes that are
+ to be used to decode this block. The representation is itself Huffman
+ coded, and so is preceded by a description of that code. These code
+ descriptions take up a little space, and so for small blocks, there is
+ a predefined set of codes, called the fixed codes. The fixed method is
+ used if the block ends up smaller that way (usually for quite small
+ chunks); otherwise the dynamic method is used. In the latter case, the
+ codes are customized to the probabilities in the current block and so
+ can code it much better than the pre-determined fixed codes can.
+
+ The Huffman codes themselves are decoded using a multi-level table
+ lookup, in order to maximize the speed of decoding plus the speed of
+ building the decoding tables. See the comments below that precede the
+ lbits and dbits tuning parameters.
+
+ GRR: return values(?)
+ 0 OK
+ 1 incomplete table
+ 2 bad input
+ 3 not enough memory
+ the following return codes are passed through from FLUSH() errors
+ 50 (PK_DISK) "overflow of output space"
+ 80 (IZ_CTRLC) "canceled by user's request"
+ */
+
+
+/*
+ Notes beyond the 1.93a appnote.txt:
+
+ 1. Distance pointers never point before the beginning of the output
+ stream.
+ 2. Distance pointers can point back across blocks, up to 32k away.
+ 3. There is an implied maximum of 7 bits for the bit length table and
+ 15 bits for the actual data.
+ 4. If only one code exists, then it is encoded using one bit. (Zero
+ would be more efficient, but perhaps a little confusing.) If two
+ codes exist, they are coded using one bit each (0 and 1).
+ 5. There is no way of sending zero distance codes--a dummy must be
+ sent if there are none. (History: a pre 2.0 version of PKZIP would
+ store blocks with no distance codes, but this was discovered to be
+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
+ zero distance codes, which is sent as one code of zero bits in
+ length.
+ 6. There are up to 286 literal/length codes. Code 256 represents the
+ end-of-block. Note however that the static length tree defines
+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
+ cannot be used though, since there is no length base or extra bits
+ defined for them. Similarily, there are up to 30 distance codes.
+ However, static trees define 32 codes (all 5 bits) to fill out the
+ Huffman codes, but the last two had better not show up in the data.
+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
+ The exception is that a single code would not be complete (see #4).
+ 8. The five bits following the block type is really the number of
+ literal codes sent minus 257.
+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+ (1+6+6). Therefore, to output three times the length, you output
+ three codes (1+1+1), whereas to output four times the same length,
+ you only need two codes (1+3). Hmm.
+ 10. In the tree reconstruction algorithm, Code = Code + Increment
+ only if BitLength(i) is not zero. (Pretty obvious.)
+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
+ 12. Note: length code 284 can represent 227-258, but length code 285
+ really is 258. The last length deserves its own, short code
+ since it gets used a lot in very redundant files. The length
+ 258 is special since 258 - 3 (the min match length) is 255.
+ 13. The literal/length and distance code bit lengths are read as a
+ single stream of lengths. It is possible (and advantageous) for
+ a repeat code (16, 17, or 18) to go across the boundary between
+ the two sets of lengths.
+ 14. The Deflate64 (PKZIP method 9) variant of the compression algorithm
+ differs from "classic" deflate in the following 3 aspect:
+ a) The size of the sliding history window is expanded to 64 kByte.
+ b) The previously unused distance codes #30 and #31 code distances
+ from 32769 to 49152 and 49153 to 65536. Both codes take 14 bits
+ of extra data to determine the exact position in their 16 kByte
+ range.
+ c) The last lit/length code #285 gets a different meaning. Instead
+ of coding a fixed maximum match length of 258, it is used as a
+ "generic" match length code, capable of coding any length from
+ 3 (min match length + 0) to 65538 (min match length + 65535).
+ This means that the length code #285 takes 16 bits (!) of uncoded
+ extra data, added to a fixed min length of 3.
+ Changes a) and b) would have been transparent for valid deflated
+ data, but change c) requires to switch decoder configurations between
+ Deflate and Deflate64 modes.
+ */
+
+
+#define PKZIP_BUG_WORKAROUND /* PKZIP 1.93a problem--live with it */
+
+/*
+ inflate.h must supply the uch slide[WSIZE] array, the zvoid typedef
+ (void if (void *) is accepted, else char) and the NEXTBYTE,
+ FLUSH() and memzero macros. If the window size is not 32K, it
+ should also define WSIZE. If INFMOD is defined, it can include
+ compiled functions to support the NEXTBYTE and/or FLUSH() macros.
+ There are defaults for NEXTBYTE and FLUSH() below for use as
+ examples of what those functions need to do. Normally, you would
+ also want FLUSH() to compute a crc on the data. inflate.h also
+ needs to provide these typedefs:
+
+ typedef unsigned char uch;
+ typedef unsigned short ush;
+ typedef unsigned long ulg;
+
+ This module uses the external functions malloc() and free() (and
+ probably memset() or bzero() in the memzero() macro). Their
+ prototypes are normally found in <string.h> and <stdlib.h>.
+ */
+
+#define __INFLATE_C /* identifies this source module */
+
+/* #define DEBUG */
+#define INFMOD /* tell inflate.h to include code to be compiled */
+#include "inflate.h"
+
+
+/* marker for "unused" huft code, and corresponding check macro */
+#define INVALID_CODE 99
+#define IS_INVALID_CODE(c) ((c) == INVALID_CODE)
+
+#ifndef WSIZE /* default is 32K resp. 64K */
+# ifdef USE_DEFLATE64
+# define WSIZE 65536L /* window size--must be a power of two, and */
+# else /* at least 64K for PKZip's deflate64 method */
+# define WSIZE 0x8000 /* window size--must be a power of two, and */
+# endif /* at least 32K for zip's deflate method */
+#endif
+
+/* some buffer counters must be capable of holding 64k for Deflate64 */
+#if (defined(USE_DEFLATE64) && defined(INT_16BIT))
+# define UINT_D64 ulg
+#else
+# define UINT_D64 unsigned
+#endif
+
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+# define wsize G._wsize /* wsize is a variable */
+#else
+# define wsize WSIZE /* wsize is a constant */
+#endif
+
+
+#ifndef NEXTBYTE /* default is to simply get a byte from stdin */
+# define NEXTBYTE getchar()
+#endif
+
+#ifndef MESSAGE /* only used twice, for fixed strings--NOT general-purpose */
+# define MESSAGE(str,len,flag) fprintf(stderr,(char *)(str))
+#endif
+
+#ifndef FLUSH /* default is to simply write the buffer to stdout */
+# define FLUSH(n) \
+ (((extent)fwrite(redirSlide, 1, (extent)(n), stdout) == (extent)(n)) ? \
+ 0 : PKDISK)
+#endif
+/* Warning: the fwrite above might not work on 16-bit compilers, since
+ 0x8000 might be interpreted as -32,768 by the library function. When
+ support for Deflate64 is enabled, the window size is 64K and the
+ simple fwrite statement is definitely broken for 16-bit compilers. */
+
+#ifndef Trace
+# ifdef DEBUG
+# define Trace(x) fprintf x
+# else
+# define Trace(x)
+# endif
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+#ifdef USE_ZLIB
+
+
+/*
+ GRR: return values for both original inflate() and UZinflate()
+ 0 OK
+ 1 incomplete table(?)
+ 2 bad input
+ 3 not enough memory
+ */
+
+/**************************/
+/* Function UZinflate() */
+/**************************/
+
+int UZinflate(__G__ is_defl64)
+ __GDEF
+ int is_defl64;
+/* decompress an inflated entry using the zlib routines */
+{
+ int retval = 0; /* return code: 0 = "no error" */
+ int err=Z_OK;
+ int repeated_buf_err;
+
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+ if (G.redirect_slide)
+ wsize = G.redirect_size, redirSlide = G.redirect_buffer;
+ else
+ wsize = WSIZE, redirSlide = slide;
+#endif
+
+ G.dstrm.next_out = redirSlide;
+ G.dstrm.avail_out = wsize;
+
+ G.dstrm.next_in = G.inptr;
+ G.dstrm.avail_in = G.incnt;
+
+ if (!G.inflInit) {
+ unsigned i;
+ int windowBits;
+ /* local buffer for efficiency */
+ ZCONST char *zlib_RtVersion = zlibVersion();
+
+ /* only need to test this stuff once */
+ if (zlib_RtVersion[0] != ZLIB_VERSION[0]) {
+ Info(slide, 0x21, ((char *)slide,
+ "error: incompatible zlib version (expected %s, found %s)\n",
+ ZLIB_VERSION, zlib_RtVersion));
+ return 3;
+ } else if (strcmp(zlib_RtVersion, ZLIB_VERSION) != 0)
+ Info(slide, 0x21, ((char *)slide,
+ "warning: different zlib version (expected %s, using %s)\n",
+ ZLIB_VERSION, zlib_RtVersion));
+
+ /* windowBits = log2(wsize) */
+ for (i = (unsigned)wsize, windowBits = 0;
+ !(i & 1); i >>= 1, ++windowBits);
+ if ((unsigned)windowBits > (unsigned)15)
+ windowBits = 15;
+ else if (windowBits < 8)
+ windowBits = 8;
+
+ G.dstrm.zalloc = (alloc_func)Z_NULL;
+ G.dstrm.zfree = (free_func)Z_NULL;
+
+ Trace((stderr, "initializing inflate()\n"));
+ err = inflateInit2(&G.dstrm, -windowBits);
+
+ if (err == Z_MEM_ERROR)
+ return 3;
+ else if (err != Z_OK)
+ Trace((stderr, "oops! (inflateInit2() err = %d)\n", err));
+ G.inflInit = 1;
+ }
+
+#ifdef FUNZIP
+ while (err != Z_STREAM_END) {
+#else /* !FUNZIP */
+ while (G.csize > 0) {
+ Trace((stderr, "first loop: G.csize = %ld\n", G.csize));
+#endif /* ?FUNZIP */
+ while (G.dstrm.avail_out > 0) {
+ err = inflate(&G.dstrm, Z_PARTIAL_FLUSH);
+
+ if (err == Z_DATA_ERROR) {
+ retval = 2; goto uzinflate_cleanup_exit;
+ } else if (err == Z_MEM_ERROR) {
+ retval = 3; goto uzinflate_cleanup_exit;
+ } else if (err != Z_OK && err != Z_STREAM_END)
+ Trace((stderr, "oops! (inflate(first loop) err = %d)\n", err));
+
+#ifdef FUNZIP
+ if (err == Z_STREAM_END) /* "END-of-entry-condition" ? */
+#else /* !FUNZIP */
+ if (G.csize <= 0L) /* "END-of-entry-condition" ? */
+#endif /* ?FUNZIP */
+ break;
+
+ if (G.dstrm.avail_in == 0) {
+ if (fillinbuf(__G) == 0) {
+ /* no "END-condition" yet, but no more data */
+ retval = 2; goto uzinflate_cleanup_exit;
+ }
+
+ G.dstrm.next_in = G.inptr;
+ G.dstrm.avail_in = G.incnt;
+ }
+ Trace((stderr, " avail_in = %u\n", G.dstrm.avail_in));
+ }
+ /* flush slide[] */
+ if ((retval = FLUSH(wsize - G.dstrm.avail_out)) != 0)
+ goto uzinflate_cleanup_exit;
+ Trace((stderr, "inside loop: flushing %ld bytes (ptr diff = %ld)\n",
+ (long)(wsize - G.dstrm.avail_out),
+ (long)(G.dstrm.next_out-(Bytef *)redirSlide)));
+ G.dstrm.next_out = redirSlide;
+ G.dstrm.avail_out = wsize;
+ }
+
+ /* no more input, so loop until we have all output */
+ Trace((stderr, "beginning final loop: err = %d\n", err));
+ repeated_buf_err = FALSE;
+ while (err != Z_STREAM_END) {
+ err = inflate(&G.dstrm, Z_PARTIAL_FLUSH);
+ if (err == Z_DATA_ERROR) {
+ retval = 2; goto uzinflate_cleanup_exit;
+ } else if (err == Z_MEM_ERROR) {
+ retval = 3; goto uzinflate_cleanup_exit;
+ } else if (err == Z_BUF_ERROR) { /* DEBUG */
+#ifdef FUNZIP
+ Trace((stderr,
+ "zlib inflate() did not detect stream end\n"));
+#else
+ Trace((stderr,
+ "zlib inflate() did not detect stream end (%s, %s)\n",
+ G.zipfn, G.filename));
+#endif
+ if ((!repeated_buf_err) && (G.dstrm.avail_in == 0)) {
+ /* when detecting this problem for the first time,
+ try to provide one fake byte beyond "EOF"... */
+ G.dstrm.next_in = "";
+ G.dstrm.avail_in = 1;
+ repeated_buf_err = TRUE;
+ } else
+ break;
+ } else if (err != Z_OK && err != Z_STREAM_END) {
+ Trace((stderr, "oops! (inflate(final loop) err = %d)\n", err));
+ DESTROYGLOBALS();
+ EXIT(PK_MEM3);
+ }
+ /* final flush of slide[] */
+ if ((retval = FLUSH(wsize - G.dstrm.avail_out)) != 0)
+ goto uzinflate_cleanup_exit;
+ Trace((stderr, "final loop: flushing %ld bytes (ptr diff = %ld)\n",
+ (long)(wsize - G.dstrm.avail_out),
+ (long)(G.dstrm.next_out-(Bytef *)redirSlide)));
+ G.dstrm.next_out = redirSlide;
+ G.dstrm.avail_out = wsize;
+ }
+ Trace((stderr, "total in = %lu, total out = %lu\n", G.dstrm.total_in,
+ G.dstrm.total_out));
+
+ G.inptr = (uch *)G.dstrm.next_in;
+ G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */
+
+uzinflate_cleanup_exit:
+ err = inflateReset(&G.dstrm);
+ if (err != Z_OK)
+ Trace((stderr, "oops! (inflateReset() err = %d)\n", err));
+
+ return retval;
+}
+
+
+/*---------------------------------------------------------------------------*/
+#else /* !USE_ZLIB */
+
+
+/* Function prototypes */
+#ifndef OF
+# ifdef __STDC__
+# define OF(a) a
+# else
+# define OF(a) ()
+# endif
+#endif /* !OF */
+int inflate_codes OF((__GPRO__ struct huft *tl, struct huft *td,
+ unsigned bl, unsigned bd));
+static int inflate_stored OF((__GPRO));
+static int inflate_fixed OF((__GPRO));
+static int inflate_dynamic OF((__GPRO));
+static int inflate_block OF((__GPRO__ int *e));
+
+
+/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
+ stream to find repeated byte strings. This is implemented here as a
+ circular buffer. The index is updated simply by incrementing and then
+ and'ing with 0x7fff (32K-1). */
+/* It is left to other modules to supply the 32K area. It is assumed
+ to be usable as if it were declared "uch slide[32768];" or as just
+ "uch *slide;" and then malloc'ed in the latter case. The definition
+ must be in unzip.h, included above. */
+
+
+/* unsigned wp; moved to globals.h */ /* current position in slide */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+/* - Order of the bit length code lengths */
+static ZCONST unsigned border[] = {
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/* - Copy lengths for literal codes 257..285 */
+#ifdef USE_DEFLATE64
+static ZCONST ush cplens64[] = {
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 3, 0, 0};
+ /* For Deflate64, the code 285 is defined differently. */
+#else
+# define cplens32 cplens
+#endif
+static ZCONST ush cplens32[] = {
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ /* note: see note #13 above about the 258 in this list. */
+/* - Extra bits for literal codes 257..285 */
+#ifdef USE_DEFLATE64
+static ZCONST uch cplext64[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, INVALID_CODE, INVALID_CODE};
+#else
+# define cplext32 cplext
+#endif
+static ZCONST uch cplext32[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, INVALID_CODE, INVALID_CODE};
+
+/* - Copy offsets for distance codes 0..29 (0..31 for Deflate64) */
+static ZCONST ush cpdist[] = {
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+#if (defined(USE_DEFLATE64) || defined(PKZIP_BUG_WORKAROUND))
+ 8193, 12289, 16385, 24577, 32769, 49153};
+#else
+ 8193, 12289, 16385, 24577};
+#endif
+
+/* - Extra bits for distance codes 0..29 (0..31 for Deflate64) */
+#ifdef USE_DEFLATE64
+static ZCONST uch cpdext64[] = {
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13, 14, 14};
+#else
+# define cpdext32 cpdext
+#endif
+static ZCONST uch cpdext32[] = {
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+#ifdef PKZIP_BUG_WORKAROUND
+ 12, 12, 13, 13, INVALID_CODE, INVALID_CODE};
+#else
+ 12, 12, 13, 13};
+#endif
+
+#ifdef PKZIP_BUG_WORKAROUND
+# define MAXLITLENS 288
+#else
+# define MAXLITLENS 286
+#endif
+#if (defined(USE_DEFLATE64) || defined(PKZIP_BUG_WORKAROUND))
+# define MAXDISTS 32
+#else
+# define MAXDISTS 30
+#endif
+
+
+/* moved to consts.h (included in unzip.c), resp. funzip.c */
+#if 0
+/* And'ing with mask_bits[n] masks the lower n bits */
+ZCONST unsigned near mask_bits[17] = {
+ 0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+#endif /* 0 */
+
+
+/* Macros for inflate() bit peeking and grabbing.
+ The usage is:
+
+ NEEDBITS(j)
+ x = b & mask_bits[j];
+ DUMPBITS(j)
+
+ where NEEDBITS makes sure that b has at least j bits in it, and
+ DUMPBITS removes the bits from b. The macros use the variable k
+ for the number of bits in b. Normally, b and k are register
+ variables for speed and are initialized at the beginning of a
+ routine that uses these macros from a global bit buffer and count.
+
+ In order to not ask for more bits than there are in the compressed
+ stream, the Huffman tables are constructed to only ask for just
+ enough bits to make up the end-of-block code (value 256). Then no
+ bytes need to be "returned" to the buffer at the end of the last
+ block. See the huft_build() routine.
+
+ Actually, the precautions mentioned above are not sufficient to
+ prevent fetches of bits beyound the end of the last block in every
+ case. When the last code fetched before the end-of-block code was
+ a very short distance code (shorter than "distance-prefetch-bits" -
+ "end-of-block code bits"), this last distance code fetch already
+ exausts the available data. To prevent failure of extraction in this
+ case, the "read beyond EOF" check delays the raise of the "invalid
+ data" error until an actual overflow of "used data" is detected.
+ This error condition is only fulfilled when the "number of available
+ bits" counter k is found to be negative in the NEEDBITS() macro.
+
+ An alternate fix for that problem adjusts the size of the distance code
+ base table so that it does not exceed the length of the end-of-block code
+ plus the minimum length of a distance code. This alternate fix can be
+ enabled by defining the preprocessor symbol FIX_PAST_EOB_BY_TABLEADJUST.
+ */
+
+/* These have been moved to globals.h */
+#if 0
+ulg bb; /* bit buffer */
+unsigned bk; /* bits in bit buffer */
+#endif
+
+#ifndef CHECK_EOF
+# define CHECK_EOF /* default as of 5.13/5.2 */
+#endif
+
+#ifndef CHECK_EOF
+# define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE)<<k;k+=8;}}
+#else
+# ifdef FIX_PAST_EOB_BY_TABLEADJUST
+# define NEEDBITS(n) {while(k<(n)){int c=NEXTBYTE;\
+ if(c==EOF){retval=1;goto cleanup_and_exit;}\
+ b|=((ulg)c)<<k;k+=8;}}
+# else
+# define NEEDBITS(n) {while((int)k<(int)(n)){int c=NEXTBYTE;\
+ if(c==EOF){if((int)k>=0)break;retval=1;goto cleanup_and_exit;}\
+ b|=((ulg)c)<<k;k+=8;}}
+# endif
+#endif
+
+#define DUMPBITS(n) {b>>=(n);k-=(n);}
+
+
+/*
+ Huffman code decoding is performed using a multi-level table lookup.
+ The fastest way to decode is to simply build a lookup table whose
+ size is determined by the longest code. However, the time it takes
+ to build this table can also be a factor if the data being decoded
+ are not very long. The most common codes are necessarily the
+ shortest codes, so those codes dominate the decoding time, and hence
+ the speed. The idea is you can have a shorter table that decodes the
+ shorter, more probable codes, and then point to subsidiary tables for
+ the longer codes. The time it costs to decode the longer codes is
+ then traded against the time it takes to make longer tables.
+
+ This results of this trade are in the variables lbits and dbits
+ below. lbits is the number of bits the first level table for literal/
+ length codes can decode in one step, and dbits is the same thing for
+ the distance codes. Subsequent tables are also less than or equal to
+ those sizes. These values may be adjusted either when all of the
+ codes are shorter than that, in which case the longest code length in
+ bits is used, or when the shortest code is *longer* than the requested
+ table size, in which case the length of the shortest code in bits is
+ used.
+
+ There are two different values for the two tables, since they code a
+ different number of possibilities each. The literal/length table
+ codes 286 possible values, or in a flat code, a little over eight
+ bits. The distance table codes 30 possible values, or a little less
+ than five bits, flat. The optimum values for speed end up being
+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+ The optimum values may differ though from machine to machine, and
+ possibly even between compilers. Your mileage may vary.
+ */
+
+
+/* bits in base literal/length lookup table */
+static ZCONST unsigned lbits = 9;
+/* bits in base distance lookup table */
+static ZCONST unsigned dbits = 6;
+
+
+#ifndef ASM_INFLATECODES
+
+int inflate_codes(__G__ tl, td, bl, bd)
+ __GDEF
+struct huft *tl, *td; /* literal/length and distance decoder tables */
+unsigned bl, bd; /* number of bits decoded by tl[] and td[] */
+/* inflate (decompress) the codes in a deflated (compressed) block.
+ Return an error code or zero if it all goes ok. */
+{
+ register unsigned e; /* table entry flag/number of extra bits */
+ unsigned d; /* index for copy */
+ UINT_D64 n; /* length for copy (deflate64: might be 64k+2) */
+ UINT_D64 w; /* current window position (deflate64: up to 64k) */
+ struct huft *t; /* pointer to table entry */
+ unsigned ml, md; /* masks for bl and bd bits */
+ register ulg b; /* bit buffer */
+ register unsigned k; /* number of bits in bit buffer */
+ int retval = 0; /* error code returned: initialized to "no error" */
+
+
+ /* make local copies of globals */
+ b = G.bb; /* initialize bit buffer */
+ k = G.bk;
+ w = G.wp; /* initialize window position */
+
+
+ /* inflate the coded data */
+ ml = mask_bits[bl]; /* precompute masks for speed */
+ md = mask_bits[bd];
+ while (1) /* do until end of block */
+ {
+ NEEDBITS(bl)
+ t = tl + ((unsigned)b & ml);
+ while (1) {
+ DUMPBITS(t->b)
+
+ if ((e = t->e) == 32) /* then it's a literal */
+ {
+ redirSlide[w++] = (uch)t->v.n;
+ if (w == wsize)
+ {
+ if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit;
+ w = 0;
+ }
+ break;
+ }
+
+ if (e < 31) /* then it's a length */
+ {
+ /* get length of block to copy */
+ NEEDBITS(e)
+ n = t->v.n + ((unsigned)b & mask_bits[e]);
+ DUMPBITS(e)
+
+ /* decode distance of block to copy */
+ NEEDBITS(bd)
+ t = td + ((unsigned)b & md);
+ while (1) {
+ DUMPBITS(t->b)
+ if ((e = t->e) < 32)
+ break;
+ if (IS_INVALID_CODE(e))
+ return 1;
+ e &= 31;
+ NEEDBITS(e)
+ t = t->v.t + ((unsigned)b & mask_bits[e]);
+ }
+ NEEDBITS(e)
+ d = (unsigned)w - t->v.n - ((unsigned)b & mask_bits[e]);
+ DUMPBITS(e)
+
+ /* do the copy */
+ do {
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+ if (G.redirect_slide) {
+ /* &= w/ wsize unnecessary & wrong if redirect */
+ if ((UINT_D64)d >= wsize)
+ return 1; /* invalid compressed data */
+ e = (unsigned)(wsize - (d > (unsigned)w ? (UINT_D64)d : w));
+ }
+ else
+#endif
+ e = (unsigned)(wsize -
+ ((d &= (unsigned)(wsize-1)) > (unsigned)w ?
+ (UINT_D64)d : w));
+ if ((UINT_D64)e > n) e = (unsigned)n;
+ n -= e;
+#ifndef NOMEMCPY
+ if ((unsigned)w - d >= e)
+ /* (this test assumes unsigned comparison) */
+ {
+ memcpy(redirSlide + (unsigned)w, redirSlide + d, e);
+ w += e;
+ d += e;
+ }
+ else /* do it slowly to avoid memcpy() overlap */
+#endif /* !NOMEMCPY */
+ do {
+ redirSlide[w++] = redirSlide[d++];
+ } while (--e);
+ if (w == wsize)
+ {
+ if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit;
+ w = 0;
+ }
+ } while (n);
+ break;
+ }
+
+ if (e == 31) /* it's the EOB signal */
+ {
+ /* sorry for this goto, but we have to exit two loops at once */
+ goto cleanup_decode;
+ }
+
+ if (IS_INVALID_CODE(e))
+ return 1;
+
+ e &= 31;
+ NEEDBITS(e)
+ t = t->v.t + ((unsigned)b & mask_bits[e]);
+ }
+ }
+cleanup_decode:
+
+ /* restore the globals from the locals */
+ G.wp = (unsigned)w; /* restore global window pointer */
+ G.bb = b; /* restore global bit buffer */
+ G.bk = k;
+
+
+cleanup_and_exit:
+ /* done */
+ return retval;
+}
+
+#endif /* ASM_INFLATECODES */
+
+
+
+static int inflate_stored(__G)
+ __GDEF
+/* "decompress" an inflated type 0 (stored) block. */
+{
+ UINT_D64 w; /* current window position (deflate64: up to 64k!) */
+ unsigned n; /* number of bytes in block */
+ register ulg b; /* bit buffer */
+ register unsigned k; /* number of bits in bit buffer */
+ int retval = 0; /* error code returned: initialized to "no error" */
+
+
+ /* make local copies of globals */
+ Trace((stderr, "\nstored block"));
+ b = G.bb; /* initialize bit buffer */
+ k = G.bk;
+ w = G.wp; /* initialize window position */
+
+
+ /* go to byte boundary */
+ n = k & 7;
+ DUMPBITS(n);
+
+
+ /* get the length and its complement */
+ NEEDBITS(16)
+ n = ((unsigned)b & 0xffff);
+ DUMPBITS(16)
+ NEEDBITS(16)
+ if (n != (unsigned)((~b) & 0xffff))
+ return 1; /* error in compressed data */
+ DUMPBITS(16)
+
+
+ /* read and output the compressed data */
+ while (n--)
+ {
+ NEEDBITS(8)
+ redirSlide[w++] = (uch)b;
+ if (w == wsize)
+ {
+ if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit;
+ w = 0;
+ }
+ DUMPBITS(8)
+ }
+
+
+ /* restore the globals from the locals */
+ G.wp = (unsigned)w; /* restore global window pointer */
+ G.bb = b; /* restore global bit buffer */
+ G.bk = k;
+
+cleanup_and_exit:
+ return retval;
+}
+
+
+/* Globals for literal tables (built once) */
+/* Moved to globals.h */
+#if 0
+struct huft *fixed_tl = (struct huft *)NULL;
+struct huft *fixed_td;
+int fixed_bl, fixed_bd;
+#endif
+
+static int inflate_fixed(__G)
+ __GDEF
+/* decompress an inflated type 1 (fixed Huffman codes) block. We should
+ either replace this with a custom decoder, or at least precompute the
+ Huffman tables. */
+{
+ /* if first time, set up tables for fixed blocks */
+ Trace((stderr, "\nliteral block"));
+ if (G.fixed_tl == (struct huft *)NULL)
+ {
+ int i; /* temporary variable */
+ unsigned l[288]; /* length list for huft_build */
+
+ /* literal table */
+ for (i = 0; i < 144; i++)
+ l[i] = 8;
+ for (; i < 256; i++)
+ l[i] = 9;
+ for (; i < 280; i++)
+ l[i] = 7;
+ for (; i < 288; i++) /* make a complete, but wrong code set */
+ l[i] = 8;
+ G.fixed_bl = 7;
+#ifdef USE_DEFLATE64
+ if ((i = huft_build(__G__ l, 288, 257, G.cplens, G.cplext,
+ &G.fixed_tl, &G.fixed_bl)) != 0)
+#else
+ if ((i = huft_build(__G__ l, 288, 257, cplens, cplext,
+ &G.fixed_tl, &G.fixed_bl)) != 0)
+#endif
+ {
+ G.fixed_tl = (struct huft *)NULL;
+ return i;
+ }
+
+ /* distance table */
+ for (i = 0; i < MAXDISTS; i++) /* make an incomplete code set */
+ l[i] = 5;
+ G.fixed_bd = 5;
+#ifdef USE_DEFLATE64
+ if ((i = huft_build(__G__ l, MAXDISTS, 0, cpdist, G.cpdext,
+ &G.fixed_td, &G.fixed_bd)) > 1)
+#else
+ if ((i = huft_build(__G__ l, MAXDISTS, 0, cpdist, cpdext,
+ &G.fixed_td, &G.fixed_bd)) > 1)
+#endif
+ {
+ huft_free(G.fixed_tl);
+ G.fixed_td = G.fixed_tl = (struct huft *)NULL;
+ return i;
+ }
+ }
+
+ /* decompress until an end-of-block code */
+ return inflate_codes(__G__ G.fixed_tl, G.fixed_td,
+ G.fixed_bl, G.fixed_bd);
+}
+
+
+
+static int inflate_dynamic(__G)
+ __GDEF
+/* decompress an inflated type 2 (dynamic Huffman codes) block. */
+{
+ unsigned i; /* temporary variables */
+ unsigned j;
+ unsigned l; /* last length */
+ unsigned m; /* mask for bit lengths table */
+ unsigned n; /* number of lengths to get */
+ struct huft *tl; /* literal/length code table */
+ struct huft *td; /* distance code table */
+ unsigned bl; /* lookup bits for tl */
+ unsigned bd; /* lookup bits for td */
+ unsigned nb; /* number of bit length codes */
+ unsigned nl; /* number of literal/length codes */
+ unsigned nd; /* number of distance codes */
+ unsigned ll[MAXLITLENS+MAXDISTS]; /* lit./length and distance code lengths */
+ register ulg b; /* bit buffer */
+ register unsigned k; /* number of bits in bit buffer */
+ int retval = 0; /* error code returned: initialized to "no error" */
+
+
+ /* make local bit buffer */
+ Trace((stderr, "\ndynamic block"));
+ b = G.bb;
+ k = G.bk;
+
+
+ /* read in table lengths */
+ NEEDBITS(5)
+ nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */
+ DUMPBITS(5)
+ NEEDBITS(5)
+ nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */
+ DUMPBITS(5)
+ NEEDBITS(4)
+ nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */
+ DUMPBITS(4)
+ if (nl > MAXLITLENS || nd > MAXDISTS)
+ return 1; /* bad lengths */
+
+
+ /* read in bit-length-code lengths */
+ for (j = 0; j < nb; j++)
+ {
+ NEEDBITS(3)
+ ll[border[j]] = (unsigned)b & 7;
+ DUMPBITS(3)
+ }
+ for (; j < 19; j++)
+ ll[border[j]] = 0;
+
+
+ /* build decoding table for trees--single level, 7 bit lookup */
+ bl = 7;
+ retval = huft_build(__G__ ll, 19, 19, NULL, NULL, &tl, &bl);
+ if (bl == 0) /* no bit lengths */
+ retval = 1;
+ if (retval)
+ {
+ if (retval == 1)
+ huft_free(tl);
+ return retval; /* incomplete code set */
+ }
+
+
+ /* read in literal and distance code lengths */
+ n = nl + nd;
+ m = mask_bits[bl];
+ i = l = 0;
+ while (i < n)
+ {
+ NEEDBITS(bl)
+ j = (td = tl + ((unsigned)b & m))->b;
+ DUMPBITS(j)
+ j = td->v.n;
+ if (j < 16) /* length of code in bits (0..15) */
+ ll[i++] = l = j; /* save last length in l */
+ else if (j == 16) /* repeat last length 3 to 6 times */
+ {
+ NEEDBITS(2)
+ j = 3 + ((unsigned)b & 3);
+ DUMPBITS(2)
+ if ((unsigned)i + j > n)
+ return 1;
+ while (j--)
+ ll[i++] = l;
+ }
+ else if (j == 17) /* 3 to 10 zero length codes */
+ {
+ NEEDBITS(3)
+ j = 3 + ((unsigned)b & 7);
+ DUMPBITS(3)
+ if ((unsigned)i + j > n)
+ return 1;
+ while (j--)
+ ll[i++] = 0;
+ l = 0;
+ }
+ else /* j == 18: 11 to 138 zero length codes */
+ {
+ NEEDBITS(7)
+ j = 11 + ((unsigned)b & 0x7f);
+ DUMPBITS(7)
+ if ((unsigned)i + j > n)
+ return 1;
+ while (j--)
+ ll[i++] = 0;
+ l = 0;
+ }
+ }
+
+
+ /* free decoding table for trees */
+ huft_free(tl);
+
+
+ /* restore the global bit buffer */
+ G.bb = b;
+ G.bk = k;
+
+
+ /* build the decoding tables for literal/length and distance codes */
+ bl = lbits;
+#ifdef USE_DEFLATE64
+ retval = huft_build(__G__ ll, nl, 257, G.cplens, G.cplext, &tl, &bl);
+#else
+ retval = huft_build(__G__ ll, nl, 257, cplens, cplext, &tl, &bl);
+#endif
+ if (bl == 0) /* no literals or lengths */
+ retval = 1;
+ if (retval)
+ {
+ if (retval == 1) {
+ if (!uO.qflag)
+ MESSAGE((uch *)"(incomplete l-tree) ", 21L, 1);
+ huft_free(tl);
+ }
+ return retval; /* incomplete code set */
+ }
+#ifdef FIX_PAST_EOB_BY_TABLEADJUST
+ /* Adjust the requested distance base table size so that a distance code
+ fetch never tries to get bits behind an immediatly following end-of-block
+ code. */
+ bd = (dbits <= bl+1 ? dbits : bl+1);
+#else
+ bd = dbits;
+#endif
+#ifdef USE_DEFLATE64
+ retval = huft_build(__G__ ll + nl, nd, 0, cpdist, G.cpdext, &td, &bd);
+#else
+ retval = huft_build(__G__ ll + nl, nd, 0, cpdist, cpdext, &td, &bd);
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ if (retval == 1)
+ retval = 0;
+#endif
+ if (bd == 0 && nl > 257) /* lengths but no distances */
+ retval = 1;
+ if (retval)
+ {
+ if (retval == 1) {
+ if (!uO.qflag)
+ MESSAGE((uch *)"(incomplete d-tree) ", 21L, 1);
+ huft_free(td);
+ }
+ huft_free(tl);
+ return retval;
+ }
+
+ /* decompress until an end-of-block code */
+ retval = inflate_codes(__G__ tl, td, bl, bd);
+
+cleanup_and_exit:
+ /* free the decoding tables, return */
+ huft_free(tl);
+ huft_free(td);
+ return retval;
+}
+
+
+
+static int inflate_block(__G__ e)
+ __GDEF
+ int *e; /* last block flag */
+/* decompress an inflated block */
+{
+ unsigned t; /* block type */
+ register ulg b; /* bit buffer */
+ register unsigned k; /* number of bits in bit buffer */
+ int retval = 0; /* error code returned: initialized to "no error" */
+
+
+ /* make local bit buffer */
+ b = G.bb;
+ k = G.bk;
+
+
+ /* read in last block bit */
+ NEEDBITS(1)
+ *e = (int)b & 1;
+ DUMPBITS(1)
+
+
+ /* read in block type */
+ NEEDBITS(2)
+ t = (unsigned)b & 3;
+ DUMPBITS(2)
+
+
+ /* restore the global bit buffer */
+ G.bb = b;
+ G.bk = k;
+
+
+ /* inflate that block type */
+ if (t == 2)
+ return inflate_dynamic(__G);
+ if (t == 0)
+ return inflate_stored(__G);
+ if (t == 1)
+ return inflate_fixed(__G);
+
+
+ /* bad block type */
+ retval = 2;
+
+cleanup_and_exit:
+ return retval;
+}
+
+
+
+int inflate(__G__ is_defl64)
+ __GDEF
+ int is_defl64;
+/* decompress an inflated entry */
+{
+ int e; /* last block flag */
+ int r; /* result code */
+#ifdef DEBUG
+ unsigned h = 0; /* maximum struct huft's malloc'ed */
+#endif
+
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+ if (G.redirect_slide)
+ wsize = G.redirect_size, redirSlide = G.redirect_buffer;
+ else
+ wsize = WSIZE, redirSlide = slide; /* how they're #defined if !DLL */
+#endif
+
+ /* initialize window, bit buffer */
+ G.wp = 0;
+ G.bk = 0;
+ G.bb = 0;
+
+#ifdef USE_DEFLATE64
+ if (is_defl64) {
+ G.cplens = cplens64;
+ G.cplext = cplext64;
+ G.cpdext = cpdext64;
+ G.fixed_tl = G.fixed_tl64;
+ G.fixed_bl = G.fixed_bl64;
+ G.fixed_td = G.fixed_td64;
+ G.fixed_bd = G.fixed_bd64;
+ } else {
+ G.cplens = cplens32;
+ G.cplext = cplext32;
+ G.cpdext = cpdext32;
+ G.fixed_tl = G.fixed_tl32;
+ G.fixed_bl = G.fixed_bl32;
+ G.fixed_td = G.fixed_td32;
+ G.fixed_bd = G.fixed_bd32;
+ }
+#else /* !USE_DEFLATE64 */
+ if (is_defl64) {
+ /* This should not happen unless UnZip is built from object files
+ * compiled with inconsistent option setting. Handle this by
+ * returning with "bad input" error code.
+ */
+ Trace((stderr, "\nThis inflate() cannot handle Deflate64!\n"));
+ return 2;
+ }
+#endif /* ?USE_DEFLATE64 */
+
+ /* decompress until the last block */
+ do {
+#ifdef DEBUG
+ G.hufts = 0;
+#endif
+ if ((r = inflate_block(__G__ &e)) != 0)
+ return r;
+#ifdef DEBUG
+ if (G.hufts > h)
+ h = G.hufts;
+#endif
+ } while (!e);
+
+ Trace((stderr, "\n%u bytes in Huffman tables (%u/entry)\n",
+ h * (unsigned)sizeof(struct huft), (unsigned)sizeof(struct huft)));
+
+#ifdef USE_DEFLATE64
+ if (is_defl64) {
+ G.fixed_tl64 = G.fixed_tl;
+ G.fixed_bl64 = G.fixed_bl;
+ G.fixed_td64 = G.fixed_td;
+ G.fixed_bd64 = G.fixed_bd;
+ } else {
+ G.fixed_tl32 = G.fixed_tl;
+ G.fixed_bl32 = G.fixed_bl;
+ G.fixed_td32 = G.fixed_td;
+ G.fixed_bd32 = G.fixed_bd;
+ }
+#endif
+
+ /* flush out redirSlide and return (success, unless final FLUSH failed) */
+ return (FLUSH(G.wp));
+}
+
+
+
+int inflate_free(__G)
+ __GDEF
+{
+ if (G.fixed_tl != (struct huft *)NULL)
+ {
+ huft_free(G.fixed_td);
+ huft_free(G.fixed_tl);
+ G.fixed_td = G.fixed_tl = (struct huft *)NULL;
+ }
+ return 0;
+}
+
+#endif /* ?USE_ZLIB */
+
+
+/*
+ * GRR: moved huft_build() and huft_free() down here; used by explode()
+ * and fUnZip regardless of whether USE_ZLIB defined or not
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+#define BMAX 16 /* maximum bit length of any code (16 for explode) */
+#define N_MAX 288 /* maximum number of codes in any set */
+
+
+int huft_build(__G__ b, n, s, d, e, t, m)
+ __GDEF
+ ZCONST unsigned *b; /* code lengths in bits (all assumed <= BMAX) */
+ unsigned n; /* number of codes (assumed <= N_MAX) */
+ unsigned s; /* number of simple-valued codes (0..s-1) */
+ ZCONST ush *d; /* list of base values for non-simple codes */
+ ZCONST uch *e; /* list of extra bits for non-simple codes */
+ struct huft **t; /* result: starting table */
+ unsigned *m; /* maximum lookup bits, returns actual */
+/* Given a list of code lengths and a maximum table size, make a set of
+ tables to decode that set of codes. Return zero on success, one if
+ the given code set is incomplete (the tables are still built in this
+ case), two if the input is invalid (all zero length codes or an
+ oversubscribed set of lengths), and three if not enough memory.
+ The code with value 256 is special, and the tables are constructed
+ so that no bits beyond that code are fetched when that code is
+ decoded. */
+{
+ unsigned a; /* counter for codes of length k */
+ unsigned c[BMAX+1]; /* bit length count table */
+ unsigned el; /* length of EOB code (value 256) */
+ unsigned f; /* i repeats in table every f entries */
+ int g; /* maximum code length */
+ int h; /* table level */
+ register unsigned i; /* counter, current code */
+ register unsigned j; /* counter */
+ register int k; /* number of bits in current code */
+ int lx[BMAX+1]; /* memory for l[-1..BMAX-1] */
+ int *l = lx+1; /* stack of bits per table */
+ register unsigned *p; /* pointer into c[], b[], or v[] */
+ register struct huft *q; /* points to current table */
+ struct huft r; /* table entry for structure assignment */
+ struct huft *u[BMAX]; /* table stack */
+ unsigned v[N_MAX]; /* values in order of bit length */
+ register int w; /* bits before this table == (l * h) */
+ unsigned x[BMAX+1]; /* bit offsets, then code stack */
+ unsigned *xp; /* pointer into x */
+ int y; /* number of dummy codes added */
+ unsigned z; /* number of entries in current table */
+
+
+ /* Generate counts for each bit length */
+ el = n > 256 ? b[256] : BMAX; /* set length of EOB code, if any */
+ memzero((char *)c, sizeof(c));
+ p = (unsigned *)b; i = n;
+ do {
+ c[*p]++; p++; /* assume all entries <= BMAX */
+ } while (--i);
+ if (c[0] == n) /* null input--all zero length codes */
+ {
+ *t = (struct huft *)NULL;
+ *m = 0;
+ return 0;
+ }
+
+
+ /* Find minimum and maximum length, bound *m by those */
+ for (j = 1; j <= BMAX; j++)
+ if (c[j])
+ break;
+ k = j; /* minimum code length */
+ if (*m < j)
+ *m = j;
+ for (i = BMAX; i; i--)
+ if (c[i])
+ break;
+ g = i; /* maximum code length */
+ if (*m > i)
+ *m = i;
+
+
+ /* Adjust last length count to fill out codes, if needed */
+ for (y = 1 << j; j < i; j++, y <<= 1)
+ if ((y -= c[j]) < 0)
+ return 2; /* bad input: more codes than bits */
+ if ((y -= c[i]) < 0)
+ return 2;
+ c[i] += y;
+
+
+ /* Generate starting offsets into the value table for each length */
+ x[1] = j = 0;
+ p = c + 1; xp = x + 2;
+ while (--i) { /* note that i == g from above */
+ *xp++ = (j += *p++);
+ }
+
+
+ /* Make a table of values in order of bit lengths */
+ memzero((char *)v, sizeof(v));
+ p = (unsigned *)b; i = 0;
+ do {
+ if ((j = *p++) != 0)
+ v[x[j]++] = i;
+ } while (++i < n);
+ n = x[g]; /* set n to length of v */
+
+
+ /* Generate the Huffman codes and for each, make the table entries */
+ x[0] = i = 0; /* first Huffman code is zero */
+ p = v; /* grab values in bit order */
+ h = -1; /* no tables yet--level -1 */
+ w = l[-1] = 0; /* no bits decoded yet */
+ u[0] = (struct huft *)NULL; /* just to keep compilers happy */
+ q = (struct huft *)NULL; /* ditto */
+ z = 0; /* ditto */
+
+ /* go through the bit lengths (k already is bits in shortest code) */
+ for (; k <= g; k++)
+ {
+ a = c[k];
+ while (a--)
+ {
+ /* here i is the Huffman code of length k bits for value *p */
+ /* make tables up to required level */
+ while (k > w + l[h])
+ {
+ w += l[h++]; /* add bits already decoded */
+
+ /* compute minimum size table less than or equal to *m bits */
+ z = (z = g - w) > *m ? *m : z; /* upper limit */
+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
+ { /* too few codes for k-w bit table */
+ f -= a + 1; /* deduct codes from patterns left */
+ xp = c + k;
+ while (++j < z) /* try smaller tables up to z bits */
+ {
+ if ((f <<= 1) <= *++xp)
+ break; /* enough codes to use up j bits */
+ f -= *xp; /* else deduct codes from patterns */
+ }
+ }
+ if ((unsigned)w + j > el && (unsigned)w < el)
+ j = el - w; /* make EOB code end at table */
+ z = 1 << j; /* table entries for j-bit table */
+ l[h] = j; /* set table size in stack */
+
+ /* allocate and link in new table */
+ if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
+ (struct huft *)NULL)
+ {
+ if (h)
+ huft_free(u[0]);
+ return 3; /* not enough memory */
+ }
+#ifdef DEBUG
+ G.hufts += z + 1; /* track memory usage */
+#endif
+ *t = q + 1; /* link to list for huft_free() */
+ *(t = &(q->v.t)) = (struct huft *)NULL;
+ u[h] = ++q; /* table starts after link */
+
+ /* connect to last table, if there is one */
+ if (h)
+ {
+ x[h] = i; /* save pattern for backing up */
+ r.b = (uch)l[h-1]; /* bits to dump before this table */
+ r.e = (uch)(32 + j); /* bits in this table */
+ r.v.t = q; /* pointer to this table */
+ j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
+ u[h-1][j] = r; /* connect to last table */
+ }
+ }
+
+ /* set up table entry in r */
+ r.b = (uch)(k - w);
+ if (p >= v + n)
+ r.e = INVALID_CODE; /* out of values--invalid code */
+ else if (*p < s)
+ {
+ r.e = (uch)(*p < 256 ? 32 : 31); /* 256 is end-of-block code */
+ r.v.n = (ush)*p++; /* simple code is just the value */
+ }
+ else
+ {
+ r.e = e[*p - s]; /* non-simple--look up in lists */
+ r.v.n = d[*p++ - s];
+ }
+
+ /* fill code-like entries with r */
+ f = 1 << (k - w);
+ for (j = i >> w; j < z; j += f)
+ q[j] = r;
+
+ /* backwards increment the k-bit code i */
+ for (j = 1 << (k - 1); i & j; j >>= 1)
+ i ^= j;
+ i ^= j;
+
+ /* backup over finished tables */
+ while ((i & ((1 << w) - 1)) != x[h])
+ w -= l[--h]; /* don't need to update q */
+ }
+ }
+
+
+ /* return actual size of base table */
+ *m = l[0];
+
+
+ /* Return true (1) if we were given an incomplete table */
+ return y != 0 && g != 1;
+}
+
+
+
+int huft_free(t)
+struct huft *t; /* table to free */
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+ list of the tables it made, with the links in a dummy first entry of
+ each table. */
+{
+ register struct huft *p, *q;
+
+
+ /* Go through linked list, freeing from the malloced (t[-1]) address. */
+ p = t;
+ while (p != (struct huft *)NULL)
+ {
+ q = (--p)->v.t;
+ free((zvoid *)p);
+ p = q;
+ }
+ return 0;
+}
Property changes on: trunk/build/install/installer/inflate.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/inflate.h
===================================================================
--- trunk/build/install/installer/inflate.h (rev 0)
+++ trunk/build/install/installer/inflate.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,39 @@
+/*
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* inflate.h for UnZip -- by Mark Adler
+ version c14f, 23 November 1995 */
+
+
+/* Copyright history:
+ - Starting with UnZip 5.41 of 16-April-2000, this source file
+ is covered by the Info-Zip LICENSE cited above.
+ - Prior versions of this source file, found in UnZip source packages
+ up to UnZip 5.40, were put in the public domain.
+ The original copyright note by Mark Adler was:
+ "You can do whatever you like with this source file,
+ though I would prefer that if you modify it and
+ redistribute it that you include comments to that effect
+ with your name and the date. Thank you."
+
+ History:
+ vers date who what
+ ---- --------- -------------- ------------------------------------
+ c14 12 Mar 93 M. Adler made inflate.c standalone with the
+ introduction of inflate.h.
+ c14d 28 Aug 93 G. Roelofs replaced flush/FlushOutput with new version
+ c14e 29 Sep 93 G. Roelofs moved everything into unzip.h; added crypt.h
+ c14f 23 Nov 95 G. Roelofs added UNZIP_INTERNAL to accommodate newly
+ split unzip.h
+ */
+
+#define UNZIP_INTERNAL
+#include "unzip.h" /* provides slide[], typedefs and macros */
+#ifdef FUNZIP
+# include "crypt.h" /* provides NEXTBYTE macro for crypt version of funzip */
+#endif
Property changes on: trunk/build/install/installer/inflate.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/licenses/LICENSE
===================================================================
--- trunk/build/install/installer/licenses/LICENSE (rev 0)
+++ trunk/build/install/installer/licenses/LICENSE 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,55 @@
+This is version 2005-Feb-10 of the Info-ZIP copyright and license.
+The definitive version of this document should be available at
+ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely.
+
+
+Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+For the purposes of this copyright and license, "Info-ZIP" is defined as
+the following set of individuals:
+
+ Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
+ Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth,
+ Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
+ David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
+ Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
+ Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda,
+ Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren,
+ Rich Wales, Mike White
+
+This software is provided "as is," without warranty of any kind, express
+or implied. In no event shall Info-ZIP or its contributors be held liable
+for any direct, indirect, incidental, special or consequential damages
+arising out of the use of or inability to use this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ definition, disclaimer, and this list of conditions.
+
+ 2. Redistributions in binary form (compiled executables) must reproduce
+ the above copyright notice, definition, disclaimer, and this list of
+ conditions in documentation and/or other materials provided with the
+ distribution. The sole exception to this condition is redistribution
+ of a standard UnZipSFX binary (including SFXWiz) as part of a
+ self-extracting archive; that is permitted without inclusion of this
+ license, as long as the normal SFX banner has not been removed from
+ the binary or disabled.
+
+ 3. Altered versions--including, but not limited to, ports to new operating
+ systems, existing ports with new graphical interfaces, and dynamic,
+ shared, or static library versions--must be plainly marked as such
+ and must not be misrepresented as being the original source. Such
+ altered versions also must not be misrepresented as being Info-ZIP
+ releases--including, but not limited to, labeling of the altered
+ versions with the names "Info-ZIP" (or any variation thereof, including,
+ but not limited to, different capitalizations), "Pocket UnZip," "WiZ"
+ or "MacZip" without the explicit permission of Info-ZIP. Such altered
+ versions are further prohibited from misrepresentative use of the
+ Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s).
+
+ 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip,"
+ "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its
+ own source and binary releases.
Property changes on: trunk/build/install/installer/licenses/LICENSE
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/main.c
===================================================================
--- trunk/build/install/installer/main.c (rev 0)
+++ trunk/build/install/installer/main.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,664 @@
+/*
+ * SINSTALL - JBoss Installer
+ *
+ * Copyright(c) 2007 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#include "sinstall.h"
+
+#include <direct.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <process.h>
+
+#define __UNZIP_C /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h" /* includes, typedefs, macros, prototypes, etc. */
+#include "crypt.h"
+#include "unzvers.h"
+
+#define MAX_CMDLINE 16384
+#define IS_INVALID_HANDLE(x) (((x) == NULL || (x) == INVALID_HANDLE_VALUE))
+
+static LPCSTR CMD_PREFIX = "%s /E:ON /S /C \"SET JBINSTALL_PPID=%d&&CALL %s ";
+static LPCSTR CMD_SUFIX = "> install.log 2>&1\"";
+static LPCSTR CMD_BATCH = "install.bat";
+static LPCSTR DIR_BATCH = "\\_install";
+static LPCSTR CMD_QUOTE = " &()[]{}^=;!'+,`~";
+static LPSTR ppUnizpArgs[] = { "unzip", "-qq", "-d", NULL, NULL };
+
+BOOL opt_Quiet = FALSE;
+BOOL opt_Verbose = FALSE;
+
+
+static int optslash = '/'; /* allow slashes as option modifiers */
+static int optsbrk = 1; /* Break if slash is unknown modifier */
+static int opterr = 1; /* if error message should be printed */
+static int optind = 1; /* index into parent argv vector */
+static int optopt = 0; /* character checked for validity */
+static int optlong = 1; /* Allow long options */
+static int optreset = 1; /* reset getopt */
+static char *optarg = NULL; /* argument associated with option */
+
+#define BADCH '?'
+#define BADARG ':'
+#define LNGOPT '.'
+#define EMSG ""
+
+static LPSTR szProgramName = NULL;
+static LPSTR szProgramPath = NULL;
+static CHAR szTempPath[MAX_PATH] = { 0 };
+
+static int c_errno_table[] = {
+
+ 0, /* NO_ERROR */
+ EINVAL, /* ERROR_INVALID_FUNCTION */
+ ENOENT, /* ERROR_FILE_NOT_FOUND */
+ ENOENT, /* ERROR_PATH_NOT_FOUND */
+ EMFILE, /* ERROR_TOO_MANY_OPEN_FILES */
+ EACCES, /* ERROR_ACCESS_DENIED */
+ EBADF, /* ERROR_INVALID_HANDLE */
+ ENOMEM, /* ERROR_ARENA_TRASHED */
+ ENOMEM, /* ERROR_NOT_ENOUGH_MEMORY */
+ ENOMEM, /* ERROR_INVALID_BLOCK */
+ E2BIG, /* ERROR_BAD_ENVIRONMENT */
+ ENOEXEC, /* ERROR_BAD_FORMAT */
+ EINVAL, /* ERROR_INVALID_ACCESS */
+ EINVAL, /* ERROR_INVALID_DATA */
+ 14, /* **** reserved */
+ ENOENT, /* ERROR_INVALID_DRIVE */
+ EACCES, /* ERROR_CURRENT_DIRECTORY */
+ EXDEV, /* ERROR_NOT_SAME_DEVICE */
+ ENOENT, /* ERROR_NO_MORE_FILES */
+ 0
+};
+
+int x_cerror(int err)
+{
+ if (err == 0) {
+ if ((err = GetLastError()) == 0)
+ return 0;
+ }
+ if (err < 0 || err > ERROR_NO_MORE_FILES) {
+ switch (err) {
+ case 1026:
+ return ENOENT;
+ break;
+ case ERROR_ALREADY_EXISTS:
+ return EEXIST;
+ case ERROR_INSUFFICIENT_BUFFER:
+ return ENAMETOOLONG;
+ break;
+ default:
+ return err;
+ break;
+ }
+ }
+ else
+ return c_errno_table[err];
+}
+
+static void x_perror(const char *msg)
+{
+ int err = errno;
+
+ errno = x_cerror(err);
+ perror(msg);
+ exit(err);
+}
+
+static void x_free(void *ptr)
+{
+ if (ptr)
+ free(ptr);
+}
+
+static void *x_malloc(size_t len)
+{
+ void *ptr = calloc(1, len);
+
+ if (!ptr) {
+ x_perror("Malloc");
+ }
+ return ptr;
+}
+
+static char *x_strdup(const char *s)
+{
+ char *p;
+ size_t size;
+
+ if (s != NULL)
+ size = strlen(s);
+ else
+ return NULL;
+ if (!size)
+ return NULL;
+ p = (char *)x_malloc(size + 2);
+ memcpy(p, s, size);
+ return p;
+}
+
+
+LPCSTR
+GetProgramName()
+{
+ char *p;
+
+ if (szProgramName)
+ return szProgramName;
+
+ szProgramPath = (LPSTR)calloc(1, MAX_PATH);
+ if (!GetModuleFileNameExA(GetCurrentProcess(), NULL,
+ szProgramPath, MAX_PATH))
+ exit(GetLastError());
+
+ if ((p = strrchr(szProgramPath, '\\')))
+ *(p++) = '\0';
+ else
+ p = szProgramPath;
+ szProgramName = x_strdup(p);
+ /* Remove extension */
+ if ((p = strrchr(szProgramName, '.')))
+ *p = '\0';
+ return szProgramName;
+}
+
+LPCSTR
+GetProgramPath()
+{
+ char *p;
+
+ if (szProgramPath)
+ return szProgramPath;
+
+ szProgramPath = (LPSTR)x_malloc(MAX_PATH);
+ if (!GetModuleFileNameExA(GetCurrentProcess(), NULL,
+ szProgramPath, MAX_PATH))
+ exit(GetLastError());
+
+ if ((p = strrchr(szProgramPath, '\\')))
+ *(p++) = '\0';
+ else
+ p = szProgramPath;
+ szProgramName = x_strdup(p);
+ /* Remove extension */
+ if ((p = strrchr(szProgramName, '.')))
+ *p = '\0';
+ return szProgramPath;
+}
+
+static void vwarnx(const char *fmt, va_list ap)
+{
+ fprintf(stderr, "%s: ", GetProgramName());
+ if (fmt != NULL)
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+}
+
+static void warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ * However this one allows both - and / as argument options
+ */
+static int getopt(int nargc, const char **nargv, const char *ostr)
+{
+ static const char *place = EMSG; /* option letter processing */
+ char *oli = NULL; /* option letter list index */
+ int first = 0;
+
+ optarg = NULL;
+ if (optreset || *place == 0) { /* update scanning pointer */
+ optreset = 0;
+ place = nargv[optind];
+ if (optind >= nargc) {
+ /* Argument is absent or is not an option */
+ place = EMSG;
+ return EOF;
+ }
+ first = *place++;
+ if (first != '-' && first != optslash) {
+ /* Argument is absent or is not an option */
+ place = EMSG;
+ return EOF;
+ }
+ optopt = *place++;
+ /* Check for invalid sequence */
+ if ((optslash == '/') &&
+ ((first == '-' && optopt == '/') ||
+ (first == '/' && optopt == '-'))) {
+ ++optind;
+ if (opterr)
+ warnx("Invalid sequence -- %c%c",
+ first, optopt);
+ place = EMSG;
+ return BADCH;
+
+ }
+ if (first == '-' && optopt == '-') {
+ ++optind;
+ if (*place == 0 || !optlong) {
+ place = EMSG;
+ /* "--" => end of options */
+ return EOF;
+ }
+ else {
+ optarg = (char *)place;
+ place = EMSG;
+ /* "--long" => long option */
+ return LNGOPT;
+ }
+ }
+ if (optopt == 0) {
+ /*
+ * Solitary '-', treat as a '-' option
+ * if the program (eg su) is looking for it.
+ */
+ place = EMSG;
+ if (strchr(ostr, first) == NULL)
+ return EOF;
+ optopt = first;
+ }
+ if (optopt == optslash) {
+ ++optind;
+ place = EMSG;
+ /* "//" => end of options */
+ return EOF;
+ }
+ }
+ else
+ optopt = *place++;
+
+ /* See if option letter is one the caller wanted... */
+ if (optopt == BADARG || (oli = strchr(ostr, optopt)) == NULL) {
+ if (!optsbrk && optslash == '/' && first == optslash) {
+ /* Non option starting with / */
+ place = EMSG;
+ return EOF;
+ }
+ if (*place == 0)
+ ++optind;
+ if (opterr && *ostr != ':')
+ warnx("unknown option -- %c\n"
+ "Try '%s --help' for more information.",
+ optopt, GetProgramName());
+ return BADCH;
+ }
+
+ /* Does this option need an argument? */
+ if (oli[1] != ':') {
+ /* don't need argument */
+ optarg = NULL;
+ if (*place == 0) {
+ ++optind;
+ place = EMSG;
+ }
+ else if (optslash == '/' && first == optslash) {
+ ++optind;
+ optarg = (char *)place;
+ place = EMSG;
+ }
+ } else {
+ /*
+ * Option-argument is either the rest of this argument or the
+ * entire next argument.
+ */
+ if (*place)
+ optarg = (char *)place;
+ else if (nargc > ++optind)
+ optarg = (char *)nargv[optind];
+ else {
+ /* option-argument absent */
+ place = EMSG;
+ if (*ostr == ':')
+ return BADARG;
+ if (opterr)
+ warnx("option requires an argument -- %c\n"
+ "Try '%s --help' for more information.",
+ optopt, GetProgramName());
+ return BADCH;
+ }
+ place = EMSG;
+ ++optind;
+ }
+ return optopt; /* return option letter */
+}
+
+
+static int
+ErrorMessage(
+ LPCSTR szError,
+ BOOL bFatal)
+{
+ LPVOID lpMsgBuf = NULL;
+ UINT nType;
+ int nRet = 0;
+ DWORD dwErr = GetLastError();
+
+ if (bFatal)
+ nType = MB_ICONERROR | MB_ABORTRETRYIGNORE | MB_SYSTEMMODAL;
+ else
+ nType = MB_ICONEXCLAMATION | MB_OK;
+ if (szError) {
+#ifdef _CONSOLE
+ nRet = MessageBoxA(NULL, szError, "Application Error", nType);
+#else
+ fprintf(stderr, "Application Error (08X): %s\n", dwErr, szError);
+#endif
+ }
+ else {
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ dwErr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
+ (LPSTR) &lpMsgBuf, 0, NULL);
+#ifdef _CONSOLE
+ nRet = MessageBoxA(NULL, (LPCSTR)lpMsgBuf,
+ "Application System Error", nType);
+#else
+ fprintf(stderr, "Application Error (08X): %s\n", dwErr,
+ (LPCSTR)lpMsgBuf);
+#endif
+
+ LocalFree(lpMsgBuf);
+ }
+ return nRet;
+}
+
+
+static int
+SXDeleteDirectory(LPCSTR szName)
+{
+ SHFILEOPSTRUCTA shfop;
+
+ memset(&shfop, 0, sizeof(shfop));
+ shfop.wFunc = FO_DELETE;
+ shfop.pFrom = szName;
+ shfop.fFlags = FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION;
+ return SHFileOperationA(&shfop);
+}
+
+static void
+BuildCommandLine(
+ LPSTR szBuf,
+ LPCSTR szCmdExe,
+ LPCSTR szBatchFile,
+ ...)
+{
+ char *p;
+ va_list vl;
+
+ va_start(vl, szBatchFile);
+ sprintf(szBuf, CMD_PREFIX, szCmdExe,
+ _getpid(), szBatchFile);
+ while ((p = va_arg(vl, char *)) != NULL) {
+ if (p[strcspn(p, CMD_QUOTE)]) {
+ strcat(szBuf, "\"");
+ strcat(szBuf, p);
+ strcat(szBuf, "\"");
+ }
+ else
+ strcat(szBuf, p);
+ strcat(szBuf, " ");
+ }
+ va_end(vl);
+ strcat(szBuf, CMD_SUFIX);
+ fprintf(stdout, "Service Cmd %s\n", szBuf);
+}
+
+
+static BOOL
+RunChildProcess(
+ LPCSTR szApplication,
+ LPSTR szCmdLine,
+ LPCSTR szWorkingPath,
+ LPPROCESS_INFORMATION lpprInfo)
+{
+ STARTUPINFO stInfo;
+ BOOL bResult;
+
+ ZeroMemory(&stInfo, sizeof(stInfo));
+ stInfo.cb = sizeof(stInfo);
+ stInfo.dwFlags = STARTF_USESHOWWINDOW;
+ stInfo.wShowWindow = SW_HIDE;
+ bResult = CreateProcess(szApplication,
+ szCmdLine,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_NEW_PROCESS_GROUP,
+ NULL,
+ szWorkingPath,
+ &stInfo,
+ lpprInfo);
+
+ return bResult;
+}
+
+static BOOL
+AcceptLicensePage()
+{
+ HANDLE hHtml;
+ CHAR sBuf[MAX_PATH] = { 0 };
+ CHAR *retVal;
+ BOOL rv = FALSE;
+
+ hHtml = DHTMLDialogInit(GetModuleHandle(NULL), "/HTML_LGPLMAIN");
+ if (IS_INVALID_HANDLE(hHtml))
+ return FALSE;
+
+ sprintf(sBuf, "%s", GetProgramName());
+ DHTMLDialogRun(NULL, hHtml,
+ "Accept License Agreement",
+ 505, 360,
+ sBuf);
+ retVal = DHTMLDialogResult(hHtml);
+ if (retVal && !strcmp(retVal, "OK")) {
+ rv = TRUE;
+ }
+ DHTMLDialogClose(hHtml);
+
+ return rv;
+}
+
+static void ExitCleanup(void)
+{
+ static int cleanup = 0;
+
+ if (cleanup++)
+ return;
+ if (szTempPath[0])
+ SXDeleteDirectory(szTempPath);
+ GuiTerminate();
+}
+
+LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg,
+ WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_QUIT:
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ break;
+ default:
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ break;
+ }
+
+ return FALSE;
+}
+
+#ifdef _CONSOLE
+int
+main(
+ int argc,
+ char *argv[])
+{
+
+ HINSTANCE hInstance = NULL;
+#else
+int WINAPI
+WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nShowCmd)
+{
+#endif
+ int i, r, ch;
+ int ap = 1;
+ int hasDest = 0;
+ LPSTR szCmdLine = NULL;
+ CHAR szBuf[MAX_PATH];
+ CHAR szCmdExe[MAX_PATH];
+ CHAR szDest[MAX_PATH] = { 0 };
+ PROCESS_INFORMATION prInfo;
+
+ atexit(ExitCleanup);
+
+ if (!GuiInitialize()) {
+ exit(-1);
+ }
+ while ((ch = getopt(__argc, __argv, "aAd:D:hHqQvV")) != EOF) {
+ switch (ch) {
+ case 'a':
+ case 'A':
+ GuiAboutBox(NULL);
+ r = 0;
+ goto cleanup;
+ break;
+ case 'q':
+ case 'Q':
+ opt_Quiet = TRUE;
+ break;
+ case 'v':
+ case 'V':
+ opt_Verbose = TRUE;
+ break;
+ case 'd':
+ case 'D':
+ hasDest = ap++;
+ break;
+ }
+ }
+ __argc -= optind;
+ __argv += optind;
+
+ if (!AcceptLicensePage()) {
+ r = EPERM;
+ goto cleanup;
+ }
+ if (hasDest) {
+ strcpy(szDest, __argv[hasDest - 1]);
+ /* TODO: Check if valid */
+ }
+ else {
+ if (!GuiBrowseForFolder(NULL,
+ "Select Installation Directory",
+ szDest)) {
+ r = EACCES;
+ goto cleanup;
+ }
+ }
+ szCmdLine = (char *)x_malloc(MAX_CMDLINE);
+
+ if (GetSystemDirectory(szBuf, MAX_PATH - 20)) {
+ strcat(szBuf, "\\cmd.exe");
+ if (strchr(szBuf, ' ')) {
+ szCmdExe[0] = '"';
+ strcpy(&szCmdExe[1], szBuf);
+ strcat(szCmdExe, "\"");
+ }
+ else
+ strcpy(szCmdExe, szBuf);
+ }
+ else {
+ perror("System Directory");
+ exit(-1);
+ }
+
+ if (GetTempPathA(MAX_PATH - 20, szBuf) == 0) {
+ perror("Temp Path");
+ exit(-1);
+ }
+ for (i = 0; i < 100; i++) {
+ CHAR szTmp[MAX_PATH];
+ if (GetTempFileName(szBuf, "_sx", _getpid(), szTmp) == 0) {
+ perror("Temp File");
+ exit(-1);
+ }
+ if (!mkdir(szTmp)) {
+ strcpy(szTempPath, szTmp);
+ break;
+ }
+ else {
+ if (errno != EEXIST) {
+ perror("Creating Temp directory");
+ exit(-1);
+ }
+ }
+ }
+ if (!szTempPath[0]) {
+ errno = EPERM;
+ perror("Creating Temp directory");
+ exit(-1);
+ }
+#if 0
+ ppUnizpArgs[3] = szTempPath;
+ printf("Running main %s\n", szTempPath);
+ CONSTRUCTGLOBALS();
+ r = unzip(4, ppUnizpArgs);
+ DESTROYGLOBALS();
+ if (RunChildProcess(szCmdExe, szCmdLine, szBuf, &prInfo)) {
+
+
+ }
+
+#endif
+ strcpy(szBuf, szTempPath);
+ strcat(szBuf, DIR_BATCH);
+ BuildCommandLine(szCmdLine, szCmdExe, CMD_BATCH,
+ "install", szDest, NULL);
+ if (RunChildProcess(szCmdExe, szCmdLine, szBuf, &prInfo)) {
+
+ r = 0;
+ }
+ else
+ r = GetLastError();
+ printf("(%s) Done %d!\n", GetProgramName(), r);
+
+cleanup:
+ x_free(szCmdLine);
+ ExitCleanup();
+ return r;
+}
Property changes on: trunk/build/install/installer/main.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/match.c
===================================================================
--- trunk/build/install/installer/match.c (rev 0)
+++ trunk/build/install/installer/match.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,356 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ match.c
+
+ The match() routine recursively compares a string to a "pattern" (regular
+ expression), returning TRUE if a match is found or FALSE if not. This
+ version is specifically for use with unzip.c: as did the previous match()
+ routines from SEA and J. Kercheval, it leaves the case (upper, lower, or
+ mixed) of the string alone, but converts any uppercase characters in the
+ pattern to lowercase if indicated by the global var pInfo->lcflag (which
+ is to say, string is assumed to have been converted to lowercase already,
+ if such was necessary).
+
+ GRR: reversed order of text, pattern in matche() (now same as match());
+ added ignore_case/ic flags, Case() macro.
+
+ PaulK: replaced matche() with recmatch() from Zip, modified to have an
+ ignore_case argument; replaced test frame with simpler one.
+
+ ---------------------------------------------------------------------------
+
+ Copyright on recmatch() from Zip's util.c (although recmatch() was almost
+ certainly written by Mark Adler...ask me how I can tell :-) ):
+
+ Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
+ Kai Uwe Rommel and Igor Mandrichenko.
+
+ Permission is granted to any individual or institution to use, copy,
+ or redistribute this software so long as all of the original files are
+ included unmodified, that it is not sold for profit, and that this copy-
+ right notice is retained.
+
+ ---------------------------------------------------------------------------
+
+ Match the pattern (wildcard) against the string (fixed):
+
+ match(string, pattern, ignore_case, sepc);
+
+ returns TRUE if string matches pattern, FALSE otherwise. In the pattern:
+
+ `*' matches any sequence of characters (zero or more)
+ `?' matches any single character
+ [SET] matches any character in the specified set,
+ [!SET] or [^SET] matches any character not in the specified set.
+
+ A set is composed of characters or ranges; a range looks like ``character
+ hyphen character'' (as in 0-9 or A-Z). [0-9a-zA-Z_] is the minimal set of
+ characters allowed in the [..] pattern construct. Other characters are
+ allowed (i.e., 8-bit characters) if your system will support them.
+
+ To suppress the special syntactic significance of any of ``[]*?!^-\'', in-
+ side or outside a [..] construct, and match the character exactly, precede
+ it with a ``\'' (backslash).
+
+ Note that "*.*" and "*." are treated specially under MS-DOS if DOSWILD is
+ defined. See the DOSWILD section below for an explanation. Note also
+ that with VMSWILD defined, '%' is used instead of '?', and sets (ranges)
+ are delimited by () instead of [].
+
+ ---------------------------------------------------------------------------*/
+
+
+#define __MATCH_C /* identifies this source module */
+
+/* define ToLower() in here (for Unix, define ToLower to be macro (using
+ * isupper()); otherwise just use tolower() */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+#ifndef THEOS /* the Theos port defines its own variant of match() */
+
+#if 0 /* this is not useful until it matches Amiga names insensitively */
+#ifdef AMIGA /* some other platforms might also want to use this */
+# define ANSI_CHARSET /* MOVE INTO UNZIP.H EVENTUALLY */
+#endif
+#endif /* 0 */
+
+#ifdef ANSI_CHARSET
+# ifdef ToLower
+# undef ToLower
+# endif
+ /* uppercase letters are values 41 thru 5A, C0 thru D6, and D8 thru DE */
+# define IsUpper(c) (c>=0xC0 ? c<=0xDE && c!=0xD7 : c>=0x41 && c<=0x5A)
+# define ToLower(c) (IsUpper((uch) c) ? (unsigned) c | 0x20 : (unsigned) c)
+#endif
+#define Case(x) (ic? ToLower(x) : (x))
+
+#ifdef VMSWILD
+# define WILDCHAR '%'
+# define BEG_RANGE '('
+# define END_RANGE ')'
+#else
+# define WILDCHAR '?'
+# define BEG_RANGE '['
+# define END_RANGE ']'
+#endif
+
+#if 0 /* GRR: add this to unzip.h someday... */
+#if !(defined(MSDOS) && defined(DOSWILD))
+#ifdef WILD_STOP_AT_DIR
+#define match(s,p,ic,sc) (recmatch((ZCONST uch *)p,(ZCONST uch *)s,ic,sc) == 1)
+#else
+#define match(s,p,ic) (recmatch((ZCONST uch *)p,(ZCONST uch *)s,ic) == 1)
+#endif
+int recmatch OF((ZCONST uch *pattern, ZCONST uch *string,
+ int ignore_case __WDLPRO));
+#endif
+#endif /* 0 */
+static int recmatch OF((ZCONST uch *pattern, ZCONST uch *string,
+ int ignore_case __WDLPRO));
+
+
+
+/* match() is a shell to recmatch() to return only Boolean values. */
+
+int match(string, pattern, ignore_case __WDL)
+ ZCONST char *string, *pattern;
+ int ignore_case;
+ __WDLDEF
+{
+#if (defined(MSDOS) && defined(DOSWILD))
+ char *dospattern;
+ int j = strlen(pattern);
+
+/*---------------------------------------------------------------------------
+ Optional MS-DOS preprocessing section: compare last three chars of the
+ wildcard to "*.*" and translate to "*" if found; else compare the last
+ two characters to "*." and, if found, scan the non-wild string for dots.
+ If in the latter case a dot is found, return failure; else translate the
+ "*." to "*". In either case, continue with the normal (Unix-like) match
+ procedure after translation. (If not enough memory, default to normal
+ match.) This causes "a*.*" and "a*." to behave as MS-DOS users expect.
+ ---------------------------------------------------------------------------*/
+
+ if ((dospattern = (char *)malloc(j+1)) != NULL) {
+ strcpy(dospattern, pattern);
+ if (!strcmp(dospattern+j-3, "*.*")) {
+ dospattern[j-2] = '\0'; /* nuke the ".*" */
+ } else if (!strcmp(dospattern+j-2, "*.")) {
+ char *p = MBSCHR(string, '.');
+
+ if (p) { /* found a dot: match fails */
+ free(dospattern);
+ return 0;
+ }
+ dospattern[j-1] = '\0'; /* nuke the end "." */
+ }
+ j = recmatch((uch *)dospattern, (uch *)string, ignore_case __WDL);
+ free(dospattern);
+ return j == 1;
+ } else
+#endif /* MSDOS && DOSWILD */
+ return recmatch((uch *)pattern, (uch *)string, ignore_case __WDL) == 1;
+}
+
+
+
+static int recmatch(p, s, ic __WDL)
+ ZCONST uch *p; /* sh pattern to match */
+ ZCONST uch *s; /* string to which to match it */
+ int ic; /* true for case insensitivity */
+ __WDLDEF /* directory sepchar for WildStopAtDir mode, or 0 */
+/* Recursively compare the sh pattern p with the string s and return 1 if
+ * they match, and 0 or 2 if they don't or if there is a syntax error in the
+ * pattern. This routine recurses on itself no more deeply than the number
+ * of characters in the pattern. */
+{
+ unsigned int c; /* pattern char or start of range in [-] loop */
+
+ /* Get first character, the pattern for new recmatch calls follows */
+ c = *p; INCSTR(p);
+
+ /* If that was the end of the pattern, match if string empty too */
+ if (c == 0)
+ return *s == 0;
+
+ /* '?' (or '%') matches any character (but not an empty string). */
+ if (c == WILDCHAR)
+#ifdef WILD_STOP_AT_DIR
+ /* If uO.W_flag is non-zero, it won't match '/' */
+ return (*s && (!sepc || *s != (uch)sepc))
+ ? recmatch(p, s + CLEN(s), ic, sepc) : 0;
+#else
+ return *s ? recmatch(p, s + CLEN(s), ic) : 0;
+#endif
+
+ /* '*' matches any number of characters, including zero */
+#ifdef AMIGA
+ if (c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
+ c = '*', p++;
+#endif /* AMIGA */
+ if (c == '*') {
+#ifdef WILD_STOP_AT_DIR
+ if (sepc) {
+ /* check for single "*" or double "**" */
+# ifdef AMIGA
+ if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
+ c = '*', p++;
+ if (c != '*') {
+# else /* !AMIGA */
+ if (*p != '*') {
+# endif /* ?AMIGA */
+ /* single "*": this doesn't match the dirsep character */
+ for (; *s && *s != (uch)sepc; INCSTR(s))
+ if ((c = recmatch(p, s, ic, sepc)) != 0)
+ return (int)c;
+ /* end of pattern: matched if at end of string, else continue */
+ if (*p == '\0')
+ return (*s == 0);
+ /* continue to match if at sepc in pattern, else give up */
+ return (*p == (uch)sepc || (*p == '\\' && p[1] == (uch)sepc))
+ ? recmatch(p, s, ic, sepc) : 2;
+ }
+ /* "**": this matches slashes */
+ ++p; /* move p behind the second '*' */
+ /* and continue with the non-W_flag code variant */
+ }
+#endif /* WILD_STOP_AT_DIR */
+ if (*p == 0)
+ return 1;
+ for (; *s; INCSTR(s))
+ if ((c = recmatch(p, s, ic __WDL)) != 0)
+ return (int)c;
+ return 2; /* 2 means give up--match will return false */
+ }
+
+ /* Parse and process the list of characters and ranges in brackets */
+ if (c == BEG_RANGE) {
+ int e; /* flag true if next char to be taken literally */
+ ZCONST uch *q; /* pointer to end of [-] group */
+ int r; /* flag true to match anything but the range */
+
+ if (*s == 0) /* need a character to match */
+ return 0;
+ p += (r = (*p == '!' || *p == '^')); /* see if reverse */
+ for (q = p, e = 0; *q; INCSTR(q)) /* find closing bracket */
+ if (e)
+ e = 0;
+ else
+ if (*q == '\\') /* GRR: change to ^ for MS-DOS, OS/2? */
+ e = 1;
+ else if (*q == END_RANGE)
+ break;
+ if (*q != END_RANGE) /* nothing matches if bad syntax */
+ return 0;
+ for (c = 0, e = (*p == '-'); p < q; INCSTR(p)) {
+ /* go through the list */
+ if (!e && *p == '\\') /* set escape flag if \ */
+ e = 1;
+ else if (!e && *p == '-') /* set start of range if - */
+ c = *(p-1);
+ else {
+ unsigned int cc = Case(*s);
+
+ if (*(p+1) != '-')
+ for (c = c ? c : *p; c <= *p; c++) /* compare range */
+ if ((unsigned)Case(c) == cc) /* typecast for MSC bug */
+ return r ? 0 : recmatch(q + 1, s + 1, ic __WDL);
+ c = e = 0; /* clear range, escape flags */
+ }
+ }
+ return r ? recmatch(q + CLEN(q), s + CLEN(s), ic __WDL) : 0;
+ /* bracket match failed */
+ }
+
+ /* if escape ('\\'), just compare next character */
+ if (c == '\\' && (c = *p++) == 0) /* if \ at end, then syntax error */
+ return 0;
+
+ /* just a character--compare it */
+#ifdef QDOS
+ return QMatch(Case((uch)c), Case(*s)) ?
+ recmatch(p, s + CLEN(s), ic __WDL) : 0;
+#else
+ return Case((uch)c) == Case(*s) ?
+ recmatch(p, s + CLEN(s), ic __WDL) : 0;
+#endif
+
+} /* end function recmatch() */
+
+#endif /* !THEOS */
+
+
+
+
+int iswild(p) /* originally only used for stat()-bug workaround in */
+ ZCONST char *p; /* VAX C, Turbo/Borland C, Watcom C, Atari MiNT libs; */
+{ /* now used in process_zipfiles() as well */
+ for (; *p; INCSTR(p))
+ if (*p == '\\' && *(p+1))
+ ++p;
+#ifdef THEOS
+ else if (*p == '?' || *p == '*' || *p=='#'|| *p == '@')
+#else /* !THEOS */
+#ifdef VMS
+ else if (*p == '%' || *p == '*')
+#else /* !VMS */
+#ifdef AMIGA
+ else if (*p == '?' || *p == '*' || (*p=='#' && p[1]=='?') || *p == '[')
+#else /* !AMIGA */
+ else if (*p == '?' || *p == '*' || *p == '[')
+#endif /* ?AMIGA */
+#endif /* ?VMS */
+#endif /* ?THEOS */
+#ifdef QDOS
+ return (int)p;
+#else
+ return TRUE;
+#endif
+
+ return FALSE;
+
+} /* end function iswild() */
+
+
+
+
+
+#ifdef TEST_MATCH
+
+#define put(s) {fputs(s,stdout); fflush(stdout);}
+#ifdef main
+# undef main
+#endif
+
+int main(int argc, char **argv)
+{
+ char pat[256], str[256];
+
+ for (;;) {
+ put("Pattern (return to exit): ");
+ gets(pat);
+ if (!pat[0])
+ break;
+ for (;;) {
+ put("String (return for new pattern): ");
+ gets(str);
+ if (!str[0])
+ break;
+ printf("Case sensitive: %s insensitive: %s\n",
+ match(str, pat, 0) ? "YES" : "NO",
+ match(str, pat, 1) ? "YES" : "NO");
+ }
+ }
+ EXIT(0);
+}
+
+#endif /* TEST_MATCH */
Property changes on: trunk/build/install/installer/match.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/process.c
===================================================================
--- trunk/build/install/installer/process.c (rev 0)
+++ trunk/build/install/installer/process.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,1679 @@
+/*
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ process.c
+
+ This file contains the top-level routines for processing multiple zipfiles.
+
+ Contains: process_zipfiles()
+ free_G_buffers()
+ do_seekable()
+ find_ecrec()
+ uz_end_central()
+ process_cdir_file_hdr()
+ get_cdir_ent()
+ process_local_file_hdr()
+ ef_scan_for_izux()
+ getRISCOSexfield()
+
+ ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+#ifdef WINDLL
+# ifdef POCKET_UNZIP
+# include "wince/intrface.h"
+# else
+# include "windll/windll.h"
+# endif
+#endif
+
+static int do_seekable OF((__GPRO__ int lastchance));
+static int find_ecrec OF((__GPRO__ long searchlen));
+
+static ZCONST char Far CannotAllocateBuffers[] =
+ "error: cannot allocate unzip buffers\n";
+
+#ifdef SFX
+ static ZCONST char Far CannotFindMyself[] =
+ "unzipsfx: cannot find myself! [%s]\n";
+# ifdef CHEAP_SFX_AUTORUN
+ static ZCONST char Far AutorunPrompt[] =
+ "\nAuto-run command: %s\nExecute this command? [y/n] ";
+ static ZCONST char Far NotAutoRunning[] =
+ "Not executing auto-run command.";
+# endif
+
+#else /* !SFX */
+ /* process_zipfiles() strings */
+# if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+ static ZCONST char Far WarnInvalidTZ[] =
+ "Warning: TZ environment variable not found, cannot use UTC times!!\n";
+# endif
+ static ZCONST char Far FilesProcessOK[] =
+ "%d archive%s successfully processed.\n";
+ static ZCONST char Far ArchiveWarning[] =
+ "%d archive%s had warnings but no fatal errors.\n";
+ static ZCONST char Far ArchiveFatalError[] =
+ "%d archive%s had fatal errors.\n";
+ static ZCONST char Far FileHadNoZipfileDir[] =
+ "%d file%s had no zipfile directory.\n";
+ static ZCONST char Far ZipfileWasDir[] = "1 \"zipfile\" was a directory.\n";
+ static ZCONST char Far ManyZipfilesWereDir[] =
+ "%d \"zipfiles\" were directories.\n";
+ static ZCONST char Far NoZipfileFound[] = "No zipfiles found.\n";
+
+ /* do_seekable() strings */
+# ifdef UNIX
+ static ZCONST char Far CannotFindZipfileDirMsg[] =
+ "%s: cannot find zipfile directory in one of %s or\n\
+ %s%s.zip, and cannot find %s, period.\n";
+ static ZCONST char Far CannotFindEitherZipfile[] =
+ "%s: cannot find or open %s, %s.zip or %s.\n";
+# else /* !UNIX */
+# ifndef AMIGA
+ static ZCONST char Far CannotFindWildcardMatch[] =
+ "%s: cannot find any matches for wildcard specification \"%s\".\n";
+# endif /* !AMIGA */
+ static ZCONST char Far CannotFindZipfileDirMsg[] =
+ "%s: cannot find zipfile directory in %s,\n\
+ %sand cannot find %s, period.\n";
+ static ZCONST char Far CannotFindEitherZipfile[] =
+ "%s: cannot find either %s or %s.\n";
+# endif /* ?UNIX */
+ extern ZCONST char Far Zipnfo[]; /* in unzip.c */
+#ifndef WINDLL
+ static ZCONST char Far Unzip[] = "unzip";
+#else
+ static ZCONST char Far Unzip[] = "UnZip DLL";
+#endif
+ static ZCONST char Far MaybeExe[] =
+ "note: %s may be a plain executable, not an archive\n";
+ static ZCONST char Far CentDirNotInZipMsg[] = "\n\
+ [%s]:\n\
+ Zipfile is disk %u of a multi-disk archive, and this is not the disk on\n\
+ which the central zipfile directory begins (disk %u).\n";
+ static ZCONST char Far EndCentDirBogus[] =
+ "\nwarning [%s]: end-of-central-directory record claims this\n\
+ is disk %u but that the central directory starts on disk %u; this is a\n\
+ contradiction. Attempting to process anyway.\n";
+# ifdef NO_MULTIPART
+ static ZCONST char Far NoMultiDiskArcSupport[] =
+ "\nerror [%s]: zipfile is part of multi-disk archive\n\
+ (sorry, not yet supported).\n";
+ static ZCONST char Far MaybePakBug[] = "warning [%s]:\
+ zipfile claims to be 2nd disk of a 2-part archive;\n\
+ attempting to process anyway. If no further errors occur, this archive\n\
+ was probably created by PAK v2.51 or earlier. This bug was reported to\n\
+ NoGate in March 1991 and was supposed to have been fixed by mid-1991; as\n\
+ of mid-1992 it still hadn't been. (If further errors do occur, archive\n\
+ was probably created by PKZIP 2.04c or later; UnZip does not yet support\n\
+ multi-part archives.)\n";
+# else
+ static ZCONST char Far MaybePakBug[] = "warning [%s]:\
+ zipfile claims to be last disk of a multi-part archive;\n\
+ attempting to process anyway, assuming all parts have been concatenated\n\
+ together in order. Expect \"errors\" and warnings...true multi-part support\
+\n doesn't exist yet (coming soon).\n";
+# endif
+ static ZCONST char Far ExtraBytesAtStart[] =
+ "warning [%s]: %ld extra byte%s at beginning or within zipfile\n\
+ (attempting to process anyway)\n";
+#endif /* ?SFX */
+
+static ZCONST char Far MissingBytes[] =
+ "error [%s]: missing %ld bytes in zipfile\n\
+ (attempting to process anyway)\n";
+static ZCONST char Far NullCentDirOffset[] =
+ "error [%s]: NULL central directory offset\n\
+ (attempting to process anyway)\n";
+static ZCONST char Far ZipfileEmpty[] = "warning [%s]: zipfile is empty\n";
+static ZCONST char Far CentDirStartNotFound[] =
+ "error [%s]: start of central directory not found;\n\
+ zipfile corrupt.\n%s";
+#ifndef SFX
+ static ZCONST char Far CentDirTooLong[] =
+ "error [%s]: reported length of central directory is\n\
+ %ld bytes too long (Atari STZip zipfile? J.H.Holm ZIPSPLIT 1.1\n\
+ zipfile?). Compensating...\n";
+ static ZCONST char Far CentDirEndSigNotFound[] = "\
+ End-of-central-directory signature not found. Either this file is not\n\
+ a zipfile, or it constitutes one disk of a multi-part archive. In the\n\
+ latter case the central directory and zipfile comment will be found on\n\
+ the last disk(s) of this archive.\n";
+#else /* SFX */
+ static ZCONST char Far CentDirEndSigNotFound[] =
+ " End-of-central-directory signature not found.\n";
+#endif /* ?SFX */
+static ZCONST char Far ZipfileCommTrunc1[] =
+ "\ncaution: zipfile comment truncated\n";
+
+
+
+
+/*******************************/
+/* Function process_zipfiles() */
+/*******************************/
+
+int process_zipfiles(__G) /* return PK-type error code */
+ __GDEF
+{
+#ifndef SFX
+ char *lastzipfn = (char *)NULL;
+ int NumWinFiles, NumLoseFiles, NumWarnFiles;
+ int NumMissDirs, NumMissFiles;
+#endif
+ int error=0, error_in_archive=0;
+
+
+/*---------------------------------------------------------------------------
+ Start by allocating buffers and (re)constructing the various PK signature
+ strings.
+ ---------------------------------------------------------------------------*/
+
+ G.inbuf = (uch *)malloc(INBUFSIZ + 4); /* 4 extra for hold[] (below) */
+ G.outbuf = (uch *)malloc(OUTBUFSIZ + 1); /* 1 extra for string term. */
+
+ if ((G.inbuf == (uch *)NULL) || (G.outbuf == (uch *)NULL)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotAllocateBuffers)));
+ return(PK_MEM);
+ }
+ G.hold = G.inbuf + INBUFSIZ; /* to check for boundary-spanning sigs */
+#ifndef VMS /* VMS uses its own buffer scheme for textmode flush(). */
+#ifdef SMALL_MEM
+ G.outbuf2 = G.outbuf+RAWBUFSIZ; /* never changes */
+#endif
+#endif /* !VMS */
+
+#if 0 /* CRC_32_TAB has been NULLified by CONSTRUCTGLOBALS !!!! */
+ /* allocate the CRC table only later when we know we have a zipfile */
+ CRC_32_TAB = NULL;
+#endif /* 0 */
+
+ /* finish up initialization of magic signature strings */
+ local_hdr_sig[0] /* = extd_local_sig[0] */ = /* ASCII 'P', */
+ central_hdr_sig[0] = end_central_sig[0] = 0x50; /* not EBCDIC */
+
+ local_hdr_sig[1] /* = extd_local_sig[1] */ = /* ASCII 'K', */
+ central_hdr_sig[1] = end_central_sig[1] = 0x4B; /* not EBCDIC */
+
+/*---------------------------------------------------------------------------
+ Make sure timezone info is set correctly; localtime() returns GMT on
+ some OSes (e.g., Solaris 2.x) if this isn't done first. The ifdefs were
+ initially copied from dos_to_unix_time() in fileio.c. probably, they are
+ still too strict; any listed OS that supplies tzset(), regardless of
+ whether the function does anything, should be removed from the ifdefs.
+ ---------------------------------------------------------------------------*/
+
+#if (defined(WIN32) && defined(USE_EF_UT_TIME))
+ /* For the Win32 environment, we may have to "prepare" the environment
+ prior to the tzset() call, to work around tzset() implementation bugs.
+ */
+ iz_w32_prepareTZenv();
+#endif
+
+#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
+# ifndef VALID_TIMEZONE
+# define VALID_TIMEZONE(tmp) \
+ (((tmp = getenv("TZ")) != NULL) && (*tmp != '\0'))
+# endif
+ {
+ char *p;
+ G.tz_is_valid = VALID_TIMEZONE(p);
+# ifndef SFX
+ if (!G.tz_is_valid) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(WarnInvalidTZ)));
+ error_in_archive = error = PK_WARN;
+ }
+# endif /* !SFX */
+ }
+#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
+
+/* For systems that do not have tzset() but supply this function using another
+ name (_tzset() or something similar), an appropiate "#define tzset ..."
+ should be added to the system specifc configuration section. */
+#if (!defined(T20_VMS) && !defined(MACOS) && !defined(RISCOS) && !defined(QDOS))
+#if (!defined(BSD) && !defined(MTS) && !defined(CMS_MVS) && !defined(TANDEM))
+ tzset();
+#endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Initialize the internal flag holding the mode of processing "overwrite
+ existing file" cases. We do not use the calling interface flags directly
+ because the overwrite mode may be changed by user interaction while
+ processing archive files. Such a change should not affect the option
+ settings as passed through the DLL calling interface.
+ In case of conflicting options, the 'safer' flag uO.overwrite_none takes
+ precedence.
+ ---------------------------------------------------------------------------*/
+ G.overwrite_mode = (uO.overwrite_none ? OVERWRT_NEVER :
+ (uO.overwrite_all ? OVERWRT_ALWAYS : OVERWRT_QUERY));
+
+/*---------------------------------------------------------------------------
+ Match (possible) wildcard zipfile specification with existing files and
+ attempt to process each. If no hits, try again after appending ".zip"
+ suffix. If still no luck, give up.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+ if ((error = do_seekable(__G__ 0)) == PK_NOZIP) {
+#ifdef EXE_EXTENSION
+ int len=strlen(G.argv0);
+
+ /* append .exe if appropriate; also .sfx? */
+ if ( (G.zipfn = (char *)malloc(len+sizeof(EXE_EXTENSION))) !=
+ (char *)NULL ) {
+ strcpy(G.zipfn, G.argv0);
+ strcpy(G.zipfn+len, EXE_EXTENSION);
+ error = do_seekable(__G__ 0);
+ free(G.zipfn);
+ G.zipfn = G.argv0; /* for "cannot find myself" message only */
+ }
+#endif /* EXE_EXTENSION */
+#ifdef WIN32
+ G.zipfn = G.argv0; /* for "cannot find myself" message only */
+#endif
+ }
+ if (error) {
+ if (error == IZ_DIR)
+ error_in_archive = PK_NOZIP;
+ else
+ error_in_archive = error;
+ if (error == PK_NOZIP)
+ Info(slide, 1, ((char *)slide, LoadFarString(CannotFindMyself),
+ G.zipfn));
+ }
+#ifdef CHEAP_SFX_AUTORUN
+ if (G.autorun_command[0] && !uO.qflag) { /* NO autorun without prompt! */
+ Info(slide, 0x81, ((char *)slide, LoadFarString(AutorunPrompt),
+ FnFilter1(G.autorun_command)));
+ if (fgets(G.answerbuf, 9, stdin) != (char *)NULL
+ && toupper(*G.answerbuf) == 'Y')
+ system(G.autorun_command);
+ else
+ Info(slide, 1, ((char *)slide, LoadFarString(NotAutoRunning)));
+ }
+#endif /* CHEAP_SFX_AUTORUN */
+
+#else /* !SFX */
+ NumWinFiles = NumLoseFiles = NumWarnFiles = 0;
+ NumMissDirs = NumMissFiles = 0;
+
+ while ((G.zipfn = do_wild(__G__ G.wildzipfn)) != (char *)NULL) {
+ Trace((stderr, "do_wild( %s ) returns %s\n", G.wildzipfn, G.zipfn));
+
+ lastzipfn = G.zipfn;
+
+ /* print a blank line between the output of different zipfiles */
+ if (!uO.qflag && error != PK_NOZIP && error != IZ_DIR
+#ifdef TIMESTAMP
+ && (!uO.T_flag || uO.zipinfo_mode)
+#endif
+ && (NumWinFiles+NumLoseFiles+NumWarnFiles+NumMissFiles) > 0)
+ (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+
+ if ((error = do_seekable(__G__ 0)) == PK_WARN)
+ ++NumWarnFiles;
+ else if (error == IZ_DIR)
+ ++NumMissDirs;
+ else if (error == PK_NOZIP)
+ ++NumMissFiles;
+ else if (error)
+ ++NumLoseFiles;
+ else
+ ++NumWinFiles;
+
+ Trace((stderr, "do_seekable(0) returns %d\n", error));
+ if (error != IZ_DIR && error > error_in_archive)
+ error_in_archive = error;
+#ifdef WINDLL
+ if (error == IZ_CTRLC) {
+ free_G_buffers(__G);
+ return error;
+ }
+#endif
+
+ } /* end while-loop (wildcard zipfiles) */
+
+ if ((NumWinFiles + NumWarnFiles + NumLoseFiles) == 0 &&
+ (NumMissDirs + NumMissFiles) == 1 && lastzipfn != (char *)NULL)
+ {
+#if (!defined(UNIX) && !defined(AMIGA)) /* filenames with wildcard characters */
+ if (iswild(G.wildzipfn)) {
+ if (iswild(lastzipfn)) {
+ NumMissDirs = NumMissFiles = 0;
+ error_in_archive = PK_COOL;
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotFindWildcardMatch), uO.zipinfo_mode?
+ LoadFarStringSmall(Zipnfo) : LoadFarStringSmall(Unzip),
+ G.wildzipfn));
+ }
+ } else
+#endif
+ {
+ char *p = lastzipfn + strlen(lastzipfn);
+
+ G.zipfn = lastzipfn;
+ strcpy(p, ZSUFX);
+
+ NumMissDirs = NumMissFiles = 0;
+ error_in_archive = PK_COOL;
+
+#if defined(UNIX) || defined(QDOS)
+ /* only Unix has case-sensitive filesystems */
+ /* Well FlexOS (sometimes) also has them, but support is per media */
+ /* and a pig to code for, so treat as case insensitive for now */
+ /* we do this under QDOS to check for .zip as well as _zip */
+ if ((error = do_seekable(__G__ 0)) == PK_NOZIP || error == IZ_DIR) {
+ if (error == IZ_DIR)
+ ++NumMissDirs;
+ strcpy(p, ALT_ZSUFX);
+ error = do_seekable(__G__ 1);
+ }
+#else
+ error = do_seekable(__G__ 1);
+#endif
+ Trace((stderr, "do_seekable(1) returns %d\n", error));
+ switch (error) {
+ case PK_WARN:
+ ++NumWarnFiles;
+ break;
+ case IZ_DIR:
+ ++NumMissDirs;
+ error = PK_NOZIP;
+ break;
+ case PK_NOZIP:
+ /* increment again => bug:
+ "1 file had no zipfile directory." */
+ /* ++NumMissFiles */ ;
+ break;
+ default:
+ if (error)
+ ++NumLoseFiles;
+ else
+ ++NumWinFiles;
+ break;
+ }
+
+ if (error > error_in_archive)
+ error_in_archive = error;
+#ifdef WINDLL
+ if (error == IZ_CTRLC) {
+ free_G_buffers(__G);
+ return error;
+ }
+#endif
+ }
+ }
+#endif /* ?SFX */
+
+/*---------------------------------------------------------------------------
+ Print summary of all zipfiles, assuming zipfile spec was a wildcard (no
+ need for a summary if just one zipfile).
+ ---------------------------------------------------------------------------*/
+
+#ifndef SFX
+ if (iswild(G.wildzipfn) && uO.qflag < 3
+#ifdef TIMESTAMP
+ && !(uO.T_flag && uO.qflag && !uO.zipinfo_mode)
+#endif
+ )
+ {
+ if ((NumMissFiles + NumLoseFiles + NumWarnFiles > 0 || NumWinFiles != 1)
+#ifdef TIMESTAMP
+ && !(uO.T_flag && !uO.zipinfo_mode)
+#endif
+ && !(uO.tflag && uO.qflag > 1))
+ (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0x401);
+ if ((NumWinFiles > 1) || (NumWinFiles == 1 &&
+ NumMissDirs + NumMissFiles + NumLoseFiles + NumWarnFiles > 0))
+ Info(slide, 0x401, ((char *)slide, LoadFarString(FilesProcessOK),
+ NumWinFiles, (NumWinFiles == 1)? " was" : "s were"));
+ if (NumWarnFiles > 0)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ArchiveWarning),
+ NumWarnFiles, (NumWarnFiles == 1)? "" : "s"));
+ if (NumLoseFiles > 0)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ArchiveFatalError),
+ NumLoseFiles, (NumLoseFiles == 1)? "" : "s"));
+ if (NumMissFiles > 0)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(FileHadNoZipfileDir), NumMissFiles,
+ (NumMissFiles == 1)? "" : "s"));
+ if (NumMissDirs == 1)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileWasDir)));
+ else if (NumMissDirs > 0)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ManyZipfilesWereDir), NumMissDirs));
+ if (NumWinFiles + NumLoseFiles + NumWarnFiles == 0)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoZipfileFound)));
+ }
+#endif /* !SFX */
+
+ /* free allocated memory */
+ free_G_buffers(__G);
+
+ return error_in_archive;
+
+} /* end function process_zipfiles() */
+
+
+
+
+
+/*****************************/
+/* Function free_G_buffers() */
+/*****************************/
+
+void free_G_buffers(__G) /* releases all memory allocated in global vars */
+ __GDEF
+{
+#ifndef SFX
+ unsigned i;
+#endif
+
+#ifdef SYSTEM_SPECIFIC_DTOR
+ SYSTEM_SPECIFIC_DTOR(__G);
+#endif
+
+ inflate_free(__G);
+ checkdir(__G__ (char *)NULL, END);
+
+#ifdef DYNALLOC_CRCTAB
+ if (CRC_32_TAB) {
+ free_crc_table();
+ CRC_32_TAB = NULL;
+ }
+#endif
+
+ if (G.key != (char *)NULL) {
+ free(G.key);
+ G.key = (char *)NULL;
+ }
+
+ if (G.extra_field != (uch *)NULL) {
+ free(G.extra_field);
+ G.extra_field = (uch *)NULL;
+ }
+
+#if (!defined(VMS) && !defined(SMALL_MEM))
+ /* VMS uses its own buffer scheme for textmode flush() */
+ if (G.outbuf2) {
+ free(G.outbuf2); /* malloc'd ONLY if unshrink and -a */
+ G.outbuf2 = (uch *)NULL;
+ }
+#endif
+
+ if (G.outbuf)
+ free(G.outbuf);
+ if (G.inbuf)
+ free(G.inbuf);
+ G.inbuf = G.outbuf = (uch *)NULL;
+
+#ifndef SFX
+ for (i = 0; i < DIR_BLKSIZ; i++) {
+ if (G.info[i].cfilname != (char Far *)NULL) {
+ zffree(G.info[i].cfilname);
+ G.info[i].cfilname = (char Far *)NULL;
+ }
+ }
+#endif
+
+#ifdef MALLOC_WORK
+ if (G.area.Slide) {
+ free(G.area.Slide);
+ G.area.Slide = (uch *)NULL;
+ }
+#endif
+
+} /* end function free_G_buffers() */
+
+
+
+
+
+/**************************/
+/* Function do_seekable() */
+/**************************/
+
+static int do_seekable(__G__ lastchance) /* return PK-type error code */
+ __GDEF
+ int lastchance;
+{
+#ifndef SFX
+ /* static int no_ecrec = FALSE; SKM: moved to globals.h */
+ int maybe_exe=FALSE;
+ int too_weird_to_continue=FALSE;
+#ifdef TIMESTAMP
+ time_t uxstamp;
+ ulg nmember = 0L;
+#endif
+#endif
+ int error=0, error_in_archive;
+
+
+/*---------------------------------------------------------------------------
+ Open the zipfile for reading in BINARY mode to prevent CR/LF translation,
+ which would corrupt the bit streams.
+ ---------------------------------------------------------------------------*/
+
+ if (SSTAT(G.zipfn, &G.statbuf) ||
+#ifdef THEOS
+ (error = S_ISLIB(G.statbuf.st_mode)) != 0 ||
+#endif
+ (error = S_ISDIR(G.statbuf.st_mode)) != 0)
+ {
+#ifndef SFX
+ if (lastchance && (uO.qflag < 3)) {
+#if defined(UNIX) || defined(QDOS)
+ if (G.no_ecrec)
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(CannotFindZipfileDirMsg), uO.zipinfo_mode?
+ LoadFarStringSmall(Zipnfo) : LoadFarStringSmall(Unzip),
+ G.wildzipfn, uO.zipinfo_mode? " " : "", G.wildzipfn,
+ G.zipfn));
+ else
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(CannotFindEitherZipfile), uO.zipinfo_mode?
+ LoadFarStringSmall(Zipnfo) : LoadFarStringSmall(Unzip),
+ G.wildzipfn, G.wildzipfn, G.zipfn));
+#else /* !(UNIX || QDOS) */
+ if (G.no_ecrec)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotFindZipfileDirMsg), uO.zipinfo_mode?
+ LoadFarStringSmall(Zipnfo) : LoadFarStringSmall(Unzip),
+ G.wildzipfn, uO.zipinfo_mode? " " : "", G.zipfn));
+ else
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CannotFindEitherZipfile), uO.zipinfo_mode?
+ LoadFarStringSmall(Zipnfo) : LoadFarStringSmall(Unzip),
+ G.wildzipfn, G.zipfn));
+#endif /* ?(UNIX || QDOS) */
+ }
+#endif /* !SFX */
+ return error? IZ_DIR : PK_NOZIP;
+ }
+ G.ziplen = G.statbuf.st_size;
+
+#ifndef SFX
+#if defined(UNIX) || defined(DOS_OS2_W32) || defined(THEOS)
+ if (G.statbuf.st_mode & S_IEXEC) /* no extension on Unix exes: might */
+ maybe_exe = TRUE; /* find unzip, not unzip.zip; etc. */
+#endif
+#endif /* !SFX */
+
+#ifdef VMS
+ if (check_format(__G)) /* check for variable-length format */
+ return PK_ERR;
+#endif
+
+ if (open_input_file(__G)) /* this should never happen, given */
+ return PK_NOZIP; /* the stat() test above, but... */
+
+/*---------------------------------------------------------------------------
+ Find and process the end-of-central-directory header. UnZip need only
+ check last 65557 bytes of zipfile: comment may be up to 65535, end-of-
+ central-directory record is 18 bytes, and signature itself is 4 bytes;
+ add some to allow for appended garbage. Since ZipInfo is often used as
+ a debugging tool, search the whole zipfile if zipinfo_mode is true.
+ ---------------------------------------------------------------------------*/
+
+ /* initialize the CRC table pointer (once) */
+ if (CRC_32_TAB == NULL) {
+ if ((CRC_32_TAB = get_crc_table()) == NULL) {
+ CLOSE_INFILE();
+ return PK_MEM;
+ }
+ }
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+ /* check out if specified extraction root directory exists */
+ if (uO.exdir != (char *)NULL && G.extract_flag) {
+ G.create_dirs = !uO.fflag;
+ if ((error = checkdir(__G__ uO.exdir, ROOT)) > MPN_INF_SKIP) {
+ /* out of memory, or file in way */
+ CLOSE_INFILE();
+ return (error == MPN_NOMEM ? PK_MEM : PK_ERR);
+ }
+ }
+#endif /* !SFX || SFX_EXDIR */
+
+ G.cur_zipfile_bufstart = 0;
+ G.inptr = G.inbuf;
+
+#if (!defined(WINDLL) && !defined(SFX))
+#ifdef TIMESTAMP
+ if (!uO.zipinfo_mode && !uO.qflag && !uO.T_flag)
+#else
+ if (!uO.zipinfo_mode && !uO.qflag)
+#endif
+#ifdef WIN32 /* Win32 console may require codepage conversion for G.zipfn */
+ Info(slide, 0, ((char *)slide, "Archive: %s\n", FnFilter1(G.zipfn)));
+#else
+ Info(slide, 0, ((char *)slide, "Archive: %s\n", G.zipfn));
+#endif
+#endif /* !WINDLL && !SFX */
+
+ if ((
+#ifndef NO_ZIPINFO
+ uO.zipinfo_mode &&
+ ((error_in_archive = find_ecrec(__G__ G.ziplen)) != 0 ||
+ (error_in_archive = zi_end_central(__G)) > PK_WARN))
+ || (!uO.zipinfo_mode &&
+#endif
+ ((error_in_archive = find_ecrec(__G__ MIN(G.ziplen,66000L))) != 0 ||
+ (error_in_archive = uz_end_central(__G)) > PK_WARN)))
+ {
+ CLOSE_INFILE();
+
+#ifdef SFX
+ ++lastchance; /* avoid picky compiler warnings */
+ return error_in_archive;
+#else
+ if (maybe_exe)
+ Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeExe),
+ G.zipfn));
+ if (lastchance)
+ return error_in_archive;
+ else {
+ G.no_ecrec = TRUE; /* assume we found wrong file: e.g., */
+ return PK_NOZIP; /* unzip instead of unzip.zip */
+ }
+#endif /* ?SFX */
+ }
+
+ if ((uO.zflag > 0) && !uO.zipinfo_mode) { /* unzip: zflag = comment ONLY */
+ CLOSE_INFILE();
+ return error_in_archive;
+ }
+
+/*---------------------------------------------------------------------------
+ Test the end-of-central-directory info for incompatibilities (multi-disk
+ archives) or inconsistencies (missing or extra bytes in zipfile).
+ ---------------------------------------------------------------------------*/
+
+#ifdef NO_MULTIPART
+ error = !uO.zipinfo_mode && (G.ecrec.number_this_disk == 1) &&
+ (G.ecrec.num_disk_start_cdir == 1);
+#else
+ error = !uO.zipinfo_mode && (G.ecrec.number_this_disk != 0);
+#endif
+
+#ifndef SFX
+ if (uO.zipinfo_mode &&
+ G.ecrec.number_this_disk != G.ecrec.num_disk_start_cdir)
+ {
+ if (G.ecrec.number_this_disk > G.ecrec.num_disk_start_cdir) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentDirNotInZipMsg), G.zipfn,
+ G.ecrec.number_this_disk, G.ecrec.num_disk_start_cdir));
+ error_in_archive = PK_FIND;
+ too_weird_to_continue = TRUE;
+ } else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(EndCentDirBogus), G.zipfn,
+ G.ecrec.number_this_disk, G.ecrec.num_disk_start_cdir));
+ error_in_archive = PK_WARN;
+ }
+#ifdef NO_MULTIPART /* concatenation of multiple parts works in some cases */
+ } else if (!uO.zipinfo_mode && !error && G.ecrec.number_this_disk != 0) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NoMultiDiskArcSupport),
+ G.zipfn));
+ error_in_archive = PK_FIND;
+ too_weird_to_continue = TRUE;
+#endif
+ }
+
+ if (!too_weird_to_continue) { /* (relatively) normal zipfile: go for it */
+ if (error) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(MaybePakBug),
+ G.zipfn));
+ error_in_archive = PK_WARN;
+ }
+#endif /* !SFX */
+ if ((G.extra_bytes = G.real_ecrec_offset-G.expect_ecrec_offset) <
+ (Z_OFF_T)0)
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(MissingBytes),
+ G.zipfn, (long)(-G.extra_bytes)));
+ error_in_archive = PK_ERR;
+ } else if (G.extra_bytes > 0) {
+ if ((G.ecrec.offset_start_central_directory == 0) &&
+ (G.ecrec.size_central_directory != 0)) /* zip 1.5 -go bug */
+ {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(NullCentDirOffset), G.zipfn));
+ G.ecrec.offset_start_central_directory = G.extra_bytes;
+ G.extra_bytes = 0;
+ error_in_archive = PK_ERR;
+ }
+#ifndef SFX
+ else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ExtraBytesAtStart), G.zipfn,
+ (long)G.extra_bytes, (G.extra_bytes == 1)? "":"s"));
+ error_in_archive = PK_WARN;
+ }
+#endif /* !SFX */
+ }
+
+ /*-----------------------------------------------------------------------
+ Check for empty zipfile and exit now if so.
+ -----------------------------------------------------------------------*/
+
+ if (G.expect_ecrec_offset==0L && G.ecrec.size_central_directory==0) {
+ if (uO.zipinfo_mode)
+ Info(slide, 0, ((char *)slide, "%sEmpty zipfile.\n",
+ uO.lflag>9? "\n " : ""));
+ else
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileEmpty),
+ G.zipfn));
+ CLOSE_INFILE();
+ return (error_in_archive > PK_WARN)? error_in_archive : PK_WARN;
+ }
+
+ /*-----------------------------------------------------------------------
+ Compensate for missing or extra bytes, and seek to where the start
+ of central directory should be. If header not found, uncompensate
+ and try again (necessary for at least some Atari archives created
+ with STZip, as well as archives created by J.H. Holm's ZIPSPLIT 1.1).
+ -----------------------------------------------------------------------*/
+
+ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+ if (error == PK_BADERR) {
+ CLOSE_INFILE();
+ return PK_BADERR;
+ }
+#ifdef OLD_SEEK_TEST
+ if (error != PK_OK || readbuf(__G__ G.sig, 4) == 0) {
+ CLOSE_INFILE();
+ return PK_ERR; /* file may be locked, or possibly disk error(?) */
+ }
+ if (strncmp(G.sig, central_hdr_sig, 4))
+#else
+ if ((error != PK_OK) || (readbuf(__G__ G.sig, 4) == 0) ||
+ strncmp(G.sig, central_hdr_sig, 4))
+#endif
+ {
+#ifndef SFX
+ long tmp = G.extra_bytes;
+#endif
+
+ G.extra_bytes = 0;
+ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+ if ((error != PK_OK) || (readbuf(__G__ G.sig, 4) == 0) ||
+ strncmp(G.sig, central_hdr_sig, 4))
+ {
+ if (error != PK_BADERR)
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentDirStartNotFound), G.zipfn,
+ LoadFarStringSmall(ReportMsg)));
+ CLOSE_INFILE();
+ return (error != PK_OK ? error : PK_BADERR);
+ }
+#ifndef SFX
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CentDirTooLong),
+ G.zipfn, -tmp));
+#endif
+ error_in_archive = PK_ERR;
+ }
+
+ /*-----------------------------------------------------------------------
+ Seek to the start of the central directory one last time, since we
+ have just read the first entry's signature bytes; then list, extract
+ or test member files as instructed, and close the zipfile.
+ -----------------------------------------------------------------------*/
+
+ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory);
+ if (error != PK_OK) {
+ CLOSE_INFILE();
+ return error;
+ }
+
+ Trace((stderr, "about to extract/list files (error = %d)\n",
+ error_in_archive));
+
+#ifdef DLL
+ /* G.fValidate is used only to look at an archive to see if
+ it appears to be a valid archive. There is no interest
+ in what the archive contains, nor in validating that the
+ entries in the archive are in good condition. This is
+ currently used only in the Windows DLLs for purposes of
+ checking archives within an archive to determine whether
+ or not to display the inner archives.
+ */
+ if (!G.fValidate)
+#endif
+ {
+#ifndef NO_ZIPINFO
+ if (uO.zipinfo_mode)
+ error = zipinfo(__G); /* ZIPINFO 'EM */
+ else
+#endif
+#ifndef SFX
+#ifdef TIMESTAMP
+ if (uO.T_flag)
+ error = get_time_stamp(__G__ &uxstamp, &nmember);
+ else
+#endif
+ if (uO.vflag && !uO.tflag && !uO.cflag)
+ error = list_files(__G); /* LIST 'EM */
+ else
+#endif /* !SFX */
+ error = extract_or_test_files(__G); /* EXTRACT OR TEST 'EM */
+
+ Trace((stderr, "done with extract/list files (error = %d)\n",
+ error));
+ }
+
+ if (error > error_in_archive) /* don't overwrite stronger error */
+ error_in_archive = error; /* with (for example) a warning */
+#ifndef SFX
+ } /* end if (!too_weird_to_continue) */
+#endif
+
+ CLOSE_INFILE();
+
+#ifdef TIMESTAMP
+ if (uO.T_flag && !uO.zipinfo_mode && (nmember > 0L)) {
+# ifdef WIN32
+ if (stamp_file(__G__ G.zipfn, uxstamp)) { /* TIME-STAMP 'EM */
+# else
+ if (stamp_file(G.zipfn, uxstamp)) { /* TIME-STAMP 'EM */
+# endif
+ if (uO.qflag < 3)
+ Info(slide, 0x201, ((char *)slide,
+ "warning: cannot set time for %s\n", G.zipfn));
+ if (error_in_archive < PK_WARN)
+ error_in_archive = PK_WARN;
+ }
+ }
+#endif
+ return error_in_archive;
+
+} /* end function do_seekable() */
+
+
+
+
+
+/*************************/
+/* Function find_ecrec() */
+/*************************/
+
+static int find_ecrec(__G__ searchlen) /* return PK-class error */
+ __GDEF
+ long searchlen;
+{
+ int i, numblks, found=FALSE;
+ Z_OFF_T tail_len;
+ ec_byte_rec byterec;
+
+
+/*---------------------------------------------------------------------------
+ Treat case of short zipfile separately.
+ ---------------------------------------------------------------------------*/
+
+ if (G.ziplen <= INBUFSIZ) {
+ lseek(G.zipfd, 0L, SEEK_SET);
+ if ((G.incnt = read(G.zipfd,(char *)G.inbuf,(unsigned int)G.ziplen))
+ == (int)G.ziplen)
+
+ /* 'P' must be at least (ECREC_SIZE+4) bytes from end of zipfile */
+ for (G.inptr = G.inbuf+(int)G.ziplen-(ECREC_SIZE+4);
+ G.inptr >= G.inbuf;
+ --G.inptr) {
+ if ( (*G.inptr == (uch)0x50) && /* ASCII 'P' */
+ !strncmp((char *)G.inptr, end_central_sig, 4)) {
+ G.incnt -= (int)(G.inptr - G.inbuf);
+ found = TRUE;
+ break;
+ }
+ }
+
+/*---------------------------------------------------------------------------
+ Zipfile is longer than INBUFSIZ: may need to loop. Start with short
+ block at end of zipfile (if not TOO short).
+ ---------------------------------------------------------------------------*/
+
+ } else {
+ if ((tail_len = G.ziplen % INBUFSIZ) > ECREC_SIZE) {
+#ifdef USE_STRM_INPUT
+ fseek((FILE *)G.zipfd, G.ziplen-tail_len, SEEK_SET);
+ G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);
+#else /* !USE_STRM_INPUT */
+ G.cur_zipfile_bufstart = lseek(G.zipfd, G.ziplen-tail_len,
+ SEEK_SET);
+#endif /* ?USE_STRM_INPUT */
+ if ((G.incnt = read(G.zipfd, (char *)G.inbuf,
+ (unsigned int)tail_len)) != (int)tail_len)
+ goto fail; /* it's expedient... */
+
+ /* 'P' must be at least (ECREC_SIZE+4) bytes from end of zipfile */
+ for (G.inptr = G.inbuf+(int)tail_len-(ECREC_SIZE+4);
+ G.inptr >= G.inbuf;
+ --G.inptr) {
+ if ( (*G.inptr == (uch)0x50) && /* ASCII 'P' */
+ !strncmp((char *)G.inptr, end_central_sig, 4)) {
+ G.incnt -= (int)(G.inptr - G.inbuf);
+ found = TRUE;
+ break;
+ }
+ }
+ /* sig may span block boundary: */
+ memcpy((char *)G.hold, (char *)G.inbuf, 3);
+ } else
+ G.cur_zipfile_bufstart = G.ziplen - tail_len;
+
+ /*-----------------------------------------------------------------------
+ Loop through blocks of zipfile data, starting at the end and going
+ toward the beginning. In general, need not check whole zipfile for
+ signature, but may want to do so if testing.
+ -----------------------------------------------------------------------*/
+
+ numblks = (int)((searchlen - tail_len + (INBUFSIZ-1)) / INBUFSIZ);
+ /* ==amount= ==done== ==rounding== =blksiz= */
+
+ for (i = 1; !found && (i <= numblks); ++i) {
+ G.cur_zipfile_bufstart -= INBUFSIZ;
+ lseek(G.zipfd, G.cur_zipfile_bufstart, SEEK_SET);
+ if ((G.incnt = read(G.zipfd,(char *)G.inbuf,INBUFSIZ))
+ != INBUFSIZ)
+ break; /* fall through and fail */
+
+ for (G.inptr = G.inbuf+INBUFSIZ-1; G.inptr >= G.inbuf;
+ --G.inptr)
+ if ((native(*G.inptr) == 'P') &&
+ !strncmp((char *)G.inptr, end_central_sig, 4)) {
+ G.incnt -= (int)(G.inptr - G.inbuf);
+ found = TRUE;
+ break;
+ }
+ /* sig may span block boundary: */
+ memcpy((char *)G.hold, (char *)G.inbuf, 3);
+ }
+ } /* end if (ziplen > INBUFSIZ) */
+
+/*---------------------------------------------------------------------------
+ Searched through whole region where signature should be without finding
+ it. Print informational message and die a horrible death.
+ ---------------------------------------------------------------------------*/
+
+fail:
+ if (!found) {
+ if (uO.qflag || uO.zipinfo_mode)
+ Info(slide, 0x401, ((char *)slide, "[%s]\n", G.zipfn));
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(CentDirEndSigNotFound)));
+ return PK_ERR; /* failed */
+ }
+
+/*---------------------------------------------------------------------------
+ Found the signature, so get the end-central data before returning. Do
+ any necessary machine-type conversions (byte ordering, structure padding
+ compensation) by reading data into character array and copying to struct.
+ ---------------------------------------------------------------------------*/
+
+ G.real_ecrec_offset = G.cur_zipfile_bufstart + (G.inptr-G.inbuf);
+#ifdef TEST
+ printf("\n found end-of-central-dir signature at offset %ld (%.8lXh)\n",
+ G.real_ecrec_offset, G.real_ecrec_offset);
+ printf(" from beginning of file; offset %d (%.4Xh) within block\n",
+ G.inptr-G.inbuf, G.inptr-G.inbuf);
+#endif
+
+ if (readbuf(__G__ (char *)byterec, ECREC_SIZE+4) == 0)
+ return PK_EOF;
+
+ G.ecrec.number_this_disk =
+ makeword(&byterec[NUMBER_THIS_DISK]);
+ G.ecrec.num_disk_start_cdir =
+ makeword(&byterec[NUM_DISK_WITH_START_CENTRAL_DIR]);
+ G.ecrec.num_entries_centrl_dir_ths_disk =
+ makeword(&byterec[NUM_ENTRIES_CENTRL_DIR_THS_DISK]);
+ G.ecrec.total_entries_central_dir =
+ makeword(&byterec[TOTAL_ENTRIES_CENTRAL_DIR]);
+ G.ecrec.size_central_directory =
+ makelong(&byterec[SIZE_CENTRAL_DIRECTORY]);
+ G.ecrec.offset_start_central_directory =
+ makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
+ G.ecrec.zipfile_comment_length =
+ makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
+
+ G.expect_ecrec_offset = G.ecrec.offset_start_central_directory +
+ G.ecrec.size_central_directory;
+ return PK_COOL;
+
+} /* end function find_ecrec() */
+
+
+
+
+
+/*****************************/
+/* Function uz_end_central() */
+/*****************************/
+
+int uz_end_central(__G) /* return PK-type error code */
+ __GDEF
+{
+ int error = PK_COOL;
+
+
+/*---------------------------------------------------------------------------
+ Get the zipfile comment (up to 64KB long), if any, and print it out.
+ Then position the file pointer to the beginning of the central directory
+ and fill buffer.
+ ---------------------------------------------------------------------------*/
+
+#ifdef WINDLL
+ /* for comment button: */
+ if ((!G.fValidate) && (G.lpUserFunctions != NULL))
+ G.lpUserFunctions->cchComment = G.ecrec.zipfile_comment_length;
+ if (G.ecrec.zipfile_comment_length && (uO.zflag > 0))
+#else /* !WINDLL */
+ if (G.ecrec.zipfile_comment_length && (uO.zflag > 0 ||
+ (uO.zflag == 0 &&
+#ifdef TIMESTAMP
+ !uO.T_flag &&
+#endif
+ !uO.qflag)))
+#endif /* ?WINDLL */
+ {
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+ if (do_string(__G__ G.ecrec.zipfile_comment_length, CHECK_AUTORUN)) {
+#else
+ if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY)) {
+#endif
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ZipfileCommTrunc1)));
+ error = PK_WARN;
+ }
+ }
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+ else if (G.ecrec.zipfile_comment_length) {
+ if (do_string(__G__ G.ecrec.zipfile_comment_length, CHECK_AUTORUN_Q)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(ZipfileCommTrunc1)));
+ error = PK_WARN;
+ }
+ }
+#endif
+ return error;
+
+} /* end function uz_end_central() */
+
+
+
+
+
+/************************************/
+/* Function process_cdir_file_hdr() */
+/************************************/
+
+int process_cdir_file_hdr(__G) /* return PK-type error code */
+ __GDEF
+{
+ int error;
+
+
+/*---------------------------------------------------------------------------
+ Get central directory info, save host and method numbers, and set flag
+ for lowercase conversion of filename, depending on the OS from which the
+ file is coming.
+ ---------------------------------------------------------------------------*/
+
+ if ((error = get_cdir_ent(__G)) != 0)
+ return error;
+
+ G.pInfo->hostver = G.crec.version_made_by[0];
+ G.pInfo->hostnum = MIN(G.crec.version_made_by[1], NUM_HOSTS);
+/* extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS); */
+
+ G.pInfo->lcflag = 0;
+ if (uO.L_flag == 1) /* name conversion for monocase systems */
+ switch (G.pInfo->hostnum) {
+ case FS_FAT_: /* PKZIP and zip -k store in uppercase */
+ case CPM_: /* like MS-DOS, right? */
+ case VM_CMS_: /* all caps? */
+ case MVS_: /* all caps? */
+ case TANDEM_:
+ case TOPS20_:
+ case VMS_: /* our Zip uses lowercase, but ASi's doesn't */
+ /* case Z_SYSTEM_: ? */
+ /* case QDOS_: ? */
+ G.pInfo->lcflag = 1; /* convert filename to lowercase */
+ break;
+
+ default: /* AMIGA_, FS_HPFS_, FS_NTFS_, MAC_, UNIX_, ATARI_, */
+ break; /* FS_VFAT_, ATHEOS_, BEOS_ (Z_SYSTEM_), THEOS_: */
+ /* no conversion */
+ }
+ else if (uO.L_flag > 1) /* let -LL force lower case for all names */
+ G.pInfo->lcflag = 1;
+
+ /* do Amigas (AMIGA_) also have volume labels? */
+ if (IS_VOLID(G.crec.external_file_attributes) &&
+ (G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ ||
+ G.pInfo->hostnum == FS_NTFS_ || G.pInfo->hostnum == ATARI_))
+ {
+ G.pInfo->vollabel = TRUE;
+ G.pInfo->lcflag = 0; /* preserve case of volume labels */
+ } else
+ G.pInfo->vollabel = FALSE;
+
+ /* this flag is needed to detect archives made by "PKZIP for Unix" when
+ deciding which kind of codepage conversion has to be applied to
+ strings (see do_string() function in fileio.c) */
+ G.pInfo->HasUxAtt = (G.crec.external_file_attributes & 0xffff0000L) != 0L;
+
+ return PK_COOL;
+
+} /* end function process_cdir_file_hdr() */
+
+
+
+
+
+/***************************/
+/* Function get_cdir_ent() */
+/***************************/
+
+int get_cdir_ent(__G) /* return PK-type error code */
+ __GDEF
+{
+ cdir_byte_hdr byterec;
+
+
+/*---------------------------------------------------------------------------
+ Read the next central directory entry and do any necessary machine-type
+ conversions (byte ordering, structure padding compensation--do so by
+ copying the data from the array into which it was read (byterec) to the
+ usable struct (crec)).
+ ---------------------------------------------------------------------------*/
+
+ if (readbuf(__G__ (char *)byterec, CREC_SIZE) == 0)
+ return PK_EOF;
+
+ G.crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0];
+ G.crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1];
+ G.crec.version_needed_to_extract[0] =
+ byterec[C_VERSION_NEEDED_TO_EXTRACT_0];
+ G.crec.version_needed_to_extract[1] =
+ byterec[C_VERSION_NEEDED_TO_EXTRACT_1];
+
+ G.crec.general_purpose_bit_flag =
+ makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
+ G.crec.compression_method =
+ makeword(&byterec[C_COMPRESSION_METHOD]);
+ G.crec.last_mod_dos_datetime =
+ makelong(&byterec[C_LAST_MOD_DOS_DATETIME]);
+ G.crec.crc32 =
+ makelong(&byterec[C_CRC32]);
+ G.crec.csize =
+ makelong(&byterec[C_COMPRESSED_SIZE]);
+ G.crec.ucsize =
+ makelong(&byterec[C_UNCOMPRESSED_SIZE]);
+ G.crec.filename_length =
+ makeword(&byterec[C_FILENAME_LENGTH]);
+ G.crec.extra_field_length =
+ makeword(&byterec[C_EXTRA_FIELD_LENGTH]);
+ G.crec.file_comment_length =
+ makeword(&byterec[C_FILE_COMMENT_LENGTH]);
+ G.crec.disk_number_start =
+ makeword(&byterec[C_DISK_NUMBER_START]);
+ G.crec.internal_file_attributes =
+ makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]);
+ G.crec.external_file_attributes =
+ makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]); /* LONG, not word! */
+ G.crec.relative_offset_local_header =
+ makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]);
+
+ return PK_COOL;
+
+} /* end function get_cdir_ent() */
+
+
+
+
+
+/*************************************/
+/* Function process_local_file_hdr() */
+/*************************************/
+
+int process_local_file_hdr(__G) /* return PK-type error code */
+ __GDEF
+{
+ local_byte_hdr byterec;
+
+
+/*---------------------------------------------------------------------------
+ Read the next local file header and do any necessary machine-type con-
+ versions (byte ordering, structure padding compensation--do so by copy-
+ ing the data from the array into which it was read (byterec) to the
+ usable struct (lrec)).
+ ---------------------------------------------------------------------------*/
+
+ if (readbuf(__G__ (char *)byterec, LREC_SIZE) == 0)
+ return PK_EOF;
+
+ G.lrec.version_needed_to_extract[0] =
+ byterec[L_VERSION_NEEDED_TO_EXTRACT_0];
+ G.lrec.version_needed_to_extract[1] =
+ byterec[L_VERSION_NEEDED_TO_EXTRACT_1];
+
+ G.lrec.general_purpose_bit_flag =
+ makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]);
+ G.lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]);
+ G.lrec.last_mod_dos_datetime = makelong(&byterec[L_LAST_MOD_DOS_DATETIME]);
+ G.lrec.crc32 = makelong(&byterec[L_CRC32]);
+ G.lrec.csize = makelong(&byterec[L_COMPRESSED_SIZE]);
+ G.lrec.ucsize = makelong(&byterec[L_UNCOMPRESSED_SIZE]);
+ G.lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
+ G.lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
+
+ if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
+ /* can't trust local header, use central directory: */
+ G.lrec.crc32 = G.pInfo->crc;
+ G.lrec.csize = G.pInfo->compr_size;
+ G.lrec.ucsize = G.pInfo->uncompr_size;
+ }
+
+ G.csize = (long)G.lrec.csize;
+
+ return PK_COOL;
+
+} /* end function process_local_file_hdr() */
+
+
+#ifdef USE_EF_UT_TIME
+
+/*******************************/
+/* Function ef_scan_for_izux() */
+/*******************************/
+
+unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime,
+ z_utim, z_uidgid)
+ ZCONST uch *ef_buf; /* buffer containing extra field */
+ unsigned ef_len; /* total length of extra field */
+ int ef_is_c; /* flag indicating "is central extra field" */
+ ulg dos_mdatetime; /* last_mod_file_date_time in DOS format */
+ iztimes *z_utim; /* return storage: atime, mtime, ctime */
+ ush *z_uidgid; /* return storage: uid and gid */
+{
+ unsigned flags = 0;
+ unsigned eb_id;
+ unsigned eb_len;
+ int have_new_type_eb = FALSE;
+ long i_time; /* buffer for Unix style 32-bit integer time value */
+#ifdef TIME_T_TYPE_DOUBLE
+ int ut_in_archive_sgn = 0;
+#else
+ int ut_zip_unzip_compatible = FALSE;
+#endif
+
+/*---------------------------------------------------------------------------
+ This function scans the extra field for EF_TIME, EF_IZUNIX2, EF_IZUNIX, or
+ EF_PKUNIX blocks containing Unix-style time_t (GMT) values for the entry's
+ access, creation, and modification time.
+ If a valid block is found, the time stamps are copied to the iztimes
+ structure (provided the z_utim pointer is not NULL).
+ If a IZUNIX2 block is found or the IZUNIX block contains UID/GID fields,
+ and the z_uidgid array pointer is valid (!= NULL), the owner info is
+ transfered as well.
+ The presence of an EF_TIME or EF_IZUNIX2 block results in ignoring all
+ data from probably present obsolete EF_IZUNIX blocks.
+ If multiple blocks of the same type are found, only the information from
+ the last block is used.
+ The return value is a combination of the EF_TIME Flags field with an
+ additional flag bit indicating the presence of valid UID/GID info,
+ or 0 in case of failure.
+ ---------------------------------------------------------------------------*/
+
+ if (ef_len == 0 || ef_buf == NULL || (z_utim == 0 && z_uidgid == NULL))
+ return 0;
+
+ TTrace((stderr,"\nef_scan_for_izux: scanning extra field of length %u\n",
+ ef_len));
+
+ while (ef_len >= EB_HEADSIZE) {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ TTrace((stderr,
+ "ef_scan_for_izux: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ switch (eb_id) {
+ case EF_TIME:
+ flags &= ~0x0ff; /* ignore previous IZUNIX or EF_TIME fields */
+ have_new_type_eb = TRUE;
+ if ( eb_len >= EB_UT_MINLEN && z_utim != NULL) {
+ unsigned eb_idx = EB_UT_TIME1;
+ TTrace((stderr,"ef_scan_for_izux: found TIME extra field\n"));
+ flags |= (ef_buf[EB_HEADSIZE+EB_UT_FLAGS] & 0x0ff);
+ if ((flags & EB_UT_FL_MTIME)) {
+ if ((eb_idx+4) <= eb_len) {
+ i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+ eb_idx += 4;
+ TTrace((stderr," UT e.f. modification time = %ld\n",
+ i_time));
+
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (dos_mdatetime == DOSTIME_MINIMUM) {
+ ut_in_archive_sgn = -1;
+ z_utim->mtime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (dos_mdatetime >= DOSTIME_2038_01_18) {
+ ut_in_archive_sgn = 1;
+ z_utim->mtime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else {
+ ut_in_archive_sgn = 0;
+ /* cannot determine sign of mtime;
+ without modtime: ignore complete UT field */
+ flags &= ~0x0ff; /* no time_t times available */
+ TTrace((stderr,
+ " UT modtime range error; ignore e.f.!\n"));
+ break; /* stop scanning this field */
+ }
+ } else {
+ /* cannot determine, safe assumption is FALSE */
+ ut_in_archive_sgn = 0;
+ z_utim->mtime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ ut_zip_unzip_compatible =
+ ((time_t)0x80000000L < (time_t)0L)
+ ? (dos_mdatetime == DOSTIME_MINIMUM)
+ : (dos_mdatetime >= DOSTIME_2038_01_18);
+ if (!ut_zip_unzip_compatible) {
+ /* UnZip interprets mtime differently than Zip;
+ without modtime: ignore complete UT field */
+ flags &= ~0x0ff; /* no time_t times available */
+ TTrace((stderr,
+ " UT modtime range error; ignore e.f.!\n"));
+ break; /* stop scanning this field */
+ }
+ } else {
+ /* cannot determine, safe assumption is FALSE */
+ ut_zip_unzip_compatible = FALSE;
+ }
+ z_utim->mtime = (time_t)i_time;
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ } else {
+ flags &= ~EB_UT_FL_MTIME;
+ TTrace((stderr," UT e.f. truncated; no modtime\n"));
+ }
+ }
+ if (ef_is_c) {
+ break; /* central version of TIME field ends here */
+ }
+
+ if (flags & EB_UT_FL_ATIME) {
+ if ((eb_idx+4) <= eb_len) {
+ i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+ eb_idx += 4;
+ TTrace((stderr," UT e.f. access time = %ld\n",
+ i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (ut_in_archive_sgn == -1)
+ z_utim->atime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (ut_in_archive_sgn == 1) {
+ z_utim->atime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else {
+ /* sign of 32-bit time is unknown -> ignore it */
+ flags &= ~EB_UT_FL_ATIME;
+ TTrace((stderr,
+ " UT access time range error: skip time!\n"));
+ }
+ } else {
+ z_utim->atime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+ !ut_zip_unzip_compatible) {
+ flags &= ~EB_UT_FL_ATIME;
+ TTrace((stderr,
+ " UT access time range error: skip time!\n"));
+ } else {
+ z_utim->atime = (time_t)i_time;
+ }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ } else {
+ flags &= ~EB_UT_FL_ATIME;
+ }
+ }
+ if (flags & EB_UT_FL_CTIME) {
+ if ((eb_idx+4) <= eb_len) {
+ i_time = (long)makelong((EB_HEADSIZE+eb_idx) + ef_buf);
+ TTrace((stderr," UT e.f. creation time = %ld\n",
+ i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (ut_in_archive_sgn == -1)
+ z_utim->ctime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (ut_in_archive_sgn == 1) {
+ z_utim->ctime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else {
+ /* sign of 32-bit time is unknown -> ignore it */
+ flags &= ~EB_UT_FL_CTIME;
+ TTrace((stderr,
+ " UT creation time range error: skip time!\n"));
+ }
+ } else {
+ z_utim->ctime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+ !ut_zip_unzip_compatible) {
+ flags &= ~EB_UT_FL_CTIME;
+ TTrace((stderr,
+ " UT creation time range error: skip time!\n"));
+ } else {
+ z_utim->ctime = (time_t)i_time;
+ }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ } else {
+ flags &= ~EB_UT_FL_CTIME;
+ }
+ }
+ }
+ break;
+
+ case EF_IZUNIX2:
+ if (!have_new_type_eb) {
+ flags &= ~0x0ff; /* ignore any previous IZUNIX field */
+ have_new_type_eb = TRUE;
+ }
+ if (eb_len >= EB_UX2_MINLEN && z_uidgid != NULL) {
+ z_uidgid[0] = makeword((EB_HEADSIZE+EB_UX2_UID) + ef_buf);
+ z_uidgid[1] = makeword((EB_HEADSIZE+EB_UX2_GID) + ef_buf);
+ flags |= EB_UX2_VALID; /* signal success */
+ }
+ break;
+
+ case EF_IZUNIX:
+ case EF_PKUNIX: /* PKUNIX e.f. layout is identical to IZUNIX */
+ if (eb_len >= EB_UX_MINLEN) {
+ TTrace((stderr,"ef_scan_for_izux: found %s extra field\n",
+ (eb_id == EF_IZUNIX ? "IZUNIX" : "PKUNIX")));
+ if (have_new_type_eb) {
+ break; /* Ignore IZUNIX extra field block ! */
+ }
+ if (z_utim != NULL) {
+ flags |= (EB_UT_FL_MTIME | EB_UT_FL_ATIME);
+ i_time = (long)makelong((EB_HEADSIZE+EB_UX_MTIME)+ef_buf);
+ TTrace((stderr," Unix EF modtime = %ld\n", i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (dos_mdatetime == DOSTIME_MINIMUM) {
+ ut_in_archive_sgn = -1;
+ z_utim->mtime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (dos_mdatetime >= DOSTIME_2038_01_18) {
+ ut_in_archive_sgn = 1;
+ z_utim->mtime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else {
+ ut_in_archive_sgn = 0;
+ /* cannot determine sign of mtime;
+ without modtime: ignore complete UT field */
+ flags &= ~0x0ff; /* no time_t times available */
+ TTrace((stderr,
+ " UX modtime range error: ignore e.f.!\n"));
+ }
+ } else {
+ /* cannot determine, safe assumption is FALSE */
+ ut_in_archive_sgn = 0;
+ z_utim->mtime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ ut_zip_unzip_compatible =
+ ((time_t)0x80000000L < (time_t)0L)
+ ? (dos_mdatetime == DOSTIME_MINIMUM)
+ : (dos_mdatetime >= DOSTIME_2038_01_18);
+ if (!ut_zip_unzip_compatible) {
+ /* UnZip interpretes mtime differently than Zip;
+ without modtime: ignore complete UT field */
+ flags &= ~0x0ff; /* no time_t times available */
+ TTrace((stderr,
+ " UX modtime range error: ignore e.f.!\n"));
+ }
+ } else {
+ /* cannot determine, safe assumption is FALSE */
+ ut_zip_unzip_compatible = FALSE;
+ }
+ z_utim->mtime = (time_t)i_time;
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ i_time = (long)makelong((EB_HEADSIZE+EB_UX_ATIME)+ef_buf);
+ TTrace((stderr," Unix EF actime = %ld\n", i_time));
+#ifdef TIME_T_TYPE_DOUBLE
+ if ((ulg)(i_time) & (ulg)(0x80000000L)) {
+ if (ut_in_archive_sgn == -1)
+ z_utim->atime =
+ (time_t)((long)i_time | (~(long)0x7fffffffL));
+ } else if (ut_in_archive_sgn == 1) {
+ z_utim->atime =
+ (time_t)((ulg)i_time & (ulg)0xffffffffL);
+ } else if (flags & 0x0ff) {
+ /* sign of 32-bit time is unknown -> ignore it */
+ flags &= ~EB_UT_FL_ATIME;
+ TTrace((stderr,
+ " UX access time range error: skip time!\n"));
+ }
+ } else {
+ z_utim->atime = (time_t)i_time;
+ }
+#else /* !TIME_T_TYPE_DOUBLE */
+ if (((ulg)(i_time) & (ulg)(0x80000000L)) &&
+ !ut_zip_unzip_compatible && (flags & 0x0ff)) {
+ /* atime not in range of UnZip's time_t */
+ flags &= ~EB_UT_FL_ATIME;
+ TTrace((stderr,
+ " UX access time range error: skip time!\n"));
+ } else {
+ z_utim->atime = (time_t)i_time;
+ }
+#endif /* ?TIME_T_TYPE_DOUBLE */
+ }
+ if (eb_len >= EB_UX_FULLSIZE && z_uidgid != NULL) {
+ z_uidgid[0] = makeword((EB_HEADSIZE+EB_UX_UID) + ef_buf);
+ z_uidgid[1] = makeword((EB_HEADSIZE+EB_UX_GID) + ef_buf);
+ flags |= EB_UX2_VALID;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Skip this extra field block */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return flags;
+}
+
+#endif /* USE_EF_UT_TIME */
+
+
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+
+#define SPARKID_2 0x30435241 /* = "ARC0" */
+
+/*******************************/
+/* Function getRISCOSexfield() */
+/*******************************/
+
+zvoid *getRISCOSexfield(ef_buf, ef_len)
+ ZCONST uch *ef_buf; /* buffer containing extra field */
+ unsigned ef_len; /* total length of extra field */
+{
+ unsigned eb_id;
+ unsigned eb_len;
+
+/*---------------------------------------------------------------------------
+ This function scans the extra field for a Acorn SPARK filetype ef-block.
+ If a valid block is found, the function returns a pointer to the start
+ of the SPARK_EF block in the extra field buffer. Otherwise, a NULL
+ pointer is returned.
+ ---------------------------------------------------------------------------*/
+
+ if (ef_len == 0 || ef_buf == NULL)
+ return NULL;
+
+ TTrace((stderr,"\ngetRISCOSexfield: scanning extra field of length %u\n",
+ ef_len));
+
+ while (ef_len >= EB_HEADSIZE) {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ TTrace((stderr,
+ "getRISCOSexfield: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ if (eb_id == EF_SPARK && (eb_len == 24 || eb_len == 20)) {
+ if (makelong(EB_HEADSIZE + ef_buf) == SPARKID_2) {
+ /* Return a pointer to the valid SPARK filetype ef block */
+ return (zvoid *)ef_buf;
+ }
+ }
+
+ /* Skip this extra field block */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return NULL;
+}
+
+#endif /* (RISCOS || ACORN_FTYPE_NFS) */
Property changes on: trunk/build/install/installer/process.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/res/commonc.manifest
===================================================================
--- trunk/build/install/installer/res/commonc.manifest (rev 0)
+++ trunk/build/install/installer/res/commonc.manifest 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity version="3.1.0.0" processorArchitecture="*" name="JBoss Installer" type="win32" />
+<description>JBoss Windows Installer</description>
+<dependency>
+<dependentAssembly>
+<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
+</dependentAssembly>
+</dependency>
+</assembly>
Property changes on: trunk/build/install/installer/res/commonc.manifest
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/res/jboss.ico
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/installer/res/jboss.ico
___________________________________________________________________
Name: svn:mime-type
+ image/x-icon
Added: trunk/build/install/installer/res/jbosstop.bmp
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/installer/res/jbosstop.bmp
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/build/install/installer/res/jbosstop.png
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/installer/res/jbosstop.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: trunk/build/install/installer/res/lgpl.htm
===================================================================
--- trunk/build/install/installer/res/lgpl.htm (rev 0)
+++ trunk/build/install/installer/res/lgpl.htm 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,526 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HEAD lang="en">
+ <META http-equiv="Content-Type" content="text/html; charset=windows-1252">
+ <META http-equiv="MSThemeCompatible" content="Yes">
+ <TITLE>GNU Lesser General Public License</TITLE>
+ <STYLE type="text/css">
+ BODY, TABLE, TR, TD, UL, OL, LI, P {
+ font-family: Serife, Verdana, Helvetica, Tahoma;
+ font-size: 11px;
+ font-style: normal;
+ text-decoration: none;
+ background-color: Window;
+ color: WindowText;
+ }
+ PRE {
+ font-size: 10px;
+ font-style: normal;
+ text-decoration: none;
+ background-color: Window;
+ color: WindowText;
+ }
+ H1 {
+ font-family: Serife, Verdana, Helvetica, Tahoma;
+ font-size: 18px;
+ }
+ H2 {
+ font-family: Serife, Verdana, Helvetica, Tahoma;
+ font-size: 13px;
+ }
+ </STYLE>
+</HEAD>
+<BODY scroll="auto" topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0"
+ marginwidth="0" marginheight="0">
+<DIV style="position:absolute; top:0px; left:4px; width:482px;">
+<BR/>
+<h1>GNU Lesser General Public License</h1>
+<p>
+Version 2.1, February 1999
+<p>
+<pre>
+Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+</pre>
+
+
+<h2>Preamble</h2>
+
+<p>
+The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+<p>
+This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+<p>
+When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+<p>
+To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+<p>
+For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+<p>
+We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+<p>
+To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+<p>
+Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+<p>
+Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+<p>
+When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+<p>
+We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+<p>
+For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+<p>
+In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+<p>
+Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+<p>
+The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+<p>
+
+<h2>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</h2>
+
+<p>
+<strong>0.</strong>
+This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+<p>
+A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+<p>
+The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+<p>
+"Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+<p>
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+<p>
+<strong>1.</strong>
+You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+<p>
+You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+<p>
+<strong>2.</strong>
+You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+<p>
+<ul>
+<li><strong>a)</strong>
+The modified work must itself be a software library.
+ <li><strong>b)</strong>
+You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ <li><strong>c)</strong>
+You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ <li><strong>d)</strong>
+If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+ <p>
+(For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+ <p>
+These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.
+ <p>
+Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.
+ <p>
+In addition, mere aggregation of another work not based on the Library
+ with the Library (or with a work based on the Library) on a volume of
+ a storage or distribution medium does not bring the other work under
+ the scope of this License.
+</ul>
+<p>
+<strong>3.</strong>
+You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+<p>
+Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+<p>
+This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+<p>
+<strong>4.</strong>
+You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+<p>
+If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+<p>
+<strong>5.</strong>
+A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+<p>
+However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+<p>
+When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+<p>
+If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+<p>
+Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+<p>
+<strong>6.</strong>
+As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+<p>
+You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+<p>
+<ul>
+<li><strong>a)</strong> Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ <li><strong>b)</strong> Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ <li><strong>c)</strong> Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ <li><strong>d)</strong> If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ <li><strong>e)</strong> Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+</ul>
+<p>
+For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+<p>
+It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+<p>
+<strong>7.</strong> You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+<p>
+<ul>
+<li><strong>a)</strong> Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ <li><strong>b)</strong> Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+</ul>
+<p>
+<strong>8.</strong> You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+<p>
+<strong>9.</strong>
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+<p>
+<strong>10.</strong>
+Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+<p>
+<strong>11.</strong>
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+<p>
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+<p>
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+<p>
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+<p>
+<strong>12.</strong>
+If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+<p>
+<strong>13.</strong>
+The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+<p>
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+<p>
+<strong>14.</strong>
+If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+<p>
+<strong>NO WARRANTY</strong>
+<p>
+<strong>15.</strong>
+BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+<p>
+<strong>16.</strong>
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+<p>
+<h2>END OF TERMS AND CONDITIONS</h2>
+</DIV>
+</BODY>
+</HTML>
Added: trunk/build/install/installer/res/lgpl.rtf
===================================================================
--- trunk/build/install/installer/res/lgpl.rtf (rev 0)
+++ trunk/build/install/installer/res/lgpl.rtf 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,85 @@
+{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Verdana;}{\f1\fmodern\fprq1\fcharset0 Courier New;}}
+{\colortbl ;\red255\green255\blue255;}
+{\stylesheet{ Normal;}{\s1 heading 1;}{\s2 heading 2;}}
+{\*\generator Msftedit 5.41.21.2508;}\viewkind4\uc1\pard\f0\fs17\par
+\pard\s1\sb100\sa100\kerning36\b\fs27 GNU Lesser General Public License\par
+\pard\cbpat1\sb100\sa100\kerning0\b0\fs17 Version 2.1, February 1999 \par
+\pard\cbpat1\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\fs15\par
+\f1 Copyright (C) 1991, 1999 Free Software Foundation, Inc.\par
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\par
+Everyone is permitted to copy and distribute verbatim copies\par
+of this license document, but changing it is not allowed.\par
+\par
+[This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]\par
+\pard\s2\sb100\sa100\b\f0\fs20 Preamble\par
+\pard\cbpat1\sb100\sa100\b0\fs17 The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. \par
+This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. \par
+When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. \par
+To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. \par
+For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. \par
+We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. \par
+To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. \par
+Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. \par
+Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. \par
+When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. \par
+We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. \par
+For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. \par
+In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. \par
+Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. \par
+The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. \par
+\pard\s2\sb100\sa100\b\fs20 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\par
+\pard\cbpat1\sb100\sa100\fs17 0.\b0 This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". \par
+A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. \par
+The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) \par
+"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. \par
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. \par
+\b 1.\b0 You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. \par
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. \par
+\b 2.\b0 You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: \par
+\pard\cbpat1\fi-360\li720\sb100\sa100\tx720\fs20\'b7\tab\b\fs17 a)\b0 The modified work must itself be a software library. \par
+\pard\cbpat1\fi-360\li720\sb100\sa100\fs20\'b7\tab\b\fs17 b)\b0 You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. \par
+\fs20\'b7\tab\b\fs17 c)\b0 You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. \par
+\fs20\'b7\tab\b\fs17 d)\b0 If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. \par
+\pard\cbpat1\li720\sb100\sa100 (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) \par
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. \par
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. \par
+In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. \par
+\pard\cbpat1\sb100\sa100\b 3.\b0 You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. \par
+Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. \par
+This option is useful when you wish to copy part of the code of the Library into a program that is not a library. \par
+\b 4.\b0 You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. \par
+If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. \par
+\b 5.\b0 A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. \par
+However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. \par
+When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. \par
+If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) \par
+Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. \par
+\b 6.\b0 As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. \par
+You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: \par
+\pard\cbpat1\fi-360\li720\sb100\sa100\tx720\fs20\'b7\tab\b\fs17 a)\b0 Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) \par
+\pard\cbpat1\fi-360\li720\sb100\sa100\fs20\'b7\tab\b\fs17 b)\b0 Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. \par
+\fs20\'b7\tab\b\fs17 c)\b0 Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. \par
+\fs20\'b7\tab\b\fs17 d)\b0 If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. \par
+\fs20\'b7\tab\b\fs17 e)\b0 Verify that the user has already received a copy of these materials or that you have already sent this user a copy. \par
+\pard\cbpat1\sb100\sa100 For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. \par
+It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. \par
+\b 7.\b0 You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: \par
+\pard\cbpat1\fi-360\li720\sb100\sa100\tx720\fs20\'b7\tab\b\fs17 a)\b0 Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. \par
+\pard\cbpat1\fi-360\li720\sb100\sa100\fs20\'b7\tab\b\fs17 b)\b0 Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. \par
+\pard\cbpat1\sb100\sa100\b 8.\b0 You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. \par
+\b 9.\b0 You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. \par
+\b 10.\b0 Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. \par
+\b 11.\b0 If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. \par
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. \par
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. \par
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. \par
+\b 12.\b0 If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. \par
+\b 13.\b0 The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. \par
+Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. \par
+\b 14.\b0 If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. \par
+\b NO WARRANTY\b0 \par
+\b 15.\b0 BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. \par
+\b 16.\b0 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. \par
+\pard\s2\sb100\sa100\b\fs20 END OF TERMS AND CONDITIONS\par
+}
+
\ No newline at end of file
Added: trunk/build/install/installer/res/lgplmain.htm
===================================================================
--- trunk/build/install/installer/res/lgplmain.htm (rev 0)
+++ trunk/build/install/installer/res/lgplmain.htm 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,147 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HEAD lang="en">
+ <META http-equiv="Content-Type" content="text/html; charset=windows-1252">
+ <META http-equiv="MSThemeCompatible" content="Yes">
+ <TITLE>Accept License Agreement</TITLE>
+ <STYLE type="text/css">
+ BODY, TABLE, TR, TD, UL, OL, LI, P {
+ font-family: MS Shell Dlg;
+ font-size: 10px;
+ font-style: normal;
+ text-decoration: none;
+ background-color: ButtonFace;
+ color: ButtonText;
+ }
+ INPUT {
+ font-family: MS Shell Dlg;
+ font-size: 10px;
+ }
+ TH {
+ font-family: MS Shell Dlg;
+ font-size: 10px;
+ font-style: normal;
+ text-decoration: none;
+ text-align: left;
+ line-height: 22px;
+ background-color: ActiveCaption;
+ color: CaptionText;
+ }
+ H1 {
+ font-family: Serife, Verdana, Helvetica, Arial, Tahoma;
+ font-size: 24px;
+ }
+ H2 {
+ font-family: Serife, Verdana, Helvetica, Arial, Tahoma;
+ font-size: 20px;
+ }
+ H3 {
+ font-family: Serife, Verdana, Helvetica, Arial, Tahoma;
+ font-size: 18px;
+ }
+ H4 {
+ font-family: Serife, Verdana, Helvetica, Arial, Tahoma;
+ font-size: 13px;
+ }
+ A {
+ color: blue;
+ }
+ IFRAME {
+ border-left:0px;
+ border-right:0px;
+ border-top:1px solid;
+ border-top-color: ActiveBorder;
+ border-bottom:1px solid;
+ border-bottom-color: ActiveBorder;
+ }
+ .hide {
+ display: none;
+ visibility: hidden;
+ }
+ .show {
+ display: block;
+ visibility: visible;
+ }
+ </STYLE>
+ <SCRIPT language="JScript">
+
+ function pageOnLoad()
+ {
+ window.returnValue = null;
+ if (window.dialogArguments != null) {
+ var args;
+ args = window.dialogArguments.split("\t");
+ for (i = 0; i < args.length; i++) {
+ try {
+ obj = eval("val" + i);
+ if (obj != null)
+ obj.value = args[i];
+ } catch (err) {
+ // Nothing
+ }
+ }
+ }
+ iLicense.focus();
+ return true;
+ }
+
+ function okClick()
+ {
+ rv = "OK";
+ for (i = 0; i < 4; i++) {
+ try {
+ obj = eval("val" + i);
+ if (obj != null) {
+ rv = rv + "\t" + obj.value;
+ }
+ } catch (err) {
+ // Nothing
+ }
+ }
+ window.returnValue = rv;
+ window.close();
+ }
+
+ function cancelClick()
+ {
+ window.returnValue = "CANCEL";
+ window.close();
+ }
+
+ function onAcceptClick()
+ {
+ if (accept.checked)
+ ok.disabled=false;
+ else
+ ok.disabled=true;
+ }
+ </SCRIPT>
+</HEAD>
+<BODY scroll="no" topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0"
+ marginwidth="0" marginheight="0" onload="pageOnLoad(); return true;">
+<DIV style="position:absolute; top:0px; left:0px; width=505px; height:360px; border:0px solid;">
+<DIV style="position:absolute; top:0px; left:0px; width=505px; height:48px;">
+<IMG src="PNG/IMG_JBOSSTOP" border="0"/>
+</DIV>
+<DIV style="position:absolute; top:48px; left:0px; width=505px;">
+<IFRAME src="HTML_LGPL" id="iLicense" FRAMEBORDER=0 SCROLLING=YES style="width: 100%; height: 240px;"></IFRAME>
+</DIV>
+<DIV style="position:absolute; top:296px; left:6px; width=505px; height:48px;">
+ <strong style="color:red;">Required: </strong> You must accept the license agreement to install the product.<br/>
+<INPUT type="checkbox" id="accept" onclick="onAcceptClick();"/> Accept License Agreement
+</DIV>
+<DIV style="position:absolute; top:336px; left:10px; width=300px;">
+<IMG src="PNG/IMG_REDHAT16" border="0" width=16 height=16/> Copyright � 2008 Red Hat� Middleware, LLC.
+</DIV>
+<DIV style="position:absolute; top:310px; left:300px;">
+<TABLE cellspacing="0" style="margin:6px;">
+ <TR>
+ <TD align="right">
+ <INPUT type="button" value="Accept" disabled id="ok" style="width: 88px; height: 24px; cursor: hand;" onclick="okClick();"/>
+ <INPUT type="button" value="Decline" id="cancel" style="width: 88px; height: 24px; cursor: hand;" onclick="cancelClick();"/>
+ </TD>
+ </TR>
+</TABLE>
+</DIV>
+</DIV>
+</BODY>
+</HTML>
Added: trunk/build/install/installer/res/redhat.ico
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/installer/res/redhat.ico
___________________________________________________________________
Name: svn:mime-type
+ image/x-icon
Added: trunk/build/install/installer/res/redhat16.png
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/installer/res/redhat16.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: trunk/build/install/installer/res/redhat32.png
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/installer/res/redhat32.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: trunk/build/install/installer/res/redhat48.png
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/installer/res/redhat48.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: trunk/build/install/installer/sinstall.h
===================================================================
--- trunk/build/install/installer/sinstall.h (rev 0)
+++ trunk/build/install/installer/sinstall.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,130 @@
+/*
+ * SINSTALL - JBoss Installer
+ *
+ * Copyright(c) 2007 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#ifndef SINSTALL_H
+#define SINSTALL_H
+
+/*
+ * Ignore most warnings (back down to /W3) for poorly constructed headers
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1200
+#pragma warning(push, 3)
+#endif
+
+/* disable or reduce the frequency of...
+ * C4057: indirection to slightly different base types
+ * C4075: slight indirection changes (unsigned short* vs short[])
+ * C4100: unreferenced formal parameter
+ * C4127: conditional expression is constant
+ * C4163: '_rotl64' : not available as an intrinsic function
+ * C4201: nonstandard extension nameless struct/unions
+ * C4244: int to char/short - precision loss
+ * C4514: unreferenced inline function removed
+ */
+#pragma warning(disable: 4100 4127 4163 4201 4514; once: 4057 4075 4244)
+
+/* Ignore Microsoft's interpretation of secure development
+ * and the POSIX string handling API
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#pragma warning(disable: 4996)
+#endif
+
+#ifndef _WINDOWS_
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#ifndef _WIN32_WINNT
+/* Restrict the server to a subset of Windows 2000 header files by default
+ */
+#define _WIN32_WINNT 0x0500
+#endif
+#endif
+// #define _WIN32_DCOM
+
+#include <windows.h>
+#include <windowsx.h>
+#include <commdlg.h>
+#include <commctrl.h>
+#include <objbase.h>
+#include <shlobj.h>
+#include <shlwapi.h>
+#include <shellapi.h>
+#include <zmouse.h>
+#include <richedit.h>
+#include <urlmon.h>
+#include <mshtmhst.h>
+#include <lm.h>
+#include <psapi.h>
+
+#define IDC_STATIC -1
+#define IDC_APPLICATION 100
+#define IDI_MAINICON 101
+#define IDI_RHELICON 102
+
+#define IDS_APPLICATION 150
+#define IDS_APPDESCRIPTION 151
+#define IDS_APPVERSION 152
+#define IDS_APPCOPYRIGHT 153
+#define IDS_APPFULLNAME 154
+#define IDS_ALLFILES 155
+#define IDS_DLLFILES 156
+#define IDS_EXEFILES 157
+#define IDS_PPIMAGE 158
+
+
+#define IDD_ABOUTBOX 250
+#define IDC_LICENSE 251
+#define IDR_LICENSE 252
+#define IAB_SYSINF 253
+#define IDC_ABOUTAPP 254
+
+#define SIZ_BUFLEN 1024
+#define SIZ_BUFMAX (SIZ_BUFLEN - 1)
+#define IS_INVALID_HANDLE(x) (((x) == NULL || (x) == INVALID_HANDLE_VALUE))
+
+
+BOOL GuiInitialize();
+BOOL GuiTerminate();
+LPSTR GuiLoadResource(UINT, UINT);
+void GuiCenterWindow(HWND);
+BOOL GuiBrowseForFolder(HWND, LPCSTR, LPSTR);
+void GuiAboutBox(HWND);
+
+HICON gui_h16Icon;
+HICON gui_h32Icon;
+HICON gui_h48Icon;
+HMODULE gui_hMSHTML;
+
+HANDLE DHTMLDialogInit(HINSTANCE, LPCSTR);
+void DHTMLDialogClose(HANDLE);
+BOOL DHTMLDialogRun(HWND, HANDLE, LPCSTR, DWORD, DWORD, LPCSTR);
+LPSTR DHTMLDialogResult(HANDLE);
+
+#endif /* SINSTALL_H */
Property changes on: trunk/build/install/installer/sinstall.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/sinstall.rc
===================================================================
--- trunk/build/install/installer/sinstall.rc (rev 0)
+++ trunk/build/install/installer/sinstall.rc 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,117 @@
+/*
+ * SINSTALL - JBoss Installer
+ *
+ * Copyright(c) 2007 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#include "sinstall.h"
+
+#define STR_COPYRIGHT "Copyright � 2008 Red Hat Middleware, LLC. " \
+ "or its licensors, as applicable."
+
+#define STR_LICENSE "Distributable under LGPL license. " \
+ "See terms of license at gnu.org."
+
+#define STR_COMPANY "Red Hat�, Inc."
+#define STR_TRADEMARK "� Red Hat Inc."
+#define STR_PRODUCT "JBoss Installer"
+#define STR_DESCR "JBoss Windows Installer"
+
+#define STR_VERSION "1.0.0.0"
+
+IDI_MAINICON ICON "res/jboss.ico"
+IDI_RHELICON ICON "res/redhat.ico"
+IDR_LICENSE RTF "res/lgpl.rtf"
+IDB_JBOSSTOP BITMAP "res/jbosstop.bmp"
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "res/commonc.manifest"
+
+IMG_REDHAT48 PNG "res/redhat48.png"
+IMG_REDHAT32 PNG "res/redhat32.png"
+IMG_REDHAT16 PNG "res/redhat16.png"
+IMG_JBOSSTOP PNG "res/jbosstop.png"
+HTML_LGPLMAIN HTML "res/lgplmain.htm"
+HTML_LGPL HTML "res/lgpl.htm"
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 337, 187
+STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION STR_PRODUCT
+FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
+BEGIN
+ DEFPUSHBUTTON "&OK",IDOK,285,150,50,14
+ CONTROL "",IDC_LICENSE,"RichEdit20A",ES_MULTILINE |
+ ES_READONLY | WS_BORDER | WS_VSCROLL,0,31,335,115
+ CONTROL "IDB_JBOSSTOP",IDC_STATIC,"Static",SS_BITMAP|0x00000040L,0,0,337,30
+ LTEXT " ",IDC_ABOUTAPP,2,150,270,12
+ LTEXT "Copyright � 2008 Red Hat Middleware, LLC.",IDC_STATIC,2,160,270,12
+ LTEXT "http://www.jboss.org",IDC_STATIC,2,170,270,12
+ PUSHBUTTON "&System Info",IAB_SYSINF,285,170,50,14
+END
+
+STRINGTABLE
+BEGIN
+ IDS_APPLICATION STR_PRODUCT
+ IDS_APPVERSION "Version " STR_VERSION
+ IDS_APPFULLNAME STR_PRODUCT " Version " STR_VERSION
+ IDS_APPCOPYRIGHT "Copyright � 2008 Red Hat Middleware, LLC."
+ IDS_APPDESCRIPTION "JBoss Windows Installer"
+ IDS_ALLFILES "All Files (*.*)\0*.*\0"
+ IDS_DLLFILES "Dynamic Link Libraries (*.dll)\0*.dll\0"
+ IDS_EXEFILES "Executables (*.exe)\0*.exe\0"
+ IDS_PPIMAGE "Select Executable Image"
+END
+
+
+1 VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x3fL
+#if defined(_DEBUG)
+ FILEFLAGS 0x03L
+#else
+ FILEFLAGS 0x02L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", STR_COPYRIGHT "\0"
+ VALUE "CompanyName", STR_COMPANY "\0"
+ VALUE "FileDescription", STR_PRODUCT "\0"
+ VALUE "FileVersion", STR_VERSION
+ VALUE "InternalName", STR_PRODUCT "\0"
+ VALUE "LegalCopyright", STR_COPYRIGHT "\0"
+ VALUE "OriginalFilename", "sinstall.exe\0"
+ VALUE "ProductName", STR_PRODUCT "\0"
+ VALUE "ProductVersion", STR_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
Added: trunk/build/install/installer/ttyio.c
===================================================================
--- trunk/build/install/installer/ttyio.c (rev 0)
+++ trunk/build/install/installer/ttyio.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,700 @@
+/*
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ ttyio.c
+
+ This file contains routines for doing console input/output, including code
+ for non-echoing input. It is used by the encryption/decryption code but
+ does not contain any restricted code itself. This file is shared between
+ Info-ZIP's Zip and UnZip.
+
+ Contains: echo() (VMS only)
+ Echon() (Unix only)
+ Echoff() (Unix only)
+ screensize() (Unix only)
+ zgetch() (Unix, VMS, and non-Unix/VMS versions)
+ getp() ("PC," Unix/Atari/Be, VMS/VMCMS/MVS)
+
+ ---------------------------------------------------------------------------*/
+
+#define __TTYIO_C /* identifies this source module */
+
+#include "zip.h"
+#include "crypt.h"
+
+#if (CRYPT || (defined(UNZIP) && !defined(FUNZIP)))
+/* Non-echo console/keyboard input is needed for (en/de)cryption's password
+ * entry, and for UnZip(SFX)'s MORE and Pause features.
+ * (The corresponding #endif is found at the end of this module.)
+ */
+
+#include "ttyio.h"
+
+#ifndef PUTC
+# define PUTC putc
+#endif
+
+#ifdef ZIP
+# ifdef GLOBAL /* used in Amiga system headers, maybe others too */
+# undef GLOBAL
+# endif
+# define GLOBAL(g) g
+#else
+# define GLOBAL(g) G.g
+#endif
+
+#if (defined(__ATHEOS__) || defined(__BEOS__)) /* why yes, we do */
+# define HAVE_TERMIOS_H
+#endif
+
+#ifdef _POSIX_VERSION
+# ifndef USE_POSIX_TERMIOS
+# define USE_POSIX_TERMIOS /* use POSIX style termio (termios) */
+# endif
+# ifndef HAVE_TERMIOS_H
+# define HAVE_TERMIOS_H /* POSIX termios.h */
+# endif
+#endif /* _POSIX_VERSION */
+
+#ifdef UNZIP /* Zip handles this with the unix/configure script */
+# ifndef _POSIX_VERSION
+# if (defined(SYSV) || defined(CRAY)) && !defined(__MINT__)
+# ifndef USE_SYSV_TERMIO
+# define USE_SYSV_TERMIO
+# endif
+# ifdef COHERENT
+# ifndef HAVE_TERMIO_H
+# define HAVE_TERMIO_H
+# endif
+# ifdef HAVE_SYS_TERMIO_H
+# undef HAVE_SYS_TERMIO_H
+# endif
+# else /* !COHERENT */
+# ifdef HAVE_TERMIO_H
+# undef HAVE_TERMIO_H
+# endif
+# ifndef HAVE_SYS_TERMIO_H
+# define HAVE_SYS_TERMIO_H
+# endif
+# endif /* ?COHERENT */
+# endif /* (SYSV || CRAY) && !__MINT__ */
+# endif /* !_POSIX_VERSION */
+# if !(defined(BSD4_4) || defined(SYSV) || defined(__convexc__))
+# ifndef NO_FCNTL_H
+# define NO_FCNTL_H
+# endif
+# endif /* !(BSD4_4 || SYSV || __convexc__) */
+#endif /* UNZIP */
+
+#ifdef HAVE_TERMIOS_H
+# ifndef USE_POSIX_TERMIOS
+# define USE_POSIX_TERMIOS
+# endif
+#endif
+
+#if (defined(HAVE_TERMIO_H) || defined(HAVE_SYS_TERMIO_H))
+# ifndef USE_SYSV_TERMIO
+# define USE_SYSV_TERMIO
+# endif
+#endif
+
+#if (defined(UNZIP) && !defined(FUNZIP) && defined(UNIX) && defined(MORE))
+# include <sys/ioctl.h>
+# define GOT_IOCTL_H
+ /* int ioctl OF((int, int, zvoid *)); GRR: may need for some systems */
+#endif
+
+#ifndef HAVE_WORKING_GETCH
+ /* include system support for switching of console echo */
+# ifdef VMS
+# include <descrip.h>
+# include <iodef.h>
+# include <ttdef.h>
+# include <starlet.h>
+# include <ssdef.h>
+# else /* !VMS */
+# ifdef HAVE_TERMIOS_H
+# include <termios.h>
+# define sgttyb termios
+# define sg_flags c_lflag
+# define GTTY(f, s) tcgetattr(f, (zvoid *) s)
+# define STTY(f, s) tcsetattr(f, TCSAFLUSH, (zvoid *) s)
+# else /* !HAVE_TERMIOS_H */
+# ifdef USE_SYSV_TERMIO /* Amdahl, Cray, all SysV? */
+# ifdef HAVE_TERMIO_H
+# include <termio.h>
+# endif
+# ifdef HAVE_SYS_TERMIO_H
+# include <sys/termio.h>
+# endif
+# ifdef NEED_PTEM
+# include <sys/stream.h>
+# include <sys/ptem.h>
+# endif
+# define sgttyb termio
+# define sg_flags c_lflag
+# define GTTY(f,s) ioctl(f,TCGETA,(zvoid *)s)
+# define STTY(f,s) ioctl(f,TCSETAW,(zvoid *)s)
+# else /* !USE_SYSV_TERMIO */
+# ifndef CMS_MVS
+# if (!defined(MINIX) && !defined(GOT_IOCTL_H))
+# include <sys/ioctl.h>
+# endif
+# include <sgtty.h>
+# define GTTY gtty
+# define STTY stty
+# ifdef UNZIP
+ /*
+ * XXX : Are these declarations needed at all ????
+ */
+ /*
+ * GRR: let's find out... Hmmm, appears not...
+ int gtty OF((int, struct sgttyb *));
+ int stty OF((int, struct sgttyb *));
+ */
+# endif
+# endif /* !CMS_MVS */
+# endif /* ?USE_SYSV_TERMIO */
+# endif /* ?HAVE_TERMIOS_H */
+# ifndef NO_FCNTL_H
+# ifndef UNZIP
+# include <fcntl.h>
+# endif
+# else
+ char *ttyname OF((int));
+# endif
+# endif /* ?VMS */
+#endif /* !HAVE_WORKING_GETCH */
+
+
+
+#ifndef HAVE_WORKING_GETCH
+#ifdef VMS
+
+static struct dsc$descriptor_s DevDesc =
+ {11, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$COMMAND"};
+ /* {dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer}; */
+
+/*
+ * Turn keyboard echoing on or off (VMS). Loosely based on VMSmunch.c
+ * and hence on Joe Meadows' file.c code.
+ */
+int echo(opt)
+ int opt;
+{
+ /*
+ * For VMS v5.x:
+ * IO$_SENSEMODE/SETMODE info: Programming, Vol. 7A, System Programming,
+ * I/O User's: Part I, sec. 8.4.1.1, 8.4.3, 8.4.5, 8.6
+ * sys$assign(), sys$qio() info: Programming, Vol. 4B, System Services,
+ * System Services Reference Manual, pp. sys-23, sys-379
+ * fixed-length descriptor info: Programming, Vol. 3, System Services,
+ * Intro to System Routines, sec. 2.9.2
+ * Greg Roelofs, 15 Aug 91
+ */
+
+ short DevChan, iosb[4];
+ long status;
+ unsigned long ttmode[2]; /* space for 8 bytes */
+
+
+ /* assign a channel to standard input */
+ status = sys$assign(&DevDesc, &DevChan, 0, 0);
+ if (!(status & 1))
+ return status;
+
+ /* use sys$qio and the IO$_SENSEMODE function to determine the current
+ * tty status (for password reading, could use IO$_READVBLK function
+ * instead, but echo on/off will be more general)
+ */
+ status = sys$qiow(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0,
+ ttmode, 8, 0, 0, 0, 0);
+ if (!(status & 1))
+ return status;
+ status = iosb[0];
+ if (!(status & 1))
+ return status;
+
+ /* modify mode buffer to be either NOECHO or ECHO
+ * (depending on function argument opt)
+ */
+ if (opt == 0) /* off */
+ ttmode[1] |= TT$M_NOECHO; /* set NOECHO bit */
+ else
+ ttmode[1] &= ~((unsigned long) TT$M_NOECHO); /* clear NOECHO bit */
+
+ /* use the IO$_SETMODE function to change the tty status */
+ status = sys$qiow(0, DevChan, IO$_SETMODE, &iosb, 0, 0,
+ ttmode, 8, 0, 0, 0, 0);
+ if (!(status & 1))
+ return status;
+ status = iosb[0];
+ if (!(status & 1))
+ return status;
+
+ /* deassign the sys$input channel by way of clean-up */
+ status = sys$dassgn(DevChan);
+ if (!(status & 1))
+ return status;
+
+ return SS$_NORMAL; /* we be happy */
+
+} /* end function echo() */
+
+
+/*
+ * Read a single character from keyboard in non-echoing mode (VMS).
+ * (returns EOF in case of errors)
+ */
+int tt_getch()
+{
+ short DevChan, iosb[4];
+ long status;
+ char kbbuf[16]; /* input buffer with - some - excess length */
+
+ /* assign a channel to standard input */
+ status = sys$assign(&DevDesc, &DevChan, 0, 0);
+ if (!(status & 1))
+ return EOF;
+
+ /* read a single character from SYS$COMMAND (no-echo) and
+ * wait for completion
+ */
+ status = sys$qiow(0,DevChan,
+ IO$_READVBLK|IO$M_NOECHO|IO$M_NOFILTR,
+ &iosb, 0, 0,
+ &kbbuf, 1, 0, 0, 0, 0);
+ if ((status&1) == 1)
+ status = iosb[0];
+
+ /* deassign the sys$input channel by way of clean-up
+ * (for this step, we do not need to check the completion status)
+ */
+ sys$dassgn(DevChan);
+
+ /* return the first char read, or EOF in case the read request failed */
+ return (int)(((status&1) == 1) ? (uch)kbbuf[0] : EOF);
+
+} /* end function tt_getch() */
+
+
+#else /* !VMS: basically Unix */
+
+
+/* For VM/CMS and MVS, non-echo terminal input is not (yet?) supported. */
+#ifndef CMS_MVS
+
+#ifdef ZIP /* moved to globals.h for UnZip */
+ static int echofd=(-1); /* file descriptor whose echo is off */
+#endif
+
+/*
+ * Turn echo off for file descriptor f. Assumes that f is a tty device.
+ */
+void Echoff(__G__ f)
+ __GDEF
+ int f; /* file descriptor for which to turn echo off */
+{
+ struct sgttyb sg; /* tty device structure */
+
+ GLOBAL(echofd) = f;
+ GTTY(f, &sg); /* get settings */
+ sg.sg_flags &= ~ECHO; /* turn echo off */
+ STTY(f, &sg);
+}
+
+/*
+ * Turn echo back on for file descriptor echofd.
+ */
+void Echon(__G)
+ __GDEF
+{
+ struct sgttyb sg; /* tty device structure */
+
+ if (GLOBAL(echofd) != -1) {
+ GTTY(GLOBAL(echofd), &sg); /* get settings */
+ sg.sg_flags |= ECHO; /* turn echo on */
+ STTY(GLOBAL(echofd), &sg);
+ GLOBAL(echofd) = -1;
+ }
+}
+
+#endif /* !CMS_MVS */
+#endif /* ?VMS */
+
+
+#if (defined(UNZIP) && !defined(FUNZIP))
+
+#ifdef ATH_BEO_UNX
+#ifdef MORE
+
+/*
+ * Get the number of lines on the output terminal. SCO Unix apparently
+ * defines TIOCGWINSZ but doesn't support it (!M_UNIX).
+ *
+ * GRR: will need to know width of terminal someday, too, to account for
+ * line-wrapping.
+ */
+
+#if (defined(TIOCGWINSZ) && !defined(M_UNIX))
+
+int screensize(tt_rows, tt_cols)
+ int *tt_rows;
+ int *tt_cols;
+{
+ struct winsize wsz;
+#ifdef DEBUG_WINSZ
+ static int firsttime = TRUE;
+#endif
+
+ /* see termio(4) under, e.g., SunOS */
+ if (ioctl(1, TIOCGWINSZ, &wsz) == 0) {
+#ifdef DEBUG_WINSZ
+ if (firsttime) {
+ firsttime = FALSE;
+ fprintf(stderr, "ttyio.c screensize(): ws_row = %d\n",
+ wsz.ws_row);
+ fprintf(stderr, "ttyio.c screensize(): ws_col = %d\n",
+ wsz.ws_col);
+ }
+#endif
+ /* number of rows */
+ if (tt_rows != NULL)
+ *tt_rows = (int)((wsz.ws_row > 0) ? wsz.ws_row : 24);
+ /* number of columns */
+ if (tt_cols != NULL)
+ *tt_cols = (int)((wsz.ws_col > 0) ? wsz.ws_col : 80);
+ return 0; /* signal success */
+ } else { /* this happens when piping to more(1), for example */
+#ifdef DEBUG_WINSZ
+ if (firsttime) {
+ firsttime = FALSE;
+ fprintf(stderr,
+ "ttyio.c screensize(): ioctl(TIOCGWINSZ) failed\n"));
+ }
+#endif
+ /* VT-100 assumed to be minimal hardware */
+ if (tt_rows != NULL)
+ *tt_rows = 24;
+ if (tt_cols != NULL)
+ *tt_cols = 80;
+ return 1; /* signal failure */
+ }
+}
+
+#else /* !TIOCGWINSZ: service not available, fall back to semi-bogus method */
+
+int screensize(tt_rows, tt_cols)
+ int *tt_rows;
+ int *tt_cols;
+{
+ char *envptr, *getenv();
+ int n;
+ int errstat = 0;
+
+ /* GRR: this is overly simplistic, but don't have access to stty/gtty
+ * system anymore
+ */
+ if (tt_rows != NULL) {
+ envptr = getenv("LINES");
+ if (envptr == (char *)NULL || (n = atoi(envptr)) < 5) {
+ /* VT-100 assumed to be minimal hardware */
+ *tt_rows = 24;
+ errstat = 1; /* signal failure */
+ } else {
+ *tt_rows = n;
+ }
+ }
+ if (tt_cols != NULL) {
+ envptr = getenv("COLUMNS");
+ if (envptr == (char *)NULL || (n = atoi(envptr)) < 5) {
+ *tt_cols = 80;
+ errstat = 1; /* signal failure */
+ } else {
+ *tt_cols = n;
+ }
+ }
+ return errstat;
+}
+
+#endif /* ?(TIOCGWINSZ && !M_UNIX) */
+#endif /* MORE */
+
+
+/*
+ * Get a character from the given file descriptor without echo or newline.
+ */
+int zgetch(__G__ f)
+ __GDEF
+ int f; /* file descriptor from which to read */
+{
+#if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
+ char oldmin, oldtim;
+#endif
+ char c;
+ struct sgttyb sg; /* tty device structure */
+
+ GTTY(f, &sg); /* get settings */
+#if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
+ oldmin = sg.c_cc[VMIN]; /* save old values */
+ oldtim = sg.c_cc[VTIME];
+ sg.c_cc[VMIN] = 1; /* need only one char to return read() */
+ sg.c_cc[VTIME] = 0; /* no timeout */
+ sg.sg_flags &= ~ICANON; /* canonical mode off */
+#else
+ sg.sg_flags |= CBREAK; /* cbreak mode on */
+#endif
+ sg.sg_flags &= ~ECHO; /* turn echo off, too */
+ STTY(f, &sg); /* set cbreak mode */
+ GLOBAL(echofd) = f; /* in case ^C hit (not perfect: still CBREAK) */
+
+ read(f, &c, 1); /* read our character */
+
+#if (defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS))
+ sg.c_cc[VMIN] = oldmin; /* restore old values */
+ sg.c_cc[VTIME] = oldtim;
+ sg.sg_flags |= ICANON; /* canonical mode on */
+#else
+ sg.sg_flags &= ~CBREAK; /* cbreak mode off */
+#endif
+ sg.sg_flags |= ECHO; /* turn echo on */
+ STTY(f, &sg); /* restore canonical mode */
+ GLOBAL(echofd) = -1;
+
+ return (int)(uch)c;
+}
+
+
+#else /* !ATH_BEO_UNX */
+#ifndef VMS /* VMS supplies its own variant of getch() */
+
+
+int zgetch(__G__ f)
+ __GDEF
+ int f; /* file descriptor from which to read (must be open already) */
+{
+ char c, c2;
+
+/*---------------------------------------------------------------------------
+ Get a character from the given file descriptor without echo; can't fake
+ CBREAK mode (i.e., newline required), but can get rid of all chars up to
+ and including newline.
+ ---------------------------------------------------------------------------*/
+
+ echoff(f);
+ read(f, &c, 1);
+ if (c != '\n')
+ do {
+ read(f, &c2, 1); /* throw away all other chars up thru newline */
+ } while (c2 != '\n');
+ echon();
+ return (int)c;
+}
+
+#endif /* !VMS */
+#endif /* ?ATH_BEO_UNX */
+
+#endif /* UNZIP && !FUNZIP */
+#endif /* !HAVE_WORKING_GETCH */
+
+
+#if CRYPT /* getp() is only used with full encryption */
+
+/*
+ * Simple compile-time check for source compatibility between
+ * zcrypt and ttyio:
+ */
+#if (!defined(CR_MAJORVER) || (CR_MAJORVER < 2) || (CR_MINORVER < 7))
+ error: This Info-ZIP tool requires zcrypt 2.7 or later.
+#endif
+
+/*
+ * Get a password of length n-1 or less into *p using the prompt *m.
+ * The entered password is not echoed.
+ */
+
+#ifdef HAVE_WORKING_GETCH
+/*
+ * For the AMIGA, getch() is defined as Agetch(), which is in
+ * amiga/filedate.c; SAS/C 6.x provides a getch(), but since Agetch()
+ * uses the infrastructure that is already in place in filedate.c, it is
+ * smaller. With this function, echoff() and echon() are not needed.
+ *
+ * For the MAC, a non-echo macgetch() function is defined in the MacOS
+ * specific sources which uses the event handling mechanism of the
+ * desktop window manager to get a character from the keyboard.
+ *
+ * For the other systems in this section, a non-echo getch() function
+ * is either contained the C runtime library (conio package), or getch()
+ * is defined as an alias for a similar system specific RTL function.
+ */
+
+#ifndef WINDLL /* WINDLL does not support a console interface */
+#ifndef QDOS /* QDOS supplies a variant of this function */
+
+/* This is the getp() function for all systems (with TTY type user interface)
+ * that supply a working `non-echo' getch() function for "raw" console input.
+ */
+char *getp(__G__ m, p, n)
+ __GDEF
+ ZCONST char *m; /* prompt for password */
+ char *p; /* return value: line input */
+ int n; /* bytes available in p[] */
+{
+ char c; /* one-byte buffer for read() to use */
+ int i; /* number of characters input */
+ char *w; /* warning on retry */
+
+ /* get password */
+ w = "";
+ do {
+ fputs(w, stderr); /* warning if back again */
+ fputs(m, stderr); /* display prompt and flush */
+ fflush(stderr);
+ i = 0;
+ do { /* read line, keeping first n characters */
+ if ((c = (char)getch()) == '\r')
+ c = '\n'; /* until user hits CR */
+ if (c == 8 || c == 127) {
+ if (i > 0) i--; /* the `backspace' and `del' keys works */
+ }
+ else if (i < n)
+ p[i++] = c; /* truncate past n */
+ } while (c != '\n');
+ PUTC('\n', stderr); fflush(stderr);
+ w = "(line too long--try again)\n";
+ } while (p[i-1] != '\n');
+ p[i-1] = 0; /* terminate at newline */
+
+ return p; /* return pointer to password */
+
+} /* end function getp() */
+
+#endif /* !QDOS */
+#endif /* !WINDLL */
+
+
+#else /* !HAVE_WORKING_GETCH */
+
+
+#if (defined(ATH_BEO_UNX) || defined(__MINT__))
+
+#ifndef _PATH_TTY
+# ifdef __MINT__
+# define _PATH_TTY ttyname(2)
+# else
+# define _PATH_TTY "/dev/tty"
+# endif
+#endif
+
+char *getp(__G__ m, p, n)
+ __GDEF
+ ZCONST char *m; /* prompt for password */
+ char *p; /* return value: line input */
+ int n; /* bytes available in p[] */
+{
+ char c; /* one-byte buffer for read() to use */
+ int i; /* number of characters input */
+ char *w; /* warning on retry */
+ int f; /* file descriptor for tty device */
+
+#ifdef PASSWD_FROM_STDIN
+ /* Read from stdin. This is unsafe if the password is stored on disk. */
+ f = 0;
+#else
+ /* turn off echo on tty */
+
+ if ((f = open(_PATH_TTY, 0)) == -1)
+ return NULL;
+#endif
+ /* get password */
+ w = "";
+ do {
+ fputs(w, stderr); /* warning if back again */
+ fputs(m, stderr); /* prompt */
+ fflush(stderr);
+ i = 0;
+ echoff(f);
+ do { /* read line, keeping n */
+ read(f, &c, 1);
+ if (i < n)
+ p[i++] = c;
+ } while (c != '\n');
+ echon();
+ PUTC('\n', stderr); fflush(stderr);
+ w = "(line too long--try again)\n";
+ } while (p[i-1] != '\n');
+ p[i-1] = 0; /* terminate at newline */
+
+#ifndef PASSWD_FROM_STDIN
+ close(f);
+#endif
+
+ return p; /* return pointer to password */
+
+} /* end function getp() */
+
+#endif /* ATH_BEO_UNX || __MINT__ */
+
+
+
+#if (defined(VMS) || defined(CMS_MVS))
+
+char *getp(__G__ m, p, n)
+ __GDEF
+ ZCONST char *m; /* prompt for password */
+ char *p; /* return value: line input */
+ int n; /* bytes available in p[] */
+{
+ char c; /* one-byte buffer for read() to use */
+ int i; /* number of characters input */
+ char *w; /* warning on retry */
+ FILE *f; /* file structure for SYS$COMMAND device */
+
+#ifdef PASSWD_FROM_STDIN
+ f = stdin;
+#else
+ if ((f = fopen(ctermid(NULL), "r")) == NULL)
+ return NULL;
+#endif
+
+ /* get password */
+ fflush(stdout);
+ w = "";
+ do {
+ if (*w) /* bug: VMS apparently adds \n to NULL fputs */
+ fputs(w, stderr); /* warning if back again */
+ fputs(m, stderr); /* prompt */
+ fflush(stderr);
+ i = 0;
+ echoff(f);
+ do { /* read line, keeping n */
+ if ((c = (char)getc(f)) == '\r')
+ c = '\n';
+ if (i < n)
+ p[i++] = c;
+ } while (c != '\n');
+ echon();
+ PUTC('\n', stderr); fflush(stderr);
+ w = "(line too long--try again)\n";
+ } while (p[i-1] != '\n');
+ p[i-1] = 0; /* terminate at newline */
+#ifndef PASSWD_FROM_STDIN
+ fclose(f);
+#endif
+
+ return p; /* return pointer to password */
+
+} /* end function getp() */
+
+#endif /* VMS || CMS_MVS */
+#endif /* ?HAVE_WORKING_GETCH */
+#endif /* CRYPT */
+#endif /* CRYPT || (UNZIP && !FUNZIP) */
Property changes on: trunk/build/install/installer/ttyio.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/ttyio.h
===================================================================
--- trunk/build/install/installer/ttyio.h (rev 0)
+++ trunk/build/install/installer/ttyio.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,227 @@
+/*
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ ttyio.h
+ */
+
+#ifndef __ttyio_h /* don't include more than once */
+#define __ttyio_h
+
+#ifndef __crypt_h
+# include "crypt.h" /* ensure that encryption header file has been seen */
+#endif
+
+#if (CRYPT || (defined(UNZIP) && !defined(FUNZIP)))
+/*
+ * Non-echo keyboard/console input support is needed and enabled.
+ */
+
+#ifndef __G /* UnZip only, for now (DLL stuff) */
+# define __G
+# define __G__
+# define __GDEF
+# define __GPRO void
+# define __GPRO__
+#endif
+
+#ifndef ZCONST /* UnZip only (until have configure script like Zip) */
+# define ZCONST const
+#endif
+
+#if (defined(MSDOS) || defined(OS2) || defined(WIN32))
+# ifndef DOS_OS2_W32
+# define DOS_OS2_W32
+# endif
+#endif
+
+#if (defined(DOS_OS2_W32) || defined(__human68k__))
+# ifndef DOS_H68_OS2_W32
+# define DOS_H68_OS2_W32
+# endif
+#endif
+
+#if (defined(DOS_OS2_W32) || defined(FLEXOS))
+# ifndef DOS_FLX_OS2_W32
+# define DOS_FLX_OS2_W32
+# endif
+#endif
+
+#if (defined(DOS_H68_OS2_W32) || defined(FLEXOS))
+# ifndef DOS_FLX_H68_OS2_W32
+# define DOS_FLX_H68_OS2_W32
+# endif
+#endif
+
+#if (defined(__ATHEOS__) || defined(__BEOS__) || defined(UNIX))
+# ifndef ATH_BEO_UNX
+# define ATH_BEO_UNX
+# endif
+#endif
+
+#if (defined(VM_CMS) || defined(MVS))
+# ifndef CMS_MVS
+# define CMS_MVS
+# endif
+#endif
+
+
+/* Function prototypes */
+
+/* The following systems supply a `non-echo' character input function "getch()"
+ * (or an alias) and do not need the echoff() / echon() function pair.
+ */
+#ifdef AMIGA
+# define echoff(f)
+# define echon()
+# define getch() Agetch()
+# define HAVE_WORKING_GETCH
+#endif /* AMIGA */
+
+#ifdef ATARI
+# define echoff(f)
+# define echon()
+# include <osbind.h>
+# define getch() (Cnecin() & 0x000000ff)
+# define HAVE_WORKING_GETCH
+#endif
+
+#ifdef MACOS
+# define echoff(f)
+# define echon()
+# define getch() macgetch()
+# define HAVE_WORKING_GETCH
+#endif
+
+#ifdef NLM
+# define echoff(f)
+# define echon()
+# define HAVE_WORKING_GETCH
+#endif
+
+#ifdef QDOS
+# define echoff(f)
+# define echon()
+# define HAVE_WORKING_GETCH
+#endif
+
+#ifdef RISCOS
+# define echoff(f)
+# define echon()
+# define getch() SWI_OS_ReadC()
+# define HAVE_WORKING_GETCH
+#endif
+
+#ifdef DOS_H68_OS2_W32
+# define echoff(f)
+# define echon()
+# ifdef WIN32
+# ifndef getch
+# define getch() getch_win32()
+# endif
+# else /* !WIN32 */
+# ifdef __EMX__
+# ifndef getch
+# define getch() _read_kbd(0, 1, 0)
+# endif
+# else /* !__EMX__ */
+# ifdef __GO32__
+# include <pc.h>
+# define getch() getkey()
+# else /* !__GO32__ */
+# include <conio.h>
+# endif /* ?__GO32__ */
+# endif /* ?__EMX__ */
+# endif /* ?WIN32 */
+# define HAVE_WORKING_GETCH
+#endif /* DOS_H68_OS2_W32 */
+
+#ifdef FLEXOS
+# define echoff(f)
+# define echon()
+# define getch() getchar() /* not correct, but may not be on a console */
+# define HAVE_WORKING_GETCH
+#endif
+
+/* For VM/CMS and MVS, we do not (yet) have any support to switch terminal
+ * input echo on and off. The following "fake" definitions allow inclusion
+ * of crypt support and UnZip's "pause prompting" features, but without
+ * any echo suppression.
+ */
+#ifdef CMS_MVS
+# define echoff(f)
+# define echon()
+#endif
+
+#ifdef TANDEM
+# define echoff(f)
+# define echon()
+# define getch() zgetch() /* defined in TANDEMC */
+# define HAVE_WORKING_GETCH
+#endif
+
+/* The THEOS C runtime library supplies the function conmask() to toggle
+ * terminal input echo on (conmask("e")) and off (conmask("n")). But,
+ * since THEOS C RTL also contains a working non-echo getch() function,
+ * the echo toggles are not needed.
+ */
+#ifdef THEOS
+# define echoff(f)
+# define echon()
+# define HAVE_WORKING_GETCH
+#endif
+
+/* VMS has a single echo() function in ttyio.c to toggle terminal
+ * input echo on and off.
+ */
+#ifdef VMS
+# define echoff(f) echo(0)
+# define echon() echo(1)
+# define getch() tt_getch()
+# define FGETCH(f) tt_getch()
+ int echo OF((int));
+ int tt_getch OF((void));
+#endif
+
+/* For all other systems, ttyio.c supplies the two functions Echoff() and
+ * Echon() for suppressing and (re)enabling console input echo.
+ */
+#ifndef echoff
+# define echoff(f) Echoff(__G__ f)
+# define echon() Echon(__G)
+ void Echoff OF((__GPRO__ int f));
+ void Echon OF((__GPRO));
+#endif
+
+/* this stuff is used by MORE and also now by the ctrl-S code; fileio.c only */
+#if (defined(UNZIP) && !defined(FUNZIP))
+# ifdef HAVE_WORKING_GETCH
+# define FGETCH(f) getch()
+# endif
+# ifndef FGETCH
+ /* default for all systems where no getch()-like function is available */
+ int zgetch OF((__GPRO__ int f));
+# define FGETCH(f) zgetch(__G__ f)
+# endif
+#endif /* UNZIP && !FUNZIP */
+
+#if (CRYPT && !defined(WINDLL))
+ char *getp OF((__GPRO__ ZCONST char *m, char *p, int n));
+#endif
+
+#else /* !(CRYPT || (UNZIP && !FUNZIP)) */
+
+/*
+ * No need for non-echo keyboard/console input; provide dummy definitions.
+ */
+#define echoff(f)
+#define echon()
+
+#endif /* ?(CRYPT || (UNZIP && !FUNZIP)) */
+
+#endif /* !__ttyio_h */
Property changes on: trunk/build/install/installer/ttyio.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/unzip.c
===================================================================
--- trunk/build/install/installer/unzip.c (rev 0)
+++ trunk/build/install/installer/unzip.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,2042 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ unzip.c
+
+ UnZip - a zipfile extraction utility. See below for make instructions, or
+ read the comments in Makefile and the various Contents files for more de-
+ tailed explanations. To report a bug, submit a *complete* description via
+ //www.info-zip.org/zip-bug.html; include machine type, operating system and
+ version, compiler and version, and reasonably detailed error messages or
+ problem report. To join Info-ZIP, see the instructions in README.
+
+ UnZip 5.x is a greatly expanded and partially rewritten successor to 4.x,
+ which in turn was almost a complete rewrite of version 3.x. For a detailed
+ revision history, see UnzpHist.zip at quest.jpl.nasa.gov. For a list of
+ the many (near infinite) contributors, see "CONTRIBS" in the UnZip source
+ distribution.
+
+ ---------------------------------------------------------------------------
+
+ [from original zipinfo.c]
+
+ This program reads great gobs of totally nifty information, including the
+ central directory stuff, from ZIP archives ("zipfiles" for short). It
+ started as just a testbed for fooling with zipfiles, but at this point it
+ is actually a useful utility. It also became the basis for the rewrite of
+ UnZip (3.16 -> 4.0), using the central directory for processing rather than
+ the individual (local) file headers.
+
+ As of ZipInfo v2.0 and UnZip v5.1, the two programs are combined into one.
+ If the executable is named "unzip" (or "unzip.exe", depending), it behaves
+ like UnZip by default; if it is named "zipinfo" or "ii", it behaves like
+ ZipInfo. The ZipInfo behavior may also be triggered by use of unzip's -Z
+ option; for example, "unzip -Z [zipinfo_options] archive.zip".
+
+ Another dandy product from your buddies at Newtware!
+
+ Author: Greg Roelofs, newt(a)pobox.com, http://pobox.com/~newt/
+ 23 August 1990 -> April 1997
+
+ ---------------------------------------------------------------------------
+
+ Version: unzip5??.{tar.Z | tar.gz | zip} for Unix, VMS, OS/2, MS-DOS, Amiga,
+ Atari, Windows 3.x/95/NT/CE, Macintosh, Human68K, Acorn RISC OS,
+ AtheOS, BeOS, SMS/QDOS, VM/CMS, MVS, AOS/VS, Tandem NSK, Theos
+ and TOPS-20.
+
+ Copyrights: see accompanying file "LICENSE" in UnZip source distribution.
+ (This software is free but NOT IN THE PUBLIC DOMAIN.)
+
+ ---------------------------------------------------------------------------*/
+
+
+
+#define __UNZIP_C /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h" /* includes, typedefs, macros, prototypes, etc. */
+#include "crypt.h"
+#include "unzvers.h"
+
+#ifndef WINDLL /* The WINDLL port uses windll/windll.c instead... */
+
+/***************************/
+/* Local type declarations */
+/***************************/
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+typedef struct _sign_info
+ {
+ struct _sign_info *previous;
+ void (*sighandler)(int);
+ int sigtype;
+ } savsigs_info;
+#endif
+
+/*******************/
+/* Local Functions */
+/*******************/
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+static int setsignalhandler OF((__GPRO__ savsigs_info **p_savedhandler_chain,
+ int signal_type, void (*newhandler)(int)));
+#endif
+#ifndef SFX
+static void show_version_info OF((__GPRO));
+#endif
+
+
+/*************/
+/* Constants */
+/*************/
+
+#include "consts.h" /* all constant global variables are in here */
+ /* (non-constant globals were moved to globals.c) */
+
+/* constant local variables: */
+
+#ifndef SFX
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ static ZCONST char Far EnvUnZip[] = ENV_UNZIP;
+ static ZCONST char Far EnvUnZip2[] = ENV_UNZIP2;
+ static ZCONST char Far EnvZipInfo[] = ENV_ZIPINFO;
+ static ZCONST char Far EnvZipInfo2[] = ENV_ZIPINFO2;
+#ifdef RISCOS
+ static ZCONST char Far EnvUnZipExts[] = ENV_UNZIPEXTS;
+#endif /* RISCOS */
+ static ZCONST char Far NoMemArguments[] =
+ "envargs: cannot get memory for arguments";
+#endif /* !_WIN32_WCE */
+#endif /* !SFX */
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+ static ZCONST char Far CantSaveSigHandler[] =
+ "error: cannot save signal handler settings\n";
+#endif
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+ static ZCONST char Far NotExtracting[] =
+ "caution: not extracting; -d ignored\n";
+ static ZCONST char Far MustGiveExdir[] =
+ "error: must specify directory to which to extract with -d option\n";
+ static ZCONST char Far OnlyOneExdir[] =
+ "error: -d option used more than once (only one exdir allowed)\n";
+#endif
+
+#if CRYPT
+ static ZCONST char Far MustGivePasswd[] =
+ "error: must give decryption password with -P option\n";
+#endif
+
+#ifndef SFX
+ static ZCONST char Far Zfirst[] =
+ "error: -Z must be first option for ZipInfo mode (check UNZIP variable?)\n";
+#endif
+static ZCONST char Far InvalidOptionsMsg[] = "error:\
+ -fn or any combination of -c, -l, -p, -t, -u and -v options invalid\n";
+static ZCONST char Far IgnoreOOptionMsg[] =
+ "caution: both -n and -o specified; ignoring -o\n";
+
+/* usage() strings */
+#ifndef SFX
+#ifdef VMS
+ static ZCONST char Far Example3[] = "vms.c";
+ static ZCONST char Far Example2[] = " unzip \"-V\" foo \"Bar\"\
+ (Quote names to preserve case, unless SET PROC/PARS=EXT)\n";
+#else /* !VMS */
+ static ZCONST char Far Example3[] = "ReadMe";
+#ifdef RISCOS
+ static ZCONST char Far Example2[] =
+" unzip foo -d RAM:$ => extract all files from foo into RAMDisc\n";
+#else /* !RISCOS */
+#if (defined(OS2) || (defined(DOS_FLX_OS2_W32) && defined(MORE)))
+ static ZCONST char Far Example2[] =
+ ""; /* no room: too many local3[] items */
+#else /* !OS2 */
+#ifdef MACOS
+ static ZCONST char Far Example2[] = ""; /* not needed */
+#else /* !MACOS */
+ static ZCONST char Far Example2[] = " \
+ unzip -p foo | more => send contents of foo.zip via pipe into program more\n";
+#endif /* ?MACOS */
+#endif /* ?OS2 */
+#endif /* ?RISCOS */
+#endif /* ?VMS */
+
+/* local1[]: command options */
+#if (defined(DLL) && defined(API_DOC))
+ static ZCONST char Far local1[] =
+ " -A print extended help for API functions";
+#else /* !(DLL && API_DOC) */
+ static ZCONST char Far local1[] = "";
+#endif /* ?(DLL && API_DOC) */
+
+/* local2[] and local3[]: modifier options */
+#ifdef DOS_FLX_H68_OS2_W32
+#ifdef FLEXOS
+ static ZCONST char Far local2[] = "";
+#else
+ static ZCONST char Far local2[] =
+ " -$ label removables (-$$ => fixed disks)";
+#endif
+#ifdef OS2
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -X restore ACLs if supported -s spaces in filenames => '_'\n\
+ -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = " \
+ -X restore ACLs if supported -s spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#else /* !OS2 */
+#ifdef WIN32
+#ifdef NTSD_EAS
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -X restore ACLs (-XX => use privileges) -s spaces in filenames => '_'\n\
+ -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = " \
+ -X restore ACLs (-XX => use privileges) -s spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#else /* !NTSD_EAS */
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -M pipe through \"more\" pager \
+ -s spaces in filenames => '_'\n\n";
+#else
+ static ZCONST char Far local3[] = " \
+ -s spaces in filenames => '_'\n\n";
+#endif /* ?MORE */
+#endif /* ?NTSD_EAS */
+#else /* !WIN32 */
+#ifdef MORE
+ static ZCONST char Far local3[] = " -\
+M pipe through \"more\" pager -s spaces in filenames => '_'\n\n";
+#else
+ static ZCONST char Far local3[] = "\
+ -s spaces in filenames => '_'\n";
+#endif
+#endif /* ?WIN32 */
+#endif /* ?OS2 || ?WIN32 */
+#else /* !DOS_FLX_OS2_W32 */
+#ifdef VMS
+ static ZCONST char Far local2[] = "\"-X\" restore owner/protection info";
+#ifdef MORE
+ static ZCONST char Far local3[] = " \
+ \"-M\" pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = "\n";
+#endif
+#else /* !VMS */
+#ifdef ATH_BEO_UNX
+ static ZCONST char Far local2[] = " -X restore UID/GID info";
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -K keep setuid/setgid/tacky permissions -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = "\
+ -K keep setuid/setgid/tacky permissions\n";
+#endif
+#else /* !ATH_BEO_UNX */
+#ifdef TANDEM
+ static ZCONST char Far local2[] = "\
+ -X restore Tandem User ID -r remove file extensions\n\
+ -b create 'C' (180) text files ";
+#ifdef MORE
+ static ZCONST char Far local3[] = " \
+ -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = "\n";
+#endif
+#else /* !TANDEM */
+#ifdef AMIGA
+ static ZCONST char Far local2[] = " -N restore comments as filenotes";
+#ifdef MORE
+ static ZCONST char Far local3[] = " \
+ -M pipe through \"more\" pager\n";
+#else
+ static ZCONST char Far local3[] = "\n";
+#endif
+#else /* !AMIGA */
+#ifdef MACOS
+ static ZCONST char Far local2[] = " -E show Mac info during extraction";
+ static ZCONST char Far local3[] = " \
+ -i ignore filenames in mac extra info -J junk (ignore) Mac extra info\n\
+\n";
+#else /* !MACOS */
+#ifdef MORE
+ static ZCONST char Far local2[] = " -M pipe through \"more\" pager";
+ static ZCONST char Far local3[] = "\n";
+#else
+ static ZCONST char Far local2[] = ""; /* Atari, Mac, CMS/MVS etc. */
+ static ZCONST char Far local3[] = "";
+#endif
+#endif /* ?MACOS */
+#endif /* ?AMIGA */
+#endif /* ?TANDEM */
+#endif /* ?ATH_BEO_UNX */
+#endif /* ?VMS */
+#endif /* ?DOS_FLX_OS2_W32 */
+#endif /* !SFX */
+
+#ifndef NO_ZIPINFO
+#ifdef VMS
+ static ZCONST char Far ZipInfoExample[] = "* or % (e.g., \"*font-%.zip\")";
+#else
+ static ZCONST char Far ZipInfoExample[] = "*, ?, [] (e.g., \"[a-j]*.zip\")";
+#endif
+
+static ZCONST char Far ZipInfoUsageLine1[] = "\
+ZipInfo %d.%d%d%s of %s, by Greg Roelofs and the Info-ZIP group.\n\
+\n\
+List name, date/time, attribute, size, compression method, etc., about files\n\
+in list (excluding those in xlist) contained in the specified .zip archive(s).\
+\n\"file[.zip]\" may be a wildcard name containing %s.\n\n\
+ usage: zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n\
+ or: unzip %s-Z%s [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]\n";
+
+static ZCONST char Far ZipInfoUsageLine2[] = "\nmain\
+ listing-format options: -s short Unix \"ls -l\" format (def.)\n\
+ -1 filenames ONLY, one per line -m medium Unix \"ls -l\" format\n\
+ -2 just filenames but allow -h/-t/-z -l long Unix \"ls -l\" format\n\
+ -v verbose, multi-page format\n";
+
+static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
+ -h print header line -t print totals for listed files or for all\n\
+ -z print zipfile comment %c-T%c print file times in sortable decimal format\
+\n %c-C%c be case-insensitive %s\
+ -x exclude filenames that follow from listing\n";
+#ifdef MORE
+#ifdef VMS
+ static ZCONST char Far ZipInfoUsageLine4[] =
+ " \"-M\" page output through built-in \"more\"\n";
+#else
+ static ZCONST char Far ZipInfoUsageLine4[] =
+ " -M page output through built-in \"more\"\n";
+#endif
+#else /* !MORE */
+ static ZCONST char Far ZipInfoUsageLine4[] = "";
+#endif /* ?MORE */
+#endif /* !NO_ZIPINFO */
+
+#ifdef BETA
+# ifdef VMSCLI
+ /* BetaVersion[] is also used in vms/cmdline.c: do not make it static */
+ ZCONST char Far BetaVersion[] = "%s\
+ THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
+# else
+ static ZCONST char Far BetaVersion[] = "%s\
+ THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n";
+# endif
+#endif
+
+#ifdef SFX
+# ifdef VMSCLI
+ /* UnzipSFXBanner[] is also used in vms/cmdline.c: do not make it static */
+ ZCONST char Far UnzipSFXBanner[] =
+# else
+ static ZCONST char Far UnzipSFXBanner[] =
+# endif
+ "UnZipSFX %d.%d%d%s of %s, by Info-ZIP (http://www.info-zip.org).\n";
+# ifdef SFX_EXDIR
+ static ZCONST char Far UnzipSFXOpts[] =
+ "Valid options are -tfupcz and -d <exdir>; modifiers are -abjnoqCL%sV%s.\n";
+# else
+ static ZCONST char Far UnzipSFXOpts[] =
+ "Valid options are -tfupcz; modifiers are -abjnoqCL%sV%s.\n";
+# endif
+#else /* !SFX */
+ static ZCONST char Far CompileOptions[] =
+ "UnZip special compilation options:\n";
+ static ZCONST char Far CompileOptFormat[] = "\t%s\n";
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ static ZCONST char Far EnvOptions[] =
+ "\nUnZip and ZipInfo environment options:\n";
+ static ZCONST char Far EnvOptFormat[] = "%16s: %s\n";
+#endif
+ static ZCONST char Far None[] = "[none]";
+# ifdef ACORN_FTYPE_NFS
+ static ZCONST char Far AcornFtypeNFS[] = "ACORN_FTYPE_NFS";
+# endif
+# ifdef ASM_CRC
+ static ZCONST char Far AsmCRC[] = "ASM_CRC";
+# endif
+# ifdef ASM_INFLATECODES
+ static ZCONST char Far AsmInflateCodes[] = "ASM_INFLATECODES";
+# endif
+# ifdef CHECK_VERSIONS
+ static ZCONST char Far Check_Versions[] = "CHECK_VERSIONS";
+# endif
+# ifdef COPYRIGHT_CLEAN
+ static ZCONST char Far Copyright_Clean[] =
+ "COPYRIGHT_CLEAN (PKZIP 0.9x unreducing method not supported)";
+# endif
+# ifdef DEBUG
+ static ZCONST char Far UDebug[] = "DEBUG";
+# endif
+# ifdef DEBUG_TIME
+ static ZCONST char Far DebugTime[] = "DEBUG_TIME";
+# endif
+# ifdef DLL
+ static ZCONST char Far Dll[] = "DLL";
+# endif
+# ifdef DOSWILD
+ static ZCONST char Far DosWild[] = "DOSWILD";
+# endif
+# ifdef LZW_CLEAN
+ static ZCONST char Far LZW_Clean[] =
+ "LZW_CLEAN (PKZIP/Zip 1.x unshrinking method not supported)";
+# endif
+# ifndef MORE
+ static ZCONST char Far No_More[] = "NO_MORE";
+# endif
+# ifdef NO_ZIPINFO
+ static ZCONST char Far No_ZipInfo[] = "NO_ZIPINFO";
+# endif
+# ifdef NTSD_EAS
+ static ZCONST char Far NTSDExtAttrib[] = "NTSD_EAS";
+# endif
+# if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
+ static ZCONST char Far W32NoIZTimeFix[] = "NO_W32TIMES_IZFIX";
+# endif
+# ifdef OLD_THEOS_EXTRA
+ static ZCONST char Far OldTheosExtra[] =
+ "OLD_THEOS_EXTRA (handle also old Theos port extra field)";
+# endif
+# ifdef OS2_EAS
+ static ZCONST char Far OS2ExtAttrib[] = "OS2_EAS";
+# endif
+# ifdef QLZIP
+ static ZCONST char Far SMSExFldOnUnix[] = "QLZIP";
+# endif
+# ifdef REENTRANT
+ static ZCONST char Far Reentrant[] = "REENTRANT";
+# endif
+# ifdef REGARGS
+ static ZCONST char Far RegArgs[] = "REGARGS";
+# endif
+# ifdef RETURN_CODES
+ static ZCONST char Far Return_Codes[] = "RETURN_CODES";
+# endif
+# ifdef SET_DIR_ATTRIB
+ static ZCONST char Far SetDirAttrib[] = "SET_DIR_ATTRIB";
+# endif
+# ifdef TIMESTAMP
+ static ZCONST char Far TimeStamp[] = "TIMESTAMP";
+# endif
+# ifdef UNIXBACKUP
+ static ZCONST char Far UnixBackup[] = "UNIXBACKUP";
+# endif
+# ifdef USE_EF_UT_TIME
+ static ZCONST char Far Use_EF_UT_time[] = "USE_EF_UT_TIME";
+# endif
+# ifndef LZW_CLEAN
+ static ZCONST char Far Use_Unshrink[] =
+ "USE_UNSHRINK (PKZIP/Zip 1.x unshrinking method supported)";
+# endif
+# ifndef COPYRIGHT_CLEAN
+ static ZCONST char Far Use_Smith_Code[] =
+ "USE_SMITH_CODE (PKZIP 0.9x unreducing method supported)";
+# endif
+# ifdef USE_DEFLATE64
+ static ZCONST char Far Use_Deflate64[] =
+ "USE_DEFLATE64 (PKZIP 4.x Deflate64(tm) supported)";
+# endif
+# ifdef MULT_VOLUME
+ static ZCONST char Far Use_MultiVol[] =
+ "MULT_VOLUME (multi-volume archives supported)";
+# endif
+# if (defined(__DJGPP__) && (__DJGPP__ >= 2))
+# ifdef USE_DJGPP_ENV
+ static ZCONST char Far Use_DJGPP_Env[] = "USE_DJGPP_ENV";
+# endif
+# ifdef USE_DJGPP_GLOB
+ static ZCONST char Far Use_DJGPP_Glob[] = "USE_DJGPP_GLOB";
+# endif
+# endif /* __DJGPP__ && (__DJGPP__ >= 2) */
+# ifdef USE_VFAT
+ static ZCONST char Far Use_VFAT_support[] = "USE_VFAT";
+# endif
+# ifdef USE_ZLIB
+ static ZCONST char Far UseZlib[] =
+ "USE_ZLIB (compiled with version %s; using version %s)";
+# endif
+# ifdef VMS_TEXT_CONV
+ static ZCONST char Far VmsTextConv[] = "VMS_TEXT_CONV";
+# endif
+# ifdef VMSCLI
+ static ZCONST char Far VmsCLI[] = "VMSCLI";
+# endif
+# ifdef VMSWILD
+ static ZCONST char Far VmsWild[] = "VMSWILD";
+# endif
+# ifdef WILD_STOP_AT_DIR
+ static ZCONST char Far WildStopAtDir[] = "WILD_STOP_AT_DIR";
+# endif
+# if CRYPT
+# ifdef PASSWD_FROM_STDIN
+ static ZCONST char Far PasswdStdin[] = "PASSWD_FROM_STDIN";
+# endif
+ static ZCONST char Far Decryption[] =
+ "\t[decryption, version %d.%d%s of %s]\n";
+ static ZCONST char Far CryptDate[] = CR_VERSION_DATE;
+# endif
+# ifndef __RSXNT__
+# ifdef __EMX__
+ static ZCONST char Far EnvEMX[] = "EMX";
+ static ZCONST char Far EnvEMXOPT[] = "EMXOPT";
+# endif
+# if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
+ static ZCONST char Far EnvGO32[] = "GO32";
+ static ZCONST char Far EnvGO32TMP[] = "GO32TMP";
+# endif
+# endif /* !__RSXNT__ */
+
+#ifdef VMS
+/* UnzipUsageLine1[] is also used in vms/cmdline.c: do not make it static */
+ ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. For more details see: unzip -v.\n\n";
+# ifdef COPYRIGHT_CLEAN
+ static ZCONST char Far UnzipUsageLine1v[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. Maintained by C. Spieler. Send\n\
+bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# else
+ static ZCONST char Far UnzipUsageLine1v[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. UnReduce (c) 1989 by S. H. Smith.\n\
+Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# endif /* ?COPYRIGHT_CLEAN */
+#else /* !VMS */
+# ifdef COPYRIGHT_CLEAN
+ static ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. Maintained by C. Spieler. Send\n\
+bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# else
+ static ZCONST char Far UnzipUsageLine1[] = "\
+UnZip %d.%d%d%s of %s, by Info-ZIP. UnReduce (c) 1989 by S. H. Smith.\n\
+Send bug reports using //www.info-zip.org/zip-bug.html; see README for details.\
+\n\n";
+# endif /* ?COPYRIGHT_CLEAN */
+# define UnzipUsageLine1v UnzipUsageLine1
+#endif /* ?VMS */
+
+static ZCONST char Far UnzipUsageLine2v[] = "\
+Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip/ ;\
+\nsee ftp://ftp.info-zip.org/pub/infozip/UnZip.html for other sites.\
+\n\n";
+
+#ifdef MACOS
+static ZCONST char Far UnzipUsageLine2[] = "\
+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-d exdir]\n \
+ Default action is to extract files in list, to exdir;\n\
+ file[.zip] may be a wildcard. %s\n";
+#else /* !MACOS */
+#ifdef VM_CMS
+static ZCONST char Far UnzipUsageLine2[] = "\
+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d fm]\n \
+ Default action is to extract files in list, except those in xlist, to disk fm;\
+\n file[.zip] may be a wildcard. %s\n";
+#else /* !VM_CMS */
+static ZCONST char Far UnzipUsageLine2[] = "\
+Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n \
+ Default action is to extract files in list, except those in xlist, to exdir;\n\
+ file[.zip] may be a wildcard. %s\n";
+#endif /* ?VM_CMS */
+#endif /* ?MACOS */
+
+#ifdef NO_ZIPINFO
+# define ZIPINFO_MODE_OPTION ""
+ static ZCONST char Far ZipInfoMode[] =
+ "(ZipInfo mode is disabled in this version.)";
+#else
+# define ZIPINFO_MODE_OPTION "[-Z] "
+# ifdef VMS
+ static ZCONST char Far ZipInfoMode[] =
+ "\"-Z\" => ZipInfo mode (`unzip \"-Z\"' for usage).";
+# else
+ static ZCONST char Far ZipInfoMode[] =
+ "-Z => ZipInfo mode (\"unzip -Z\" for usage).";
+# endif
+#endif /* ?NO_ZIPINFO */
+
+#ifdef VMS
+ static ZCONST char Far VMSusageLine2b[] = "\
+=> define foreign command symbol in LOGIN.COM: $ unzip :== $dev:[dir]unzip.exe\
+\n";
+#endif
+
+#ifdef MACOS
+static ZCONST char Far UnzipUsageLine3[] = "\n\
+ -d extract files into exdir -l list files (short format)\n\
+ -f freshen existing files, create none -t test compressed archive data\n\
+ -u update files, create if necessary -z display archive comment\n\
+%s\n";
+#else /* !MACOS */
+#ifdef VM_CMS
+static ZCONST char Far UnzipUsageLine3[] = "\n\
+ -p extract files to pipe, no messages -l list files (short format)\n\
+ -f freshen existing files, create none -t test compressed archive data\n\
+ -u update files, create if necessary -z display archive comment\n\
+ -x exclude files that follow (in xlist) -d extract files onto disk fm\n\
+%s\n";
+#else /* !VM_CMS */
+static ZCONST char Far UnzipUsageLine3[] = "\n\
+ -p extract files to pipe, no messages -l list files (short format)\n\
+ -f freshen existing files, create none -t test compressed archive data\n\
+ -u update files, create if necessary -z display archive comment\n\
+ -x exclude files that follow (in xlist) -d extract files into exdir\n\
+%s\n";
+#endif /* ?VM_CMS */
+#endif /* ?MACOS */
+
+static ZCONST char Far UnzipUsageLine4[] = "\
+modifiers: -q quiet mode (-qq => quieter)\n\
+ -n never overwrite existing files -a auto-convert any text files\n\
+ -o overwrite files WITHOUT prompting -aa treat ALL files as text\n \
+ -j junk paths (do not make directories) -v be verbose/print version info\n\
+ %c-C%c match filenames case-insensitively %c-L%c make (some) names \
+lowercase\n %-42s %c-V%c retain VMS version numbers\n%s";
+
+static ZCONST char Far UnzipUsageLine5[] = "\
+Examples (see unzip.txt for more info):\n\
+ unzip data1 -x joe => extract all files except joe from zipfile data1.zip\n\
+%s\
+ unzip -fo foo %-6s => quietly replace existing %s if archive file newer\n";
+#endif /* ?SFX */
+
+
+
+
+
+/*****************************/
+/* main() / UzpMain() stub */
+/*****************************/
+
+int MAIN(argc, argv) /* return PK-type error code (except under VMS) */
+ int argc;
+ char *argv[];
+{
+ int r;
+
+ CONSTRUCTGLOBALS();
+ r = unzip(__G__ argc, argv);
+ DESTROYGLOBALS();
+ RETURN(r);
+}
+
+
+
+
+/*******************************/
+/* Primary UnZip entry point */
+/*******************************/
+
+int unzip(__G__ argc, argv)
+ __GDEF
+ int argc;
+ char *argv[];
+{
+#ifndef NO_ZIPINFO
+ char *p;
+#endif
+#ifdef DOS_FLX_H68_NLM_OS2_W32
+ int i;
+#endif
+ int retcode, error=FALSE;
+#ifndef NO_EXCEPT_SIGNALS
+#ifdef REENTRANT
+ savsigs_info *oldsighandlers = NULL;
+# define SET_SIGHANDLER(sigtype, newsighandler) \
+ if ((retcode = setsignalhandler(__G__ &oldsighandlers, (sigtype), \
+ (newsighandler))) > PK_WARN) \
+ goto cleanup_and_exit
+#else
+# define SET_SIGHANDLER(sigtype, newsighandler) \
+ signal((sigtype), (newsighandler))
+#endif
+#endif /* NO_EXCEPT_SIGNALS */
+
+ SETLOCALE(LC_CTYPE,"");
+
+#if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
+ extern void DebugMalloc(void);
+
+ atexit(DebugMalloc);
+#endif
+
+#ifdef MALLOC_WORK
+ /* The following (rather complex) expression determines the allocation
+ size of the decompression work area. It simulates what the
+ combined "union" and "struct" declaration of the "static" work
+ area reservation achieves automatically at compile time.
+ Any decent compiler should evaluate this expression completely at
+ compile time and provide constants to the zcalloc() call.
+ (For better readability, some subexpressions are encapsulated
+ in temporarly defined macros.)
+ */
+# define UZ_SLIDE_CHUNK (sizeof(shrint)+sizeof(uch)+sizeof(uch))
+# define UZ_NUMOF_CHUNKS \
+ (unsigned)(((WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK > HSIZE) ? \
+ (WSIZE+UZ_SLIDE_CHUNK-1)/UZ_SLIDE_CHUNK : HSIZE)
+ G.area.Slide = (uch *)zcalloc(UZ_NUMOF_CHUNKS, UZ_SLIDE_CHUNK);
+# undef UZ_SLIDE_CHUNK
+# undef UZ_NUMOF_CHUNKS
+ G.area.shrink.Parent = (shrint *)G.area.Slide;
+ G.area.shrink.value = G.area.Slide + (sizeof(shrint)*(HSIZE));
+ G.area.shrink.Stack = G.area.Slide +
+ (sizeof(shrint) + sizeof(uch))*(HSIZE);
+#endif
+
+/*---------------------------------------------------------------------------
+ Set signal handler for restoring echo, warn of zipfile corruption, etc.
+ ---------------------------------------------------------------------------*/
+#ifndef NO_EXCEPT_SIGNALS
+#ifdef SIGINT
+ SET_SIGHANDLER(SIGINT, handler);
+#endif
+#ifdef SIGTERM /* some systems really have no SIGTERM */
+ SET_SIGHANDLER(SIGTERM, handler);
+#endif
+#ifdef SIGBUS
+ SET_SIGHANDLER(SIGBUS, handler);
+#endif
+#ifdef SIGSEGV
+ SET_SIGHANDLER(SIGSEGV, handler);
+#endif
+#endif /* NO_EXCEPT_SIGNALS */
+
+#if (defined(WIN32) && defined(__RSXNT__))
+ for (i = 0 ; i < argc; i++) {
+ _ISO_INTERN(argv[i]);
+ }
+#endif
+
+/*---------------------------------------------------------------------------
+ Macintosh initialization code.
+ ---------------------------------------------------------------------------*/
+
+#ifdef MACOS
+ {
+ int a;
+
+ for (a = 0; a < 4; ++a)
+ G.rghCursor[a] = GetCursor(a+128);
+ G.giCursor = 0;
+ }
+#endif
+
+/*---------------------------------------------------------------------------
+ NetWare initialization code.
+ ---------------------------------------------------------------------------*/
+
+#ifdef NLM
+ InitUnZipConsole();
+#endif
+
+/*---------------------------------------------------------------------------
+ Acorn RISC OS initialization code.
+ ---------------------------------------------------------------------------*/
+
+#ifdef RISCOS
+ set_prefix();
+#endif
+
+/*---------------------------------------------------------------------------
+ Theos initialization code.
+ ---------------------------------------------------------------------------*/
+
+#ifdef THEOS
+ /* The easiest way found to force creation of libraries when selected
+ * members are to be unzipped. Explicitely add libraries names to the
+ * arguments list before the first member of the library.
+ */
+ if (! _setargv(&argc, &argv)) {
+ Info(slide, 0x401, ((char *)slide, "cannot process argv\n"));
+ retcode = PK_MEM;
+ goto cleanup_and_exit;
+ }
+#endif
+
+/*---------------------------------------------------------------------------
+ First figure out if we're running in UnZip mode or ZipInfo mode, and put
+ the appropriate environment-variable options into the queue. Then rip
+ through any command-line options lurking about...
+ ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+ G.argv0 = argv[0];
+#if (defined(OS2) || defined(WIN32))
+ G.zipfn = GetLoadPath(__G);/* non-MSC NT puts path into G.filename[] */
+#else
+ G.zipfn = G.argv0;
+#endif
+
+#ifdef VMSCLI
+ {
+ ulg status = vms_unzip_cmdline(&argc, &argv);
+ if (!(status & 1)) {
+ retcode = (int)status;
+ goto cleanup_and_exit;
+ }
+ }
+#endif /* VMSCLI */
+
+ uO.zipinfo_mode = FALSE;
+ error = uz_opts(__G__ &argc, &argv); /* UnZipSFX call only */
+
+#else /* !SFX */
+
+#ifdef RISCOS
+ /* get the extensions to swap from environment */
+ getRISCOSexts(ENV_UNZIPEXTS);
+#endif
+
+#ifdef MSDOS
+ /* extract MKS extended argument list from environment (before envargs!) */
+ mksargs(&argc, &argv);
+#endif
+
+#ifdef VMSCLI
+ {
+ ulg status = vms_unzip_cmdline(&argc, &argv);
+ if (!(status & 1)) {
+ retcode = (int)status;
+ goto cleanup_and_exit;
+ }
+ }
+#endif /* VMSCLI */
+
+ G.noargs = (argc == 1); /* no options, no zipfile, no anything */
+
+#ifndef NO_ZIPINFO
+ for (p = argv[0] + strlen(argv[0]); p >= argv[0]; --p) {
+ if (*p == DIR_END
+#ifdef DIR_END2
+ || *p == DIR_END2
+#endif
+ )
+ break;
+ }
+ ++p;
+
+#ifdef THEOS
+ if (strncmp(p, "ZIPINFO.",8) == 0 || strstr(p, ".ZIPINFO:") != NULL ||
+ strncmp(p, "II.",3) == 0 || strstr(p, ".II:") != NULL ||
+#else
+ if (STRNICMP(p, LoadFarStringSmall(Zipnfo), 7) == 0 ||
+ STRNICMP(p, "ii", 2) == 0 ||
+#endif
+ (argc > 1 && strncmp(argv[1], "-Z", 2) == 0))
+ {
+ uO.zipinfo_mode = TRUE;
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvZipInfo),
+ LoadFarStringSmall2(EnvZipInfo2))) != PK_OK)
+ perror(LoadFarString(NoMemArguments));
+ else
+#endif
+ error = zi_opts(__G__ &argc, &argv);
+ } else
+#endif /* !NO_ZIPINFO */
+ {
+ uO.zipinfo_mode = FALSE;
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ if ((error = envargs(&argc, &argv, LoadFarStringSmall(EnvUnZip),
+ LoadFarStringSmall2(EnvUnZip2))) != PK_OK)
+ perror(LoadFarString(NoMemArguments));
+ else
+#endif
+ error = uz_opts(__G__ &argc, &argv);
+ }
+
+#endif /* ?SFX */
+
+ if ((argc < 0) || error) {
+ retcode = error;
+ goto cleanup_and_exit;
+ }
+
+/*---------------------------------------------------------------------------
+ Now get the zipfile name from the command line and then process any re-
+ maining options and file specifications.
+ ---------------------------------------------------------------------------*/
+
+#ifdef DOS_FLX_H68_NLM_OS2_W32
+ /* convert MSDOS-style 'backward slash' directory separators to Unix-style
+ * 'forward slashes' for user's convenience (include zipfile name itself)
+ */
+#ifdef SFX
+ for (G.pfnames = argv, i = argc; i > 0; --i) {
+#else
+ /* argc does not include the zipfile specification */
+ for (G.pfnames = argv, i = argc+1; i > 0; --i) {
+#endif
+#ifdef __human68k__
+ extern char *_toslash(char *);
+ _toslash(*G.pfnames);
+#else /* !__human68k__ */
+ char *q = *G.pfnames;
+
+ while (*q != '\0') {
+ if (*q == '\\')
+ *q = '/';
+ INCSTR(q);
+ }
+ ++G.pfnames;
+#endif /* ?__human68k__ */
+ }
+#endif /* DOS_FLX_H68_NLM_OS2_W32 */
+
+#ifndef SFX
+ G.wildzipfn = *argv++;
+#endif
+
+#if (defined(SFX) && !defined(SFX_EXDIR)) /* only check for -x */
+
+ G.filespecs = argc;
+ G.xfilespecs = 0;
+
+ if (argc > 0) {
+ char **pp = argv-1;
+
+ G.pfnames = argv;
+ while (*++pp)
+ if (strcmp(*pp, "-x") == 0) {
+ if (pp > argv) {
+ *pp = 0; /* terminate G.pfnames */
+ G.filespecs = pp - G.pfnames;
+ } else {
+ G.pfnames = (char **)fnames; /* defaults */
+ G.filespecs = 0;
+ }
+ G.pxnames = pp + 1; /* excluded-names ptr: _after_ -x */
+ G.xfilespecs = argc - G.filespecs - 1;
+ break; /* skip rest of args */
+ }
+ G.process_all_files = FALSE;
+ } else
+ G.process_all_files = TRUE; /* for speed */
+
+#else /* !SFX || SFX_EXDIR */ /* check for -x or -d */
+
+ G.filespecs = argc;
+ G.xfilespecs = 0;
+
+ if (argc > 0) {
+ int in_files=FALSE, in_xfiles=FALSE;
+ char **pp = argv-1;
+
+ G.process_all_files = FALSE;
+ G.pfnames = argv;
+ while (*++pp) {
+ Trace((stderr, "pp - argv = %d\n", pp-argv));
+#ifdef CMS_MVS
+ if (!uO.exdir && STRNICMP(*pp, "-d", 2) == 0) {
+#else
+ if (!uO.exdir && strncmp(*pp, "-d", 2) == 0) {
+#endif
+ int firstarg = (pp == argv);
+
+ uO.exdir = (*pp) + 2;
+ if (in_files) { /* ... zipfile ... -d exdir ... */
+ *pp = (char *)NULL; /* terminate G.pfnames */
+ G.filespecs = pp - G.pfnames;
+ in_files = FALSE;
+ } else if (in_xfiles) {
+ *pp = (char *)NULL; /* terminate G.pxnames */
+ G.xfilespecs = pp - G.pxnames;
+ /* "... -x xlist -d exdir": nothing left */
+ }
+ /* first check for "-dexdir", then for "-d exdir" */
+ if (*uO.exdir == '\0') {
+ if (*++pp)
+ uO.exdir = *pp;
+ else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGiveExdir)));
+ /* don't extract here by accident */
+ retcode = PK_PARAM;
+ goto cleanup_and_exit;
+ }
+ }
+ if (firstarg) { /* ... zipfile -d exdir ... */
+ if (pp[1]) {
+ G.pfnames = pp + 1; /* argv+2 */
+ G.filespecs = argc - (G.pfnames-argv); /* for now... */
+ } else {
+ G.process_all_files = TRUE;
+ G.pfnames = (char **)fnames; /* GRR: necessary? */
+ G.filespecs = 0; /* GRR: necessary? */
+ break;
+ }
+ }
+ } else if (!in_xfiles) {
+ if (strcmp(*pp, "-x") == 0) {
+ in_xfiles = TRUE;
+ if (pp == G.pfnames) {
+ G.pfnames = (char **)fnames; /* defaults */
+ G.filespecs = 0;
+ } else if (in_files) {
+ *pp = 0; /* terminate G.pfnames */
+ G.filespecs = pp - G.pfnames; /* adjust count */
+ in_files = FALSE;
+ }
+ G.pxnames = pp + 1; /* excluded-names ptr starts after -x */
+ G.xfilespecs = argc - (G.pxnames-argv); /* anything left */
+ } else
+ in_files = TRUE;
+ }
+ }
+ } else
+ G.process_all_files = TRUE; /* for speed */
+
+ if (uO.exdir != (char *)NULL && !G.extract_flag) /* -d ignored */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(NotExtracting)));
+#endif /* ?(SFX && !SFX_EXDIR) */
+
+/*---------------------------------------------------------------------------
+ Okey dokey, we have everything we need to get started. Let's roll.
+ ---------------------------------------------------------------------------*/
+
+ retcode = process_zipfiles(__G);
+
+cleanup_and_exit:
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+ /* restore all signal handlers back to their state at function entry */
+ while (oldsighandlers != NULL) {
+ savsigs_info *thissigsav = oldsighandlers;
+
+ signal(thissigsav->sigtype, thissigsav->sighandler);
+ oldsighandlers = thissigsav->previous;
+ free(thissigsav);
+ }
+#endif
+#if (defined(MALLOC_WORK) && !defined(REENTRANT))
+ if (G.area.Slide != (uch *)NULL) {
+ free(G.area.Slide);
+ G.area.Slide = (uch *)NULL;
+ }
+#endif
+ return(retcode);
+
+} /* end main()/unzip() */
+
+
+
+
+
+#if (defined(REENTRANT) && !defined(NO_EXCEPT_SIGNALS))
+/*******************************/
+/* Function setsignalhandler() */
+/*******************************/
+
+static int setsignalhandler(__G__ p_savedhandler_chain, signal_type,
+ newhandler)
+ __GDEF
+ savsigs_info **p_savedhandler_chain;
+ int signal_type;
+ void (*newhandler)(int);
+{
+ savsigs_info *savsig;
+
+ savsig = malloc(sizeof(savsigs_info));
+ if (savsig == NULL) {
+ /* error message and break */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CantSaveSigHandler)));
+ return PK_MEM;
+ }
+ savsig->sigtype = signal_type;
+ savsig->sighandler = signal(SIGINT, newhandler);
+ if (savsig->sighandler == SIG_ERR) {
+ free(savsig);
+ } else {
+ savsig->previous = *p_savedhandler_chain;
+ *p_savedhandler_chain = savsig;
+ }
+ return PK_OK;
+
+} /* end function setsignalhandler() */
+
+#endif /* REENTRANT && !NO_EXCEPT_SIGNALS */
+
+
+
+
+
+/**********************/
+/* Function uz_opts() */
+/**********************/
+
+int uz_opts(__G__ pargc, pargv)
+ __GDEF
+ int *pargc;
+ char ***pargv;
+{
+ char **argv, *s;
+ int argc, c, error=FALSE, negative=0;
+
+
+ argc = *pargc;
+ argv = *pargv;
+
+ while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
+ s = *argv + 1;
+ while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
+#ifdef CMS_MVS
+ switch (tolower(c))
+#else
+ switch (c)
+#endif
+ {
+ case ('-'):
+ ++negative;
+ break;
+#ifdef RISCOS
+ case ('/'):
+ if (negative) { /* negative not allowed with -/ swap */
+ Info(slide, 0x401, ((char *)slide,
+ "error: must give extensions list"));
+ return(PK_PARAM); /* don't extract here by accident */
+ }
+ exts2swap = s; /* override Unzip$Exts */
+ s += strlen(s);
+ break;
+#endif
+ case ('a'):
+ if (negative) {
+ uO.aflag = MAX(uO.aflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.aflag;
+ break;
+#if (defined(DLL) && defined(API_DOC))
+ case ('A'): /* extended help for API */
+ APIhelp(__G__ argc, argv);
+ *pargc = -1; /* signal to exit successfully */
+ return 0;
+#endif
+ case ('b'):
+ if (negative) {
+#if (defined(TANDEM) || defined(VMS))
+ uO.bflag = MAX(uO.bflag-negative,0);
+#endif
+ negative = 0; /* do nothing: "-b" is default */
+ } else {
+#ifdef VMS
+ if (uO.aflag == 0)
+ ++uO.bflag;
+#endif
+#ifdef TANDEM
+ ++uO.bflag;
+#endif
+ uO.aflag = 0;
+ }
+ break;
+#ifdef UNIXBACKUP
+ case ('B'): /* -B: back up existing files */
+ if (negative)
+ uO.B_flag = FALSE, negative = 0;
+ else
+ uO.B_flag = TRUE;
+ break;
+#endif
+ case ('c'):
+ if (negative) {
+ uO.cflag = FALSE, negative = 0;
+#ifdef NATIVE
+ uO.aflag = 0;
+#endif
+ } else {
+ uO.cflag = TRUE;
+#ifdef NATIVE
+ uO.aflag = 2; /* so you can read it on the screen */
+#endif
+#ifdef DLL
+ if (G.redirect_text)
+ G.redirect_data = 2;
+#endif
+ }
+ break;
+#ifndef CMS_MVS
+ case ('C'): /* -C: match filenames case-insensitively */
+ if (negative)
+ uO.C_flag = FALSE, negative = 0;
+ else
+ uO.C_flag = TRUE;
+ break;
+#endif /* !CMS_MVS */
+#if (!defined(SFX) || defined(SFX_EXDIR))
+ case ('d'):
+ if (negative) { /* negative not allowed with -d exdir */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGiveExdir)));
+ return(PK_PARAM); /* don't extract here by accident */
+ }
+ if (uO.exdir != (char *)NULL) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OnlyOneExdir)));
+ return(PK_PARAM); /* GRR: stupid restriction? */
+ } else {
+ /* first check for "-dexdir", then for "-d exdir" */
+ uO.exdir = s;
+ if (*uO.exdir == '\0') {
+ if (argc > 1) {
+ --argc;
+ uO.exdir = *++argv;
+ if (*uO.exdir == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGiveExdir)));
+ return(PK_PARAM);
+ }
+ /* else uO.exdir points at extraction dir */
+ } else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGiveExdir)));
+ return(PK_PARAM);
+ }
+ }
+ /* uO.exdir now points at extraction dir (-dexdir or
+ * -d exdir); point s at end of exdir to avoid mis-
+ * interpretation of exdir characters as more options
+ */
+ if (*s != 0)
+ while (*++s != 0)
+ ;
+ }
+ break;
+#endif /* !SFX || SFX_EXDIR */
+ case ('e'): /* just ignore -e, -x options (extract) */
+ break;
+#ifdef MACOS
+ case ('E'): /* -E [MacOS] display Mac e.f. when restoring */
+ if( negative ) {
+ uO.E_flag = FALSE, negative = 0;
+ } else {
+ uO.E_flag = TRUE;
+ }
+ break;
+#endif /* MACOS */
+ case ('f'): /* "freshen" (extract only newer files) */
+ if (negative)
+ uO.fflag = uO.uflag = FALSE, negative = 0;
+ else
+ uO.fflag = uO.uflag = TRUE;
+ break;
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+ case ('F'): /* Acorn filetype & NFS extension handling */
+ if (negative)
+ uO.acorn_nfs_ext = FALSE, negative = 0;
+ else
+ uO.acorn_nfs_ext = TRUE;
+ break;
+#endif /* RISCOS || ACORN_FTYPE_NFS */
+ case ('h'): /* just print help message and quit */
+ *pargc = -1;
+ return USAGE(PK_OK);
+#ifdef MACOS
+ case ('i'): /* -i [MacOS] ignore filenames stored in Mac ef */
+ if( negative ) {
+ uO.i_flag = FALSE, negative = 0;
+ } else {
+ uO.i_flag = TRUE;
+ }
+ break;
+#endif /* MACOS */
+ case ('j'): /* junk pathnames/directory structure */
+ if (negative)
+ uO.jflag = FALSE, negative = 0;
+ else
+ uO.jflag = TRUE;
+ break;
+#if (defined(ATH_BEO) || defined(MACOS))
+ case ('J'): /* Junk AtheOS, BeOS or MacOS file attributes */
+ if( negative ) {
+ uO.J_flag = FALSE, negative = 0;
+ } else {
+ uO.J_flag = TRUE;
+ }
+ break;
+#endif /* ATH_BEO || MACOS */
+#ifdef ATH_BEO_UNX
+ case ('K'):
+ if (negative) {
+ uO.K_flag = FALSE, negative = 0;
+ } else {
+ uO.K_flag = TRUE;
+ }
+ break;
+#endif /* ATH_BEO_UNX */
+#ifndef SFX
+ case ('l'):
+ if (negative) {
+ uO.vflag = MAX(uO.vflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.vflag;
+ break;
+#endif /* !SFX */
+#ifndef CMS_MVS
+ case ('L'): /* convert (some) filenames to lowercase */
+ if (negative) {
+ uO.L_flag = MAX(uO.L_flag-negative,0);
+ negative = 0;
+ } else
+ ++uO.L_flag;
+ break;
+#endif /* !CMS_MVS */
+#ifdef MORE
+#ifdef CMS_MVS
+ case ('m'):
+#endif
+ case ('M'): /* send all screen output through "more" fn. */
+/* GRR: eventually check for numerical argument => height */
+ if (negative)
+ G.M_flag = FALSE, negative = 0;
+ else
+ G.M_flag = TRUE;
+ break;
+#endif /* MORE */
+ case ('n'): /* don't overwrite any files */
+ if (negative)
+ uO.overwrite_none = FALSE, negative = 0;
+ else
+ uO.overwrite_none = TRUE;
+ break;
+#ifdef AMIGA
+ case ('N'): /* restore comments as filenotes */
+ if (negative)
+ uO.N_flag = FALSE, negative = 0;
+ else
+ uO.N_flag = TRUE;
+ break;
+#endif /* AMIGA */
+ case ('o'): /* OK to overwrite files without prompting */
+ if (negative) {
+ uO.overwrite_all = MAX(uO.overwrite_all-negative,0);
+ negative = 0;
+ } else
+ ++uO.overwrite_all;
+ break;
+ case ('p'): /* pipes: extract to stdout, no messages */
+ if (negative) {
+ uO.cflag = FALSE;
+ uO.qflag = MAX(uO.qflag-999,0);
+ negative = 0;
+ } else {
+ uO.cflag = TRUE;
+ uO.qflag += 999;
+ }
+ break;
+#if CRYPT
+ /* GRR: yes, this is highly insecure, but dozens of people
+ * have pestered us for this, so here we go... */
+ case ('P'):
+ if (negative) { /* negative not allowed with -P passwd */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGivePasswd)));
+ return(PK_PARAM); /* don't extract here by accident */
+ }
+ if (uO.pwdarg != (char *)NULL) {
+/*
+ GRR: eventually support multiple passwords?
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OnlyOnePasswd)));
+ return(PK_PARAM);
+ */
+ } else {
+ /* first check for "-Ppasswd", then for "-P passwd" */
+ uO.pwdarg = s;
+ if (*uO.pwdarg == '\0') {
+ if (argc > 1) {
+ --argc;
+ uO.pwdarg = *++argv;
+ if (*uO.pwdarg == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGivePasswd)));
+ return(PK_PARAM);
+ }
+ /* else pwdarg points at decryption password */
+ } else {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(MustGivePasswd)));
+ return(PK_PARAM);
+ }
+ }
+ /* pwdarg now points at decryption password (-Ppasswd or
+ * -P passwd); point s at end of passwd to avoid mis-
+ * interpretation of passwd characters as more options
+ */
+ if (*s != 0)
+ while (*++s != 0)
+ ;
+ }
+ break;
+#endif /* CRYPT */
+ case ('q'): /* quiet: fewer comments/messages */
+ if (negative) {
+ uO.qflag = MAX(uO.qflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.qflag;
+ break;
+#ifdef QDOS
+ case ('Q'): /* QDOS flags */
+ qlflag ^= strtol(s, &s, 10);
+ break; /* we XOR this as we can config qlflags */
+#endif
+#ifdef TANDEM
+ case ('r'): /* remove file extensions */
+ if (negative)
+ uO.rflag = FALSE, negative = 0;
+ else
+ uO.rflag = TRUE;
+ break;
+#endif /* TANDEM */
+#ifdef DOS_FLX_NLM_OS2_W32
+ case ('s'): /* spaces in filenames: allow by default */
+ if (negative)
+ uO.sflag = FALSE, negative = 0;
+ else
+ uO.sflag = TRUE;
+ break;
+#endif /* DOS_FLX_NLM_OS2_W32 */
+ case ('t'):
+ if (negative)
+ uO.tflag = FALSE, negative = 0;
+ else
+ uO.tflag = TRUE;
+ break;
+#ifdef TIMESTAMP
+ case ('T'):
+ if (negative)
+ uO.T_flag = FALSE, negative = 0;
+ else
+ uO.T_flag = TRUE;
+ break;
+#endif
+ case ('u'): /* update (extract only new and newer files) */
+ if (negative)
+ uO.uflag = FALSE, negative = 0;
+ else
+ uO.uflag = TRUE;
+ break;
+#ifndef CMS_MVS
+ case ('U'): /* obsolete; to be removed in version 6.0 */
+ if (negative)
+ uO.L_flag = TRUE, negative = 0;
+ else
+ uO.L_flag = FALSE;
+ break;
+#endif /* !CMS_MVS */
+#ifndef SFX
+ case ('v'): /* verbose */
+ if (negative) {
+ uO.vflag = MAX(uO.vflag-negative,0);
+ negative = 0;
+ } else if (uO.vflag)
+ ++uO.vflag;
+ else
+ uO.vflag = 2;
+ break;
+#endif /* !SFX */
+#ifndef CMS_MVS
+ case ('V'): /* Version (retain VMS/DEC-20 file versions) */
+ if (negative)
+ uO.V_flag = FALSE, negative = 0;
+ else
+ uO.V_flag = TRUE;
+ break;
+#endif /* !CMS_MVS */
+#ifdef WILD_STOP_AT_DIR
+ case ('W'): /* Wildcard interpretation (stop at '/'?) */
+ if (negative)
+ uO.W_flag = FALSE, negative = 0;
+ else
+ uO.W_flag = TRUE;
+ break;
+#endif /* WILD_STOP_AT_DIR */
+ case ('x'): /* extract: default */
+#ifdef SFX
+ /* when 'x' is the only option in this argument, and the
+ * next arg is not an option, assume this initiates an
+ * exclusion list (-x xlist): terminate option-scanning
+ * and leave uz_opts with argv still pointing to "-x";
+ * the xlist is processed later
+ */
+ if (s - argv[0] == 2 && *s == '\0' &&
+ argc > 1 && argv[1][0] != '-') {
+ /* break out of nested loops without "++argv;--argc" */
+ goto opts_done;
+ }
+#endif /* SFX */
+ break;
+#if (defined(RESTORE_UIDGID) || defined(RESTORE_ACL))
+ case ('X'): /* restore owner/protection info (need privs?) */
+ if (negative) {
+ uO.X_flag = MAX(uO.X_flag-negative,0);
+ negative = 0;
+ } else
+ ++uO.X_flag;
+ break;
+#endif /* RESTORE_UIDGID || RESTORE_ACL */
+ case ('z'): /* display only the archive comment */
+ if (negative) {
+ uO.zflag = MAX(uO.zflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.zflag;
+ break;
+#ifndef SFX
+ case ('Z'): /* should have been first option (ZipInfo) */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(Zfirst)));
+ error = TRUE;
+ break;
+#endif /* !SFX */
+#ifdef DOS_H68_OS2_W32
+ case ('$'):
+ if (negative) {
+ uO.volflag = MAX(uO.volflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.volflag;
+ break;
+#endif /* DOS_H68_OS2_W32 */
+#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
+ case (':'):
+ if (negative) {
+ uO.ddotflag = MAX(uO.ddotflag-negative,0);
+ negative = 0;
+ } else
+ ++uO.ddotflag;
+ break;
+#endif /* !RISCOS && !CMS_MVS && !TANDEM */
+ default:
+ error = TRUE;
+ break;
+
+ } /* end switch */
+ } /* end while (not end of argument string) */
+ } /* end while (not done with switches) */
+
+/*---------------------------------------------------------------------------
+ Check for nonsensical combinations of options.
+ ---------------------------------------------------------------------------*/
+
+#ifdef SFX
+opts_done: /* yes, very ugly...but only used by UnZipSFX with -x xlist */
+#endif
+
+ if ((uO.cflag && uO.tflag) || (uO.cflag && uO.uflag) ||
+ (uO.tflag && uO.uflag) || (uO.fflag && uO.overwrite_none))
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(InvalidOptionsMsg)));
+ error = TRUE;
+ }
+ if (uO.aflag > 2)
+ uO.aflag = 2;
+#ifdef VMS
+ if (uO.bflag > 2)
+ uO.bflag = 2;
+#endif
+ if (uO.overwrite_all && uO.overwrite_none) {
+ Info(slide, 0x401, ((char *)slide, LoadFarString(IgnoreOOptionMsg)));
+ uO.overwrite_all = FALSE;
+ }
+#ifdef MORE
+ if (G.M_flag && !isatty(1)) /* stdout redirected: "more" func. useless */
+ G.M_flag = 0;
+#endif
+
+#ifdef SFX
+ if (error)
+#else
+ if ((argc-- == 0) || error)
+#endif
+ {
+ *pargc = argc;
+ *pargv = argv;
+#ifndef SFX
+ if (uO.vflag >= 2 && argc == -1) { /* "unzip -v" */
+ show_version_info(__G);
+ return PK_OK;
+ }
+ if (!G.noargs && !error)
+ error = PK_PARAM; /* had options (not -h or -v) but no zipfile */
+#endif /* !SFX */
+ return USAGE(error);
+ }
+
+#ifdef SFX
+ /* print our banner unless we're being fairly quiet */
+ if (uO.qflag < 2)
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate)));
+#ifdef BETA
+ /* always print the beta warning: no unauthorized distribution!! */
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
+ "SFX"));
+#endif
+#endif /* SFX */
+
+ if (uO.cflag || uO.tflag || uO.vflag || uO.zflag
+#ifdef TIMESTAMP
+ || uO.T_flag
+#endif
+ )
+ G.extract_flag = FALSE;
+ else
+ G.extract_flag = TRUE;
+
+ *pargc = argc;
+ *pargv = argv;
+ return PK_OK;
+
+} /* end function uz_opts() */
+
+
+
+
+/********************/
+/* Function usage() */
+/********************/
+
+#ifdef SFX
+# ifdef VMS
+# define LOCAL "X.\n\
+(Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND.)"
+# endif
+# ifdef UNIX
+# define LOCAL "X"
+# endif
+# ifdef DOS_OS2_W32
+# define LOCAL "s$"
+# endif
+# if (defined(FLEXOS) || defined(NLM))
+# define LOCAL "s"
+# endif
+# ifdef AMIGA
+# define LOCAL "N"
+# endif
+ /* Default for all other systems: */
+# ifndef LOCAL
+# define LOCAL ""
+# endif
+
+# ifdef MORE
+# define SFXOPT1 "M"
+# else
+# define SFXOPT1 ""
+# endif
+
+int usage(__G__ error) /* return PK-type error code */
+ __GDEF
+ int error;
+{
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXBanner),
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate)));
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(UnzipSFXOpts),
+ SFXOPT1, LOCAL));
+#ifdef BETA
+ Info(slide, error? 1 : 0, ((char *)slide, LoadFarString(BetaVersion), "\n",
+ "SFX"));
+#endif
+
+ if (error)
+ return PK_PARAM;
+ else
+ return PK_COOL; /* just wanted usage screen: no error */
+
+} /* end function usage() */
+
+
+
+
+
+#else /* !SFX */
+# ifdef VMS
+# define QUOT '\"'
+# define QUOTS "\""
+# else
+# define QUOT ' '
+# define QUOTS ""
+# endif
+
+int usage(__G__ error) /* return PK-type error code */
+ __GDEF
+ int error;
+{
+ int flag = (error? 1 : 0);
+
+
+/*---------------------------------------------------------------------------
+ Print either ZipInfo usage or UnZip usage, depending on incantation.
+ (Strings must be no longer than 512 bytes for Turbo C, apparently.)
+ ---------------------------------------------------------------------------*/
+
+ if (uO.zipinfo_mode) {
+
+#ifndef NO_ZIPINFO
+
+ Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine1),
+ ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate),
+ LoadFarStringSmall2(ZipInfoExample), QUOTS,QUOTS));
+ Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine2)));
+ Info(slide, flag, ((char *)slide, LoadFarString(ZipInfoUsageLine3),
+ QUOT,QUOT, QUOT,QUOT, LoadFarStringSmall(ZipInfoUsageLine4)));
+#ifdef VMS
+ Info(slide, flag, ((char *)slide, "\n\
+You must quote non-lowercase options and filespecs, unless SET PROC/PARSE=EXT.\
+\n"));
+#endif
+
+#endif /* !NO_ZIPINFO */
+
+ } else { /* UnZip mode */
+
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine1),
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate)));
+#ifdef BETA
+ Info(slide, flag, ((char *)slide, LoadFarString(BetaVersion), "", ""));
+#endif
+
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine2),
+ ZIPINFO_MODE_OPTION, LoadFarStringSmall(ZipInfoMode)));
+#ifdef VMS
+ if (!error) /* maybe no command-line tail found; show extra help */
+ Info(slide, flag, ((char *)slide, LoadFarString(VMSusageLine2b)));
+#endif
+
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine3),
+ LoadFarStringSmall(local1)));
+
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine4),
+ QUOT,QUOT, QUOT,QUOT, LoadFarStringSmall(local2), QUOT,QUOT,
+ LoadFarStringSmall2(local3)));
+
+ /* This is extra work for SMALL_MEM, but it will work since
+ * LoadFarStringSmall2 uses the same buffer. Remember, this
+ * is a hack. */
+ Info(slide, flag, ((char *)slide, LoadFarString(UnzipUsageLine5),
+ LoadFarStringSmall(Example2), LoadFarStringSmall2(Example3),
+ LoadFarStringSmall2(Example3)));
+
+ } /* end if (uO.zipinfo_mode) */
+
+ if (error)
+ return PK_PARAM;
+ else
+ return PK_COOL; /* just wanted usage screen: no error */
+
+} /* end function usage() */
+
+#endif /* ?SFX */
+
+
+
+
+#ifndef SFX
+
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+#if (!defined(MODERN) || defined(NO_STDLIB_H))
+/* Declare getenv() to be sure (might be missing in some environments) */
+extern char *getenv();
+#endif
+#endif
+
+/********************************/
+/* Function show_version_info() */
+/********************************/
+
+static void show_version_info(__G)
+ __GDEF
+{
+ if (uO.qflag > 3) /* "unzip -vqqqq" */
+ Info(slide, 0, ((char *)slide, "%d\n",
+ (UZ_MAJORVER*100 + UZ_MINORVER*10 + UZ_PATCHLEVEL)));
+ else {
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ char *envptr;
+#endif
+ int numopts = 0;
+
+ Info(slide, 0, ((char *)slide, LoadFarString(UnzipUsageLine1v),
+ UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL,
+ LoadFarStringSmall(VersionDate)));
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(UnzipUsageLine2v)));
+ version(__G);
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptions)));
+#ifdef ACORN_FTYPE_NFS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(AcornFtypeNFS)));
+ ++numopts;
+#endif
+#ifdef ASM_CRC
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(AsmCRC)));
+ ++numopts;
+#endif
+#ifdef ASM_INFLATECODES
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(AsmInflateCodes)));
+ ++numopts;
+#endif
+#ifdef CHECK_VERSIONS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Check_Versions)));
+ ++numopts;
+#endif
+#ifdef COPYRIGHT_CLEAN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Copyright_Clean)));
+ ++numopts;
+#endif
+#ifdef DEBUG
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(UDebug)));
+ ++numopts;
+#endif
+#ifdef DEBUG_TIME
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(DebugTime)));
+ ++numopts;
+#endif
+#ifdef DLL
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Dll)));
+ ++numopts;
+#endif
+#ifdef DOSWILD
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(DosWild)));
+ ++numopts;
+#endif
+#ifdef LZW_CLEAN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(LZW_Clean)));
+ ++numopts;
+#endif
+#ifndef MORE
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(No_More)));
+ ++numopts;
+#endif
+#ifdef NO_ZIPINFO
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(No_ZipInfo)));
+ ++numopts;
+#endif
+#ifdef NTSD_EAS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(NTSDExtAttrib)));
+ ++numopts;
+#endif
+#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(W32NoIZTimeFix)));
+ ++numopts;
+#endif
+#ifdef OLD_THEOS_EXTRA
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(OldTheosExtra)));
+ ++numopts;
+#endif
+#ifdef OS2_EAS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(OS2ExtAttrib)));
+ ++numopts;
+#endif
+#ifdef QLZIP
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(SMSExFldOnUnix)));
+ ++numopts;
+#endif
+#ifdef REENTRANT
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Reentrant)));
+ ++numopts;
+#endif
+#ifdef REGARGS
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(RegArgs)));
+ ++numopts;
+#endif
+#ifdef RETURN_CODES
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Return_Codes)));
+ ++numopts;
+#endif
+#ifdef SET_DIR_ATTRIB
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(SetDirAttrib)));
+ ++numopts;
+#endif
+#ifdef TIMESTAMP
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(TimeStamp)));
+ ++numopts;
+#endif
+#ifdef UNIXBACKUP
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(UnixBackup)));
+ ++numopts;
+#endif
+#ifdef USE_EF_UT_TIME
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_EF_UT_time)));
+ ++numopts;
+#endif
+#ifndef COPYRIGHT_CLEAN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_Smith_Code)));
+ ++numopts;
+#endif
+#ifndef LZW_CLEAN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_Unshrink)));
+ ++numopts;
+#endif
+#ifdef USE_DEFLATE64
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_Deflate64)));
+ ++numopts;
+#endif
+#ifdef MULT_VOLUME
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_MultiVol)));
+ ++numopts;
+#endif
+#if (defined(__DJGPP__) && (__DJGPP__ >= 2))
+# ifdef USE_DJGPP_ENV
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_DJGPP_Env)));
+ ++numopts;
+# endif
+# ifdef USE_DJGPP_GLOB
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_DJGPP_Glob)));
+ ++numopts;
+# endif
+#endif /* __DJGPP__ && (__DJGPP__ >= 2) */
+#ifdef USE_VFAT
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(Use_VFAT_support)));
+ ++numopts;
+#endif
+#ifdef USE_ZLIB
+ sprintf((char *)(slide+256), LoadFarStringSmall(UseZlib),
+ ZLIB_VERSION, zlibVersion());
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ (char *)(slide+256)));
+ ++numopts;
+#endif
+#ifdef VMS_TEXT_CONV
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(VmsTextConv)));
+ ++numopts;
+#endif
+#ifdef VMSCLI
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(VmsCLI)));
+ ++numopts;
+#endif
+#ifdef VMSWILD
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(VmsWild)));
+ ++numopts;
+#endif
+#ifdef WILD_STOP_AT_DIR
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(WildStopAtDir)));
+ ++numopts;
+#endif
+#if CRYPT
+# ifdef PASSWD_FROM_STDIN
+ Info(slide, 0, ((char *)slide, LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(PasswdStdin)));
+# endif
+ Info(slide, 0, ((char *)slide, LoadFarString(Decryption),
+ CR_MAJORVER, CR_MINORVER, CR_BETA_VER,
+ LoadFarStringSmall(CryptDate)));
+ ++numopts;
+#endif /* CRYPT */
+ if (numopts == 0)
+ Info(slide, 0, ((char *)slide,
+ LoadFarString(CompileOptFormat),
+ LoadFarStringSmall(None)));
+
+#ifndef _WIN32_WCE /* Win CE does not support environment variables */
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptions)));
+ envptr = getenv(LoadFarStringSmall(EnvUnZip));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvUnZip),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvUnZip2));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvUnZip2),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvZipInfo));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvZipInfo),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvZipInfo2));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvZipInfo2),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+#ifndef __RSXNT__
+#ifdef __EMX__
+ envptr = getenv(LoadFarStringSmall(EnvEMX));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvEMX),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvEMXOPT));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvEMXOPT),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+#endif /* __EMX__ */
+#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2)))
+ envptr = getenv(LoadFarStringSmall(EnvGO32));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvGO32),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+ envptr = getenv(LoadFarStringSmall(EnvGO32TMP));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvGO32TMP),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+#endif /* __GO32__ && !(__DJGPP__ >= 2) */
+#endif /* !__RSXNT__ */
+#ifdef RISCOS
+ envptr = getenv(LoadFarStringSmall(EnvUnZipExts));
+ Info(slide, 0, ((char *)slide, LoadFarString(EnvOptFormat),
+ LoadFarStringSmall(EnvUnZipExts),
+ (envptr == (char *)NULL || *envptr == 0)?
+ LoadFarStringSmall2(None) : envptr));
+#endif /* RISCOS */
+#endif /* !_WIN32_WCE */
+ }
+} /* end function show_version() */
+
+#endif /* !SFX */
+#endif /* !WINDLL */
Property changes on: trunk/build/install/installer/unzip.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/unzip.h
===================================================================
--- trunk/build/install/installer/unzip.h (rev 0)
+++ trunk/build/install/installer/unzip.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,658 @@
+/*---------------------------------------------------------------------------
+
+ unzip.h (new)
+
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ This header file contains the public macros and typedefs required by
+ both the UnZip sources and by any application using the UnZip API. If
+ UNZIP_INTERNAL is defined, it includes unzpriv.h (containing includes,
+ prototypes and extern variables used by the actual UnZip sources).
+
+ ---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------
+This is version 2005-Feb-10 of the Info-ZIP copyright and license.
+The definitive version of this document should be available at
+ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely.
+
+
+Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+For the purposes of this copyright and license, "Info-ZIP" is defined as
+the following set of individuals:
+
+ Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
+ Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth,
+ Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
+ David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
+ Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
+ Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda,
+ Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren,
+ Rich Wales, Mike White
+
+This software is provided "as is," without warranty of any kind, express
+or implied. In no event shall Info-ZIP or its contributors be held liable
+for any direct, indirect, incidental, special or consequential damages
+arising out of the use of or inability to use this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ definition, disclaimer, and this list of conditions.
+
+ 2. Redistributions in binary form (compiled executables) must reproduce
+ the above copyright notice, definition, disclaimer, and this list of
+ conditions in documentation and/or other materials provided with the
+ distribution. The sole exception to this condition is redistribution
+ of a standard UnZipSFX binary (including SFXWiz) as part of a
+ self-extracting archive; that is permitted without inclusion of this
+ license, as long as the normal SFX banner has not been removed from
+ the binary or disabled.
+
+ 3. Altered versions--including, but not limited to, ports to new operating
+ systems, existing ports with new graphical interfaces, and dynamic,
+ shared, or static library versions--must be plainly marked as such
+ and must not be misrepresented as being the original source. Such
+ altered versions also must not be misrepresented as being Info-ZIP
+ releases--including, but not limited to, labeling of the altered
+ versions with the names "Info-ZIP" (or any variation thereof, including,
+ but not limited to, different capitalizations), "Pocket UnZip," "WiZ"
+ or "MacZip" without the explicit permission of Info-ZIP. Such altered
+ versions are further prohibited from misrepresentative use of the
+ Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s).
+
+ 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip,"
+ "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its
+ own source and binary releases.
+ ---------------------------------------------------------------------------*/
+
+#ifndef __unzip_h /* prevent multiple inclusions */
+#define __unzip_h
+
+/*---------------------------------------------------------------------------
+ Predefined, machine-specific macros.
+ ---------------------------------------------------------------------------*/
+
+#ifdef __GO32__ /* MS-DOS extender: NOT Unix */
+# ifdef unix
+# undef unix
+# endif
+# ifdef _unix
+# undef _unix
+# endif
+# ifdef __unix
+# undef __unix
+# endif
+# ifdef __unix__
+# undef __unix__
+# endif
+#endif
+
+#if ((defined(__convex__) || defined(__convexc__)) && !defined(CONVEX))
+# define CONVEX
+#endif
+
+#if (defined(unix) || defined(_unix) || defined(__unix) || defined(__unix__))
+# ifndef UNIX
+# define UNIX
+# endif
+#endif /* unix || _unix || __unix || __unix__ */
+#if (defined(M_XENIX) || defined(COHERENT) || defined(__hpux))
+# ifndef UNIX
+# define UNIX
+# endif
+#endif /* M_XENIX || COHERENT || __hpux */
+#if (defined(__NetBSD__) || defined(__FreeBSD__))
+# ifndef UNIX
+# define UNIX
+# endif
+#endif /* __NetBSD__ || __FreeBSD__ */
+#if (defined(CONVEX) || defined(MINIX) || defined(_AIX) || defined(__QNX__))
+# ifndef UNIX
+# define UNIX
+# endif
+#endif /* CONVEX || MINIX || _AIX || __QNX__ */
+
+#if (defined(VM_CMS) || defined(MVS))
+# define CMS_MVS
+#endif
+
+#if (defined(__OS2__) && !defined(OS2))
+# define OS2
+#endif
+
+#if (defined(__TANDEM) && !defined(TANDEM))
+# define TANDEM
+#endif
+
+#if (defined(__VMS) && !defined(VMS))
+# define VMS
+#endif
+
+#if ((defined(__WIN32__) || defined(_WIN32)) && !defined(WIN32))
+# define WIN32
+#endif
+#if ((defined(__WINNT__) || defined(__WINNT)) && !defined(WIN32))
+# define WIN32
+#endif
+
+#if defined(_WIN32_WCE)
+# ifndef WIN32 /* WinCE is treated as a variant of the Win32 API */
+# define WIN32
+# endif
+# ifndef UNICODE /* WinCE requires UNICODE wide character support */
+# define UNICODE
+# endif
+#endif
+
+#ifdef __COMPILER_KCC__
+# include <c-env.h>
+# ifdef SYS_T20
+# define TOPS20
+# endif
+#endif /* __COMPILER_KCC__ */
+
+/* Borland C does not define __TURBOC__ if compiling for a 32-bit platform */
+#ifdef __BORLANDC__
+# ifndef __TURBOC__
+# define __TURBOC__
+# endif
+# if (!defined(__MSDOS__) && !defined(OS2) && !defined(WIN32))
+# define __MSDOS__
+# endif
+#endif
+
+/* define MSDOS for Turbo C (unless OS/2) and Power C as well as Microsoft C */
+#ifdef __POWERC
+# define __TURBOC__
+# define MSDOS
+#endif /* __POWERC */
+
+#if (defined(__MSDOS__) && !defined(MSDOS)) /* just to make sure */
+# define MSDOS
+#endif
+
+/* RSXNTDJ (at least up to v1.3) compiles for WIN32 (RSXNT) using a derivate
+ of the EMX environment, but defines MSDOS and __GO32__. ARG !!! */
+#if (defined(MSDOS) && defined(WIN32))
+# undef MSDOS /* WIN32 is >>>not<<< MSDOS */
+#endif
+#if (defined(__GO32__) && defined(__EMX__) && defined(__RSXNT__))
+# undef __GO32__
+#endif
+
+#if (defined(linux) && !defined(LINUX))
+# define LINUX
+#endif
+
+#ifdef __riscos
+# define RISCOS
+#endif
+
+#if (defined(THINK_C) || defined(MPW))
+# define MACOS
+#endif
+#if (defined(__MWERKS__) && defined(macintosh))
+# define MACOS
+#endif
+
+/* use prototypes and ANSI libraries if __STDC__, or MS-DOS, or OS/2, or Win32,
+ * or IBM C Set/2, or Borland C, or Watcom C, or GNU gcc (emx or Cygwin),
+ * or Macintosh, or Sequent, or Atari, or IBM RS/6000, or Silicon Graphics,
+ * or Convex?, or AtheOS, or BeOS.
+ */
+#if (defined(__STDC__) || defined(MSDOS) || defined(OS2) || defined(WIN32))
+# ifndef PROTO
+# define PROTO
+# endif
+# ifndef MODERN
+# define MODERN
+# endif
+#endif
+#if (defined(__IBMC__) || defined(__BORLANDC__) || defined(__WATCOMC__))
+# ifndef PROTO
+# define PROTO
+# endif
+# ifndef MODERN
+# define MODERN
+# endif
+#endif
+#if (defined(__EMX__) || defined(__CYGWIN__))
+# ifndef PROTO
+# define PROTO
+# endif
+# ifndef MODERN
+# define MODERN
+# endif
+#endif
+#if (defined(MACOS) || defined(ATARI_ST) || defined(RISCOS) || defined(THEOS))
+# ifndef PROTO
+# define PROTO
+# endif
+# ifndef MODERN
+# define MODERN
+# endif
+#endif
+/* Sequent running Dynix/ptx: non-modern compiler */
+#if (defined(_AIX) || defined(sgi) || (defined(_SEQUENT_) && !defined(PTX)))
+# ifndef PROTO
+# define PROTO
+# endif
+# ifndef MODERN
+# define MODERN
+# endif
+#endif
+#if (defined(CMS_MVS) || defined(__ATHEOS__) || defined(__BEOS__))
+/* || defined(CONVEX) ? */
+# ifndef PROTO
+# define PROTO
+# endif
+# ifndef MODERN
+# define MODERN
+# endif
+#endif
+
+/* turn off prototypes if requested */
+#if (defined(NOPROTO) && defined(PROTO))
+# undef PROTO
+#endif
+
+/* used to remove arguments in function prototypes for non-ANSI C */
+#ifdef PROTO
+# define OF(a) a
+#else
+# define OF(a) ()
+#endif
+
+/* enable the "const" keyword only if MODERN and if not otherwise instructed */
+#ifdef MODERN
+# if (!defined(ZCONST) && (defined(USE_CONST) || !defined(NO_CONST)))
+# define ZCONST const
+# endif
+#endif
+
+#ifndef ZCONST
+# define ZCONST
+#endif
+
+
+/*---------------------------------------------------------------------------
+ Grab system-specific public include headers.
+ ---------------------------------------------------------------------------*/
+
+#ifdef POCKET_UNZIP /* WinCE port */
+# include "wince/punzip.h" /* must appear before windows.h */
+#endif
+
+#ifdef WINDLL
+ /* for UnZip, the "basic" part of the win32 api is sufficient */
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# define IZ_HASDEFINED_WIN32LEAN
+# endif
+# include <windows.h>
+# include "windll/structs.h"
+# ifdef IZ_HASDEFINED_WIN32LEAN
+# undef WIN32_LEAN_AND_MEAN
+# undef IZ_HASDEFINED_WIN32LEAN
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Grab system-dependent definition of EXPENTRY for prototypes below.
+ ---------------------------------------------------------------------------*/
+
+#if 0
+#if (defined(OS2) && !defined(FUNZIP))
+# ifdef UNZIP_INTERNAL
+# define INCL_NOPM
+# define INCL_DOSNLS
+# define INCL_DOSPROCESS
+# define INCL_DOSDEVICES
+# define INCL_DOSDEVIOCTL
+# define INCL_DOSERRORS
+# define INCL_DOSMISC
+# ifdef OS2DLL
+# define INCL_REXXSAA
+# include <rexxsaa.h>
+# endif
+# endif /* UNZIP_INTERNAL */
+# include <os2.h>
+# define UZ_EXP EXPENTRY
+#endif /* OS2 && !FUNZIP */
+#endif /* 0 */
+
+#if (defined(OS2) && !defined(FUNZIP))
+# if (defined(__IBMC__) || defined(__WATCOMC__))
+# define UZ_EXP _System /* compiler keyword */
+# else
+# define UZ_EXP
+# endif
+#endif /* OS2 && !FUNZIP */
+
+#if (defined(WINDLL) || defined(USE_UNZIP_LIB))
+# ifndef EXPENTRY
+# define UZ_EXP WINAPI
+# else
+# define UZ_EXP EXPENTRY
+# endif
+#endif
+
+#ifndef UZ_EXP
+# define UZ_EXP
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------
+ Public typedefs.
+ ---------------------------------------------------------------------------*/
+
+#ifndef _IZ_TYPES_DEFINED
+#ifdef MODERN
+ typedef void zvoid;
+#else /* !MODERN */
+# ifndef AOS_VS /* mostly modern? */
+# ifndef VAXC /* not fully modern, but has knows 'void' */
+# define void int
+# endif /* !VAXC */
+# endif /* !AOS_VS */
+ typedef char zvoid;
+#endif /* ?MODERN */
+typedef unsigned char uch; /* code assumes unsigned bytes; these type- */
+typedef unsigned short ush; /* defs replace byte/UWORD/ULONG (which are */
+typedef unsigned long ulg; /* predefined on some systems) & match zip */
+#define _IZ_TYPES_DEFINED
+#endif /* !_IZ_TYPES_DEFINED */
+
+/* InputFn is not yet used and is likely to change: */
+#ifdef PROTO
+ typedef int (UZ_EXP MsgFn) (zvoid *pG, uch *buf, ulg size, int flag);
+ typedef int (UZ_EXP InputFn) (zvoid *pG, uch *buf, int *size, int flag);
+ typedef void (UZ_EXP PauseFn) (zvoid *pG, ZCONST char *prompt, int flag);
+ typedef int (UZ_EXP PasswdFn) (zvoid *pG, int *rcnt, char *pwbuf,
+ int size, ZCONST char *zfn,
+ ZCONST char *efn);
+ typedef int (UZ_EXP StatCBFn) (zvoid *pG, int fnflag, ZCONST char *zfn,
+ ZCONST char *efn, ZCONST zvoid *details);
+ typedef void (UZ_EXP UsrIniFn) (void);
+#else /* !PROTO */
+ typedef int (UZ_EXP MsgFn) ();
+ typedef int (UZ_EXP InputFn) ();
+ typedef void (UZ_EXP PauseFn) ();
+ typedef int (UZ_EXP PasswdFn) ();
+ typedef int (UZ_EXP StatCBFn) ();
+ typedef void (UZ_EXP UsrIniFn) ();
+#endif /* ?PROTO */
+
+typedef struct _UzpBuffer { /* rxstr */
+ ulg strlength; /* length of string */
+ char *strptr; /* pointer to string */
+} UzpBuffer;
+
+typedef struct _UzpInit {
+ ulg structlen; /* length of the struct being passed */
+
+ /* GRR: can we assume that each of these is a 32-bit pointer? if not,
+ * does it matter? add "far" keyword to make sure? */
+ MsgFn *msgfn;
+ InputFn *inputfn;
+ PauseFn *pausefn;
+ UsrIniFn *userfn; /* user init function to be called after */
+ /* globals constructed and initialized */
+
+ /* pointer to program's environment area or something? */
+ /* hooks for performance testing? */
+ /* hooks for extra unzip -v output? (detect CPU or other hardware?) */
+ /* anything else? let me (Greg) know... */
+} UzpInit;
+
+typedef struct _UzpCB {
+ ulg structlen; /* length of the struct being passed */
+ /* GRR: can we assume that each of these is a 32-bit pointer? if not,
+ * does it matter? add "far" keyword to make sure? */
+ MsgFn *msgfn;
+ InputFn *inputfn;
+ PauseFn *pausefn;
+ PasswdFn *passwdfn;
+ StatCBFn *statrepfn;
+} UzpCB;
+
+/* the collection of general UnZip option flags and option arguments */
+typedef struct _UzpOpts {
+#ifndef FUNZIP
+ char *exdir; /* pointer to extraction root directory (-d option) */
+ char *pwdarg; /* pointer to command-line password (-P option) */
+ int zipinfo_mode; /* behave like ZipInfo or like normal UnZip? */
+ int aflag; /* -a: do ASCII-EBCDIC and/or end-of-line translation */
+#ifdef VMS
+ int bflag; /* -b: force fixed record format for binary files */
+#endif
+#ifdef TANDEM
+ int bflag; /* -b: create text files in 'C' format (180)*/
+#endif
+#ifdef UNIXBACKUP
+ int B_flag; /* -B: back up existing files by renaming to *~ first */
+#endif
+ int cflag; /* -c: output to stdout */
+ int C_flag; /* -C: match filenames case-insensitively */
+#ifdef MACOS
+ int E_flag; /* -E: [MacOS] show Mac extra field during restoring */
+#endif
+ int fflag; /* -f: "freshen" (extract only newer files) */
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+ int acorn_nfs_ext; /* -F: RISC OS types & NFS filetype extensions */
+#endif
+ int hflag; /* -h: header line (zipinfo) */
+#ifdef MACOS
+ int i_flag; /* -i: [MacOS] ignore filenames stored in Mac e.f. */
+#endif
+#ifdef RISCOS
+ int scanimage; /* -I: scan image files */
+#endif
+ int jflag; /* -j: junk pathnames (unzip) */
+#if (defined(__ATHEOS__) || defined(__BEOS__) || defined(MACOS))
+ int J_flag; /* -J: ignore AtheOS/BeOS/MacOS e. f. info (unzip) */
+#endif
+#if (defined(__ATHEOS__) || defined(__BEOS__) || defined(UNIX))
+ int K_flag; /* -K: keep setuid/setgid/tacky permissions */
+#endif
+ int lflag; /* -12slmv: listing format (zipinfo) */
+ int L_flag; /* -L: convert filenames from some OSes to lowercase */
+ int overwrite_none; /* -n: never overwrite files (no prompting) */
+#ifdef AMIGA
+ int N_flag; /* -N: restore comments as AmigaDOS filenotes */
+#endif
+ int overwrite_all; /* -o: OK to overwrite files without prompting */
+#endif /* !FUNZIP */
+ int qflag; /* -q: produce a lot less output */
+#ifdef TANDEM
+ int rflag; /* -r: remove file extensions */
+#endif
+#ifndef FUNZIP
+#if (defined(MSDOS) || defined(FLEXOS) || defined(OS2) || defined(WIN32))
+ int sflag; /* -s: convert spaces in filenames to underscores */
+#endif
+#if (defined(NLM))
+ int sflag; /* -s: convert spaces in filenames to underscores */
+#endif
+#if (defined(MSDOS) || defined(__human68k__) || defined(OS2) || defined(WIN32))
+ int volflag; /* -$: extract volume labels */
+#endif
+ int tflag; /* -t: test (unzip) or totals line (zipinfo) */
+ int T_flag; /* -T: timestamps (unzip) or dec. time fmt (zipinfo) */
+ int uflag; /* -u: "update" (extract only newer/brand-new files) */
+ int vflag; /* -v: (verbosely) list directory */
+ int V_flag; /* -V: don't strip VMS version numbers */
+ int W_flag; /* -W: wildcard '*' won't match '/' dir separator */
+#if (defined (__ATHEOS__) || defined(__BEOS__) || defined(UNIX))
+ int X_flag; /* -X: restore owner/protection or UID/GID or ACLs */
+#else
+#if (defined(TANDEM) || defined(THEOS))
+ int X_flag; /* -X: restore owner/protection or UID/GID or ACLs */
+#else
+#if (defined(OS2) || defined(VMS) || defined(WIN32))
+ int X_flag; /* -X: restore owner/protection or UID/GID or ACLs */
+#endif
+#endif
+#endif
+ int zflag; /* -z: display the zipfile comment (only, for unzip) */
+#if (!defined(RISCOS) && !defined(CMS_MVS) && !defined(TANDEM))
+ int ddotflag; /* -:: don't skip over "../" path elements */
+#endif
+#endif /* !FUNZIP */
+} UzpOpts;
+
+/* intended to be a private struct: */
+typedef struct _ver {
+ uch major; /* e.g., integer 5 */
+ uch minor; /* e.g., 2 */
+ uch patchlevel; /* e.g., 0 */
+ uch not_used;
+} _version_type;
+
+typedef struct _UzpVer {
+ ulg structlen; /* length of the struct being passed */
+ ulg flag; /* bit 0: is_beta bit 1: uses_zlib */
+ char *betalevel; /* e.g., "g BETA" or "" */
+ char *date; /* e.g., "4 Sep 95" (beta) or "4 September 1995" */
+ char *zlib_version; /* e.g., "0.95" or NULL */
+ _version_type unzip;
+ _version_type zipinfo;
+ _version_type os2dll;
+ _version_type windll;
+} UzpVer;
+
+/* for Visual BASIC access to Windows DLLs: */
+typedef struct _UzpVer2 {
+ ulg structlen; /* length of the struct being passed */
+ ulg flag; /* bit 0: is_beta bit 1: uses_zlib */
+ char betalevel[10]; /* e.g., "g BETA" or "" */
+ char date[20]; /* e.g., "4 Sep 95" (beta) or "4 September 1995" */
+ char zlib_version[10]; /* e.g., "0.95" or NULL */
+ _version_type unzip;
+ _version_type zipinfo;
+ _version_type os2dll;
+ _version_type windll;
+} UzpVer2;
+
+typedef struct central_directory_file_header { /* CENTRAL */
+ uch version_made_by[2];
+ uch version_needed_to_extract[2];
+ ush general_purpose_bit_flag;
+ ush compression_method;
+ ulg last_mod_dos_datetime;
+ ulg crc32;
+ ulg csize;
+ ulg ucsize;
+ ush filename_length;
+ ush extra_field_length;
+ ush file_comment_length;
+ ush disk_number_start;
+ ush internal_file_attributes;
+ ulg external_file_attributes;
+ ulg relative_offset_local_header;
+} cdir_file_hdr;
+
+
+#define UZPINIT_LEN sizeof(UzpInit)
+#define UZPVER_LEN sizeof(UzpVer)
+#define cbList(func) int (* UZ_EXP func)(char *filename, cdir_file_hdr *crec)
+
+
+/*---------------------------------------------------------------------------
+ Return (and exit) values of the public UnZip API functions.
+ ---------------------------------------------------------------------------*/
+
+/* external return codes */
+#define PK_OK 0 /* no error */
+#define PK_COOL 0 /* no error */
+#define PK_WARN 1 /* warning error */
+#define PK_ERR 2 /* error in zipfile */
+#define PK_BADERR 3 /* severe error in zipfile */
+#define PK_MEM 4 /* insufficient memory (during initialization) */
+#define PK_MEM2 5 /* insufficient memory (password failure) */
+#define PK_MEM3 6 /* insufficient memory (file decompression) */
+#define PK_MEM4 7 /* insufficient memory (memory decompression) */
+#define PK_MEM5 8 /* insufficient memory (not yet used) */
+#define PK_NOZIP 9 /* zipfile not found */
+#define PK_PARAM 10 /* bad or illegal parameters specified */
+#define PK_FIND 11 /* no files found */
+#define PK_DISK 50 /* disk full */
+#define PK_EOF 51 /* unexpected EOF */
+
+#define IZ_CTRLC 80 /* user hit ^C to terminate */
+#define IZ_UNSUP 81 /* no files found: all unsup. compr/encrypt. */
+#define IZ_BADPWD 82 /* no files found: all had bad password */
+
+/* return codes of password fetches (negative = user abort; positive = error) */
+#define IZ_PW_ENTERED 0 /* got some password string; use/try it */
+#define IZ_PW_CANCEL -1 /* no password available (for this entry) */
+#define IZ_PW_CANCELALL -2 /* no password, skip any further pwd. request */
+#define IZ_PW_ERROR 5 /* = PK_MEM2 : failure (no mem, no tty, ...) */
+
+/* flag values for status callback function */
+#define UZ_ST_START_EXTRACT 1 /* no details */
+#define UZ_ST_IN_PROGRESS 2 /* no details */
+#define UZ_ST_FINISH_MEMBER 3 /* 'details': extracted size */
+
+/* return values of status callback function */
+#define UZ_ST_CONTINUE 0
+#define UZ_ST_BREAK 1
+
+
+/*---------------------------------------------------------------------------
+ Prototypes for public UnZip API (DLL) functions.
+ ---------------------------------------------------------------------------*/
+
+#define UzpMatch match
+
+int UZ_EXP UzpMain OF((int argc, char **argv));
+int UZ_EXP UzpAltMain OF((int argc, char **argv, UzpInit *init));
+UzpVer * UZ_EXP UzpVersion OF((void));
+void UZ_EXP UzpFreeMemBuffer OF((UzpBuffer *retstr));
+#ifndef WINDLL
+int UZ_EXP UzpUnzipToMemory OF((char *zip, char *file, UzpOpts *optflgs,
+ UzpCB *UsrFunc, UzpBuffer *retstr));
+int UZ_EXP UzpGrep OF((char *archive, char *file,
+ char *pattern, int cmd, int SkipBin,
+ UzpCB *UsrFunc));
+#endif
+#ifdef OS2
+int UZ_EXP UzpFileTree OF((char *name, cbList(callBack),
+ char *cpInclude[], char *cpExclude[]));
+#endif
+
+void UZ_EXP UzpVersion2 OF((UzpVer2 *version));
+int UZ_EXP UzpValidate OF((char *archive, int AllCodes));
+
+
+/* default I/O functions (can be swapped out via UzpAltMain() entry point): */
+
+int UZ_EXP UzpMessagePrnt OF((zvoid *pG, uch *buf, ulg size, int flag));
+int UZ_EXP UzpMessageNull OF((zvoid *pG, uch *buf, ulg size, int flag));
+int UZ_EXP UzpInput OF((zvoid *pG, uch *buf, int *size, int flag));
+void UZ_EXP UzpMorePause OF((zvoid *pG, ZCONST char *prompt, int flag));
+int UZ_EXP UzpPassword OF((zvoid *pG, int *rcnt, char *pwbuf,
+ int size, ZCONST char *zfn,
+ ZCONST char *efn));
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*---------------------------------------------------------------------------
+ Remaining private stuff for UnZip compilation.
+ ---------------------------------------------------------------------------*/
+
+#ifdef UNZIP_INTERNAL
+# include "unzpriv.h"
+#endif
+
+
+#endif /* !__unzip_h */
Property changes on: trunk/build/install/installer/unzip.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/unzpriv.h
===================================================================
--- trunk/build/install/installer/unzpriv.h (rev 0)
+++ trunk/build/install/installer/unzpriv.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,2618 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ unzpriv.h
+
+ This header file contains private (internal) macros, typedefs, prototypes
+ and global-variable declarations used by all of the UnZip source files.
+ In a prior life it was part of the main unzip.h header, but now it is only
+ included by that header if UNZIP_INTERNAL is defined.
+
+ ---------------------------------------------------------------------------*/
+
+
+
+#ifndef __unzpriv_h /* prevent multiple inclusions */
+#define __unzpriv_h
+
+/* First thing: Signal all following code that we compile UnZip utilities! */
+#ifndef UNZIP
+# define UNZIP
+#endif
+
+/* GRR 960204: MORE defined here in preparation for removal altogether */
+#ifndef MORE
+# ifndef RISCOS
+# define MORE
+# endif
+#endif
+
+/* fUnZip should never need to be reentrant */
+#ifdef FUNZIP
+# ifdef REENTRANT
+# undef REENTRANT
+# endif
+# ifdef DLL
+# undef DLL
+# endif
+# ifdef SFX /* fUnZip is NOT the sfx stub! */
+# undef SFX
+# endif
+#endif
+
+#if (defined(USE_ZLIB) && !defined(NO_DEFLATE64))
+ /* zlib does not (yet?) provide Deflate64(tm) support */
+# define NO_DEFLATE64
+#endif
+
+#ifdef NO_DEFLATE64
+ /* disable support for Deflate64(tm) */
+# ifdef USE_DEFLATE64
+# undef USE_DEFLATE64
+# endif
+#else
+ /* enable Deflate64(tm) support unless compiling for SFX stub */
+# if (!defined(USE_DEFLATE64) && !defined(SFX))
+# define USE_DEFLATE64
+# endif
+#endif
+
+#if (defined(NO_VMS_TEXT_CONV) || defined(VMS))
+# ifdef VMS_TEXT_CONV
+# undef VMS_TEXT_CONV
+# endif
+#else
+# if (!defined(VMS_TEXT_CONV) && !defined(SFX))
+# define VMS_TEXT_CONV
+# endif
+#endif
+
+#if (defined(DLL) && !defined(REENTRANT))
+# define REENTRANT
+#endif
+
+#if (!defined(DYNAMIC_CRC_TABLE) && !defined(FUNZIP))
+# define DYNAMIC_CRC_TABLE
+#endif
+
+#if (defined(DYNAMIC_CRC_TABLE) && !defined(REENTRANT))
+# ifndef DYNALLOC_CRCTAB
+# define DYNALLOC_CRCTAB
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ OS-dependent configuration for UnZip internals
+ ---------------------------------------------------------------------------*/
+
+/* Some compiler distributions for Win32/i386 systems try to emulate
+ * a Unix (POSIX-compatible) environment.
+ */
+#if (defined(WIN32) && defined(UNIX))
+ /* UnZip does not support merging both ports in a single executable. */
+# if (defined(FORCE_WIN32_OVER_UNIX) && defined(FORCE_UNIX_OVER_WIN32))
+ /* conflicting choice requests -> we prefer the Win32 environment */
+# undef FORCE_UNIX_OVER_WIN32
+# endif
+# ifdef FORCE_WIN32_OVER_UNIX
+ /* native Win32 support was explicitely requested... */
+# undef UNIX
+# else
+ /* use the POSIX (Unix) emulation features by default... */
+# undef WIN32
+# endif
+#endif
+
+/* bad or (occasionally?) missing stddef.h: */
+#if (defined(M_XENIX) || defined(DNIX))
+# define NO_STDDEF_H
+#endif
+
+#if (defined(M_XENIX) && !defined(M_UNIX)) /* SCO Xenix only, not SCO Unix */
+# define SCO_XENIX
+# define NO_LIMITS_H /* no limits.h, but MODERN defined */
+# define NO_UID_GID /* no uid_t/gid_t */
+# define size_t int
+#endif
+
+#ifdef realix /* Modcomp Real/IX, real-time SysV.3 variant */
+# define SYSV
+# define NO_UID_GID /* no uid_t/gid_t */
+#endif
+
+#if (defined(_AIX) && !defined(_ALL_SOURCE))
+# define _ALL_SOURCE
+#endif
+
+#if defined(apollo) /* defines __STDC__ */
+# define NO_STDLIB_H
+#endif
+
+#ifdef DNIX
+# define SYSV
+# define SHORT_NAMES /* 14-char limitation on path components */
+/* # define FILENAME_MAX 14 */
+# define FILENAME_MAX NAME_MAX /* GRR: experiment */
+#endif
+
+#if (defined(SYSTEM_FIVE) || defined(__SYSTEM_FIVE))
+# ifndef SYSV
+# define SYSV
+# endif
+#endif /* SYSTEM_FIVE || __SYSTEM_FIVE */
+#if (defined(M_SYSV) || defined(M_SYS5))
+# ifndef SYSV
+# define SYSV
+# endif
+#endif /* M_SYSV || M_SYS5 */
+/* __SVR4 and __svr4__ catch Solaris on at least some combos of compiler+OS */
+#if (defined(__SVR4) || defined(__svr4__) || defined(sgi) || defined(__hpux))
+# ifndef SYSV
+# define SYSV
+# endif
+#endif /* __SVR4 || __svr4__ || sgi || __hpux */
+#if (defined(LINUX) || defined(__QNX__))
+# ifndef SYSV
+# define SYSV
+# endif
+#endif /* LINUX || __QNX__ */
+
+#if (defined(ultrix) || defined(__ultrix) || defined(bsd4_2))
+# if (!defined(BSD) && !defined(SYSV))
+# define BSD
+# endif
+#endif /* ultrix || __ultrix || bsd4_2 */
+#if (defined(sun) || defined(pyr) || defined(CONVEX))
+# if (!defined(BSD) && !defined(SYSV))
+# define BSD
+# endif
+#endif /* sun || pyr || CONVEX */
+
+#ifdef pyr /* Pyramid: has BSD and AT&T "universes" */
+# ifdef BSD
+# define pyr_bsd
+# define USE_STRINGS_H /* instead of more common string.h */
+# define ZMEM /* ZMEM now uses bcopy/bzero: not in AT&T universe */
+# endif /* (AT&T memcpy claimed to be very slow, though) */
+# define DECLARE_ERRNO
+#endif /* pyr */
+
+/* stat() bug for Borland, VAX C RTL, and Atari ST MiNT on TOS
+ * filesystems: returns 0 for wildcards! (returns 0xffffffff on Minix
+ * filesystem or `U:' drive under Atari MiNT.) Watcom C was previously
+ * included on this list; it would be good to know what version the problem
+ * was fixed at, if it did exist. */
+#if (defined(__TURBOC__) && !defined(WIN32))
+/*# define WILD_STAT_BUG*/
+#endif
+#if (defined(VMS) || defined(__MINT__))
+# define WILD_STAT_BUG
+#endif
+
+/*---------------------------------------------------------------------------
+ OS-dependent includes
+ ---------------------------------------------------------------------------*/
+
+#ifdef EFT
+# define Z_OFF_T off_t /* Amdahl UTS nonsense ("extended file types") */
+#else
+#if (defined(UNIX) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64))
+# define Z_OFF_T off_t /* 64bit offsets to support 2GB < zipfile size < 4GB */
+#else
+# define Z_OFF_T long
+#endif
+#endif
+
+#ifdef MODERN
+# ifndef NO_STDDEF_H
+# include <stddef.h>
+# endif
+# ifndef NO_STDLIB_H
+# include <stdlib.h> /* standard library prototypes, malloc(), etc. */
+# endif
+ typedef size_t extent;
+#else /* !MODERN */
+# ifndef AOS_VS /* mostly modern? */
+ Z_OFF_T lseek();
+# ifdef VAXC /* not fully modern, but has stdlib.h and void */
+# include <stdlib.h>
+# else
+ char *malloc();
+# endif /* ?VAXC */
+# endif /* !AOS_VS */
+ typedef unsigned int extent;
+#endif /* ?MODERN */
+
+
+#ifndef MINIX /* Minix needs it after all the other includes (?) */
+# include <stdio.h>
+#endif
+#include <ctype.h> /* skip for VMS, to use tolower() function? */
+#include <errno.h> /* used in mapname() */
+#ifdef USE_STRINGS_H
+# include <strings.h> /* strcpy, strcmp, memcpy, index/rindex, etc. */
+#else
+# include <string.h> /* strcpy, strcmp, memcpy, strchr/strrchr, etc. */
+#endif
+#if (defined(MODERN) && !defined(NO_LIMITS_H))
+# include <limits.h> /* GRR: EXPERIMENTAL! (can be deleted) */
+#endif
+
+/* this include must be down here for SysV.4, for some reason... */
+#include <signal.h> /* used in unzip.c, fileio.c */
+
+
+/*---------------------------------------------------------------------------
+ API (DLL) section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef DLL
+# define MAIN UZ_EXP UzpMain /* was UzpUnzip */
+# ifdef OS2DLL
+# undef Info
+# define REDIRECTC(c) varputchar(__G__ c)
+# define REDIRECTPRINT(buf,size) varmessage(__G__ buf, size)
+# define FINISH_REDIRECT() finish_REXX_redirect(__G)
+# else
+# define REDIRECTC(c)
+# define REDIRECTPRINT(buf,size) 0
+# define FINISH_REDIRECT() close_redirect(__G)
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Acorn RISCOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef RISCOS
+# include "acorn/riscos.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ Amiga section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef AMIGA
+# include "amiga/amiga.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ AOS/VS section (somewhat similar to Unix, apparently):
+ ---------------------------------------------------------------------------*/
+
+#ifdef AOS_VS
+# ifdef __FILEIO_C
+# include "aosvs/aosvs.h"
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Atari ST section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef ATARI
+# include <time.h>
+# include <stat.h>
+# include <fcntl.h>
+# include <limits.h>
+# define SYMLINKS
+# define EXE_EXTENSION ".tos"
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_DMY
+# endif
+# define DIR_END '/'
+# define INT_SPRINTF
+# define timezone _timezone
+# define lenEOL 2
+# define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
+# undef SHORT_NAMES
+# if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
+# define TIMESTAMP
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ AtheOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef __ATHEOS__
+# include "atheos/athcfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ BeOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef __BEOS__
+# include "beos/beocfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ Human68k/X680x0 section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef __human68k__
+ /* DO NOT DEFINE DOS_OS2 HERE! If Human68k is so much */
+ /* like MS-DOS and/or OS/2, create DOS_H68_OS2 macro. */
+# ifndef _MBCS
+# define _MBCS
+# endif
+# include <time.h>
+# include <fcntl.h>
+# include <io.h>
+# include <conio.h>
+# include <sys/stat.h>
+# ifdef HAVE_MBSTRING_H
+# include <mbstring.h>
+# endif
+# ifdef HAVE_MBCTYPE_H
+# include <mbctype.h>
+# else
+# ifndef _ismbblead
+# define _ismbblead(c) (0x80 <= (c) && ((c) < 0xa0 || 0xe0 <= (c)))
+# endif
+# endif
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_YMD /* Japanese standard */
+# endif
+# define lenEOL 1
+# define PutNativeEOL *q++ = native(LF);
+# define INT_SPRINTF
+# define SYMLINKS
+# ifdef SFX
+# define MAIN main_sfx
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Mac section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef MACOS
+# include "maccfg.h"
+#endif /* MACOS */
+
+/*---------------------------------------------------------------------------
+ MS-DOS, OS/2, FLEXOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef WINDLL
+# ifdef MORE
+# undef MORE
+# endif
+# ifdef OS2_EAS
+# undef OS2_EAS
+# endif
+#endif
+
+#if (defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)))
+# ifndef MSC
+# define MSC /* This should work for older MSC, too! */
+# endif
+#endif
+
+#if (defined(MSDOS) || defined(OS2) || defined(FLEXOS))
+# include <sys/types.h> /* off_t, time_t, dev_t, ... */
+# include <sys/stat.h>
+# include <io.h> /* lseek(), open(), setftime(), dup(), creat() */
+# include <time.h> /* localtime() */
+# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */
+
+# ifdef OS2 /* defined for all OS/2 compilers */
+# include "os2/os2cfg.h"
+# else
+# ifdef FLEXOS
+# include "flexos/flxcfg.h"
+# else
+# include "msdos/doscfg.h"
+# endif
+# endif
+
+# if (defined(_MSC_VER) && (_MSC_VER == 700) && !defined(GRR))
+ /*
+ * ARGH. MSC 7.0 libraries think times are based on 1899 Dec 31 00:00, not
+ * 1970 Jan 1 00:00. So we have to diddle time_t's appropriately: add or
+ * subtract 70 years' worth of seconds; i.e., number of days times 86400;
+ * i.e., (70*365 regular days + 17 leap days + 1 1899 day) * 86400 ==
+ * (25550 + 17 + 1) * 86400 == 2209075200 seconds. We know time_t is an
+ * unsigned long (ulg) on the only system with this bug.
+ */
+# define TIMET_TO_NATIVE(x) (x) += (ulg)2209075200L;
+# define NATIVE_TO_TIMET(x) (x) -= (ulg)2209075200L;
+# endif
+# if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0450))
+# define timezone _timezone
+# endif
+# if (defined(__GO32__) || defined(FLEXOS))
+# define DIR_END '/'
+# else
+# define DIR_END '\\' /* OS uses '\\' as directory separator */
+# define DIR_END2 '/' /* also check for '/' (RTL may convert) */
+# endif
+# ifdef DATE_FORMAT
+# undef DATE_FORMAT
+# endif
+# define DATE_FORMAT dateformat()
+# define lenEOL 2
+# define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
+# if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME))
+# define USE_EF_UT_TIME
+# endif
+#endif /* MSDOS || OS2 || FLEXOS */
+
+/*---------------------------------------------------------------------------
+ MTS section (piggybacks UNIX, I think):
+ ---------------------------------------------------------------------------*/
+
+#ifdef MTS
+# include <sys/types.h> /* off_t, time_t, dev_t, ... */
+# include <sys/stat.h>
+# include <sys/file.h> /* MTS uses this instead of fcntl.h */
+# include <timeb.h>
+# include <time.h>
+# include <unix.h> /* some important non-ANSI routines */
+# define mkdir(s,n) (-1) /* no "make directory" capability */
+# define EBCDIC /* set EBCDIC conversion on */
+# define NO_STRNICMP /* unzip's is as good the one in MTS */
+# define USE_FWRITE
+# define close_outfile() fclose(G.outfile) /* can't set time on files */
+# define umask(n) /* don't have umask() on MTS */
+# define FOPWT "w" /* open file for writing in TEXT mode */
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY
+# endif
+# define lenEOL 1
+# define PutNativeEOL *q++ = native(LF);
+#endif /* MTS */
+
+ /*---------------------------------------------------------------------------
+ Novell NLM section
+ ---------------------------------------------------------------------------*/
+
+#ifdef NLM
+# include "novell/nlmcfg.h"
+#endif
+
+ /*---------------------------------------------------------------------------
+ QDOS section
+ ---------------------------------------------------------------------------*/
+
+#ifdef QDOS
+# define DIRENT
+# include <fcntl.h>
+# include <unistd.h>
+# include <sys/stat.h>
+# include <time.h>
+# include "qdos/izqdos.h"
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY
+# endif
+# define lenEOL 1
+# define PutNativeEOL *q++ = native(LF);
+# define DIR_END '_'
+# define RETURN QReturn
+# undef PATH_MAX
+# define PATH_MAX 36
+# if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
+# define TIMESTAMP
+# endif
+# define SCREENSIZE(ttrows, ttcols) screensize(ttrows, ttcols)
+# define SCREENWIDTH 80
+#endif
+
+/*---------------------------------------------------------------------------
+ Tandem NSK section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef TANDEM
+# include "tandem.h"
+# include <fcntl.h>
+# ifndef __INT32
+ /* We are compiling with non-WIDE memory model, int = 16 bits */
+# ifndef INT_16BIT
+# define INT_16BIT /* report "int" size is 16-bit to inflate setup */
+# endif
+# ifdef USE_DEFLATE64
+ /* Following required for 64k WSIZE of Deflate64 support */
+# define MED_MEM /* else OUTBUFSIZ is 64K and fails in do_string */
+# define INBUFSIZ 8192 /* but larger buffer for real OSes */
+# endif
+# endif
+ /* use a single LF delimiter so that writes to 101 text files work */
+# define PutNativeEOL *q++ = native(LF);
+# define lenEOL 1
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_DMY
+# endif
+# define SCREENLINES 25
+ /* USE_EF_UT_TIME is set in tandem.h */
+# define RESTORE_UIDGID
+# define NO_STRNICMP
+#endif
+
+/*---------------------------------------------------------------------------
+ THEOS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef THEOS
+# include "theos/thscfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ TOPS-20 section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef TOPS20
+# include <sys/types.h> /* off_t, time_t, dev_t, ... */
+# include <sys/stat.h>
+# include <sys/param.h>
+# include <sys/time.h>
+# include <sys/timeb.h>
+# include <sys/file.h>
+# include <timex.h>
+# include <monsym.h> /* get amazing monsym() macro */
+ extern int open(), close(), read();
+ extern int stat(), unlink(), jsys(), fcntl();
+ extern long lseek(), dup(), creat();
+# define strchr index /* GRR: necessary? */
+# define strrchr rindex
+# define REALLY_SHORT_SYMS
+# define NO_MKDIR
+# ifndef HAVE_STRNICMP
+# define NO_STRNICMP /* probably not provided by TOPS20 C RTL */
+# endif
+# define DIR_BEG '<'
+# define DIR_END '>'
+# define DIR_EXT ".directory"
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY
+# endif
+# define EXE_EXTENSION ".exe" /* just a guess... */
+#endif /* TOPS20 */
+
+/*---------------------------------------------------------------------------
+ Unix section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef UNIX
+# include "unix/unxcfg.h"
+#endif /* UNIX */
+
+/*---------------------------------------------------------------------------
+ VM/CMS and MVS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef CMS_MVS
+# include "vmmvs.h"
+# define CLOSE_INFILE() close_infile(__G)
+#endif
+
+/*---------------------------------------------------------------------------
+ VMS section:
+ ---------------------------------------------------------------------------*/
+
+#ifdef VMS
+# include <types.h> /* GRR: experimenting... */
+# include <stat.h>
+# include <time.h> /* the usual non-BSD time functions */
+# include <file.h> /* same things as fcntl.h has */
+# include <unixio.h>
+# include <rms.h>
+# define _MAX_PATH (NAM$C_MAXRSS+1) /* to define FILNAMSIZ below */
+# ifndef HAVE_STRNICMP /* use our private zstrnicmp() */
+# define NO_STRNICMP /* unless explicitely overridden */
+# endif
+# ifdef RETURN_CODES /* VMS interprets standard PK return codes incorrectly */
+# define RETURN(ret) return_VMS(__G__ (ret)) /* verbose version */
+# define EXIT(ret) return_VMS(__G__ (ret))
+# else
+# define RETURN return_VMS /* quiet version */
+# define EXIT return_VMS
+# endif
+# ifdef VMSCLI
+# define USAGE(ret) VMSCLI_usage(__G__ (ret))
+# endif
+# define DIR_BEG '['
+# define DIR_END ']'
+# define DIR_EXT ".dir"
+# ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY
+# endif
+# define lenEOL 1
+# define PutNativeEOL *q++ = native(LF);
+# define SCREENSIZE(ttrows, ttcols) screensize(ttrows, ttcols)
+# define SCREENWIDTH 80
+# define SCREENLWRAP screenlinewrap()
+# if (defined(__VMS_VERSION) && !defined(VMS_VERSION))
+# define VMS_VERSION __VMS_VERSION
+# endif
+# if (defined(__VMS_VER) && !defined(__CRTL_VER))
+# define __CRTL_VER __VMS_VER
+# endif
+# if ((!defined(__CRTL_VER)) || (__CRTL_VER < 70000000))
+# define NO_GMTIME /* gmtime() of earlier VMS C RTLs is broken */
+# else
+# if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME))
+# define USE_EF_UT_TIME
+# endif
+# endif
+# if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
+# define TIMESTAMP
+# endif
+# define RESTORE_UIDGID
+# ifdef __DECC
+ /* File open callback ID values. */
+# define OPENR_ID 1
+ /* File open callback ID storage. */
+ extern int openr_id;
+ /* File open callback function. */
+ extern int acc_cb();
+ /* Option macros for open().
+ * General: Stream access
+ *
+ * Callback function (DEC C only) sets deq, mbc, mbf, rah, wbh, ...
+ */
+# define OPNZIP_RMS_ARGS "ctx=stm", "acc", acc_cb, &openr_id
+# else /* !__DECC */ /* (So, GNU C, VAX C, ...)*/
+# define OPNZIP_RMS_ARGS "ctx=stm"
+# endif /* ?__DECC */
+#endif /* VMS */
+
+/*---------------------------------------------------------------------------
+ Win32 (Windows 95/NT) section:
+ ---------------------------------------------------------------------------*/
+
+#if (defined(WIN32) && !defined(POCKET_UNZIP) && !defined(_WIN32_WCE))
+# include "win32/w32cfg.h"
+#endif
+
+/*---------------------------------------------------------------------------
+ Win32 Windows CE section (when not using POCKET_UNZIP)
+ ---------------------------------------------------------------------------*/
+
+#if (defined(_WIN32_WCE) || defined(POCKET_UNZIP))
+# include "wince/wcecfg.h"
+#endif
+
+
+
+
+
+/*************/
+/* Defines */
+/*************/
+
+#ifdef USE_DEFLATE64
+# define UNZIP_VERSION 21 /* compatible with PKUNZIP 4.0 */
+#else
+# define UNZIP_VERSION 20 /* compatible with PKUNZIP 2.0 */
+#endif
+#define VMS_UNZIP_VERSION 42 /* if OS-needed-to-extract is VMS: can do */
+
+#if (defined(MSDOS) || defined(OS2))
+# define DOS_OS2
+#endif
+
+#if (defined(OS2) || defined(WIN32))
+# define OS2_W32
+#endif
+
+#if (defined(DOS_OS2) || defined(WIN32))
+# define DOS_OS2_W32
+# define DOS_W32_OS2 /* historical: don't use */
+#endif
+
+#if (defined(DOS_OS2_W32) || defined(__human68k__))
+# define DOS_H68_OS2_W32
+#endif
+
+#if (defined(DOS_OS2) || defined(FLEXOS))
+# define DOS_FLX_OS2
+#endif
+
+#if (defined(DOS_OS2_W32) || defined(FLEXOS))
+# define DOS_FLX_OS2_W32
+#endif
+
+#if (defined(DOS_H68_OS2_W32) || defined(FLEXOS))
+# define DOS_FLX_H68_OS2_W32
+#endif
+
+#if (defined(DOS_FLX_OS2) || defined(NLM))
+# define DOS_FLX_NLM_OS2
+#endif
+
+#if (defined(DOS_FLX_OS2_W32) || defined(NLM))
+# define DOS_FLX_NLM_OS2_W32
+#endif
+
+#if (defined(DOS_FLX_H68_OS2_W32) || defined(NLM))
+# define DOS_FLX_H68_NLM_OS2_W32
+#endif
+
+#if (defined(TOPS20) || defined(VMS))
+# define T20_VMS
+#endif
+
+#if (defined(MSDOS) || defined(T20_VMS))
+# define DOS_T20_VMS
+#endif
+
+#if (defined(__ATHEOS__) || defined(__BEOS__))
+# define ATH_BEO
+#endif
+
+#if (defined(ATH_BEO) || defined(UNIX))
+# define ATH_BEO_UNX
+#endif
+
+#if (defined(ATH_BEO_UNX) || defined(THEOS))
+# define ATH_BEO_THS_UNX
+#endif
+
+/* clean up with a few defaults */
+#ifndef DIR_END
+# define DIR_END '/' /* last char before program name or filename */
+#endif
+#ifndef DATE_FORMAT
+# define DATE_FORMAT DF_MDY /* defaults to US convention */
+#endif
+#ifndef DATE_SEPCHAR
+# define DATE_SEPCHAR '-'
+#endif
+#ifndef CLOSE_INFILE
+# define CLOSE_INFILE() close(G.zipfd)
+#endif
+#ifndef RETURN
+# define RETURN return /* only used in main() */
+#endif
+#ifndef EXIT
+# define EXIT exit
+#endif
+#ifndef USAGE
+# define USAGE(ret) usage(__G__ (ret)) /* used in unzip.c, zipinfo.c */
+#endif
+#ifndef TIMET_TO_NATIVE /* everybody but MSC 7.0 and Macintosh */
+# define TIMET_TO_NATIVE(x)
+# define NATIVE_TO_TIMET(x)
+#endif
+#ifndef SSTAT
+# ifdef WILD_STAT_BUG
+# define SSTAT(path,pbuf) (iswild(path) || stat(path,pbuf))
+# else
+# define SSTAT stat
+# endif
+#endif
+#ifndef STRNICMP
+# ifdef NO_STRNICMP
+# define STRNICMP zstrnicmp
+# else
+# define STRNICMP strnicmp
+# endif
+#endif
+
+
+#if (defined(DOS_FLX_NLM_OS2_W32) || defined(ATH_BEO_UNX) || defined(RISCOS))
+# ifndef HAVE_UNLINK
+# define HAVE_UNLINK
+# endif
+#endif
+#if (defined(AOS_VS) || defined(ATARI)) /* GRR: others? */
+# ifndef HAVE_UNLINK
+# define HAVE_UNLINK
+# endif
+#endif
+
+/* OS-specific exceptions to the "ANSI <--> INT_SPRINTF" rule */
+
+#if (!defined(PCHAR_SPRINTF) && !defined(INT_SPRINTF))
+# if (defined(SYSV) || defined(CONVEX) || defined(NeXT) || defined(BSD4_4))
+# define INT_SPRINTF /* sprintf() returns int: SysVish/Posix */
+# endif
+# if (defined(DOS_FLX_NLM_OS2_W32) || defined(VMS) || defined(AMIGA))
+# define INT_SPRINTF /* sprintf() returns int: ANSI */
+# endif
+# if (defined(ultrix) || defined(__ultrix)) /* Ultrix 4.3 and newer */
+# if (defined(POSIX) || defined(__POSIX))
+# define INT_SPRINTF /* sprintf() returns int: ANSI/Posix */
+# endif
+# ifdef __GNUC__
+# define PCHAR_SPRINTF /* undetermined actual return value */
+# endif
+# endif
+# if (defined(__osf__) || defined(_AIX) || defined(CMS_MVS) || defined(THEOS))
+# define INT_SPRINTF /* sprintf() returns int: ANSI/Posix */
+# endif
+# if defined(sun)
+# define PCHAR_SPRINTF /* sprintf() returns char *: SunOS cc *and* gcc */
+# endif
+#endif
+
+/* defaults that we hope will take care of most machines in the future */
+
+#if (!defined(PCHAR_SPRINTF) && !defined(INT_SPRINTF))
+# ifdef __STDC__
+# define INT_SPRINTF /* sprintf() returns int: ANSI */
+# endif
+# ifndef INT_SPRINTF
+# define PCHAR_SPRINTF /* sprintf() returns char *: BSDish */
+# endif
+#endif
+
+#define MSG_STDERR(f) (f & 1) /* bit 0: 0 = stdout, 1 = stderr */
+#define MSG_INFO(f) ((f & 6) == 0) /* bits 1 and 2: 0 = info */
+#define MSG_WARN(f) ((f & 6) == 2) /* bits 1 and 2: 1 = warning */
+#define MSG_ERROR(f) ((f & 6) == 4) /* bits 1 and 2: 2 = error */
+#define MSG_FATAL(f) ((f & 6) == 6) /* bits 1 and 2: (3 = fatal error) */
+#define MSG_ZFN(f) (f & 0x0008) /* bit 3: 1 = print zipfile name */
+#define MSG_FN(f) (f & 0x0010) /* bit 4: 1 = print filename */
+#define MSG_LNEWLN(f) (f & 0x0020) /* bit 5: 1 = leading newline if !SOL */
+#define MSG_TNEWLN(f) (f & 0x0040) /* bit 6: 1 = trailing newline if !SOL */
+#define MSG_MNEWLN(f) (f & 0x0080) /* bit 7: 1 = trailing NL for prompts */
+/* the following are subject to change */
+#define MSG_NO_WGUI(f) (f & 0x0100) /* bit 8: 1 = skip if Windows GUI */
+#define MSG_NO_AGUI(f) (f & 0x0200) /* bit 9: 1 = skip if Acorn GUI */
+#define MSG_NO_DLL2(f) (f & 0x0400) /* bit 10: 1 = skip if OS/2 DLL */
+#define MSG_NO_NDLL(f) (f & 0x0800) /* bit 11: 1 = skip if WIN32 DLL */
+#define MSG_NO_WDLL(f) (f & 0x1000) /* bit 12: 1 = skip if Windows DLL */
+
+#if (defined(MORE) && !defined(SCREENLINES))
+# ifdef DOS_FLX_NLM_OS2_W32
+# define SCREENLINES 25 /* can be (should be) a function instead */
+# else
+# define SCREENLINES 24 /* VT-100s are assumed to be minimal hardware */
+# endif
+#endif
+#if (defined(MORE) && !defined(SCREENSIZE))
+# ifndef SCREENWIDTH
+# define SCREENSIZE(scrrows, scrcols) { \
+ if ((scrrows) != NULL) *(scrrows) = SCREENLINES; }
+# else
+# define SCREENSIZE(scrrows, scrcols) { \
+ if ((scrrows) != NULL) *(scrrows) = SCREENLINES; \
+ if ((scrcols) != NULL) *(scrcols) = SCREENWIDTH; }
+# endif
+#endif
+
+#define DIR_BLKSIZ 64 /* number of directory entries per block
+ * (should fit in 4096 bytes, usually) */
+#ifndef WSIZE
+# ifdef USE_DEFLATE64
+# define WSIZE 65536L /* window size--must be a power of two, and */
+# else /* at least 64K for PKZip's deflate64 method */
+# define WSIZE 0x8000 /* window size--must be a power of two, and */
+# endif /* at least 32K for zip's deflate method */
+#endif
+
+#ifdef __16BIT__
+# ifndef INT_16BIT
+# define INT_16BIT /* on 16-bit systems int size is 16 bits */
+# endif
+#else
+# define nearmalloc malloc
+# define nearfree free
+# if (!defined(__IBMC__) || !defined(OS2))
+# ifndef near
+# define near
+# endif
+# ifndef far
+# define far
+# endif
+# endif
+#endif
+
+#if (defined(DYNALLOC_CRCTAB) && !defined(DYNAMIC_CRC_TABLE))
+# undef DYNALLOC_CRCTAB
+#endif
+
+#if (defined(DYNALLOC_CRCTAB) && defined(REENTRANT))
+# undef DYNALLOC_CRCTAB /* not safe with reentrant code */
+#endif
+
+#if (defined(USE_ZLIB) && !defined(USE_OWN_CRCTAB))
+# ifdef DYNALLOC_CRCTAB
+# undef DYNALLOC_CRCTAB
+# endif
+#endif
+
+#if (defined(USE_ZLIB) && defined(ASM_CRC))
+# undef ASM_CRC
+#endif
+
+#ifndef INBUFSIZ
+# if (defined(MED_MEM) || defined(SMALL_MEM))
+# define INBUFSIZ 2048 /* works for MS-DOS small model */
+# else
+# define INBUFSIZ 8192 /* larger buffers for real OSes */
+# endif
+#endif
+
+#if (defined(INT_16BIT) && (defined(USE_DEFLATE64) || lenEOL > 1))
+ /* For environments using 16-bit integers OUTBUFSIZ must be limited to
+ * less than 64k (do_string() uses "unsigned" in calculations involving
+ * OUTBUFSIZ). This is achieved by defining MED_MEM when WSIZE = 64k (aka
+ * Deflate64 support enabled) or EOL markers consist multiple characters.
+ * (The rule gets applied AFTER the default rule for INBUFSIZ because it
+ * is not neccessary to reduce INBUFSIZE in this case.)
+ */
+# if (!defined(SMALL_MEM) && !defined(MED_MEM))
+# define MED_MEM
+# endif
+#endif
+
+/* Logic for case of small memory, length of EOL > 1: if OUTBUFSIZ == 2048,
+ * OUTBUFSIZ>>1 == 1024 and OUTBUFSIZ>>7 == 16; therefore rawbuf is 1008 bytes
+ * and transbuf 1040 bytes. Have room for 32 extra EOL chars; 1008/32 == 31.5
+ * chars/line, smaller than estimated 35-70 characters per line for C source
+ * and normal text. Hence difference is sufficient for most "average" files.
+ * (Argument scales for larger OUTBUFSIZ.)
+ */
+#ifdef SMALL_MEM /* i.e., 16-bit OSes: MS-DOS, OS/2 1.x, etc. */
+# define LoadFarString(x) fLoadFarString(__G__ (x))
+# define LoadFarStringSmall(x) fLoadFarStringSmall(__G__ (x))
+# define LoadFarStringSmall2(x) fLoadFarStringSmall2(__G__ (x))
+# if (defined(_MSC_VER) && (_MSC_VER >= 600))
+# define zfstrcpy(dest, src) _fstrcpy((dest), (src))
+# define zfstrcmp(s1, s2) _fstrcmp((s1), (s2))
+# endif
+# if !(defined(SFX) || defined(FUNZIP))
+# if (defined(_MSC_VER))
+# define zfmalloc(sz) _fmalloc((sz))
+# define zffree(x) _ffree(x)
+# endif
+# if (defined(__TURBOC__))
+# include <alloc.h>
+# define zfmalloc(sz) farmalloc((unsigned long)(sz))
+# define zffree(x) farfree(x)
+# endif
+# endif /* !(SFX || FUNZIP) */
+# ifndef Far
+# define Far far /* __far only works for MSC 6.00, not 6.0a or Borland */
+# endif
+# define OUTBUFSIZ INBUFSIZ
+# if (lenEOL == 1)
+# define RAWBUFSIZ (OUTBUFSIZ>>1)
+# else
+# define RAWBUFSIZ ((OUTBUFSIZ>>1) - (OUTBUFSIZ>>7))
+# endif
+# define TRANSBUFSIZ (OUTBUFSIZ-RAWBUFSIZ)
+ typedef short shrint; /* short/int or "shrink int" (unshrink) */
+#else
+# define zfstrcpy(dest, src) strcpy((dest), (src))
+# define zfstrcmp(s1, s2) strcmp((s1), (s2))
+# define zfmalloc malloc
+# define zffree(x) free(x)
+# ifdef QDOS
+# define LoadFarString(x) Qstrfix(x) /* fix up _ for '.' */
+# define LoadFarStringSmall(x) Qstrfix(x)
+# define LoadFarStringSmall2(x) Qstrfix(x)
+# else
+# define LoadFarString(x) (char *)(x)
+# define LoadFarStringSmall(x) (char *)(x)
+# define LoadFarStringSmall2(x) (char *)(x)
+# endif
+# ifdef MED_MEM
+# define OUTBUFSIZ 0xFF80 /* can't malloc arrays of 0xFFE8 or more */
+# define TRANSBUFSIZ 0xFF80
+ typedef short shrint;
+# else
+# define OUTBUFSIZ (lenEOL*WSIZE) /* more efficient text conversion */
+# define TRANSBUFSIZ (lenEOL*OUTBUFSIZ)
+# ifdef AMIGA
+ typedef short shrint;
+# else
+ typedef int shrint; /* for efficiency/speed, we hope... */
+# endif
+# endif /* ?MED_MEM */
+# define RAWBUFSIZ OUTBUFSIZ
+#endif /* ?SMALL_MEM */
+
+#ifndef Far
+# define Far
+#endif
+
+#ifndef Cdecl
+# define Cdecl
+#endif
+
+#ifndef MAIN
+# define MAIN main
+#endif
+
+#ifdef SFX /* disable some unused features for SFX executables */
+# ifndef NO_ZIPINFO
+# define NO_ZIPINFO
+# endif
+# ifdef TIMESTAMP
+# undef TIMESTAMP
+# endif
+#endif
+
+#ifdef SFX
+# ifdef CHEAP_SFX_AUTORUN
+# ifndef NO_SFX_EXDIR
+# define NO_SFX_EXDIR
+# endif
+# endif
+# ifndef NO_SFX_EXDIR
+# ifndef SFX_EXDIR
+# define SFX_EXDIR
+# endif
+# else
+# ifdef SFX_EXDIR
+# undef SFX_EXDIR
+# endif
+# endif
+#endif
+
+/* user may have defined both by accident... NOTIMESTAMP takes precedence */
+#if (defined(TIMESTAMP) && defined(NOTIMESTAMP))
+# undef TIMESTAMP
+#endif
+
+#if (!defined(COPYRIGHT_CLEAN) && !defined(USE_SMITH_CODE))
+# define COPYRIGHT_CLEAN
+#endif
+
+/* The LZW patent is expired worldwide since 2004-Jul-07, so USE_UNSHRINK
+ * is now enabled by default. See unshrink.c.
+ */
+#if (!defined(LZW_CLEAN) && !defined(USE_UNSHRINK))
+# define USE_UNSHRINK
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+#ifndef PIPE_ERROR
+# define PIPE_ERROR (errno == EPIPE)
+#endif
+
+/* File operations--use "b" for binary if allowed or fixed length 512 on VMS */
+#ifdef VMS
+# define FOPR "r","ctx=stm"
+# define FOPM "r+","ctx=stm","rfm=fix","mrs=512"
+# define FOPW "w","ctx=stm","rfm=fix","mrs=512"
+#endif /* VMS */
+
+#ifdef CMS_MVS
+/* Binary files must be RECFM=F,LRECL=1 for ftell() to get correct pos */
+/* ...unless byteseek is used. Let's try that for a while. */
+# define FOPR "rb,byteseek"
+# define FOPM "r+b,byteseek"
+# ifdef MVS
+# define FOPW "wb,recfm=u,lrecl=32760,byteseek" /* New binary files */
+# define FOPWE "wb" /* Existing binary files */
+# define FOPWT "w,lrecl=133" /* New text files */
+# define FOPWTE "w" /* Existing text files */
+# else
+# define FOPW "wb,recfm=v,lrecl=32760"
+# define FOPWT "w"
+# endif
+#endif /* CMS_MVS */
+
+#ifdef TOPS20 /* TOPS-20 MODERN? You kidding? */
+# define FOPW "w8"
+#endif /* TOPS20 */
+
+/* Defaults when nothing special has been defined previously. */
+#ifdef MODERN
+# ifndef FOPR
+# define FOPR "rb"
+# endif
+# ifndef FOPM
+# define FOPM "r+b"
+# endif
+# ifndef FOPW
+# define FOPW "wb"
+# endif
+# ifndef FOPWT
+# define FOPWT "wt"
+# endif
+#else /* !MODERN */
+# ifndef FOPR
+# define FOPR "r"
+# endif
+# ifndef FOPM
+# define FOPM "r+"
+# endif
+# ifndef FOPW
+# define FOPW "w"
+# endif
+# ifndef FOPWT
+# define FOPWT "w"
+# endif
+#endif /* ?MODERN */
+
+/*
+ * If <limits.h> exists on most systems, should include that, since it may
+ * define some or all of the following: NAME_MAX, PATH_MAX, _POSIX_NAME_MAX,
+ * _POSIX_PATH_MAX.
+ */
+#ifdef DOS_FLX_NLM_OS2_W32
+# include <limits.h>
+#endif
+
+#ifndef PATH_MAX
+# ifdef MAXPATHLEN
+# define PATH_MAX MAXPATHLEN /* in <sys/param.h> on some systems */
+# else
+# ifdef _MAX_PATH
+# define PATH_MAX _MAX_PATH
+# else
+# if FILENAME_MAX > 255
+# define PATH_MAX FILENAME_MAX /* used like PATH_MAX on some systems */
+# else
+# define PATH_MAX 1024
+# endif
+# endif /* ?_MAX_PATH */
+# endif /* ?MAXPATHLEN */
+#endif /* !PATH_MAX */
+
+#define FILNAMSIZ PATH_MAX
+
+/* DBCS support for Info-ZIP (mainly for japanese (-: )
+ * by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y(a)is.aist-nara.ac.jp)
+ */
+#ifdef _MBCS
+# include <locale.h>
+ /* Multi Byte Character Set */
+# define ___MBS_TMP_DEF char *___tmp_ptr;
+# define ___TMP_PTR ___tmp_ptr
+# define CLEN(ptr) mblen((ZCONST char *)(ptr), MB_CUR_MAX)
+# ifndef PREINCSTR
+# define PREINCSTR(ptr) (ptr += CLEN(ptr))
+# endif
+# define POSTINCSTR(ptr) (___TMP_PTR=(char *)(ptr), PREINCSTR(ptr),___TMP_PTR)
+ char *plastchar OF((ZCONST char *ptr, extent len));
+# define lastchar(ptr, len) ((int)(unsigned)*plastchar(ptr, len))
+# ifndef MBSCHR
+# define NEED_UZMBSCHR
+# define MBSCHR(str,c) (char *)uzmbschr((ZCONST unsigned char *)(str), c)
+# endif
+# ifndef MBSRCHR
+# define NEED_UZMBSRCHR
+# define MBSRCHR(str,c) (char *)uzmbsrchr((ZCONST unsigned char *)(str), c)
+# endif
+# define SETLOCALE(category, locale) setlocale(category, locale)
+#else /* !_MBCS */
+# define ___MBS_TMP_DEF
+# define ___TMP_PTR
+# define CLEN(ptr) 1
+# define PREINCSTR(ptr) (++(ptr))
+# define POSTINCSTR(ptr) ((ptr)++)
+# define plastchar(ptr, len) (&ptr[(len)-1])
+# define lastchar(ptr, len) (ptr[(len)-1])
+# define MBSCHR(str, c) strchr(str, c)
+# define MBSRCHR(str, c) strrchr(str, c)
+# define SETLOCALE(category, locale)
+#endif /* ?_MBCS */
+#define INCSTR(ptr) PREINCSTR(ptr)
+
+
+#if (defined(MALLOC_WORK) && !defined(MY_ZCALLOC))
+ /* Any system without a special calloc function */
+# ifndef zcalloc
+# define zcalloc(items, size) \
+ (zvoid far *)calloc((unsigned)(items), (unsigned)(size))
+# endif
+# ifndef zcfree
+# define zcfree free
+# endif
+#endif /* MALLOC_WORK && !MY_ZCALLOC */
+
+#ifdef REGULUS /* returns the inode number on success(!)...argh argh argh */
+# define stat(p,s) zstat((p),(s))
+#endif
+
+#if (defined(CRAY) && defined(ZMEM))
+# undef ZMEM
+#endif
+
+#ifdef ZMEM
+# undef ZMEM
+# define memcmp(b1,b2,len) bcmp(b2,b1,len)
+# define memcpy(dest,src,len) bcopy(src,dest,len)
+# define memzero bzero
+#else
+# define memzero(dest,len) memset(dest,0,len)
+#endif
+
+#ifndef TRUE
+# define TRUE 1 /* sort of obvious */
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+# define SEEK_CUR 1
+# define SEEK_END 2
+#endif
+
+#if (!defined(S_IEXEC) && defined(S_IXUSR))
+# define S_IEXEC S_IXUSR
+#endif
+
+#if (defined(UNIX) && defined(S_IFLNK) && !defined(MTS))
+# define SYMLINKS
+# ifndef S_ISLNK
+# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# endif
+#endif /* UNIX && S_IFLNK && !MTS */
+
+#ifndef S_ISDIR
+# ifdef CMS_MVS
+# define S_ISDIR(m) (FALSE)
+# else
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+# endif
+#endif
+
+#ifndef IS_VOLID
+# define IS_VOLID(m) ((m) & 0x08)
+#endif
+
+
+#ifdef SHORT_SYMS /* Mark Williams C, ...? */
+# define extract_or_test_files xtr_or_tst_files
+# define extract_or_test_member xtr_or_tst_member
+#endif
+
+#ifdef REALLY_SHORT_SYMS /* TOPS-20 linker: first 6 chars */
+# define process_cdir_file_hdr XXpcdfh
+# define process_local_file_hdr XXplfh
+# define extract_or_test_files XXxotf /* necessary? */
+# define extract_or_test_member XXxotm /* necessary? */
+# define check_for_newer XXcfn
+# define overwrite_all XXoa
+# define process_all_files XXpaf
+# define extra_field XXef
+# define explode_lit8 XXel8
+# define explode_lit4 XXel4
+# define explode_nolit8 XXnl8
+# define explode_nolit4 XXnl4
+# define cpdist8 XXcpdist8
+# define inflate_codes XXic
+# define inflate_stored XXis
+# define inflate_fixed XXif
+# define inflate_dynamic XXid
+# define inflate_block XXib
+# define maxcodemax XXmax
+#endif
+
+#ifndef S_TIME_T_MAX /* max value of signed (>= 32-bit) time_t */
+# define S_TIME_T_MAX ((time_t)(ulg)0x7fffffffL)
+#endif
+#ifndef U_TIME_T_MAX /* max value of unsigned (>= 32-bit) time_t */
+# define U_TIME_T_MAX ((time_t)(ulg)0xffffffffL)
+#endif
+#ifdef DOSTIME_MINIMUM /* min DOSTIME value (1980-01-01) */
+# undef DOSTIME_MINIMUM
+#endif
+#define DOSTIME_MINIMUM ((ulg)0x00210000L)
+#ifdef DOSTIME_2038_01_18 /* approximate DOSTIME equivalent of */
+# undef DOSTIME_2038_01_18 /* the signed-32-bit time_t limit */
+#endif
+#define DOSTIME_2038_01_18 ((ulg)0x74320000L)
+
+#ifdef QDOS
+# define ZSUFX "_zip"
+# define ALT_ZSUFX ".zip"
+#else
+# ifdef RISCOS
+# define ZSUFX "/zip"
+# else
+# define ZSUFX ".zip"
+# endif
+# define ALT_ZSUFX ".ZIP" /* Unix-only so far (only case-sensitive fs) */
+#endif
+
+#define CENTRAL_HDR_SIG "\001\002" /* the infamous "PK" signature bytes, */
+#define LOCAL_HDR_SIG "\003\004" /* w/o "PK" (so unzip executable not */
+#define END_CENTRAL_SIG "\005\006" /* mistaken for zipfile itself) */
+#define EXTD_LOCAL_SIG "\007\010" /* [ASCII "\113" == EBCDIC "\080" ??] */
+
+/** internal-only return codes **/
+#define IZ_DIR 76 /* potential zipfile is a directory */
+/* special return codes for mapname() */
+#define MPN_OK 0 /* mapname successful */
+#define MPN_INF_TRUNC (1<<8) /* caution - filename truncated */
+#define MPN_INF_SKIP (2<<8) /* info - skipped because nothing to do */
+#define MPN_ERR_SKIP (3<<8) /* error - entry skipped */
+#define MPN_ERR_TOOLONG (4<<8) /* error - path too long */
+#define MPN_NOMEM (10<<8) /* error - out of memory, file skipped */
+#define MPN_CREATED_DIR (16<<8) /* directory created: set time & permission */
+#define MPN_VOL_LABEL (17<<8) /* volume label, but can't set on hard disk */
+#define MPN_INVALID (99<<8) /* internal logic error, should never reach */
+/* mask for internal mapname&checkdir return codes */
+#define MPN_MASK 0x7F00
+/* error code for extracting/testing extra field blocks */
+#define IZ_EF_TRUNC 79 /* local extra field truncated (PKZIP'd) */
+
+/* choice of activities for do_string() */
+#define SKIP 0 /* skip header block */
+#define DISPLAY 1 /* display archive comment (ASCII) */
+#define DISPL_8 5 /* display file comment (ext. ASCII) */
+#define DS_FN 2 /* read filename (ext. ASCII, chead) */
+#define DS_FN_C 2 /* read filename from central header */
+#define DS_FN_L 6 /* read filename from local header */
+#define EXTRA_FIELD 3 /* copy extra field into buffer */
+#define DS_EF 3
+#ifdef AMIGA
+# define FILENOTE 4 /* convert file comment to filenote */
+#endif
+#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
+# define CHECK_AUTORUN 7 /* copy command, display remainder */
+# define CHECK_AUTORUN_Q 8 /* copy command, skip remainder */
+#endif
+
+#define DOES_NOT_EXIST -1 /* return values for check_for_newer() */
+#define EXISTS_AND_OLDER 0
+#define EXISTS_AND_NEWER 1
+
+#define OVERWRT_QUERY 0 /* status values for G.overwrite_mode */
+#define OVERWRT_ALWAYS 1
+#define OVERWRT_NEVER 2
+
+#define IS_OVERWRT_ALL (G.overwrite_mode == OVERWRT_ALWAYS)
+#define IS_OVERWRT_NONE (G.overwrite_mode == OVERWRT_NEVER)
+
+#define ROOT 0 /* checkdir() extract-to path: called once */
+#define INIT 1 /* allocate buildpath: called once per member */
+#define APPEND_DIR 2 /* append a dir comp.: many times per member */
+#define APPEND_NAME 3 /* append actual filename: once per member */
+#define GETPATH 4 /* retrieve the complete path and free it */
+#define END 5 /* free root path prior to exiting program */
+
+/* version_made_by codes (central dir): make sure these */
+/* are not defined on their respective systems!! */
+#define FS_FAT_ 0 /* filesystem used by MS-DOS, OS/2, Win32 */
+#define AMIGA_ 1
+#define VMS_ 2
+#define UNIX_ 3
+#define VM_CMS_ 4
+#define ATARI_ 5 /* what if it's a minix filesystem? [cjh] */
+#define FS_HPFS_ 6 /* filesystem used by OS/2 (and NT 3.x) */
+#define MAC_ 7 /* HFS filesystem used by MacOS */
+#define Z_SYSTEM_ 8
+#define CPM_ 9
+#define TOPS20_ 10
+#define FS_NTFS_ 11 /* filesystem used by Windows NT */
+#define QDOS_ 12
+#define ACORN_ 13 /* Archimedes Acorn RISC OS */
+#define FS_VFAT_ 14 /* filesystem used by Windows 95, NT */
+#define MVS_ 15
+#define BEOS_ 16 /* hybrid POSIX/database filesystem */
+#define TANDEM_ 17 /* Tandem NSK */
+#define THEOS_ 18 /* THEOS */
+#define MAC_OSX_ 19 /* Mac OS/X (Darwin) */
+#define ATHEOS_ 30 /* AtheOS */
+#define NUM_HOSTS 31 /* index of last system + 1 */
+/* don't forget to update zipinfo.c appropiately if NUM_HOSTS changes! */
+
+#define STORED 0 /* compression methods */
+#define SHRUNK 1
+#define REDUCED1 2
+#define REDUCED2 3
+#define REDUCED3 4
+#define REDUCED4 5
+#define IMPLODED 6
+#define TOKENIZED 7
+#define DEFLATED 8
+#define ENHDEFLATED 9
+#define DCLIMPLODED 10
+#define PKRESMOD11 11
+#define BZIP2ED 12
+#define NUM_METHODS 13 /* index of last method + 1 */
+/* don't forget to update list_files(), extract.c and zipinfo.c appropriately
+ * if NUM_METHODS changes */
+
+/* (the PK-class error codes are public and have been moved into unzip.h) */
+
+#define DF_MDY 0 /* date format 10/26/91 (USA only) */
+#define DF_DMY 1 /* date format 26/10/91 (most of the world) */
+#define DF_YMD 2 /* date format 91/10/26 (a few countries) */
+
+/*---------------------------------------------------------------------------
+ Extra-field block ID values and offset info.
+ ---------------------------------------------------------------------------*/
+/* extra-field ID values, all little-endian: */
+#define EF_PKSZ64 0x0001 /* PKWARE's 64-bit filesize extensions */
+#define EF_AV 0x0007 /* PKWARE's authenticity verification */
+#define EF_OS2 0x0009 /* OS/2 extended attributes */
+#define EF_PKW32 0x000a /* PKWARE's Win95/98/WinNT filetimes */
+#define EF_PKVMS 0x000c /* PKWARE's VMS */
+#define EF_PKUNIX 0x000d /* PKWARE's Unix */
+#define EF_IZVMS 0x4d49 /* Info-ZIP's VMS ("IM") */
+#define EF_IZUNIX 0x5855 /* Info-ZIP's old Unix[1] ("UX") */
+#define EF_IZUNIX2 0x7855 /* Info-ZIP's new Unix[2] ("Ux") */
+#define EF_TIME 0x5455 /* universal timestamp ("UT") */
+#define EF_MAC3 0x334d /* Info-ZIP's new Macintosh (= "M3") */
+#define EF_JLMAC 0x07c8 /* Johnny Lee's old Macintosh (= 1992) */
+#define EF_ZIPIT 0x2605 /* Thomas Brown's Macintosh (ZipIt) */
+#define EF_ZIPIT2 0x2705 /* T. Brown's Mac (ZipIt) v 1.3.8 and newer ? */
+#define EF_SMARTZIP 0x4d63 /* Mac SmartZip by Marco Bambini */
+#define EF_VMCMS 0x4704 /* Info-ZIP's VM/CMS ("\004G") */
+#define EF_MVS 0x470f /* Info-ZIP's MVS ("\017G") */
+#define EF_ACL 0x4c41 /* (OS/2) access control list ("AL") */
+#define EF_NTSD 0x4453 /* NT security descriptor ("SD") */
+#define EF_ATHEOS 0x7441 /* AtheOS ("At") */
+#define EF_BEOS 0x6542 /* BeOS ("Be") */
+#define EF_QDOS 0xfb4a /* SMS/QDOS ("J\373") */
+#define EF_AOSVS 0x5356 /* AOS/VS ("VS") */
+#define EF_SPARK 0x4341 /* David Pilling's Acorn/SparkFS ("AC") */
+#define EF_TANDEM 0x4154 /* Tandem NSK ("TA") */
+#define EF_THEOS 0x6854 /* Jean-Michel Dubois' Theos "Th" */
+#define EF_THEOSO 0x4854 /* old Theos port */
+#define EF_MD5 0x4b46 /* Fred Kantor's MD5 ("FK") */
+#define EF_ASIUNIX 0x756e /* ASi's Unix ("nu") */
+
+#define EB_HEADSIZE 4 /* length of extra field block header */
+#define EB_ID 0 /* offset of block ID in header */
+#define EB_LEN 2 /* offset of data length field in header */
+#define EB_UCSIZE_P 0 /* offset of ucsize field in compr. data */
+#define EB_CMPRHEADLEN 6 /* lenght of compression header */
+
+#define EB_UX_MINLEN 8 /* minimal "UX" field contains atime, mtime */
+#define EB_UX_FULLSIZE 12 /* full "UX" field (atime, mtime, uid, gid) */
+#define EB_UX_ATIME 0 /* offset of atime in "UX" extra field data */
+#define EB_UX_MTIME 4 /* offset of mtime in "UX" extra field data */
+#define EB_UX_UID 8 /* byte offset of UID in "UX" field data */
+#define EB_UX_GID 10 /* byte offset of GID in "UX" field data */
+
+#define EB_UX2_MINLEN 4 /* minimal "Ux" field contains UID/GID */
+#define EB_UX2_UID 0 /* byte offset of UID in "Ux" field data */
+#define EB_UX2_GID 2 /* byte offset of GID in "Ux" field data */
+#define EB_UX2_VALID (1 << 8) /* UID/GID present */
+
+#define EB_UT_MINLEN 1 /* minimal UT field contains Flags byte */
+#define EB_UT_FLAGS 0 /* byte offset of Flags field */
+#define EB_UT_TIME1 1 /* byte offset of 1st time value */
+#define EB_UT_FL_MTIME (1 << 0) /* mtime present */
+#define EB_UT_FL_ATIME (1 << 1) /* atime present */
+#define EB_UT_FL_CTIME (1 << 2) /* ctime present */
+
+#define EB_FLGS_OFFS 4 /* offset of flags area in generic compressed
+ extra field blocks (BEOS, MAC, and others) */
+#define EB_OS2_HLEN 4 /* size of OS2/ACL compressed data header */
+#define EB_BEOS_HLEN 5 /* length of BeOS&AtheOS e.f attribute header */
+#define EB_BE_FL_UNCMPR 0x01 /* "BeOS&AtheOS attribs uncompr." bit flag */
+#define EB_MAC3_HLEN 14 /* length of Mac3 attribute block header */
+#define EB_SMARTZIP_HLEN 64 /* fixed length of the SmartZip extra field */
+#define EB_M3_FL_DATFRK 0x01 /* "this entry is data fork" flag */
+#define EB_M3_FL_UNCMPR 0x04 /* "Mac3 attributes uncompressed" bit flag */
+#define EB_M3_FL_TIME64 0x08 /* "Mac3 time fields are 64 bit wide" flag */
+#define EB_M3_FL_NOUTC 0x10 /* "Mac3 timezone offset fields missing" flag */
+
+#define EB_NTSD_C_LEN 4 /* length of central NT security data */
+#define EB_NTSD_L_LEN 5 /* length of minimal local NT security data */
+#define EB_NTSD_VERSION 4 /* offset of NTSD version byte */
+#define EB_NTSD_MAX_VER (0) /* maximum version # we know how to handle */
+
+#define EB_ASI_CRC32 0 /* offset of ASI Unix field's crc32 checksum */
+#define EB_ASI_MODE 4 /* offset of ASI Unix permission mode field */
+
+#define EB_IZVMS_HLEN 12 /* length of IZVMS attribute block header */
+#define EB_IZVMS_FLGS 4 /* offset of compression type flag */
+#define EB_IZVMS_UCSIZ 6 /* offset of ucsize field in IZVMS header */
+#define EB_IZVMS_BCMASK 07 /* 3 bits for compression type */
+#define EB_IZVMS_BCSTOR 0 /* Stored */
+#define EB_IZVMS_BC00 1 /* 0byte -> 0bit compression */
+#define EB_IZVMS_BCDEFL 2 /* Deflated */
+
+
+/*---------------------------------------------------------------------------
+ True sizes of the various headers, as defined by PKWARE--so it is not
+ likely that these will ever change. But if they do, make sure both these
+ defines AND the typedefs below get updated accordingly.
+ ---------------------------------------------------------------------------*/
+#define LREC_SIZE 26 /* lengths of local file headers, central */
+#define CREC_SIZE 42 /* directory headers, and the end-of- */
+#define ECREC_SIZE 18 /* central-dir record, respectively */
+
+#define MAX_BITS 13 /* used in unshrink() */
+#define HSIZE (1 << MAX_BITS) /* size of global work area */
+
+#define LF 10 /* '\n' on ASCII machines; must be 10 due to EBCDIC */
+#define CR 13 /* '\r' on ASCII machines; must be 13 due to EBCDIC */
+#define CTRLZ 26 /* DOS & OS/2 EOF marker (used in fileio.c, vms.c) */
+
+#ifdef EBCDIC
+# define foreign(c) ascii[(uch)(c)]
+# define native(c) ebcdic[(uch)(c)]
+# define NATIVE "EBCDIC"
+# define NOANSIFILT
+#endif
+
+#ifdef VMS
+# define ENV_UNZIP "UNZIP_OPTS" /* names of environment variables */
+# define ENV_ZIPINFO "ZIPINFO_OPTS"
+#endif /* VMS */
+#ifdef RISCOS
+# define ENV_UNZIP "Unzip$Options"
+# define ENV_ZIPINFO "Zipinfo$Options"
+# define ENV_UNZIPEXTS "Unzip$Exts"
+#endif /* RISCOS */
+#ifndef ENV_UNZIP
+# define ENV_UNZIP "UNZIP" /* the standard names */
+# define ENV_ZIPINFO "ZIPINFO"
+#endif
+#define ENV_UNZIP2 "UNZIPOPT" /* alternate names, for zip compat. */
+#define ENV_ZIPINFO2 "ZIPINFOOPT"
+
+#if (!defined(QQ) && !defined(NOQQ))
+# define QQ
+#endif
+
+#ifdef QQ /* Newtware version: no file */
+# define QCOND (!uO.qflag) /* comments with -vq or -vqq */
+#else /* Bill Davidsen version: no way to */
+# define QCOND (longhdr) /* kill file comments when listing */
+#endif
+
+#ifdef OLD_QQ
+# define QCOND2 (uO.qflag < 2)
+#else
+# define QCOND2 (!uO.qflag)
+#endif
+
+#ifdef WILD_STOP_AT_DIR
+# define __WDLPRO , int sepc
+# define __WDL , sepc
+# define __WDLDEF int sepc;
+# define WISEP , (uO.W_flag ? '/' : '\0')
+#else
+# define __WDLPRO
+# define __WDL
+# define __WDLDEF
+# define WISEP
+#endif
+
+
+
+
+/**************/
+/* Typedefs */
+/**************/
+
+#ifdef NO_UID_GID
+# ifdef UID_USHORT
+ typedef unsigned short uid_t; /* TI SysV.3 */
+ typedef unsigned short gid_t;
+# else
+ typedef unsigned int uid_t; /* SCO Xenix */
+ typedef unsigned int gid_t;
+# endif
+#endif
+
+#if (defined(GOT_UTIMBUF) || defined(sgi) || defined(ATARI))
+ typedef struct utimbuf ztimbuf;
+#else
+ typedef struct ztimbuf {
+ time_t actime; /* new access time */
+ time_t modtime; /* new modification time */
+ } ztimbuf;
+#endif
+
+typedef struct iztimes {
+ time_t atime; /* new access time */
+ time_t mtime; /* new modification time */
+ time_t ctime; /* used for creation time; NOT same as st_ctime */
+} iztimes;
+
+#ifdef SET_DIR_ATTRIB
+ typedef struct direntry { /* head of system-specific struct holding */
+ struct direntry *next; /* defered directory attributes info */
+ char *fn; /* filename of directory */
+ char buf[1]; /* start of system-specific internal data */
+ } direntry;
+#endif /* SET_DIR_ATTRIB */
+
+#ifdef SYMLINKS
+ typedef struct slinkentry { /* info for deferred symlink creation */
+ struct slinkentry *next; /* pointer to next entry in chain */
+ extent targetlen; /* length of target filespec */
+ extent attriblen; /* length of system-specific attrib data */
+ char *target; /* pointer to target filespec */
+ char *fname; /* pointer to name of link */
+ char buf[2]; /* name of link, allocs space for 2 '\0's */
+ } slinkentry;
+#endif /* SYMLINKS */
+
+typedef struct min_info {
+ Z_OFF_T offset;
+ ulg compr_size; /* compressed size (needed if extended header) */
+ ulg uncompr_size; /* uncompressed size (needed if extended header) */
+ ulg crc; /* crc (needed if extended header) */
+ ush diskstart; /* no of volume where this entry starts */
+ uch hostver;
+ uch hostnum;
+ unsigned file_attr; /* local flavor, as used by creat(), chmod()... */
+ unsigned encrypted : 1; /* file encrypted: decrypt before uncompressing */
+ unsigned ExtLocHdr : 1; /* use time instead of CRC for decrypt check */
+ unsigned textfile : 1; /* file is text (according to zip) */
+ unsigned textmode : 1; /* file is to be extracted as text */
+ unsigned lcflag : 1; /* convert filename to lowercase */
+ unsigned vollabel : 1; /* "file" is an MS-DOS volume (disk) label */
+ unsigned HasUxAtt : 1; /* crec ext_file_attr has Unix style mode bits */
+#ifndef SFX
+ char Far *cfilname; /* central header version of filename */
+#endif
+} min_info;
+
+typedef struct VMStimbuf {
+ char *revdate; /* (both roughly correspond to Unix modtime/st_mtime) */
+ char *credate;
+} VMStimbuf;
+
+/*---------------------------------------------------------------------------
+ Zipfile work area declarations.
+ ---------------------------------------------------------------------------*/
+
+#ifdef MALLOC_WORK
+ union work {
+ struct { /* unshrink(): */
+ shrint *Parent; /* pointer to (8192 * sizeof(shrint)) */
+ uch *value; /* pointer to 8KB char buffer */
+ uch *Stack; /* pointer to another 8KB char buffer */
+ } shrink;
+ uch *Slide; /* explode(), inflate(), unreduce() */
+ };
+#else /* !MALLOC_WORK */
+ union work {
+ struct { /* unshrink(): */
+ shrint Parent[HSIZE]; /* (8192 * sizeof(shrint)) == 16KB minimum */
+ uch value[HSIZE]; /* 8KB */
+ uch Stack[HSIZE]; /* 8KB */
+ } shrink; /* total = 32KB minimum; 80KB on Cray/Alpha */
+ uch Slide[WSIZE]; /* explode(), inflate(), unreduce() */
+ };
+#endif /* ?MALLOC_WORK */
+
+#define slide G.area.Slide
+
+#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+# define redirSlide G.redirect_sldptr
+#else
+# define redirSlide G.area.Slide
+#endif
+
+/*---------------------------------------------------------------------------
+ Zipfile layout declarations. If these headers ever change, make sure the
+ xxREC_SIZE defines (above) change with them!
+ ---------------------------------------------------------------------------*/
+
+ typedef uch local_byte_hdr[ LREC_SIZE ];
+# define L_VERSION_NEEDED_TO_EXTRACT_0 0
+# define L_VERSION_NEEDED_TO_EXTRACT_1 1
+# define L_GENERAL_PURPOSE_BIT_FLAG 2
+# define L_COMPRESSION_METHOD 4
+# define L_LAST_MOD_DOS_DATETIME 6
+# define L_CRC32 10
+# define L_COMPRESSED_SIZE 14
+# define L_UNCOMPRESSED_SIZE 18
+# define L_FILENAME_LENGTH 22
+# define L_EXTRA_FIELD_LENGTH 24
+
+ typedef uch cdir_byte_hdr[ CREC_SIZE ];
+# define C_VERSION_MADE_BY_0 0
+# define C_VERSION_MADE_BY_1 1
+# define C_VERSION_NEEDED_TO_EXTRACT_0 2
+# define C_VERSION_NEEDED_TO_EXTRACT_1 3
+# define C_GENERAL_PURPOSE_BIT_FLAG 4
+# define C_COMPRESSION_METHOD 6
+# define C_LAST_MOD_DOS_DATETIME 8
+# define C_CRC32 12
+# define C_COMPRESSED_SIZE 16
+# define C_UNCOMPRESSED_SIZE 20
+# define C_FILENAME_LENGTH 24
+# define C_EXTRA_FIELD_LENGTH 26
+# define C_FILE_COMMENT_LENGTH 28
+# define C_DISK_NUMBER_START 30
+# define C_INTERNAL_FILE_ATTRIBUTES 32
+# define C_EXTERNAL_FILE_ATTRIBUTES 34
+# define C_RELATIVE_OFFSET_LOCAL_HEADER 38
+
+ typedef uch ec_byte_rec[ ECREC_SIZE+4 ];
+/* define SIGNATURE 0 space-holder only */
+# define NUMBER_THIS_DISK 4
+# define NUM_DISK_WITH_START_CENTRAL_DIR 6
+# define NUM_ENTRIES_CENTRL_DIR_THS_DISK 8
+# define TOTAL_ENTRIES_CENTRAL_DIR 10
+# define SIZE_CENTRAL_DIRECTORY 12
+# define OFFSET_START_CENTRAL_DIRECTORY 16
+# define ZIPFILE_COMMENT_LENGTH 20
+
+
+/* The following structs are used to hold all header data of a zip entry.
+ Traditionally, the structs' layouts followed the data layout of the
+ corresponding zipfile header structures. However, the zipfile header
+ layouts were designed in the old ages of 16-bit CPUs, they are subject
+ to structure padding and/or alignment issues on newer systems with a
+ "natural word width" of more than 2 bytes.
+ Please note that the structure members are now reordered by size
+ (top-down), to prevent internal padding and optimize memory usage!
+ */
+ typedef struct local_file_header { /* LOCAL */
+ ulg csize;
+ ulg ucsize;
+ ulg last_mod_dos_datetime;
+ ulg crc32;
+ uch version_needed_to_extract[2];
+ ush general_purpose_bit_flag;
+ ush compression_method;
+ ush filename_length;
+ ush extra_field_length;
+ } local_file_hdr;
+
+#if 0
+ typedef struct central_directory_file_header { /* CENTRAL */
+ uch version_made_by[2];
+ uch version_needed_to_extract[2];
+ ush general_purpose_bit_flag;
+ ush compression_method;
+ ulg last_mod_dos_datetime;
+ ulg crc32;
+ ulg csize;
+ ulg ucsize;
+ ush filename_length;
+ ush extra_field_length;
+ ush file_comment_length;
+ ush disk_number_start;
+ ush internal_file_attributes;
+ ulg external_file_attributes;
+ ulg relative_offset_local_header;
+ } cdir_file_hdr;
+#endif /* 0 */
+
+ typedef struct end_central_dir_record { /* END CENTRAL */
+ ush number_this_disk;
+ ush num_disk_start_cdir;
+ ush num_entries_centrl_dir_ths_disk;
+ ush total_entries_central_dir;
+ ulg size_central_directory;
+ ulg offset_start_central_directory;
+ ush zipfile_comment_length;
+ } ecdir_rec;
+
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+ that have 16-bit pointers (e.g. PC's in the small or medium model).
+ Valid extra bits are 0..16. e == 31 is EOB (end of block), e == 32
+ means that v is a literal, 32 < e < 64 means that v is a pointer to
+ the next table, which codes (e & 31) bits, and lastly e == 99 indicates
+ an unused code. If a code with e == 99 is looked up, this implies an
+ error in the data. */
+
+struct huft {
+ uch e; /* number of extra bits or operation */
+ uch b; /* number of bits in this code or subcode */
+ union {
+ ush n; /* literal, length base, or distance base */
+ struct huft *t; /* pointer to next level of table */
+ } v;
+};
+
+
+typedef struct _APIDocStruct {
+ char *compare;
+ char *function;
+ char *syntax;
+ char *purpose;
+} APIDocStruct;
+
+
+
+
+/*************/
+/* Globals */
+/*************/
+
+#if (defined(OS2) && !defined(FUNZIP))
+# include "os2/os2data.h"
+#endif
+
+#include "globals.h"
+
+
+
+/*************************/
+/* Function Prototypes */
+/*************************/
+
+/*---------------------------------------------------------------------------
+ Functions in unzip.c (initialization routines):
+ ---------------------------------------------------------------------------*/
+
+#ifndef WINDLL
+ int MAIN OF((int argc, char **argv));
+ int unzip OF((__GPRO__ int argc, char **argv));
+ int uz_opts OF((__GPRO__ int *pargc, char ***pargv));
+ int usage OF((__GPRO__ int error));
+#endif /* !WINDLL */
+
+/*---------------------------------------------------------------------------
+ Functions in process.c (main driver routines):
+ ---------------------------------------------------------------------------*/
+
+int process_zipfiles OF((__GPRO));
+void free_G_buffers OF((__GPRO));
+/* static int do_seekable OF((__GPRO__ int lastchance)); */
+/* static int find_ecrec OF((__GPRO__ long searchlen)); */
+int uz_end_central OF((__GPRO));
+int process_cdir_file_hdr OF((__GPRO));
+int get_cdir_ent OF((__GPRO));
+int process_local_file_hdr OF((__GPRO));
+unsigned ef_scan_for_izux OF((ZCONST uch *ef_buf, unsigned ef_len,
+ int ef_is_c, ulg dos_mdatetime,
+ iztimes *z_utim, ush *z_uidgid));
+#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
+ zvoid *getRISCOSexfield OF((ZCONST uch *ef_buf, unsigned ef_len));
+#endif
+
+#ifndef SFX
+
+/*---------------------------------------------------------------------------
+ Functions in zipinfo.c (`zipinfo-style' listing routines):
+ ---------------------------------------------------------------------------*/
+
+#ifndef NO_ZIPINFO
+#ifndef WINDLL
+ int zi_opts OF((__GPRO__ int *pargc, char ***pargv));
+#endif
+int zi_end_central OF((__GPRO));
+int zipinfo OF((__GPRO));
+/* static int zi_long OF((__GPRO__ ulg *pEndprev)); */
+/* static int zi_short OF((__GPRO)); */
+/* static char *zi_time OF((__GPRO__ ZCONST ulg *datetimez,
+ ZCONST time_t *modtimez, char *d_t_str));*/
+#endif /* !NO_ZIPINFO */
+
+/*---------------------------------------------------------------------------
+ Functions in list.c (generic zipfile-listing routines):
+ ---------------------------------------------------------------------------*/
+
+int list_files OF((__GPRO));
+#ifdef TIMESTAMP
+ int get_time_stamp OF((__GPRO__ time_t *last_modtime,
+ ulg *nmember));
+#endif
+int ratio OF((ulg uc, ulg c));
+void fnprint OF((__GPRO));
+
+#endif /* !SFX */
+
+/*---------------------------------------------------------------------------
+ Functions in fileio.c:
+ ---------------------------------------------------------------------------*/
+
+int open_input_file OF((__GPRO));
+int open_outfile OF((__GPRO)); /* also vms.c */
+void undefer_input OF((__GPRO));
+void defer_leftover_input OF((__GPRO));
+unsigned readbuf OF((__GPRO__ char *buf, register unsigned len));
+int readbyte OF((__GPRO));
+int fillinbuf OF((__GPRO));
+int seek_zipf OF((__GPRO__ Z_OFF_T abs_offset));
+#ifdef FUNZIP
+ int flush OF((__GPRO__ ulg size)); /* actually funzip.c */
+#else
+ int flush OF((__GPRO__ uch *buf, ulg size, int unshrink));
+#endif
+/* static int disk_error OF((__GPRO)); */
+void handler OF((int signal));
+time_t dos_to_unix_time OF((ulg dos_datetime));
+int check_for_newer OF((__GPRO__ char *filename)); /* os2,vmcms,vms */
+int do_string OF((__GPRO__ unsigned int length, int option));
+ush makeword OF((ZCONST uch *b));
+ulg makelong OF((ZCONST uch *sig));
+#if (!defined(STR_TO_ISO) || defined(NEED_STR2ISO))
+ char *str2iso OF((char *dst, ZCONST char *src));
+#endif
+#if (!defined(STR_TO_OEM) || defined(NEED_STR2OEM))
+ char *str2oem OF((char *dst, ZCONST char *src));
+#endif
+#ifdef NO_STRNICMP
+ int zstrnicmp OF((register ZCONST char *s1,
+ register ZCONST char *s2,
+ register unsigned n));
+#endif
+#ifdef REGULUS
+ int zstat OF((ZCONST char *p, struct stat *s));
+#endif
+#ifdef ZMEM /* MUST be ifdef'd because of conflicts with the standard def. */
+ zvoid *memset OF((register zvoid *, register int, register unsigned int));
+ int memcmp OF((register ZCONST zvoid*, register ZCONST zvoid *,
+ register unsigned int));
+ zvoid *memcpy OF((register zvoid *, register ZCONST zvoid *,
+ register unsigned int));
+#endif
+#ifdef NEED_UZMBSCHR
+ unsigned char *uzmbschr OF((ZCONST unsigned char *str, unsigned int c));
+#endif
+#ifdef NEED_UZMBSRCHR
+ unsigned char *uzmbsrchr OF((ZCONST unsigned char *str, unsigned int c));
+#endif
+#ifdef SMALL_MEM
+ char *fLoadFarString OF((__GPRO__ const char Far *sz));
+ char *fLoadFarStringSmall OF((__GPRO__ const char Far *sz));
+ char *fLoadFarStringSmall2 OF((__GPRO__ const char Far *sz));
+ #ifndef zfstrcpy
+ char Far * Far zfstrcpy OF((char Far *s1, const char Far *s2));
+ #endif
+ #if (!defined(SFX) && !defined(zfstrcmp))
+ int Far zfstrcmp OF((const char Far *s1, const char Far *s2));
+ #endif
+#endif
+
+
+/*---------------------------------------------------------------------------
+ Functions in extract.c:
+ ---------------------------------------------------------------------------*/
+
+int extract_or_test_files OF((__GPRO));
+/* static int store_info OF((void)); */
+/* static int extract_or_test_member OF((__GPRO)); */
+/* static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len)); */
+/* static int test_OS2 OF((__GPRO__ uch *eb, unsigned eb_size)); */
+/* static int test_NT OF((__GPRO__ uch *eb, unsigned eb_size)); */
+int memextract OF((__GPRO__ uch *tgt, ulg tgtsize,
+ ZCONST uch *src, ulg srcsize));
+int memflush OF((__GPRO__ ZCONST uch *rawbuf, ulg size));
+#if (defined(VMS) || defined(VMS_TEXT_CONV))
+ uch *extract_izvms_block OF((__GPRO__ ZCONST uch *ebdata,
+ unsigned size, unsigned *retlen,
+ ZCONST uch *init, unsigned needlen));
+#endif
+char *fnfilter OF((ZCONST char *raw, uch *space));
+
+/*---------------------------------------------------------------------------
+ Decompression functions:
+ ---------------------------------------------------------------------------*/
+
+#if (!defined(SFX) && !defined(FUNZIP))
+int explode OF((__GPRO)); /* explode.c */
+#endif
+int huft_free OF((struct huft *t)); /* inflate.c */
+int huft_build OF((__GPRO__ ZCONST unsigned *b, unsigned n,
+ unsigned s, ZCONST ush *d, ZCONST uch *e,
+ struct huft **t, unsigned *m));
+#ifdef USE_ZLIB
+ int UZinflate OF((__GPRO__ int is_defl64)); /* inflate.c */
+# define inflate_free(x) inflateEnd(&((Uz_Globs *)(&G))->dstrm)
+#else
+ int inflate OF((__GPRO__ int is_defl64)); /* inflate.c */
+ int inflate_free OF((__GPRO)); /* inflate.c */
+#endif /* ?USE_ZLIB */
+#if (!defined(SFX) && !defined(FUNZIP))
+#ifndef COPYRIGHT_CLEAN
+ int unreduce OF((__GPRO)); /* unreduce.c */
+/* static void LoadFollowers OF((__GPRO__ f_array *follower, uch *Slen));
+ * unreduce.c */
+#endif /* !COPYRIGHT_CLEAN */
+#ifndef LZW_CLEAN
+ int unshrink OF((__GPRO)); /* unshrink.c */
+/* static void partial_clear OF((__GPRO)); * unshrink.c */
+#endif /* !LZW_CLEAN */
+#endif /* !SFX && !FUNZIP */
+
+/*---------------------------------------------------------------------------
+ Internal API functions (only included in DLL versions):
+ ---------------------------------------------------------------------------*/
+
+#ifdef DLL
+ void setFileNotFound OF((__GPRO)); /* api.c */
+ int unzipToMemory OF((__GPRO__ char *zip, char *file,
+ UzpBuffer *retstr)); /* api.c */
+ int redirect_outfile OF((__GPRO)); /* api.c */
+ int writeToMemory OF((__GPRO__ ZCONST uch *rawbuf,
+ extent size)); /* api.c */
+ int close_redirect OF((__GPRO)); /* api.c */
+ /* this obsolescent entry point kept for compatibility: */
+ int UzpUnzip OF((int argc, char **argv));/* use UzpMain */
+#ifdef OS2DLL
+ int varmessage OF((__GPRO__ ZCONST uch *buf, ulg size));
+ int varputchar OF((__GPRO__ int c)); /* rexxapi.c */
+ int finish_REXX_redirect OF((__GPRO)); /* rexxapi.c */
+#endif
+#ifdef API_DOC
+ void APIhelp OF((__GPRO__ int argc, char **argv));
+#endif /* apihelp.c */
+#endif /* DLL */
+
+/*---------------------------------------------------------------------------
+ MSDOS-only functions:
+ ---------------------------------------------------------------------------*/
+
+#if (defined(MSDOS) && (defined(__GO32__) || defined(__EMX__)))
+ unsigned _dos_getcountryinfo(void *); /* msdos.c */
+#if (!defined(__DJGPP__) || (__DJGPP__ < 2))
+ unsigned _dos_setftime(int, unsigned, unsigned); /* msdos.c */
+ unsigned _dos_setfileattr(const char *, unsigned); /* msdos.c */
+ unsigned _dos_creat(const char *, unsigned, int *); /* msdos.c */
+ void _dos_getdrive(unsigned *); /* msdos.c */
+ unsigned _dos_close(int); /* msdos.c */
+#endif /* !__DJGPP__ || (__DJGPP__ < 2) */
+#endif
+
+/*---------------------------------------------------------------------------
+ OS/2-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef OS2 /* GetFileTime conflicts with something in Win32 header files */
+#if (defined(REENTRANT) && defined(USETHREADID))
+ ulg GetThreadId OF((void));
+#endif
+ int GetCountryInfo OF((void)); /* os2.c */
+ long GetFileTime OF((ZCONST char *name)); /* os2.c */
+/* static void SetPathAttrTimes OF((__GPRO__ int flags, int dir)); os2.c */
+/* static int SetEAs OF((__GPRO__ const char *path,
+ void *eablock)); os2.c */
+/* static int SetACL OF((__GPRO__ const char *path,
+ void *eablock)); os2.c */
+/* static int IsFileNameValid OF((const char *name)); os2.c */
+/* static void map2fat OF((char *pathcomp, char **pEndFAT)); os2.c */
+/* static int SetLongNameEA OF((char *name, char *longname)); os2.c */
+/* static void InitNLS OF((void)); os2.c */
+ int IsUpperNLS OF((int nChr)); /* os2.c */
+ int ToLowerNLS OF((int nChr)); /* os2.c */
+ void DebugMalloc OF((void)); /* os2.c */
+#endif
+
+/*---------------------------------------------------------------------------
+ QDOS-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef QDOS
+ int QMatch (uch, uch);
+ void QFilename (__GPRO__ char *);
+ char *Qstrfix (char *);
+ int QReturn (int zip_error);
+#endif
+
+/*---------------------------------------------------------------------------
+ TOPS20-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef TOPS20
+ int upper OF((char *s)); /* tops20.c */
+ int enquote OF((char *s)); /* tops20.c */
+ int dequote OF((char *s)); /* tops20.c */
+ int fnlegal OF(()); /* error if prototyped? */ /* tops20.c */
+#endif
+
+/*---------------------------------------------------------------------------
+ VM/CMS- and MVS-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef CMS_MVS
+ extent getVMMVSexfield OF((char *type, uch *ef_block, unsigned datalen));
+ FILE *vmmvs_open_infile OF((__GPRO)); /* vmmvs.c */
+ void close_infile OF((__GPRO)); /* vmmvs.c */
+#endif
+
+/*---------------------------------------------------------------------------
+ VMS-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef VMS
+ int check_format OF((__GPRO)); /* vms.c */
+/* int open_outfile OF((__GPRO)); * (see fileio.c) vms.c */
+/* int flush OF((__GPRO__ uch *rawbuf, unsigned size,
+ int final_flag)); * (see fileio.c) vms.c */
+#ifdef RETURN_CODES
+ void return_VMS OF((__GPRO__ int zip_error)); /* vms.c */
+#else
+ void return_VMS OF((int zip_error)); /* vms.c */
+#endif
+#ifdef VMSCLI
+ ulg vms_unzip_cmdline OF((int *, char ***)); /* cmdline.c */
+ int VMSCLI_usage OF((__GPRO__ int error)); /* cmdline.c */
+#endif
+#endif
+
+/*---------------------------------------------------------------------------
+ WIN32-only functions:
+ ---------------------------------------------------------------------------*/
+
+#ifdef WIN32
+ int IsWinNT OF((void)); /* win32.c */
+#ifdef NTSD_EAS
+ void process_defer_NT OF((__GPRO)); /* win32.c */
+ int test_NTSD OF((__GPRO__ uch *eb, unsigned eb_size,
+ uch *eb_ucptr, ulg eb_ucsize)); /* win32.c */
+# define TEST_NTSD test_NTSD
+#endif
+#ifdef W32_STAT_BANDAID
+ int zstat_win32 OF((__W32STAT_GLOBALS__
+ const char *path, struct stat *buf)); /* win32.c */
+#endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Miscellaneous/shared functions:
+ ---------------------------------------------------------------------------*/
+
+Uz_Globs *globalsCtor OF((void)); /* globals.c */
+
+int envargs OF((int *Pargc, char ***Pargv,
+ ZCONST char *envstr, ZCONST char *envstr2));
+ /* envargs.c */
+void mksargs OF((int *argcp, char ***argvp)); /* envargs.c */
+
+int match OF((ZCONST char *s, ZCONST char *p,
+ int ic __WDLPRO)); /* match.c */
+int iswild OF((ZCONST char *p)); /* match.c */
+
+#ifdef DYNALLOC_CRCTAB
+ void free_crc_table OF((void)); /* crctab.c */
+#endif
+#ifndef USE_ZLIB
+ ZCONST ulg near *get_crc_table OF((void)); /* funzip.c, crctab.c */
+ ulg crc32 OF((ulg crc, ZCONST uch *buf, extent len));
+#endif /* !USE_ZLIB */ /* assembler source or crc32.c */
+
+int dateformat OF((void)); /* local */
+char dateseparator OF((void)); /* local */
+#ifndef WINDLL
+ void version OF((__GPRO)); /* local */
+#endif
+int mapattr OF((__GPRO)); /* local */
+int mapname OF((__GPRO__ int renamed)); /* local */
+int checkdir OF((__GPRO__ char *pathcomp, int flag)); /* local */
+char *do_wild OF((__GPRO__ ZCONST char *wildzipfn)); /* local */
+char *GetLoadPath OF((__GPRO)); /* local */
+#if (defined(MORE) && (defined(ATH_BEO_UNX) || defined(QDOS) || defined(VMS)))
+ int screensize OF((int *tt_rows, int *tt_cols)); /* local */
+# if defined(VMS)
+ int screenlinewrap OF((void)); /* local */
+# endif
+#endif /* MORE && (ATH_BEO_UNX || QDOS || VMS) */
+#ifdef OS2_W32
+ int SetFileSize OF((FILE *file, ulg filesize)); /* local */
+#endif
+#ifndef MTS /* macro in MTS */
+ void close_outfile OF((__GPRO)); /* local */
+#endif
+#ifdef SET_SYMLINK_ATTRIBS
+ int set_symlnk_attribs OF((__GPRO__ slinkentry *slnk_entry)); /* local */
+#endif
+#ifdef SET_DIR_ATTRIB
+ int defer_dir_attribs OF((__GPRO__ direntry **pd)); /* local */
+ int set_direc_attribs OF((__GPRO__ direntry *d)); /* local */
+#endif
+#ifdef TIMESTAMP
+# ifdef WIN32
+ int stamp_file OF((__GPRO__
+ ZCONST char *fname, time_t modtime)); /* local */
+# else
+ int stamp_file OF((ZCONST char *fname, time_t modtime)); /* local */
+# endif
+#endif
+#if (defined(MALLOC_WORK) && defined(MY_ZCALLOC))
+ zvoid far *zcalloc OF((unsigned int, unsigned int));
+ zvoid zcfree OF((zvoid far *));
+#endif /* MALLOC_WORK && MY_ZCALLOC */
+#ifdef SYSTEM_SPECIFIC_CTOR
+ void SYSTEM_SPECIFIC_CTOR OF((__GPRO)); /* local */
+#endif
+#ifdef SYSTEM_SPECIFIC_DTOR
+ void SYSTEM_SPECIFIC_DTOR OF((__GPRO)); /* local */
+#endif
+
+
+
+
+
+/************/
+/* Macros */
+/************/
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifdef DEBUG
+# if (defined(THEOS) && defined(NO_BOGUS_SPC))
+# define NO_DEBUG_IN_MACROS
+# define Trace(x) _fprintf x
+# else
+# define Trace(x) fprintf x
+# endif
+#else
+# define Trace(x)
+#endif
+
+#ifdef DEBUG_TIME
+# define TTrace(x) fprintf x
+#else
+# define TTrace(x)
+#endif
+
+#ifdef NO_DEBUG_IN_MACROS
+# define MTrace(x)
+#else
+# define MTrace(x) Trace(x)
+#endif
+
+#if (defined(UNIX) || defined(T20_VMS)) /* generally old systems */
+# define ToLower(x) ((char)(isupper((int)x)? tolower((int)x) : x))
+#else
+# define ToLower tolower /* assumed "smart"; used in match() */
+#endif
+
+#ifdef USE_STRM_INPUT
+ /* ``Replace'' the unbuffered UNIX style I/O function with similar
+ * standard C functions from <stdio.h>.
+ */
+# define read(fd,buf,n) fread((buf),1,(n),(FILE *)(fd))
+# define lseek(fd,o,w) fseek((FILE *)(fd),(o),(w))
+# define close(fd) fclose((FILE *)(fd))
+#endif /* USE_STRM_INPUT */
+
+/* The return value of the Info() "macro function" is never checked in
+ * UnZip. Otherwise, to get the same behaviour as for (*G.message)(), the
+ * Info() definition for "FUNZIP" would have to be corrected:
+ * #define Info(buf,flag,sprf_arg) \
+ * (fprintf((flag)&1? stderr : stdout, \
+ * (char *)(sprintf sprf_arg, (buf))) == EOF)
+ */
+#ifndef Info /* may already have been defined for redirection */
+# ifdef FUNZIP
+# define Info(buf,flag,sprf_arg) \
+ fprintf((flag)&1? stderr : stdout, (char *)(sprintf sprf_arg, (buf)))
+# else
+# ifdef INT_SPRINTF /* optimized version for "int sprintf()" flavour */
+# define Info(buf,flag,sprf_arg) \
+ (*G.message)((zvoid *)&G, (uch *)(buf), (ulg)sprintf sprf_arg, (flag))
+# else /* generic version, does not use sprintf() return value */
+# define Info(buf,flag,sprf_arg) \
+ (*G.message)((zvoid *)&G, (uch *)(buf), \
+ (ulg)(sprintf sprf_arg, strlen((char *)(buf))), (flag))
+# endif
+# endif
+#endif /* !Info */
+
+/* The following macro wrappers around the fnfilter function are used many
+ * times to prepare archive entry names or name components for displaying
+ * listings and (warning/error) messages. They use sections in the upper half
+ * of 'slide' as buffer, since their output is normally fed through the
+ * Info() macro with 'slide' (the start of this area) as message buffer.
+ */
+#define FnFilter1(fname) fnfilter((fname), slide + (WSIZE>>1))
+#define FnFilter2(fname) fnfilter((fname), slide + ((WSIZE>>1) + (WSIZE>>2)))
+
+#ifndef FUNZIP /* used only in inflate.c */
+# define MESSAGE(str,len,flag) (*G.message)((zvoid *)&G,(str),(len),(flag))
+#endif
+
+#if 0 /* Optimization: use the (const) result of crc32(0L,NULL,0) */
+# define CRCVAL_INITIAL crc32(0L, NULL, 0)
+#else
+# define CRCVAL_INITIAL 0L
+#endif
+
+#ifndef TEST_NTSD /* "NTSD valid?" checking function */
+# define TEST_NTSD NULL /* ... is not available */
+#endif
+
+#define SKIP_(length) if(length&&((error=do_string(__G__ length,SKIP))!=0))\
+ {error_in_archive=error; if(error>1) return error;}
+
+/*
+ * Skip a variable-length field, and report any errors. Used in zipinfo.c
+ * and unzip.c in several functions.
+ *
+ * macro SKIP_(length)
+ * ush length;
+ * {
+ * if (length && ((error = do_string(length, SKIP)) != 0)) {
+ * error_in_archive = error; /-* might be warning *-/
+ * if (error > 1) /-* fatal *-/
+ * return (error);
+ * }
+ * }
+ *
+ */
+
+
+#ifdef FUNZIP
+# define FLUSH(w) flush(__G__ (ulg)(w))
+# define NEXTBYTE getc(G.in) /* redefined in crypt.h if full version */
+#else
+# define FLUSH(w) ((G.mem_mode) ? memflush(__G__ redirSlide,(ulg)(w)) \
+ : flush(__G__ redirSlide,(ulg)(w),0))
+# define NEXTBYTE (G.incnt-- > 0 ? (int)(*G.inptr++) : readbyte(__G))
+#endif
+
+
+#define READBITS(nbits,zdest) {if(nbits>G.bits_left) {int temp; G.zipeof=1;\
+ while (G.bits_left<=8*(int)(sizeof(G.bitbuf)-1) && (temp=NEXTBYTE)!=EOF) {\
+ G.bitbuf|=(ulg)temp<<G.bits_left; G.bits_left+=8; G.zipeof=0;}}\
+ zdest=(shrint)((unsigned)G.bitbuf&mask_bits[nbits]);G.bitbuf>>=nbits;\
+ G.bits_left-=nbits;}
+
+/*
+ * macro READBITS(nbits,zdest) * only used by unreduce and unshrink *
+ * {
+ * if (nbits > G.bits_left) { * fill G.bitbuf, 8*sizeof(ulg) bits *
+ * int temp;
+ *
+ * G.zipeof = 1;
+ * while (G.bits_left <= 8*(int)(sizeof(G.bitbuf)-1) &&
+ * (temp = NEXTBYTE) != EOF) {
+ * G.bitbuf |= (ulg)temp << G.bits_left;
+ * G.bits_left += 8;
+ * G.zipeof = 0;
+ * }
+ * }
+ * zdest = (shrint)((unsigned)G.bitbuf & mask_bits[nbits]);
+ * G.bitbuf >>= nbits;
+ * G.bits_left -= nbits;
+ * }
+ *
+ */
+
+
+/* GRR: should use StringLower for STRLOWER macro if possible */
+
+/*
+ * Copy the zero-terminated string in str1 into str2, converting any
+ * uppercase letters to lowercase as we go. str2 gets zero-terminated
+ * as well, of course. str1 and str2 may be the same character array.
+ */
+#ifdef _MBCS
+# define STRLOWER(str1, str2) \
+ { \
+ char *p, *q, c; unsigned i; \
+ p = (char *)(str1); \
+ q = (char *)(str2); \
+ while ((c = *p) != '\0') { \
+ if ((i = CLEN(p)) > 1) { \
+ while (i--) *q++ = *p++; \
+ } else { \
+ *q++ = (char)(isupper((int)(c))? tolower((int)(c)) : c); \
+ p++; \
+ } \
+ } \
+ *q = '\0'; \
+ }
+#else
+# define STRLOWER(str1, str2) \
+ { \
+ char *p, *q; \
+ p = (char *)(str1) - 1; \
+ q = (char *)(str2); \
+ while (*++p) \
+ *q++ = (char)(isupper((int)(*p))? tolower((int)(*p)) : *p); \
+ *q = '\0'; \
+ }
+#endif
+/*
+ * NOTES: This macro makes no assumptions about the characteristics of
+ * the tolower() function or macro (beyond its existence), nor does it
+ * make assumptions about the structure of the character set (i.e., it
+ * should work on EBCDIC machines, too). The fact that either or both
+ * of isupper() and tolower() may be macros has been taken into account;
+ * watch out for "side effects" (in the C sense) when modifying this
+ * macro.
+ */
+
+#ifndef foreign
+# define foreign(c) (c)
+#endif
+
+#ifndef native
+# define native(c) (c)
+# define A_TO_N(str1)
+#else
+# ifndef NATIVE
+# define NATIVE "native chars"
+# endif
+# define A_TO_N(str1) {register uch *p;\
+ for (p=(uch *)(str1); *p; p++) *p=native(*p);}
+#endif
+/*
+ * Translate the zero-terminated string in str1 from ASCII to the native
+ * character set. The translation is performed in-place and uses the
+ * "native" macro to translate each character.
+ *
+ * NOTE: Using the "native" macro means that is it the only part of unzip
+ * which knows which translation table (if any) is actually in use to
+ * produce the native character set. This makes adding new character set
+ * translation tables easy, insofar as all that is needed is an appropriate
+ * "native" macro definition and the translation table itself. Currently,
+ * the only non-ASCII native character set implemented is EBCDIC, but this
+ * may not always be so.
+ */
+
+
+/* default setup for internal codepage: assume ISO 8859-1 compatibility!! */
+#if (!defined(NATIVE) && !defined(CRTL_CP_IS_ISO) && !defined(CRTL_CP_IS_OEM))
+# define CRTL_CP_IS_ISO
+#endif
+
+
+/* Translate "extended ASCII" chars (OEM coding for DOS and OS/2; else
+ * ISO-8859-1 [ISO Latin 1, Win Ansi,...]) into the internal "native"
+ * code page. As with A_TO_N(), conversion is done in place.
+ */
+#ifndef _ISO_INTERN
+# ifdef CRTL_CP_IS_OEM
+# ifndef IZ_ISO2OEM_ARRAY
+# define IZ_ISO2OEM_ARRAY
+# endif
+# define _ISO_INTERN(str1) {register uch *p;\
+ for (p=(uch *)(str1); *p; p++)\
+ *p = native((*p & 0x80) ? iso2oem[*p & 0x7f] : *p);}
+# else
+# define _ISO_INTERN(str1) A_TO_N(str1)
+# endif
+#endif
+
+#ifndef _OEM_INTERN
+# ifdef CRTL_CP_IS_OEM
+# define _OEM_INTERN(str1) A_TO_N(str1)
+# else
+# ifndef IZ_OEM2ISO_ARRAY
+# define IZ_OEM2ISO_ARRAY
+# endif
+# define _OEM_INTERN(str1) {register uch *p;\
+ for (p=(uch *)(str1); *p; p++)\
+ *p = native((*p & 0x80) ? oem2iso[*p & 0x7f] : *p);}
+# endif
+#endif
+
+#ifndef STR_TO_ISO
+# ifdef CRTL_CP_IS_ISO
+# define STR_TO_ISO strcpy
+# else
+# define STR_TO_ISO str2iso
+# define NEED_STR2ISO
+# endif
+#endif
+
+#ifndef STR_TO_OEM
+# ifdef CRTL_CP_IS_OEM
+# define STR_TO_OEM strcpy
+# else
+# define STR_TO_OEM str2oem
+# define NEED_STR2OEM
+# endif
+#endif
+
+#if (!defined(INTERN_TO_ISO) && !defined(ASCII2ISO))
+# ifdef CRTL_CP_IS_OEM
+ /* know: "ASCII" is "OEM" */
+# define ASCII2ISO(c) (((c) & 0x80) ? oem2iso[(c) & 0x7f] : (c))
+# if (defined(NEED_STR2ISO) && !defined(CRYP_USES_OEM2ISO))
+# define CRYP_USES_OEM2ISO
+# endif
+# else
+ /* assume: "ASCII" is "ISO-ANSI" */
+# define ASCII2ISO(c) (c)
+# endif
+#endif
+
+#if (!defined(INTERN_TO_OEM) && !defined(ASCII2OEM))
+# ifdef CRTL_CP_IS_OEM
+ /* know: "ASCII" is "OEM" */
+# define ASCII2OEM(c) (c)
+# else
+ /* assume: "ASCII" is "ISO-ANSI" */
+# define ASCII2OEM(c) (((c) & 0x80) ? iso2oem[(c) & 0x7f] : (c))
+# if (defined(NEED_STR2OEM) && !defined(CRYP_USES_ISO2OEM))
+# define CRYP_USES_ISO2OEM
+# endif
+# endif
+#endif
+
+/* codepage conversion setup for testp() in crypt.c */
+#ifdef CRTL_CP_IS_ISO
+# ifndef STR_TO_CP2
+# define STR_TO_CP2 STR_TO_OEM
+# endif
+#else
+# ifdef CRTL_CP_IS_OEM
+# ifndef STR_TO_CP2
+# define STR_TO_CP2 STR_TO_ISO
+# endif
+# else /* native internal CP is neither ISO nor OEM */
+# ifndef STR_TO_CP1
+# define STR_TO_CP1 STR_TO_ISO
+# endif
+# ifndef STR_TO_CP2
+# define STR_TO_CP2 STR_TO_OEM
+# endif
+# endif
+#endif
+
+
+/* Convert filename (and file comment string) into "internal" charset.
+ * This macro assumes that Zip entry filenames are coded in OEM (IBM DOS)
+ * codepage when made on
+ * -> DOS (this includes 16-bit Windows 3.1) (FS_FAT_)
+ * -> OS/2 (FS_HPFS_)
+ * -> Win95/WinNT with Nico Mak's WinZip (FS_NTFS_ && hostver == "5.0")
+ * EXCEPTIONS:
+ * PKZIP for Windows 2.5, 2.6, and 4.0 flag their entries as "FS_FAT_", but
+ * the filename stored in the local header is coded in Windows ANSI (CP 1252
+ * resp. ISO 8859-1 on US and western Europe locale settings).
+ * Likewise, PKZIP for UNIX 2.51 flags its entries as "FS_FAT_", but the
+ * filenames stored in BOTH the local and the central header are coded
+ * in the local system's codepage (usually ANSI codings like ISO 8859-1).
+ *
+ * All other ports are assumed to code zip entry filenames in ISO 8859-1.
+ */
+#ifndef Ext_ASCII_TO_Native
+# define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
+ if (((hostnum) == FS_FAT_ && \
+ !(((islochdr) || (isuxatt)) && \
+ ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
+ (hostnum) == FS_HPFS_ || \
+ ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
+ _OEM_INTERN((string)); \
+ } else { \
+ _ISO_INTERN((string)); \
+ }
+#endif
+
+
+
+/**********************/
+/* Global constants */
+/**********************/
+
+ extern ZCONST unsigned near mask_bits[17];
+ extern ZCONST char *fnames[2];
+
+#ifdef EBCDIC
+ extern ZCONST uch ebcdic[];
+#endif
+#ifdef IZ_ISO2OEM_ARRAY
+ extern ZCONST uch Far iso2oem[];
+#endif
+#ifdef IZ_OEM2ISO_ARRAY
+ extern ZCONST uch Far oem2iso[];
+#endif
+
+ extern ZCONST char Far VersionDate[];
+ extern ZCONST char Far CentSigMsg[];
+#ifndef SFX
+ extern ZCONST char Far EndSigMsg[];
+#endif
+ extern ZCONST char Far SeekMsg[];
+ extern ZCONST char Far FilenameNotMatched[];
+ extern ZCONST char Far ExclFilenameNotMatched[];
+ extern ZCONST char Far ReportMsg[];
+
+#ifndef SFX
+ extern ZCONST char Far Zipnfo[];
+ extern ZCONST char Far CompiledWith[];
+#endif /* !SFX */
+
+
+
+/***********************************/
+/* Global (shared?) RTL variables */
+/***********************************/
+
+#ifdef DECLARE_ERRNO
+ extern int errno;
+#endif
+
+
+#endif /* !__unzpriv_h */
Property changes on: trunk/build/install/installer/unzpriv.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/unzvers.h
===================================================================
--- trunk/build/install/installer/unzvers.h (rev 0)
+++ trunk/build/install/installer/unzvers.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,58 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ unzvers.h (for UnZip) by Info-ZIP.
+ */
+
+#ifndef __unzvers_h /* don't include more than once */
+#define __unzvers_h
+
+#ifdef BETA
+# undef BETA /* undefine BETA for public releases */
+#endif
+
+#ifdef BETA
+# define UZ_BETALEVEL "j BETA"
+# define UZ_VERSION_DATE "27 Feb 05" /* internal beta version */
+#else
+# define UZ_BETALEVEL ""
+# define UZ_VERSION_DATE "28 February 2005" /* official release version */
+# define RELEASE
+#endif
+
+#define UZ_MAJORVER 5 /* UnZip */
+#define UZ_MINORVER 5
+
+#define ZI_MAJORVER 2 /* ZipInfo */
+#define ZI_MINORVER 4
+
+#define UZ_PATCHLEVEL 2
+
+#define UZ_VER_STRING "5.52" /* keep in sync with Version numbers! */
+
+#ifndef IZ_COMPANY_NAME /* might be already defined... */
+# define IZ_COMPANY_NAME "Info-ZIP"
+#endif
+
+/* these are obsolete but remain for backward compatibility: */
+#if (defined(OS2) || defined(__OS2__))
+# define D2_MAJORVER UZ_MAJORVER /* DLL for OS/2 */
+# define D2_MINORVER UZ_MINORVER
+# define D2_PATCHLEVEL UZ_PATCHLEVEL
+#endif
+
+#define DW_MAJORVER UZ_MAJORVER /* DLL for MS Windows */
+#define DW_MINORVER UZ_MINORVER
+#define DW_PATCHLEVEL UZ_PATCHLEVEL
+
+#define WIN_VERSION_DATE UZ_VERSION_DATE
+
+#define UNZ_DLL_VERSION UZ_VER_STRING
+
+#endif /* !__unzvers_h */
Property changes on: trunk/build/install/installer/unzvers.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/win32/crc_i386.asm
===================================================================
--- trunk/build/install/installer/win32/crc_i386.asm (rev 0)
+++ trunk/build/install/installer/win32/crc_i386.asm 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,241 @@
+;===========================================================================
+; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; (the contents of which are also included in zip.h) for terms of use.
+; If, for some reason, all these files are missing, the Info-ZIP license
+; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+;===========================================================================
+; crc_i386.asm, optimized CRC calculation function for Zip and UnZip,
+; created by Paul Kienitz and Christian Spieler. Last revised 16 Jan 2005.
+;
+; Revised 06-Oct-96, Scott Field (sfield(a)microsoft.com)
+; fixed to assemble with masm by not using .model directive which makes
+; assumptions about segment alignment. Also,
+; avoid using loop, and j[e]cxz where possible. Use mov + inc, rather
+; than lodsb, and other misc. changes resulting in the following performance
+; increases:
+;
+; unrolled loops NO_UNROLLED_LOOPS
+; *8 >8 <8 *8 >8 <8
+;
+; +54% +42% +35% +82% +52% +25%
+;
+; first item in each table is input buffer length, even multiple of 8
+; second item in each table is input buffer length, > 8
+; third item in each table is input buffer length, < 8
+;
+; Revised 02-Apr-97, Chr. Spieler, based on Rodney Brown (rdb(a)cmutual.com.au)
+; Incorporated Rodney Brown's 32-bit-reads optimization as found in the
+; UNIX AS source crc_i386.S. This new code can be disabled by defining
+; the macro symbol NO_32_BIT_LOADS.
+;
+; Revised 12-Oct-97, Chr. Spieler, based on Rodney Brown (rdb(a)cmutual.com.au)
+; Incorporated Rodney Brown's additional tweaks for 32-bit-optimized CPUs
+; (like the Pentium Pro, Pentium II, and probably some Pentium clones).
+; This optimization is controlled by the macro symbol __686 and is disabled
+; by default. (This default is based on the assumption that most users
+; do not yet work on a Pentium Pro or Pentium II machine ...)
+;
+; Revised 25-Mar-98, Cosmin Truta (cosmint(a)cs.ubbcluj.ro)
+; Working without .model directive caused tasm32 version 5.0 to produce
+; bad object code. The optimized alignments can be optionally disabled
+; by defining NO_ALIGN, thus allowing to use .model flat. There is no need
+; to define this macro if using other versions of tasm.
+;
+; Revised 16-Jan-2005, Cosmin Truta (cosmint(a)cs.ubbcluj.ro)
+; Enabled the 686 build by default, because there are hardly any pre-686 CPUs
+; in serious use nowadays. (See the 12-Oct-97 note above.)
+;
+; FLAT memory model assumed.
+;
+; Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
+; This results in shorter code at the expense of reduced performance.
+;
+;==============================================================================
+;
+; Do NOT assemble this source if external crc32 routine from zlib gets used.
+;
+ IFNDEF USE_ZLIB
+;
+ .386p
+ name crc_i386
+
+ IFDEF NO_ALIGN
+ .model flat
+ ENDIF
+
+ IFNDEF PRE_686
+ IFNDEF __686
+__686 EQU 1 ; optimize for Pentium Pro, Pentium II and compatible CPUs
+ ENDIF
+ ENDIF
+
+extrn _get_crc_table:near ; ZCONST ulg near *get_crc_table(void);
+
+;
+ IFNDEF NO_STD_STACKFRAME
+ ; Use a `standard' stack frame setup on routine entry and exit.
+ ; Actually, this option is set as default, because it results
+ ; in smaller code !!
+STD_ENTRY MACRO
+ push ebp
+ mov ebp,esp
+ ENDM
+
+ Arg1 EQU 08H[ebp]
+ Arg2 EQU 0CH[ebp]
+ Arg3 EQU 10H[ebp]
+
+STD_LEAVE MACRO
+ pop ebp
+ ENDM
+
+ ELSE ; NO_STD_STACKFRAME
+
+STD_ENTRY MACRO
+ ENDM
+
+ Arg1 EQU 18H[esp]
+ Arg2 EQU 1CH[esp]
+ Arg3 EQU 20H[esp]
+
+STD_LEAVE MACRO
+ ENDM
+
+ ENDIF ; ?NO_STD_STACKFRAME
+
+; These two (three) macros make up the loop body of the CRC32 cruncher.
+; registers modified:
+; eax : crc value "c"
+; esi : pointer to next data byte (or dword) "buf++"
+; registers read:
+; edi : pointer to base of crc_table array
+; scratch registers:
+; ebx : index into crc_table array
+; (requires upper three bytes = 0 when __686 is undefined)
+ IFNDEF __686 ; optimize for 386, 486, Pentium
+Do_CRC MACRO
+ mov bl,al ; tmp = c & 0xFF
+ shr eax,8 ; c = (c >> 8)
+ xor eax,[edi+ebx*4] ; ^ table[tmp]
+ ENDM
+ ELSE ; __686 : optimize for Pentium Pro, Pentium II and compatible CPUs
+Do_CRC MACRO
+ movzx ebx,al ; tmp = c & 0xFF
+ shr eax,8 ; c = (c >> 8)
+ xor eax,[edi+ebx*4] ; ^ table[tmp]
+ ENDM
+ ENDIF ; ?__686
+Do_CRC_byte MACRO
+ xor al, byte ptr [esi] ; c ^= *buf
+ inc esi ; buf++
+ Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
+ ENDM
+ IFNDEF NO_32_BIT_LOADS
+Do_CRC_dword MACRO
+ xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
+ add esi, 4 ; ((ulg *)buf)++
+ Do_CRC
+ Do_CRC
+ Do_CRC
+ Do_CRC
+ ENDM
+ ENDIF ; !NO_32_BIT_LOADS
+
+ IFNDEF NO_ALIGN
+_TEXT segment use32 para public 'CODE'
+ ELSE
+_TEXT segment use32
+ ENDIF
+ assume CS: _TEXT
+
+ public _crc32
+_crc32 proc near ; ulg crc32(ulg crc, ZCONST uch *buf, extent len)
+ STD_ENTRY
+ push edi
+ push esi
+ push ebx
+ push edx
+ push ecx
+
+ mov esi,Arg2 ; 2nd arg: uch *buf
+ sub eax,eax ;> if (!buf)
+ test esi,esi ;> return 0;
+ jz fine ;> else {
+
+ call _get_crc_table
+ mov edi,eax
+ mov eax,Arg1 ; 1st arg: ulg crc
+ IFNDEF __686
+ sub ebx,ebx ; ebx=0; make bl usable as a dword
+ ENDIF
+ mov ecx,Arg3 ; 3rd arg: extent len
+ not eax ;> c = ~crc;
+
+ test ecx,ecx
+ IFNDEF NO_UNROLLED_LOOPS
+ jz bail
+ IFNDEF NO_32_BIT_LOADS
+align_loop:
+ test esi,3 ; align buf pointer on next
+ jz SHORT aligned_now ; dword boundary
+ Do_CRC_byte
+ dec ecx
+ jnz align_loop
+aligned_now:
+ ENDIF ; !NO_32_BIT_LOADS
+ mov edx,ecx ; save len in edx
+ shr ecx,3 ; ecx = len / 8
+ jz SHORT No_Eights
+ IFNDEF NO_ALIGN
+; align loop head at start of 486 internal cache line !!
+ align 16
+ ENDIF
+Next_Eight:
+ IFNDEF NO_32_BIT_LOADS
+ Do_CRC_dword
+ Do_CRC_dword
+ ELSE ; NO_32_BIT_LOADS
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ Do_CRC_byte
+ ENDIF ; ?NO_32_BIT_LOADS
+ dec ecx
+ jnz Next_Eight
+No_Eights:
+ mov ecx,edx
+ and ecx,000000007H ; ecx = len % 8
+ ENDIF ; !NO_UNROLLED_LOOPS
+ jz SHORT bail ;> if (len)
+ IFNDEF NO_ALIGN
+; align loop head at start of 486 internal cache line !!
+ align 16
+ ENDIF
+loupe: ;> do {
+ Do_CRC_byte ; c = CRC32(c, *buf++);
+ dec ecx ;> } while (--len);
+ jnz loupe
+
+bail: ;> }
+ not eax ;> return ~c;
+fine:
+ pop ecx
+ pop edx
+ pop ebx
+ pop esi
+ pop edi
+ STD_LEAVE
+ ret
+_crc32 endp
+
+_TEXT ends
+;
+ ENDIF ; !USE_ZLIB
+;
+end
Added: trunk/build/install/installer/win32/crc_i386.c
===================================================================
--- trunk/build/install/installer/win32/crc_i386.c (rev 0)
+++ trunk/build/install/installer/win32/crc_i386.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,229 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* crc_i386.c -- Microsoft 32-bit C/C++ adaptation of crc_i386.asm
+ * Created by Rodney Brown from crc_i386.asm, modified by Chr. Spieler.
+ * Last revised: 16-Jan-2005
+ *
+ * Original coded (in crc_i386.asm) and put into the public domain
+ * by Paul Kienitz and Christian Spieler.
+ *
+ * Revised 06-Oct-96, Scott Field (sfield(a)microsoft.com)
+ * fixed to assemble with masm by not using .model directive which makes
+ * assumptions about segment alignment. Also,
+ * avoid using loop, and j[e]cxz where possible. Use mov + inc, rather
+ * than lodsb, and other misc. changes resulting in the following performance
+ * increases:
+ *
+ * unrolled loops NO_UNROLLED_LOOPS
+ * *8 >8 <8 *8 >8 <8
+ *
+ * +54% +42% +35% +82% +52% +25%
+ *
+ * first item in each table is input buffer length, even multiple of 8
+ * second item in each table is input buffer length, > 8
+ * third item in each table is input buffer length, < 8
+ *
+ * Revised 02-Apr-97, Chr. Spieler, based on Rodney Brown (rdb(a)cmutual.com.au)
+ * Incorporated Rodney Brown's 32-bit-reads optimization as found in the
+ * UNIX AS source crc_i386.S. This new code can be disabled by defining
+ * the macro symbol NO_32_BIT_LOADS.
+ *
+ * Revised 12-Oct-97, Chr. Spieler, based on Rodney Brown (rdb(a)cmutual.com.au)
+ * Incorporated Rodney Brown's additional tweaks for 32-bit-optimized CPUs
+ * (like the Pentium Pro, Pentium II, and probably some Pentium clones).
+ * This optimization is controlled by the macro symbol __686 and is disabled
+ * by default. (This default is based on the assumption that most users
+ * do not yet work on a Pentium Pro or Pentium II machine ...)
+ *
+ * Revised 16-Nov-97, Chr. Spieler: Made code compatible with Borland C++
+ * 32-bit, removed unneeded kludge for potentially unknown movzx mnemonic,
+ * confirmed correct working with MS VC++ (32-bit).
+ *
+ * Revised 22-May-98, Peter Kunath, Chr. Spieler: The 16-Nov-97 revision broke
+ * MSVC 5.0. Inside preprocessor macros, each instruction is enclosed in its
+ * own __asm {...} construct. For MSVC, a "#pragma warning" was added to
+ * shut up the "no return value" warning message.
+ *
+ * Revised 13-Dec-98, Chr. Spieler: Modified path to "zip.h" header file.
+ *
+ * Revised 16-Jan-2005, Cosmin Truta: Added the ASM_CRC guard, for easier
+ * switching between ASM vs. non-ASM builds, when handling makefiles.
+ * Also enabled the 686 build by default, because there are hardly any
+ * pre-686 CPUs in serious use nowadays. (See the 12-Oct-97 note above.)
+ *
+ * FLAT memory model assumed.
+ *
+ * Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
+ * This results in shorter code at the expense of reduced performance.
+ *
+ */
+
+#include "../zip.h"
+
+#if defined(ASM_CRC) && !defined(USE_ZLIB)
+
+#if !defined(PRE_686) && !defined(__686)
+# define __686
+#endif
+
+#ifndef ZCONST
+# define ZCONST const
+#endif
+
+/* Select wether the following inline-assember code is supported. */
+#if (defined(_MSC_VER) && _MSC_VER >= 700)
+#if (defined(_M_IX86) && _M_IX86 >= 300)
+# define MSC_INLINE_ASM_32BIT_SUPPORT
+ /* Disable warning for no return value, typical of asm functions */
+# pragma warning( disable : 4035 )
+#endif
+#endif
+
+#if (defined(__BORLANDC__) && __BORLANDC__ >= 452)
+# define MSC_INLINE_ASM_32BIT_SUPPORT
+#endif
+
+#ifdef MSC_INLINE_ASM_32BIT_SUPPORT
+/* This code is intended for Microsoft C/C++ (32-bit) compatible compilers. */
+
+/*
+ * These two (three) macros make up the loop body of the CRC32 cruncher.
+ * registers modified:
+ * eax : crc value "c"
+ * esi : pointer to next data byte (or dword) "buf++"
+ * registers read:
+ * edi : pointer to base of crc_table array
+ * scratch registers:
+ * ebx : index into crc_table array
+ * (requires upper three bytes = 0 when __686 is undefined)
+ */
+#ifndef __686
+#define Do_CRC { \
+ __asm { mov bl, al }; \
+ __asm { shr eax, 8 }; \
+ __asm { xor eax, [edi+ebx*4] }; }
+#else /* __686 */
+#define Do_CRC { \
+ __asm { movzx ebx, al }; \
+ __asm { shr eax, 8 }; \
+ __asm { xor eax, [edi+ebx*4] }; }
+#endif /* ?__686 */
+
+#define Do_CRC_byte { \
+ __asm { xor al, byte ptr [esi] }; \
+ __asm { inc esi }; \
+ Do_CRC; }
+
+#ifndef NO_32_BIT_LOADS
+#define Do_CRC_dword { \
+ __asm { xor eax, dword ptr [esi] }; \
+ __asm { add esi, 4 }; \
+ Do_CRC; \
+ Do_CRC; \
+ Do_CRC; \
+ Do_CRC; }
+#endif /* !NO_32_BIT_LOADS */
+
+/* ========================================================================= */
+ulg crc32(crc, buf, len)
+ ulg crc; /* crc shift register */
+ ZCONST uch *buf; /* pointer to bytes to pump through */
+ extent len; /* number of bytes in buf[] */
+/* Run a set of bytes through the crc shift register. If buf is a NULL
+ pointer, then initialize the crc shift register contents instead.
+ Return the current crc in either case. */
+{
+ __asm {
+ push edx
+ push ecx
+
+ mov esi,buf ;/* 2nd arg: uch *buf */
+ sub eax,eax ;/*> if (!buf) */
+ test esi,esi ;/*> return 0; */
+ jz fine ;/*> else { */
+
+ call get_crc_table
+ mov edi,eax
+ mov eax,crc ;/* 1st arg: ulg crc */
+#ifndef __686
+ sub ebx,ebx ;/* ebx=0; => bl usable as a dword */
+#endif
+ mov ecx,len ;/* 3rd arg: extent len */
+ not eax ;/*> c = ~crc; */
+
+ test ecx,ecx
+#ifndef NO_UNROLLED_LOOPS
+ jz bail
+# ifndef NO_32_BIT_LOADS
+align_loop:
+ test esi,3 ;/* align buf pointer on next */
+ jz aligned_now ;/* dword boundary */
+ }
+ Do_CRC_byte ;
+ __asm {
+ dec ecx
+ jnz align_loop
+aligned_now:
+# endif /* !NO_32_BIT_LOADS */
+ mov edx,ecx ;/* save len in edx */
+ shr ecx,3 ;/* ecx = len / 8 */
+ jz No_Eights
+; align loop head at start of 486 internal cache line !!
+ align 16
+Next_Eight:
+ }
+# ifndef NO_32_BIT_LOADS
+ Do_CRC_dword ;
+ Do_CRC_dword ;
+# else /* NO_32_BIT_LOADS */
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+ Do_CRC_byte ;
+# endif /* ?NO_32_BIT_LOADS */
+ __asm {
+ dec ecx
+ jnz Next_Eight
+No_Eights:
+ mov ecx,edx
+ and ecx,000000007H ;/* ecx = len % 8 */
+
+#endif /* !NO_UNROLLED_LOOPS */
+ jz bail ;/*> if (len) */
+; align loop head at start of 486 internal cache line !!
+ align 16
+loupe: ;/*> do { */
+ }
+ Do_CRC_byte ;/* c = CRC32(c, *buf++); */
+ __asm {
+ dec ecx ;/*> } while (--len); */
+ jnz loupe
+
+bail: ;/*> } */
+ not eax ;/*> return ~c; */
+fine:
+ pop ecx
+ pop edx
+ }
+#ifdef NEED_RETURN
+ return _EAX;
+#endif
+}
+#endif /* MSC_INLINE_ASM_32BIT_SUPPORT */
+#if (defined(_MSC_VER) && _MSC_VER >= 700)
+#if (defined(_M_IX86) && _M_IX86 >= 300)
+ /* Reenable missing return value warning */
+# pragma warning( default : 4035 )
+#endif
+#endif
+#endif /* ASM_CRC && !USE_ZLIB */
Property changes on: trunk/build/install/installer/win32/crc_i386.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/win32/crc_lcc.asm
===================================================================
--- trunk/build/install/installer/win32/crc_lcc.asm (rev 0)
+++ trunk/build/install/installer/win32/crc_lcc.asm 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,119 @@
+;===========================================================================
+; Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 2000-Apr-09 or later
+; (the contents of which are also included in zip.h) for terms of use.
+; If, for some reason, all these files are missing, the Info-ZIP license
+; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+;===========================================================================
+; crc_lcc.asm, optimized CRC calculation function for Zip and UnZip,
+; created by Paul Kienitz and Christian Spieler. Last revised 24 Dec 98.
+;
+; The code in this file has been copied verbatim from crc_i386.{asm|S};
+; only the assembler syntax and metacommands have been adapted to
+; the habits of the free LCC-Win32 C compiler package.
+; This version of the code uses the "optimized for i686" variant of
+; crc_i386.{asm|S}.
+; IMPORTANT NOTE to the Info-ZIP editors:
+; The TAB characters in this source file are required by the parser of
+; the LCC-Win32 assembler program and MUST NOT be removed!!
+;
+; For more information (and a revision log), look into the original
+; source files.
+;
+ .text
+ .file "crc32.c"
+ .text
+ .type _crc32,function
+_crc32:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ecx
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ .line 34
+ .line 37
+ movl 12(%ebp),%esi
+ subl %eax,%eax
+ testl %esi,%esi
+ jz _$3
+ .line 39
+ call _get_crc_table
+ movl %eax,%edi
+ .line 41
+ movl 8(%ebp),%eax
+ movl 16(%ebp),%ecx
+ notl %eax
+ testl %ecx,%ecx
+ jz _$4
+_$5:
+ testl $3,%esi
+ jz _$6
+ xorb (%esi),%al
+ incl %esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ decl %ecx
+ jnz _$5
+_$6:
+ movl %ecx,%edx
+ shrl $3,%ecx
+ jz _$8
+_$7:
+ xorl (%esi),%eax
+ addl $4,%esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ xorl (%esi),%eax
+ addl $4,%esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ decl %ecx
+ jnz _$7
+_$8:
+ movl %edx,%ecx
+ andl $7,%ecx
+ jz _$4
+_$9:
+ xorb (%esi),%al
+ incl %esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ decl %ecx
+ jnz _$9
+_$4:
+ xorl $0xffffffff,%eax
+_$3:
+ .line 52
+ popl %edi
+ popl %esi
+ popl %ebx
+ leave
+ ret
+_$34:
+ .size _crc32,_$34-_crc32
+ .globl _crc32
+ .extern _get_crc_table
Added: trunk/build/install/installer/win32/nt.c
===================================================================
--- trunk/build/install/installer/win32/nt.c (rev 0)
+++ trunk/build/install/installer/win32/nt.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,539 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+
+ Copyright (c) 1996 Scott Field (dedicated to Info-Zip group)
+
+ Module Name:
+
+ nt.c
+
+ Abstract:
+
+ This module implements WinNT security descriptor operations for the
+ Win32 Info-ZIP project. Operation such as setting file security,
+ using/querying local and remote privileges, and queuing of operations
+ is performed here. The contents of this module are only relevant
+ when the code is running on Windows NT, and the target volume supports
+ persistent Acl storage.
+
+ User privileges that allow accessing certain privileged aspects of the
+ security descriptor (such as the Sacl) are only used if the user specified
+ to do so.
+
+ Author:
+
+ Scott Field (sfield(a)microsoft.com)
+
+ Last revised: 18 Jan 97
+
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#define UNZIP_INTERNAL
+#include "../unzip.h"
+#include <windows.h>
+#ifdef __RSXNT__
+# include "../win32/rsxntwin.h"
+#endif
+#include "../win32/nt.h"
+
+
+#ifdef NTSD_EAS /* This file is only needed for NTSD handling */
+
+/* Borland C++ does not define FILE_SHARE_DELETE. Others also? */
+#ifndef FILE_SHARE_DELETE
+# define FILE_SHARE_DELETE 0x00000004
+#endif
+
+
+/* private prototypes */
+
+static BOOL Initialize(VOID);
+static VOID GetRemotePrivilegesSet(CHAR *FileName, PDWORD dwRemotePrivileges);
+static VOID InitLocalPrivileges(VOID);
+
+
+BOOL bInitialized = FALSE; /* module level stuff initialized? */
+HANDLE hInitMutex = NULL; /* prevent multiple initialization */
+
+BOOL g_bRestorePrivilege = FALSE; /* for local set file security override */
+BOOL g_bSaclPrivilege = FALSE; /* for local set sacl operations, only when
+ restore privilege not present */
+
+/* our single cached volume capabilities structure that describes the last
+ volume root we encountered. A single entry like this works well in the
+ zip/unzip scenario for a number of reasons:
+ 1. typically one extraction path during unzip.
+ 2. typically process one volume at a time during zip, and then move
+ on to the next.
+ 3. no cleanup code required and no memory leaks.
+ 4. simple code.
+
+ This approach should be reworked to a linked list approach if we expect to
+ be called by many threads which are processing a variety of input/output
+ volumes, since lock contention and stale data may become a bottleneck. */
+
+VOLUMECAPS g_VolumeCaps;
+CRITICAL_SECTION VolumeCapsLock;
+
+
+static BOOL Initialize(VOID)
+{
+ HANDLE hMutex;
+ HANDLE hOldMutex;
+
+ if(bInitialized) return TRUE;
+
+ hMutex = CreateMutex(NULL, TRUE, NULL);
+ if(hMutex == NULL) return FALSE;
+
+ hOldMutex = (HANDLE)InterlockedExchange((LPLONG)&hInitMutex, (LONG)hMutex);
+
+ if(hOldMutex != NULL) {
+ /* somebody setup the mutex already */
+ InterlockedExchange((LPLONG)&hInitMutex, (LONG)hOldMutex);
+
+ CloseHandle(hMutex); /* close new, un-needed mutex */
+
+ /* wait for initialization to complete and return status */
+ WaitForSingleObject(hOldMutex, INFINITE);
+ ReleaseMutex(hOldMutex);
+
+ return bInitialized;
+ }
+
+ /* initialize module level resources */
+
+ InitializeCriticalSection( &VolumeCapsLock );
+ memset(&g_VolumeCaps, 0, sizeof(VOLUMECAPS));
+
+ InitLocalPrivileges();
+
+ bInitialized = TRUE;
+
+ ReleaseMutex(hMutex); /* release correct mutex */
+
+ return TRUE;
+}
+
+
+BOOL ValidateSecurity(uch *securitydata)
+{
+ PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)securitydata;
+ PACL pAcl;
+ PSID pSid;
+ BOOL bAclPresent;
+ BOOL bDefaulted;
+
+ if(!IsWinNT()) return TRUE; /* don't do anything if not on WinNT */
+
+ if(!IsValidSecurityDescriptor(sd)) return FALSE;
+
+ /* verify Dacl integrity */
+
+ if(!GetSecurityDescriptorDacl(sd, &bAclPresent, &pAcl, &bDefaulted))
+ return FALSE;
+
+ if(bAclPresent) {
+ if(!IsValidAcl(pAcl)) return FALSE;
+ }
+
+ /* verify Sacl integrity */
+
+ if(!GetSecurityDescriptorSacl(sd, &bAclPresent, &pAcl, &bDefaulted))
+ return FALSE;
+
+ if(bAclPresent) {
+ if(!IsValidAcl(pAcl)) return FALSE;
+ }
+
+ /* verify owner integrity */
+
+ if(!GetSecurityDescriptorOwner(sd, &pSid, &bDefaulted))
+ return FALSE;
+
+ if(pSid != NULL) {
+ if(!IsValidSid(pSid)) return FALSE;
+ }
+
+ /* verify group integrity */
+
+ if(!GetSecurityDescriptorGroup(sd, &pSid, &bDefaulted))
+ return FALSE;
+
+ if(pSid != NULL) {
+ if(!IsValidSid(pSid)) return FALSE;
+ }
+
+ return TRUE;
+}
+
+static VOID GetRemotePrivilegesSet(char *FileName, PDWORD dwRemotePrivileges)
+{
+ HANDLE hFile;
+
+ *dwRemotePrivileges = 0;
+
+ /* see if we have the SeRestorePrivilege */
+
+ hFile = CreateFileA(
+ FileName,
+ ACCESS_SYSTEM_SECURITY | WRITE_DAC | WRITE_OWNER | READ_CONTROL,
+ FILE_SHARE_READ | FILE_SHARE_DELETE, /* no sd updating allowed here */
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+
+ if(hFile != INVALID_HANDLE_VALUE) {
+ /* no remote way to determine SeRestorePrivilege -- just try a
+ read/write to simulate it */
+ SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION |
+ SACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION;
+ PSECURITY_DESCRIPTOR sd;
+ DWORD cbBuf = 0;
+
+ GetKernelObjectSecurity(hFile, si, NULL, cbBuf, &cbBuf);
+
+ if(ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
+ if((sd = HeapAlloc(GetProcessHeap(), 0, cbBuf)) != NULL) {
+ if(GetKernelObjectSecurity(hFile, si, sd, cbBuf, &cbBuf)) {
+ if(SetKernelObjectSecurity(hFile, si, sd))
+ *dwRemotePrivileges |= OVERRIDE_RESTORE;
+ }
+ HeapFree(GetProcessHeap(), 0, sd);
+ }
+ }
+
+ CloseHandle(hFile);
+ } else {
+
+ /* see if we have the SeSecurityPrivilege */
+ /* note we don't need this if we have SeRestorePrivilege */
+
+ hFile = CreateFileA(
+ FileName,
+ ACCESS_SYSTEM_SECURITY,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* max */
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL
+ );
+
+ if(hFile != INVALID_HANDLE_VALUE) {
+ CloseHandle(hFile);
+ *dwRemotePrivileges |= OVERRIDE_SACL;
+ }
+ }
+}
+
+
+BOOL GetVolumeCaps(
+ char *rootpath, /* filepath, or NULL */
+ char *name, /* filename associated with rootpath */
+ PVOLUMECAPS VolumeCaps /* result structure describing capabilities */
+ )
+{
+ char TempRootPath[MAX_PATH + 1];
+ DWORD cchTempRootPath = 0;
+ BOOL bSuccess = TRUE; /* assume success until told otherwise */
+
+ if(!bInitialized) if(!Initialize()) return FALSE;
+
+ /* process the input path to produce a consistent path suitable for
+ compare operations and also suitable for certain picky Win32 API
+ that don't like forward slashes */
+
+ if(rootpath != NULL && rootpath[0] != '\0') {
+ DWORD i;
+
+ cchTempRootPath = lstrlen(rootpath);
+ if(cchTempRootPath > MAX_PATH) return FALSE;
+
+ /* copy input, converting forward slashes to back slashes as we go */
+
+ for(i = 0 ; i <= cchTempRootPath ; i++) {
+ if(rootpath[i] == '/') TempRootPath[i] = '\\';
+ else TempRootPath[i] = rootpath[i];
+ }
+
+ /* check for UNC and Null terminate or append trailing \ as
+ appropriate */
+
+ /* possible valid UNCs we are passed follow:
+ \\machine\foo\bar (path is \\machine\foo\)
+ \\machine\foo (path is \\machine\foo\)
+ \\machine\foo\
+ \\.\c$\ (FIXFIX: Win32API doesn't like this - GetComputerName())
+ LATERLATER: handling mounted DFS drives in the future will require
+ slightly different logic which isn't available today.
+ This is required because directories can point at
+ different servers which have differing capabilities.
+ */
+
+ if(TempRootPath[0] == '\\' && TempRootPath[1] == '\\') {
+ DWORD slash = 0;
+
+ for(i = 2 ; i < cchTempRootPath ; i++) {
+ if(TempRootPath[i] == '\\') {
+ slash++;
+
+ if(slash == 2) {
+ i++;
+ TempRootPath[i] = '\0';
+ cchTempRootPath = i;
+ break;
+ }
+ }
+ }
+
+ /* if there was only one slash found, just tack another onto the
+ end */
+
+ if(slash == 1 && TempRootPath[cchTempRootPath] != '\\') {
+ TempRootPath[cchTempRootPath] = TempRootPath[0]; /* '\\' */
+ TempRootPath[cchTempRootPath+1] = '\0';
+ cchTempRootPath++;
+ }
+
+ } else {
+
+ if(TempRootPath[1] == ':') {
+
+ /* drive letter specified, truncate to root */
+ TempRootPath[2] = '\\';
+ TempRootPath[3] = '\0';
+ cchTempRootPath = 3;
+ } else {
+
+ /* must be file on current drive */
+ TempRootPath[0] = '\0';
+ cchTempRootPath = 0;
+ }
+
+ }
+
+ } /* if path != NULL */
+
+ /* grab lock protecting cached entry */
+ EnterCriticalSection( &VolumeCapsLock );
+
+ if(!g_VolumeCaps.bValid ||
+ lstrcmpi(g_VolumeCaps.RootPath, TempRootPath) != 0)
+ {
+
+ /* no match found, build up new entry */
+
+ DWORD dwFileSystemFlags;
+ DWORD dwRemotePrivileges = 0;
+ BOOL bRemote = FALSE;
+
+ /* release lock during expensive operations */
+ LeaveCriticalSection( &VolumeCapsLock );
+
+ bSuccess = GetVolumeInformation(
+ (TempRootPath[0] == '\0') ? NULL : TempRootPath,
+ NULL, 0,
+ NULL, NULL,
+ &dwFileSystemFlags,
+ NULL, 0);
+
+
+ /* only if target volume supports Acls, and we were told to use
+ privileges do we need to go out and test for the remote case */
+
+ if(bSuccess && (dwFileSystemFlags & FS_PERSISTENT_ACLS) &&
+ VolumeCaps->bUsePrivileges)
+ {
+ if(GetDriveType( (TempRootPath[0] == '\0') ? NULL : TempRootPath )
+ == DRIVE_REMOTE)
+ {
+ bRemote = TRUE;
+
+ /* make a determination about our remote capabilities */
+
+ GetRemotePrivilegesSet(name, &dwRemotePrivileges);
+ }
+ }
+
+ /* always take the lock again, since we release it below */
+ EnterCriticalSection( &VolumeCapsLock );
+
+ /* replace the existing data if successful */
+ if(bSuccess) {
+
+ lstrcpynA(g_VolumeCaps.RootPath, TempRootPath, cchTempRootPath+1);
+ g_VolumeCaps.dwFileSystemFlags = dwFileSystemFlags;
+ g_VolumeCaps.bRemote = bRemote;
+ g_VolumeCaps.dwRemotePrivileges = dwRemotePrivileges;
+ g_VolumeCaps.bValid = TRUE;
+ }
+ }
+
+ if(bSuccess) {
+ /* copy input elements */
+ g_VolumeCaps.bUsePrivileges = VolumeCaps->bUsePrivileges;
+ g_VolumeCaps.dwFileAttributes = VolumeCaps->dwFileAttributes;
+
+ /* give caller results */
+ memcpy(VolumeCaps, &g_VolumeCaps, sizeof(VOLUMECAPS));
+ } else {
+ g_VolumeCaps.bValid = FALSE;
+ }
+
+ LeaveCriticalSection( &VolumeCapsLock ); /* release lock */
+
+ return bSuccess;
+}
+
+
+BOOL SecuritySet(char *resource, PVOLUMECAPS VolumeCaps, uch *securitydata)
+{
+ HANDLE hFile;
+ DWORD dwDesiredAccess = 0;
+ DWORD dwFlags = 0;
+ PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)securitydata;
+ SECURITY_DESCRIPTOR_CONTROL sdc;
+ SECURITY_INFORMATION RequestedInfo = 0;
+ DWORD dwRev;
+ BOOL bRestorePrivilege = FALSE;
+ BOOL bSaclPrivilege = FALSE;
+ BOOL bSuccess;
+
+ if(!bInitialized) if(!Initialize()) return FALSE;
+
+ /* defer directory processing */
+
+ if(VolumeCaps->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ /* opening a directory requires FILE_FLAG_BACKUP_SEMANTICS */
+ dwFlags |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+
+ /* evaluate the input security descriptor and act accordingly */
+
+ if(!IsValidSecurityDescriptor(sd))
+ return FALSE;
+
+ if(!GetSecurityDescriptorControl(sd, &sdc, &dwRev))
+ return FALSE;
+
+ /* setup privilege usage based on if told we can use privileges, and if so,
+ what privileges we have */
+
+ if(VolumeCaps->bUsePrivileges) {
+ if(VolumeCaps->bRemote) {
+ /* use remotely determined privileges */
+ if(VolumeCaps->dwRemotePrivileges & OVERRIDE_RESTORE)
+ bRestorePrivilege = TRUE;
+
+ if(VolumeCaps->dwRemotePrivileges & OVERRIDE_SACL)
+ bSaclPrivilege = TRUE;
+
+ } else {
+ /* use local privileges */
+ bRestorePrivilege = g_bRestorePrivilege;
+ bSaclPrivilege = g_bSaclPrivilege;
+ }
+ }
+
+
+ /* if a Dacl is present write Dacl out */
+ /* if we have SeRestorePrivilege, write owner and group info out */
+
+ if(sdc & SE_DACL_PRESENT) {
+ dwDesiredAccess |= WRITE_DAC;
+ RequestedInfo |= DACL_SECURITY_INFORMATION;
+
+ if(bRestorePrivilege) {
+ dwDesiredAccess |= WRITE_OWNER;
+ RequestedInfo |= (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION);
+ }
+ }
+
+ /* if a Sacl is present and we have either SeRestorePrivilege or
+ SeSystemSecurityPrivilege try to write Sacl out */
+
+ if((sdc & SE_SACL_PRESENT) && (bRestorePrivilege || bSaclPrivilege)) {
+ dwDesiredAccess |= ACCESS_SYSTEM_SECURITY;
+ RequestedInfo |= SACL_SECURITY_INFORMATION;
+ }
+
+ if(RequestedInfo == 0) /* nothing to do */
+ return FALSE;
+
+ if(bRestorePrivilege)
+ dwFlags |= FILE_FLAG_BACKUP_SEMANTICS;
+
+ hFile = CreateFileA(
+ resource,
+ dwDesiredAccess,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,/* max sharing */
+ NULL,
+ OPEN_EXISTING,
+ dwFlags,
+ NULL
+ );
+
+ if(hFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ bSuccess = SetKernelObjectSecurity(hFile, RequestedInfo, sd);
+
+ CloseHandle(hFile);
+
+ return bSuccess;
+}
+
+static VOID InitLocalPrivileges(VOID)
+{
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tp;
+
+ /* try to enable some interesting privileges that give us the ability
+ to get some security information that we normally cannot.
+
+ note that enabling privileges is only relevant on the local machine;
+ when accessing files that are on a remote machine, any privileges
+ that are present on the remote machine get enabled by default. */
+
+ if(!OpenProcessToken(GetCurrentProcess(),
+ TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
+ return;
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if(LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid)) {
+
+ /* try to enable SeRestorePrivilege; if this succeeds, we can write
+ all aspects of the security descriptor */
+
+ if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) &&
+ GetLastError() == ERROR_SUCCESS) g_bRestorePrivilege = TRUE;
+
+ }
+
+ /* try to enable SeSystemSecurityPrivilege, if SeRestorePrivilege not
+ present; if this succeeds, we can write the Sacl */
+
+ if(!g_bRestorePrivilege &&
+ LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tp.Privileges[0].Luid)) {
+
+ if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) &&
+ GetLastError() == ERROR_SUCCESS) g_bSaclPrivilege = TRUE;
+ }
+
+ CloseHandle(hToken);
+}
+#endif /* NTSD_EAS */
Property changes on: trunk/build/install/installer/win32/nt.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/win32/nt.h
===================================================================
--- trunk/build/install/installer/win32/nt.h (rev 0)
+++ trunk/build/install/installer/win32/nt.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,33 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* nt.h: central header for EF_NTSD "SD" extra field */
+
+#ifndef _NT_H
+#define _NT_H
+
+#define NTSD_BUFFERSIZE (1024) /* threshold to cause malloc() */
+#define OVERRIDE_BACKUP 1 /* we have SeBackupPrivilege on remote */
+#define OVERRIDE_RESTORE 2 /* we have SeRestorePrivilege on remote */
+#define OVERRIDE_SACL 4 /* we have SeSystemSecurityPrivilege on remote */
+
+typedef struct {
+ BOOL bValid; /* are our contents valid? */
+ BOOL bUsePrivileges; /* use privilege overrides? */
+ DWORD dwFileSystemFlags; /* describes target file system */
+ BOOL bRemote; /* is volume remote? */
+ DWORD dwRemotePrivileges; /* relevant only on remote volumes */
+ DWORD dwFileAttributes;
+ char RootPath[MAX_PATH+1]; /* path to network / filesystem */
+} VOLUMECAPS, *PVOLUMECAPS, *LPVOLUMECAPS;
+
+BOOL SecuritySet(char *resource, PVOLUMECAPS VolumeCaps, uch *securitydata);
+BOOL GetVolumeCaps(char *rootpath, char *name, PVOLUMECAPS VolumeCaps);
+BOOL ValidateSecurity(uch *securitydata);
+
+#endif /* _NT_H */
Property changes on: trunk/build/install/installer/win32/nt.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/win32/w32cfg.h
===================================================================
--- trunk/build/install/installer/win32/w32cfg.h (rev 0)
+++ trunk/build/install/installer/win32/w32cfg.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,372 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+ Win32 specific configuration section:
+ ---------------------------------------------------------------------------*/
+
+#ifndef __w32cfg_h
+#define __w32cfg_h
+
+#ifdef __CYGWIN__
+/* We treat the file system underneath the Cygwin Unix emulator environment
+ * as "native VFAT/NTFS" and use the WIN32 API for its special attributes...
+ */
+# ifdef UNIX
+# undef UNIX
+# endif
+#endif
+
+#if (defined(_MSC_VER) && !defined(MSC))
+# define MSC
+#endif
+
+/* enable multibyte character set support by default */
+#ifndef _MBCS
+# define _MBCS
+#endif
+#if (defined(__CYGWIN__) && defined(_MBCS))
+# undef _MBCS /* Cygwin RTL lacks support for __mb_cur_max */
+#endif
+#if (defined(__DJGPP__) && !defined(__EMX__) && defined(_MBCS))
+# undef _MBCS /* __mb_cur_max missing for RSXNTdj 1.6 beta */
+#endif
+
+#include <sys/types.h> /* off_t, time_t, dev_t, ... */
+#include <sys/stat.h>
+#include <io.h> /* read(), open(), etc. */
+#include <time.h>
+#if ((defined(__RSXNT__) || defined(__EMX__)) && !defined(tzset))
+# define tzset _tzset
+#endif
+#if (defined(__LCC__) && !defined(tzset))
+# define tzset _tzset
+#endif
+#ifdef __MINGW32__
+ extern void _tzset(void); /* this is missing in <time.h> */
+# ifndef tzset
+# define tzset _tzset
+# endif
+#endif
+#ifdef W32_USE_IZ_TIMEZONE
+# ifdef __BORLANDC__
+# define tzname tzname
+# define IZTZ_DEFINESTDGLOBALS
+# endif
+# ifdef __WATCOMC__
+# define IZTZ_DEFINESTDGLOBALS
+# endif
+# ifndef tzset
+# define tzset _tzset
+# endif
+# ifndef timezone
+# define timezone _timezone
+# endif
+# ifndef daylight
+# define daylight _daylight
+# endif
+# ifndef tzname
+# define tzname _tzname
+# endif
+# if (!defined(NEED__ISINDST) && !defined(__BORLANDC__))
+# define NEED__ISINDST
+# endif
+# ifdef IZTZ_GETLOCALETZINFO
+# undef IZTZ_GETLOCALETZINFO
+# endif
+# define IZTZ_GETLOCALETZINFO GetPlatformLocalTimezone
+#endif /* W32_USE_IZ_TIMEZONE */
+#include <memory.h>
+#if (!defined(__RSXNT__) && !defined(__CYGWIN__))
+# include <direct.h> /* mkdir() */
+#endif
+#include <fcntl.h>
+#ifdef __CYGWIN__
+# include <unistd.h>
+ extern int setmode(int, int); /* this is missing in <fcntl.h> */
+#endif
+#if (defined(MSC) || defined(__WATCOMC__) || defined(__MINGW32__))
+# include <sys/utime.h>
+#else
+# include <utime.h>
+#endif
+#define GOT_UTIMBUF
+
+#ifdef _MBCS
+# if (!defined(__EMX__) && !defined(__MINGW32__) && !defined(__CYGWIN__))
+# if (!defined(__DJGPP__))
+# include <stdlib.h>
+# include <mbstring.h>
+ /* for MSC (and compatible compilers), use routines supplied by RTL */
+# define PREINCSTR(ptr) (ptr = (char *)_mbsinc((const uch *)(ptr)))
+# define MBSCHR(str, c) (char *)_mbschr((const uch *)(str), (c))
+# define MBSRCHR(str, c) (char *)_mbsrchr((const uch *)(str), (c))
+# endif
+# endif
+# if (defined(__MINGW32__) && !defined(MB_CUR_MAX))
+# ifdef __MSVCRT__
+ extern int *__p___mb_cur_max(void);
+# define MB_CUR_MAX (*__p___mb_cur_max())
+# else
+ extern int *_imp____mb_cur_max_dll;
+# define MB_CUR_MAX (*_imp____mb_cur_max_dll)
+# endif
+# endif
+# if (defined(__LCC__) && !defined(MB_CUR_MAX))
+ extern int *_imp____mb_cur_max;
+# define MB_CUR_MAX (*_imp____mb_cur_max)
+# endif
+# if (defined(__DJGPP__) && !defined(__EMX__) && !defined(MB_CUR_MAX))
+ extern int *_imp____mb_cur_max;
+# define MB_CUR_MAX (*_imp____mb_cur_max)
+# endif
+#endif
+
+/* for UnZip, the "basic" part of the win32 api is sufficient */
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#if defined(__FILEIO_C)
+# ifndef __CYGWIN__
+# include <conio.h>
+# endif
+# include <windows.h>
+# ifdef __RSXNT__
+# include "../win32/rsxntwin.h"
+# endif
+# ifndef TIME_ZONE_ID_INVALID
+# define TIME_ZONE_ID_INVALID (DWORD)0xFFFFFFFFL
+# endif
+#endif
+#if (defined(__ENVARGS_C) || defined(__EXTRACT_C) || defined(__UNZIP_C) || \
+ defined(ZCRYPT_INTERNAL))
+# include <windows.h>
+# ifdef __RSXNT__
+# include "../win32/rsxntwin.h"
+# endif
+# ifndef TIME_ZONE_ID_INVALID
+# define TIME_ZONE_ID_INVALID (DWORD)0xFFFFFFFFL
+# endif
+#endif
+
+#ifndef Cdecl
+# define Cdecl __cdecl
+#endif
+
+/* the following definitions are considered as "obsolete" by Microsoft and
+ * might be missing in some versions of <windows.h>
+ */
+#ifndef AnsiToOem
+# define AnsiToOem CharToOemA
+#endif
+#ifndef OemToAnsi
+# define OemToAnsi OemToCharA
+#endif
+
+#define DIR_END '\\' /* OS uses '\\' as directory separator */
+#define DIR_END2 '/' /* also check for '/' (RTL may convert) */
+#ifdef DATE_FORMAT
+# undef DATE_FORMAT
+#endif
+#define DATE_FORMAT dateformat()
+#ifdef DATE_SEPCHAR
+# undef DATE_SEPCHAR
+#endif
+#define DATE_SEPCHAR dateseparator()
+#define lenEOL 2
+#define PutNativeEOL {*q++ = native(CR); *q++ = native(LF);}
+
+#if (defined(__RSXNT__) && !defined(HAVE_MKTIME))
+# define HAVE_MKTIME /* use mktime() in time conversion routines */
+#endif
+#if (defined(MSC) && !defined(HAVE_MKTIME))
+# define HAVE_MKTIME /* use mktime() in time conversion routines */
+#endif
+#if (defined(__CYGWIN__) && defined(HAVE_MKTIME))
+# undef HAVE_MKTIME /* Cygnus' mktime() implementation is buggy */
+#endif
+#if (defined(W32_USE_IZ_TIMEZONE) && !defined(HAVE_MKTIME))
+# define HAVE_MKTIME /* use mktime() in time conversion routines */
+#endif
+#if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME))
+# define USE_EF_UT_TIME
+#endif
+#if (!defined(NO_DIR_ATTRIB) && !defined(SET_DIR_ATTRIB))
+# define SET_DIR_ATTRIB
+#endif
+#if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP))
+# define TIMESTAMP
+#endif
+#if (!defined(NO_NTSD_EAS) && !defined(NTSD_EAS))
+# define NTSD_EAS /* enable NTSD support unless explicitly suppressed */
+#endif
+#if (defined(NTSD_EAS) && !defined(RESTORE_ACL))
+# define RESTORE_ACL /* "restore ACLs" only needed when NTSD_EAS active */
+#endif
+
+/* handlers for OEM <--> ANSI string conversions */
+#ifdef __RSXNT__
+ /* RSXNT uses OEM coded strings in functions supplied by C RTL */
+# ifdef CRTL_CP_IS_ISO
+# undef CRTL_CP_IS_ISO
+# endif
+# ifndef CRTL_CP_IS_OEM
+# define CRTL_CP_IS_OEM
+# endif
+#else
+ /* "real" native WIN32 compilers use ANSI coded strings in C RTL calls */
+# ifndef CRTL_CP_IS_ISO
+# define CRTL_CP_IS_ISO
+# endif
+# ifdef CRTL_CP_IS_OEM
+# undef CRTL_CP_IS_OEM
+# endif
+#endif
+
+#ifdef CRTL_CP_IS_ISO
+ /* C RTL's file system support assumes ANSI coded strings */
+# define ISO_TO_INTERN(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define OEM_TO_INTERN(src, dst) OemToAnsi(src, dst)
+# define INTERN_TO_ISO(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define INTERN_TO_OEM(src, dst) AnsiToOem(src, dst)
+#endif /* CRTL_CP_IS_ISO */
+#ifdef CRTL_CP_IS_OEM
+ /* C RTL's file system support assumes OEM coded strings */
+# define ISO_TO_INTERN(src, dst) AnsiToOem(src, dst)
+# define OEM_TO_INTERN(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define INTERN_TO_ISO(src, dst) OemToAnsi(src, dst)
+# define INTERN_TO_OEM(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+#endif /* CRTL_CP_IS_OEM */
+#define _OEM_INTERN(str1) OEM_TO_INTERN(str1, str1)
+#define _ISO_INTERN(str1) ISO_TO_INTERN(str1, str1)
+#ifndef WINDLL
+ /* Despite best intentions, for the command-line version UzpPassword()
+ * could return either character set, depending on whether running under
+ * Win95 (DOS-session) or WinNT (native WinNT command interpreter)! */
+# define STR_TO_CP2(dst, src) (AnsiToOem(src, dst), dst)
+# define STR_TO_CP3(dst, src) (OemToAnsi(src, dst), dst)
+#else
+ /* The WINDLL front end is known to supply ISO/ANSI-coded passwords! */
+# define STR_TO_CP2(dst, src) (AnsiToOem(src, dst), dst)
+#endif
+/* dummy defines to disable these functions, they are not needed */
+#define STR_TO_OEM
+#define STR_TO_ISO
+
+/* Static variables that we have to add to Uz_Globs: */
+#define SYSTEM_SPECIFIC_GLOBALS \
+ int created_dir, renamed_fullpath, fnlen;\
+ unsigned nLabelDrive;\
+ char lastRootPath[4];\
+ int lastVolOldFAT, lastVolLocTim;\
+ char *rootpath, *buildpathHPFS, *buildpathFAT, *endHPFS, *endFAT;\
+ ZCONST char *wildname;\
+ char *dirname, matchname[FILNAMSIZ];\
+ int rootlen, have_dirname, dirnamelen, notfirstcall;\
+ zvoid *wild_dir;
+
+/* created_dir, renamed_fullpath, fnlen, and nLabelDrive are used by */
+/* both mapname() and checkdir(). */
+/* lastRootPath, lastVolOldFAT and lastVolLocTim are used by */
+/* IsVolumeOldFAT() and NTQueryVolInfo(). */
+/* rootlen, rootpath, buildpathHPFS, buildpathFAT, endHPFS, and endFAT */
+/* are used by checkdir(). */
+/* wild_dir, dirname, wildname, matchname[], dirnamelen, have_dirname, */
+/* and notfirstcall are used by do_wild(). */
+
+/* This replacement for C-RTL-supplied getch() (or similar) functionality
+ * avoids leaving unabsorbed LFs in the keyboard buffer under Windows95,
+ * and supports the <ALT>+[0]<digit><digit><digit> feature.
+ */
+int getch_win32 OF((void));
+
+/* Up to now, all versions of Microsoft C runtime libraries lack the support
+ * for customized (non-US) switching rules between daylight saving time and
+ * standard time in the TZ environment variable string.
+ * But non-US timezone rules are correctly supported when timezone information
+ * is read from the OS system settings in the Win32 registry.
+ * The following work-around deletes any TZ environment setting from
+ * the process environment. This results in a fallback of the RTL time
+ * handling code to the (correctly interpretable) OS system settings, read
+ * from the registry.
+ */
+#ifdef USE_EF_UT_TIME
+# if (defined(__WATCOMC__) || defined(__CYGWIN__) || \
+ defined(W32_USE_IZ_TIMEZONE))
+# define iz_w32_prepareTZenv()
+# else
+# define iz_w32_prepareTZenv() putenv("TZ=")
+# endif
+#endif
+
+/* This patch of stat() is useful for at least two compilers. It is */
+/* difficult to take a stat() of a root directory under Windows95, so */
+/* zstat_win32() detects that case and fills in suitable values. */
+#ifndef __RSXNT__
+# ifndef W32_STATROOT_FIX
+# define W32_STATROOT_FIX
+# endif
+#endif /* !__RSXNT__ */
+
+#define W32_STAT_BANDAID
+#if defined(REENTRANT)
+# define __W32STAT_GLOBALS__ Uz_Globs *pG,
+# define __W32STAT_G__ pG,
+#else
+# define __W32STAT_GLOBALS__
+# define __W32STAT_G__
+#endif
+#ifdef SSTAT
+# undef SSTAT
+#endif
+#ifdef WILD_STAT_BUG
+# define SSTAT(path, pbuf) (iswild(path) || zstat_win32(__W32STAT_G__ path, pbuf))
+#else
+# define SSTAT(path, pbuf) zstat_win32(__W32STAT_G__ path, pbuf)
+#endif
+
+#ifdef __WATCOMC__
+# ifdef __386__
+# ifndef WATCOMC_386
+# define WATCOMC_386
+# endif
+# define __32BIT__
+# undef far
+# define far
+# undef near
+# define near
+# undef Cdecl
+# define Cdecl
+
+/* gaah -- Watcom's docs claim that _get_osfhandle exists, but it doesn't. */
+# define _get_osfhandle _os_handle
+
+/* Get asm routines to link properly without using "__cdecl": */
+# ifndef USE_ZLIB
+# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax]
+# pragma aux get_crc_table "_*" parm caller [] value [eax] \
+ modify [eax ecx edx]
+# endif /* !USE_ZLIB */
+# endif /* __386__ */
+
+# ifndef EPIPE
+# define EPIPE 29 /* Watcom 11.0c(+) errno.h contains this define */
+# endif
+# define PIPE_ERROR (errno == EPIPE)
+#endif /* __WATCOMC__ */
+
+#define SCREENWIDTH 80
+#define SCREENSIZE(scrrows, scrcols) screensize(scrrows, scrcols)
+int screensize(int *tt_rows, int *tt_cols);
+
+/* on the DOS or NT console screen, line-wraps are always enabled */
+#define SCREENLWRAP 1
+#define TABSIZE 8
+
+#endif /* !__w32cfg_h */
Property changes on: trunk/build/install/installer/win32/w32cfg.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/win32/win32.c
===================================================================
--- trunk/build/install/installer/win32/win32.c (rev 0)
+++ trunk/build/install/installer/win32/win32.c 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,2876 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ win32.c
+
+ 32-bit Windows-specific (NT/9x) routines for use with Info-ZIP's UnZip 5.3
+ and later.
+
+ Contains: GetLoadPath()
+ Opendir()
+ Readdir()
+ Closedir()
+ SetSD() set security descriptor on file
+ FindSDExtraField() extract SD e.f. block from extra field
+ IsWinNT() indicate type of WIN32 platform
+ test_NTSD() test integrity of NT security data
+ utime2NtfsFileTime()
+ utime2VFatFileTime()
+ FStampIsLocTime()
+ NtfsFileTime2utime()
+ VFatFileTime2utime()
+ getNTfiletime()
+ SetFileSize()
+ close_outfile()
+ defer_dir_attribs()
+ set_direc_attribs()
+ stamp_file()
+ isfloppy()
+ NTQueryVolInfo()
+ IsVolumeOldFAT()
+ do_wild()
+ mapattr()
+ mapname()
+ maskDOSdevice()
+ map2fat()
+ checkdir()
+ dateformat()
+ dateseparator()
+ version()
+ screensize()
+ zstat_win32()
+ conv_to_rule()
+ GetPlatformLocalTimezone()
+ getch_win32()
+
+ ---------------------------------------------------------------------------*/
+
+
+#define UNZIP_INTERNAL
+#include "../unzip.h"
+#include <windows.h> /* must be AFTER unzip.h to avoid struct G problems */
+#ifdef __RSXNT__
+# include "../win32/rsxntwin.h"
+#endif
+#include "../win32/nt.h"
+
+#ifndef FUNZIP /* most of this file is not used with fUnZip */
+
+/* some non-MS runtime headers (e.g. lcc) may miss this definition */
+#ifndef FILE_WRITE_ATTRIBUTES
+# define FILE_WRITE_ATTRIBUTES 0x0100
+#endif
+
+#if (defined(__EMX__) || defined(__CYGWIN__))
+# define MKDIR(path,mode) mkdir(path,mode)
+#else
+# define MKDIR(path,mode) mkdir(path)
+#endif
+
+#ifdef HAVE_WORKING_DIRENT_H
+# undef HAVE_WORKING_DIRENT_H
+#endif
+/* The emxrtl dirent support of (__GO32__ || __EMX__) converts to lowercase! */
+#if defined(__CYGWIN__)
+# define HAVE_WORKING_DIRENT_H
+#endif
+
+#ifndef SFX
+# ifdef HAVE_WORKING_DIRENT_H
+# include <dirent.h> /* use readdir() */
+# define zdirent dirent
+# define zDIR DIR
+# define Opendir opendir
+# define Readdir readdir
+# define Closedir closedir
+# else /* !HAVE_WORKING_DIRENT_H */
+ typedef struct zdirent {
+ char reserved [21];
+ char ff_attrib;
+ short ff_ftime;
+ short ff_fdate;
+ long size;
+ char d_name[MAX_PATH];
+ int d_first;
+ HANDLE d_hFindFile;
+ } zDIR;
+
+ static zDIR *Opendir (const char *n);
+ static struct zdirent *Readdir (zDIR *d);
+ static void Closedir (zDIR *d);
+# endif /* ?HAVE_WORKING_DIRENT_H */
+#endif /* !SFX */
+
+#ifdef SET_DIR_ATTRIB
+typedef struct NTdirattr { /* struct for holding unix style directory */
+ struct NTdirattr *next; /* info until can be sorted and set at end */
+ char *fn; /* filename of directory */
+ FILETIME Modft; /* File time type defined in NT, `last modified' time */
+ FILETIME Accft; /* NT file time type, `last access' time */
+ FILETIME Creft; /* NT file time type, `file creation' time */
+ int gotTime;
+ unsigned perms; /* same as min_info.file_attr */
+#ifdef NTSD_EAS
+ unsigned SDlen; /* length of SD data in buf */
+#endif
+ char buf[1]; /* buffer stub for directory SD and name */
+} NTdirattr;
+#define NtAtt(d) ((NTdirattr *)d) /* typecast shortcut */
+#endif /* SET_DIR_ATTRIB */
+
+
+/* Function prototypes */
+#ifdef NTSD_EAS
+ static int SetSD(__GPRO__ char *path, unsigned fperms,
+ uch *eb_ptr, unsigned eb_len);
+ static int FindSDExtraField(__GPRO__
+ uch *ef_ptr, unsigned ef_len,
+ uch **p_ebSD_ptr, unsigned *p_ebSD_len);
+#endif
+
+#ifndef NO_W32TIMES_IZFIX
+ static void utime2NtfsFileTime(time_t ut, FILETIME *pft);
+#endif
+static void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin);
+#if (defined(W32_STAT_BANDAID) && !defined(NO_W32TIMES_IZFIX))
+ static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut);
+#endif
+#ifdef W32_STAT_BANDAID
+ static int VFatFileTime2utime(const FILETIME *pft, time_t *ut);
+#endif
+static int FStampIsLocTime(__GPRO__ const char *path);
+
+
+static int getNTfiletime (__GPRO__ FILETIME *pModFT, FILETIME *pAccFT,
+ FILETIME *pCreFT);
+static int isfloppy (int nDrive);
+static int NTQueryVolInfo (__GPRO__ const char *name);
+static int IsVolumeOldFAT (__GPRO__ const char *name);
+static void maskDOSdevice (__GPRO__ char *pathcomp);
+static void map2fat (char *pathcomp, char **pEndFAT);
+
+
+#ifdef __MINGW32__
+ int _CRT_glob = 0; /* suppress command line globbing by C RTL */
+#endif
+
+#ifdef ACORN_FTYPE_NFS
+/* Acorn bits for NFS filetyping */
+typedef struct {
+ uch ID[2];
+ uch size[2];
+ uch ID_2[4];
+ uch loadaddr[4];
+ uch execaddr[4];
+ uch attr[4];
+} RO_extra_block;
+
+#endif /* ACORN_FTYPE_NFS */
+
+/* static int created_dir; */ /* used by mapname(), checkdir() */
+/* static int renamed_fullpath; */ /* ditto */
+/* static int fnlen; */ /* ditto */
+/* static unsigned nLabelDrive; */ /* ditto */
+
+extern char Far TruncNTSD[]; /* in extract.c */
+
+
+
+#ifdef SFX
+
+/**************************/
+/* Function GetLoadPath() */
+/**************************/
+
+char *GetLoadPath(__GPRO)
+{
+#ifdef MSC
+ extern char *_pgmptr;
+ return _pgmptr;
+
+#else /* use generic API call */
+
+ GetModuleFileName(NULL, G.filename, FILNAMSIZ-1);
+ _ISO_INTERN(G.filename); /* translate to codepage of C rtl's stdio */
+ return G.filename;
+#endif
+
+} /* end function GetLoadPath() */
+
+
+
+
+
+#else /* !SFX */
+
+#ifndef HAVE_WORKING_DIRENT_H
+
+/**********************/ /* Borrowed from ZIP 2.0 sources */
+/* Function Opendir() */ /* Difference: no special handling for */
+/**********************/ /* hidden or system files. */
+
+static zDIR *Opendir(n)
+ const char *n; /* directory to open */
+{
+ zDIR *d; /* malloc'd return value */
+ char *p; /* malloc'd temporary string */
+ WIN32_FIND_DATA fd;
+ extent len = strlen(n);
+
+ /* Start searching for files in directory n */
+
+ if ((d = (zDIR *)malloc(sizeof(zDIR))) == NULL ||
+ (p = malloc(strlen(n) + 5)) == NULL)
+ {
+ if (d != (zDIR *)NULL)
+ free((void *)d);
+ return (zDIR *)NULL;
+ }
+ INTERN_TO_ISO(n, p);
+ if (len > 0) {
+ if (p[len-1] == ':')
+ p[len++] = '.'; /* x: => x:. */
+ else if (p[len-1] == '/' || p[len-1] == '\\')
+ --len; /* foo/ => foo */
+ }
+ strcpy(p+len, "/*");
+
+ if (INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFile(p, &fd))) {
+ free((zvoid *)d);
+ free((zvoid *)p);
+ return NULL;
+ }
+ strcpy(d->d_name, fd.cFileName);
+
+ free((zvoid *)p);
+ d->d_first = 1;
+ return d;
+
+} /* end of function Opendir() */
+
+
+
+
+/**********************/ /* Borrowed from ZIP 2.0 sources */
+/* Function Readdir() */ /* Difference: no special handling for */
+/**********************/ /* hidden or system files. */
+
+static struct zdirent *Readdir(d)
+ zDIR *d; /* directory stream from which to read */
+{
+ /* Return pointer to first or next directory entry, or NULL if end. */
+
+ if ( d->d_first )
+ d->d_first = 0;
+ else
+ {
+ WIN32_FIND_DATA fd;
+
+ if ( !FindNextFile(d->d_hFindFile, &fd) )
+ return NULL;
+
+ ISO_TO_INTERN(fd.cFileName, d->d_name);
+ }
+ return (struct zdirent *)d;
+
+} /* end of function Readdir() */
+
+
+
+
+/***********************/
+/* Function Closedir() */ /* Borrowed from ZIP 2.0 sources */
+/***********************/
+
+static void Closedir(d)
+ zDIR *d; /* directory stream to close */
+{
+ FindClose(d->d_hFindFile);
+ free(d);
+}
+
+#endif /* !HAVE_WORKING_DIRENT_H */
+#endif /* ?SFX */
+
+
+
+
+#ifdef NTSD_EAS
+
+/**********************/
+/* Function SetSD() */ /* return almost-PK errors */
+/**********************/
+
+static int SetSD(__G__ path, fperms, eb_ptr, eb_len)
+ __GDEF
+ char *path;
+ unsigned fperms;
+ uch *eb_ptr;
+ unsigned eb_len;
+{
+ ulg ntsd_ucSize;
+ VOLUMECAPS VolumeCaps;
+ uch *security_data;
+ int error;
+
+ ntsd_ucSize = makelong(eb_ptr + (EB_HEADSIZE+EB_UCSIZE_P));
+ if (ntsd_ucSize > 0L && eb_len <= (EB_NTSD_L_LEN + EB_CMPRHEADLEN))
+ return IZ_EF_TRUNC; /* no compressed data! */
+
+ /* provide useful input */
+ VolumeCaps.dwFileAttributes = fperms;
+ VolumeCaps.bUsePrivileges = (uO.X_flag > 1);
+
+ /* check target volume capabilities - just fall through
+ * and try if fail */
+ if (GetVolumeCaps(G.rootpath, path, &VolumeCaps) &&
+ !(VolumeCaps.dwFileSystemFlags & FS_PERSISTENT_ACLS))
+ return PK_OK;
+
+ /* allocate storage for uncompressed data */
+ security_data = (uch *)malloc((extent)ntsd_ucSize);
+ if (security_data == (uch *)NULL)
+ return PK_MEM4;
+
+ error = memextract(__G__ security_data, ntsd_ucSize,
+ (eb_ptr + (EB_HEADSIZE+EB_NTSD_L_LEN)), (ulg)(eb_len - EB_NTSD_L_LEN));
+
+ if (error == PK_OK) {
+ if (SecuritySet(path, &VolumeCaps, security_data)) {
+ error = PK_COOL;
+ if (!uO.tflag && QCOND2)
+ Info(slide, 0, ((char *)slide, " (%ld bytes security)",
+ ntsd_ucSize));
+ }
+ }
+
+ free(security_data);
+ return error;
+}
+
+
+
+
+/********************************/ /* scan extra fields for something */
+/* Function FindSDExtraField() */ /* we happen to know */
+/********************************/
+/* Returns TRUE when a valid NTFS SD block is found.
+ * Address and size of the NTSD e.f. block are passed up to the caller.
+ * In case of more than one valid NTSD block in the e.f., the last block
+ * found is passed up.
+ * Returns FALSE and leaves the content of the ebSD_ptr and ebSD_len
+ * parameters untouched when no valid NTFS SD block is found. */
+static int FindSDExtraField(__GPRO__
+ uch *ef_ptr, unsigned ef_len,
+ uch **p_ebSD_ptr, unsigned *p_ebSD_len)
+{
+ int rc = FALSE;
+
+ if (!uO.X_flag)
+ return FALSE; /* user said don't process ACLs; for now, no other
+ extra block types are handled here */
+
+ while (ef_len >= EB_HEADSIZE)
+ {
+ unsigned eb_id = makeword(EB_ID + ef_ptr);
+ unsigned eb_len = makeword(EB_LEN + ef_ptr);
+
+ if (eb_len > (ef_len - EB_HEADSIZE)) {
+ /* discovered some extra field inconsistency! */
+ Trace((stderr,
+ "FindSDExtraField: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+
+ switch (eb_id)
+ {
+ /* process security descriptor extra data if:
+ Caller is WinNT AND
+ Target local/remote drive supports acls AND
+ Target file is not a directory (else we defer processing
+ until later)
+ */
+ case EF_NTSD:
+ if (!IsWinNT())
+ break; /* OS not capable of handling NTFS attributes */
+
+ if (eb_len < EB_NTSD_L_LEN)
+ break; /* not a valid NTSD extra field */
+
+ /* check if we know how to handle this version */
+ if (*(ef_ptr + (EB_HEADSIZE+EB_NTSD_VERSION))
+ > (uch)EB_NTSD_MAX_VER)
+ break;
+
+ *p_ebSD_ptr = ef_ptr;
+ *p_ebSD_len = eb_len;
+ rc = TRUE;
+ break;
+
+#ifdef DEBUG
+ case EF_OS2:
+ case EF_AV:
+ case EF_PKVMS:
+ case EF_PKW32:
+ case EF_PKUNIX:
+ case EF_IZVMS:
+ case EF_IZUNIX:
+ case EF_IZUNIX2:
+ case EF_TIME:
+ case EF_MAC3:
+ case EF_JLMAC:
+ case EF_ZIPIT:
+ case EF_VMCMS:
+ case EF_MVS:
+ case EF_ACL:
+ case EF_ATHEOS:
+ case EF_BEOS:
+ case EF_QDOS:
+ case EF_AOSVS:
+ case EF_SPARK:
+ case EF_MD5:
+ case EF_ASIUNIX:
+ break; /* shut up for other known e.f. blocks */
+#endif /* DEBUG */
+
+ default:
+ Trace((stderr,
+ "FindSDExtraField: unknown extra field block, ID=%u\n",
+ eb_id));
+ break;
+ }
+
+ ef_ptr += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
+
+ return rc;
+}
+
+
+
+
+#ifndef SFX
+
+/**************************/
+/* Function test_NTSD() */ /* returns PK_WARN when NTSD data is invalid */
+/**************************/
+
+#ifdef __BORLANDC__
+/* Turn off warning about not using all parameters for this function only */
+#pragma argsused
+#endif
+int test_NTSD(__G__ eb, eb_size, eb_ucptr, eb_ucsize)
+ __GDEF
+ uch *eb;
+ unsigned eb_size;
+ uch *eb_ucptr;
+ ulg eb_ucsize;
+{
+ return (ValidateSecurity(eb_ucptr) ? PK_OK : PK_WARN);
+} /* end function test_NTSD() */
+
+#endif /* !SFX */
+#endif /* NTSD_EAS */
+
+
+
+
+/**********************/
+/* Function IsWinNT() */
+/**********************/
+
+int IsWinNT(void) /* returns TRUE if real NT, FALSE if Win9x or Win32s */
+{
+ static DWORD g_PlatformId = 0xFFFFFFFF; /* saved platform indicator */
+
+ if (g_PlatformId == 0xFFFFFFFF) {
+ /* note: GetVersionEx() doesn't exist on WinNT 3.1 */
+ if (GetVersion() < 0x80000000)
+ g_PlatformId = TRUE;
+ else
+ g_PlatformId = FALSE;
+ }
+ return (int)g_PlatformId;
+}
+
+
+/* DEBUG_TIME insertion: */
+#ifdef DEBUG_TIME
+static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft);
+
+static int show_NTFileTime(FILE *hdo, char *TTmsg, int isloc, FILETIME *pft)
+{
+ SYSTEMTIME w32tm;
+ int rval;
+
+ rval = FileTimeToSystemTime(pft, &w32tm);
+ if (!rval) {
+ fprintf(hdo, "%s\n %08lX,%08lX (%s) -> Conversion failed !!!\n",
+ TTmsg, (ulg)(pft->dwHighDateTime), (ulg)(pft->dwLowDateTime),
+ (isloc ? "local" : "UTC"));
+ } else {
+ fprintf(hdo, "%s\n %08lx,%08lx -> %04u-%02u-%02u, %02u:%02u:%02u %s\n",
+ TTmsg, (ulg)(pft->dwHighDateTime), (ulg)(pft->dwLowDateTime),
+ w32tm.wYear, w32tm.wMonth, w32tm.wDay, w32tm.wHour,
+ w32tm.wMinute, w32tm.wSecond, (isloc ? "local" : "UTC"));
+ }
+ return rval;
+}
+#define FTTrace(x) show_NTFileTime x
+#else
+#define FTTrace(x)
+#endif /* DEBUG_TIME */
+/* end of DEBUG_TIME insertion */
+
+#ifndef IZ_USE_INT64
+# if (defined(__GNUC__) || defined(ULONG_LONG_MAX))
+ typedef long long LLONG64;
+ typedef unsigned long long ULLNG64;
+# define IZ_USE_INT64
+# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
+ typedef __int64 LLONG64;
+ typedef unsigned __int64 ULLNG64;
+# define IZ_USE_INT64
+# elif (defined(_MSC_VER) && (_MSC_VER >= 1100))
+ typedef __int64 LLONG64;
+ typedef unsigned __int64 ULLNG64;
+# define IZ_USE_INT64
+# elif (defined(__IBMC__) && (__IBMC__ >= 350))
+ typedef __int64 LLONG64;
+ typedef unsigned __int64 ULLNG64;
+# define IZ_USE_INT64
+# elif defined(HAVE_INT64)
+ typedef __int64 LLONG64;
+ typedef unsigned __int64 ULLNG64;
+# define IZ_USE_INT64
+# endif
+#endif
+
+/* scale factor and offset for conversion time_t -> FILETIME */
+#define NT_QUANTA_PER_UNIX 10000000L
+#define UNIX_TIME_ZERO_HI 0x019DB1DEUL
+#define UNIX_TIME_ZERO_LO 0xD53E8000UL
+/* special FILETIME values for bound-checks */
+#define UNIX_TIME_UMAX_HI 0x0236485EUL
+#define UNIX_TIME_UMAX_LO 0xD4A5E980UL
+#define UNIX_TIME_SMIN_HI 0x0151669EUL
+#define UNIX_TIME_SMIN_LO 0xD53E8000UL
+#define UNIX_TIME_SMAX_HI 0x01E9FD1EUL
+#define UNIX_TIME_SMAX_LO 0xD4A5E980UL
+#define DOSTIME_MIN_FT_HI 0x01A8E79FUL
+#define DOSTIME_MIN_FT_LO 0xE1D58000UL
+/* time_t equivalent of DOSTIME_MINIMUM */
+#define UTIME_1980_JAN_01_00_00 315532800L
+
+
+#ifndef NO_W32TIMES_IZFIX
+/*********************************/
+/* Function utime2NtfsFileTime() */ /* convert Unix time_t format into the */
+/*********************************/ /* form used by SetFileTime() in NT/9x */
+
+static void utime2NtfsFileTime(time_t ut, FILETIME *pft)
+{
+#ifdef IZ_USE_INT64
+ ULLNG64 NTtime;
+
+ /* NT_QUANTA_PER_UNIX is small enough so that "ut * NT_QUANTA_PER_UNIX"
+ * cannot overflow in 64-bit signed calculation, regardless whether "ut"
+ * is signed or unsigned. */
+ NTtime = ((LLONG64)ut * NT_QUANTA_PER_UNIX) +
+ ((ULLNG64)UNIX_TIME_ZERO_LO + ((ULLNG64)UNIX_TIME_ZERO_HI << 32));
+ pft->dwLowDateTime = (DWORD)NTtime;
+ pft->dwHighDateTime = (DWORD)(NTtime >> 32);
+
+#else /* !IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */
+ unsigned int b1, b2, carry = 0;
+ unsigned long r0, r1, r2, r3;
+ long r4; /* signed, to catch environments with signed time_t */
+
+ b1 = ut & 0xFFFF;
+ b2 = (ut >> 16) & 0xFFFF; /* if ut is over 32 bits, too bad */
+ r1 = b1 * (NT_QUANTA_PER_UNIX & 0xFFFF);
+ r2 = b1 * (NT_QUANTA_PER_UNIX >> 16);
+ r3 = b2 * (NT_QUANTA_PER_UNIX & 0xFFFF);
+ r4 = b2 * (NT_QUANTA_PER_UNIX >> 16);
+ r0 = (r1 + (r2 << 16)) & 0xFFFFFFFFL;
+ if (r0 < r1)
+ carry++;
+ r1 = r0;
+ r0 = (r0 + (r3 << 16)) & 0xFFFFFFFFL;
+ if (r0 < r1)
+ carry++;
+ pft->dwLowDateTime = r0 + UNIX_TIME_ZERO_LO;
+ if (pft->dwLowDateTime < r0)
+ carry++;
+ pft->dwHighDateTime = r4 + (r2 >> 16) + (r3 >> 16)
+ + UNIX_TIME_ZERO_HI + carry;
+#endif /* ?IZ_USE_INT64 */
+
+} /* end function utime2NtfsFileTime() */
+#endif /* !NO_W32TIMES_IZFIX */
+
+
+
+/*********************************/
+/* Function utime2VFatFileTime() */ /* convert Unix time_t format into the */
+/*********************************/ /* form used by SetFileTime() in NT/9x */
+
+static void utime2VFatFileTime(time_t ut, FILETIME *pft, int clipDosMin)
+{
+ time_t utc = ut;
+ struct tm *ltm;
+ SYSTEMTIME w32tm;
+ FILETIME lft;
+
+#ifdef __BORLANDC__ /* Borland C++ 5.x crashes when trying to reference tm */
+ if (utc < UTIME_1980_JAN_01_00_00)
+ utc = UTIME_1980_JAN_01_00_00;
+#endif
+ ltm = localtime(&utc);
+ if (ltm == (struct tm *)NULL)
+ /* localtime() did not accept given utc time value; try to use
+ the UTC value */
+ ltm = gmtime(&utc);
+ if (ltm == (struct tm *)NULL) {
+ if (ut <= (UTIME_1980_JAN_01_00_00 + 86400)) {
+ /* use DOSTIME_MINIMUM date instead of "early" failure dates */
+ w32tm.wYear = 1980;
+ w32tm.wMonth = 1;
+ w32tm.wDay = 1;
+ w32tm.wHour = 0;
+ w32tm.wMinute = 0;
+ w32tm.wSecond = 0;
+ } else {
+ /* as a last resort, use the current system time */
+ GetLocalTime(&w32tm);
+ }
+ } else if (clipDosMin && (ltm->tm_year < 80)) {
+ w32tm.wYear = 1980;
+ w32tm.wMonth = 1;
+ w32tm.wDay = 1;
+ w32tm.wHour = 0;
+ w32tm.wMinute = 0;
+ w32tm.wSecond = 0;
+ } else {
+ w32tm.wYear = ltm->tm_year + 1900; /* year + 1900 -> year */
+ w32tm.wMonth = ltm->tm_mon + 1; /* 0..11 -> 1..12 */
+ w32tm.wDay = ltm->tm_mday; /* 1..31 */
+ w32tm.wHour = ltm->tm_hour; /* 0..23 */
+ w32tm.wMinute = ltm->tm_min; /* 0..59 */
+ w32tm.wSecond = ltm->tm_sec; /* 0..61 in ANSI C */
+ }
+
+ SystemTimeToFileTime(&w32tm, &lft);
+ LocalFileTimeToFileTime(&lft, pft);
+
+} /* end function utime2VFatFileTime() */
+
+
+
+ /* nonzero if `y' is a leap year, else zero */
+#define leap(y) (((y)%4 == 0 && (y)%100 != 0) || (y)%400 == 0)
+ /* number of leap years from 1970 to `y' (not including `y' itself) */
+#define nleap(y) (((y)-1969)/4 - ((y)-1901)/100 + ((y)-1601)/400)
+
+extern ZCONST ush ydays[]; /* defined in fileio.c */
+
+#if (defined(W32_STAT_BANDAID) && !defined(NO_W32TIMES_IZFIX))
+/*********************************/
+/* Function NtfsFileTime2utime() */
+/*********************************/
+
+static int NtfsFileTime2utime(const FILETIME *pft, time_t *ut)
+{
+#ifdef IZ_USE_INT64
+ ULLNG64 NTtime;
+
+ NTtime = ((ULLNG64)pft->dwLowDateTime +
+ ((ULLNG64)pft->dwHighDateTime << 32));
+
+#ifndef TIME_T_TYPE_DOUBLE
+ /* underflow and overflow handling */
+#ifdef CHECK_UTIME_SIGNED_UNSIGNED
+ if ((time_t)0x80000000L < (time_t)0L)
+ {
+ if (NTtime < ((ULLNG64)UNIX_TIME_SMIN_LO +
+ ((ULLNG64)UNIX_TIME_SMIN_HI << 32))) {
+ *ut = (time_t)LONG_MIN;
+ return FALSE;
+ }
+ if (NTtime > ((ULLNG64)UNIX_TIME_SMAX_LO +
+ ((ULLNG64)UNIX_TIME_SMAX_HI << 32))) {
+ *ut = (time_t)LONG_MAX;
+ return FALSE;
+ }
+ }
+ else
+#endif /* CHECK_UTIME_SIGNED_UNSIGNED */
+ {
+ if (NTtime < ((ULLNG64)UNIX_TIME_ZERO_LO +
+ ((ULLNG64)UNIX_TIME_ZERO_HI << 32))) {
+ *ut = (time_t)0;
+ return FALSE;
+ }
+ if (NTtime > ((ULLNG64)UNIX_TIME_UMAX_LO +
+ ((ULLNG64)UNIX_TIME_UMAX_HI << 32))) {
+ *ut = (time_t)ULONG_MAX;
+ return FALSE;
+ }
+ }
+#endif /* !TIME_T_TYPE_DOUBLE */
+
+ NTtime -= ((ULLNG64)UNIX_TIME_ZERO_LO +
+ ((ULLNG64)UNIX_TIME_ZERO_HI << 32));
+ *ut = (time_t)(NTtime / (unsigned long)NT_QUANTA_PER_UNIX);
+ return TRUE;
+#else /* !IZ_USE_INT64 (64-bit integer arithmetics may not be supported) */
+ time_t days;
+ SYSTEMTIME w32tm;
+
+#ifndef TIME_T_TYPE_DOUBLE
+ /* underflow and overflow handling */
+#ifdef CHECK_UTIME_SIGNED_UNSIGNED
+ if ((time_t)0x80000000L < (time_t)0L)
+ {
+ if ((pft->dwHighDateTime < UNIX_TIME_SMIN_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_SMIN_HI) &&
+ (pft->dwLowDateTime < UNIX_TIME_SMIN_LO))) {
+ *ut = (time_t)LONG_MIN;
+ return FALSE;
+ if ((pft->dwHighDateTime > UNIX_TIME_SMAX_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_SMAX_HI) &&
+ (pft->dwLowDateTime > UNIX_TIME_SMAX_LO))) {
+ *ut = (time_t)LONG_MAX;
+ return FALSE;
+ }
+ }
+ else
+#endif /* CHECK_UTIME_SIGNED_UNSIGNED */
+ {
+ if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) &&
+ (pft->dwLowDateTime < UNIX_TIME_ZERO_LO))) {
+ *ut = (time_t)0;
+ return FALSE;
+ }
+ if ((pft->dwHighDateTime > UNIX_TIME_UMAX_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_UMAX_HI) &&
+ (pft->dwLowDateTime > UNIX_TIME_UMAX_LO))) {
+ *ut = (time_t)ULONG_MAX;
+ return FALSE;
+ }
+ }
+#endif /* !TIME_T_TYPE_DOUBLE */
+
+ FileTimeToSystemTime(pft, &w32tm);
+
+ /* set `days' to the number of days into the year */
+ days = w32tm.wDay - 1 + ydays[w32tm.wMonth-1] +
+ (w32tm.wMonth > 2 && leap (w32tm.wYear));
+
+ /* now set `days' to the number of days since 1 Jan 1970 */
+ days += 365 * (time_t)(w32tm.wYear - 1970) +
+ (time_t)(nleap(w32tm.wYear));
+
+ *ut = (time_t)(86400L * days + 3600L * (time_t)w32tm.wHour +
+ (time_t)(60 * w32tm.wMinute + w32tm.wSecond));
+ return TRUE;
+#endif /* ?IZ_USE_INT64 */
+} /* end function NtfsFileTime2utime() */
+#endif /* W32_STAT_BANDAID && !NO_W32TIMES_IZFIX */
+
+
+
+#ifdef W32_STAT_BANDAID
+/*********************************/
+/* Function VFatFileTime2utime() */
+/*********************************/
+
+static int VFatFileTime2utime(const FILETIME *pft, time_t *ut)
+{
+ FILETIME lft;
+#ifndef HAVE_MKTIME
+ WORD wDOSDate, wDOSTime;
+#else
+ SYSTEMTIME w32tm;
+ struct tm ltm;
+#endif
+
+ if (!FileTimeToLocalFileTime(pft, &lft)) {
+ /* if pft cannot be converted to local time, return current time */
+ return time(NULL);
+ }
+ FTTrace((stdout, "VFatFT2utime, feed for mktime()", 1, &lft));
+#ifndef HAVE_MKTIME
+ /* This version of the FILETIME-to-UNIXTIME conversion function
+ * uses DOS-DATE-TIME format as intermediate stage. For modification
+ * and access times, this is no problem. But, the extra fine resolution
+ * of the VFAT-stored creation time gets lost.
+ */
+ if (!FileTimeToDosDateTime(&lft, &wDOSDate, &wDOSTime)) {
+ static const FILETIME dosmin_ft =
+ {DOSTIME_MIN_FT_LO, DOSTIME_MIN_FT_HI};
+ if (CompareFileTime(&lft, &dosmin_ft) <= 0) {
+ /* underflow -> set to minimum DOS time */
+ wDOSDate = (WORD)((DWORD)DOSTIME_MINIMUM >> 16);
+ wDOSTime = (WORD)DOSTIME_MINIMUM;
+ } else {
+ /* overflow -> set to maximum DOS time */
+ wDOSDate = (WORD)0xFF9F; /* 2107-12-31 */
+ wDOSTime = (WORD)0xBF7D; /* 23:59:58 */
+ }
+ }
+ TTrace((stdout,"DosDateTime is %04u-%02u-%02u %02u:%02u:%02u\n",
+ (unsigned)((wDOSDate>>9)&0x7f)+1980,(unsigned)((wDOSDate>>5)&0x0f),
+ (unsigned)(wDOSDate&0x1f),(unsigned)((wDOSTime>>11)&0x1f),
+ (unsigned)((wDOSTime>>5)&0x3f),(unsigned)((wDOSTime<<1)&0x3e)));
+ *ut = dos_to_unix_time(((ulg)wDOSDate << 16) | (ulg)wDOSTime);
+
+ /* a cheap error check: dos_to_unix_time() only returns an odd time
+ * when clipping at maximum time_t value. DOS_DATE_TIME values have
+ * a resolution of 2 seconds and are therefore even numbers.
+ */
+ return (((*ut)&1) == (time_t)0);
+#else /* HAVE_MKTIME */
+ FileTimeToSystemTime(&lft, &w32tm);
+#ifndef TIME_T_TYPE_DOUBLE
+ /* underflow and overflow handling */
+ /* TODO: The range checks are not accurate, the actual limits may
+ * be off by one daylight-saving-time shift (typically 1 hour),
+ * depending on the current state of "is_dst".
+ */
+#ifdef CHECK_UTIME_SIGNED_UNSIGNED
+ if ((time_t)0x80000000L < (time_t)0L)
+ {
+ if ((pft->dwHighDateTime < UNIX_TIME_SMIN_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_SMIN_HI) &&
+ (pft->dwLowDateTime < UNIX_TIME_SMIN_LO))) {
+ *ut = (time_t)LONG_MIN;
+ return FALSE;
+ if ((pft->dwHighDateTime > UNIX_TIME_SMAX_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_SMAX_HI) &&
+ (pft->dwLowDateTime > UNIX_TIME_SMAX_LO))) {
+ *ut = (time_t)LONG_MAX;
+ return FALSE;
+ }
+ }
+ else
+#endif /* CHECK_UTIME_SIGNED_UNSIGNED */
+ {
+ if ((pft->dwHighDateTime < UNIX_TIME_ZERO_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_ZERO_HI) &&
+ (pft->dwLowDateTime < UNIX_TIME_ZERO_LO))) {
+ *ut = (time_t)0;
+ return FALSE;
+ }
+ if ((pft->dwHighDateTime > UNIX_TIME_UMAX_HI) ||
+ ((pft->dwHighDateTime == UNIX_TIME_UMAX_HI) &&
+ (pft->dwLowDateTime > UNIX_TIME_UMAX_LO))) {
+ *ut = (time_t)ULONG_MAX;
+ return FALSE;
+ }
+ }
+#endif /* !TIME_T_TYPE_DOUBLE */
+ ltm.tm_year = w32tm.wYear - 1900;
+ ltm.tm_mon = w32tm.wMonth - 1;
+ ltm.tm_mday = w32tm.wDay;
+ ltm.tm_hour = w32tm.wHour;
+ ltm.tm_min = w32tm.wMinute;
+ ltm.tm_sec = w32tm.wSecond;
+ ltm.tm_isdst = -1; /* let mktime determine if DST is in effect */
+ *ut = mktime(<m);
+
+ /* a cheap error check: mktime returns "(time_t)-1L" on conversion errors.
+ * Normally, we would have to apply a consistency check because "-1"
+ * could also be a valid time. But, it is quite unlikely to read back odd
+ * time numbers from file systems that store time stamps in DOS format.
+ * (The only known exception is creation time on VFAT partitions.)
+ */
+ return (*ut != (time_t)-1L);
+#endif /* ?HAVE_MKTIME */
+
+} /* end function VFatFileTime2utime() */
+#endif /* W32_STAT_BANDAID */
+
+
+
+/******************************/
+/* Function FStampIsLocTime() */
+/******************************/
+
+static int FStampIsLocTime(__GPRO__ const char *path)
+{
+ return (NTQueryVolInfo(__G__ path) ? G.lastVolLocTim : FALSE);
+}
+
+
+
+#ifndef NO_W32TIMES_IZFIX
+# define UTIME_2_IZFILETIME(ut, pft) \
+ if (fs_uses_loctime) {utime2VFatFileTime(ut, pft, TRUE);} \
+ else {utime2NtfsFileTime(ut, pft);}
+#else
+# define UTIME_2_IZFILETIME(ut, pft) \
+ utime2VFatFileTime(ut, pft, fs_uses_loctime);
+#endif
+
+
+
+/****************************/ /* Get the file time in a format that */
+/* Function getNTfiletime() */ /* can be used by SetFileTime() in NT */
+/****************************/
+
+static int getNTfiletime(__G__ pModFT, pAccFT, pCreFT)
+ __GDEF
+ FILETIME *pModFT;
+ FILETIME *pAccFT;
+ FILETIME *pCreFT;
+{
+#ifdef USE_EF_UT_TIME
+ unsigned eb_izux_flg;
+ iztimes z_utime; /* struct for Unix-style actime & modtime, + creatime */
+#endif
+ int fs_uses_loctime = FStampIsLocTime(__G__ G.filename);
+
+ /* Copy and/or convert time and date variables, if necessary;
+ * return a flag indicating which time stamps are available. */
+#ifdef USE_EF_UT_TIME
+ if (G.extra_field &&
+#ifdef IZ_CHECK_TZ
+ G.tz_is_valid &&
+#endif
+ ((eb_izux_flg = ef_scan_for_izux(G.extra_field,
+ G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
+ &z_utime, NULL)) & EB_UT_FL_MTIME))
+ {
+ TTrace((stderr, "getNTfiletime: Unix e.f. modif. time = %lu\n",
+ z_utime.mtime));
+ UTIME_2_IZFILETIME(z_utime.mtime, pModFT)
+ if (eb_izux_flg & EB_UT_FL_ATIME) {
+ UTIME_2_IZFILETIME(z_utime.atime, pAccFT)
+ }
+ if (eb_izux_flg & EB_UT_FL_CTIME) {
+ UTIME_2_IZFILETIME(z_utime.ctime, pCreFT)
+ }
+ return (int)eb_izux_flg;
+ }
+#endif /* USE_EF_UT_TIME */
+#ifndef NO_W32TIMES_IZFIX
+ if (!fs_uses_loctime) {
+ time_t ux_modtime;
+
+ ux_modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
+ utime2NtfsFileTime(ux_modtime, pModFT);
+ } else
+#endif /* NO_W32TIMES_IZFIX */
+ {
+ FILETIME lft;
+
+ DosDateTimeToFileTime((WORD)(G.lrec.last_mod_dos_datetime >> 16),
+ (WORD)(G.lrec.last_mod_dos_datetime & 0xFFFFL),
+ &lft);
+ LocalFileTimeToFileTime(&lft, pModFT);
+ }
+ *pAccFT = *pModFT;
+ return (EB_UT_FL_MTIME | EB_UT_FL_ATIME);
+
+} /* end function getNTfiletime() */
+
+
+
+
+/**************************/
+/* Function SetFileSize() */
+/**************************/
+
+int SetFileSize(FILE *file, ulg filesize)
+{
+#ifdef __RSXNT__
+ /* RSXNT environment lacks a translation function from C file pointer
+ to Win32-API file handle. So, simply do nothing. */
+ return 0;
+#else /* !__RSXNT__ */
+ /* not yet verified, if that really creates an unfragmented file
+ rommel(a)ars.de
+ */
+ HANDLE os_fh;
+
+ /* Win9x supports FAT file system, only; presetting file size does
+ not help to prevent fragmentation. */
+ if (!IsWinNT()) return 0;
+
+ /* Win32-API calls require access to the Win32 file handle.
+ The interface function used to retrieve the Win32 handle for
+ a file opened by the C rtl is non-standard and may not be
+ available for every Win32 compiler environment.
+ (see also win32/win32.c of the Zip distribution)
+ */
+ os_fh = (HANDLE)_get_osfhandle(fileno(file));
+ /* move file pointer behind the last byte of the expected file size */
+ if (SetFilePointer(os_fh, filesize, 0, FILE_BEGIN) == 0xFFFFFFFF)
+ return -1;
+ /* extend/truncate file to the current position */
+ if (SetEndOfFile(os_fh) == 0)
+ return -1;
+ /* move file position pointer back to the start of the file! */
+ return (SetFilePointer(os_fh, 0, 0, FILE_BEGIN) == 0xFFFFFFFF) ? -1 : 0;
+#endif /* ?__RSXNT__ */
+} /* end function SetFileSize() */
+
+
+
+
+/****************************/
+/* Function close_outfile() */
+/****************************/
+
+void close_outfile(__G)
+ __GDEF
+{
+ FILETIME Modft; /* File time type defined in NT, `last modified' time */
+ FILETIME Accft; /* NT file time type, `last access' time */
+ FILETIME Creft; /* NT file time type, `file creation' time */
+ HANDLE hFile; /* File handle defined in NT */
+ int gotTime;
+#ifdef NTSD_EAS
+ uch *ebSDptr;
+ unsigned ebSDlen;
+#endif
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(G.filename) + 1);
+
+ INTERN_TO_ISO(G.filename, ansi_name);
+# define Ansi_Fname ansi_name
+#else
+# define Ansi_Fname G.filename
+#endif
+
+ /* Close the file and then re-open it using the Win32
+ * CreateFile call, so that the file can be created
+ * with GENERIC_WRITE access, otherwise the SetFileTime
+ * call will fail. */
+ fclose(G.outfile);
+
+ /* don't set the time stamp and attributes on standard output */
+ if (uO.cflag)
+ return;
+
+ gotTime = getNTfiletime(__G__ &Modft, &Accft, &Creft);
+
+ /* open a handle to the file before processing extra fields;
+ we do this in case new security on file prevents us from updating
+ time stamps */
+ hFile = CreateFile(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ /* sfield(a)microsoft.com: set attributes before time in case we decide to
+ support other filetime members later. This also allows us to apply
+ attributes before the security is changed, which may prevent this
+ from succeeding otherwise. Also, since most files don't have
+ any interesting attributes, only change them if something other than
+ FILE_ATTRIBUTE_ARCHIVE appears in the attributes. This works well
+ as an optimization because FILE_ATTRIBUTE_ARCHIVE gets applied to the
+ file anyway, when it's created new. */
+ if((G.pInfo->file_attr & 0x7F) & ~FILE_ATTRIBUTE_ARCHIVE) {
+ if (!SetFileAttributes(Ansi_Fname, G.pInfo->file_attr & 0x7F))
+ Info(slide, 1, ((char *)slide,
+ "\nwarning (%d): could not set file attributes\n",
+ (int)GetLastError()));
+ }
+
+#ifdef NTSD_EAS
+ /* set NTFS SD extra fields */
+ if (G.extra_field && /* zipfile extra field may have extended attribs */
+ FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length,
+ &ebSDptr, &ebSDlen))
+ {
+ int err = SetSD(__G__ Ansi_Fname, G.pInfo->file_attr,
+ ebSDptr, ebSDlen);
+
+ if (err == IZ_EF_TRUNC) {
+ if (uO.qflag)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+ FnFilter1(G.filename)));
+ Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD),
+ ebSDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), uO.qflag? "\n":""));
+ }
+ }
+#endif /* NTSD_EAS */
+
+ if ( hFile == INVALID_HANDLE_VALUE )
+ Info(slide, 1, ((char *)slide,
+ "\nCreateFile() error %d when trying set file time\n",
+ (int)GetLastError()));
+ else {
+ if (gotTime) {
+ FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL;
+ FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL;
+ FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL;
+
+ if (!SetFileTime(hFile, pCreft, pAccft, pModft))
+ Info(slide, 0, ((char *)slide, "\nSetFileTime failed: %d\n",
+ (int)GetLastError()));
+ }
+ CloseHandle(hFile);
+ }
+
+ return;
+
+#undef Ansi_Fname
+
+} /* end function close_outfile() */
+
+
+
+
+#ifdef SET_DIR_ATTRIB
+
+int defer_dir_attribs(__G__ pd)
+ __GDEF
+ direntry **pd;
+{
+ NTdirattr *d_entry;
+#ifdef NTSD_EAS
+ uch *ebSDptr;
+ unsigned ebSDlen;
+#endif
+
+ /* Win9x does not support setting directory time stamps. */
+ if (!IsWinNT()) {
+ *pd = (direntry *)NULL;
+ return PK_OK;
+ }
+
+#ifdef NTSD_EAS
+ /* set extended attributes from extra fields */
+ if (G.extra_field && /* zipfile e.f. may have extended attribs */
+ FindSDExtraField(__G__ G.extra_field, G.lrec.extra_field_length,
+ &ebSDptr, &ebSDlen)) {
+ /* ebSDlen contains the payload size of the e.f. block, but
+ we store it including the e.b. header. */
+ ebSDlen += EB_HEADSIZE;
+ } else {
+ /* no NTSD e.f. block -> no space needed to allocate */
+ ebSDlen = 0;
+ }
+#endif /* NTSD_EAS */
+
+ d_entry = (NTdirattr *)malloc(sizeof(NTdirattr)
+#ifdef NTSD_EAS
+ + ebSDlen
+#endif
+ + strlen(G.filename));
+ *pd = (direntry *)d_entry;
+ if (d_entry == (NTdirattr *)NULL) {
+ return PK_MEM;
+ }
+#ifdef NTSD_EAS
+ if (ebSDlen > 0)
+ memcpy(d_entry->buf, ebSDptr, ebSDlen);
+ d_entry->SDlen = ebSDlen;
+ d_entry->fn = d_entry->buf + ebSDlen;
+#else
+ d_entry->fn = d_entry->buf;
+#endif
+
+ strcpy(d_entry->fn, G.filename);
+
+ d_entry->perms = G.pInfo->file_attr;
+
+ d_entry->gotTime = getNTfiletime(__G__ &(d_entry->Modft),
+ &(d_entry->Accft), &(d_entry->Creft));
+ return PK_OK;
+} /* end function defer_dir_attribs() */
+
+
+int set_direc_attribs(__G__ d)
+ __GDEF
+ direntry *d;
+{
+ int errval;
+ HANDLE hFile; /* File handle defined in NT */
+#ifdef __RSXNT__
+ char *ansi_name;
+#endif
+
+ /* Win9x does not support setting directory time stamps. */
+ if (!IsWinNT())
+ return PK_OK;
+
+ errval = PK_OK;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ ansi_name = (char *)alloca(strlen(d->fn) + 1);
+ INTERN_TO_ISO(d->fn, ansi_name);
+# define Ansi_Dirname ansi_name
+#else
+# define Ansi_Dirname d->fn
+#endif
+
+ /* Open a handle to the directory before processing extra fields;
+ we do this in case new security on file prevents us from updating
+ time stamps.
+ Although the WIN32 documentation recommends to use GENERIC_WRITE
+ access flag to create the handle for SetFileTime(), this is too
+ demanding for directories with the "read-only" attribute bit set.
+ So we use the more specific flag FILE_WRITE_ATTRIBUTES here to
+ request the minimum required access rights. (This problem is a
+ Windows bug that has been silently fixed in Windows XP SP2.) */
+ hFile = CreateFile(Ansi_Dirname, FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+#ifdef NTSD_EAS
+ if (NtAtt(d)->SDlen > 0) {
+ int err;
+
+ if (QCOND2) {
+ Info(slide, 1, ((char *)slide, " set attrib: %-22s ",
+ FnFilter1(d->fn)));
+ }
+
+ /* set NTFS SD extra fields */
+ err = SetSD(__G__ Ansi_Dirname, NtAtt(d)->perms,
+ NtAtt(d)->buf, NtAtt(d)->SDlen - EB_HEADSIZE);
+ if (err == IZ_EF_TRUNC) {
+ if (!QCOND2)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+ FnFilter1(d->fn)));
+ Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD),
+ NtAtt(d)->SDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n"));
+ } else if (QCOND2) {
+ Info(slide, 0, ((char *)slide, "\n"));
+ }
+ if (errval < err)
+ errval = err;
+ }
+#endif /* NTSD_EAS */
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ Info(slide, 1, ((char *)slide,
+ "warning: CreateFile() error %d (set file times for %s)\n",
+ (int)GetLastError(), FnFilter1(d->fn)));
+ if (!errval)
+ errval = PK_WARN;
+ } else {
+ if (NtAtt(d)->gotTime) {
+ FILETIME *pModft = (NtAtt(d)->gotTime & EB_UT_FL_MTIME)
+ ? &(NtAtt(d)->Modft) : NULL;
+ FILETIME *pAccft = (NtAtt(d)->gotTime & EB_UT_FL_ATIME)
+ ? &(NtAtt(d)->Accft) : NULL;
+ FILETIME *pCreft = (NtAtt(d)->gotTime & EB_UT_FL_CTIME)
+ ? &(NtAtt(d)->Creft) : NULL;
+
+ if (!SetFileTime(hFile, pCreft, pAccft, pModft)) {
+ Info(slide, 0, ((char *)slide,
+ "warning: SetFileTime() for %s error %d\n",
+ FnFilter1(d->fn), (int)GetLastError()));
+ if (!errval)
+ errval = PK_WARN;
+ }
+ }
+ CloseHandle(hFile);
+ }
+
+ return errval;
+} /* end function set_direc_attribs() */
+
+#endif /* SET_DIR_ATTRIB */
+
+
+
+
+#ifdef TIMESTAMP
+
+/*************************/
+/* Function stamp_file() */
+/*************************/
+
+int stamp_file(__GPRO__ ZCONST char *fname, time_t modtime)
+{
+ FILETIME Modft; /* File time type defined in NT, `last modified' time */
+ HANDLE hFile; /* File handle defined in NT */
+ int errstat = 0; /* return status: 0 == "OK", -1 == "Failure" */
+ int fs_uses_loctime = FStampIsLocTime(__G__ fname);
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(fname) + 1);
+
+ INTERN_TO_ISO(fname, ansi_name);
+# define Ansi_Fname ansi_name
+#else
+# define Ansi_Fname fname
+#endif
+
+ /* open a handle to the file to prepare setting the mod-time stamp */
+ hFile = CreateFile(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if ( hFile == INVALID_HANDLE_VALUE ) {
+ errstat = -1;
+ } else {
+ /* convert time_t modtime into WIN32 native 64bit format */
+ UTIME_2_IZFILETIME(modtime, &Modft)
+ /* set Access and Modification times of the file to modtime */
+ if (!SetFileTime(hFile, NULL, &Modft, &Modft)) {
+ errstat = -1;
+ }
+ CloseHandle(hFile);
+ }
+
+ return errstat;
+
+#undef Ansi_Fname
+} /* end function stamp_file() */
+
+#endif /* TIMESTAMP */
+
+
+
+
+/***********************/
+/* Function isfloppy() */ /* more precisely, is it removable? */
+/***********************/
+
+static int isfloppy(int nDrive) /* 1 == A:, 2 == B:, etc. */
+{
+ char rootPathName[4];
+
+ rootPathName[0] = (char)('A' + nDrive - 1); /* build the root path */
+ rootPathName[1] = ':'; /* name, e.g. "A:/" */
+ rootPathName[2] = '/';
+ rootPathName[3] = '\0';
+
+ return (GetDriveType(rootPathName) == DRIVE_REMOVABLE);
+
+} /* end function isfloppy() */
+
+
+
+
+/*****************************/
+/* Function NTQueryVolInfo() */
+/*****************************/
+
+/*
+ * Note: 8.3 limits on filenames apply only to old-style FAT filesystems.
+ * More recent versions of Windows (Windows NT 3.5 / Windows 4.0)
+ * can support long filenames (LFN) on FAT filesystems. Check the
+ * filesystem maximum component length field to detect LFN support.
+ */
+
+static int NTQueryVolInfo(__GPRO__ const char *name)
+{
+ /* static char lastRootPath[4] = ""; */
+ /* static int lastVolOldFAT; */
+ /* static int lastVolLocTim; */
+ char *tmp0;
+ char tmp1[MAX_PATH], tmp2[MAX_PATH];
+ DWORD volSerNo, maxCompLen, fileSysFlags;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(name) + 1);
+
+ INTERN_TO_ISO(name, ansi_name);
+ name = ansi_name;
+#endif
+
+ if ((!strncmp(name, "//", 2) || !strncmp(name,"\\\\", 2)) &&
+ (name[2] != '\0' && name[2] != '/' && name[2] != '\\')) {
+ /* GetFullPathname() and GetVolumeInformation() do not work
+ * on UNC names. For now, we return "error".
+ * **FIXME**: check if UNC name is mapped to a drive letter
+ * and use mapped drive for volume info query.
+ */
+ return FALSE;
+ }
+ if (isalpha((uch)name[0]) && (name[1] == ':'))
+ tmp0 = (char *)name;
+ else
+ {
+ if (!GetFullPathName(name, MAX_PATH, tmp1, &tmp0))
+ return FALSE;
+ tmp0 = &tmp1[0];
+ }
+ if (strncmp(G.lastRootPath, tmp0, 2) != 0) {
+ /* For speed, we skip repeated queries for the same device */
+ strncpy(G.lastRootPath, tmp0, 2); /* Build the root path name, */
+ G.lastRootPath[2] = '/'; /* e.g. "A:/" */
+ G.lastRootPath[3] = '\0';
+
+ if (!GetVolumeInformation((LPCTSTR)G.lastRootPath,
+ (LPTSTR)tmp1, (DWORD)MAX_PATH,
+ &volSerNo, &maxCompLen, &fileSysFlags,
+ (LPTSTR)tmp2, (DWORD)MAX_PATH)) {
+ G.lastRootPath[0] = '\0';
+ return FALSE;
+ }
+
+ /* LFNs are available if the component length is > 12 */
+ G.lastVolOldFAT = (maxCompLen <= 12);
+/* G.lastVolOldFAT = !strncmp(strupr(tmp2), "FAT", 3); old version */
+
+ /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in
+ * local time!
+ */
+ G.lastVolLocTim = !strncmp(strupr(tmp2), "VFAT", 4) ||
+ !strncmp(tmp2, "HPFS", 4) ||
+ !strncmp(tmp2, "FAT", 3);
+ }
+
+ return TRUE;
+
+} /* end function NTQueryVolInfo() */
+
+
+
+
+/*****************************/
+/* Function IsVolumeOldFAT() */
+/*****************************/
+
+static int IsVolumeOldFAT(__GPRO__ const char *name)
+{
+ return (NTQueryVolInfo(__G__ name) ? G.lastVolOldFAT : FALSE);
+}
+
+
+
+
+#ifndef SFX
+
+/************************/
+/* Function do_wild() */ /* identical to OS/2 version */
+/************************/
+
+char *do_wild(__G__ wildspec)
+ __GDEF
+ ZCONST char *wildspec; /* only used first time on a given dir */
+{
+/* these statics are now declared in SYSTEM_SPECIFIC_GLOBALS in w32cfg.h:
+ static zDIR *wild_dir = NULL;
+ static ZCONST char *wildname;
+ static char *dirname, matchname[FILNAMSIZ];
+ static int notfirstcall=FALSE, have_dirname, dirnamelen;
+*/
+ char *fnamestart;
+ struct zdirent *file;
+
+ /* Even when we're just returning wildspec, we *always* do so in
+ * matchname[]--calling routine is allowed to append four characters
+ * to the returned string, and wildspec may be a pointer to argv[].
+ */
+ if (!G.notfirstcall) { /* first call: must initialize everything */
+ G.notfirstcall = TRUE;
+
+ if (!iswild(wildspec)) {
+ strncpy(G.matchname, wildspec, FILNAMSIZ);
+ G.matchname[FILNAMSIZ-1] = '\0';
+ G.have_dirname = FALSE;
+ G.wild_dir = NULL;
+ return G.matchname;
+ }
+
+ /* break the wildspec into a directory part and a wildcard filename */
+ if ((G.wildname = MBSRCHR(wildspec, '/')) == (ZCONST char *)NULL &&
+ (G.wildname = MBSRCHR(wildspec, ':')) == (ZCONST char *)NULL) {
+ G.dirname = ".";
+ G.dirnamelen = 1;
+ G.have_dirname = FALSE;
+ G.wildname = wildspec;
+ } else {
+ ++G.wildname; /* point at character after '/' or ':' */
+ G.dirnamelen = G.wildname - wildspec;
+ if ((G.dirname = (char *)malloc(G.dirnamelen+1)) == NULL) {
+ Info(slide, 1, ((char *)slide,
+ "warning: cannot allocate wildcard buffers\n"));
+ strncpy(G.matchname, wildspec, FILNAMSIZ);
+ G.matchname[FILNAMSIZ-1] = '\0';
+ return G.matchname; /* but maybe filespec was not a wildcard */
+ }
+ strncpy(G.dirname, wildspec, G.dirnamelen);
+ G.dirname[G.dirnamelen] = '\0'; /* terminate for strcpy below */
+ G.have_dirname = TRUE;
+ }
+ Trace((stderr, "do_wild: dirname = [%s]\n", FnFilter1(G.dirname)));
+
+ if ((G.wild_dir = (zvoid *)Opendir(G.dirname)) != NULL) {
+ if (G.have_dirname) {
+ strcpy(G.matchname, G.dirname);
+ fnamestart = G.matchname + G.dirnamelen;
+ } else
+ fnamestart = G.matchname;
+ while ((file = Readdir((zDIR *)G.wild_dir)) != NULL) {
+ Trace((stderr, "do_wild: Readdir returns %s\n",
+ FnFilter1(file->d_name)));
+ strcpy(fnamestart, file->d_name);
+ if (MBSRCHR(fnamestart, '.') == (char *)NULL)
+ strcat(fnamestart, ".");
+ if (match(fnamestart, G.wildname, TRUE WISEP) &&
+ /* skip "." and ".." directory entries */
+ strcmp(fnamestart, ".") && strcmp(fnamestart, "..")) {
+ Trace((stderr, "do_wild: match() succeeds\n"));
+ /* remove trailing dot */
+ fnamestart = plastchar(fnamestart, strlen(fnamestart));
+ if (*fnamestart == '.')
+ *fnamestart = '\0';
+ return G.matchname;
+ }
+ }
+ /* if we get to here directory is exhausted, so close it */
+ Closedir((zDIR *)G.wild_dir);
+ G.wild_dir = NULL;
+ }
+ Trace((stderr, "do_wild: Opendir(%s) returns NULL\n",
+ FnFilter1(G.dirname)));
+
+ /* return the raw wildspec in case that works (e.g., directory not
+ * searchable, but filespec was not wild and file is readable) */
+ strncpy(G.matchname, wildspec, FILNAMSIZ);
+ G.matchname[FILNAMSIZ-1] = '\0';
+ return G.matchname;
+ }
+
+ /* last time through, might have failed opendir but returned raw wildspec */
+ if (G.wild_dir == NULL) {
+ G.notfirstcall = FALSE; /* reset for new wildspec */
+ if (G.have_dirname)
+ free(G.dirname);
+ return (char *)NULL;
+ }
+
+ /* If we've gotten this far, we've read and matched at least one entry
+ * successfully (in a previous call), so dirname has been copied into
+ * matchname already.
+ */
+ if (G.have_dirname) {
+ /* strcpy(G.matchname, G.dirname); */
+ fnamestart = G.matchname + G.dirnamelen;
+ } else
+ fnamestart = G.matchname;
+ while ((file = Readdir((zDIR *)G.wild_dir)) != NULL) {
+ Trace((stderr, "do_wild: readdir returns %s\n",
+ FnFilter1(file->d_name)));
+ strcpy(fnamestart, file->d_name);
+ if (MBSRCHR(fnamestart, '.') == (char *)NULL)
+ strcat(fnamestart, ".");
+ if (match(fnamestart, G.wildname, TRUE WISEP)) {
+ Trace((stderr, "do_wild: match() succeeds\n"));
+ /* remove trailing dot */
+ fnamestart = plastchar(fnamestart, strlen(fnamestart));
+ if (*fnamestart == '.')
+ *fnamestart = '\0';
+ return G.matchname;
+ }
+ }
+
+ Closedir((zDIR *)G.wild_dir); /* at least one entry read; nothing left */
+ G.wild_dir = NULL;
+ G.notfirstcall = FALSE; /* reset for new wildspec */
+ if (G.have_dirname)
+ free(G.dirname);
+ return (char *)NULL;
+
+} /* end function do_wild() */
+
+#endif /* !SFX */
+
+
+
+/**********************/
+/* Function mapattr() */
+/**********************/
+
+/* Identical to MS-DOS, OS/2 versions. However, NT has a lot of extra
+ * permission stuff, so this function should probably be extended in the
+ * future. */
+
+int mapattr(__G)
+ __GDEF
+{
+ /* set archive bit for file entries (file is not backed up): */
+ G.pInfo->file_attr = ((unsigned)G.crec.external_file_attributes |
+ (G.crec.external_file_attributes & FILE_ATTRIBUTE_DIRECTORY ?
+ 0 : FILE_ATTRIBUTE_ARCHIVE)) & 0xff;
+ return 0;
+
+} /* end function mapattr() */
+
+
+
+
+/************************/
+/* Function mapname() */
+/************************/
+
+int mapname(__G__ renamed)
+ __GDEF
+ int renamed;
+/*
+ * returns:
+ * MPN_OK - no problem detected
+ * MPN_INF_TRUNC - caution (truncated filename)
+ * MPN_INF_SKIP - info "skip entry" (dir doesn't exist)
+ * MPN_ERR_SKIP - error -> skip entry
+ * MPN_ERR_TOOLONG - error -> path is too long
+ * MPN_NOMEM - error (memory allocation failed) -> skip entry
+ * [also MPN_VOL_LABEL, MPN_CREATED_DIR]
+ */
+{
+ char pathcomp[FILNAMSIZ]; /* path-component buffer */
+ char *pp, *cp=NULL; /* character pointers */
+ char *lastsemi = NULL; /* pointer to last semi-colon in pathcomp */
+#ifdef ACORN_FTYPE_NFS
+ char *lastcomma=(char *)NULL; /* pointer to last comma in pathcomp */
+ RO_extra_block *ef_spark; /* pointer Acorn FTYPE ef block */
+#endif
+ int killed_ddot = FALSE; /* is set when skipping "../" pathcomp */
+ int error;
+ register unsigned workch; /* hold the character being tested */
+
+
+/*---------------------------------------------------------------------------
+ Initialize various pointers and counters and stuff.
+ ---------------------------------------------------------------------------*/
+
+ /* can create path as long as not just freshening, or if user told us */
+ G.create_dirs = (!uO.fflag || renamed);
+
+ G.created_dir = FALSE; /* not yet */
+ G.renamed_fullpath = FALSE;
+ G.fnlen = strlen(G.filename);
+
+ if (renamed) {
+ cp = G.filename; /* point to beginning of renamed name... */
+ if (*cp) do {
+ if (*cp == '\\') /* convert backslashes to forward */
+ *cp = '/';
+ } while (*PREINCSTR(cp));
+ cp = G.filename;
+ /* use temporary rootpath if user gave full pathname */
+ if (G.filename[0] == '/') {
+ G.renamed_fullpath = TRUE;
+ pathcomp[0] = '/'; /* copy the '/' and terminate */
+ pathcomp[1] = '\0';
+ ++cp;
+ } else if (isalpha((uch)G.filename[0]) && G.filename[1] == ':') {
+ G.renamed_fullpath = TRUE;
+ pp = pathcomp;
+ *pp++ = *cp++; /* copy the "d:" (+ '/', possibly) */
+ *pp++ = *cp++;
+ if (*cp == '/')
+ *pp++ = *cp++; /* otherwise add "./"? */
+ *pp = '\0';
+ }
+ }
+
+ /* pathcomp is ignored unless renamed_fullpath is TRUE: */
+ if ((error = checkdir(__G__ pathcomp, INIT)) != 0) /* init path buffer */
+ return error; /* ...unless no mem or vol label on hard disk */
+
+ *pathcomp = '\0'; /* initialize translation buffer */
+ pp = pathcomp; /* point to translation buffer */
+ if (!renamed) { /* cp already set if renamed */
+ if (uO.jflag) /* junking directories */
+ cp = (char *)MBSRCHR(G.filename, '/');
+ if (cp == NULL) /* no '/' or not junking dirs */
+ cp = G.filename; /* point to internal zipfile-member pathname */
+ else
+ ++cp; /* point to start of last component of path */
+ }
+
+/*---------------------------------------------------------------------------
+ Begin main loop through characters in filename.
+ ---------------------------------------------------------------------------*/
+
+ for (; (workch = (uch)*cp) != 0; INCSTR(cp)) {
+
+ switch (workch) {
+ case '/': /* can assume -j flag not given */
+ *pp = '\0';
+ maskDOSdevice(__G__ pathcomp);
+ if (strcmp(pathcomp, ".") == 0) {
+ /* don't bother appending "./" to the path */
+ *pathcomp = '\0';
+ } else if (!uO.ddotflag && strcmp(pathcomp, "..") == 0) {
+ /* "../" dir traversal detected, skip over it */
+ *pathcomp = '\0';
+ killed_ddot = TRUE; /* set "show message" flag */
+ }
+ /* when path component is not empty, append it now */
+ if (*pathcomp != '\0' &&
+ ((error = checkdir(__G__ pathcomp, APPEND_DIR))
+ & MPN_MASK) > MPN_INF_TRUNC)
+ return error;
+ pp = pathcomp; /* reset conversion buffer for next piece */
+ lastsemi = (char *)NULL; /* leave direct. semi-colons alone */
+ break;
+
+ case ':': /* drive spec not stored, so no colon allowed */
+ case '\\': /* '\\' may come as normal filename char (not */
+ case '<': /* dir sep char!) from unix-like file system */
+ case '>': /* no redirection symbols allowed either */
+ case '|': /* no pipe signs allowed */
+ case '"': /* no double quotes allowed */
+ case '?': /* no wildcards allowed */
+ case '*':
+ *pp++ = '_'; /* these rules apply equally to FAT and NTFS */
+ break;
+ case ';': /* start of VMS version? */
+ lastsemi = pp; /* remove VMS version later... */
+ *pp++ = ';'; /* but keep semicolon for now */
+ break;
+
+#ifdef ACORN_FTYPE_NFS
+ case ',': /* NFS filetype extension */
+ lastcomma = pp;
+ *pp++ = ','; /* keep for now; may need to remove */
+ break; /* later, if requested */
+#endif
+
+ case ' ': /* keep spaces unless specifically */
+ /* NT cannot create filenames with spaces on FAT volumes */
+ if (uO.sflag || IsVolumeOldFAT(__G__ G.filename))
+ *pp++ = '_';
+ else
+ *pp++ = ' ';
+ break;
+
+ default:
+ /* allow European characters in filenames: */
+ if (isprint(workch) || workch >= 127)
+#ifdef _MBCS
+ {
+ memcpy(pp, cp, CLEN(cp));
+ INCSTR(pp);
+ }
+#else
+ *pp++ = (char)workch;
+#endif
+ } /* end switch */
+
+ } /* end while loop */
+
+ /* Show warning when stripping insecure "parent dir" path components */
+ if (killed_ddot && QCOND2) {
+ Info(slide, 0, ((char *)slide,
+ "warning: skipped \"../\" path component(s) in %s\n",
+ FnFilter1(G.filename)));
+ if (!(error & ~MPN_MASK))
+ error = (error & MPN_MASK) | PK_WARN;
+ }
+
+/*---------------------------------------------------------------------------
+ Report if directory was created (and no file to create: filename ended
+ in '/'), check name to be sure it exists, and combine path and name be-
+ fore exiting.
+ ---------------------------------------------------------------------------*/
+
+ if (lastchar(G.filename, G.fnlen) == '/') {
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(G.filename) + 1);
+
+ INTERN_TO_ISO(G.filename, ansi_name);
+# define Ansi_Fname ansi_name
+#else
+# define Ansi_Fname G.filename
+#endif
+ checkdir(__G__ G.filename, GETPATH);
+ if (G.created_dir) {
+ if (QCOND2) {
+ Info(slide, 0, ((char *)slide, " creating: %-22s\n",
+ FnFilter1(G.filename)));
+ }
+
+ /* set file attributes:
+ The default for newly created directories is "DIR attribute
+ flags set", so there is no need to change attributes unless
+ one of the DOS style attribute flags is set. The readonly
+ attribute need not be masked, since it does not prevent
+ modifications in the new directory. */
+ if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) {
+ if (!SetFileAttributes(Ansi_Fname, G.pInfo->file_attr & 0x7F))
+ Info(slide, 1, ((char *)slide,
+ "\nwarning (%d): could not set file attributes for %s\n",
+ (int)GetLastError(), FnFilter1(G.filename)));
+ }
+
+ /* set dir time (note trailing '/') */
+ return (error & ~MPN_MASK) | MPN_CREATED_DIR;
+ } else if (IS_OVERWRT_ALL) {
+ /* overwrite attributes of existing directory on user's request */
+
+ /* set file attributes: */
+ if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) {
+ if (!SetFileAttributes(Ansi_Fname, G.pInfo->file_attr & 0x7F))
+ Info(slide, 1, ((char *)slide,
+ "\nwarning (%d): could not set file attributes for %s\n",
+ (int)GetLastError(), FnFilter1(G.filename)));
+ }
+ }
+ /* dir existed already; don't look for data to extract */
+ return (error & ~MPN_MASK) | MPN_INF_SKIP;
+ }
+
+ *pp = '\0'; /* done with pathcomp: terminate it */
+
+ /* if not saving them, remove VMS version numbers (appended "###") */
+ if (!uO.V_flag && lastsemi) {
+ pp = lastsemi + 1; /* semi-colon was kept: expect #'s after */
+ while (isdigit((uch)(*pp)))
+ ++pp;
+ if (*pp == '\0') /* only digits between ';' and end: nuke */
+ *lastsemi = '\0';
+ }
+
+#ifdef ACORN_FTYPE_NFS
+ /* translate Acorn filetype information if asked to do so */
+ if (uO.acorn_nfs_ext &&
+ (ef_spark = (RO_extra_block *)
+ getRISCOSexfield(G.extra_field, G.lrec.extra_field_length))
+ != (RO_extra_block *)NULL)
+ {
+ /* file *must* have a RISC OS extra field */
+ long ft = (long)makelong(ef_spark->loadaddr);
+ /*32-bit*/
+ if (lastcomma) {
+ pp = lastcomma + 1;
+ while (isxdigit((uch)(*pp))) ++pp;
+ if (pp == lastcomma+4 && *pp == '\0') *lastcomma='\0'; /* nuke */
+ }
+ if ((ft & 1<<31)==0) ft=0x000FFD00;
+ sprintf(pathcomp+strlen(pathcomp), ",%03x", (int)(ft>>8) & 0xFFF);
+ }
+#endif /* ACORN_FTYPE_NFS */
+
+ maskDOSdevice(__G__ pathcomp);
+
+ if (*pathcomp == '\0') {
+ Info(slide, 1, ((char *)slide, "mapname: conversion of %s failed\n",
+ FnFilter1(G.filename)));
+ return (error & ~MPN_MASK) | MPN_ERR_SKIP;
+ }
+
+ checkdir(__G__ pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */
+ checkdir(__G__ G.filename, GETPATH);
+
+ if (G.pInfo->vollabel) { /* set the volume label now */
+ char drive[4];
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(G.filename) + 1);
+ INTERN_TO_ISO(G.filename, ansi_name);
+# define Ansi_Fname ansi_name
+#else
+# define Ansi_Fname G.filename
+#endif
+
+ /* Build a drive string, e.g. "b:" */
+ drive[0] = (char)('a' + G.nLabelDrive - 1);
+ strcpy(drive + 1, ":\\");
+ if (QCOND2)
+ Info(slide, 0, ((char *)slide, "labelling %s %-22s\n", drive,
+ FnFilter1(G.filename)));
+ if (!SetVolumeLabel(drive, Ansi_Fname)) {
+ Info(slide, 1, ((char *)slide,
+ "mapname: error setting volume label\n"));
+ return (error & ~MPN_MASK) | MPN_ERR_SKIP;
+ }
+ /* success: skip the "extraction" quietly */
+ return (error & ~MPN_MASK) | MPN_INF_SKIP;
+#undef Ansi_Fname
+ }
+
+ Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n",
+ FnFilter1(G.filename), error));
+ return error;
+
+} /* end function mapname() */
+
+
+
+
+/****************************/
+/* Function maskDOSdevice() */
+/****************************/
+
+static void maskDOSdevice(__G__ pathcomp)
+ __GDEF
+ char *pathcomp;
+{
+/*---------------------------------------------------------------------------
+ Put an underscore in front of the file name if the file name is a
+ DOS/WINDOWS device name like CON.*, AUX.*, PRN.*, etc. Trying to
+ extract such a file would fail at best and wedge us at worst.
+ ---------------------------------------------------------------------------*/
+#if !defined(S_IFCHR) && defined(_S_IFCHR)
+# define S_IFCHR _S_IFCHR
+#endif
+#if !defined(S_ISCHR)
+# if defined(_S_ISCHR)
+# define S_ISCHR(m) _S_ISCHR(m)
+# elif defined(S_IFCHR)
+# define S_ISCHR(m) ((m) & S_IFCHR)
+# endif
+#endif
+
+#ifdef DEBUG
+ if (stat(pathcomp, &G.statbuf) == 0) {
+ Trace((stderr,
+ "maskDOSdevice() stat(\"%s\", buf) st_mode result: %X, %o\n",
+ FnFilter1(pathcomp), G.statbuf.st_mode, G.statbuf.st_mode));
+ } else {
+ Trace((stderr, "maskDOSdevice() stat(\"%s\", buf) failed\n",
+ FnFilter1(pathcomp)));
+ }
+#endif
+ if (stat(pathcomp, &G.statbuf) == 0 && S_ISCHR(G.statbuf.st_mode)) {
+ extent i;
+
+ /* pathcomp contains a name of a DOS character device (builtin or
+ * installed device driver).
+ * Prepend a '_' to allow creation of the item in the file system.
+ */
+ for (i = strlen(pathcomp) + 1; i > 0; --i)
+ pathcomp[i] = pathcomp[i - 1];
+ pathcomp[0] = '_';
+ }
+} /* end function maskDOSdevice() */
+
+
+
+
+
+/**********************/
+/* Function map2fat() */ /* Not quite identical to OS/2 version */
+/**********************/
+
+static void map2fat(pathcomp, pEndFAT)
+ char *pathcomp, **pEndFAT;
+{
+ char *ppc = pathcomp; /* variable pointer to pathcomp */
+ char *pEnd = *pEndFAT; /* variable pointer to buildpathFAT */
+ char *pBegin = *pEndFAT; /* constant pointer to start of this comp. */
+ char *last_dot = NULL; /* last dot not converted to underscore */
+ register unsigned workch; /* hold the character being tested */
+
+
+ /* Only need check those characters which are legal in NTFS but not
+ * in FAT: to get here, must already have passed through mapname.
+ * Also must truncate path component to ensure 8.3 compliance.
+ */
+ while ((workch = (uch)*ppc++) != 0) {
+ switch (workch) {
+ case '[':
+ case ']':
+ case '+':
+ case ',':
+ case ';':
+ case '=':
+ *pEnd++ = '_'; /* convert brackets to underscores */
+ break;
+
+ case '.':
+ if (pEnd == *pEndFAT) { /* nothing appended yet... */
+ if (*ppc == '\0') /* don't bother appending a */
+ break; /* "./" component to the path */
+ else if (*ppc == '.' && ppc[1] == '\0') { /* "../" */
+ *pEnd++ = '.'; /* add first dot, */
+ *pEnd++ = '.'; /* add second dot, and */
+ ++ppc; /* skip over to pathcomp's end */
+ } else { /* FAT doesn't allow null filename */
+ *pEnd++ = '_'; /* bodies, so map .exrc -> _exrc */
+ } /* (_.exr would keep max 3 chars) */
+ } else { /* found dot within path component */
+ last_dot = pEnd; /* point at last dot so far... */
+ *pEnd++ = '_'; /* convert to underscore for now */
+ }
+ break;
+
+ default:
+ *pEnd++ = (char)workch;
+
+ } /* end switch */
+ } /* end while loop */
+
+ *pEnd = '\0'; /* terminate buildpathFAT */
+
+ /* NOTE: keep in mind that pEnd points to the end of the path
+ * component, and *pEndFAT still points to the *beginning* of it...
+ * Also note that the algorithm does not try to get too fancy:
+ * if there are no dots already, the name either gets truncated
+ * at 8 characters or the last underscore is converted to a dot
+ * (only if more characters are saved that way). In no case is
+ * a dot inserted between existing characters.
+ */
+ if (last_dot == NULL) { /* no dots: check for underscores... */
+ char *plu = MBSRCHR(pBegin, '_'); /* pointer to last underscore */
+
+ if ((plu != NULL) && /* found underscore: convert to dot? */
+ (MIN(plu - pBegin, 8) + MIN(pEnd - plu - 1, 3) > 8)) {
+ last_dot = plu; /* be lazy: drop through to next if-blk */
+ } else if ((pEnd - *pEndFAT) > 8) {
+ /* no underscore; or converting underscore to dot would save less
+ chars than leaving everything in the basename */
+ *pEndFAT += 8; /* truncate at 8 chars */
+ **pEndFAT = '\0';
+ } else
+ *pEndFAT = pEnd; /* whole thing fits into 8 chars or less */
+ }
+
+ if (last_dot != NULL) { /* one dot is OK: */
+ *last_dot = '.'; /* put it back in */
+
+ if ((last_dot - pBegin) > 8) {
+ char *p, *q;
+ int i;
+
+ p = last_dot;
+ q = last_dot = pBegin + 8;
+ for (i = 0; (i < 4) && *p; ++i) /* too many chars in basename: */
+ *q++ = *p++; /* shift .ext left and trun- */
+ *q = '\0'; /* cate/terminate it */
+ *pEndFAT = q;
+ } else if ((pEnd - last_dot) > 4) { /* too many chars in extension */
+ *pEndFAT = last_dot + 4;
+ **pEndFAT = '\0';
+ } else
+ *pEndFAT = pEnd; /* filename is fine; point at terminating zero */
+
+ if ((last_dot - pBegin) > 0 && last_dot[-1] == ' ')
+ last_dot[-1] = '_'; /* NO blank in front of '.'! */
+ }
+} /* end function map2fat() */
+
+
+
+
+/***********************/ /* Borrowed from os2.c for UnZip 5.1. */
+/* Function checkdir() */ /* Difference: no EA stuff */
+/***********************/ /* HPFS stuff works on NTFS too */
+
+int checkdir(__G__ pathcomp, flag)
+ __GDEF
+ char *pathcomp;
+ int flag;
+/*
+ * returns:
+ * MPN_OK - no problem detected
+ * MPN_INF_TRUNC - (on APPEND_NAME) truncated filename
+ * MPN_INF_SKIP - path doesn't exist, not allowed to create
+ * MPN_ERR_SKIP - path doesn't exist, tried to create and failed; or path
+ * exists and is not a directory, but is supposed to be
+ * MPN_ERR_TOOLONG - path is too long
+ * MPN_NOMEM - can't allocate memory for filename buffers
+ */
+{
+ /* static int rootlen = 0; */ /* length of rootpath */
+ /* static char *rootpath; */ /* user's "extract-to" directory */
+ /* static char *buildpathHPFS; */ /* full path (so far) to extracted file, */
+ /* static char *buildpathFAT; */ /* both HPFS/EA (main) and FAT versions */
+ /* static char *endHPFS; */ /* corresponding pointers to end of */
+ /* static char *endFAT; */ /* buildpath ('\0') */
+
+# define FN_MASK 7
+# define FUNCTION (flag & FN_MASK)
+
+
+
+/*---------------------------------------------------------------------------
+ APPEND_DIR: append the path component to the path being built and check
+ for its existence. If doesn't exist and we are creating directories, do
+ so for this one; else signal success or error as appropriate.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == APPEND_DIR) {
+ char *p = pathcomp;
+ int too_long = FALSE;
+
+ Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));
+ while ((*G.endHPFS = *p++) != '\0') /* copy to HPFS filename */
+ ++G.endHPFS;
+ if (!IsVolumeOldFAT(__G__ G.buildpathHPFS)) {
+ p = pathcomp;
+ while ((*G.endFAT = *p++) != '\0') /* copy to FAT filename, too */
+ ++G.endFAT;
+ } else
+ map2fat(pathcomp, &G.endFAT); /* map into FAT fn, update endFAT */
+
+ /* GRR: could do better check, see if overrunning buffer as we go:
+ * check endHPFS-buildpathHPFS after each append, set warning variable
+ * if within 20 of FILNAMSIZ; then if var set, do careful check when
+ * appending. Clear variable when begin new path. */
+
+ /* next check: need to append '/', at least one-char name, '\0' */
+ if ((G.endHPFS-G.buildpathHPFS) > FILNAMSIZ-3)
+ too_long = TRUE; /* check if extracting dir? */
+#ifdef FIX_STAT_BUG
+ /* Borland C++ 5.0 does not handle a call to stat() well if the
+ * directory does not exist (it tends to crash in strange places.)
+ * This is apparently a problem only when compiling for GUI rather
+ * than console. The code below attempts to work around this problem.
+ */
+ if (access(G.buildpathFAT, 0) != 0) {
+ if (!G.create_dirs) { /* told not to create (freshening) */
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ /* path doesn't exist: nothing to do */
+ return MPN_INF_SKIP;
+ }
+ if (too_long) { /* GRR: should allow FAT extraction w/o EAs */
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: path too long: %s\n",
+ FnFilter1(G.buildpathHPFS)));
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ /* no room for filenames: fatal */
+ return MPN_ERR_TOOLONG;
+ }
+ if (MKDIR(G.buildpathFAT, 0777) == -1) { /* create the directory */
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: cannot create %s\n\
+ unable to process %s.\n",
+ FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ /* path didn't exist, tried to create, failed */
+ return MPN_ERR_SKIP;
+ }
+ G.created_dir = TRUE;
+ }
+#endif /* FIX_STAT_BUG */
+ if (SSTAT(G.buildpathFAT, &G.statbuf)) /* path doesn't exist */
+ {
+ if (!G.create_dirs) { /* told not to create (freshening) */
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ /* path doesn't exist: nothing to do */
+ return MPN_INF_SKIP;
+ }
+ if (too_long) { /* GRR: should allow FAT extraction w/o EAs */
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: path too long: %s\n",
+ FnFilter1(G.buildpathHPFS)));
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ /* no room for filenames: fatal */
+ return MPN_ERR_TOOLONG;
+ }
+ if (MKDIR(G.buildpathFAT, 0777) == -1) { /* create the directory */
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: cannot create %s\n\
+ unable to process %s.\n",
+ FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ /* path didn't exist, tried to create, failed */
+ return MPN_ERR_SKIP;
+ }
+ G.created_dir = TRUE;
+ } else if (!S_ISDIR(G.statbuf.st_mode)) {
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: %s exists but is not directory\n \
+ unable to process %s.\n",
+ FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ /* path existed but wasn't dir */
+ return MPN_ERR_SKIP;
+ }
+ if (too_long) {
+ Info(slide, 1, ((char *)slide,
+ "checkdir error: path too long: %s\n",
+ FnFilter1(G.buildpathHPFS)));
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ /* no room for filenames: fatal */
+ return MPN_ERR_TOOLONG;
+ }
+ *G.endHPFS++ = '/';
+ *G.endFAT++ = '/';
+ *G.endHPFS = *G.endFAT = '\0';
+ Trace((stderr, "buildpathHPFS now = [%s]\nbuildpathFAT now = [%s]\n",
+ FnFilter1(G.buildpathHPFS), FnFilter2(G.buildpathFAT)));
+ return MPN_OK;
+
+ } /* end if (FUNCTION == APPEND_DIR) */
+
+/*---------------------------------------------------------------------------
+ GETPATH: copy full FAT path to the string pointed at by pathcomp (want
+ filename to reflect name used on disk, not EAs; if full path is HPFS,
+ buildpathFAT and buildpathHPFS will be identical). Also free both paths.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == GETPATH) {
+ Trace((stderr, "getting and freeing FAT path [%s]\n",
+ FnFilter1(G.buildpathFAT)));
+ Trace((stderr, "freeing HPFS path [%s]\n",
+ FnFilter1(G.buildpathHPFS)));
+ strcpy(pathcomp, G.buildpathFAT);
+ free(G.buildpathFAT);
+ free(G.buildpathHPFS);
+ G.buildpathHPFS = G.buildpathFAT = G.endHPFS = G.endFAT = NULL;
+ return MPN_OK;
+ }
+
+/*---------------------------------------------------------------------------
+ APPEND_NAME: assume the path component is the filename; append it and
+ return without checking for existence.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == APPEND_NAME) {
+ char *p = pathcomp;
+ int error = MPN_OK;
+
+ Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
+ while ((*G.endHPFS = *p++) != '\0') { /* copy to HPFS filename */
+ ++G.endHPFS;
+ if ((G.endHPFS-G.buildpathHPFS) >= FILNAMSIZ) {
+ *--G.endHPFS = '\0';
+ Info(slide, 1, ((char *)slide,
+ "checkdir warning: path too long; truncating\n \
+ %s\n -> %s\n",
+ FnFilter1(G.filename), FnFilter2(G.buildpathHPFS)));
+ error = MPN_INF_TRUNC; /* filename truncated */
+ }
+ }
+
+ if ( G.pInfo->vollabel || !IsVolumeOldFAT(__G__ G.buildpathHPFS)) {
+ p = pathcomp;
+ while ((*G.endFAT = *p++) != '\0') /* copy to FAT filename, too */
+ ++G.endFAT;
+ } else
+ map2fat(pathcomp, &G.endFAT); /* map into FAT fn, update endFAT */
+ Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT: %s\n",
+ FnFilter1(G.buildpathHPFS), FnFilter2(G.buildpathFAT)));
+
+ return error; /* could check for existence, prompt for new name... */
+
+ } /* end if (FUNCTION == APPEND_NAME) */
+
+/*---------------------------------------------------------------------------
+ INIT: allocate and initialize buffer space for the file currently being
+ extracted. If file was renamed with an absolute path, don't prepend the
+ extract-to path.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == INIT) {
+ Trace((stderr, "initializing buildpathHPFS and buildpathFAT to "));
+#ifdef ACORN_FTYPE_NFS
+ if ((G.buildpathHPFS = (char *)malloc(G.fnlen+G.rootlen+
+ (uO.acorn_nfs_ext ? 5 : 1)))
+#else
+ if ((G.buildpathHPFS = (char *)malloc(G.fnlen+G.rootlen+1))
+#endif
+ == NULL)
+ return MPN_NOMEM;
+#ifdef ACORN_FTYPE_NFS
+ if ((G.buildpathFAT = (char *)malloc(G.fnlen+G.rootlen+
+ (uO.acorn_nfs_ext ? 5 : 1)))
+#else
+ if ((G.buildpathFAT = (char *)malloc(G.fnlen+G.rootlen+1))
+#endif
+ == NULL) {
+ free(G.buildpathHPFS);
+ return MPN_NOMEM;
+ }
+ if (G.pInfo->vollabel) { /* use root or renamed path, but don't store */
+/* GRR: for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */
+ if (G.renamed_fullpath && pathcomp[1] == ':')
+ *G.buildpathHPFS = (char)ToLower(*pathcomp);
+ else if (!G.renamed_fullpath && G.rootlen > 1 &&
+ G.rootpath[1] == ':')
+ *G.buildpathHPFS = (char)ToLower(*G.rootpath);
+ else {
+ char tmpN[MAX_PATH], *tmpP;
+ if (GetFullPathName(".", MAX_PATH, tmpN, &tmpP) > MAX_PATH)
+ { /* by definition of MAX_PATH we should never get here */
+ Info(slide, 1, ((char *)slide,
+ "checkdir warning: current dir path too long\n"));
+ return MPN_INF_TRUNC; /* can't get drive letter */
+ }
+ G.nLabelDrive = *tmpN - 'a' + 1;
+ *G.buildpathHPFS = (char)(G.nLabelDrive - 1 + 'a');
+ }
+ G.nLabelDrive = *G.buildpathHPFS - 'a' + 1; /* save for mapname() */
+ if (uO.volflag == 0 || *G.buildpathHPFS < 'a' /* no labels/bogus? */
+ || (uO.volflag == 1 && !isfloppy(G.nLabelDrive))) { /* !fixed */
+ free(G.buildpathHPFS);
+ free(G.buildpathFAT);
+ return MPN_VOL_LABEL; /* skipping with message */
+ }
+ *G.buildpathHPFS = '\0';
+ } else if (G.renamed_fullpath) /* pathcomp = valid data */
+ strcpy(G.buildpathHPFS, pathcomp);
+ else if (G.rootlen > 0)
+ strcpy(G.buildpathHPFS, G.rootpath);
+ else
+ *G.buildpathHPFS = '\0';
+ G.endHPFS = G.buildpathHPFS;
+ G.endFAT = G.buildpathFAT;
+ while ((*G.endFAT = *G.endHPFS) != '\0') {
+ ++G.endFAT;
+ ++G.endHPFS;
+ }
+ Trace((stderr, "[%s]\n", FnFilter1(G.buildpathHPFS)));
+ return MPN_OK;
+ }
+
+/*---------------------------------------------------------------------------
+ ROOT: if appropriate, store the path in rootpath and create it if neces-
+ sary; else assume it's a zipfile member and return. This path segment
+ gets used in extracting all members from every zipfile specified on the
+ command line. Note that under OS/2 and MS-DOS, if a candidate extract-to
+ directory specification includes a drive letter (leading "x:"), it is
+ treated just as if it had a trailing '/'--that is, one directory level
+ will be created if the path doesn't exist, unless this is otherwise pro-
+ hibited (e.g., freshening).
+ ---------------------------------------------------------------------------*/
+
+#if (!defined(SFX) || defined(SFX_EXDIR))
+ if (FUNCTION == ROOT) {
+ Trace((stderr, "initializing root path to [%s]\n",
+ FnFilter1(pathcomp)));
+ if (pathcomp == NULL) {
+ G.rootlen = 0;
+ return MPN_OK;
+ }
+ if (G.rootlen > 0) /* rootpath was already set, nothing to do */
+ return MPN_OK;
+ if ((G.rootlen = strlen(pathcomp)) > 0) {
+ int had_trailing_pathsep=FALSE, has_drive=FALSE, add_dot=FALSE;
+ char *tmproot;
+
+ if ((tmproot = (char *)malloc(G.rootlen+3)) == (char *)NULL) {
+ G.rootlen = 0;
+ return MPN_NOMEM;
+ }
+ strcpy(tmproot, pathcomp);
+ if (isalpha((uch)tmproot[0]) && tmproot[1] == ':')
+ has_drive = TRUE; /* drive designator */
+ if (tmproot[G.rootlen-1] == '/' || tmproot[G.rootlen-1] == '\\') {
+ tmproot[--G.rootlen] = '\0';
+ had_trailing_pathsep = TRUE;
+ }
+ if (has_drive && (G.rootlen == 2)) {
+ if (!had_trailing_pathsep) /* i.e., original wasn't "x:/" */
+ add_dot = TRUE; /* relative path: add '.' before '/' */
+ } else if (G.rootlen > 0) { /* need not check "x:." and "x:/" */
+ if (SSTAT(tmproot, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode))
+ {
+ /* path does not exist */
+ if (!G.create_dirs /* || iswild(tmproot) */ ) {
+ free(tmproot);
+ G.rootlen = 0;
+ /* treat as stored file */
+ return MPN_INF_SKIP;
+ }
+ /* create directory (could add loop here scanning tmproot
+ * to create more than one level, but really necessary?) */
+ if (MKDIR(tmproot, 0777) == -1) {
+ Info(slide, 1, ((char *)slide,
+ "checkdir: cannot create extraction directory: %s\n",
+ FnFilter1(tmproot)));
+ free(tmproot);
+ G.rootlen = 0;
+ /* path didn't exist, tried to create, failed: */
+ /* file exists, or need 2+ subdir levels */
+ return MPN_ERR_SKIP;
+ }
+ }
+ }
+ if (add_dot) /* had just "x:", make "x:." */
+ tmproot[G.rootlen++] = '.';
+ tmproot[G.rootlen++] = '/';
+ tmproot[G.rootlen] = '\0';
+ if ((G.rootpath = (char *)realloc(tmproot, G.rootlen+1)) == NULL) {
+ free(tmproot);
+ G.rootlen = 0;
+ return MPN_NOMEM;
+ }
+ Trace((stderr, "rootpath now = [%s]\n", FnFilter1(G.rootpath)));
+ }
+ return MPN_OK;
+ }
+#endif /* !SFX || SFX_EXDIR */
+
+/*---------------------------------------------------------------------------
+ END: free rootpath, immediately prior to program exit.
+ ---------------------------------------------------------------------------*/
+
+ if (FUNCTION == END) {
+ Trace((stderr, "freeing rootpath\n"));
+ if (G.rootlen > 0) {
+ free(G.rootpath);
+ G.rootlen = 0;
+ }
+ return MPN_OK;
+ }
+
+ return MPN_INVALID; /* should never reach */
+
+} /* end function checkdir() */
+
+
+
+
+
+#ifndef SFX
+
+/*************************/
+/* Function dateformat() */
+/*************************/
+
+int dateformat()
+{
+ TCHAR df[2]; /* LOCALE_IDATE has a maximum value of 2 */
+
+ if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDATE, df, 2) != 0) {
+ switch (df[0])
+ {
+ case '0':
+ return DF_MDY;
+ case '1':
+ return DF_DMY;
+ case '2':
+ return DF_YMD;
+ }
+ }
+ return DF_MDY;
+}
+
+
+/****************************/
+/* Function dateseparator() */
+/****************************/
+
+char dateseparator()
+{
+ TCHAR df[2]; /* use only if it is one character */
+
+ if ((GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDATE, df, 2) != 0) &&
+ (df[0] != '\0'))
+ return df[0];
+ else
+ return '-';
+}
+
+
+#ifndef WINDLL
+
+/************************/
+/* Function version() */
+/************************/
+
+void version(__G)
+ __GDEF
+{
+ int len;
+#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__DJGPP__))
+ char buf[80];
+#if (defined(_MSC_VER) && (_MSC_VER > 900))
+ char buf2[80];
+#endif
+#endif
+
+ len = sprintf((char *)slide, CompiledWith,
+
+#if defined(_MSC_VER) /* MSC == VC++, but what about SDK compiler? */
+ (sprintf(buf, "Microsoft C %d.%02d ", _MSC_VER/100, _MSC_VER%100), buf),
+# if (_MSC_VER == 800)
+ "(Visual C++ v1.1)",
+# elif (_MSC_VER == 850)
+ "(Windows NT v3.5 SDK)",
+# elif (_MSC_VER == 900)
+ "(Visual C++ v2.x)",
+# elif (_MSC_VER > 900)
+ (sprintf(buf2, "(Visual C++ %d.%d)", _MSC_VER/100 - 6, _MSC_VER%100/10),
+ buf2),
+# else
+ "(bad version)",
+# endif
+#elif defined(__WATCOMC__)
+# if (__WATCOMC__ % 10 > 0)
+ (sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100,
+ __WATCOMC__ % 100), buf), "",
+# else
+ (sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100,
+ (__WATCOMC__ % 100) / 10), buf), "",
+# endif
+#elif defined(__BORLANDC__)
+ "Borland C++",
+# if (__BORLANDC__ < 0x0200)
+ " 1.0",
+# elif (__BORLANDC__ == 0x0200)
+ " 2.0",
+# elif (__BORLANDC__ == 0x0400)
+ " 3.0",
+# elif (__BORLANDC__ == 0x0410) /* __TURBOC__ = 0x0310 */
+ " 3.1",
+# elif (__BORLANDC__ == 0x0452) /* __TURBOC__ = 0x0320 */
+ " 4.0 or 4.02",
+# elif (__BORLANDC__ == 0x0460) /* __TURBOC__ = 0x0340 */
+ " 4.5",
+# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0340 */
+ " 5.0",
+# elif (__BORLANDC__ == 0x0520) /* __TURBOC__ = 0x0520 */
+ " 5.2 (C++ Builder 1.0)",
+# elif (__BORLANDC__ == 0x0530) /* __TURBOC__ = 0x0530 */
+ " 5.3 (C++ Builder 3.0)",
+# elif (__BORLANDC__ == 0x0540) /* __TURBOC__ = 0x0540 */
+ " 5.4 (C++ Builder 4.0)",
+# elif (__BORLANDC__ == 0x0550) /* __TURBOC__ = 0x0550 */
+ " 5.5 (C++ Builder 5.0)",
+# elif (__BORLANDC__ == 0x0551) /* __TURBOC__ = 0x0551 */
+ " 5.5.1 (C++ Builder 5.0.1)",
+# elif (__BORLANDC__ == 0x0560) /* __TURBOC__ = 0x0560 */
+ " 6.0 (C++ Builder 6.0)",
+# else
+ " later than 6.0",
+# endif
+#elif defined(__LCC__)
+ "LCC-Win32", "",
+#elif defined(__GNUC__)
+# if defined(__RSXNT__)
+# if (defined(__DJGPP__) && !defined(__EMX__))
+ (sprintf(buf, "rsxnt(djgpp v%d.%02d) / gcc ",
+ __DJGPP__, __DJGPP_MINOR__), buf),
+# elif defined(__DJGPP__)
+ (sprintf(buf, "rsxnt(emx+djgpp v%d.%02d) / gcc ",
+ __DJGPP__, __DJGPP_MINOR__), buf),
+# elif (defined(__GO32__) && !defined(__EMX__))
+ "rsxnt(djgpp v1.x) / gcc ",
+# elif defined(__GO32__)
+ "rsxnt(emx + djgpp v1.x) / gcc ",
+# elif defined(__EMX__)
+ "rsxnt(emx)+gcc ",
+# else
+ "rsxnt(unknown) / gcc ",
+# endif
+# elif defined(__CYGWIN__)
+ "cygnus win32 / gcc ",
+# elif defined(__MINGW32__)
+ "mingw32 / gcc ",
+# else
+ "gcc ",
+# endif
+ __VERSION__,
+#else /* !_MSC_VER, !__WATCOMC__, !__BORLANDC__, !__LCC__, !__GNUC__ */
+ "unknown compiler (SDK?)", "",
+#endif /* ?compilers */
+
+ "\nWindows 9x / Windows NT/2K/XP/2K3", " (32-bit)",
+
+#ifdef __DATE__
+ " on ", __DATE__
+#else
+ "", ""
+#endif
+ );
+
+ (*G.message)((zvoid *)&G, slide, (ulg)len, 0);
+
+ return;
+
+} /* end function version() */
+
+#endif /* !WINDLL */
+#endif /* !SFX */
+
+
+
+#ifdef MORE
+
+int screensize(int *tt_rows, int *tt_cols)
+{
+ HANDLE hstdout;
+ CONSOLE_SCREEN_BUFFER_INFO scr;
+
+ hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ GetConsoleScreenBufferInfo(hstdout, &scr);
+ if (tt_rows != NULL) *tt_rows = scr.srWindow.Bottom - scr.srWindow.Top + 1;
+ if (tt_cols != NULL) *tt_cols = scr.srWindow.Right - scr.srWindow.Left + 1;
+ return 0; /* signal success */
+}
+
+#endif /* MORE */
+
+
+
+#ifdef W32_STAT_BANDAID
+
+/* All currently known variants of WIN32 operating systems (Windows 95/98,
+ * WinNT 3.x, 4.0, 5.x) have a nasty bug in the OS kernel concerning
+ * conversions between UTC and local time: In the time conversion functions
+ * of the Win32 API, the timezone offset (including seasonal daylight saving
+ * shift) between UTC and local time evaluation is erratically based on the
+ * current system time. The correct evaluation must determine the offset
+ * value as it {was/is/will be} for the actual time to be converted.
+ *
+ * Newer versions of MS C runtime lib's stat() returns utc time-stamps so
+ * that localtime(timestamp) corresponds to the (potentially false) local
+ * time shown by the OS' system programs (Explorer, command shell dir, etc.)
+ * The RSXNT port follows the same strategy, but fails to recognize the
+ * access-time attribute.
+ *
+ * For the NTFS file system (and other filesystems that store time-stamps
+ * as UTC values), this results in st_mtime (, st_{c|a}time) fields which
+ * are not stable but vary according to the seasonal change of "daylight
+ * saving time in effect / not in effect".
+ *
+ * Other C runtime libs (CygWin, or the crtdll.dll supplied with Win9x/NT
+ * return the unix-time equivalent of the UTC FILETIME values as got back
+ * from the Win32 API call. This time, return values from NTFS are correct
+ * whereas utimes from files on (V)FAT volumes vary according to the DST
+ * switches.
+ *
+ * To achieve timestamp consistency of UTC (UT extra field) values in
+ * Zip archives, the Info-ZIP programs require work-around code for
+ * proper time handling in stat() (and other time handling routines).
+ *
+ * However, nowadays most other programs on Windows systems use the
+ * time conversion strategy of Microsofts C runtime lib "msvcrt.dll".
+ * To improve interoperability in environments where a "consistent" (but
+ * false) "UTC<-->LocalTime" conversion is preferred over "stable" time
+ * stamps, the Info-ZIP specific time conversion handling can be
+ * deactivated by defining the preprocessor flag NO_W32TIMES_IZFIX.
+ */
+/* stat() functions under Windows95 tend to fail for root directories. *
+ * Watcom and Borland, at least, are affected by this bug. Watcom made *
+ * a partial fix for 11.0 but still missed some cases. This substitute *
+ * detects the case and fills in reasonable values. Otherwise we get *
+ * effects like failure to extract to a root dir because it's not found. */
+
+int zstat_win32(__W32STAT_GLOBALS__ const char *path, struct stat *buf)
+{
+ if (!stat(path, buf))
+ {
+ /* stat was successful, now redo the time-stamp fetches */
+#ifndef NO_W32TIMES_IZFIX
+ int fs_uses_loctime = FStampIsLocTime(__G__ path);
+#endif
+ HANDLE h;
+ FILETIME Modft, Accft, Creft;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(path) + 1);
+
+ INTERN_TO_ISO(path, ansi_path);
+# define Ansi_Path ansi_path
+#else
+# define Ansi_Path path
+#endif
+
+ TTrace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime));
+ h = CreateFile(Ansi_Path, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h != INVALID_HANDLE_VALUE) {
+ BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
+ CloseHandle(h);
+
+ if (ftOK) {
+ FTTrace((stdout, "GetFileTime returned Modft", 0, &Modft));
+ FTTrace((stdout, "GetFileTime returned Creft", 0, &Creft));
+#ifndef NO_W32TIMES_IZFIX
+ if (!fs_uses_loctime) {
+ /* On a filesystem that stores UTC timestamps, we refill
+ * the time fields of the struct stat buffer by directly
+ * using the UTC values as returned by the Win32
+ * GetFileTime() API call.
+ */
+ NtfsFileTime2utime(&Modft, &(buf->st_mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ NtfsFileTime2utime(&Accft, &(buf->st_atime));
+ else
+ buf->st_atime = buf->st_mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ NtfsFileTime2utime(&Creft, &(buf->st_ctime));
+ else
+ buf->st_ctime = buf->st_mtime;
+ TTrace((stdout,"NTFS, recalculated modtime %08lx\n",
+ buf->st_mtime));
+ } else
+#endif /* NO_W32TIMES_IZFIX */
+ {
+ /* On VFAT and FAT-like filesystems, the FILETIME values
+ * are converted back to the stable local time before
+ * converting them to UTC unix time-stamps.
+ */
+ VFatFileTime2utime(&Modft, &(buf->st_mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ VFatFileTime2utime(&Accft, &(buf->st_atime));
+ else
+ buf->st_atime = buf->st_mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ VFatFileTime2utime(&Creft, &(buf->st_ctime));
+ else
+ buf->st_ctime = buf->st_mtime;
+ TTrace((stdout, "VFAT, recalculated modtime %08lx\n",
+ buf->st_mtime));
+ }
+ }
+ }
+# undef Ansi_Path
+ return 0;
+ }
+#ifdef W32_STATROOT_FIX
+ else
+ {
+ DWORD flags;
+#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(path) + 1);
+
+ INTERN_TO_ISO(path, ansi_path);
+# define Ansi_Path ansi_path
+#else
+# define Ansi_Path path
+#endif
+
+ flags = GetFileAttributes(Ansi_Path);
+ if (flags != 0xFFFFFFFF && flags & FILE_ATTRIBUTE_DIRECTORY) {
+ Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
+ FnFilter1(path)));
+ memset(buf, 0, sizeof(struct stat));
+ buf->st_atime = buf->st_ctime = buf->st_mtime =
+ dos_to_unix_time(DOSTIME_MINIMUM); /* 1-1-80 */
+ buf->st_mode = S_IFDIR | S_IREAD |
+ ((flags & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE);
+ return 0;
+ } /* assumes: stat() won't fail on non-dirs without good reason */
+# undef Ansi_Path
+ }
+#endif /* W32_STATROOT_FIX */
+ return -1;
+}
+
+#endif /* W32_STAT_BANDAID */
+
+
+
+#ifdef W32_USE_IZ_TIMEZONE
+#include "timezone.h"
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule);
+
+static void conv_to_rule(LPSYSTEMTIME lpw32tm, struct rule * ZCONST ptrule)
+{
+ if (lpw32tm->wYear != 0) {
+ ptrule->r_type = JULIAN_DAY;
+ ptrule->r_day = ydays[lpw32tm->wMonth - 1] + lpw32tm->wDay;
+ } else {
+ ptrule->r_type = MONTH_NTH_DAY_OF_WEEK;
+ ptrule->r_mon = lpw32tm->wMonth;
+ ptrule->r_day = lpw32tm->wDayOfWeek;
+ ptrule->r_week = lpw32tm->wDay;
+ }
+ ptrule->r_time = (long)lpw32tm->wHour * SECSPERHOUR +
+ (long)(lpw32tm->wMinute * SECSPERMIN) +
+ (long)lpw32tm->wSecond;
+}
+
+int GetPlatformLocalTimezone(register struct state * ZCONST sp,
+ void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res,
+ ZCONST struct rule * ZCONST start,
+ ZCONST struct rule * ZCONST end))
+{
+ TIME_ZONE_INFORMATION tzinfo;
+ DWORD res;
+
+ /* read current timezone settings from registry if TZ envvar missing */
+ res = GetTimeZoneInformation(&tzinfo);
+ if (res != TIME_ZONE_ID_INVALID)
+ {
+ struct rule startrule, stoprule;
+
+ conv_to_rule(&(tzinfo.StandardDate), &stoprule);
+ conv_to_rule(&(tzinfo.DaylightDate), &startrule);
+ sp->timecnt = 0;
+ sp->ttis[0].tt_abbrind = 0;
+ if ((sp->charcnt =
+ WideCharToMultiByte(CP_ACP, 0, tzinfo.StandardName, -1,
+ sp->chars, sizeof(sp->chars), NULL, NULL))
+ == 0)
+ sp->chars[sp->charcnt++] = '\0';
+ sp->ttis[1].tt_abbrind = sp->charcnt;
+ sp->charcnt +=
+ WideCharToMultiByte(CP_ACP, 0, tzinfo.DaylightName, -1,
+ sp->chars + sp->charcnt,
+ sizeof(sp->chars) - sp->charcnt, NULL, NULL);
+ if ((sp->charcnt - sp->ttis[1].tt_abbrind) == 0)
+ sp->chars[sp->charcnt++] = '\0';
+ sp->ttis[0].tt_gmtoff = - (tzinfo.Bias + tzinfo.StandardBias)
+ * MINSPERHOUR;
+ sp->ttis[1].tt_gmtoff = - (tzinfo.Bias + tzinfo.DaylightBias)
+ * MINSPERHOUR;
+ sp->ttis[0].tt_isdst = 0;
+ sp->ttis[1].tt_isdst = 1;
+ sp->typecnt = (startrule.r_mon == 0 && stoprule.r_mon == 0) ? 1 : 2;
+
+ if (sp->typecnt > 1)
+ (*fill_tzstate_from_rules)(sp, &startrule, &stoprule);
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif /* W32_USE_IZ_TIMEZONE */
+
+#endif /* !FUNZIP */
+
+
+
+#ifndef WINDLL
+/* This replacement getch() function was originally created for Watcom C
+ * and then additionally used with CYGWIN. Since UnZip 5.4, all other Win32
+ * ports apply this replacement rather that their supplied getch() (or
+ * alike) function. There are problems with unabsorbed LF characters left
+ * over in the keyboard buffer under Win95 (and 98) when ENTER was pressed.
+ * (Under Win95, ENTER returns two(!!) characters: CR-LF.) This problem
+ * does not appear when run on a WinNT console prompt!
+ */
+
+/* Watcom 10.6's getch() does not handle Alt+<digit><digit><digit>. */
+/* Note that if PASSWD_FROM_STDIN is defined, the file containing */
+/* the password must have a carriage return after the word, not a */
+/* Unix-style newline (linefeed only). This discards linefeeds. */
+
+int getch_win32(void)
+{
+ HANDLE stin;
+ DWORD rc;
+ unsigned char buf[2];
+ int ret = -1;
+ DWORD odemode = ~(DWORD)0;
+
+# ifdef PASSWD_FROM_STDIN
+ stin = GetStdHandle(STD_INPUT_HANDLE);
+# else
+ stin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (stin == INVALID_HANDLE_VALUE)
+ return -1;
+# endif
+ if (GetConsoleMode(stin, &odemode))
+ SetConsoleMode(stin, ENABLE_PROCESSED_INPUT); /* raw except ^C noticed */
+ if (ReadFile(stin, &buf, 1, &rc, NULL) && rc == 1)
+ ret = buf[0];
+ /* when the user hits return we get CR LF. We discard the LF, not the CR,
+ * because when we call this for the first time after a previous input
+ * such as the one for "replace foo? [y]es, ..." the LF may still be in
+ * the input stream before whatever the user types at our prompt. */
+ if (ret == '\n')
+ if (ReadFile(stin, &buf, 1, &rc, NULL) && rc == 1)
+ ret = buf[0];
+ if (odemode != ~(DWORD)0)
+ SetConsoleMode(stin, odemode);
+# ifndef PASSWD_FROM_STDIN
+ CloseHandle(stin);
+# endif
+ return ret;
+}
+#endif /* !WINDLL */
Property changes on: trunk/build/install/installer/win32/win32.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/installer/zip.h
===================================================================
--- trunk/build/install/installer/zip.h (rev 0)
+++ trunk/build/install/installer/zip.h 2008-03-31 12:15:21 UTC (rev 1490)
@@ -0,0 +1,24 @@
+/*
+ Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/* This is a dummy zip.h to allow the source files shared with Zip (crypt.c,
+ crc32.c, crctab.c, ttyio.c) to compile for UnZip. (In case you are looking
+ for the Info-ZIP license, please follow the pointers above.) */
+
+#ifndef __zip_h /* don't include more than once */
+#define __zip_h
+
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+#define local static
+
+#define ZE_MEM PK_MEM
+#define ziperr(c, h) return
+
+#endif /* !__zip_h */
Property changes on: trunk/build/install/installer/zip.h
___________________________________________________________________
Name: svn:eol-style
+ native
16 years, 9 months
JBoss Native SVN: r1489 - in trunk/build/install: xtool and 1 other directory.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-03-31 08:14:20 -0400 (Mon, 31 Mar 2008)
New Revision: 1489
Added:
trunk/build/install/xtool/
trunk/build/install/xtool/NMAKEmakefile
trunk/build/install/xtool/jboss.ico
trunk/build/install/xtool/redhat.ico
trunk/build/install/xtool/xtool.c
trunk/build/install/xtool/xtool.rc
Log:
Add Generic build tool utilities (rmdir, touch, etc)
Added: trunk/build/install/xtool/NMAKEmakefile
===================================================================
--- trunk/build/install/xtool/NMAKEmakefile (rev 0)
+++ trunk/build/install/xtool/NMAKEmakefile 2008-03-31 12:14:20 UTC (rev 1489)
@@ -0,0 +1,71 @@
+# Copyright(c) 2006 Red Hat Middleware, LLC,
+# and individual contributors as indicated by the @authors tag.
+# See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library in the file COPYING.LIB;
+# if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+# @author Mladen Turk
+#
+
+TARGET = EXE
+PROJECT = xtool
+!include <..\..\NMAKEcommon.inc>
+
+!IF !DEFINED(SRCDIR) || "$(SRCDIR)" == ""
+SRCDIR = .
+!ENDIF
+
+LFLAGS = $(LFLAGS) user32.lib shell32.lib advapi32.lib psapi.lib
+
+PDBFLAGS = -Fo$(WORKDIR)\ -Fd$(WORKDIR)\$(PROJECT)-src
+OBJECTS = \
+ $(WORKDIR)\xtool.obj
+
+OBJDEPS = NMAKEmakefile
+
+BUILDLOC = $(PREFIX)\bin
+BUILDEXE = $(WORKDIR)\$(PROJECT).exe
+BUILDPDB = $(WORKDIR)\$(PROJECT).pdb
+BUILDRES = $(WORKDIR)\$(PROJECT).res
+BUILDMAN = $(BUILDEXE).manifest
+
+all : $(WORKDIR) $(BUILDEXE)
+
+$(BUILDLOC) :
+ @if not exist "$(BUILDLOC)\$(NULL)" mkdir "$(BUILDLOC)"
+
+$(WORKDIR) :
+ @$(MAKEWORKDIR)
+
+{$(SRCDIR)}.c{$(WORKDIR)}.obj:
+ $(CC) $(CFLAGS) $(INCLUDES) $(PDBFLAGS) $<
+
+$(BUILDRES): $(SRCDIR)/$(PROJECT).rc
+ $(RC) $(RCFLAGS) /fo $(BUILDRES) $(SRCDIR)/$(PROJECT).rc
+
+$(OBJECTS): $(OBJDEPS)
+
+$(BUILDEXE): $(WORKDIR) $(OBJECTS) $(BUILDRES)
+ $(LINK) $(LFLAGS) $(OBJECTS) $(BUILDRES) $(LIBS) $(LDIRS) /pdb:$(BUILDPDB) /out:$(BUILDEXE)
+ IF EXIST $(BUILDMAN) \
+ mt -nologo -manifest $(BUILDMAN) -outputresource:$(BUILDEXE);1
+
+clean:
+ @$(CLEANTARGET)
+
+install: $(BUILDLOC) $(WORKDIR) $(BUILDEXE)
+ @xcopy "$(WORKDIR)\*.exe" "$(BUILDLOC)" /Y /Q
Property changes on: trunk/build/install/xtool/NMAKEmakefile
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/xtool/jboss.ico
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/xtool/jboss.ico
___________________________________________________________________
Name: svn:mime-type
+ image/x-icon
Added: trunk/build/install/xtool/redhat.ico
===================================================================
(Binary files differ)
Property changes on: trunk/build/install/xtool/redhat.ico
___________________________________________________________________
Name: svn:mime-type
+ image/x-icon
Added: trunk/build/install/xtool/xtool.c
===================================================================
--- trunk/build/install/xtool/xtool.c (rev 0)
+++ trunk/build/install/xtool/xtool.c 2008-03-31 12:14:20 UTC (rev 1489)
@@ -0,0 +1,2369 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file xtools.c
+ * @brief Windows generic build tool
+ * @author mturk(a)redhat.com
+ */
+
+#if defined(_MSC_VER) && _MSC_VER >= 1200
+#pragma warning(push, 3)
+#endif
+
+/*
+ * disable or reduce the frequency of...
+ * C4057: indirection to slightly different base types
+ * C4075: slight indirection changes (unsigned short* vs short[])
+ * C4100: unreferenced formal parameter
+ * C4127: conditional expression is constant
+ * C4163: '_rotl64' : not available as an intrinsic function
+ * C4201: nonstandard extension nameless struct/unions
+ * C4244: int to char/short - precision loss
+ * C4514: unreferenced inline function removed
+ */
+#pragma warning(disable: 4100 4127 4163 4201 4514; once: 4057 4075 4244)
+
+/*
+ * Ignore Microsoft's interpretation of secure development
+ * and the POSIX string handling API
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#pragma warning(disable: 4996)
+
+#define WIN32_LEAN_AND_MEAN
+/*
+ * Restrict the server to a subset of Windows NT 4.0 header files by default
+ */
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+#include <windows.h>
+#include <shellapi.h>
+#include <psapi.h>
+#include <shlobj.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <sys/timeb.h>
+#include <errno.h>
+#include <conio.h>
+#include <process.h>
+#include <direct.h>
+#include <io.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <crtdbg.h>
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of local defines
+ * ---------------------------------------------------------------------
+ */
+
+/* An arbitrary size that is digestable. True max is a bit less than 32000 */
+#define X_MAX_PATH 8192
+/* Make hash size always as 0xFF value */
+#define DEFAULT_HASH_SIZE 256
+/* Maximum size for environment expansion */
+#define INFO_BUFFER_SIZE 32767
+
+/*
+ * Alignment macros
+ */
+
+/* X_ALIGN() is only to be used to align on a power of 2 boundary */
+#define X_ALIGN(size, boundary) \
+ (((size) + ((boundary) - 1)) & ~((boundary) - 1))
+
+/** Default alignment */
+#define X_ALIGN_DEFAULT(size) X_ALIGN(size, 8)
+
+#define x_isalnum(c) (isalnum(((unsigned char)(c))))
+#define x_isalpha(c) (isalpha(((unsigned char)(c))))
+#define x_isdigit(c) (isdigit(((unsigned char)(c))))
+#define x_isspace(c) (isspace(((unsigned char)(c))))
+
+typedef enum {
+ SYSDLL_KERNEL32 = 0, // kernel32 From WinBase.h
+ SYSDLL_NTDLL = 1, // ntdll From our real kernel
+ SYSDLL_USER32 = 2, // user32 From WinUser.h
+ SYSDLL_defined = 3 // must define as last idx_ + 1
+} x_dlltoken_e;
+
+static FARPROC x_load_dll_func(x_dlltoken_e, const char *);
+
+#define DECLARE_LATE_DLL_FUNC(lib, rettype, def, \
+ calltype, fn, args, names) \
+ typedef rettype (calltype *x_late_fpt_##fn) args; \
+ static x_late_fpt_##fn x_late_pfn_##fn = NULL; \
+ static __inline rettype x_late_##fn args \
+ { if (!x_late_pfn_##fn) \
+ x_late_pfn_##fn = (x_late_fpt_##fn) \
+ x_load_dll_func(lib, #fn); \
+ if (x_late_pfn_##fn) \
+ return (*(x_late_pfn_##fn)) names; \
+ else return def; } //
+
+DECLARE_LATE_DLL_FUNC(SYSDLL_KERNEL32, BOOL, FALSE,
+ WINAPI, IsWow64Process, (
+ IN HANDLE hProcess,
+ OUT PBOOL Wow64Process),
+ (hProcess, Wow64Process));
+#undef IsWow64Process
+#define IsWow64Process x_late_IsWow64Process
+
+
+/*
+ * ---------------------------------------------------------------------
+ * end of local defines
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of local variables
+ * ---------------------------------------------------------------------
+ */
+
+static int xtools_pause = 0;
+static SYSTEM_INFO win_osinf;
+static OSVERSIONINFOEXA win_osver;
+static int verbose = 0;
+
+/*
+ * ---------------------------------------------------------------------
+ * end of local variables
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of forward declrations
+ * ---------------------------------------------------------------------
+ */
+
+int utf8_to_unicode_path(wchar_t*, size_t, const char *, size_t);
+int unicode_to_utf8_path(char *, size_t, const wchar_t *);
+int utf8_to_unicode(wchar_t *, size_t, const char *);
+int unicode_to_utf8(char *, size_t, const wchar_t* srcstr);
+int x_wfullpath(wchar_t *, size_t, const char *);
+
+/*
+ * ---------------------------------------------------------------------
+ * end of forward declrations
+ * ---------------------------------------------------------------------
+ */
+
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of local types
+ * ---------------------------------------------------------------------
+ */
+
+typedef struct hash_node_t hash_node_t;
+
+struct hash_node_t {
+ hash_node_t *next;
+ void *data;
+ char key[1];
+};
+
+typedef struct hash_t {
+ int icase;
+ unsigned int size;
+ hash_node_t **nodes;
+} hash_t;
+
+typedef struct sbuffer {
+ char *data;
+ size_t pos;
+ size_t size;
+} sbuffer;
+
+typedef struct ini_node_t ini_node_t;
+
+struct ini_node_t {
+ ini_node_t *next;
+ ini_node_t **last;
+ char *key;
+ char *val;
+};
+
+typedef struct ini_section_t ini_section_t;
+
+struct ini_section_t {
+ ini_section_t *next;
+ ini_section_t **last;
+ char *name;
+ ini_node_t *nodes;
+};
+
+/*
+ * ---------------------------------------------------------------------
+ * end of of local types
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of stdlib replacement functions
+ * ---------------------------------------------------------------------
+ */
+
+static int c_errno_table[] = {
+
+ 0, /* NO_ERROR */
+ EINVAL, /* ERROR_INVALID_FUNCTION */
+ ENOENT, /* ERROR_FILE_NOT_FOUND */
+ ENOENT, /* ERROR_PATH_NOT_FOUND */
+ EMFILE, /* ERROR_TOO_MANY_OPEN_FILES */
+ EACCES, /* ERROR_ACCESS_DENIED */
+ EBADF, /* ERROR_INVALID_HANDLE */
+ ENOMEM, /* ERROR_ARENA_TRASHED */
+ ENOMEM, /* ERROR_NOT_ENOUGH_MEMORY */
+ ENOMEM, /* ERROR_INVALID_BLOCK */
+ E2BIG, /* ERROR_BAD_ENVIRONMENT */
+ ENOEXEC, /* ERROR_BAD_FORMAT */
+ EINVAL, /* ERROR_INVALID_ACCESS */
+ EINVAL, /* ERROR_INVALID_DATA */
+ 14, /* **** reserved */
+ ENOENT, /* ERROR_INVALID_DRIVE */
+ EACCES, /* ERROR_CURRENT_DIRECTORY */
+ EXDEV, /* ERROR_NOT_SAME_DEVICE */
+ ENOENT, /* ERROR_NO_MORE_FILES */
+ 0
+};
+
+int x_cerror(int err)
+{
+ if (err == 0) {
+ if ((err = GetLastError()) == 0)
+ return 0;
+ }
+ if (err < 0 || err > ERROR_NO_MORE_FILES) {
+ switch (err) {
+ case 1026:
+ return ENOENT;
+ break;
+ case ERROR_ALREADY_EXISTS:
+ return EEXIST;
+ case ERROR_INSUFFICIENT_BUFFER:
+ return ENAMETOOLONG;
+ break;
+ default:
+ return err;
+ break;
+ }
+ }
+ else
+ return c_errno_table[err];
+}
+
+static void x_free(void *p)
+{
+ if (p != NULL) {
+ free(p);
+ }
+}
+
+static void *x_malloc(size_t size)
+{
+ void *p = malloc(size);
+ if (p == NULL) {
+ perror("malloc");
+ _exit(ENOMEM);
+ }
+ return p;
+}
+
+static void *x_calloc(size_t size)
+{
+ void *p = calloc(1, size);
+ if (p == NULL) {
+ perror("calloc");
+ _exit(ENOMEM);
+ }
+ return p;
+}
+
+static void *x_realloc(void *m, size_t size)
+{
+ m = realloc(m, size);
+ if (m == NULL) {
+ perror("realloc");
+ _exit(ENOMEM);
+ }
+ return m;
+}
+
+static char *x_strdup(const char *s)
+{
+ char *p;
+ size_t size;
+ if (s != NULL)
+ size = strlen(s);
+ else
+ return NULL;
+ p = (char *)x_malloc(size + 2);
+ memcpy(p, s, size);
+ p[size++] = '\0';
+ p[size] = '\0';
+ return p;
+}
+
+static wchar_t *x_wstrdup_utf8(const char *str)
+{
+ int len;
+ wchar_t *res;
+ if (!str)
+ return NULL;
+ len = strlen(str);
+ res = x_malloc((len + 2) * sizeof(wchar_t));
+ if (!MultiByteToWideChar(CP_UTF8, 0, str, -1, res, len + 1)) {
+ x_free(res);
+ return NULL;
+ }
+ else {
+ len = wcslen(res);
+ res[len + 1] = L'\0';
+ return res;
+ }
+}
+
+static char *x_strdup_utf8(const wchar_t *str)
+{
+ size_t l;
+ char *r;
+
+ if (!(l = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, 0)))
+ return NULL;
+ r = x_malloc(l + 1);
+ if (!(l = WideCharToMultiByte(CP_UTF8, 0, str, -1, r, l, NULL, 0))) {
+ x_free(r);
+ return NULL;
+ }
+ else {
+ r[l] = '\0';
+ return r;
+ }
+}
+
+
+/*
+ * Replacement for the strncpy() function. We roll our
+ * own to implement these specific changes:
+ * (1) strncpy() doesn't always null terminate and we want it to.
+ * (2) strncpy() null fills, which is bogus, esp. when copy 8byte
+ * strings into 8k blocks.
+ * (3) Instead of returning the pointer to the beginning of
+ * the destination string, we return a pointer to the
+ * terminating '\0' to allow us to "check" for truncation
+ *
+ * x_strncpy() follows the same call structure as strncpy().
+ */
+static char *x_strncpy(char *d, const char *s, size_t l)
+{
+ char *dst, *end;
+ if (l == 0)
+ return d;
+ if (s == NULL) {
+ *d = '\0';
+ return d;
+ }
+ dst = d;
+ end = d + l - 1;
+
+ for (; dst < end; ++dst, ++s) {
+ if (!(*dst = *s))
+ return dst;
+ }
+
+ *dst = '\0'; /* always null terminate */
+ return dst;
+}
+
+static char *x_strvcat(const char *str, ...)
+{
+ char *dst = NULL;
+ const char *ptr = str;
+ size_t len = 0;
+ va_list v;
+ if (!str)
+ return NULL;
+ va_start(v, str);
+ while (ptr) {
+ len += strlen(ptr);
+ ptr = va_arg(v, const char *);
+ }
+ va_end(v);
+ dst = x_malloc(len + 2);
+ *dst = '\0';
+ ptr = str;
+ va_start(v, str);
+ while (ptr) {
+ strcat(dst, ptr);
+ ptr = va_arg(v, const char *);
+ }
+ va_end(v);
+ dst[len + 1] = '\0';
+ return dst;
+}
+
+static char *x_strcat(char *dst, const char *add)
+{
+ if (dst) {
+ size_t len = strlen(dst) + strlen(add);
+ char *res = realloc(dst, len + 2);
+ if (!res) {
+ res = x_malloc(len + 2);
+ strcpy(res, dst);
+ }
+ strcat(res, add);
+ res[len + 1] = '\0';
+ return res;
+ }
+ else
+ return x_strdup(add);
+}
+
+static char *__argv0 = NULL;
+static char *__pname = NULL;
+static char *__ppath = NULL;
+static char *__paren = NULL;
+
+static const char *getprogname()
+{
+ char *p;
+
+ if (__pname)
+ return __pname;
+ if ((p = strrchr(__argv0, '\\')))
+ p++;
+ else
+ p = __argv0;
+ __pname = x_strdup(p);
+ /* Remove extension */
+ if ((p = strrchr(__pname, '.')))
+ *p = '\0';
+ return __pname;
+}
+
+static const char *getexecpath()
+{
+ char *p;
+
+ if (__ppath)
+ return __ppath;
+ __ppath = x_strdup(__argv0);
+ if ((p = strrchr(__ppath, '\\')))
+ *++p = '\0';
+ return __ppath;
+}
+
+static const char *getexecparent()
+{
+ char *p;
+
+ if (__paren)
+ return __paren;
+ __paren = x_strdup(getexecpath());
+ if ((p = strrchr(__paren, '\\')))
+ *++p = '\0';
+ if ((p = strrchr(__paren, '\\')))
+ *++p = '\0';
+ return __paren;
+}
+
+#define progname getprogname()
+#define execpath getexecpath()
+#define execparent getexecparent()
+
+static const char *wstrerror(int err)
+{
+ static char buff[X_MAX_PATH] = {0};
+
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buff,
+ X_MAX_PATH,
+ NULL);
+
+ return buff;
+}
+
+static const char *cstrerror(int err)
+{
+ if (err > EILSEQ)
+ return wstrerror(err);
+ else
+ return strerror(err);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of stdlib replacement functions
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of string utilities
+ * ---------------------------------------------------------------------
+ */
+
+/* Match = 0, NoMatch = 1, Abort = -1
+ * Based loosely on sections of wildmat.c by Rich Salz
+ */
+static int wildchar_match(const char *str, const char *exp, int icase)
+{
+ int x, y;
+
+ for (x = 0, y = 0; exp[y]; ++y, ++x) {
+ if (!str[x] && exp[y] != '*')
+ return -1;
+ if (exp[y] == '*') {
+ while (exp[++y] == '*');
+ if (!exp[y])
+ return 0;
+ while (str[x]) {
+ int ret;
+ if ((ret = wildchar_match(&str[x++], &exp[y], icase)) != 1)
+ return ret;
+ }
+ return -1;
+ }
+ else if (exp[y] != '?') {
+ if (icase && (tolower(str[x]) != tolower(exp[y])))
+ return 1;
+ else if (!icase && str[x] != exp[y])
+ return 1;
+ }
+ }
+ return (str[x] != '\0');
+}
+
+/* Win32 Exceptions:
+ *
+ * Note that trailing spaces and trailing periods are never recorded
+ * in the file system, except by a very obscure bug where any file
+ * that is created with a trailing space or period, followed by the
+ * ':' stream designator on an NTFS volume can never be accessed again.
+ * In other words, don't ever accept them when designating a stream!
+ *
+ * An interesting side effect is that two or three periods are both
+ * treated as the parent directory, although the fourth and on are
+ * not [strongly suggest all trailing periods are trimmed off, or
+ * down to two if there are no other characters.]
+ *
+ * Leading spaces and periods are accepted, however.
+ * The * ? < > codes all have wildcard side effects
+ * The " / \ : are exclusively component separator tokens
+ * The system doesn't accept | for any (known) purpose
+ * Oddly, \x7f _is_ acceptable ;)
+ */
+
+/* apr_c_is_fnchar[] maps Win32's file name and shell escape symbols
+ *
+ * element & 1 == valid file name character [excluding delimiters]
+ * element & 2 == character should be shell (caret) escaped from cmd.exe
+ *
+ * this must be in-sync with Apache httpd's gen_test_char.c for cgi escaping.
+ */
+
+static const char is_valid_fnchar[256] = {
+ /* Reject all ctrl codes... Escape \n and \r (ascii 10 and 13) */
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ /* ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ 1,1,2,1,3,3,3,3,3,3,2,1,1,1,1,0, 1,1,1,1,1,1,1,1,1,1,0,3,2,1,2,2,
+ /* @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ */
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,3,2,3,3,1,
+ /* ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ */
+ 3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,3,2,3,3,1,
+ /* High bit codes are accepted (subject to utf-8->Unicode xlation) */
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+};
+
+
+#define IS_FNCHAR(c) (is_valid_fnchar[(unsigned char)(c)] & 1)
+#define IS_SHCHAR(c) ((is_valid_fnchar[(unsigned char)(c)] & 2) == 2)
+
+/* Is = 1, No = 0, Error = -1
+ */
+static int is_wildpath(const char *path)
+{
+ size_t i = 0;
+ size_t len;
+
+ if (!path) {
+ errno = EINVAL;
+ return -1;
+ }
+ len = strlen(path);
+ if (len > 8 && !strncmp(path, "\\\\?\\UNC\\", 8))
+ path += 8;
+ else if (len > 4 && !strncmp(path, "\\\\?\\", 4))
+ path += 4;
+ if (x_isalpha(*path) && (path[1] == ':')) {
+ path += 2;
+ }
+ while (*path) {
+ if (!IS_FNCHAR(*path) && (*path != '\\') && (*path != '/')) {
+ if (*path == '?' || *path == '*')
+ return 1;
+ else {
+ errno = ENOENT;
+ return -1;
+ }
+ }
+ ++path;
+ }
+ return 0;
+}
+
+static char *rtrim(char *s)
+{
+ size_t i;
+ /* check for empty strings */
+ if (!(i = strlen(s)))
+ return s;
+ for (i = i - 1; i >= 0 && x_isspace(s[i]); i--)
+ ;
+ s[i + 1] = '\0';
+ return s;
+}
+
+static char *ltrim(char *s)
+{
+ size_t i;
+ for (i = 0; s[i] != '\0' && x_isspace(s[i]); i++)
+ ;
+
+ return s + i;
+}
+
+static char *rltrim(char *s)
+{
+ size_t i;
+ /* check for empty strings */
+ if (!(i = strlen(s)))
+ return s;
+ for (i = i - 1; i >= 0 && x_isspace(s[i]); i--)
+ ;
+ s[i + 1] = '\0';
+ for (i = 0; s[i] != '\0' && x_isspace(s[i]); i++)
+ ;
+
+ return s + i;
+}
+/*
+ * ---------------------------------------------------------------------
+ * end of string utilities
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of hash
+ * ---------------------------------------------------------------------
+ */
+
+static unsigned int strhash(const char *string, int icase)
+{
+ unsigned int hash = 0;
+ int i;
+
+ while (*string) {
+ if (icase)
+ i = toupper(*string);
+ else
+ i = *string;
+ hash = hash * 33 + i;
+ string ++;
+ }
+ return hash;
+}
+
+static void free_node(void *unused, void *data)
+{
+ unused;
+ x_free(data);
+}
+
+static hash_t *hash_create(unsigned int size, int icase)
+{
+ hash_t *h;
+ if (!size)
+ size = DEFAULT_HASH_SIZE;
+ else
+ size = X_ALIGN_DEFAULT(size);
+ h = (hash_t *)x_malloc(sizeof(hash_t));
+ h->nodes = (hash_node_t **)x_calloc(sizeof(hash_node_t *) * size);
+ h->size = size;
+ h->icase = icase;
+ return h;
+}
+
+static void *hash_insert(hash_t *ht, const char *key, void *data)
+{
+ unsigned int ikey;
+ if (!ht || !key)
+ return NULL;
+ ikey = strhash(key, ht->icase) % ht->size;
+ if (!ht->nodes[ikey]) {
+ ht->nodes[ikey] = (hash_node_t *)x_malloc(sizeof(hash_node_t) +
+ strlen(key));
+ strcpy(ht->nodes[ikey]->key, key);
+ ht->nodes[ikey]->data = data;
+ ht->nodes[ikey]->next = NULL;
+ }
+ else {
+ hash_node_t *p;
+ for (p = ht->nodes[ikey]; p; p = p->next) {
+ if (ht->icase ? stricmp(p->key, key) : strcmp(p->key, key)) {
+ void *org = p->data;
+ p->data = data;
+ return org;
+ }
+ }
+ p = (hash_node_t *)x_malloc(sizeof(hash_node_t) + strlen(key));
+ strcpy(p->key, key);
+ p->data = data;
+ p->next = ht->nodes[ikey];
+ ht->nodes[ikey] = p;
+ }
+ return NULL;
+}
+
+static void *hash_find(hash_t *ht, const char *key, int *found)
+{
+ unsigned int ikey;
+ if (!ht || !key)
+ return NULL;
+ ikey = strhash(key, ht->icase) % ht->size;
+
+ if (found)
+ *found = 0;
+ if (!ht->nodes[ikey])
+ return NULL;
+ else {
+ hash_node_t *p;
+ for (p = ht->nodes[ikey]; p; p = p->next) {
+ if (ht->icase ? stricmp(p->key, key) : strcmp(p->key, key)) {
+ if (found)
+ *found = 1;
+ return p->data;
+ }
+ }
+ }
+ return NULL;
+}
+
+static void hash_foreach(hash_t *ht, void *opaque,
+ void (*callback)(void *, const char *, void *))
+{
+ unsigned int i;
+
+ for (i = 0; i < ht->size; i++) {
+ if (ht->nodes[i]) {
+ hash_node_t *p;
+ for (p = ht->nodes[i]; p; p = p->next) {
+ (*callback)(opaque, p->key, p->data);
+ }
+ }
+ }
+}
+
+static void hash_destroy(hash_t *ht, void *opaque,
+ void (*callback)(void *, const char *, void *))
+{
+ unsigned int i;
+ for (i = 0; i < ht->size; i++) {
+ if (ht->nodes[i]) {
+ hash_node_t *p = ht->nodes[i];
+ while (p) {
+ hash_node_t *next = p->next;
+ if (callback)
+ (*callback)(opaque, p->key, p->data);
+ x_free(p);
+ p = next;
+ }
+ }
+ }
+ x_free(ht->nodes);
+ x_free(ht);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of hash
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of posix
+ * ---------------------------------------------------------------------
+ */
+
+static FILE *x_fopen(const char *name, const char *mode)
+{
+ DWORD acc = 0;
+ DWORD mod = OPEN_EXISTING;
+ HANDLE fh;
+ wchar_t fname[X_MAX_PATH];
+ int r;
+ int flags = _O_RDONLY;
+ FILE *f;
+
+ /* Do some param checking */
+ if (!name || !*name || !mode || !*mode) {
+ errno = EINVAL;
+ return NULL;
+ }
+ if (strchr(mode, 'r'))
+ acc = GENERIC_READ;
+ if (strchr(mode, 'w')) {
+ acc = GENERIC_READ | GENERIC_WRITE;
+ mod = CREATE_ALWAYS;
+ flags = _O_RDWR;
+ }
+ if (strchr(mode, 'a')) {
+ acc = GENERIC_WRITE;
+ mod = OPEN_ALWAYS;
+ flags = _O_WRONLY;
+ }
+ if (strchr(mode, '+')) {
+ acc = GENERIC_READ | GENERIC_WRITE;
+ flags = _O_RDWR;
+ }
+ if (strchr(mode, 't'))
+ flags |= _O_TEXT;
+ else if (strchr(mode, 'b'))
+ flags |= _O_BINARY;
+ if ((r = x_wfullpath(fname, X_MAX_PATH, name)) != 0) {
+ errno = r;
+ return NULL;
+ }
+ fh = CreateFileW(fname, acc, FILE_SHARE_READ, NULL,
+ mod, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (fh == INVALID_HANDLE_VALUE) {
+ errno = x_cerror(0);
+ return NULL;
+ }
+ if ((r = _open_osfhandle((long)fh, flags)) < 0) {
+ CloseHandle(fh);
+ return NULL;
+ }
+ if (!(f = _fdopen(r, mode))) {
+ CloseHandle(fh);
+ return NULL;
+ }
+ printf("Opened %S\n", fname);
+ return f;
+}
+
+static void vwarnx(const char *fmt, va_list ap)
+{
+ fprintf(stderr, "%s: ", getprogname());
+ if (fmt != NULL)
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+}
+
+static void warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
+
+static int optslash = '/'; /* allow slashes as option modifiers */
+static int optsbrk = 1; /* Break if slash is unknown modifier */
+static int opterr = 1; /* if error message should be printed */
+static int optind = 1; /* index into parent argv vector */
+static int optopt = 0; /* character checked for validity */
+static int optlong = 1; /* Allow long options */
+static int optreset = 1; /* reset getopt */
+static char *optarg = NULL; /* argument associated with option */
+
+#define BADCH '?'
+#define BADARG ':'
+#define LNGOPT '.'
+#define EMSG ""
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ * However this one allows both - and / as argument options
+ */
+int getopt(int nargc, const char **nargv, const char *ostr)
+{
+ static const char *place = EMSG; /* option letter processing */
+ char *oli = NULL; /* option letter list index */
+ int first = 0;
+
+ optarg = NULL;
+ if (optreset || *place == 0) { /* update scanning pointer */
+ optreset = 0;
+ place = nargv[optind];
+ if (optind >= nargc) {
+ /* Argument is absent or is not an option */
+ place = EMSG;
+ return EOF;
+ }
+ first = *place++;
+ if (first != '-' && first != optslash) {
+ /* Argument is absent or is not an option */
+ place = EMSG;
+ return EOF;
+ }
+ optopt = *place++;
+ /* Check for invalid sequence */
+ if ((optslash == '/') &&
+ ((first == '-' && optopt == '/') ||
+ (first == '/' && optopt == '-'))) {
+ ++optind;
+ if (opterr)
+ warnx("Invalid sequence -- %c%c",
+ first, optopt);
+ place = EMSG;
+ return BADCH;
+
+ }
+ if (first == '-' && optopt == '-') {
+ ++optind;
+ if (*place == 0 || !optlong) {
+ place = EMSG;
+ /* "--" => end of options */
+ return EOF;
+ }
+ else {
+ optarg = (char *)place;
+ place = EMSG;
+ /* "--long" => long option */
+ return LNGOPT;
+ }
+ }
+ if (optopt == 0) {
+ /*
+ * Solitary '-', treat as a '-' option
+ * if the program (eg su) is looking for it.
+ */
+ place = EMSG;
+ if (strchr(ostr, first) == NULL)
+ return EOF;
+ optopt = first;
+ }
+ if (optopt == optslash) {
+ ++optind;
+ place = EMSG;
+ /* "//" => end of options */
+ return EOF;
+ }
+ }
+ else
+ optopt = *place++;
+
+ /* See if option letter is one the caller wanted... */
+ if (optopt == BADARG || (oli = strchr(ostr, optopt)) == NULL) {
+ if (!optsbrk && optslash == '/' && first == optslash) {
+ /* Non option starting with / */
+ place = EMSG;
+ return EOF;
+ }
+ if (*place == 0)
+ ++optind;
+ if (opterr && *ostr != ':')
+ warnx("unknown option -- %c\n"
+ "Try '%s --help' for more information.",
+ optopt, progname);
+ return BADCH;
+ }
+
+ /* Does this option need an argument? */
+ if (oli[1] != ':') {
+ /* don't need argument */
+ optarg = NULL;
+ if (*place == 0) {
+ ++optind;
+ place = EMSG;
+ }
+ else if (optslash == '/' && first == optslash) {
+ ++optind;
+ optarg = (char *)place;
+ place = EMSG;
+ }
+ } else {
+ /*
+ * Option-argument is either the rest of this argument or the
+ * entire next argument.
+ */
+ if (*place)
+ optarg = (char *)place;
+ else if (nargc > ++optind)
+ optarg = (char *)nargv[optind];
+ else {
+ /* option-argument absent */
+ place = EMSG;
+ if (*ostr == ':')
+ return BADARG;
+ if (opterr)
+ warnx("option requires an argument -- %c\n"
+ "Try '%s --help' for more information.",
+ optopt, progname);
+ return BADCH;
+ }
+ place = EMSG;
+ ++optind;
+ }
+ return optopt; /* return option letter */
+}
+
+
+/*
+ * ---------------------------------------------------------------------
+ * end of posix
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of misc
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * Convert all forward slashes to backward slashes
+ */
+static char *x_backslash(const char *s)
+{
+ char *c;
+ char *p = x_strdup(s);
+ for (c = p; *c; c++) {
+ if (*c == '/')
+ *c = '\\';
+ }
+ return p;
+}
+
+/*
+ * Convert all forward slashes to backward slashes
+ * in place.
+ */
+static char *fixslash(char *s)
+{
+ char *c = s;
+ for (; *c; c++) {
+ if (*c == '/')
+ *c = '\\';
+ }
+ return s;
+}
+
+static char *expand_envars(char *str)
+{
+ wchar_t ibuf[INFO_BUFFER_SIZE];
+ wchar_t ebuf[INFO_BUFFER_SIZE];
+ char *rv = str;
+
+ if (MultiByteToWideChar(CP_UTF8, 0, str, -1, ibuf, INFO_BUFFER_SIZE)) {
+ DWORD el = ExpandEnvironmentStringsW(ibuf, ebuf,
+ INFO_BUFFER_SIZE);
+ if (el > INFO_BUFFER_SIZE) {
+ if (verbose)
+ warnx("expansion string to large %d", el);
+ }
+ else if (el) {
+ if ((rv = x_strdup_utf8(ebuf)))
+ x_free(str);
+ else
+ rv = str;
+ }
+ }
+ return rv;
+}
+
+
+/* This is the helper code to resolve late bound entry points
+ * missing from one or more releases of the Win32 API
+ */
+
+static const char* const late_dll_mames[SYSDLL_defined] = {
+ "kernel32",
+ "ntdll.dll",
+ "user32.dll"
+};
+
+static HMODULE late_dll_handles[SYSDLL_defined] = { NULL, NULL, NULL};
+
+static FARPROC x_load_dll_func(x_dlltoken_e fnLib, const char* fnName)
+{
+ if (!late_dll_handles[fnLib]) {
+ /* First see if the .dll is already loaded in the process */
+ late_dll_handles[fnLib] = GetModuleHandleA(late_dll_mames[fnLib]);
+ if (!late_dll_handles[fnLib]) {
+ /* Do not display error messages when loading library */
+ UINT em = SetErrorMode(SEM_FAILCRITICALERRORS);
+ late_dll_handles[fnLib] = LoadLibraryA(late_dll_mames[fnLib]);
+ SetErrorMode(em);
+ }
+ if (!late_dll_handles[fnLib])
+ return NULL;
+ }
+ return GetProcAddress(late_dll_handles[fnLib], fnName);
+}
+
+
+/*
+ * ---------------------------------------------------------------------
+ * end of misc
+ * ---------------------------------------------------------------------
+ */
+
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of file functions
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * Makes a full path from partial path
+ */
+static char *x_fullpath(const char *s)
+{
+ wchar_t full[X_MAX_PATH];
+ wchar_t path[X_MAX_PATH];
+ char *res;
+ wchar_t *fn;
+ size_t len;
+ int r;
+
+ if ((r = utf8_to_unicode_path(path, X_MAX_PATH, s, X_MAX_PATH))) {
+ errno = r;
+ return NULL;
+ }
+ len = GetFullPathNameW(path,
+ X_MAX_PATH,
+ full, &fn);
+ if (len >= X_MAX_PATH) {
+ errno = ERANGE;
+ return NULL;
+ }
+ if (len == 0) {
+ errno = EINVAL;
+ return NULL;
+ }
+ res = x_malloc(X_MAX_PATH);
+ if ((r = unicode_to_utf8_path(res, X_MAX_PATH, full))) {
+ errno = r;
+ x_free(res);
+ return NULL;
+ }
+ return res;
+}
+
+/*
+ * Makes a full path from partial path
+ */
+static int x_wfullpath(wchar_t *full, size_t len, const char *s)
+{
+ wchar_t path[X_MAX_PATH];
+ wchar_t *fn;
+ int r;
+ if (!s || !*s)
+ return EINVAL;
+ *full = L'\0';
+ if ((r = utf8_to_unicode_path(path, X_MAX_PATH, s, X_MAX_PATH)))
+ return r;
+ len = GetFullPathNameW(path, len,
+ full, &fn);
+ if (len >= X_MAX_PATH)
+ return ERANGE;
+ else if (len == 0)
+ return EINVAL;
+ else
+ return 0;
+}
+
+
+/*
+ * Makes a full path ending with \ from partial path
+ */
+static char *x_fulldir(const char *s)
+{
+ wchar_t full[X_MAX_PATH];
+ wchar_t path[X_MAX_PATH];
+ char *res;
+ wchar_t *fn;
+ size_t len;
+ int r;
+
+ if ((r = utf8_to_unicode_path(path, X_MAX_PATH, s, X_MAX_PATH))) {
+ errno = r;
+ return NULL;
+ }
+ len = GetFullPathNameW(path,
+ X_MAX_PATH - 2,
+ full, &fn);
+ if (len >= (X_MAX_PATH - 2)) {
+ errno = ERANGE;
+ }
+ if (len == 0) {
+ errno = x_cerror(GetLastError());
+ return NULL;
+ }
+ res = x_malloc(X_MAX_PATH);
+ if ((r = unicode_to_utf8_path(res, X_MAX_PATH - 2, full))) {
+ errno = r;
+ x_free(res);
+ return NULL;
+ }
+ len = strlen(res);
+ if (res[len - 1] != '\\' &&
+ res[len - 1] != '*') {
+ res[len++] = '\\';
+ res[len] = '\0';
+ }
+ return res;
+}
+
+static int x_createdir(const char *dir)
+{
+ wchar_t path[X_MAX_PATH];
+ int r;
+
+ if ((r = utf8_to_unicode_path(path, X_MAX_PATH, dir, MAX_PATH)))
+ return r;
+ if (!CreateDirectoryW(path, NULL)) {
+ r = x_cerror(GetLastError());
+ if (r == EEXIST) {
+ if (verbose)
+ warnx("cannot create directory '%S': %s",
+ path, cstrerror(EEXIST));
+ return EEXIST;
+ }
+ else if (r == ENOENT) {
+ return ENOENT;
+ }
+ else {
+ if (verbose)
+ warnx("cannot create directory '%S': %s",
+ path, cstrerror(r));
+ return r;
+ }
+ }
+ else {
+ if (verbose)
+ warnx("created directory '%S'", path);
+ return 0;
+ }
+}
+
+static int dir_make_parent(char *path)
+{
+ int rv;
+ char *ch = strrchr(path, '\\');
+ if (!ch)
+ return ENOENT;
+
+ *ch = '\0';
+ rv = x_createdir(path); /* Try to make straight off */
+
+ if (rv == ENOENT) {
+ /* Missing an intermediate dir */
+ rv = dir_make_parent(path);
+ if (rv == 0)
+ rv = x_createdir(path); /* And complete the path */
+ }
+
+ *ch = '\\'; /* Always replace the slash before returning */
+ return rv;
+}
+
+static int x_createdir_r(const char *path)
+{
+ int rv;
+ char *dir = x_fullpath(path);
+
+ rv = x_createdir(dir);
+ if (rv == EEXIST) {
+ /* It's OK if PATH exists */
+ x_free(dir);
+ return 0;
+ }
+ else if (rv == ENOENT) { /* Missing an intermediate dir */
+ rv = dir_make_parent(dir); /* Make intermediate dirs */
+ if (rv == 0) {
+ rv = x_createdir(dir); /* And complete the path */
+ }
+ }
+ x_free(dir);
+ return rv;
+}
+
+static int x_rmdir(const char *src)
+{
+ wchar_t path[X_MAX_PATH];
+ int r;
+ char *loc = x_fulldir(src);
+
+ if ((r = utf8_to_unicode_path(path, X_MAX_PATH, loc, MAX_PATH))) {
+ x_free(loc);
+ return r;
+ }
+ if (!RemoveDirectoryW(path))
+ r = x_cerror(GetLastError());
+ if (verbose) {
+ if (r)
+ warnx("cannot remove directory '%S': %s",
+ path, cstrerror(r));
+ else
+ warnx("removed directory '%S'", path);
+ }
+ x_free(loc);
+ return r;
+}
+
+static int x_rmdir_r(const char *src)
+{
+ wchar_t path[X_MAX_PATH];
+ int r;
+ int full = 0;
+ char *loc = x_fulldir(src);
+ SHFILEOPSTRUCTW op;
+
+ if ((r = utf8_to_unicode_path(path, X_MAX_PATH - 4, loc, 0))) {
+ x_free(loc);
+ return r;
+ }
+ if (path[wcslen(path) - 1] == L'\\') {
+ wcscat(path, L"*.*");
+ path[wcslen(path) + 1] = L'\0';
+ full = 1;
+ }
+ op.hwnd = NULL;
+ op.wFunc = FO_DELETE;
+ op.pFrom = path;
+ op.pTo = NULL;
+ op.fFlags = FOF_NOCONFIRMATION |
+ FOF_NOERRORUI |
+ FOF_SILENT;
+
+ r = x_cerror(SHFileOperationW(&op));
+ if (r == 0 && full) {
+ path[wcslen(path) - 4] = L'\0';
+ if (!RemoveDirectoryW(path))
+ r = x_cerror(GetLastError());
+ }
+ if (verbose) {
+ if (r)
+ warnx("cannot remove directory '%s': %s",
+ loc, cstrerror(r));
+ else
+ warnx("removed directory '%s'", loc);
+ }
+ x_free(loc);
+ return r;
+}
+
+static int x_rmfile(const char *src)
+{
+ wchar_t path[X_MAX_PATH];
+ int r;
+ char *loc = x_fullpath(src);
+ SHFILEOPSTRUCTW op;
+
+ if ((r = utf8_to_unicode_path(path, X_MAX_PATH, loc, 0))) {
+ x_free(loc);
+ return r;
+ }
+ op.hwnd = NULL;
+ op.wFunc = FO_DELETE;
+ op.pFrom = path;
+ op.pTo = NULL;
+ op.fFlags = FOF_NOCONFIRMATION |
+ FOF_NOERRORUI |
+ FOF_FILESONLY |
+ FOF_SILENT;
+
+ r = x_cerror(SHFileOperationW(&op));
+ if (verbose) {
+ if (r)
+ warnx("cannot remove file '%s': %s",
+ loc, cstrerror(r));
+ else
+ warnx("removed file '%s'", loc);
+ }
+ x_free(loc);
+ return r;
+}
+
+static int x_fstat(LPWIN32_FILE_ATTRIBUTE_DATA pa,
+ const char *src)
+{
+
+ wchar_t path[X_MAX_PATH];
+ int r = 0;
+
+ if (r = x_wfullpath(path, X_MAX_PATH, src))
+ return r;
+ if (!GetFileAttributesExW(path, GetFileExInfoStandard, pa)) {
+ r = x_cerror(GetLastError());
+ if (verbose && r != ENOENT) {
+ warnx("cannot stat file '%S': %s",
+ path, cstrerror(errno));
+ }
+ }
+ return r;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of file functions
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of ini
+ * ---------------------------------------------------------------------
+ */
+
+static void ini_free(ini_section_t *ini)
+{
+ ini_section_t *p;
+ while (p = ini) {
+ ini_node_t *n;
+ while (n = ini->nodes) {
+ ini->nodes = n->next;
+ x_free(n->key);
+ x_free(n->val);
+ x_free(n);
+ }
+ ini = p->next;
+ x_free(p->name);
+ x_free(p);
+ }
+}
+
+static ini_section_t *ini_section_get(ini_section_t *ini, const char *name)
+{
+ ini_section_t *p;
+ for (p = ini; p; p = p->next) {
+ if (p->name && !stricmp(p->name, name))
+ return p;
+ }
+ return NULL;
+}
+
+static ini_section_t *ini_section_new(ini_section_t *top)
+{
+ ini_section_t *ini = x_calloc(sizeof(ini_section_t));
+ if (top) {
+ *top->last = ini;
+ top->last = &ini->next;
+ }
+ else
+ ini->last = &ini->next;
+
+ return ini;
+}
+
+static ini_node_t *ini_node_new(ini_section_t *ini)
+{
+ ini_node_t *node = x_calloc(sizeof(ini_node_t));
+ if (ini->nodes) {
+ *ini->nodes->last = node;
+ ini->nodes->last = &node->next;
+ }
+ else {
+ node->last = &node->next;
+ ini->nodes = node;
+ }
+ return node;
+}
+
+static ini_section_t *ini_load(const char *fname)
+{
+ FILE *fp;
+ ini_section_t *top = NULL;
+ ini_section_t *ini = NULL;
+ ini_node_t *node = NULL;
+ char buffer[X_MAX_PATH];
+ int counter = 0;
+ int nextline = 0;
+
+ if (!(fp = x_fopen(fname, "rt"))) {
+ if (verbose)
+ warnx("'%s' %s", fname, cstrerror(errno));
+ return NULL;
+ }
+ ini = top = ini_section_new(NULL);
+ while (fgets(buffer, X_MAX_PATH, fp)) {
+ char *section;
+ char *line;
+ /* Trim readed line */
+ counter++;
+ line = rtrim(buffer);
+ if (nextline) {
+ nextline = 0;
+ if (!node || *line == '\0')
+ continue;
+ node->val = x_strcat(node->val, line);
+ if (node->val[strlen(node->val) - 1] == '\\') {
+ node->val[strlen(node->val) - 1] = '\0';
+ nextline = 1;
+ }
+ if (!nextline) {
+ node->val = expand_envars(node->val);
+ }
+ continue;
+ }
+ line = ltrim(buffer);
+ /* Skip comments and empty lines*/
+ if (*line == '\0' || *line == '#' || *line == ';')
+ continue;
+ if (*line == '[') {
+ char *ends = strchr(++line, ']');
+ if (!ends) {
+ if (verbose)
+ warnx("'%s' unterminated section at line %d",
+ fname, counter);
+ goto cleanup;
+ }
+ *ends = '\0';
+ section = rltrim(line);
+ if (!(ini = ini_section_get(top, section))) {
+ ini = ini_section_new(top);
+ ini->name = x_strdup(section);
+ }
+ else {
+ if (verbose > 1)
+ warnx("'%s' duplicate section at line %d",
+ fname, counter);
+ }
+ continue;
+ }
+ else {
+ char *val = NULL;
+ char *equ = line;
+ if (*equ == '=')
+ equ++;
+ if (equ = strchr(equ, '=')) {
+ *equ++ = '\0';
+ val = rltrim(equ);
+ if (val[strlen(val) - 1] == '\\') {
+ val[strlen(val) - 1] = '\0';
+ nextline = 1;
+ }
+ if (!*val)
+ val = NULL;
+ }
+ line = rltrim(line);
+ if (!*line) {
+ /* Skip entries without keys **/
+ if (verbose > 1)
+ warnx("'%s' missing key at line %d",
+ fname, counter);
+ nextline = 0;
+ continue;
+ }
+ node = ini_node_new(ini);
+ node->key = x_strdup(line);
+ node->val = x_strdup(val);
+ if (node->val && !nextline) {
+ node->val = expand_envars(node->val);
+ }
+ }
+ }
+ fclose(fp);
+
+ return top;
+cleanup:
+ fclose(fp);
+ ini_free(top);
+ return NULL;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of ini
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of utf-8
+ * ---------------------------------------------------------------------
+ */
+
+static int utf8_to_unicode_path(wchar_t* retstr, size_t retlen,
+ const char* srcstr, size_t unc)
+{
+ /* TODO: The computations could preconvert the string to determine
+ * the true size of the retstr, but that's a memory over speed
+ * tradeoff that isn't appropriate this early in development.
+ *
+ * Allocate the maximum string length based on leading 4
+ * characters of \\?\ (allowing nearly unlimited path lengths)
+ * plus the trailing null, then transform /'s into \\'s since
+ * the \\?\ form doesn't allow '/' path seperators.
+ *
+ * Note that the \\?\ form only works for local drive paths, and
+ * \\?\UNC\ is needed UNC paths.
+ */
+ size_t srcremains = strlen(srcstr) + 1;
+ wchar_t *t = retstr;
+
+ /* leave an extra space for double zero */
+ --retlen;
+ /* This is correct, we don't twist the filename if it is will
+ * definately be shorter than MAX_PATH. It merits some
+ * performance testing to see if this has any effect, but there
+ * seem to be applications that get confused by the resulting
+ * Unicode \\?\ style file names, especially if they use argv[0]
+ * or call the Win32 API functions such as GetModuleName, etc.
+ * Not every application is prepared to handle such names.
+ *
+ * Note that a utf-8 name can never result in more wide chars
+ * than the original number of utf-8 narrow chars.
+ */
+ if (srcremains > unc) {
+ if (srcstr[1] == ':' && (srcstr[2] == '/' || srcstr[2] == '\\')) {
+ wcscpy (retstr, L"\\\\?\\");
+ retlen -= 4;
+ t += 4;
+ }
+ else if ((srcstr[0] == '/' || srcstr[0] == '\\')
+ && (srcstr[1] == '/' || srcstr[1] == '\\')
+ && (srcstr[2] != '?')) {
+ /* Skip the slashes */
+ srcstr += 2;
+ srcremains -= 2;
+ wcscpy (retstr, L"\\\\?\\UNC\\");
+ retlen -= 8;
+ t += 8;
+ }
+ }
+ if (!MultiByteToWideChar(CP_UTF8, 0, srcstr, -1, t, retlen))
+ return x_cerror(0);
+ for (; *t; t++) {
+ if (*t == L'/')
+ *t = L'\\';
+ }
+ *t = L'\0';
+ return 0;
+}
+
+static int unicode_to_utf8_path(char* retstr, size_t retlen,
+ const wchar_t* srcstr)
+{
+ /* Skip the leading 4 characters if the path begins \\?\, or substitute
+ * // for the \\?\UNC\ path prefix, allocating the maximum string
+ * length based on the remaining string, plus the trailing null.
+ * then transform \\'s back into /'s since the \\?\ form never
+ * allows '/' path seperators, and APR always uses '/'s.
+ */
+ if (srcstr[0] == L'\\' && srcstr[1] == L'\\' &&
+ srcstr[2] == L'?' && srcstr[3] == L'\\') {
+ if (srcstr[4] == L'U' && srcstr[5] == L'N' &&
+ srcstr[6] == L'C' && srcstr[7] == L'\\') {
+ srcstr += 8;
+ retstr[0] = '\\';
+ retstr[1] = '\\';
+ retlen -= 2;
+ retstr += 2;
+ }
+ else {
+ srcstr += 4;
+ }
+ }
+
+ if (!WideCharToMultiByte(CP_UTF8, 0, srcstr, -1,
+ retstr, retlen, NULL, 0))
+ return x_cerror(0);
+
+ return 0;
+}
+
+/*
+ * An internal function to convert an array of strings (either
+ * a counted or NULL terminated list, such as an argv[argc] or env[]
+ * list respectively) from wide Unicode strings to narrow utf-8 strings.
+ * These are allocated from the MSVCRT's _CRT_BLOCK to trick the system
+ * into trusting our store.
+ */
+int wastrtoastr(char const * const **retarr,
+ wchar_t const * const *arr, int args)
+{
+ size_t elesize = 0;
+ char **newarr;
+ char *elements;
+ char *ele;
+ int arg;
+
+ if (args < 0) {
+ for (args = 0; arr[args]; ++args) {
+ /* Nothing. */
+ }
+ }
+ newarr = _malloc_dbg((args + 1) * sizeof(char *),
+ _CRT_BLOCK, __FILE__, __LINE__);
+
+ for (arg = 0; arg < args; ++arg) {
+ newarr[arg] = (void*)(wcslen(arr[arg]) + 1);
+ elesize += (size_t)newarr[arg];
+ }
+
+ /* This is a safe max allocation, we will realloc after
+ * processing and return the excess to the free store.
+ * 3 ucs bytes hold any single wchar_t value (16 bits)
+ * 4 ucs bytes will hold a wchar_t pair value (20 bits)
+ */
+ elesize = elesize * 3 + 1;
+ ele = elements = _malloc_dbg(elesize * sizeof(char),
+ _CRT_BLOCK, __FILE__, __LINE__);
+
+ for (arg = 0; arg < args; ++arg) {
+ size_t len = (size_t)newarr[arg];
+
+ newarr[arg] = ele;
+ len = WideCharToMultiByte(CP_UTF8, 0, arr[arg], -1,
+ newarr[arg], len, NULL, 0);
+ ele += len;
+ assert(len);
+ }
+
+ newarr[arg] = NULL;
+ *(ele++) = '\0';
+
+ /* Return to the free store if the heap realloc is the least bit optimized
+ */
+ ele = _realloc_dbg(elements, ele - elements,
+ _CRT_BLOCK, __FILE__, __LINE__);
+
+ if (ele != elements) {
+ size_t diff = ele - elements;
+ for (arg = 0; arg < args; ++arg) {
+ newarr[arg] += diff;
+ }
+ }
+
+ *retarr = newarr;
+ return args;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of utf-8
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of tests
+ * ---------------------------------------------------------------------
+ */
+
+static void test_getopt(int argc, const char **argv)
+{
+ int ch;
+
+ while ((ch = getopt(argc, argv, "s:V:g:r:qLRS-")) != EOF) {
+ printf("Valid argument = %c [%s]\n", ch, optarg);
+ }
+ argc -= optind;
+ argv += optind;
+ for (ch = 0; ch < argc; ch++)
+ printf("Option %d is %s\n", ch, argv[ch]);
+}
+
+static int test_path()
+{
+ char *test[] = {
+ "test",
+ "\\test",
+ "\\\\?\\UNC\\C:\\..\\test/foo",
+ "//C://../../..\\..\\..\\..\\*/foo",
+ "C:\\W\\tools\\foo\\..\\..\\*/foo/barsalllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll/dddddddddddddddddddddddddddddddddddddddddddddddddddddddddaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ "./",
+ NULL
+ };
+ char **p;
+ for (p = test; *p; p++) {
+ printf("Full path is: %s\n", x_fulldir(*p));
+ }
+ printf("Wide is %S\n", x_wstrdup_utf8("Ax"));
+ return 0;
+}
+
+static int test_ini()
+{
+
+ ini_section_t *ini = ini_load("test.ini");
+ ini_section_t *top = ini;
+ while (ini) {
+ ini_node_t *node = ini->nodes;
+ printf("Section [%s]\n", ini->name);
+ while (node) {
+ printf(" %s=%s\n", node->key, node->val);
+ node = node->next;
+ }
+ ini = ini->next;
+ }
+ ini_free(top);
+ return 0;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of tests
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of user interface
+ * ---------------------------------------------------------------------
+ */
+
+static const char *programs[] = {
+ "mkdir", "Creates a new directory(ies)",
+ "rmdir", "Removes directory(ies)",
+ "touch", "Change file timestamps",
+ NULL, NULL
+};
+
+static const char str_license[] = ""
+"Licensed to the Apache Software Foundation (ASF) under one or more\n"
+"contributor license agreements. See the NOTICE file distributed with\n"
+"this work for additional information regarding copyright ownership.\n"
+"The ASF licenses this file to You under the Apache License, Version 2.0\n"
+"(the \"License\"); you may not use this file except in compliance with\n"
+"the License. You may obtain a copy of the License at\n"
+"\n"
+" http://www.apache.org/licenses/LICENSE-2.0\n"
+"\n"
+"Unless required by applicable law or agreed to in writing, software\n"
+"distributed under the License is distributed on an \"AS IS\" BASIS,\n"
+"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
+"See the License for the specific language governing permissions and\n"
+"limitations under the License.\n\n";
+
+static int print_banner(int license)
+{
+ fprintf(stdout, "xtools (Windows generic build tools) version 1.0.0\n");
+ fprintf(stdout, "Written by Mladen Turk (mturk(a)redhat.com).\n\n");
+ if (license)
+ fprintf(stdout, "%s", str_license);
+ return 0;
+}
+
+static void print_programs()
+{
+ const char **p;
+ fprintf(stderr, "Where supported commands are:\n\n");
+ for (p = programs; *p; p += 2) {
+ fprintf(stderr, " %-16s%s\n", *p, *(p+1));
+ }
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of user interface
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of programs usage
+ * ---------------------------------------------------------------------
+ */
+
+static int prog_mkdir_usage(int retval)
+{
+ fprintf(stderr, "Usage: %s [OPTION]... DIRECTORY...\n", progname);
+ fprintf(stderr, "Create the DIRECTORY(ies), if they do not already exist.\n");
+ fprintf(stderr, "Any intermediate directories in the path are created, if needed\n\n");
+ fprintf(stderr, " -v, -V, --verbose explain what is being done.\n");
+ fprintf(stderr, " --version output version information and exit.\n");
+ fprintf(stderr, " -h, -H, --help display this help and exit.\n\n");
+ return retval;
+}
+
+static int prog_rmdir_usage(int retval)
+{
+ fprintf(stderr, "Usage: %s [OPTION]... DIRECTORY...\n", progname);
+ fprintf(stderr, "Remove (unlink) the DIRECTORY(ies).\n\n");
+ fprintf(stderr, " -r, -R, remove the contents of directories recursively.\n\n");
+ fprintf(stderr, " -v, -V, --verbose explain what is being done.\n");
+ fprintf(stderr, " --version output version information and exit.\n");
+ fprintf(stderr, " -h, -H, --help display this help and exit.\n\n");
+ return retval;
+}
+
+static int prog_touch_usage(int retval)
+{
+ fprintf(stderr, "Usage: %s [OPTION]... FILE...\n", progname);
+ fprintf(stderr, "Update the access and modification times of each FILE to the current time\n\n");
+ fprintf(stderr, " -a, -A, change only the access time.\n");
+ fprintf(stderr, " -c, -C, do not create any files.\n");
+ fprintf(stderr, " -d, -D, STRING parse STRING and use it instead of current time.\n");
+ fprintf(stderr, " -m, -M, change only the modification time.\n");
+ fprintf(stderr, " -r, -R, FILE use this file time's instead current time.\n");
+ fprintf(stderr, " -t, -T, STAMP use [[CC]YY]MMDDhhmm[.ss] instead of current time.\n\n");
+ fprintf(stderr, " -v, -V, --verbose explain what is being done.\n");
+ fprintf(stderr, " --version output version information and exit.\n");
+ fprintf(stderr, " -h, -H, --help display this help and exit.\n\n");
+ return retval;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of programs usage
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of programs
+ * ---------------------------------------------------------------------
+ */
+
+static int prog_mkdir(int argc, const char **argv, const char **env)
+{
+ int i, ch, rv = 0;
+
+ verbose = 0;
+ x_free(__pname);
+ __pname = "mkdir";
+
+ while ((ch = getopt(argc, argv, "hHvV")) != EOF) {
+ switch (ch) {
+ case '.':
+ if (!strcmp(optarg, "verbose"))
+ verbose = 1;
+ else if (!strcmp(optarg, "version"))
+ return print_banner(1);
+ else if (!strcmp(optarg, "help"))
+ return prog_mkdir_usage(0);
+ else
+ return prog_mkdir_usage(EINVAL);
+ break;
+ case 'v':
+ case 'V':
+ verbose = 1;
+ break;
+ case 'h':
+ case 'H':
+ return prog_mkdir_usage(0);
+ break;
+ case '?':
+ return EINVAL;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc < 1) {
+ return prog_mkdir_usage(EINVAL);
+ }
+
+ for (i = 0; i < argc; i++) {
+ if ((rv = x_createdir_r(argv[0])))
+ break;
+ }
+ return rv;
+}
+
+static int prog_rmdir(int argc, const char **argv, const char **env)
+{
+ int i, ch, rv = 0;
+ int recurse = 0;
+
+ x_free(__pname);
+ __pname = "rmdir";
+ while ((ch = getopt(argc, argv, "hHvVrR")) != EOF) {
+ switch (ch) {
+ case '.':
+ if (!strcmp(optarg, "verbose"))
+ verbose = 1;
+ else if (!strcmp(optarg, "version"))
+ return print_banner(1);
+ else if (!strcmp(optarg, "help"))
+ return prog_rmdir_usage(0);
+ else
+ return prog_rmdir_usage(EINVAL);
+ break;
+ case 'v':
+ case 'V':
+ verbose = 1;
+ break;
+ case 'h':
+ case 'H':
+ return prog_rmdir_usage(0);
+ break;
+ case 'r':
+ case 'R':
+ recurse = 1;
+ break;
+ case '?':
+ return EINVAL;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc < 1) {
+ return prog_rmdir_usage(EINVAL);
+ }
+ for (i = 0; i < argc; i++) {
+ if (recurse) {
+ if ((rv = x_rmdir_r(argv[i])))
+ break;
+ }
+ else {
+ if ((rv = x_rmdir(argv[i])))
+ break;
+ }
+ }
+ return rv;
+}
+
+static int prog_touch(int argc, const char **argv, const char **env)
+{
+ int i, ch, rv = 0;
+ int force = 0;
+ int flags = 0;
+ DWORD create = OPEN_ALWAYS;
+ const char *from = NULL;
+ const char *tstr = NULL;
+ wchar_t file[X_MAX_PATH];
+ WIN32_FILE_ATTRIBUTE_DATA ad;
+
+ x_free(__pname);
+ __pname = "touch";
+ while ((ch = getopt(argc, argv, "aAcCfFmMr:R:t:hHvV")) != EOF) {
+ switch (ch) {
+ case '.':
+ if (!strcmp(optarg, "verbose"))
+ verbose = 1;
+ else if (!strcmp(optarg, "version"))
+ return print_banner(1);
+ else if (!strcmp(optarg, "help"))
+ return prog_touch_usage(0);
+ else
+ return prog_touch_usage(EINVAL);
+ break;
+ case 'v':
+ case 'V':
+ verbose = 1;
+ break;
+ case 'h':
+ case 'H':
+ return prog_touch_usage(0);
+ break;
+ case 'f':
+ case 'F':
+ force = 1;
+ case 'c':
+ case 'C':
+ create = OPEN_EXISTING;
+ break;
+ case 'a':
+ case 'A':
+ flags |= 1;
+ break;
+ case 'm':
+ case 'M':
+ flags |= 2;
+ break;
+ case 'r':
+ case 'R':
+ from = optarg;
+ break;
+ case 't':
+ case 'T':
+ tstr = optarg;
+ break;
+ case '?':
+ return EINVAL;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc < 1) {
+ return prog_touch_usage(EINVAL);
+ }
+ if (!flags)
+ flags = 3;
+ if (from) {
+ if (rv = x_fstat(&ad, from)) {
+ if (verbose) {
+ x_wfullpath(file, X_MAX_PATH, from);
+ warnx("'%S' -- %s", file, cstrerror(rv));
+ }
+ return rv;
+ }
+ }
+ else if (tstr) {
+ SYSTEMTIME t;
+ size_t tl = strlen(tstr);
+ char *sp = strchr(tstr, '.');
+ int cen = 0;
+ int r = 0;
+ memset(&t, 0, sizeof(SYSTEMTIME));
+ if (sp)
+ tl -= (size_t)(sp - tstr);
+ if (tl == 12)
+ r = sscanf(tstr, "%4d%2d%2d%2d%2d",
+ &t.wYear, &t.wMonth,
+ &t.wDay, &t.wHour, &t.wMinute);
+ else if (tl == 10)
+ r = sscanf(tstr, "%2d%2d%2d%2d%2d",
+ &t.wYear, &t.wMonth,
+ &t.wDay, &t.wHour, &t.wMinute);
+ else if (tl == 8)
+ r = sscanf(tstr, "%2d%2d%2d%2d",
+ &t.wMonth,
+ &t.wDay, &t.wHour, &t.wMinute);
+
+ else {
+ if (verbose)
+ warnx("invalid time format %s", tstr);
+ return EINVAL;
+ }
+ if (sp)
+ t.wSecond = atoi(sp + 1);
+ if (t.wYear < 100) {
+ SYSTEMTIME n;
+ GetSystemTime(&n);
+ if (t.wYear)
+ t.wYear = (n.wYear - n.wYear % 100) + t.wYear;
+ else
+ t.wYear = n.wYear;
+ }
+ if (!SystemTimeToFileTime(&t, &ad.ftLastAccessTime)) {
+ if (verbose)
+ warnx("invalid time format %04d-%02d-%02d-%02d-%02d.%02d",
+ t.wYear, t.wMonth, t.wDay, t.wHour,
+ t.wMinute, t.wSecond);
+ return EINVAL;
+ }
+ ad.ftLastWriteTime = ad.ftLastAccessTime;
+ }
+ else {
+ GetSystemTimeAsFileTime(&ad.ftLastAccessTime);
+ ad.ftLastWriteTime = ad.ftLastAccessTime;
+ }
+ for (i = 0; i < argc; i++) {
+ HANDLE hf;
+ if ((rv = x_wfullpath(file, X_MAX_PATH, argv[i]))) {
+ if (verbose) {
+ warnx("'%s' -- %s", argv[i], cstrerror(rv));
+ }
+ return rv;
+ }
+ hf = CreateFileW(file, GENERIC_READ | GENERIC_WRITE,
+ 0, NULL, create,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hf == INVALID_HANDLE_VALUE) {
+ rv = x_cerror(0);
+ if (verbose) {
+ warnx("'%S' -- %s", file, cstrerror(rv));
+ }
+ return rv;
+ }
+ else {
+ FILETIME *at = NULL;
+ FILETIME *mt = NULL;
+ FILETIME *ct = NULL;
+ if (flags & 1)
+ at = &ad.ftLastAccessTime;
+ if (flags & 2)
+ mt = &ad.ftLastWriteTime;
+ GetFileTime(hf, &ad.ftCreationTime, NULL, NULL);
+ if (at && CompareFileTime(&ad.ftCreationTime, at) > 0) {
+ /* File creation time is higher then access
+ * time we wish to set
+ */
+ at = NULL;
+ }
+ if (mt && CompareFileTime(&ad.ftCreationTime, mt) > 0) {
+ /* File creation time is higher then modification
+ * time we wish to set
+ */
+ mt = NULL;
+ }
+ if (!SetFileTime(hf, NULL, at, mt)) {
+ rv = x_cerror(0);
+ if (verbose)
+ warnx("'%S' -- %s", file, cstrerror(rv));
+ }
+ if (verbose) {
+ if (at || mt)
+ warnx("'%S' modified.", file);
+ else
+ warnx("'%S' not modified.", file);
+ }
+ CloseHandle(hf);
+ }
+ }
+ return rv;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * end of programs
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------
+ * utf-8 main. Arguments passed are utf-8 encoded
+ * ---------------------------------------------------------------------
+ */
+static int umain(int argc, const char **argv, const char **env)
+{
+ const char *name = progname;
+ if (*name == 'x' || *name == 'X')
+ name++;
+ if (!stricmp(name, "mkdir"))
+ return prog_mkdir(argc, argv, env);
+ else {
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <command>\n",
+ progname);
+ return EINVAL;
+ }
+ if (!stricmp(argv[1], "mkdir"))
+ return prog_mkdir(--argc, ++argv, env);
+ else if (!stricmp(argv[1], "rmdir"))
+ return prog_rmdir(--argc, ++argv, env);
+ else if (!stricmp(argv[1], "touch"))
+ return prog_touch(--argc, ++argv, env);
+ else if (!stricmp(argv[1], "test")) {
+ argc -= 2;
+ argv += 2;
+ printf("Test %d %s\n", argc, *argv);
+ if (argc && !strcmp(*argv, "ini"))
+ return test_ini();
+ if (argc && !strcmp(*argv, "path"))
+ return test_path(--argc, ++argv, env);
+ }
+ else {
+ fprintf(stderr, "Usage: %s <command>\n",
+ progname);
+ print_programs();
+ return EINVAL;
+ }
+ }
+ return 0;
+}
+
+static void setup_env(const char **env)
+{ char *e;
+ if ((e = getenv("XTOOLS_PAUSE")) != NULL)
+ xtools_pause = 1;
+ if ((e = getenv("XTOOLS_VERBOSE")) != NULL) {
+ verbose = atoi(e);
+ if (!verbose)
+ verbose = 1;
+ }
+}
+
+int wmain(int argc, const wchar_t **wargv, const wchar_t **wenv)
+{
+ char **argv;
+ char **env;
+ wchar_t *modname;
+ int dupenv;
+ int rv;
+
+ /* Find on what we are running */
+ GetSystemInfo(&win_osinf);
+ win_osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
+ GetVersionExA((LPOSVERSIONINFOA)&win_osver);
+
+ if (win_osver.dwMajorVersion < 5) {
+ /* Pre WIN2K. bail out */
+ fprintf(stderr, "This program cannot be run on < Windows 2000\n");
+ _exit(EACCES);
+ return EACCES;
+ }
+ wastrtoastr(&argv, wargv, argc);
+ dupenv = wastrtoastr(&env, wenv, -1);
+
+ _environ = _malloc_dbg((dupenv + 1) * sizeof (char *),
+ _CRT_BLOCK, __FILE__, __LINE__);
+ memcpy(_environ, env, (dupenv + 1) * sizeof (char *));
+
+ /*
+ * MSVCRT will attempt to maintain the wide environment calls
+ * on _putenv(), which is bogus if we've passed a non-ascii
+ * string to _putenv(), since they use MultiByteToWideChar
+ * and breaking the implicit utf-8 assumption we've built.
+ *
+ * Reset _wenviron for good measure.
+ */
+ if (_wenviron) {
+ wenv = _wenviron;
+ _wenviron = NULL;
+ free((wchar_t **)wenv);
+ }
+ modname = x_malloc(X_MAX_PATH * 2);
+ __argv0 = x_malloc(X_MAX_PATH);
+ if (!GetModuleFileNameExW(GetCurrentProcess(), NULL,
+ modname, X_MAX_PATH))
+ exit(GetLastError());
+ if ((rv = unicode_to_utf8_path(__argv0, X_MAX_PATH, modname)))
+ exit(rv);
+ x_free(modname);
+ setup_env(env);
+ rv = umain(argc, argv, env);
+ if (xtools_pause) {
+ fprintf(stdout, "\nPress any key to continue...");
+ getch();
+ fprintf(stdout, "\n");
+ }
+ if (verbose)
+ warnx("exit(%d)", rv);
+ exit(rv);
+ /*
+ * Never reached.
+ * Just to make compiler happy
+ */
+ return rv;
+}
Property changes on: trunk/build/install/xtool/xtool.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/build/install/xtool/xtool.rc
===================================================================
--- trunk/build/install/xtool/xtool.rc (rev 0)
+++ trunk/build/install/xtool/xtool.rc 2008-03-31 12:14:20 UTC (rev 1489)
@@ -0,0 +1,77 @@
+/*
+ * XTOOL - Windows generic build tools
+ *
+ * Copyright(c) 2007 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#include <windows.h>
+
+#define STR_COPYRIGHT "Copyright � 2008 Red Hat Middleware, LLC. " \
+ "or its licensors, as applicable."
+
+#define STR_LICENSE "Distributable under LGPL license. " \
+ "See terms of license at gnu.org."
+
+#define STR_COMPANY "Red Hat�, Inc."
+#define STR_TRADEMARK "� Red Hat Inc."
+#define STR_PRODUCT "Xtool"
+#define STR_DESCR "Xtool - Windows generic build tools"
+
+#define STR_VERSION "1.0.0.0"
+
+IDI_MAINICON ICON "jboss.ico"
+IDI_RHELICON ICON "redhat.ico"
+
+1 VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x3fL
+#if defined(_DEBUG)
+ FILEFLAGS 0x03L
+#else
+ FILEFLAGS 0x02L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", STR_COPYRIGHT "\0"
+ VALUE "CompanyName", STR_COMPANY "\0"
+ VALUE "FileDescription", STR_PRODUCT "\0"
+ VALUE "FileVersion", STR_VERSION
+ VALUE "InternalName", STR_PRODUCT "\0"
+ VALUE "LegalCopyright", STR_COPYRIGHT "\0"
+ VALUE "OriginalFilename", "xtool.exe\0"
+ VALUE "ProductName", STR_PRODUCT "\0"
+ VALUE "ProductVersion", STR_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
16 years, 9 months
JBoss Native SVN: r1488 - trunk/build.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-03-29 04:49:59 -0400 (Sat, 29 Mar 2008)
New Revision: 1488
Modified:
trunk/build/NMAKEcommon.inc
Log:
Add -D_CONSOLE to eEXE targets since we ar building console targets
Modified: trunk/build/NMAKEcommon.inc
===================================================================
--- trunk/build/NMAKEcommon.inc 2008-03-29 08:46:21 UTC (rev 1487)
+++ trunk/build/NMAKEcommon.inc 2008-03-29 08:49:59 UTC (rev 1488)
@@ -205,6 +205,9 @@
# Common flags for all platforms
CMN_CFLAGS = -c -nologo -DWIN32 -D_WIN32 -D_WINDOWS $(NMAKE_WINNT) -W3
+!IF "$(TARGET)" == "EXE"
+CMN_CFLAGS = $(CMN_CFLAGS) -D_CONSOLE
+!ENDIF
!IF "$(CPU)" == "X86"
CPU_CFLAGS = -D_X86_=1
16 years, 9 months
JBoss Native SVN: r1487 - sandbox/httpd/src/java.
by jbossnative-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2008-03-29 04:46:21 -0400 (Sat, 29 Mar 2008)
New Revision: 1487
Modified:
sandbox/httpd/src/java/TestHttpClient.java
Log:
Add test of STATUS.
Modified: sandbox/httpd/src/java/TestHttpClient.java
===================================================================
--- sandbox/httpd/src/java/TestHttpClient.java 2008-03-29 08:45:41 UTC (rev 1486)
+++ sandbox/httpd/src/java/TestHttpClient.java 2008-03-29 08:46:21 UTC (rev 1487)
@@ -61,6 +61,11 @@
else if (command.compareToIgnoreCase("DUMP")==0) {
pm = (PostMethod) new DumpMethod(URL);
}
+ else if (command.compareToIgnoreCase("STATUS")==0) {
+ pm = (PostMethod) new StatusMethod(URL);
+ pm.addParameter("JVMRoute","node1");
+ pm.addParameter("Load", "50");
+ }
else
pm = (PostMethod) new InfoMethod(URL);
16 years, 9 months
JBoss Native SVN: r1486 - sandbox/httpd/src/native/mod_manager.
by jbossnative-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2008-03-29 04:45:41 -0400 (Sat, 29 Mar 2008)
New Revision: 1486
Modified:
sandbox/httpd/src/native/mod_manager/mod_manager.c
Log:
Add logic to process the STATUS message.
Modified: sandbox/httpd/src/native/mod_manager/mod_manager.c
===================================================================
--- sandbox/httpd/src/native/mod_manager/mod_manager.c 2008-03-29 08:41:21 UTC (rev 1485)
+++ sandbox/httpd/src/native/mod_manager/mod_manager.c 2008-03-29 08:45:41 UTC (rev 1486)
@@ -392,7 +392,7 @@
/* Insert or update node description */
int id;
if (insert_update_node(nodestatsmem, &nodeinfo, &id) != APR_SUCCESS)
- return 500;
+ return 500;
/* Insert the Alias and corresponding Context */
phost = vhost;
@@ -540,8 +540,56 @@
{
return process_appl_cmd(r, buff, REMOVE);
}
+
+/*
+ * Process the STATUS command
+ * Load -1 : Broken
+ * Load 0 : Standby.
+ * Load 1-100 : Load factor.
+ */
static int process_status(request_rec *r, char *buff)
{
+ int Load;
+ nodeinfo_t nodeinfo;
+ nodeinfo_t *node;
+ char **ptr = process_buff(r, buff);
+ if (ptr == NULL)
+ return 500;
+
+ int i = 0;
+ while (ptr[i]) {
+ if (strcasecmp(ptr[i], "JVMRoute") == 0) {
+ if (strlen(ptr[i+1])>=sizeof(nodeinfo.mess.JVMRoute))
+ return 500;
+ strcpy(nodeinfo.mess.JVMRoute, ptr[i+1]);
+ nodeinfo.mess.id = 0;
+ }
+ else if (strcasecmp(ptr[i], "Load") == 0) {
+ Load = atoi(ptr[i+1]);
+ }
+ else
+ return 500;
+ i++;
+ i++;
+ }
+
+ /* Read the node */
+ node = read_node(nodestatsmem, &nodeinfo);
+ if (node == NULL)
+ return 500;
+
+ /*
+ * If the node is usualable do a ping/pong to prevent Split-Brain Syndrome
+ * and update the worker status and load factor acccording to the test result.
+ */
+ ap_set_content_type(r, "text/plain");
+ ap_rprintf(r, "Type=STATUS-RSP&JVMRoute=%s", nodeinfo.mess.JVMRoute);
+
+ if (proxy_cluster_isup(r, node->mess.id, Load) != OK)
+ ap_rprintf(r, "&State=NOTOK\n");
+ else
+ ap_rprintf(r, "&State=OK\n");
+
return OK;
}
16 years, 9 months
JBoss Native SVN: r1485 - sandbox/httpd/src/native/mod_proxy_cluster.
by jbossnative-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2008-03-29 04:41:21 -0400 (Sat, 29 Mar 2008)
New Revision: 1485
Modified:
sandbox/httpd/src/native/mod_proxy_cluster/mod_proxy_cluster.c
Log:
Add assynchronous ping/pong (AJP only).
Modified: sandbox/httpd/src/native/mod_proxy_cluster/mod_proxy_cluster.c
===================================================================
--- sandbox/httpd/src/native/mod_proxy_cluster/mod_proxy_cluster.c 2008-03-29 08:30:00 UTC (rev 1484)
+++ sandbox/httpd/src/native/mod_proxy_cluster/mod_proxy_cluster.c 2008-03-29 08:41:21 UTC (rev 1485)
@@ -130,7 +130,11 @@
if (ids[j]) {
/* read the node and create the worker */
nodeinfo_t *node;
- node_storage->read_node(ids[j], &node);
+ if (node_storage->read_node(ids[j], &node) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "create_workers_node can't read id %d", ids[j]);
+ continue;
+ }
proxy_balancer *balancer = ap_proxy_get_balancer(r->pool, conf,
apr_pstrcat(r->pool, "balancer://", node->balancer, NULL));
if (balancer) {
@@ -144,6 +148,81 @@
}
}
+/* reslist constructor */
+/* XXX: Should use the proxy_util one. */
+static apr_status_t connection_constructor(void **resource, void *params,
+ apr_pool_t *pool)
+{
+ apr_pool_t *ctx;
+ proxy_conn_rec *conn;
+ proxy_worker *worker = (proxy_worker *)params;
+
+ /*
+ * Create the subpool for each connection
+ * This keeps the memory consumption constant
+ * when disconnecting from backend.
+ */
+ apr_pool_create(&ctx, pool);
+ conn = apr_pcalloc(pool, sizeof(proxy_conn_rec));
+
+ conn->pool = ctx;
+ conn->worker = worker;
+#if APR_HAS_THREADS
+ conn->inreslist = 1;
+#endif
+ *resource = conn;
+
+ return APR_SUCCESS;
+}
+
+/* connection cleanup routine */
+/* XXX: Should use the proxy_util one. */
+static apr_status_t connection_cleanup(void *theconn)
+{
+ proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
+ proxy_worker *worker = conn->worker;
+
+ /*
+ * If the connection pool is NULL the worker
+ * cleanup has been run. Just return.
+ */
+ if (!worker->cp) {
+ return APR_SUCCESS;
+ }
+
+#if APR_HAS_THREADS
+ /* Sanity check: Did we already return the pooled connection? */
+ if (conn->inreslist) {
+ ap_log_perror(APLOG_MARK, APLOG_ERR, 0, conn->pool,
+ "proxy: Pooled connection 0x%pp for worker %s has been"
+ " already returned to the connection pool.", conn,
+ worker->name);
+ return APR_SUCCESS;
+ }
+#endif
+
+ /* determine if the connection need to be closed */
+ if (conn->close_on_recycle || conn->close) {
+ apr_pool_t *p = conn->pool;
+ apr_pool_clear(conn->pool);
+ memset(conn, 0, sizeof(proxy_conn_rec));
+ conn->pool = p;
+ conn->worker = worker;
+ }
+#if APR_HAS_THREADS
+ if (worker->hmax && worker->cp->res) {
+ conn->inreslist = 1;
+ apr_reslist_release(worker->cp->res, (void *)conn);
+ }
+ else
+#endif
+ {
+ worker->cp->conn = conn;
+ }
+
+ /* Always return the SUCCESS */
+ return APR_SUCCESS;
+}
/* Retrieve the parameter with the given name
* Something like 'JSESSIONID=12345...N'
* XXX: Should use the mod_proxy_balancer ones.
@@ -204,6 +283,7 @@
}
return NULL;
}
+
/*
* Check that the request has a sessionid (even invalid)
*/
@@ -364,6 +444,160 @@
return mycandidate;
}
+/*
+ * Do a ping/pong to the node
+ */
+static apr_status_t proxy_cluster_try_pingpong(request_rec *r, proxy_worker *worker)
+{
+ apr_status_t rv;
+ proxy_conn_rec *conn;
+ /* get the proxy_conn_rec: from ap_proxy_acquire_connection */
+#if APR_HAS_THREADS
+ if (worker->hmax && worker->cp->res) {
+ rv = apr_reslist_acquire(worker->cp->res, (void **)&conn);
+ }
+ else
+#endif
+ {
+ /* create the new connection if the previous was destroyed */
+ if (!worker->cp->conn) {
+ connection_constructor((void **)&conn, worker, worker->cp->pool);
+ }
+ else {
+ conn = worker->cp->conn;
+ worker->cp->conn = NULL;
+ }
+ rv = APR_SUCCESS;
+ }
+
+ const char *scheme = "AJP";
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy_cluster_try_pingpong: failed acquiring connection");
+ if (conn) {
+ conn->close = 1;
+ ap_proxy_release_connection(scheme, conn, r->server);
+ }
+ return rv;
+ }
+
+ conn->worker = worker;
+ conn->close = 0;
+#if APR_HAS_THREADS
+ conn->inreslist = 0;
+#endif
+
+ /* Replace ap_proxy_determine_connection XXX: Still not ok */
+ if (!conn->hostname) {
+ conn->hostname = apr_pstrdup(conn->pool, worker->hostname);
+ conn->port = worker->port;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy_cluster_try_pingpong: connection to %s : %d",
+ conn->hostname, conn->port);
+
+ if (conn->sock) {
+ apr_socket_close(conn->sock);
+ conn->sock = NULL;
+ }
+ if (conn->connection) {
+ apr_pool_cleanup_kill(conn->connection->pool, conn, connection_cleanup);
+ conn->connection = NULL;
+ }
+ rv = apr_sockaddr_info_get(&(conn->addr),
+ conn->hostname, APR_UNSPEC,
+ conn->port, 0,
+ conn->pool);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy_cluster_try_pingpong: can't resolve %s",
+ conn->hostname);
+ ap_proxy_release_connection(scheme, conn, r->server);
+ return rv;
+ }
+ }
+
+ /* Connect to the backend */
+ rv = ap_proxy_connect_backend(scheme, conn, worker, r->server);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy_cluster_try_pingpong: can't connect to backend");
+ ap_proxy_release_connection(scheme, conn, r->server);
+ return rv;
+ }
+
+ apr_interval_time_t timeout = worker->ping_timeout;
+ if (timeout <= 0)
+ timeout = apr_time_from_sec(10); /* 10 seconds */
+
+ rv = ajp_handle_cping_cpong(conn->sock, r, timeout);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy_cluster_try_pingpong: cping_cpong failed");
+ }
+ ap_proxy_release_connection(scheme, conn, r->server);
+ return rv;
+}
+/*
+ * Check that we could connect to the node
+ * id : worker id
+ * load : load factor from the cluster manager.
+ */
+PROXY_DECLARE(int) proxy_cluster_isup(request_rec *r, int id, int load)
+{
+ void *sconf = r->server->module_config;
+ proxy_server_conf *conf = (proxy_server_conf *)
+ ap_get_module_config(sconf, &proxy_module);
+ int i;
+ apr_status_t rv;
+ proxy_worker *worker;
+
+ /* create the workers (that could be the first time) */
+ create_workers_node(r);
+
+ /* search for the worker */
+ worker = (proxy_worker *)conf->workers->elts;
+ for (i = 0; i < conf->workers->nelts; i++) {
+ if (worker->id == id)
+ break;
+ }
+ if (i == conf->workers->nelts) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy_cluster_isup: Can't find worker for %d", id);
+ return 500;
+ }
+
+ /* Try a ping/pong to check the node */
+ if (load > 0) {
+ /* Only try usuable nodes */
+ rv = proxy_cluster_try_pingpong(r, worker);
+ if (rv != APR_SUCCESS) {
+ worker->s->status |= PROXY_WORKER_IN_ERROR;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy_cluster_isup: pingpong failed");
+ return 500;
+ }
+ }
+ if (load == -1) {
+ worker->s->status |= PROXY_WORKER_IN_ERROR;
+ }
+ else if (load == 0) {
+ /*
+ * XXX: PROXY_WORKER_HOT_STANDBY Doesn't look supported
+ * mark worker in error for the moment
+ */
+ worker->s->status |= PROXY_WORKER_IN_ERROR;
+ worker->s->status |= PROXY_WORKER_HOT_STANDBY;
+ }
+ else {
+ worker->s->status &= ~PROXY_WORKER_IN_ERROR;
+ worker->s->status &= ~PROXY_WORKER_STOPPED;
+ worker->s->status &= ~PROXY_WORKER_DISABLED;
+ worker->s->status &= PROXY_WORKER_HOT_STANDBY;
+ worker->s->lbfactor = load;
+ }
+ return 0;
+}
+
static int proxy_cluster_post_config(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s)
{
16 years, 9 months
JBoss Native SVN: r1484 - sandbox/httpd/src/native/common.
by jbossnative-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2008-03-29 04:30:00 -0400 (Sat, 29 Mar 2008)
New Revision: 1484
Modified:
sandbox/httpd/src/native/common/node.c
Log:
Add missing update of offset.
Modified: sandbox/httpd/src/native/common/node.c
===================================================================
--- sandbox/httpd/src/native/common/node.c 2008-03-29 07:22:58 UTC (rev 1483)
+++ sandbox/httpd/src/native/common/node.c 2008-03-29 08:30:00 UTC (rev 1484)
@@ -90,7 +90,8 @@
if (strcmp(in->mess.JVMRoute, ou->mess.JVMRoute) == 0) {
memcpy(ou, in, sizeof(nodeinfo_t));
ou->mess.id = id;
- ou->updatetime = apr_time_sec(apr_time_now());
+ ou->updatetime = (unsigned long) apr_time_sec(apr_time_now());
+ ou->offset = sizeof(nodemess_t) + sizeof(unsigned long) + sizeof(ou->balancer) + sizeof(int);
*data = ou;
return APR_SUCCESS;
}
@@ -117,7 +118,7 @@
memcpy(ou, node, sizeof(nodeinfo_t));
ou->mess.id = ident;
*id = ident;
- ou->updatetime = apr_time_sec(apr_time_now());
+ ou->updatetime = (unsigned long) apr_time_sec(apr_time_now());
/* set of offset to the proxy_worker_stat */
ou->offset = sizeof(nodemess_t) + sizeof(unsigned long) + sizeof(ou->balancer) + sizeof(int);
16 years, 9 months
JBoss Native SVN: r1483 - trunk/httpd/httpd-2.2.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-03-29 03:22:58 -0400 (Sat, 29 Mar 2008)
New Revision: 1483
Modified:
trunk/httpd/httpd-2.2/NMAKEcommon.inc
Log:
Copy main .inc file. TODO: Use the master .inc file
Modified: trunk/httpd/httpd-2.2/NMAKEcommon.inc
===================================================================
--- trunk/httpd/httpd-2.2/NMAKEcommon.inc 2008-03-29 07:14:23 UTC (rev 1482)
+++ trunk/httpd/httpd-2.2/NMAKEcommon.inc 2008-03-29 07:22:58 UTC (rev 1483)
@@ -20,12 +20,12 @@
# and linker parameters.
# Common params:
# CPU Compile for specified CPU. Supported CPU's are:
-# i386
-# AMD64
-# IA64
+# X86 (Common x86 architecture)
+# X64 (AMD64/EMT64 architecture)
+# I64 (Intel IA64 architecture)
# If not specified it will default to the
# PROCESSOR_ARCHITECTURE environment variable
-# or to the i386 if not specified.
+# or to the X86 if not specified.
# WINVER Compile for specified Windows version
# WINNT for Windows 2000 and up(default)
# WINXP for Windows XP and up
@@ -50,6 +50,13 @@
# LFLAGS Added to the common LFLAGS
# RCFLAGS Added to the common RCFLAGS
#
+# Compiler tools environment variables:
+# CC C compiler (defaults to cl.exe)
+# LINK Linker (defaults to link.exe)
+# RC Resource compiler (defaults to rc.exe)
+# MT Manifest toolkit (defaults to mt.exe)
+# ML Assembler (defaults to ml.exe or ml64.exe)
+#
# Originally contributed by Mladen Turk <mturk jboss.com>
#
# ====================================================================
@@ -85,12 +92,17 @@
!IF !DEFINED(CPU) || "$(CPU)" == ""
!IF "$(PROCESSOR_ARCHITECTURE)" == ""
+!IF "$(PROCESSOR_ARCHITEW6432)" == ""
CPU=X86
!ELSE
+CPU=$(PROCESSOR_ARCHITEW6432)
+!ENDIF
+!ELSE
CPU=$(PROCESSOR_ARCHITECTURE)
!ENDIF
!ENDIF
+
!IF "$(CPU)" == "I386"
CPU=X86
!ENDIF
16 years, 9 months
JBoss Native SVN: r1482 - trunk/build.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-03-29 03:14:23 -0400 (Sat, 29 Mar 2008)
New Revision: 1482
Modified:
trunk/build/NMAKEcommon.inc
Log:
Use PROCESSOR_ARCHITEW6432 envvar if present
Modified: trunk/build/NMAKEcommon.inc
===================================================================
--- trunk/build/NMAKEcommon.inc 2008-03-29 06:26:05 UTC (rev 1481)
+++ trunk/build/NMAKEcommon.inc 2008-03-29 07:14:23 UTC (rev 1482)
@@ -20,12 +20,12 @@
# and linker parameters.
# Common params:
# CPU Compile for specified CPU. Supported CPU's are:
-# i386
-# AMD64
-# IA64
+# X86 (Common x86 architecture)
+# X64 (AMD64/EMT64 architecture)
+# I64 (Intel IA64 architecture)
# If not specified it will default to the
# PROCESSOR_ARCHITECTURE environment variable
-# or to the i386 if not specified.
+# or to the X86 if not specified.
# WINVER Compile for specified Windows version
# WINNT for Windows 2000 and up(default)
# WINXP for Windows XP and up
@@ -50,6 +50,13 @@
# LFLAGS Added to the common LFLAGS
# RCFLAGS Added to the common RCFLAGS
#
+# Compiler tools environment variables:
+# CC C compiler (defaults to cl.exe)
+# LINK Linker (defaults to link.exe)
+# RC Resource compiler (defaults to rc.exe)
+# MT Manifest toolkit (defaults to mt.exe)
+# ML Assembler (defaults to ml.exe or ml64.exe)
+#
# Originally contributed by Mladen Turk <mturk jboss.com>
#
# ====================================================================
@@ -85,12 +92,17 @@
!IF !DEFINED(CPU) || "$(CPU)" == ""
!IF "$(PROCESSOR_ARCHITECTURE)" == ""
+!IF "$(PROCESSOR_ARCHITEW6432)" == ""
CPU=X86
!ELSE
+CPU=$(PROCESSOR_ARCHITEW6432)
+!ENDIF
+!ELSE
CPU=$(PROCESSOR_ARCHITECTURE)
!ENDIF
!ENDIF
+
!IF "$(CPU)" == "I386"
CPU=X86
!ENDIF
16 years, 9 months
JBoss Native SVN: r1481 - trunk/utils/windows/native/service/procrun/resources.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-03-29 02:26:05 -0400 (Sat, 29 Mar 2008)
New Revision: 1481
Modified:
trunk/utils/windows/native/service/procrun/resources/jboss.ico
trunk/utils/windows/native/service/procrun/resources/procrunr.ico
trunk/utils/windows/native/service/procrun/resources/procruns.ico
Log:
Update icon artwork
Modified: trunk/utils/windows/native/service/procrun/resources/jboss.ico
===================================================================
(Binary files differ)
Modified: trunk/utils/windows/native/service/procrun/resources/procrunr.ico
===================================================================
(Binary files differ)
Modified: trunk/utils/windows/native/service/procrun/resources/procruns.ico
===================================================================
(Binary files differ)
16 years, 9 months