Flatten InfoZIP directory and fix build issues

This commit is contained in:
Justine Tunney 2022-04-20 21:59:25 -07:00
parent ae638c0850
commit 87396f43bc
66 changed files with 869 additions and 5763 deletions

60
third_party/zip/LICENSE vendored Normal file
View file

@ -0,0 +1,60 @@
This is version 2007-Mar-4 of the Info-ZIP license.
The definitive version of this document should be available at
ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely and
a copy at http://www.info-zip.org/pub/infozip/license.html.
Copyright (c) 1990-2007 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 above disclaimer and the following restrictions:
1. Redistributions of source code (in whole or in part) must retain
the above copyright notice, definition, disclaimer, and this list
of conditions.
2. Redistributions in binary form (compiled executables and libraries)
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, versions with
modified or added functionality, and dynamic, shared, or static library
versions not from Info-ZIP--must be plainly marked as such and must not
be misrepresented as being the original source or, if binaries,
compiled from 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 the Info-ZIP URL(s), such as to imply Info-ZIP
will provide support for the altered versions.
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.

7
third_party/zip/README.cosmo vendored Normal file
View file

@ -0,0 +1,7 @@
zip utility from Info-ZIP:
http://infozip.sourceforge.net/Zip.html
source code obtained as zip30.tar.gz from:
https://sourceforge.net/projects/infozip/files/

155
third_party/zip/api.h vendored Normal file
View file

@ -0,0 +1,155 @@
#ifndef _ZIPAPI_H
#define _ZIPAPI_H
#include "third_party/zip/zip.h"
/* clang-format off */
#define MAXPATH 1024
#if defined(WINDLL) || defined(API)
/*---------------------------------------------------------------------------
Prototypes for public Zip API (DLL) functions.
---------------------------------------------------------------------------*/
#define ZPVER_LEN sizeof(ZpVer)
/* These defines are set to zero for now, until OS/2 comes out
with a dll.
*/
#define D2_MAJORVER 0
#define D2_MINORVER 0
#define D2_PATCHLEVEL 0
/* intended to be a private struct: */
typedef struct _zip_ver {
uch major; /* e.g., integer 5 */
uch minor; /* e.g., 2 */
uch patchlevel; /* e.g., 0 */
uch not_used;
} _zip_version_type;
typedef struct _ZpVer {
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 */
BOOL fEncryption; /* TRUE if encryption enabled, FALSE otherwise */
_zip_version_type zip;
_zip_version_type os2dll;
_zip_version_type windll;
} ZpVer;
# ifndef EXPENTRY
# define EXPENTRY WINAPI
# endif
#ifndef DEFINED_ONCE
#define DEFINED_ONCE
typedef int (WINAPI DLLPRNT) (LPSTR, unsigned long);
typedef int (WINAPI DLLPASSWORD) (LPSTR, int, LPCSTR, LPCSTR);
#endif
#ifdef ZIP64_SUPPORT
typedef int (WINAPI DLLSERVICE) (LPCSTR, unsigned __int64);
typedef int (WINAPI DLLSERVICE_NO_INT64) (LPCSTR, unsigned long, unsigned long);
#else
typedef int (WINAPI DLLSERVICE) (LPCSTR, unsigned long);
#endif
typedef int (WINAPI DLLSPLIT) (LPSTR);
typedef int (WINAPI DLLCOMMENT)(LPSTR);
/* Structures */
typedef struct { /* zip options */
LPSTR Date; /* Date to include after */
LPSTR szRootDir; /* Directory to use as base for zipping */
LPSTR szTempDir; /* Temporary directory used during zipping */
BOOL fTemp; /* Use temporary directory '-b' during zipping */
BOOL fSuffix; /* include suffixes (not implemented) */
BOOL fEncrypt; /* encrypt files */
BOOL fSystem; /* include system and hidden files */
BOOL fVolume; /* Include volume label */
BOOL fExtra; /* Exclude extra attributes */
BOOL fNoDirEntries; /* Do not add directory entries */
BOOL fExcludeDate; /* Exclude files newer than specified date */
BOOL fIncludeDate; /* Include only files newer than specified date */
BOOL fVerbose; /* Mention oddities in zip file structure */
BOOL fQuiet; /* Quiet operation */
BOOL fCRLF_LF; /* Translate CR/LF to LF */
BOOL fLF_CRLF; /* Translate LF to CR/LF */
BOOL fJunkDir; /* Junk directory names */
BOOL fGrow; /* Allow appending to a zip file */
BOOL fForce; /* Make entries using DOS names (k for Katz) */
BOOL fMove; /* Delete files added or updated in zip file */
BOOL fDeleteEntries; /* Delete files from zip file */
BOOL fUpdate; /* Update zip file--overwrite only if newer */
BOOL fFreshen; /* Freshen zip file--overwrite only */
BOOL fJunkSFX; /* Junk SFX prefix */
BOOL fLatestTime; /* Set zip file time to time of latest file in it */
BOOL fComment; /* Put comment in zip file */
BOOL fOffsets; /* Update archive offsets for SFX files */
BOOL fPrivilege; /* Use privileges (WIN32 only) */
BOOL fEncryption; /* TRUE if encryption supported, else FALSE.
this is a read only flag */
LPSTR szSplitSize; /* This string contains the size that you want to
split the archive into. i.e. 100 for 100 bytes,
2K for 2 k bytes, where K is 1024, m for meg
and g for gig. If this string is not NULL it
will automatically be assumed that you wish to
split an archive. */
LPSTR szIncludeList; /* Pointer to include file list string (for VB) */
long IncludeListCount; /* Count of file names in the include list array */
char **IncludeList; /* Pointer to include file list array. Note that the last
entry in the array must be NULL */
LPSTR szExcludeList; /* Pointer to exclude file list (for VB) */
long ExcludeListCount; /* Count of file names in the include list array */
char **ExcludeList; /* Pointer to exclude file list array. Note that the last
entry in the array must be NULL */
int fRecurse; /* Recurse into subdirectories. 1 => -r, 2 => -R */
int fRepair; /* Repair archive. 1 => -F, 2 => -FF */
char fLevel; /* Compression level (0 - 9) */
} ZPOPT, _far *LPZPOPT;
typedef struct {
int argc; /* Count of files to zip */
LPSTR lpszZipFN; /* name of archive to create/update */
char **FNV; /* array of file names to zip up */
LPSTR lpszAltFNL; /* pointer to a string containing a list of file
names to zip up, separated by whitespace. Intended
for use only by VB users, all others should set this
to NULL. */
} ZCL, _far *LPZCL;
typedef struct {
DLLPRNT *print;
DLLCOMMENT *comment;
DLLPASSWORD *password;
DLLSPLIT *split; /* This MUST be set to NULL unless you want to be queried
for a destination for each split archive. */
#ifdef ZIP64_SUPPORT
DLLSERVICE *ServiceApplication64;
DLLSERVICE_NO_INT64 *ServiceApplication64_No_Int64;
#else
DLLSERVICE *ServiceApplication;
#endif
} ZIPUSERFUNCTIONS, far * LPZIPUSERFUNCTIONS;
extern LPZIPUSERFUNCTIONS lpZipUserFunctions;
void EXPENTRY ZpVersion(ZpVer far *);
int EXPENTRY ZpInit(LPZIPUSERFUNCTIONS lpZipUserFunc);
int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts);
#if defined(ZIPLIB) || defined(COM_OBJECT)
# define ydays zp_ydays
#endif
/* Functions not yet supported */
#if 0
int EXPENTRY ZpMain (int argc, char **argv);
int EXPENTRY ZpAltMain (int argc, char **argv, ZpInit *init);
#endif
#endif /* WINDLL? || API? */
#endif /* _ZIPAPI_H */

736
third_party/zip/crc32.c vendored Normal file
View file

@ -0,0 +1,736 @@
/* clang-format off */
/*
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors
* instead of four steps with four exclusive-ors. This results about a factor
* of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/
/* $Id: crc32.c,v 2.0 2007/01/07 05:20:36 spc Exp $ */
#define __CRC32_C /* identifies this source module */
#include "libc/nexgen32e/crc32.h"
#include "third_party/zip/zip.h"
#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
#ifndef ZCONST
# define ZCONST const
#endif
#include "third_party/zip/crc32.h"
/* When only the table of precomputed CRC values is needed, only the basic
system-independent table containing 256 entries is created; any support
for "unfolding" optimization is disabled.
*/
#if (defined(USE_ZLIB) || defined(CRC_TABLE_ONLY))
# ifdef IZ_CRCOPTIM_UNFOLDTBL
# undef IZ_CRCOPTIM_UNFOLDTBL
# endif
#endif /* (USE_ZLIB || CRC_TABLE_ONLY) */
#if defined(IZ_CRCOPTIM_UNFOLDTBL)
# define CRC_TBLS 4
#else
# define CRC_TBLS 1
#endif
/*
Generate tables 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 first (or only) 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.
The remaining 3 tables (if IZ_CRCOPTIM_UNFOLDTBL is enabled) allow for
word-at-a-time CRC calculation, where a word is four bytes.
*/
#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[CRC_TBLS*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 ZCONST 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 (n = 0; n < sizeof(p)/sizeof(uch); n++)
xor |= 1L << (31 - p[n]);
#else
# define xor 0xedb88320L
#endif
#ifdef DYNALLOC_CRCTAB
crctab_p = (ulg near *) nearmalloc (CRC_TBLS*256*sizeof(ulg));
if (crctab_p == NULL) {
ziperr(ZE_MEM, "crc_table allocation");
}
#endif /* DYNALLOC_CRCTAB */
/* generate a crc for every 8-bit value */
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] = REV_BE(c);
}
#ifdef IZ_CRCOPTIM_UNFOLDTBL
/* generate crc for each value followed by one, two, and three zeros */
for (n = 0; n < 256; n++) {
c = crctab_p[n];
for (k = 1; k < 4; k++) {
c = CRC32(c, 0, crctab_p);
crctab_p[k*256+n] = c;
}
}
#endif /* IZ_CRCOPTIM_UNFOLDTBL */
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[CRC_TBLS*256] = {
# ifdef IZ_CRC_BE_OPTIMIZ
0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L,
0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L,
0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L,
0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L,
0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L,
0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L,
0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L,
0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L,
0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L,
0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L,
0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL,
0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L,
0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L,
0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L,
0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L,
0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L,
0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL,
0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L,
0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL,
0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L,
0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L,
0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L,
0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL,
0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL,
0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L,
0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL,
0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L,
0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL,
0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L,
0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L,
0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L,
0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L,
0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L,
0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL,
0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L,
0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L,
0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L,
0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L,
0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L,
0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L,
0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L,
0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L,
0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL,
0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L,
0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L,
0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L,
0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L,
0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L,
0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL,
0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L,
0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL,
0x8def022dL
# ifdef IZ_CRCOPTIM_UNFOLDTBL
,
0x00000000L, 0x41311b19L, 0x82623632L, 0xc3532d2bL, 0x04c56c64L,
0x45f4777dL, 0x86a75a56L, 0xc796414fL, 0x088ad9c8L, 0x49bbc2d1L,
0x8ae8effaL, 0xcbd9f4e3L, 0x0c4fb5acL, 0x4d7eaeb5L, 0x8e2d839eL,
0xcf1c9887L, 0x5112c24aL, 0x1023d953L, 0xd370f478L, 0x9241ef61L,
0x55d7ae2eL, 0x14e6b537L, 0xd7b5981cL, 0x96848305L, 0x59981b82L,
0x18a9009bL, 0xdbfa2db0L, 0x9acb36a9L, 0x5d5d77e6L, 0x1c6c6cffL,
0xdf3f41d4L, 0x9e0e5acdL, 0xa2248495L, 0xe3159f8cL, 0x2046b2a7L,
0x6177a9beL, 0xa6e1e8f1L, 0xe7d0f3e8L, 0x2483dec3L, 0x65b2c5daL,
0xaaae5d5dL, 0xeb9f4644L, 0x28cc6b6fL, 0x69fd7076L, 0xae6b3139L,
0xef5a2a20L, 0x2c09070bL, 0x6d381c12L, 0xf33646dfL, 0xb2075dc6L,
0x715470edL, 0x30656bf4L, 0xf7f32abbL, 0xb6c231a2L, 0x75911c89L,
0x34a00790L, 0xfbbc9f17L, 0xba8d840eL, 0x79dea925L, 0x38efb23cL,
0xff79f373L, 0xbe48e86aL, 0x7d1bc541L, 0x3c2ade58L, 0x054f79f0L,
0x447e62e9L, 0x872d4fc2L, 0xc61c54dbL, 0x018a1594L, 0x40bb0e8dL,
0x83e823a6L, 0xc2d938bfL, 0x0dc5a038L, 0x4cf4bb21L, 0x8fa7960aL,
0xce968d13L, 0x0900cc5cL, 0x4831d745L, 0x8b62fa6eL, 0xca53e177L,
0x545dbbbaL, 0x156ca0a3L, 0xd63f8d88L, 0x970e9691L, 0x5098d7deL,
0x11a9ccc7L, 0xd2fae1ecL, 0x93cbfaf5L, 0x5cd76272L, 0x1de6796bL,
0xdeb55440L, 0x9f844f59L, 0x58120e16L, 0x1923150fL, 0xda703824L,
0x9b41233dL, 0xa76bfd65L, 0xe65ae67cL, 0x2509cb57L, 0x6438d04eL,
0xa3ae9101L, 0xe29f8a18L, 0x21cca733L, 0x60fdbc2aL, 0xafe124adL,
0xeed03fb4L, 0x2d83129fL, 0x6cb20986L, 0xab2448c9L, 0xea1553d0L,
0x29467efbL, 0x687765e2L, 0xf6793f2fL, 0xb7482436L, 0x741b091dL,
0x352a1204L, 0xf2bc534bL, 0xb38d4852L, 0x70de6579L, 0x31ef7e60L,
0xfef3e6e7L, 0xbfc2fdfeL, 0x7c91d0d5L, 0x3da0cbccL, 0xfa368a83L,
0xbb07919aL, 0x7854bcb1L, 0x3965a7a8L, 0x4b98833bL, 0x0aa99822L,
0xc9fab509L, 0x88cbae10L, 0x4f5def5fL, 0x0e6cf446L, 0xcd3fd96dL,
0x8c0ec274L, 0x43125af3L, 0x022341eaL, 0xc1706cc1L, 0x804177d8L,
0x47d73697L, 0x06e62d8eL, 0xc5b500a5L, 0x84841bbcL, 0x1a8a4171L,
0x5bbb5a68L, 0x98e87743L, 0xd9d96c5aL, 0x1e4f2d15L, 0x5f7e360cL,
0x9c2d1b27L, 0xdd1c003eL, 0x120098b9L, 0x533183a0L, 0x9062ae8bL,
0xd153b592L, 0x16c5f4ddL, 0x57f4efc4L, 0x94a7c2efL, 0xd596d9f6L,
0xe9bc07aeL, 0xa88d1cb7L, 0x6bde319cL, 0x2aef2a85L, 0xed796bcaL,
0xac4870d3L, 0x6f1b5df8L, 0x2e2a46e1L, 0xe136de66L, 0xa007c57fL,
0x6354e854L, 0x2265f34dL, 0xe5f3b202L, 0xa4c2a91bL, 0x67918430L,
0x26a09f29L, 0xb8aec5e4L, 0xf99fdefdL, 0x3accf3d6L, 0x7bfde8cfL,
0xbc6ba980L, 0xfd5ab299L, 0x3e099fb2L, 0x7f3884abL, 0xb0241c2cL,
0xf1150735L, 0x32462a1eL, 0x73773107L, 0xb4e17048L, 0xf5d06b51L,
0x3683467aL, 0x77b25d63L, 0x4ed7facbL, 0x0fe6e1d2L, 0xccb5ccf9L,
0x8d84d7e0L, 0x4a1296afL, 0x0b238db6L, 0xc870a09dL, 0x8941bb84L,
0x465d2303L, 0x076c381aL, 0xc43f1531L, 0x850e0e28L, 0x42984f67L,
0x03a9547eL, 0xc0fa7955L, 0x81cb624cL, 0x1fc53881L, 0x5ef42398L,
0x9da70eb3L, 0xdc9615aaL, 0x1b0054e5L, 0x5a314ffcL, 0x996262d7L,
0xd85379ceL, 0x174fe149L, 0x567efa50L, 0x952dd77bL, 0xd41ccc62L,
0x138a8d2dL, 0x52bb9634L, 0x91e8bb1fL, 0xd0d9a006L, 0xecf37e5eL,
0xadc26547L, 0x6e91486cL, 0x2fa05375L, 0xe836123aL, 0xa9070923L,
0x6a542408L, 0x2b653f11L, 0xe479a796L, 0xa548bc8fL, 0x661b91a4L,
0x272a8abdL, 0xe0bccbf2L, 0xa18dd0ebL, 0x62defdc0L, 0x23efe6d9L,
0xbde1bc14L, 0xfcd0a70dL, 0x3f838a26L, 0x7eb2913fL, 0xb924d070L,
0xf815cb69L, 0x3b46e642L, 0x7a77fd5bL, 0xb56b65dcL, 0xf45a7ec5L,
0x370953eeL, 0x763848f7L, 0xb1ae09b8L, 0xf09f12a1L, 0x33cc3f8aL,
0x72fd2493L
,
0x00000000L, 0x376ac201L, 0x6ed48403L, 0x59be4602L, 0xdca80907L,
0xebc2cb06L, 0xb27c8d04L, 0x85164f05L, 0xb851130eL, 0x8f3bd10fL,
0xd685970dL, 0xe1ef550cL, 0x64f91a09L, 0x5393d808L, 0x0a2d9e0aL,
0x3d475c0bL, 0x70a3261cL, 0x47c9e41dL, 0x1e77a21fL, 0x291d601eL,
0xac0b2f1bL, 0x9b61ed1aL, 0xc2dfab18L, 0xf5b56919L, 0xc8f23512L,
0xff98f713L, 0xa626b111L, 0x914c7310L, 0x145a3c15L, 0x2330fe14L,
0x7a8eb816L, 0x4de47a17L, 0xe0464d38L, 0xd72c8f39L, 0x8e92c93bL,
0xb9f80b3aL, 0x3cee443fL, 0x0b84863eL, 0x523ac03cL, 0x6550023dL,
0x58175e36L, 0x6f7d9c37L, 0x36c3da35L, 0x01a91834L, 0x84bf5731L,
0xb3d59530L, 0xea6bd332L, 0xdd011133L, 0x90e56b24L, 0xa78fa925L,
0xfe31ef27L, 0xc95b2d26L, 0x4c4d6223L, 0x7b27a022L, 0x2299e620L,
0x15f32421L, 0x28b4782aL, 0x1fdeba2bL, 0x4660fc29L, 0x710a3e28L,
0xf41c712dL, 0xc376b32cL, 0x9ac8f52eL, 0xada2372fL, 0xc08d9a70L,
0xf7e75871L, 0xae591e73L, 0x9933dc72L, 0x1c259377L, 0x2b4f5176L,
0x72f11774L, 0x459bd575L, 0x78dc897eL, 0x4fb64b7fL, 0x16080d7dL,
0x2162cf7cL, 0xa4748079L, 0x931e4278L, 0xcaa0047aL, 0xfdcac67bL,
0xb02ebc6cL, 0x87447e6dL, 0xdefa386fL, 0xe990fa6eL, 0x6c86b56bL,
0x5bec776aL, 0x02523168L, 0x3538f369L, 0x087faf62L, 0x3f156d63L,
0x66ab2b61L, 0x51c1e960L, 0xd4d7a665L, 0xe3bd6464L, 0xba032266L,
0x8d69e067L, 0x20cbd748L, 0x17a11549L, 0x4e1f534bL, 0x7975914aL,
0xfc63de4fL, 0xcb091c4eL, 0x92b75a4cL, 0xa5dd984dL, 0x989ac446L,
0xaff00647L, 0xf64e4045L, 0xc1248244L, 0x4432cd41L, 0x73580f40L,
0x2ae64942L, 0x1d8c8b43L, 0x5068f154L, 0x67023355L, 0x3ebc7557L,
0x09d6b756L, 0x8cc0f853L, 0xbbaa3a52L, 0xe2147c50L, 0xd57ebe51L,
0xe839e25aL, 0xdf53205bL, 0x86ed6659L, 0xb187a458L, 0x3491eb5dL,
0x03fb295cL, 0x5a456f5eL, 0x6d2fad5fL, 0x801b35e1L, 0xb771f7e0L,
0xeecfb1e2L, 0xd9a573e3L, 0x5cb33ce6L, 0x6bd9fee7L, 0x3267b8e5L,
0x050d7ae4L, 0x384a26efL, 0x0f20e4eeL, 0x569ea2ecL, 0x61f460edL,
0xe4e22fe8L, 0xd388ede9L, 0x8a36abebL, 0xbd5c69eaL, 0xf0b813fdL,
0xc7d2d1fcL, 0x9e6c97feL, 0xa90655ffL, 0x2c101afaL, 0x1b7ad8fbL,
0x42c49ef9L, 0x75ae5cf8L, 0x48e900f3L, 0x7f83c2f2L, 0x263d84f0L,
0x115746f1L, 0x944109f4L, 0xa32bcbf5L, 0xfa958df7L, 0xcdff4ff6L,
0x605d78d9L, 0x5737bad8L, 0x0e89fcdaL, 0x39e33edbL, 0xbcf571deL,
0x8b9fb3dfL, 0xd221f5ddL, 0xe54b37dcL, 0xd80c6bd7L, 0xef66a9d6L,
0xb6d8efd4L, 0x81b22dd5L, 0x04a462d0L, 0x33cea0d1L, 0x6a70e6d3L,
0x5d1a24d2L, 0x10fe5ec5L, 0x27949cc4L, 0x7e2adac6L, 0x494018c7L,
0xcc5657c2L, 0xfb3c95c3L, 0xa282d3c1L, 0x95e811c0L, 0xa8af4dcbL,
0x9fc58fcaL, 0xc67bc9c8L, 0xf1110bc9L, 0x740744ccL, 0x436d86cdL,
0x1ad3c0cfL, 0x2db902ceL, 0x4096af91L, 0x77fc6d90L, 0x2e422b92L,
0x1928e993L, 0x9c3ea696L, 0xab546497L, 0xf2ea2295L, 0xc580e094L,
0xf8c7bc9fL, 0xcfad7e9eL, 0x9613389cL, 0xa179fa9dL, 0x246fb598L,
0x13057799L, 0x4abb319bL, 0x7dd1f39aL, 0x3035898dL, 0x075f4b8cL,
0x5ee10d8eL, 0x698bcf8fL, 0xec9d808aL, 0xdbf7428bL, 0x82490489L,
0xb523c688L, 0x88649a83L, 0xbf0e5882L, 0xe6b01e80L, 0xd1dadc81L,
0x54cc9384L, 0x63a65185L, 0x3a181787L, 0x0d72d586L, 0xa0d0e2a9L,
0x97ba20a8L, 0xce0466aaL, 0xf96ea4abL, 0x7c78ebaeL, 0x4b1229afL,
0x12ac6fadL, 0x25c6adacL, 0x1881f1a7L, 0x2feb33a6L, 0x765575a4L,
0x413fb7a5L, 0xc429f8a0L, 0xf3433aa1L, 0xaafd7ca3L, 0x9d97bea2L,
0xd073c4b5L, 0xe71906b4L, 0xbea740b6L, 0x89cd82b7L, 0x0cdbcdb2L,
0x3bb10fb3L, 0x620f49b1L, 0x55658bb0L, 0x6822d7bbL, 0x5f4815baL,
0x06f653b8L, 0x319c91b9L, 0xb48adebcL, 0x83e01cbdL, 0xda5e5abfL,
0xed3498beL
,
0x00000000L, 0x6567bcb8L, 0x8bc809aaL, 0xeeafb512L, 0x5797628fL,
0x32f0de37L, 0xdc5f6b25L, 0xb938d79dL, 0xef28b4c5L, 0x8a4f087dL,
0x64e0bd6fL, 0x018701d7L, 0xb8bfd64aL, 0xddd86af2L, 0x3377dfe0L,
0x56106358L, 0x9f571950L, 0xfa30a5e8L, 0x149f10faL, 0x71f8ac42L,
0xc8c07bdfL, 0xada7c767L, 0x43087275L, 0x266fcecdL, 0x707fad95L,
0x1518112dL, 0xfbb7a43fL, 0x9ed01887L, 0x27e8cf1aL, 0x428f73a2L,
0xac20c6b0L, 0xc9477a08L, 0x3eaf32a0L, 0x5bc88e18L, 0xb5673b0aL,
0xd00087b2L, 0x6938502fL, 0x0c5fec97L, 0xe2f05985L, 0x8797e53dL,
0xd1878665L, 0xb4e03addL, 0x5a4f8fcfL, 0x3f283377L, 0x8610e4eaL,
0xe3775852L, 0x0dd8ed40L, 0x68bf51f8L, 0xa1f82bf0L, 0xc49f9748L,
0x2a30225aL, 0x4f579ee2L, 0xf66f497fL, 0x9308f5c7L, 0x7da740d5L,
0x18c0fc6dL, 0x4ed09f35L, 0x2bb7238dL, 0xc518969fL, 0xa07f2a27L,
0x1947fdbaL, 0x7c204102L, 0x928ff410L, 0xf7e848a8L, 0x3d58149bL,
0x583fa823L, 0xb6901d31L, 0xd3f7a189L, 0x6acf7614L, 0x0fa8caacL,
0xe1077fbeL, 0x8460c306L, 0xd270a05eL, 0xb7171ce6L, 0x59b8a9f4L,
0x3cdf154cL, 0x85e7c2d1L, 0xe0807e69L, 0x0e2fcb7bL, 0x6b4877c3L,
0xa20f0dcbL, 0xc768b173L, 0x29c70461L, 0x4ca0b8d9L, 0xf5986f44L,
0x90ffd3fcL, 0x7e5066eeL, 0x1b37da56L, 0x4d27b90eL, 0x284005b6L,
0xc6efb0a4L, 0xa3880c1cL, 0x1ab0db81L, 0x7fd76739L, 0x9178d22bL,
0xf41f6e93L, 0x03f7263bL, 0x66909a83L, 0x883f2f91L, 0xed589329L,
0x546044b4L, 0x3107f80cL, 0xdfa84d1eL, 0xbacff1a6L, 0xecdf92feL,
0x89b82e46L, 0x67179b54L, 0x027027ecL, 0xbb48f071L, 0xde2f4cc9L,
0x3080f9dbL, 0x55e74563L, 0x9ca03f6bL, 0xf9c783d3L, 0x176836c1L,
0x720f8a79L, 0xcb375de4L, 0xae50e15cL, 0x40ff544eL, 0x2598e8f6L,
0x73888baeL, 0x16ef3716L, 0xf8408204L, 0x9d273ebcL, 0x241fe921L,
0x41785599L, 0xafd7e08bL, 0xcab05c33L, 0x3bb659edL, 0x5ed1e555L,
0xb07e5047L, 0xd519ecffL, 0x6c213b62L, 0x094687daL, 0xe7e932c8L,
0x828e8e70L, 0xd49eed28L, 0xb1f95190L, 0x5f56e482L, 0x3a31583aL,
0x83098fa7L, 0xe66e331fL, 0x08c1860dL, 0x6da63ab5L, 0xa4e140bdL,
0xc186fc05L, 0x2f294917L, 0x4a4ef5afL, 0xf3762232L, 0x96119e8aL,
0x78be2b98L, 0x1dd99720L, 0x4bc9f478L, 0x2eae48c0L, 0xc001fdd2L,
0xa566416aL, 0x1c5e96f7L, 0x79392a4fL, 0x97969f5dL, 0xf2f123e5L,
0x05196b4dL, 0x607ed7f5L, 0x8ed162e7L, 0xebb6de5fL, 0x528e09c2L,
0x37e9b57aL, 0xd9460068L, 0xbc21bcd0L, 0xea31df88L, 0x8f566330L,
0x61f9d622L, 0x049e6a9aL, 0xbda6bd07L, 0xd8c101bfL, 0x366eb4adL,
0x53090815L, 0x9a4e721dL, 0xff29cea5L, 0x11867bb7L, 0x74e1c70fL,
0xcdd91092L, 0xa8beac2aL, 0x46111938L, 0x2376a580L, 0x7566c6d8L,
0x10017a60L, 0xfeaecf72L, 0x9bc973caL, 0x22f1a457L, 0x479618efL,
0xa939adfdL, 0xcc5e1145L, 0x06ee4d76L, 0x6389f1ceL, 0x8d2644dcL,
0xe841f864L, 0x51792ff9L, 0x341e9341L, 0xdab12653L, 0xbfd69aebL,
0xe9c6f9b3L, 0x8ca1450bL, 0x620ef019L, 0x07694ca1L, 0xbe519b3cL,
0xdb362784L, 0x35999296L, 0x50fe2e2eL, 0x99b95426L, 0xfcdee89eL,
0x12715d8cL, 0x7716e134L, 0xce2e36a9L, 0xab498a11L, 0x45e63f03L,
0x208183bbL, 0x7691e0e3L, 0x13f65c5bL, 0xfd59e949L, 0x983e55f1L,
0x2106826cL, 0x44613ed4L, 0xaace8bc6L, 0xcfa9377eL, 0x38417fd6L,
0x5d26c36eL, 0xb389767cL, 0xd6eecac4L, 0x6fd61d59L, 0x0ab1a1e1L,
0xe41e14f3L, 0x8179a84bL, 0xd769cb13L, 0xb20e77abL, 0x5ca1c2b9L,
0x39c67e01L, 0x80fea99cL, 0xe5991524L, 0x0b36a036L, 0x6e511c8eL,
0xa7166686L, 0xc271da3eL, 0x2cde6f2cL, 0x49b9d394L, 0xf0810409L,
0x95e6b8b1L, 0x7b490da3L, 0x1e2eb11bL, 0x483ed243L, 0x2d596efbL,
0xc3f6dbe9L, 0xa6916751L, 0x1fa9b0ccL, 0x7ace0c74L, 0x9461b966L,
0xf10605deL
# endif /* IZ_CRCOPTIM_UNFOLDTBL */
# else /* !IZ_CRC_BE_OPTIMIZ */
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
# ifdef IZ_CRCOPTIM_UNFOLDTBL
,
0x00000000L, 0x191b3141L, 0x32366282L, 0x2b2d53c3L, 0x646cc504L,
0x7d77f445L, 0x565aa786L, 0x4f4196c7L, 0xc8d98a08L, 0xd1c2bb49L,
0xfaefe88aL, 0xe3f4d9cbL, 0xacb54f0cL, 0xb5ae7e4dL, 0x9e832d8eL,
0x87981ccfL, 0x4ac21251L, 0x53d92310L, 0x78f470d3L, 0x61ef4192L,
0x2eaed755L, 0x37b5e614L, 0x1c98b5d7L, 0x05838496L, 0x821b9859L,
0x9b00a918L, 0xb02dfadbL, 0xa936cb9aL, 0xe6775d5dL, 0xff6c6c1cL,
0xd4413fdfL, 0xcd5a0e9eL, 0x958424a2L, 0x8c9f15e3L, 0xa7b24620L,
0xbea97761L, 0xf1e8e1a6L, 0xe8f3d0e7L, 0xc3de8324L, 0xdac5b265L,
0x5d5daeaaL, 0x44469febL, 0x6f6bcc28L, 0x7670fd69L, 0x39316baeL,
0x202a5aefL, 0x0b07092cL, 0x121c386dL, 0xdf4636f3L, 0xc65d07b2L,
0xed705471L, 0xf46b6530L, 0xbb2af3f7L, 0xa231c2b6L, 0x891c9175L,
0x9007a034L, 0x179fbcfbL, 0x0e848dbaL, 0x25a9de79L, 0x3cb2ef38L,
0x73f379ffL, 0x6ae848beL, 0x41c51b7dL, 0x58de2a3cL, 0xf0794f05L,
0xe9627e44L, 0xc24f2d87L, 0xdb541cc6L, 0x94158a01L, 0x8d0ebb40L,
0xa623e883L, 0xbf38d9c2L, 0x38a0c50dL, 0x21bbf44cL, 0x0a96a78fL,
0x138d96ceL, 0x5ccc0009L, 0x45d73148L, 0x6efa628bL, 0x77e153caL,
0xbabb5d54L, 0xa3a06c15L, 0x888d3fd6L, 0x91960e97L, 0xded79850L,
0xc7cca911L, 0xece1fad2L, 0xf5facb93L, 0x7262d75cL, 0x6b79e61dL,
0x4054b5deL, 0x594f849fL, 0x160e1258L, 0x0f152319L, 0x243870daL,
0x3d23419bL, 0x65fd6ba7L, 0x7ce65ae6L, 0x57cb0925L, 0x4ed03864L,
0x0191aea3L, 0x188a9fe2L, 0x33a7cc21L, 0x2abcfd60L, 0xad24e1afL,
0xb43fd0eeL, 0x9f12832dL, 0x8609b26cL, 0xc94824abL, 0xd05315eaL,
0xfb7e4629L, 0xe2657768L, 0x2f3f79f6L, 0x362448b7L, 0x1d091b74L,
0x04122a35L, 0x4b53bcf2L, 0x52488db3L, 0x7965de70L, 0x607eef31L,
0xe7e6f3feL, 0xfefdc2bfL, 0xd5d0917cL, 0xcccba03dL, 0x838a36faL,
0x9a9107bbL, 0xb1bc5478L, 0xa8a76539L, 0x3b83984bL, 0x2298a90aL,
0x09b5fac9L, 0x10aecb88L, 0x5fef5d4fL, 0x46f46c0eL, 0x6dd93fcdL,
0x74c20e8cL, 0xf35a1243L, 0xea412302L, 0xc16c70c1L, 0xd8774180L,
0x9736d747L, 0x8e2de606L, 0xa500b5c5L, 0xbc1b8484L, 0x71418a1aL,
0x685abb5bL, 0x4377e898L, 0x5a6cd9d9L, 0x152d4f1eL, 0x0c367e5fL,
0x271b2d9cL, 0x3e001cddL, 0xb9980012L, 0xa0833153L, 0x8bae6290L,
0x92b553d1L, 0xddf4c516L, 0xc4eff457L, 0xefc2a794L, 0xf6d996d5L,
0xae07bce9L, 0xb71c8da8L, 0x9c31de6bL, 0x852aef2aL, 0xca6b79edL,
0xd37048acL, 0xf85d1b6fL, 0xe1462a2eL, 0x66de36e1L, 0x7fc507a0L,
0x54e85463L, 0x4df36522L, 0x02b2f3e5L, 0x1ba9c2a4L, 0x30849167L,
0x299fa026L, 0xe4c5aeb8L, 0xfdde9ff9L, 0xd6f3cc3aL, 0xcfe8fd7bL,
0x80a96bbcL, 0x99b25afdL, 0xb29f093eL, 0xab84387fL, 0x2c1c24b0L,
0x350715f1L, 0x1e2a4632L, 0x07317773L, 0x4870e1b4L, 0x516bd0f5L,
0x7a468336L, 0x635db277L, 0xcbfad74eL, 0xd2e1e60fL, 0xf9ccb5ccL,
0xe0d7848dL, 0xaf96124aL, 0xb68d230bL, 0x9da070c8L, 0x84bb4189L,
0x03235d46L, 0x1a386c07L, 0x31153fc4L, 0x280e0e85L, 0x674f9842L,
0x7e54a903L, 0x5579fac0L, 0x4c62cb81L, 0x8138c51fL, 0x9823f45eL,
0xb30ea79dL, 0xaa1596dcL, 0xe554001bL, 0xfc4f315aL, 0xd7626299L,
0xce7953d8L, 0x49e14f17L, 0x50fa7e56L, 0x7bd72d95L, 0x62cc1cd4L,
0x2d8d8a13L, 0x3496bb52L, 0x1fbbe891L, 0x06a0d9d0L, 0x5e7ef3ecL,
0x4765c2adL, 0x6c48916eL, 0x7553a02fL, 0x3a1236e8L, 0x230907a9L,
0x0824546aL, 0x113f652bL, 0x96a779e4L, 0x8fbc48a5L, 0xa4911b66L,
0xbd8a2a27L, 0xf2cbbce0L, 0xebd08da1L, 0xc0fdde62L, 0xd9e6ef23L,
0x14bce1bdL, 0x0da7d0fcL, 0x268a833fL, 0x3f91b27eL, 0x70d024b9L,
0x69cb15f8L, 0x42e6463bL, 0x5bfd777aL, 0xdc656bb5L, 0xc57e5af4L,
0xee530937L, 0xf7483876L, 0xb809aeb1L, 0xa1129ff0L, 0x8a3fcc33L,
0x9324fd72L
,
0x00000000L, 0x01c26a37L, 0x0384d46eL, 0x0246be59L, 0x0709a8dcL,
0x06cbc2ebL, 0x048d7cb2L, 0x054f1685L, 0x0e1351b8L, 0x0fd13b8fL,
0x0d9785d6L, 0x0c55efe1L, 0x091af964L, 0x08d89353L, 0x0a9e2d0aL,
0x0b5c473dL, 0x1c26a370L, 0x1de4c947L, 0x1fa2771eL, 0x1e601d29L,
0x1b2f0bacL, 0x1aed619bL, 0x18abdfc2L, 0x1969b5f5L, 0x1235f2c8L,
0x13f798ffL, 0x11b126a6L, 0x10734c91L, 0x153c5a14L, 0x14fe3023L,
0x16b88e7aL, 0x177ae44dL, 0x384d46e0L, 0x398f2cd7L, 0x3bc9928eL,
0x3a0bf8b9L, 0x3f44ee3cL, 0x3e86840bL, 0x3cc03a52L, 0x3d025065L,
0x365e1758L, 0x379c7d6fL, 0x35dac336L, 0x3418a901L, 0x3157bf84L,
0x3095d5b3L, 0x32d36beaL, 0x331101ddL, 0x246be590L, 0x25a98fa7L,
0x27ef31feL, 0x262d5bc9L, 0x23624d4cL, 0x22a0277bL, 0x20e69922L,
0x2124f315L, 0x2a78b428L, 0x2bbade1fL, 0x29fc6046L, 0x283e0a71L,
0x2d711cf4L, 0x2cb376c3L, 0x2ef5c89aL, 0x2f37a2adL, 0x709a8dc0L,
0x7158e7f7L, 0x731e59aeL, 0x72dc3399L, 0x7793251cL, 0x76514f2bL,
0x7417f172L, 0x75d59b45L, 0x7e89dc78L, 0x7f4bb64fL, 0x7d0d0816L,
0x7ccf6221L, 0x798074a4L, 0x78421e93L, 0x7a04a0caL, 0x7bc6cafdL,
0x6cbc2eb0L, 0x6d7e4487L, 0x6f38fadeL, 0x6efa90e9L, 0x6bb5866cL,
0x6a77ec5bL, 0x68315202L, 0x69f33835L, 0x62af7f08L, 0x636d153fL,
0x612bab66L, 0x60e9c151L, 0x65a6d7d4L, 0x6464bde3L, 0x662203baL,
0x67e0698dL, 0x48d7cb20L, 0x4915a117L, 0x4b531f4eL, 0x4a917579L,
0x4fde63fcL, 0x4e1c09cbL, 0x4c5ab792L, 0x4d98dda5L, 0x46c49a98L,
0x4706f0afL, 0x45404ef6L, 0x448224c1L, 0x41cd3244L, 0x400f5873L,
0x4249e62aL, 0x438b8c1dL, 0x54f16850L, 0x55330267L, 0x5775bc3eL,
0x56b7d609L, 0x53f8c08cL, 0x523aaabbL, 0x507c14e2L, 0x51be7ed5L,
0x5ae239e8L, 0x5b2053dfL, 0x5966ed86L, 0x58a487b1L, 0x5deb9134L,
0x5c29fb03L, 0x5e6f455aL, 0x5fad2f6dL, 0xe1351b80L, 0xe0f771b7L,
0xe2b1cfeeL, 0xe373a5d9L, 0xe63cb35cL, 0xe7fed96bL, 0xe5b86732L,
0xe47a0d05L, 0xef264a38L, 0xeee4200fL, 0xeca29e56L, 0xed60f461L,
0xe82fe2e4L, 0xe9ed88d3L, 0xebab368aL, 0xea695cbdL, 0xfd13b8f0L,
0xfcd1d2c7L, 0xfe976c9eL, 0xff5506a9L, 0xfa1a102cL, 0xfbd87a1bL,
0xf99ec442L, 0xf85cae75L, 0xf300e948L, 0xf2c2837fL, 0xf0843d26L,
0xf1465711L, 0xf4094194L, 0xf5cb2ba3L, 0xf78d95faL, 0xf64fffcdL,
0xd9785d60L, 0xd8ba3757L, 0xdafc890eL, 0xdb3ee339L, 0xde71f5bcL,
0xdfb39f8bL, 0xddf521d2L, 0xdc374be5L, 0xd76b0cd8L, 0xd6a966efL,
0xd4efd8b6L, 0xd52db281L, 0xd062a404L, 0xd1a0ce33L, 0xd3e6706aL,
0xd2241a5dL, 0xc55efe10L, 0xc49c9427L, 0xc6da2a7eL, 0xc7184049L,
0xc25756ccL, 0xc3953cfbL, 0xc1d382a2L, 0xc011e895L, 0xcb4dafa8L,
0xca8fc59fL, 0xc8c97bc6L, 0xc90b11f1L, 0xcc440774L, 0xcd866d43L,
0xcfc0d31aL, 0xce02b92dL, 0x91af9640L, 0x906dfc77L, 0x922b422eL,
0x93e92819L, 0x96a63e9cL, 0x976454abL, 0x9522eaf2L, 0x94e080c5L,
0x9fbcc7f8L, 0x9e7eadcfL, 0x9c381396L, 0x9dfa79a1L, 0x98b56f24L,
0x99770513L, 0x9b31bb4aL, 0x9af3d17dL, 0x8d893530L, 0x8c4b5f07L,
0x8e0de15eL, 0x8fcf8b69L, 0x8a809decL, 0x8b42f7dbL, 0x89044982L,
0x88c623b5L, 0x839a6488L, 0x82580ebfL, 0x801eb0e6L, 0x81dcdad1L,
0x8493cc54L, 0x8551a663L, 0x8717183aL, 0x86d5720dL, 0xa9e2d0a0L,
0xa820ba97L, 0xaa6604ceL, 0xaba46ef9L, 0xaeeb787cL, 0xaf29124bL,
0xad6fac12L, 0xacadc625L, 0xa7f18118L, 0xa633eb2fL, 0xa4755576L,
0xa5b73f41L, 0xa0f829c4L, 0xa13a43f3L, 0xa37cfdaaL, 0xa2be979dL,
0xb5c473d0L, 0xb40619e7L, 0xb640a7beL, 0xb782cd89L, 0xb2cddb0cL,
0xb30fb13bL, 0xb1490f62L, 0xb08b6555L, 0xbbd72268L, 0xba15485fL,
0xb853f606L, 0xb9919c31L, 0xbcde8ab4L, 0xbd1ce083L, 0xbf5a5edaL,
0xbe9834edL
,
0x00000000L, 0xb8bc6765L, 0xaa09c88bL, 0x12b5afeeL, 0x8f629757L,
0x37def032L, 0x256b5fdcL, 0x9dd738b9L, 0xc5b428efL, 0x7d084f8aL,
0x6fbde064L, 0xd7018701L, 0x4ad6bfb8L, 0xf26ad8ddL, 0xe0df7733L,
0x58631056L, 0x5019579fL, 0xe8a530faL, 0xfa109f14L, 0x42acf871L,
0xdf7bc0c8L, 0x67c7a7adL, 0x75720843L, 0xcdce6f26L, 0x95ad7f70L,
0x2d111815L, 0x3fa4b7fbL, 0x8718d09eL, 0x1acfe827L, 0xa2738f42L,
0xb0c620acL, 0x087a47c9L, 0xa032af3eL, 0x188ec85bL, 0x0a3b67b5L,
0xb28700d0L, 0x2f503869L, 0x97ec5f0cL, 0x8559f0e2L, 0x3de59787L,
0x658687d1L, 0xdd3ae0b4L, 0xcf8f4f5aL, 0x7733283fL, 0xeae41086L,
0x525877e3L, 0x40edd80dL, 0xf851bf68L, 0xf02bf8a1L, 0x48979fc4L,
0x5a22302aL, 0xe29e574fL, 0x7f496ff6L, 0xc7f50893L, 0xd540a77dL,
0x6dfcc018L, 0x359fd04eL, 0x8d23b72bL, 0x9f9618c5L, 0x272a7fa0L,
0xbafd4719L, 0x0241207cL, 0x10f48f92L, 0xa848e8f7L, 0x9b14583dL,
0x23a83f58L, 0x311d90b6L, 0x89a1f7d3L, 0x1476cf6aL, 0xaccaa80fL,
0xbe7f07e1L, 0x06c36084L, 0x5ea070d2L, 0xe61c17b7L, 0xf4a9b859L,
0x4c15df3cL, 0xd1c2e785L, 0x697e80e0L, 0x7bcb2f0eL, 0xc377486bL,
0xcb0d0fa2L, 0x73b168c7L, 0x6104c729L, 0xd9b8a04cL, 0x446f98f5L,
0xfcd3ff90L, 0xee66507eL, 0x56da371bL, 0x0eb9274dL, 0xb6054028L,
0xa4b0efc6L, 0x1c0c88a3L, 0x81dbb01aL, 0x3967d77fL, 0x2bd27891L,
0x936e1ff4L, 0x3b26f703L, 0x839a9066L, 0x912f3f88L, 0x299358edL,
0xb4446054L, 0x0cf80731L, 0x1e4da8dfL, 0xa6f1cfbaL, 0xfe92dfecL,
0x462eb889L, 0x549b1767L, 0xec277002L, 0x71f048bbL, 0xc94c2fdeL,
0xdbf98030L, 0x6345e755L, 0x6b3fa09cL, 0xd383c7f9L, 0xc1366817L,
0x798a0f72L, 0xe45d37cbL, 0x5ce150aeL, 0x4e54ff40L, 0xf6e89825L,
0xae8b8873L, 0x1637ef16L, 0x048240f8L, 0xbc3e279dL, 0x21e91f24L,
0x99557841L, 0x8be0d7afL, 0x335cb0caL, 0xed59b63bL, 0x55e5d15eL,
0x47507eb0L, 0xffec19d5L, 0x623b216cL, 0xda874609L, 0xc832e9e7L,
0x708e8e82L, 0x28ed9ed4L, 0x9051f9b1L, 0x82e4565fL, 0x3a58313aL,
0xa78f0983L, 0x1f336ee6L, 0x0d86c108L, 0xb53aa66dL, 0xbd40e1a4L,
0x05fc86c1L, 0x1749292fL, 0xaff54e4aL, 0x322276f3L, 0x8a9e1196L,
0x982bbe78L, 0x2097d91dL, 0x78f4c94bL, 0xc048ae2eL, 0xd2fd01c0L,
0x6a4166a5L, 0xf7965e1cL, 0x4f2a3979L, 0x5d9f9697L, 0xe523f1f2L,
0x4d6b1905L, 0xf5d77e60L, 0xe762d18eL, 0x5fdeb6ebL, 0xc2098e52L,
0x7ab5e937L, 0x680046d9L, 0xd0bc21bcL, 0x88df31eaL, 0x3063568fL,
0x22d6f961L, 0x9a6a9e04L, 0x07bda6bdL, 0xbf01c1d8L, 0xadb46e36L,
0x15080953L, 0x1d724e9aL, 0xa5ce29ffL, 0xb77b8611L, 0x0fc7e174L,
0x9210d9cdL, 0x2aacbea8L, 0x38191146L, 0x80a57623L, 0xd8c66675L,
0x607a0110L, 0x72cfaefeL, 0xca73c99bL, 0x57a4f122L, 0xef189647L,
0xfdad39a9L, 0x45115eccL, 0x764dee06L, 0xcef18963L, 0xdc44268dL,
0x64f841e8L, 0xf92f7951L, 0x41931e34L, 0x5326b1daL, 0xeb9ad6bfL,
0xb3f9c6e9L, 0x0b45a18cL, 0x19f00e62L, 0xa14c6907L, 0x3c9b51beL,
0x842736dbL, 0x96929935L, 0x2e2efe50L, 0x2654b999L, 0x9ee8defcL,
0x8c5d7112L, 0x34e11677L, 0xa9362eceL, 0x118a49abL, 0x033fe645L,
0xbb838120L, 0xe3e09176L, 0x5b5cf613L, 0x49e959fdL, 0xf1553e98L,
0x6c820621L, 0xd43e6144L, 0xc68bceaaL, 0x7e37a9cfL, 0xd67f4138L,
0x6ec3265dL, 0x7c7689b3L, 0xc4caeed6L, 0x591dd66fL, 0xe1a1b10aL,
0xf3141ee4L, 0x4ba87981L, 0x13cb69d7L, 0xab770eb2L, 0xb9c2a15cL,
0x017ec639L, 0x9ca9fe80L, 0x241599e5L, 0x36a0360bL, 0x8e1c516eL,
0x866616a7L, 0x3eda71c2L, 0x2c6fde2cL, 0x94d3b949L, 0x090481f0L,
0xb1b8e695L, 0xa30d497bL, 0x1bb12e1eL, 0x43d23e48L, 0xfb6e592dL,
0xe9dbf6c3L, 0x516791a6L, 0xccb0a91fL, 0x740cce7aL, 0x66b96194L,
0xde0506f1L
# endif /* IZ_CRCOPTIM_UNFOLDTBL */
# endif /* ? IZ_CRC_BE_OPTIMIZ */
};
#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 crc_table;
#endif
}
#ifdef DYNALLOC_CRCTAB
void free_crc_table()
{
if (!CRC_TABLE_IS_EMPTY)
{
nearfree((ulg near *)crc_table);
MARK_CRCTAB_EMPTY;
}
}
#endif
#ifndef USE_ZLIB
#ifndef CRC_TABLE_ONLY
#ifndef ASM_CRC
#define DO1(crc, buf) crc = CRC32(crc, *buf++, crc_32_tab)
#define DO2(crc, buf) DO1(crc, buf); DO1(crc, buf)
#define DO4(crc, buf) DO2(crc, buf); DO2(crc, buf)
#define DO8(crc, buf) DO4(crc, buf); DO4(crc, buf)
#if (defined(IZ_CRC_BE_OPTIMIZ) || defined(IZ_CRC_LE_OPTIMIZ))
# ifdef IZ_CRCOPTIM_UNFOLDTBL
# ifdef IZ_CRC_BE_OPTIMIZ
# define DO_OPT4(c, buf4) c ^= *(buf4)++; \
c = crc_32_tab[c & 0xff] ^ crc_32_tab[256+((c>>8) & 0xff)] ^ \
crc_32_tab[2*256+((c>>16) & 0xff)] ^ crc_32_tab[3*256+(c>>24)]
# else /* !IZ_CRC_BE_OPTIMIZ */
# define DO_OPT4(c, buf4) c ^= *(buf4)++; \
c = crc_32_tab[3*256+(c & 0xff)] ^ crc_32_tab[2*256+((c>>8) & 0xff)] \
^ crc_32_tab[256+((c>>16) & 0xff)] ^ crc_32_tab[c>>24]
# endif /* ?IZ_CRC_BE_OPTIMIZ */
# else /* !IZ_CRCOPTIM_UNFOLDTBL */
# define DO_OPT4(c, buf4) c ^= *(buf4)++; \
c = CRC32UPD(c, crc_32_tab); \
c = CRC32UPD(c, crc_32_tab); \
c = CRC32UPD(c, crc_32_tab); \
c = CRC32UPD(c, crc_32_tab)
# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */
# define DO_OPT16(crc, buf4) DO_OPT4(crc, buf4); DO_OPT4(crc, buf4); \
DO_OPT4(crc, buf4); DO_OPT4(crc, buf4);
#endif /* (IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */
/* ========================================================================= */
ulg crc32(crc, buf, len)
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. */
{
return crc32_z(crc,buf,len);
register z_uint4 c;
register ZCONST ulg near *crc_32_tab;
if (buf == NULL) return 0L;
crc_32_tab = get_crc_table();
c = (REV_BE((z_uint4)crc) ^ 0xffffffffL);
#if (defined(IZ_CRC_BE_OPTIMIZ) || defined(IZ_CRC_LE_OPTIMIZ))
/* Align buf pointer to next DWORD boundary. */
while (len && ((ptrdiff_t)buf & 3)) {
DO1(c, buf);
len--;
}
{
ZCONST z_uint4 *buf4 = (ZCONST z_uint4 *)buf;
while (len >= 16) {
DO_OPT16(c, buf4);
len -= 16;
}
while (len >= 4) {
DO_OPT4(c, buf4);
len -= 4;
}
buf = (ZCONST uch *)buf4;
}
#else /* !(IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */
#ifndef NO_UNROLLED_LOOPS
while (len >= 8) {
DO8(c, buf);
len -= 8;
}
#endif /* !NO_UNROLLED_LOOPS */
#endif /* ?(IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */
if (len) do {
DO1(c, buf);
} while (--len);
return REV_BE(c) ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
}
#endif /* !ASM_CRC */
#endif /* !CRC_TABLE_ONLY */
#endif /* !USE_ZLIB */
#endif /* !USE_ZLIB || USE_OWN_CRCTAB */

45
third_party/zip/crc32.h vendored Normal file
View file

@ -0,0 +1,45 @@
#ifndef __crc32_h
#define __crc32_h
#include "third_party/zip/zip.h"
/* clang-format off */
#ifndef OF
# define OF(a) a
#endif
#ifndef ZCONST
# define ZCONST const
#endif
#ifdef DYNALLOC_CRCTAB
void free_crc_table OF((void));
#endif
#ifndef USE_ZLIB
ZCONST ulg near *get_crc_table OF((void));
#endif
#if (defined(USE_ZLIB) || defined(CRC_TABLE_ONLY))
# ifdef IZ_CRC_BE_OPTIMIZ
# undef IZ_CRC_BE_OPTIMIZ
# endif
#else /* !(USE_ZLIB || CRC_TABLE_ONLY) */
ulg crc32 OF((ulg crc, ZCONST uch *buf, extent len));
#endif /* ?(USE_ZLIB || CRC_TABLE_ONLY) */
#ifndef CRC_32_TAB
# define CRC_32_TAB crc_32_tab
#endif
#ifdef CRC32
# undef CRC32
#endif
#ifdef IZ_CRC_BE_OPTIMIZ
# define CRC32UPD(c, crctab) (crctab[((c) >> 24)] ^ ((c) << 8))
# define CRC32(c, b, crctab) (crctab[(((int)(c) >> 24) ^ (b))] ^ ((c) << 8))
# define REV_BE(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
#else
# define CRC32UPD(c, crctab) (crctab[((int)(c)) & 0xff] ^ ((c) >> 8))
# define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
# define REV_BE(w) w
#endif
#endif /* !__crc32_h */

692
third_party/zip/crypt.c vendored Normal file
View file

@ -0,0 +1,692 @@
/* clang-format off */
/*
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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]
The main encryption/decryption source code for Info-Zip software was
originally written in Europe. To the best of our knowledge, it can
be freely distributed in both source and object forms from any country,
including the USA under License Exception TSU of the U.S. Export
Administration Regulations (section 740.13(e)) of 6 June 2002.
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 "third_party/zip/zip.h"
#include "third_party/zip/crypt.h"
#include "third_party/zip/ttyio.h"
#include "libc/rand/rand.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 "libc/time/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
#else /* def UNZIP */ /* moved to globals.h for UnZip */
local z_uint4 keys[3]; /* keys defining the pseudo-random sequence */
#endif /* def UNZIP [else] */
#ifndef Trace
# ifdef CRYPT_DEBUG
# define Trace(x) fprintf x
# else
# define Trace(x)
# endif
#endif
#include "third_party/zip/crc32.h"
#ifdef IZ_CRC_BE_OPTIMIZ
local z_uint4 near crycrctab[256];
local z_uint4 near *cry_crctb_p = NULL;
local z_uint4 near *crytab_init OF((__GPRO));
# define CRY_CRC_TAB cry_crctb_p
# undef CRC32
# define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
#else
# define CRY_CRC_TAB CRC_32_TAB
#endif /* ?IZ_CRC_BE_OPTIMIZ */
/***********************************************************************
* 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, CRY_CRC_TAB);
GLOBAL(keys[1]) = (GLOBAL(keys[1])
+ (GLOBAL(keys[0]) & 0xff))
* 134775813L + 1;
{
register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB);
}
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 */
{
#ifdef IZ_CRC_BE_OPTIMIZ
if (cry_crctb_p == NULL) {
cry_crctb_p = crytab_init(__G);
}
#endif
GLOBAL(keys[0]) = 305419896L;
GLOBAL(keys[1]) = 591751049L;
GLOBAL(keys[2]) = 878082192L;
while (*passwd != '\0') {
update_keys(__G__ (int)*passwd);
passwd++;
}
}
/***********************************************************************
* Initialize the local copy of the table of precomputed crc32 values.
* Whereas the public crc32-table is optimized for crc32 calculations
* on arrays of bytes, the crypt code needs the crc32 values in an
* byte-order-independent form as 32-bit unsigned numbers. On systems
* with Big-Endian byte order using the optimized crc32 code, this
* requires inverting the byte-order of the values in the
* crypt-crc32-table.
*/
#ifdef IZ_CRC_BE_OPTIMIZ
local z_uint4 near *crytab_init(__G)
__GDEF
{
int i;
for (i = 0; i < 256; i++) {
crycrctab[i] = REV_BE(CRC_32_TAB[i]);
}
return crycrctab;
}
#endif
#ifdef ZIP
/***********************************************************************
* Write encryption header to file zfile using the password passwd
* and the cyclic redundancy check crc.
*/
void crypthead(passwd, crc)
ZCONST char *passwd; /* password string */
ulg crc; /* crc of file being encrypted */
{
int n; /* index in random header */
int t; /* temporary */
int c; /* random byte */
uch header[RAND_HEAD_LEN]; /* 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++) {
header[n] = (uch)zencode(header[n], t);
}
header[RAND_HEAD_LEN-2] = (uch)zencode((int)(crc >> 16) & 0xff, t);
header[RAND_HEAD_LEN-1] = (uch)zencode((int)(crc >> 24) & 0xff, t);
bfwrite(header, 1, RAND_HEAD_LEN, BFWRITE_DATA);
}
#ifdef UTIL
/***********************************************************************
* Encrypt the zip entry described by z from file in_file to file y
* using the password passwd. Return an error code in the ZE_ class.
*/
int zipcloak(z, passwd)
struct zlist far *z; /* zip entry to encrypt */
ZCONST char *passwd; /* password string */
{
int c; /* input byte */
int res; /* result code */
zoff_t n; /* holds offset and counts size */
int t; /* temporary */
struct zlist far *localz; /* local header */
uch buf[1024]; /* write buffer */
int b; /* bytes in buffer */
/* Set encrypted bit, clear extended local header bit and write local
header to output file */
if ((n = (zoff_t)zftello(y)) == (zoff_t)-1L) return ZE_TEMP;
/* assume this archive is one disk and the file is open */
/* read the local header */
res = readlocal(&localz, z);
/* update disk and offset */
z->dsk = 0;
z->off = n;
/* Set encryption and unset any extended local header */
z->flg |= 1, z->flg &= ~8;
localz->lflg |= 1, localz->lflg &= ~8;
/* Add size of encryption header */
localz->siz += RAND_HEAD_LEN;
z->siz = localz->siz;
/* Put the local header */
if ((res = putlocal(localz, PUTLOCAL_WRITE)) != ZE_OK) return res;
/* Initialize keys with password and write random header */
crypthead(passwd, localz->crc);
/* Encrypt data */
b = 0;
for (n = z->siz - RAND_HEAD_LEN; n; n--) {
if ((c = getc(in_file)) == EOF) {
return ferror(in_file) ? ZE_READ : ZE_EOF;
}
buf[b] = (uch)zencode(c, t);
b++;
if (b >= 1024) {
/* write the buffer */
bfwrite(buf, 1, b, BFWRITE_DATA);
b = 0;
}
}
if (b) {
/* write the buffer */
bfwrite(buf, 1, b, BFWRITE_DATA);
b = 0;
}
/* Since we seek to the start of each local header can skip
reading any extended local header */
/*
if ((flag & 8) != 0 && zfseeko(in_file, 16L, SEEK_CUR)) {
return ferror(in_file) ? ZE_READ : ZE_EOF;
}
if (fflush(y) == EOF) return ZE_TEMP;
*/
/* Update number of bytes written to output file */
tempzn += (4 + LOCHEAD) + localz->nam + localz->ext + localz->siz;
/* Free local header */
if (localz->ext) free(localz->extra);
if (localz->nam) free(localz->iname);
if (localz->nam) free(localz->name);
#ifdef UNICODE_SUPPORT
if (localz->uname) free(localz->uname);
#endif
free(localz);
return ZE_OK;
}
/***********************************************************************
* Decrypt the zip entry described by z from file in_file to file y
* using the password passwd. Return an error code in the ZE_ class.
*/
int zipbare(z, passwd)
struct zlist far *z; /* zip entry to encrypt */
ZCONST char *passwd; /* password string */
{
#ifdef ZIP10
int c0 /* byte preceding the last input byte */
#endif
int c1; /* last input byte */
/* all file offset and size now zoff_t - 8/28/04 EG */
zoff_t size; /* size of input data */
struct zlist far *localz; /* local header */
uch buf[1024]; /* write buffer */
int b; /* bytes in buffer */
zoff_t n;
int r; /* size of encryption header */
int res; /* return code */
/* Save position */
if ((n = (zoff_t)zftello(y)) == (zoff_t)-1L) return ZE_TEMP;
/* Read local header */
res = readlocal(&localz, z);
/* Update disk and offset */
z->dsk = 0;
z->off = n;
/* Initialize keys with password */
init_keys(passwd);
/* Decrypt encryption header, save last two bytes */
c1 = 0;
for (r = RAND_HEAD_LEN; r; r--) {
#ifdef ZIP10
c0 = c1;
#endif
if ((c1 = getc(in_file)) == EOF) {
return ferror(in_file) ? 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
if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
#endif
if (zfseeko(in_file, n, SEEK_SET)) {
return ferror(in_file) ? ZE_READ : ZE_EOF;
}
if ((res = zipcopy(z)) != ZE_OK) {
ziperr(res, "was copying an entry");
}
return ZE_MISS;
}
z->siz -= RAND_HEAD_LEN;
localz->siz = z->siz;
localz->flg = z->flg &= ~9;
z->lflg = localz->lflg &= ~9;
if ((res = putlocal(localz, PUTLOCAL_WRITE)) != ZE_OK) return res;
/* Decrypt data */
b = 0;
for (size = z->siz; size; size--) {
if ((c1 = getc(in_file)) == EOF) {
return ferror(in_file) ? ZE_READ : ZE_EOF;
}
zdecode(c1);
buf[b] = c1;
b++;
if (b >= 1024) {
/* write the buffer */
bfwrite(buf, 1, b, BFWRITE_DATA);
b = 0;
}
}
if (b) {
/* write the buffer */
bfwrite(buf, 1, b, BFWRITE_DATA);
b = 0;
}
/* Since we seek to the start of each local header can skip
reading any extended local header */
/* Update number of bytes written to output file */
tempzn += (4 + LOCHEAD) + localz->nam + localz->ext + localz->siz;
/* Free local header */
if (localz->ext) free(localz->extra);
if (localz->nam) free(localz->iname);
if (localz->nam) free(localz->name);
#ifdef UNICODE_SUPPORT
if (localz->uname) free(localz->uname);
#endif
free(localz);
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.
*
* now write to global y
*
* A bug has been found when encrypting large files that don't
* compress. See trees.c for the details and the fix.
*/
unsigned zfwrite(buf, item_size, nb)
zvoid *buf; /* data buffer */
extent item_size; /* size of each item in bytes */
extent nb; /* number of items */
#if 0
FILE *f; /* file to write to */
#endif
{
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 bfwrite(buf, item_size, nb, BFWRITE_DATA);
}
#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]));
}
/* use fzofft to format zoff_t as strings - 10/19/04 from SMS */
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 = %s\n",
GLOBAL(incnt),
fzofft(GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf)),
NULL, NULL)));
/* 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 = (zoff_t)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 */

145
third_party/zip/crypt.h vendored Normal file
View file

@ -0,0 +1,145 @@
#ifndef __crypt_h /* don't include more than once */
#define __crypt_h
/* clang-format off */
#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 91
#ifdef CR_BETA
# define CR_BETA_VER "c BETA"
# define CR_VERSION_DATE "05 Jan 2007" /* last real code change */
#else
# define CR_BETA_VER ""
# define CR_VERSION_DATE "05 Jan 2007" /* 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 */
/* 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 (__GPRO);
int update_keys (__GPRO__ int c);
void init_keys (__GPRO__ ZCONST char *passwd);
#ifdef ZIP
void crypthead (ZCONST char *, ulg);
# ifdef UTIL
int zipcloak (struct zlist far *, ZCONST char *);
int zipbare (struct zlist far *, ZCONST char *);
# else
unsigned zfwrite (zvoid *, extent, extent);
# endif
#endif /* ZIP */
#if (defined(UNZIP) && !defined(FUNZIP))
int decrypt (__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(b,s,c) bfwrite(b,s,c,BFWRITE_DATA)
#endif /* ?CRYPT */
#endif /* !__crypt_h */

930
third_party/zip/deflate.c vendored Normal file
View file

@ -0,0 +1,930 @@
/* clang-format off */
/*
deflate.c - Zip 3
Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2005-Feb-10 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
*/
/*
* deflate.c by Jean-loup Gailly.
*
* PURPOSE
*
* Identify new text as repetitions of old text within a fixed-
* length sliding window trailing behind the new text.
*
* DISCUSSION
*
* The "deflation" process depends on being able to identify portions
* of the input text which are identical to earlier input (within a
* sliding window trailing behind the input currently being processed).
*
* The most straightforward technique turns out to be the fastest for
* most input files: try all possible matches and select the longest.
* The key feature of this algorithm is that insertions into the string
* dictionary are very simple and thus fast, and deletions are avoided
* completely. Insertions are performed at each input character, whereas
* string matches are performed only when the previous match ends. So it
* is preferable to spend more time in matches to allow very fast string
* insertions and avoid deletions. The matching algorithm for small
* strings is inspired from that of Rabin & Karp. A brute force approach
* is used to find longer strings when a small match has been found.
* A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
* (by Leonid Broukhis).
* A previous version of this file used a more sophisticated algorithm
* (by Fiala and Greene) which is guaranteed to run in linear amortized
* time, but has a larger average cost, uses more memory and is patented.
* However the F&G algorithm may be faster for some highly redundant
* files if the parameter max_chain_length (described below) is too large.
*
* ACKNOWLEDGEMENTS
*
* The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
* I found it in 'freeze' written by Leonid Broukhis.
* Thanks to many info-zippers for bug reports and testing.
*
* REFERENCES
*
* APPNOTE.TXT documentation file in PKZIP 1.93a distribution.
*
* A description of the Rabin and Karp algorithm is given in the book
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
*
* Fiala,E.R., and Greene,D.H.
* Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
*
* INTERFACE
*
* void lm_init (int pack_level, ush *flags)
* Initialize the "longest match" routines for a new file
*
* ulg deflate (void)
* Processes a new input file and return its compressed length. Sets
* the compressed length, crc, deflate flags and internal file
* attributes.
*/
#define __DEFLATE_C
#include "third_party/zip/zip.h"
#ifndef USE_ZLIB
/* ===========================================================================
* Configuration parameters
*/
/* Compile with MEDIUM_MEM to reduce the memory requirements or
* with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the
* entire input file can be held in memory (not possible on 16 bit systems).
* Warning: defining these symbols affects HASH_BITS (see below) and thus
* affects the compression ratio. The compressed output
* is still correct, and might even be smaller in some cases.
*/
#ifdef SMALL_MEM
# define HASH_BITS 13 /* Number of bits used to hash strings */
#endif
#ifdef MEDIUM_MEM
# define HASH_BITS 14
#endif
#ifndef HASH_BITS
# define HASH_BITS 15
/* For portability to 16 bit machines, do not use values above 15. */
#endif
#define HASH_SIZE (unsigned)(1<<HASH_BITS)
#define HASH_MASK (HASH_SIZE-1)
#define WMASK (WSIZE-1)
/* HASH_SIZE and WSIZE must be powers of two */
#define NIL 0
/* Tail of hash chains */
#define FAST 4
#define SLOW 2
/* speed options for the general purpose bit flag */
#ifndef TOO_FAR
# define TOO_FAR 4096
#endif
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
#if (defined(ASMV) && !defined(MSDOS16) && defined(DYN_ALLOC))
error: DYN_ALLOC not yet supported in match.S or match32.asm
#endif
#ifdef MEMORY16
# define MAXSEG_64K
#endif
/* ===========================================================================
* Local data used by the "longest match" routines.
*/
#if defined(MMAP) || defined(BIG_MEM)
typedef unsigned Pos; /* must be at least 32 bits */
#else
typedef ush Pos;
#endif
typedef unsigned IPos;
/* A Pos is an index in the character window. We use short instead of int to
* save space in the various tables. IPos is used only for parameter passing.
*/
#ifndef DYN_ALLOC
uch window[2L*WSIZE];
/* Sliding window. Input bytes are read into the second half of the window,
* and move to the first half later to keep a dictionary of at least WSIZE
* bytes. With this organization, matches are limited to a distance of
* WSIZE-MAX_MATCH bytes, but this ensures that IO is always
* performed with a length multiple of the block size. Also, it limits
* the window size to 64K, which is quite useful on MSDOS.
* To do: limit the window size to WSIZE+CBSZ if SMALL_MEM (the code would
* be less efficient since the data would have to be copied WSIZE/CBSZ times)
*/
Pos prev[WSIZE];
/* Link to older string with same hash index. To limit the size of this
* array to 64K, this link is maintained only for the last 32K strings.
* An index in this array is thus a window index modulo 32K.
*/
Pos head[HASH_SIZE];
/* Heads of the hash chains or NIL. If your compiler thinks that
* HASH_SIZE is a dynamic value, recompile with -DDYN_ALLOC.
*/
#else
uch far * near window = NULL;
Pos far * near prev = NULL;
Pos far * near head;
#endif
ulg window_size;
/* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
* input file length plus MIN_LOOKAHEAD.
*/
long block_start;
/* window position at the beginning of the current output block. Gets
* negative when the window is moved backwards.
*/
local int sliding;
/* Set to false when the input file is already in memory */
local unsigned ins_h; /* hash index of string to be inserted */
#define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
/* Number of bits by which ins_h and del_h must be shifted at each
* input step. It must be such that after MIN_MATCH steps, the oldest
* byte no longer takes part in the hash key, that is:
* H_SHIFT * MIN_MATCH >= HASH_BITS
*/
unsigned int near prev_length;
/* Length of the best match at previous step. Matches not greater than this
* are discarded. This is used in the lazy match evaluation.
*/
unsigned near strstart; /* start of string to insert */
unsigned near match_start; /* start of matching string */
local int eofile; /* flag set at end of input file */
local unsigned lookahead; /* number of valid bytes ahead in window */
unsigned near max_chain_length;
/* To speed up deflation, hash chains are never searched beyond this length.
* A higher limit improves compression ratio but degrades the speed.
*/
local unsigned int max_lazy_match;
/* Attempt to find a better match only when the current match is strictly
* smaller than this value. This mechanism is used only for compression
* levels >= 4.
*/
#define max_insert_length max_lazy_match
/* Insert new strings in the hash table only if the match length
* is not greater than this length. This saves time but degrades compression.
* max_insert_length is used only for compression levels <= 3.
*/
unsigned near good_match;
/* Use a faster search when the previous match is longer than this */
#ifdef FULL_SEARCH
# define nice_match MAX_MATCH
#else
int near nice_match; /* Stop searching when current match exceeds this */
#endif
/* Values for max_lazy_match, good_match, nice_match and max_chain_length,
* depending on the desired pack level (0..9). The values given below have
* been tuned to exclude worst case performance for pathological files.
* Better values may be found for specific files.
*/
typedef struct config {
ush good_length; /* reduce lazy search above this match length */
ush max_lazy; /* do not perform lazy search above this match length */
ush nice_length; /* quit search above this match length */
ush max_chain;
} config;
local config configuration_table[10] = {
/* good lazy nice chain */
/* 0 */ {0, 0, 0, 0}, /* store only */
/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */
/* 2 */ {4, 5, 16, 8},
/* 3 */ {4, 6, 32, 32},
/* 4 */ {4, 4, 16, 16}, /* lazy matches */
/* 5 */ {8, 16, 32, 32},
/* 6 */ {8, 16, 128, 128},
/* 7 */ {8, 32, 128, 256},
/* 8 */ {32, 128, 258, 1024},
/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
* For deflate_fast() (levels <= 3) good is ignored and lazy has a different
* meaning.
*/
#define EQUAL 0
/* result of memcmp for equal strings */
/* ===========================================================================
* Prototypes for local functions.
*/
local void fill_window OF((void));
local uzoff_t deflate_fast OF((void)); /* now use uzoff_t 7/24/04 EG */
int longest_match OF((IPos cur_match));
#if defined(ASMV) && !defined(RISCOS)
void match_init OF((void)); /* asm code initialization */
#endif
#ifdef DEBUG
local void check_match OF((IPos start, IPos match, int length));
#endif
/* ===========================================================================
* Update a hash value with the given input byte
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
* input characters, so that a running hash key can be computed from the
* previous key instead of complete recalculation each time.
*/
#define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
/* ===========================================================================
* Insert string s in the dictionary and set match_head to the previous head
* of the hash chain (the most recent string with same hash key). Return
* the previous length of the hash chain.
* IN assertion: all calls to to INSERT_STRING are made with consecutive
* input characters and the first MIN_MATCH bytes of s are valid
* (except for the last MIN_MATCH-1 bytes of the input file).
*/
#define INSERT_STRING(s, match_head) \
(UPDATE_HASH(ins_h, window[(s) + (MIN_MATCH-1)]), \
prev[(s) & WMASK] = match_head = head[ins_h], \
head[ins_h] = (s))
/* ===========================================================================
* Initialize the "longest match" routines for a new file
*
* IN assertion: window_size is > 0 if the input file is already read or
* mmap'ed in the window[] array, 0 otherwise. In the first case,
* window_size is sufficient to contain the whole input file plus
* MIN_LOOKAHEAD bytes (to avoid referencing memory beyond the end
* of window[] when looking for matches towards the end).
*/
void lm_init (pack_level, flags)
int pack_level; /* 0: store, 1: best speed, 9: best compression */
ush *flags; /* general purpose bit flag */
{
register unsigned j;
if (pack_level < 1 || pack_level > 9) error("bad pack level");
/* Do not slide the window if the whole input is already in memory
* (window_size > 0)
*/
sliding = 0;
if (window_size == 0L) {
sliding = 1;
window_size = (ulg)2L*WSIZE;
}
/* Use dynamic allocation if compiler does not like big static arrays: */
#ifdef DYN_ALLOC
if (window == NULL) {
window = (uch far *) zcalloc(WSIZE, 2*sizeof(uch));
if (window == NULL) ziperr(ZE_MEM, "window allocation");
}
if (prev == NULL) {
prev = (Pos far *) zcalloc(WSIZE, sizeof(Pos));
head = (Pos far *) zcalloc(HASH_SIZE, sizeof(Pos));
if (prev == NULL || head == NULL) {
ziperr(ZE_MEM, "hash table allocation");
}
}
#endif /* DYN_ALLOC */
/* Initialize the hash table (avoiding 64K overflow for 16 bit systems).
* prev[] will be initialized on the fly.
*/
head[HASH_SIZE-1] = NIL;
memset((char*)head, NIL, (unsigned)(HASH_SIZE-1)*sizeof(*head));
/* Set the default configuration parameters:
*/
max_lazy_match = configuration_table[pack_level].max_lazy;
good_match = configuration_table[pack_level].good_length;
#ifndef FULL_SEARCH
nice_match = configuration_table[pack_level].nice_length;
#endif
max_chain_length = configuration_table[pack_level].max_chain;
if (pack_level <= 2) {
*flags |= FAST;
} else if (pack_level >= 8) {
*flags |= SLOW;
}
/* ??? reduce max_chain_length for binary files */
strstart = 0;
block_start = 0L;
#if defined(ASMV) && !defined(RISCOS)
match_init(); /* initialize the asm code */
#endif
j = WSIZE;
#ifndef MAXSEG_64K
if (sizeof(int) > 2) j <<= 1; /* Can read 64K in one step */
#endif
lookahead = (*read_buf)((char*)window, j);
if (lookahead == 0 || lookahead == (unsigned)EOF) {
eofile = 1, lookahead = 0;
return;
}
eofile = 0;
/* Make sure that we always have enough lookahead. This is important
* if input comes from a device such as a tty.
*/
if (lookahead < MIN_LOOKAHEAD) fill_window();
ins_h = 0;
for (j=0; j<MIN_MATCH-1; j++) UPDATE_HASH(ins_h, window[j]);
/* If lookahead < MIN_MATCH, ins_h is garbage, but this is
* not important since only literal bytes will be emitted.
*/
}
/* ===========================================================================
* Free the window and hash table
*/
void lm_free()
{
#ifdef DYN_ALLOC
if (window != NULL) {
zcfree(window);
window = NULL;
}
if (prev != NULL) {
zcfree(prev);
zcfree(head);
prev = head = NULL;
}
#endif /* DYN_ALLOC */
}
/* ===========================================================================
* Set match_start to the longest match starting at the given string and
* return its length. Matches shorter or equal to prev_length are discarded,
* in which case the result is equal to prev_length and match_start is
* garbage.
* IN assertions: cur_match is the head of the hash chain for the current
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
*/
#ifndef ASMV
/* For 80x86 and 680x0 and ARM, an optimized version is in match.asm or
* match.S. The code is functionally equivalent, so you can use the C version
* if desired.
*/
int longest_match(cur_match)
IPos cur_match; /* current match */
{
unsigned chain_length = max_chain_length; /* max hash chain length */
register uch far *scan = window + strstart; /* current string */
register uch far *match; /* matched string */
register int len; /* length of current match */
int best_len = prev_length; /* best match length so far */
IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL;
/* Stop when cur_match becomes <= limit. To simplify the code,
* we prevent matches with the string of window index 0.
*/
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
* It is easy to get rid of this optimization if necessary.
*/
#if HASH_BITS < 8 || MAX_MATCH != 258
error: Code too clever
#endif
#ifdef UNALIGNED_OK
/* Compare two bytes at a time. Note: this is not always beneficial.
* Try with and without -DUNALIGNED_OK to check.
*/
register uch far *strend = window + strstart + MAX_MATCH - 1;
register ush scan_start = *(ush far *)scan;
register ush scan_end = *(ush far *)(scan+best_len-1);
#else
register uch far *strend = window + strstart + MAX_MATCH;
register uch scan_end1 = scan[best_len-1];
register uch scan_end = scan[best_len];
#endif
/* Do not waste too much time if we already have a good match: */
if (prev_length >= good_match) {
chain_length >>= 2;
}
Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead");
do {
Assert(cur_match < strstart, "no future");
match = window + cur_match;
/* Skip to next match if the match length cannot increase
* or if the match length is less than 2:
*/
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use
* UNALIGNED_OK if your compiler uses a different size.
*/
if (*(ush far *)(match+best_len-1) != scan_end ||
*(ush far *)match != scan_start) continue;
/* It is not necessary to compare scan[2] and match[2] since they are
* always equal when the other bytes match, given that the hash keys
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
* strstart+3, +5, ... up to strstart+257. We check for insufficient
* lookahead only every 4th comparison; the 128th check will be made
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
* necessary to put more guard bytes at the end of the window, or
* to check more often for insufficient lookahead.
*/
scan++, match++;
do {
} while (*(ush far *)(scan+=2) == *(ush far *)(match+=2) &&
*(ush far *)(scan+=2) == *(ush far *)(match+=2) &&
*(ush far *)(scan+=2) == *(ush far *)(match+=2) &&
*(ush far *)(scan+=2) == *(ush far *)(match+=2) &&
scan < strend);
/* The funny "do {}" generates better code on most compilers */
/* Here, scan <= window+strstart+257 */
Assert(scan <= window+(unsigned)(window_size-1), "wild scan");
if (*scan == *match) scan++;
len = (MAX_MATCH - 1) - (int)(strend-scan);
scan = strend - (MAX_MATCH-1);
#else /* UNALIGNED_OK */
if (match[best_len] != scan_end ||
match[best_len-1] != scan_end1 ||
*match != *scan ||
*++match != scan[1]) continue;
/* The check at best_len-1 can be removed because it will be made
* again later. (This heuristic is not always a win.)
* It is not necessary to compare scan[2] and match[2] since they
* are always equal when the other bytes match, given that
* the hash keys are equal and that HASH_BITS >= 8.
*/
scan += 2, match++;
/* We check for insufficient lookahead only every 8th comparison;
* the 256th check will be made at strstart+258.
*/
do {
} while (*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
scan < strend);
Assert(scan <= window+(unsigned)(window_size-1), "wild scan");
len = MAX_MATCH - (int)(strend - scan);
scan = strend - MAX_MATCH;
#endif /* UNALIGNED_OK */
if (len > best_len) {
match_start = cur_match;
best_len = len;
if (len >= nice_match) break;
#ifdef UNALIGNED_OK
scan_end = *(ush far *)(scan+best_len-1);
#else
scan_end1 = scan[best_len-1];
scan_end = scan[best_len];
#endif
}
} while ((cur_match = prev[cur_match & WMASK]) > limit
&& --chain_length != 0);
return best_len;
}
#endif /* ASMV */
#ifdef DEBUG
/* ===========================================================================
* Check that the match at match_start is indeed a match.
*/
local void check_match(start, match, length)
IPos start, match;
int length;
{
/* check that the match is indeed a match */
if (memcmp((char*)window + match,
(char*)window + start, length) != EQUAL) {
fprintf(mesg,
" start %d, match %d, length %d\n",
start, match, length);
error("invalid match");
}
if (verbose > 1) {
fprintf(mesg,"\\[%d,%d]", start-match, length);
#ifndef WINDLL
do { putc(window[start++], mesg); } while (--length != 0);
#else
do { fprintf(stdout,"%c",window[start++]); } while (--length != 0);
#endif
}
}
#else
# define check_match(start, match, length)
#endif
/* ===========================================================================
* Flush the current block, with given end-of-file flag.
* IN assertion: strstart is set to the end of the current match.
*/
#define FLUSH_BLOCK(eof) \
flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \
(char*)NULL, (ulg)strstart - (ulg)block_start, (eof))
/* ===========================================================================
* Fill the window when the lookahead becomes insufficient.
* Updates strstart and lookahead, and sets eofile if end of input file.
*
* IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
* OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
* At least one byte has been read, or eofile is set; file reads are
* performed for at least two bytes (required for the translate_eol option).
*/
local void fill_window()
{
register unsigned n, m;
unsigned more; /* Amount of free space at the end of the window. */
do {
more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart);
/* If the window is almost full and there is insufficient lookahead,
* move the upper half to the lower one to make room in the upper half.
*/
if (more == (unsigned)EOF) {
/* Very unlikely, but possible on 16 bit machine if strstart == 0
* and lookahead == 1 (input done one byte at time)
*/
more--;
/* For MMAP or BIG_MEM, the whole input file is already in memory so
* we must not perform sliding. We must however call (*read_buf)() in
* order to compute the crc, update lookahead and possibly set eofile.
*/
} else if (strstart >= WSIZE+MAX_DIST && sliding) {
#ifdef FORCE_METHOD
/* When methods "stored" or "store_block" are requested, the
* current block must be flushed before sliding the window.
*/
if (level <= 2) FLUSH_BLOCK(0), block_start = strstart;
#endif
/* By the IN assertion, the window is not empty so we can't confuse
* more == 0 with more == 64K on a 16 bit machine.
*/
memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE);
match_start -= WSIZE;
strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */
block_start -= (long) WSIZE;
for (n = 0; n < HASH_SIZE; n++) {
m = head[n];
head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL);
}
for (n = 0; n < WSIZE; n++) {
m = prev[n];
prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL);
/* If n is not on any hash chain, prev[n] is garbage but
* its value will never be used.
*/
}
more += WSIZE;
if (dot_size > 0 && !display_globaldots) {
/* initial space */
if (noisy && dot_count == -1) {
#ifndef WINDLL
putc(' ', mesg);
fflush(mesg);
#else
fprintf(stdout,"%c",' ');
#endif
dot_count++;
}
dot_count++;
if (dot_size <= (dot_count + 1) * WSIZE) dot_count = 0;
}
if ((verbose || noisy) && dot_size && !dot_count) {
#ifndef WINDLL
putc('.', mesg);
fflush(mesg);
#else
fprintf(stdout,"%c",'.');
#endif
mesg_line_started = 1;
}
}
if (eofile) return;
/* If there was no sliding:
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
* more == window_size - lookahead - strstart
* => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
* => more >= window_size - 2*WSIZE + 2
* In the MMAP or BIG_MEM case (not yet supported in gzip),
* window_size == input_size + MIN_LOOKAHEAD &&
* strstart + lookahead <= input_size => more >= MIN_LOOKAHEAD.
* Otherwise, window_size == 2*WSIZE so more >= 2.
* If there was sliding, more >= WSIZE. So in all cases, more >= 2.
*/
Assert(more >= 2, "more < 2");
n = (*read_buf)((char*)window+strstart+lookahead, more);
if (n == 0 || n == (unsigned)EOF) {
eofile = 1;
} else {
lookahead += n;
}
} while (lookahead < MIN_LOOKAHEAD && !eofile);
}
/* ===========================================================================
* Processes a new input file and return its compressed length. This
* function does not perform lazy evaluation of matches and inserts
* new strings in the dictionary only for unmatched strings or for short
* matches. It is used only for the fast compression options.
*/
local uzoff_t deflate_fast()
{
IPos hash_head = NIL; /* head of the hash chain */
int flush; /* set if current block must be flushed */
unsigned match_length = 0; /* length of best match */
prev_length = MIN_MATCH-1;
while (lookahead != 0) {
/* Insert the string window[strstart .. strstart+2] in the
* dictionary, and set hash_head to the head of the hash chain:
*/
#ifndef DEFL_UNDETERM
if (lookahead >= MIN_MATCH)
#endif
INSERT_STRING(strstart, hash_head);
/* Find the longest match, discarding those <= prev_length.
* At this point we have always match_length < MIN_MATCH
*/
if (hash_head != NIL && strstart - hash_head <= MAX_DIST) {
/* To simplify the code, we prevent matches with the string
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
#ifndef HUFFMAN_ONLY
# ifndef DEFL_UNDETERM
/* Do not look for matches beyond the end of the input.
* This is necessary to make deflate deterministic.
*/
if ((unsigned)nice_match > lookahead) nice_match = (int)lookahead;
# endif
match_length = longest_match (hash_head);
/* longest_match() sets match_start */
if (match_length > lookahead) match_length = lookahead;
#endif
}
if (match_length >= MIN_MATCH) {
check_match(strstart, match_start, match_length);
flush = ct_tally(strstart-match_start, match_length - MIN_MATCH);
lookahead -= match_length;
/* Insert new strings in the hash table only if the match length
* is not too large. This saves time but degrades compression.
*/
if (match_length <= max_insert_length
#ifndef DEFL_UNDETERM
&& lookahead >= MIN_MATCH
#endif
) {
match_length--; /* string at strstart already in hash table */
do {
strstart++;
INSERT_STRING(strstart, hash_head);
/* strstart never exceeds WSIZE-MAX_MATCH, so there are
* always MIN_MATCH bytes ahead.
*/
#ifdef DEFL_UNDETERM
/* If lookahead < MIN_MATCH these bytes are garbage,
* but it does not matter since the next lookahead bytes
* will be emitted as literals.
*/
#endif
} while (--match_length != 0);
strstart++;
} else {
strstart += match_length;
match_length = 0;
ins_h = window[strstart];
UPDATE_HASH(ins_h, window[strstart+1]);
#if MIN_MATCH != 3
Call UPDATE_HASH() MIN_MATCH-3 more times
#endif
}
} else {
/* No match, output a literal byte */
Tracevv((stderr,"%c",window[strstart]));
flush = ct_tally (0, window[strstart]);
lookahead--;
strstart++;
}
if (flush) FLUSH_BLOCK(0), block_start = strstart;
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
* for the next match, plus MIN_MATCH bytes to insert the
* string following the next match.
*/
if (lookahead < MIN_LOOKAHEAD) fill_window();
}
return FLUSH_BLOCK(1); /* eof */
}
/* ===========================================================================
* Same as above, but achieves better compression. We use a lazy
* evaluation for matches: a match is finally adopted only if there is
* no better match at the next window position.
*/
uzoff_t deflate()
{
IPos hash_head = NIL; /* head of hash chain */
IPos prev_match; /* previous match */
int flush; /* set if current block must be flushed */
int match_available = 0; /* set if previous match exists */
register unsigned match_length = MIN_MATCH-1; /* length of best match */
#ifdef DEBUG
extern uzoff_t isize; /* byte length of input file, for debug only */
#endif
if (level <= 3) return deflate_fast(); /* optimized for speed */
/* Process the input block. */
while (lookahead != 0) {
/* Insert the string window[strstart .. strstart+2] in the
* dictionary, and set hash_head to the head of the hash chain:
*/
#ifndef DEFL_UNDETERM
if (lookahead >= MIN_MATCH)
#endif
INSERT_STRING(strstart, hash_head);
/* Find the longest match, discarding those <= prev_length.
*/
prev_length = match_length, prev_match = match_start;
match_length = MIN_MATCH-1;
if (hash_head != NIL && prev_length < max_lazy_match &&
strstart - hash_head <= MAX_DIST) {
/* To simplify the code, we prevent matches with the string
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
#ifndef HUFFMAN_ONLY
# ifndef DEFL_UNDETERM
/* Do not look for matches beyond the end of the input.
* This is necessary to make deflate deterministic.
*/
if ((unsigned)nice_match > lookahead) nice_match = (int)lookahead;
# endif
match_length = longest_match (hash_head);
/* longest_match() sets match_start */
if (match_length > lookahead) match_length = lookahead;
#endif
#ifdef FILTERED
/* Ignore matches of length <= 5 */
if (match_length <= 5) {
#else
/* Ignore a length 3 match if it is too distant: */
if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){
#endif
/* If prev_match is also MIN_MATCH, match_start is garbage
* but we will ignore the current match anyway.
*/
match_length = MIN_MATCH-1;
}
}
/* If there was a match at the previous step and the current
* match is not better, output the previous match:
*/
if (prev_length >= MIN_MATCH && match_length <= prev_length) {
#ifndef DEFL_UNDETERM
unsigned max_insert = strstart + lookahead - MIN_MATCH;
#endif
check_match(strstart-1, prev_match, prev_length);
flush = ct_tally(strstart-1-prev_match, prev_length - MIN_MATCH);
/* Insert in hash table all strings up to the end of the match.
* strstart-1 and strstart are already inserted.
*/
lookahead -= prev_length-1;
prev_length -= 2;
#ifndef DEFL_UNDETERM
do {
if (++strstart <= max_insert) {
INSERT_STRING(strstart, hash_head);
/* strstart never exceeds WSIZE-MAX_MATCH, so there are
* always MIN_MATCH bytes ahead.
*/
}
} while (--prev_length != 0);
strstart++;
#else /* DEFL_UNDETERM */
do {
strstart++;
INSERT_STRING(strstart, hash_head);
/* strstart never exceeds WSIZE-MAX_MATCH, so there are
* always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
* these bytes are garbage, but it does not matter since the
* next lookahead bytes will always be emitted as literals.
*/
} while (--prev_length != 0);
strstart++;
#endif /* ?DEFL_UNDETERM */
match_available = 0;
match_length = MIN_MATCH-1;
if (flush) FLUSH_BLOCK(0), block_start = strstart;
} else if (match_available) {
/* If there was no match at the previous position, output a
* single literal. If there was a match but the current match
* is longer, truncate the previous match to a single literal.
*/
Tracevv((stderr,"%c",window[strstart-1]));
if (ct_tally (0, window[strstart-1])) {
FLUSH_BLOCK(0), block_start = strstart;
}
strstart++;
lookahead--;
} else {
/* There is no previous match to compare with, wait for
* the next step to decide.
*/
match_available = 1;
strstart++;
lookahead--;
}
Assert(strstart <= isize && lookahead <= isize, "a bit too far");
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
* for the next match, plus MIN_MATCH bytes to insert the
* string following the next match.
*/
if (lookahead < MIN_LOOKAHEAD) fill_window();
}
if (match_available) ct_tally (0, window[strstart-1]);
return FLUSH_BLOCK(1); /* eof */
}
#endif /* !USE_ZLIB */

4820
third_party/zip/fileio.c vendored Normal file

File diff suppressed because it is too large Load diff

254
third_party/zip/globals.c vendored Normal file
View file

@ -0,0 +1,254 @@
/* clang-format off */
/*
globals.c - Zip 3
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
/*
* globals.c by Mark Adler
*/
#define __GLOBALS_C
#define GLOBALS /* include definition of errors[] in zip.h */
#ifndef UTIL
#define UTIL /* do not declare the read_buf variable */
#endif
#include "third_party/zip/zip.h"
/* Handy place to build error messages */
char errbuf[FNMAX+4081];
/* Argument processing globals */
int recurse = 0; /* 1=recurse into directories encountered */
int dispose = 0; /* 1=remove files after put in zip file */
int pathput = 1; /* 1=store path with name */
#ifdef RISCOS
int scanimage = 1; /* 1=scan through image files */
#endif
int method = BEST; /* one of BEST, DEFLATE (only), or STORE (only) */
int dosify = 0; /* 1=make new entries look like MSDOS */
int verbose = 0; /* 1=report oddities in zip file structure */
int fix = 0; /* 1=fix the zip file, 2=FF, 3=ZipNote */
int filesync = 0; /* 1=file sync, delete entries not on file system */
int adjust = 0; /* 1=adjust offsets for sfx'd file (keep preamble) */
int level = 6; /* 0=fastest compression, 9=best compression */
int translate_eol = 0; /* Translate end-of-line LF -> CR LF */
#ifdef VMS
int vmsver = 0; /* 1=append VMS version number to file names */
int vms_native = 0; /* 1=store in VMS format */
int vms_case_2 = 0; /* ODS2 file name case in VMS. -1: down. */
int vms_case_5 = 0; /* ODS5 file name case in VMS. +1: preserve. */
#endif /* VMS */
#if defined(OS2) || defined(WIN32)
int use_longname_ea = 0; /* 1=use the .LONGNAME EA as the file's name */
#endif
/* 9/26/04 */
int no_wild = 0; /* 1 = wildcards are disabled */
int allow_regex = 0; /* 1 = allow [list] matching */
#ifdef WILD_STOP_AT_DIR
int wild_stop_at_dir = 1; /* default wildcards do not include / in matches */
#else
int wild_stop_at_dir = 0; /* default wildcards do include / in matches */
#endif
#ifdef UNICODE_SUPPORT
int using_utf8 = 0; /* 1 if current character set UTF-8 */
# ifdef WIN32
int no_win32_wide = -1; /* 1 = no wide functions, like GetFileAttributesW() */
# endif
#endif
ulg skip_this_disk = 0;
int des_good = 0; /* Good data descriptor found */
ulg des_crc = 0; /* Data descriptor CRC */
uzoff_t des_csize = 0; /* Data descriptor csize */
uzoff_t des_usize = 0; /* Data descriptor usize */
/* dots 10/20/04 */
zoff_t dot_size = 0; /* bytes processed in deflate per dot, 0 = no dots */
zoff_t dot_count = 0; /* buffers seen, recyles at dot_size */
/* status 10/30/04 */
int display_counts = 0; /* display running file count */
int display_bytes = 0; /* display running bytes remaining */
int display_globaldots = 0; /* display dots for archive instead of each file */
int display_volume = 0; /* display current input and output volume (disk) numbers */
int display_usize = 0; /* display uncompressed bytes */
ulg files_so_far = 0; /* files processed so far */
ulg bad_files_so_far = 0; /* bad files skipped so far */
ulg files_total = 0; /* files total to process */
uzoff_t bytes_so_far = 0; /* bytes processed so far (from initial scan) */
uzoff_t good_bytes_so_far = 0;/* good bytes read so far */
uzoff_t bad_bytes_so_far = 0; /* bad bytes skipped so far */
uzoff_t bytes_total = 0; /* total bytes to process (from initial scan) */
/* logfile 6/5/05 */
int logall = 0; /* 0 = warnings/errors, 1 = all */
FILE *logfile = NULL; /* pointer to open logfile or NULL */
int logfile_append = 0; /* append to existing logfile */
char *logfile_path = NULL; /* pointer to path of logfile */
int hidden_files = 0; /* process hidden and system files */
int volume_label = 0; /* add volume label */
int dirnames = 1; /* include directory entries by default */
int filter_match_case = 1; /* 1=match case when filter() */
int diff_mode = 0; /* 1=require --out and only store changed and add */
#if defined(WIN32)
int only_archive_set = 0; /* include only files with DOS archive bit set */
int clear_archive_bits = 0; /* clear DOS archive bit of included files */
#endif
int linkput = 0; /* 1=store symbolic links as such */
int noisy = 1; /* 0=quiet operation */
int extra_fields = 1; /* 0=create minimum, 1=don't copy old, 2=keep old */
int use_descriptors = 0; /* 1=use data descriptors 12/29/04 */
int zip_to_stdout = 0; /* output zipfile to stdout 12/30/04 */
int allow_empty_archive = 0; /* if no files, create empty archive anyway 12/28/05 */
int copy_only = 0; /* 1=copying archive entries only */
int allow_fifo = 0; /* 1=allow reading Unix FIFOs, waiting if pipe open */
int show_files = 0; /* show files to operate on and exit (=2 log only) */
int output_seekable = 1; /* 1 = output seekable 3/13/05 EG */
#ifdef ZIP64_SUPPORT /* zip64 support 10/4/03 */
int force_zip64 = -1; /* if 1 force entries to be zip64, 0 force not zip64 */
/* mainly for streaming from stdin */
int zip64_entry = 0; /* current entry needs Zip64 */
int zip64_archive = 0; /* if 1 then at least 1 entry needs zip64 */
#endif
#ifdef NTSD_EAS
int use_privileges = 0; /* 1=use security privilege overrides */
#endif
#ifndef RISCOS
#ifndef QDOS
#ifndef TANDEM
char *special = ".Z:.zip:.zoo:.arc:.lzh:.arj"; /* List of special suffixes */
#else /* TANDEM */
char *special = " Z: zip: zoo: arc: lzh: arj"; /* List of special suffixes */
#endif
#else /* QDOS */
char *special = "_Z:_zip:_zoo:_arc:_lzh:_arj"; /* List of special suffixes */
#endif
#else /* RISCOS */
char *special = "DDC:D96:68E";
#endif /* ?RISCOS */
char *key = NULL; /* Scramble password if scrambling */
char *tempath = NULL; /* Path for temporary files */
FILE *mesg; /* stdout by default, stderr for piping */
#ifdef UNICODE_SUPPORT
int utf8_force = 0; /* 1=force storing UTF-8 as standard per AppNote bit 11 */
#endif
int unicode_escape_all = 0; /* 1=escape all non-ASCII characters in paths */
int unicode_mismatch = 1; /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */
time_t scan_delay = 5; /* seconds before display Scanning files message */
time_t scan_dot_time = 2; /* time in seconds between Scanning files dots */
time_t scan_start = 0; /* start of scan */
time_t scan_last = 0; /* time of last message */
int scan_started = 0; /* scan has started */
uzoff_t scan_count = 0; /* Used for Scanning files ... message */
ulg before = 0; /* 0=ignore, else exclude files before this time */
ulg after = 0; /* 0=ignore, else exclude files newer than this time */
/* Zip file globals */
char *zipfile; /* New or existing zip archive (zip file) */
/* zip64 support 08/31/2003 R.Nausedat */
/* all are across splits - subtract bytes_prev_splits to get offsets for current disk */
uzoff_t zipbeg; /* Starting offset of zip structures */
uzoff_t cenbeg; /* Starting offset of central dir */
uzoff_t tempzn; /* Count of bytes written to output zip files */
/* 10/28/05 */
char *tempzip = NULL; /* name of temp file */
FILE *y = NULL; /* output file now global so can change in splits */
FILE *in_file = NULL; /* current input file for splits */
char *in_path = NULL; /* base name of input archive file */
char *in_split_path = NULL; /* in split path */
char *out_path = NULL; /* base name of output file, usually same as zipfile */
int zip_attributes = 0;
/* in split globals */
ulg total_disks = 0; /* total disks in archive */
ulg current_in_disk = 0; /* current read split disk */
uzoff_t current_in_offset = 0; /* current offset in current read disk */
ulg skip_current_disk = 0; /* if != 0 and fix then skip entries on this disk */
/* out split globals */
ulg current_local_disk = 0; /* disk with current local header */
ulg current_disk = 0; /* current disk number */
ulg cd_start_disk = (ulg)-1; /* central directory start disk */
uzoff_t cd_start_offset = 0; /* offset of start of cd on cd start disk */
uzoff_t cd_entries_this_disk = 0; /* cd entries this disk */
uzoff_t total_cd_entries = 0; /* total cd entries in new/updated archive */
ulg zip64_eocd_disk = 0; /* disk with Zip64 End Of Central Directory Record */
uzoff_t zip64_eocd_offset = 0; /* offset for Zip64 EOCD Record */
/* for split method 1 (keep split with local header open and update) */
char *current_local_tempname = NULL; /* name of temp file */
FILE *current_local_file = NULL; /* file pointer for current local header */
uzoff_t current_local_offset = 0; /* offset to start of current local header */
/* global */
uzoff_t bytes_this_split = 0; /* bytes written to the current split */
int read_split_archive = 0; /* 1=scanzipf_reg detected spanning signature */
int split_method = 0; /* 0=no splits, 1=seekable, 2=data desc, -1=no */
uzoff_t split_size = 0; /* how big each split should be */
int split_bell = 0; /* when pause for next split ring bell */
uzoff_t bytes_prev_splits = 0; /* total bytes written to all splits before this */
uzoff_t bytes_this_entry = 0; /* bytes written for this entry across all splits */
int noisy_splits = 0; /* note when splits are being created */
int mesg_line_started = 0; /* 1=started writing a line to mesg */
int logfile_line_started = 0; /* 1=started writing a line to logfile */
#ifdef WIN32
int nonlocal_name = 0; /* Name has non-local characters */
int nonlocal_path = 0; /* Path has non-local characters */
#endif
#ifdef UNICODE_SUPPORT
int use_wide_to_mb_default = 0;
#endif
struct zlist far *zfiles = NULL; /* Pointer to list of files in zip file */
/* The limit for number of files using the Zip64 format is 2^64 - 1 (8 bytes)
but extent is used for many internal sorts and other tasks and is generally
long on 32-bit systems. Because of that, but more because of various memory
utilization issues limiting the practical number of central directory entries
that can be sorted, the number of actual entries that can be stored probably
can't exceed roughly 2^30 on 32-bit systems so extent is probably sufficient. */
extent zcount; /* Number of files in zip file */
int zipfile_exists = 0; /* 1 if zipfile exists */
ush zcomlen; /* Length of zip file comment */
char *zcomment = NULL; /* Zip file comment (not zero-terminated) */
struct zlist far **zsort; /* List of files sorted by name */
#ifdef UNICODE_SUPPORT
struct zlist far **zusort; /* List of files sorted by zuname */
#endif
/* Files to operate on that are not in zip file */
struct flist far *found = NULL; /* List of names found */
struct flist far * far *fnxt = &found;
/* Where to put next name in found list */
extent fcount; /* Count of files in list */
/* Patterns to be matched */
struct plist *patterns = NULL; /* List of patterns to be matched */
unsigned pcount = 0; /* number of patterns */
unsigned icount = 0; /* number of include only patterns */
unsigned Rcount = 0; /* number of -R include patterns */
#ifdef IZ_CHECK_TZ
int zp_tz_is_valid; /* signals "timezone info is available" */
#endif

76
third_party/zip/osdep.h vendored Normal file
View file

@ -0,0 +1,76 @@
/* clang-format off */
/*
unix/osdep.h - Zip 3
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2005-Feb-10 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, both of these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
#ifdef LARGE_FILE_SUPPORT
/* 64-bit Large File Support */
/* The following Large File Summit (LFS) defines turn on large file support on
Linux (probably 2.4 or later kernel) and many other unixen */
# define _LARGEFILE_SOURCE /* some OSes need this for fseeko */
# define _LARGEFILE64_SOURCE
# define _FILE_OFFSET_BITS 64 /* select default interface as 64 bit */
# define _LARGE_FILES /* some OSes need this for 64-bit off_t */
#endif
#include "libc/calls/weirdtypes.h"
#include "libc/calls/calls.h"
#include "libc/sysv/consts/s.h"
/* printf format size prefix for zoff_t values */
#ifdef LARGE_FILE_SUPPORT
# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
#else
# define ZOFF_T_FORMAT_SIZE_PREFIX "l"
#endif
#ifdef NO_OFF_T
typedef long zoff_t;
typedef unsigned long uzoff_t;
#else
typedef off_t zoff_t;
# if defined(LARGE_FILE_SUPPORT) && !(defined(__alpha) && defined(__osf__))
typedef unsigned long long uzoff_t;
# else
typedef unsigned long uzoff_t;
# endif
#endif
typedef struct stat z_stat;
/* Automatically set ZIP64_SUPPORT if LFS */
#ifdef LARGE_FILE_SUPPORT
# ifndef NO_ZIP64_SUPPORT
# ifndef ZIP64_SUPPORT
# define ZIP64_SUPPORT
# endif
# else
# ifdef ZIP64_SUPPORT
# undef ZIP64_SUPPORT
# endif
# endif
#endif
/* Process files in binary mode */
#if defined(__DJGPP__) || defined(__CYGWIN__)
# define FOPR "rb"
# define FOPM "r+b"
# define FOPW "wb"
#endif
/* Enable the "UT" extra field (time info) */
#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)
# define USE_EF_UT_TIME
#endif

140
third_party/zip/revision.h vendored Normal file
View file

@ -0,0 +1,140 @@
/* clang-format off */
/*
revision.h - Zip 3
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
/*
* revision.h by Mark Adler.
*/
#ifndef __revision_h
#define __revision_h 1
/* For api version checking */
#define Z_MAJORVER 3
#define Z_MINORVER 0
#define Z_PATCHLEVEL 0
#define Z_BETALEVEL "i BETA"
#define VERSION "3.0"
#define REVDATE "July 5th 2008"
#define DW_MAJORVER Z_MAJORVER
#define DW_MINORVER Z_MINORVER
#define DW_PATCHLEVEL Z_PATCHLEVEL
#ifndef IZ_COMPANY_NAME /* might be already defined... */
# define IZ_COMPANY_NAME "Info-ZIP"
#endif
#if !defined(WINDLL) && !defined(IZ_VERSION_SYMBOLS_ONLY)
/* Copyright notice for binary executables--this notice only applies to
* those (zip, zipcloak, zipsplit, and zipnote), not to this file
* (revision.h).
*/
#ifndef DEFCPYRT
/* copyright[] et.al. get defined only once ! */
/* keep array sizes in sync with number of text */
/* lines in the array definitions below !! */
extern ZCONST char *copyright[1];
extern ZCONST char * far swlicense[50];
extern ZCONST char * far versinfolines[7];
extern ZCONST char * far cryptnote[7];
#else /* DEFCPYRT */
ZCONST char *copyright[] = {
"Copyright (c) 1990-2008 Info-ZIP - Type '%s \"-L\"' for software license."
/* XXX still necessary ???? */
#ifdef AZTEC_C
, /* extremely lame compiler bug workaround */
#endif
};
ZCONST char * far versinfolines[] = {
"This is %s %s (%s), by Info-ZIP.",
"Currently maintained by E. Gordon. Please send bug reports to",
"the authors using the web page at www.info-zip.org; see README for details.",
"",
"Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip,",
"as of above date; see http://www.info-zip.org/ for other sites.",
""
};
/* new notice - 4 March 2007 */
ZCONST char * far cryptnote[] = {
"Encryption notice:",
"\tThe encryption code of this program is not copyrighted and is",
"\tput in the public domain. It was originally written in Europe",
"\tand, to the best of our knowledge, can be freely distributed",
"\tin both source and object forms from any country, including",
"\tthe USA under License Exception TSU of the U.S. Export",
"\tAdministration Regulations (section 740.13(e)) of 6 June 2002."
};
ZCONST char * far swlicense[] = {
"Copyright (c) 1990-2008 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 above disclaimer and the following restrictions:",
"",
" 1. Redistributions of source code (in whole or in part) must retain",
" the above copyright notice, definition, disclaimer, and this list",
" of conditions.",
"",
" 2. Redistributions in binary form (compiled executables and libraries)",
" 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, versions with",
" modified or added functionality, and dynamic, shared, or static library",
" versions not from Info-ZIP--must be plainly marked as such and must not",
" be misrepresented as being the original source or, if binaries,",
" compiled from 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 the Info-ZIP URL(s), such as to imply Info-ZIP",
" will provide support for the altered versions.",
"",
" 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."
};
#endif /* DEFCPYRT */
#endif /* !WINDLL && !IZ_VERSION_SYMBOLS_ONLY */
#endif /* !__revision_h */

813
third_party/zip/tailor.h vendored Normal file
View file

@ -0,0 +1,813 @@
/* clang-format off */
/*
tailor.h - Zip 3
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
/* Some compiler distributions for Win32/i386 systems try to emulate
* a Unix (POSIX-compatible) environment.
*/
#if (defined(WIN32) && defined(UNIX))
/* Zip 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
/* UNICODE */
#ifdef NO_UNICODE_SUPPORT
# ifdef UNICODE_SUPPORT
# undef UNICODE_SUPPORT
# endif
#endif
#include "libc/str/str.h"
#include "third_party/zip/osdep.h"
/* generic LARGE_FILE_SUPPORT defines
These get used if not defined above.
7/21/2004 EG
*/
/* If a port hasn't defined ZOFF_T_FORMAT_SIZE_PREFIX
then probably need to define all of these. */
#ifndef ZOFF_T_FORMAT_SIZE_PREFIX
# ifdef LARGE_FILE_SUPPORT
/* Probably passed in from command line instead of in above
includes if get here. Assume large file support and hope. 8/14/04 EG */
/* Set the Large File Summit (LFS) defines to turn on large file support
in case it helps. */
# define _LARGEFILE_SOURCE /* some OSes need this for fseeko */
# define _LARGEFILE64_SOURCE
# define _FILE_OFFSET_BITS 64 /* select default interface as 64 bit */
# define _LARGE_FILES /* some OSes need this for 64-bit off_t */
typedef off_t zoff_t;
typedef unsigned long long uzoff_t; /* unsigned zoff_t (12/29/04 EG) */
/* go with common prefix */
# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
# else
/* Default type for offsets and file sizes was ulg but reports
of using ulg to create files from 2 GB to 4 GB suggest
it doesn't work well. Now just switch to Zip64 or not
support over 2 GB. 7/24/04 EG */
/* Now use uzoff_t for unsigned things. 12/29/04 EG */
typedef long zoff_t;
typedef unsigned long uzoff_t;
# define ZOFF_T_FORMAT_SIZE_PREFIX "l"
# endif
typedef struct stat z_stat;
/* flag that we are defaulting */
# define USING_DEFAULT_LARGE_FILE_SUPPORT
#endif
#if (defined(USE_ZLIB) && defined(ASM_CRC))
# undef ASM_CRC
#endif
#if (defined(USE_ZLIB) && defined(ASMV))
# undef ASMV
#endif
/* When "void" is an alias for "int", prototypes cannot be used. */
#if (defined(NO_VOID) && !defined(NO_PROTO))
# define NO_PROTO
#endif
/* Used to remove arguments in function prototypes for non-ANSI C */
#ifndef NO_PROTO
# define OF(a) a
# define OFT(a) a
#else /* NO_PROTO */
# define OF(a) ()
# define OFT(a)
#endif /* ?NO_PROTO */
/* If the compiler can't handle const define ZCONST in osdep.h */
/* Define const itself in case the system include files are bonkers */
#ifndef ZCONST
# ifdef NO_CONST
# define ZCONST
# define const
# else
# define ZCONST const
# endif
#endif
/*
* Some compiler environments may require additional attributes attached
* to declarations of runtime libary functions (e.g. to prepare for
* linking against a "shared dll" version of the RTL). Here, we provide
* the "empty" default for these attributes.
*/
#ifndef IZ_IMP
# define IZ_IMP
#endif
/*
* case mapping functions. case_map is used to ignore case in comparisons,
* to_up is used to force upper case even on Unix (for dosify option).
*/
#ifdef USE_CASE_MAP
# define case_map(c) kToUpper[(c) & 0xff]
# define to_up(c) kToLower[(c) & 0xff]
#else
# define case_map(c) (c)
# define to_up(c) ((c) >= 'a' && (c) <= 'z' ? (c)-'a'+'A' : (c))
#endif /* USE_CASE_MAP */
/* Define void, zvoid, and extent (size_t) */
#include "libc/stdio/stdio.h"
#ifndef NO_STDDEF_H
// # include <stddef.h>
#endif /* !NO_STDDEF_H */
#ifndef NO_STDLIB_H
#include "libc/mem/mem.h"
#endif /* !NO_STDLIB_H */
#ifndef NO_UNISTD_H
#include "libc/calls/calls.h"
#include "libc/calls/weirdtypes.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#endif /* !NO_UNISTD_H */
#ifndef NO_FCNTL_H
#include "libc/calls/calls.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/f.h"
#endif /* !NO_FNCTL_H */
#include "libc/str/str.h"
#ifdef NO_VOID
# define void int
typedef char zvoid;
#else /* !NO_VOID */
# ifdef NO_TYPEDEF_VOID
# define zvoid void
# else
typedef void zvoid;
# endif
#endif /* ?NO_VOID */
#ifdef NO_STRRCHR
# define strrchr rindex
#endif
#ifdef NO_STRCHR
# define strchr index
#endif
/*
* A couple of forward declarations that are needed on systems that do
* not supply C runtime library prototypes.
*/
#ifdef NO_PROTO
IZ_IMP char *strcpy();
IZ_IMP char *strcat();
IZ_IMP char *strrchr();
/* XXX use !defined(ZMEM) && !defined(__hpux__) ? */
#if !defined(ZMEM) && defined(NO_STRING_H)
IZ_IMP char *memset();
IZ_IMP char *memcpy();
#endif /* !ZMEM && NO_STRING_H */
/* XXX use !defined(__hpux__) ? */
#ifdef NO_STDLIB_H
IZ_IMP char *calloc();
IZ_IMP char *malloc();
IZ_IMP char *getenv();
IZ_IMP long atol();
#endif /* NO_STDLIB_H */
#ifndef NO_MKTEMP
IZ_IMP char *mktemp();
#endif /* !NO_MKTEMP */
#endif /* NO_PROTO */
/*
* SEEK_* macros, should be defined in stdio.h
*/
/* Define fseek() commands */
#ifndef SEEK_SET
# define SEEK_SET 0
#endif /* !SEEK_SET */
#ifndef SEEK_CUR
# define SEEK_CUR 1
#endif /* !SEEK_CUR */
#ifndef FALSE
# define FALSE 0
#endif
#ifndef TRUE
# define TRUE 1
#endif
#ifdef NO_SIZE_T
typedef unsigned int extent;
/* define size_t 3/17/05 EG */
typedef unsigned int size_t;
#else
typedef size_t extent;
#endif
#ifdef NO_TIME_T
typedef long time_t;
#endif
/* DBCS support for Info-ZIP's zip (mainly for japanese (-: )
* by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y@is.aist-nara.ac.jp)
* This code is public domain! Date: 1998/12/20
*/
/* 2007-07-29 SMS.
* Include <locale.h> here if it will be needed later for Unicode.
* Otherwise, SETLOCALE may be defined here, and then defined again
* (differently) when <locale.h> is read later.
*/
#ifdef UNICODE_SUPPORT
# if defined( UNIX) || defined( VMS)
#include "libc/unicode/locale.h"
# endif /* defined( UNIX) || defined( VMS) */
#include "libc/str/str.h"
#endif /* def UNICODE_SUPPORT */
#ifdef _MBCS
# include <locale.h>
/* Multi Byte Character Set */
extern char *___tmp_ptr;
unsigned char *zmbschr OF((ZCONST unsigned char *, unsigned int));
unsigned char *zmbsrchr OF((ZCONST unsigned char *, unsigned int));
# define CLEN(ptr) mblen((ZCONST char *)ptr, MB_CUR_MAX)
# define PREINCSTR(ptr) (ptr += CLEN(ptr))
# define POSTINCSTR(ptr) (___tmp_ptr=(char *)ptr,ptr += CLEN(ptr),___tmp_ptr)
int lastchar OF((ZCONST char *ptr));
# define MBSCHR(str,c) (char *)zmbschr((ZCONST unsigned char *)(str), c)
# define MBSRCHR(str,c) (char *)zmbsrchr((ZCONST unsigned char *)(str), (c))
# ifndef SETLOCALE
# define SETLOCALE(category, locale) setlocale(category, locale)
# endif /* ndef SETLOCALE */
#else /* !_MBCS */
# define CLEN(ptr) 1
# define PREINCSTR(ptr) (++(ptr))
# define POSTINCSTR(ptr) ((ptr)++)
# define lastchar(ptr) ((*(ptr)=='\0') ? '\0' : ptr[strlen(ptr)-1])
# define MBSCHR(str, c) strchr(str, c)
# define MBSRCHR(str, c) strrchr(str, c)
# ifndef SETLOCALE
# define SETLOCALE(category, locale)
# endif /* ndef SETLOCALE */
#endif /* ?_MBCS */
#define INCSTR(ptr) PREINCSTR(ptr)
/* System independent replacement for "struct utimbuf", which is missing
* in many older OS environments.
*/
typedef struct ztimbuf {
time_t actime; /* new access time */
time_t modtime; /* new modification time */
} ztimbuf;
/* This macro round a time_t value to the OS specific resolution */
#ifndef ROUNDED_TIME
# define ROUNDED_TIME(time) (time)
#endif
/* Some systems define S_IFLNK but do not support symbolic links */
#if defined (S_IFLNK) && defined(NO_SYMLINKS)
# undef S_IFLNK
#endif
#ifndef Z_UINT4_DEFINED
# if !defined(NO_LIMITS_H)
# if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL))
typedef unsigned int z_uint4;
# define Z_UINT4_DEFINED
# else
# if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL))
typedef unsigned long z_uint4;
# define Z_UINT4_DEFINED
# else
# if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL))
typedef unsigned short z_uint4;
# define Z_UINT4_DEFINED
# endif
# endif
# endif
# endif /* !defined(NO_LIMITS_H) */
#endif /* ndef Z_UINT4_DEFINED */
#ifndef Z_UINT4_DEFINED
typedef ulg z_uint4;
# define Z_UINT4_DEFINED
#endif
#ifndef FOPR /* fallback default definitions for FOPR, FOPM, FOPW: */
# define FOPR "r"
# define FOPM "r+"
# define FOPW "w"
#endif /* fallback definition */
#ifndef FOPW_TMP /* fallback default for opening writable temp files */
# define FOPW_TMP FOPW
#endif
/* Open the old zip file in exclusive mode if possible (to avoid adding
* zip file to itself).
*/
#ifdef OS2
# define FOPR_EX FOPM
#else
# define FOPR_EX FOPR
#endif
/* MSDOS file or directory attributes */
#define MSDOS_HIDDEN_ATTR 0x02
#define MSDOS_DIR_ATTR 0x10
/* Define this symbol if your target allows access to unaligned data.
* This is not mandatory, just a speed optimization. The compressed
* output is strictly identical.
*/
#if (defined(MSDOS) && !defined(WIN32)) || defined(i386)
# define UNALIGNED_OK
#endif
#if defined(mc68020) || defined(vax)
# define UNALIGNED_OK
#endif
#if (defined(SMALL_MEM) && !defined(CBSZ))
# define CBSZ 2048 /* buffer size for copying files */
# define ZBSZ 2048 /* buffer size for temporary zip file */
#endif
#if (defined(MEDIUM_MEM) && !defined(CBSZ))
# define CBSZ 8192
# define ZBSZ 8192
#endif
#ifndef CBSZ
# define CBSZ 16384
# define ZBSZ 16384
#endif
#ifndef SBSZ
# define SBSZ CBSZ /* copy buf size for STORED entries, see zipup() */
#endif
#ifndef MEMORY16
# ifdef __WATCOMC__
# undef huge
# undef far
# undef near
# endif
# ifdef THEOS
# undef far
# undef near
# endif
# if (!defined(__IBMC__) || !defined(OS2))
# ifndef huge
# define huge
# endif
# ifndef far
# define far
# endif
# ifndef near
# define near
# endif
# endif
# define nearmalloc malloc
# define nearfree free
# define farmalloc malloc
# define farfree free
#endif /* !MEMORY16 */
#ifndef Far
# define Far far
#endif
/* MMAP and BIG_MEM cannot be used together -> let MMAP take precedence */
#if (defined(MMAP) && defined(BIG_MEM))
# undef BIG_MEM
#endif
#if (defined(BIG_MEM) || defined(MMAP)) && !defined(DYN_ALLOC)
# define DYN_ALLOC
#endif
/* LARGE_FILE_SUPPORT
*
* Types are in osdep.h for each port
*
* LARGE_FILE_SUPPORT and ZIP64_SUPPORT are automatically
* set in osdep.h (for some ports) based on the port and compiler.
*
* Function prototypes are below as OF is defined earlier in this file
* but after osdep.h is included. In the future ANSI prototype
* support may be required and the OF define may then go away allowing
* the function defines to be in the port osdep.h.
*
* E. Gordon 9/21/2003
* Updated 7/24/04 EG
*/
#ifdef LARGE_FILE_SUPPORT
/* 64-bit Large File Support */
/* Arguments for all functions are assumed to match the actual
arguments of the various port calls. As such only the
function names are mapped below. */
/* ---------------------------- */
# ifdef UNIX
/* Assume 64-bit file environment is defined. The below should all
be set to their 64-bit versions automatically. Neat. 7/20/2004 EG */
/* 64-bit stat functions */
# define zstat stat
# define zfstat fstat
# define zlstat lstat
# if defined(__alpha) && defined(__osf__) /* support for osf4.0f */
/* 64-bit fseek */
# define zfseeko fseek
/* 64-bit ftell */
# define zftello ftell
# else
/* 64-bit fseeko */
# define zfseeko fseeko
/* 64-bit ftello */
# define zftello ftello
# endif /* __alpha && __osf__ */
/* 64-bit fopen */
# define zfopen fopen
# define zfdopen fdopen
# endif /* UNIX */
/* ---------------------------- */
# ifdef VMS
/* 64-bit stat functions */
# define zstat stat
# define zfstat fstat
# define zlstat lstat
/* 64-bit fseeko */
# define zfseeko fseeko
/* 64-bit ftello */
# define zftello ftello
/* 64-bit fopen */
# define zfopen fopen
# define zfdopen fdopen
# endif /* def VMS */
/* ---------------------------- */
# ifdef WIN32
# if defined(__MINGW32__)
/* GNU C, linked against "msvcrt.dll" */
/* 64-bit stat functions */
# define zstat _stati64
# ifdef UNICODE_SUPPORT
# define zwfstat _fstati64
# define zwstat _wstati64
# define zw_stat struct _stati64
# endif
# define zfstat _fstati64
# define zlstat lstat
/* 64-bit fseeko */
/* function in win32.c */
int zfseeko OF((FILE *, zoff_t, int));
/* 64-bit ftello */
/* function in win32.c */
zoff_t zftello OF((FILE *));
/* 64-bit fopen */
# define zfopen fopen
# define zfdopen fdopen
# endif
# if defined(__CYGWIN__)
/* GNU C, CygWin with its own POSIX compatible runtime library */
/* 64-bit stat functions */
# define zstat stat
# define zfstat fstat
# define zlstat lstat
/* 64-bit fseeko */
# define zfseeko fseeko
/* 64-bit ftello */
# define zftello ftello
/* 64-bit fopen */
# define zfopen fopen
# define zfdopen fdopen
# endif
# ifdef __WATCOMC__
/* WATCOM C */
/* 64-bit stat functions */
# define zstat _stati64
# ifdef UNICODE_SUPPORT
# define zwfstat _fstati64
# define zwstat _wstati64
# define zw_stat struct _stati64
# endif
# define zfstat _fstati64
# define zlstat lstat
/* 64-bit fseeko */
/* function in win32.c */
int zfseeko OF((FILE *, zoff_t, int));
/* 64-bit ftello */
/* function in win32.c */
zoff_t zftello OF((FILE *));
/* 64-bit fopen */
# define zfopen fopen
# define zfdopen fdopen
# endif
# ifdef _MSC_VER
/* MS C and VC */
/* 64-bit stat functions */
# define zstat _stati64
# ifdef UNICODE_SUPPORT
# define zwfstat _fstati64
# define zwstat _wstati64
# define zw_stat struct _stati64
# endif
# define zfstat _fstati64
# define zlstat lstat
/* 64-bit fseeko */
/* function in win32.c */
int zfseeko OF((FILE *, zoff_t, int));
/* 64-bit ftello */
/* function in win32.c */
zoff_t zftello OF((FILE *));
/* 64-bit fopen */
# define zfopen fopen
# define zfdopen fdopen
# endif
# ifdef __IBMC__
/* IBM C */
/* 64-bit stat functions */
/* 64-bit fseeko */
/* function in win32.c */
int zfseeko OF((FILE *, zoff_t, int));
/* 64-bit ftello */
/* function in win32.c */
zoff_t zftello OF((FILE *));
/* 64-bit fopen */
# endif
# endif /* WIN32 */
#else
/* No Large File Support or default for 64-bit environment */
# define zstat stat
# define zfstat fstat
# define zlstat lstat
# define zfseeko fseek
# define zftello ftell
# define zfopen fopen
# define zfdopen fdopen
# ifdef UNICODE_SUPPORT
# define zwfstat _fstat
# define zwstat _wstat
# define zw_stat struct _stat
# endif
#endif
#ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/2003 */
# ifndef SSTAT
# define SSTAT zstat
# ifdef UNICODE_SUPPORT
# define SSTATW zwstat
# endif
# endif
# ifdef S_IFLNK
# define LSTAT zlstat
# define LSSTAT(n, s) (linkput ? zlstat((n), (s)) : SSTAT((n), (s)))
# else
# define LSTAT SSTAT
# define LSSTAT SSTAT
# ifdef UNICODE_SUPPORT
# define LSSTATW SSTATW
# endif
# endif
#else /* no LARGE_FILE_SUPPORT */
# ifndef SSTAT
# define SSTAT stat
# endif
# ifdef S_IFLNK
# define LSTAT lstat
# define LSSTAT(n, s) (linkput ? lstat((n), (s)) : SSTAT((n), (s)))
# else
# define LSTAT SSTAT
# define LSSTAT SSTAT
# ifdef UNICODE_SUPPORT
# define LSSTATW SSTATW
# endif
# endif
#endif
/*---------------------------------------------------------------------*/
/* 2004-12-01 SMS.
* Added fancy zofft() macros, et c.
*/
/* Default fzofft() format selection.
* Modified 2004-12-27 EG
*/
#ifndef FZOFFT_FMT
# define FZOFFT_FMT ZOFF_T_FORMAT_SIZE_PREFIX /* printf for zoff_t values */
# ifdef LARGE_FILE_SUPPORT
# define FZOFFT_HEX_WID_VALUE "16" /* width of 64-bit hex values */
# else
# define FZOFFT_HEX_WID_VALUE "8" /* digits in 32-bit hex values */
# endif
#endif /* ndef FZOFFT_FMT */
#define FZOFFT_HEX_WID ((char *) -1)
#define FZOFFT_HEX_DOT_WID ((char *) -2)
/* The following default definition of the second input for the crypthead()
* random seed computation can be used on most systems (all those that
* supply a UNIX compatible getpid() function).
*/
#ifdef ZCRYPT_INTERNAL
# ifndef ZCR_SEED2
# define ZCR_SEED2 (unsigned) getpid() /* use PID as seed pattern */
# endif
#endif /* ZCRYPT_INTERNAL */
/* The following OS codes are defined in pkzip appnote.txt */
#ifdef AMIGA
# define OS_CODE 0x100
#endif
#ifdef VMS
# define OS_CODE 0x200
#endif
/* unix 3 */
#ifdef VM_CMS
# define OS_CODE 0x400
#endif
#ifdef ATARI
# define OS_CODE 0x500
#endif
#ifdef OS2
# define OS_CODE 0x600
#endif
#ifdef MACOS
# define OS_CODE 0x700
#endif
/* z system 8 */
/* cp/m 9 */
#ifdef TOPS20
# define OS_CODE 0xa00
#endif
#ifdef WIN32
# define OS_CODE 0xb00
#endif
#ifdef QDOS
# define OS_CODE 0xc00
#endif
#ifdef RISCOS
# define OS_CODE 0xd00
#endif
#ifdef VFAT
# define OS_CODE 0xe00
#endif
#ifdef MVS
# define OS_CODE 0xf00
#endif
#ifdef __BEOS__
# define OS_CODE 0x1000
#endif
#ifdef TANDEM
# define OS_CODE 0x1100
#endif
#ifdef THEOS
# define OS_CODE 0x1200
#endif
/* Yes, there is a gap here. */
#ifdef __ATHEOS__
# define OS_CODE 0x1E00
#endif
#define NUM_HOSTS 31
/* Number of operating systems. Should be updated when new ports are made */
#if defined(DOS) && !defined(OS_CODE)
# define OS_CODE 0x000
#endif
#ifndef OS_CODE
# define OS_CODE 0x300 /* assume Unix */
#endif
/* can't use "return 0" from main() on VMS */
#ifndef EXIT
# define EXIT exit
#endif
#ifndef RETURN
# define RETURN return
#endif
#ifndef ZIPERR
# define ZIPERR ziperr
#endif
#if (defined(USE_ZLIB) && defined(MY_ZCALLOC))
/* special zcalloc function is not needed when linked against zlib */
# undef MY_ZCALLOC
#endif
#if (!defined(USE_ZLIB) && !defined(MY_ZCALLOC))
/* Any system without a special calloc function */
# define zcalloc(items,size) \
(zvoid far *)calloc((unsigned)(items), (unsigned)(size))
# define zcfree free
#endif /* !USE_ZLIB && !MY_ZCALLOC */
/* end of tailor.h */

816
third_party/zip/timezone.c vendored Normal file
View file

@ -0,0 +1,816 @@
/* clang-format off */
/*
timezone.c - Zip 3
Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2003-May-08 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
*/
/* Replacement time library functions, based on platform independent public
* domain timezone code from ftp://elsie.nci.nih.gov/pub, with mktime and
* mkgmtime from our own mktime.c in Zip.
*
* Contains: tzset()
* __tzset()
* gmtime()
* localtime()
* mktime()
* mkgmtime()
* GetPlatformLocalTimezone() [different versions]
*/
/* HISTORY/CHANGES
* 17 Jun 00, Paul Kienitz, added the PD-based tzset(), localtime(), and so on
* to amiga/filedate.c, replacing GNU-based functions which had
* replaced time_lib.c, both having been rejected for licensing
* reasons. Support for timezone files and leap seconds was removed.
*
* 23 Aug 00, Paul Kienitz, split into separate timezone.c file, made platform
* independent, copied in mktime() and mkgmtime() from Zip, renamed
* locale_TZ as GetPlatformLocalTimezone(), for use as a generic
* hook by other platforms.
*/
#ifndef __timezone_c
#define __timezone_c
#include "third_party/zip/zip.h"
#include "third_party/zip/timezone.h"
#include "libc/str/str.h"
#include "libc/errno.h"
#ifdef IZTZ_DEFINESTDGLOBALS
long timezone = 0;
int daylight = 0;
char *tzname[2];
#endif
#ifndef IZTZ_GETLOCALETZINFO
# define IZTZ_GETLOCALETZINFO(ptzstruct, pgenrulefunct) (FALSE)
#endif
int real_timezone_is_set = FALSE; /* set by tzset() */
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
#define TZDEFAULT "EST5EDT"
#define SECSPERMIN 60
#define MINSPERHOUR 60
#define HOURSPERDAY 24
#define DAYSPERWEEK 7
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
#define EPOCH_WDAY 4 /* Jan 1, 1970 was thursday */
#define EPOCH_YEAR 1970
#define TM_YEAR_BASE 1900
#define FIRST_GOOD_YEAR ((time_t) -1 < (time_t) 1 ? EPOCH_YEAR-68 : EPOCH_YEAR)
#define LAST_GOOD_YEAR (EPOCH_YEAR + ((time_t) -1 < (time_t) 1 ? 67 : 135))
#define YDAYS(month, year) yr_days[leap(year)][month]
/* 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 EPOCH_YEAR to `y' (not including `y' itself). */
#define _P4 ((EPOCH_YEAR / 4) * 4 + 1)
#define _P100 ((EPOCH_YEAR / 100) * 100 + 1)
#define _P400 ((EPOCH_YEAR / 400) * 400 + 1)
#define nleap(y) (((y) - _P4) / 4 - ((y) - _P100) / 100 + ((y) - _P400) / 400)
/* Length of month `m' (0 .. 11) */
#define monthlen(m, y) (yr_days[0][(m)+1] - yr_days[0][m] + \
((m) == 1 && leap(y)))
/* internal module-level constants */
#ifndef IZ_MKTIME_ONLY
static ZCONST char gmt[] = "GMT";
static ZCONST int mon_lengths[2][MONSPERYEAR] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
#endif /* !IZ_MKTIME_ONLY */
static ZCONST int yr_days[2][MONSPERYEAR+1] = {
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
#ifndef IZ_MKTIME_ONLY
static ZCONST int year_lengths[2] = {
DAYSPERNYEAR, DAYSPERLYEAR
};
/* internal variables */
static struct state statism;
/* prototypes of static functions */
static time_t transtime OF((ZCONST time_t janfirst, ZCONST int year,
ZCONST struct rule * ZCONST rulep,
ZCONST long offset));
static void generate_transitions OF((register struct state * ZCONST sp,
ZCONST struct rule * ZCONST start,
ZCONST struct rule * ZCONST end));
static ZCONST char *getzname OF((ZCONST char *strp));
static ZCONST char *getnum OF((ZCONST char *strp, int * ZCONST nump,
ZCONST int min, ZCONST int max));
static ZCONST char *getsecs OF((ZCONST char *strp, long * ZCONST secsp));
static ZCONST char *getoffset OF((ZCONST char *strp, long * ZCONST offsetp));
static ZCONST char *getrule OF((ZCONST char *strp, struct rule * ZCONST rulep));
static int Parse_TZ OF((ZCONST char *name, register struct state * ZCONST sp));
static time_t transtime(janfirst, year, rulep, offset)
ZCONST time_t janfirst;
ZCONST int year;
ZCONST struct rule * ZCONST rulep;
ZCONST long offset;
{
register int leapyear;
register time_t value;
register int i;
int d, m1, yy0, yy1, yy2, dow;
value = 0;
leapyear = leap(year);
switch (rulep->r_type) {
case JULIAN_DAY:
/*
** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
** years.
** In non-leap years, or if the day number is 59 or less, just
** add SECSPERDAY times the day number-1 to the time of
** January 1, midnight, to get the day.
*/
value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
if (leapyear && rulep->r_day >= 60)
value += SECSPERDAY;
break;
case DAY_OF_YEAR:
/*
** n - day of year.
** Just add SECSPERDAY times the day number to the time of
** January 1, midnight, to get the day.
*/
value = janfirst + rulep->r_day * SECSPERDAY;
break;
case MONTH_NTH_DAY_OF_WEEK:
/*
** Mm.n.d - nth "dth day" of month m.
*/
value = janfirst;
/*
for (i = 0; i < rulep->r_mon - 1; ++i)
value += mon_lengths[leapyear][i] * SECSPERDAY;
*/
value += yr_days[leapyear][rulep->r_mon - 1] * SECSPERDAY;
/*
** Use Zeller's Congruence to get day-of-week of first day of
** month.
*/
m1 = (rulep->r_mon + 9) % 12 + 1;
yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
yy1 = yy0 / 100;
yy2 = yy0 % 100;
dow = ((26 * m1 - 2) / 10 +
1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
if (dow < 0)
dow += DAYSPERWEEK;
/*
** "dow" is the day-of-week of the first day of the month. Get
** the day-of-month (zero-origin) of the first "dow" day of the
** month.
*/
d = rulep->r_day - dow;
if (d < 0)
d += DAYSPERWEEK;
for (i = 1; i < rulep->r_week; ++i) {
if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])
break;
d += DAYSPERWEEK;
}
/*
** "d" is the day-of-month (zero-origin) of the day we want.
*/
value += d * SECSPERDAY;
break;
}
/*
** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
** question. To get the Epoch-relative time of the specified local
** time on that day, add the transition time and the current offset
** from UTC.
*/
return value + rulep->r_time + offset;
}
static void generate_transitions(sp, start, end)
register struct state * ZCONST sp;
ZCONST struct rule * ZCONST start;
ZCONST struct rule * ZCONST end;
{
register int year;
register time_t janfirst;
time_t starttime;
time_t endtime;
long stdoffset = -sp->ttis[0].tt_gmtoff;
long dstoffset = -sp->ttis[1].tt_gmtoff;
register time_t * atp;
register unsigned char * typep;
/*
** Two transitions per year, from EPOCH_YEAR to LAST_GOOD_YEAR.
*/
sp->timecnt = 2 * (LAST_GOOD_YEAR - EPOCH_YEAR + 1);
atp = sp->ats;
typep = sp->types;
janfirst = 0;
for (year = EPOCH_YEAR; year <= LAST_GOOD_YEAR; ++year) {
starttime = transtime(janfirst, year, start, stdoffset);
endtime = transtime(janfirst, year, end, dstoffset);
if (starttime > endtime) {
*atp++ = endtime;
*typep++ = 0; /* DST ends */
*atp++ = starttime;
*typep++ = 1; /* DST begins */
} else {
*atp++ = starttime;
*typep++ = 1; /* DST begins */
*atp++ = endtime;
*typep++ = 0; /* DST ends */
}
janfirst += year_lengths[leap(year)] * SECSPERDAY;
}
}
static ZCONST char *getzname(strp)
ZCONST char *strp;
{
register char c;
while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
c != '+')
++strp;
return strp;
}
static ZCONST char *getnum(strp, nump, min, max)
ZCONST char *strp;
int * ZCONST nump;
ZCONST int min;
ZCONST int max;
{
register char c;
register int num;
if (strp == NULL || !isdigit(c = *strp))
return NULL;
num = 0;
do {
num = num * 10 + (c - '0');
if (num > max)
return NULL; /* illegal value */
c = *++strp;
} while (isdigit(c));
if (num < min)
return NULL; /* illegal value */
*nump = num;
return strp;
}
static ZCONST char *getsecs(strp, secsp)
ZCONST char *strp;
long * ZCONST secsp;
{
int num;
/*
** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
** "M10.4.6/26", which does not conform to Posix,
** but which specifies the equivalent of
** ``02:00 on the first Sunday on or after 23 Oct''.
*/
strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
if (strp == NULL)
return NULL;
*secsp = num * (long) SECSPERHOUR;
if (*strp == ':') {
++strp;
strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
if (strp == NULL)
return NULL;
*secsp += num * SECSPERMIN;
if (*strp == ':') {
++strp;
/* `SECSPERMIN' allows for leap seconds. */
strp = getnum(strp, &num, 0, SECSPERMIN);
if (strp == NULL)
return NULL;
*secsp += num;
}
}
return strp;
}
static ZCONST char *getoffset(strp, offsetp)
ZCONST char *strp;
long * ZCONST offsetp;
{
register int neg = 0;
if (*strp == '-') {
neg = 1;
++strp;
} else if (*strp == '+')
++strp;
strp = getsecs(strp, offsetp);
if (strp == NULL)
return NULL; /* illegal time */
if (neg)
*offsetp = -*offsetp;
return strp;
}
static ZCONST char *getrule(strp, rulep)
ZCONST char *strp;
struct rule * ZCONST rulep;
{
if (*strp == 'J') {
/*
** Julian day.
*/
rulep->r_type = JULIAN_DAY;
++strp;
strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
} else if (*strp == 'M') {
/*
** Month, week, day.
*/
rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
++strp;
strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
if (strp == NULL)
return NULL;
if (*strp++ != '.')
return NULL;
strp = getnum(strp, &rulep->r_week, 1, 5);
if (strp == NULL)
return NULL;
if (*strp++ != '.')
return NULL;
strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
} else if (isdigit(*strp)) {
/*
** Day of year.
*/
rulep->r_type = DAY_OF_YEAR;
strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
} else return NULL; /* invalid format */
if (strp == NULL)
return NULL;
if (*strp == '/') {
/*
** Time specified.
*/
++strp;
strp = getsecs(strp, &rulep->r_time);
} else
rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
return strp;
}
static int Parse_TZ(name, sp)
ZCONST char *name;
register struct state * ZCONST sp;
{
ZCONST char * stdname;
ZCONST char * dstname;
size_t stdlen;
size_t dstlen;
long stdoffset;
long dstoffset;
register char * cp;
dstname = NULL;
stdname = name;
name = getzname(name);
stdlen = name - stdname;
if (stdlen < 3)
return -1;
if (*name == '\0')
return -1;
name = getoffset(name, &stdoffset);
if (name == NULL)
return -1;
if (*name != '\0') {
dstname = name;
name = getzname(name);
dstlen = name - dstname; /* length of DST zone name */
if (dstlen < 3)
return -1;
if (*name != '\0' && *name != ',' && *name != ';') {
name = getoffset(name, &dstoffset);
if (name == NULL)
return -1;
} else
dstoffset = stdoffset - SECSPERHOUR;
if (*name == '\0')
name = TZDEFRULESTRING;
if (*name == ',' || *name == ';') {
struct rule start;
struct rule end;
++name;
if ((name = getrule(name, &start)) == NULL)
return -1;
if (*name++ != ',')
return -1;
if ((name = getrule(name, &end)) == NULL)
return -1;
if (*name != '\0')
return -1;
sp->typecnt = 2; /* standard time and DST */
sp->ttis[0].tt_gmtoff = -stdoffset;
sp->ttis[0].tt_isdst = 0;
sp->ttis[0].tt_abbrind = 0;
sp->ttis[1].tt_gmtoff = -dstoffset;
sp->ttis[1].tt_isdst = 1;
sp->ttis[1].tt_abbrind = stdlen + 1;
generate_transitions(sp, &start, &end);
}
} else {
dstlen = 0;
sp->typecnt = 1; /* only standard time */
sp->timecnt = 0;
sp->ttis[0].tt_gmtoff = -stdoffset;
sp->ttis[0].tt_isdst = 0;
sp->ttis[0].tt_abbrind = 0;
}
sp->charcnt = stdlen + 1;
if (dstlen != 0)
sp->charcnt += dstlen + 1;
if ((size_t) sp->charcnt > sizeof(sp->chars))
return -1;
cp = sp->chars;
(void) strncpy(cp, stdname, stdlen);
cp += stdlen;
*cp++ = '\0';
if (dstlen != 0) {
(void) strncpy(cp, dstname, dstlen);
*(cp + dstlen) = '\0';
}
return 0;
}
void tzset()
{
char *TZstring;
int dstfirst;
static char *old_TZstring = NULL;
TZstring = getenv("TZ"); /* read TZ envvar */
if (old_TZstring && TZstring && !strcmp(old_TZstring, TZstring))
/* do not repeatedly parse an unchanged TZ specification */
return;
if ((TZstring && TZstring[0] && Parse_TZ(TZstring, &statism) == 0)
|| IZTZ_GETLOCALETZINFO(&statism, generate_transitions)
|| Parse_TZ(gmt, &statism) == 0) {
daylight = statism.typecnt > 1;
dstfirst = daylight && statism.ttis[0].tt_isdst && !statism.ttis[1].tt_isdst;
timezone = -statism.ttis[dstfirst].tt_gmtoff;
tzname[0] = statism.chars + statism.ttis[dstfirst].tt_abbrind;
tzname[1] = statism.chars + statism.ttis[!dstfirst].tt_abbrind;
real_timezone_is_set = TRUE;
if (TZstring) {
if (old_TZstring)
old_TZstring = realloc(old_TZstring, strlen(TZstring) + 1);
else
old_TZstring = malloc(strlen(TZstring) + 1);
if (old_TZstring)
strcpy(old_TZstring, TZstring);
}
} else {
timezone = 0; /* default is GMT0 which means no offsets */
daylight = 0; /* from local system time */
real_timezone_is_set = FALSE;
if (old_TZstring) {
free(old_TZstring);
old_TZstring = NULL;
}
}
#ifdef IZTZ_SETLOCALTZINFO
/* Some SAS/C library functions, e.g. stat(), call library */
/* __tzset() themselves. So envvar TZ *must* exist in order to */
/* to get the right offset from GMT. XXX TRY HARD to fix this! */
set_TZ(timezone, daylight);
#endif /* IZTZ_SETLOCALTZINFO */
}
/* XXX Does this also help SAS/C library work? */
void __tzset()
{
if (!real_timezone_is_set) tzset();
}
static struct tm _tmbuf;
struct tm *gmtime(when)
ZCONST time_t *when;
{
long days = *when / SECSPERDAY;
long secs = *when % SECSPERDAY;
int isleap;
memset(&_tmbuf, 0, sizeof(_tmbuf)); /* get any nonstandard fields */
_tmbuf.tm_wday = (days + EPOCH_WDAY) % 7;
_tmbuf.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
isleap = leap(_tmbuf.tm_year + TM_YEAR_BASE);
while (days >= year_lengths[isleap]) {
days -= year_lengths[isleap];
_tmbuf.tm_year++;
isleap = leap(_tmbuf.tm_year + TM_YEAR_BASE);
}
_tmbuf.tm_mon = 0;
_tmbuf.tm_yday = days;
while (days >= mon_lengths[isleap][_tmbuf.tm_mon])
days -= mon_lengths[isleap][_tmbuf.tm_mon++];
_tmbuf.tm_mday = days + 1;
_tmbuf.tm_isdst = 0;
_tmbuf.tm_sec = secs % SECSPERMIN;
_tmbuf.tm_min = (secs / SECSPERMIN) % SECSPERMIN;
_tmbuf.tm_hour = secs / SECSPERHOUR;
return &_tmbuf;
}
struct tm *localtime(when)
ZCONST time_t *when;
{
time_t localwhen = *when;
int timetype;
struct tm *ret;
__tzset();
if (statism.timecnt == 0 || localwhen < statism.ats[0])
timetype = statism.ttis[0].tt_isdst && statism.typecnt > 1 &&
!statism.ttis[1].tt_isdst;
else {
for (timetype = 1; timetype < statism.timecnt; ++timetype)
if (localwhen < statism.ats[timetype])
break;
timetype = statism.types[timetype - 1];
}
localwhen += statism.ttis[timetype].tt_gmtoff;
ret = gmtime(&localwhen);
ret->tm_isdst = statism.ttis[timetype].tt_isdst;
return ret;
}
#ifdef NEED__ISINDST
int _isindst(tb)
struct tm *tb;
{
time_t localt; /* time_t equivalent of given tm struct */
time_t univt; /* assumed UTC value of given time */
long tzoffset_adj; /* timezone-adjustment `remainder' */
int bailout_cnt; /* counter of tries for tz correction */
int timetype;
__tzset();
/* when DST is unsupported in current timezone, DST is always off */
if (statism.typecnt <= 1) return FALSE;
localt = mkgmtime(tb);
if (localt == (time_t)-1)
/* specified time is out-of-range, default to FALSE */
return FALSE;
univt = localt - statism.ttis[0].tt_gmtoff;
bailout_cnt = 3;
do {
if (statism.timecnt == 0 || univt < statism.ats[0])
timetype = statism.ttis[0].tt_isdst && statism.typecnt > 1 &&
!statism.ttis[1].tt_isdst;
else {
for (timetype = 1; timetype < statism.timecnt; ++timetype)
if (univt < statism.ats[timetype])
break;
timetype = statism.types[timetype - 1];
}
if ((tzoffset_adj = localt - univt - statism.ttis[timetype].tt_gmtoff)
== 0L)
break;
univt += tzoffset_adj;
} while (--bailout_cnt > 0);
/* return TRUE when DST is active at given time */
return (statism.ttis[timetype].tt_isdst);
}
#endif /* NEED__ISINDST */
#endif /* !IZ_MKTIME_ONLY */
/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
of the local time and date in the exploded time structure `tm',
adjust out of range fields in `tm' and set `tm->tm_yday', `tm->tm_wday'.
If `tm->tm_isdst < 0' was passed to mktime(), the correct setting of
tm_isdst is determined and returned. Otherwise, mktime() assumes this
field as valid; its information is used when converting local time
to UTC.
Return -1 if time in `tm' cannot be represented as time_t value. */
time_t mktime(tm)
struct tm *tm;
{
struct tm *ltm; /* Local time. */
time_t loctime; /* The time_t value of local time. */
time_t then; /* The time to return. */
long tzoffset_adj; /* timezone-adjustment `remainder' */
int bailout_cnt; /* counter of tries for tz correction */
int save_isdst; /* Copy of the tm->isdst input value */
save_isdst = tm->tm_isdst;
loctime = mkgmtime(tm);
if (loctime == -1) {
tm->tm_isdst = save_isdst;
return (time_t)-1;
}
/* Correct for the timezone and any daylight savings time.
The correction is verified and repeated when not correct, to
take into account the rare case that a change to or from daylight
savings time occurs between when it is the time in `tm' locally
and when it is that time in Greenwich. After the second correction,
the "timezone & daylight" offset should be correct in all cases. To
be sure, we allow a third try, but then the loop is stopped. */
bailout_cnt = 3;
then = loctime;
do {
ltm = localtime(&then);
if (ltm == (struct tm *)NULL ||
(tzoffset_adj = loctime - mkgmtime(ltm)) == 0L)
break;
then += tzoffset_adj;
} while (--bailout_cnt > 0);
if (ltm == (struct tm *)NULL || tzoffset_adj != 0L) {
/* Signal failure if timezone adjustment did not converge. */
tm->tm_isdst = save_isdst;
return (time_t)-1;
}
if (save_isdst >= 0) {
if (ltm->tm_isdst && !save_isdst)
{
if (then + 3600 < then)
then = (time_t)-1;
else
then += 3600;
}
else if (!ltm->tm_isdst && save_isdst)
{
if (then - 3600 > then)
then = (time_t)-1;
else
then -= 3600;
}
ltm->tm_isdst = save_isdst;
}
if (tm != ltm) /* `tm' may already point to localtime's internal storage */
*tm = *ltm;
return then;
}
#ifndef NO_TIME_T_MAX
/* Provide default values for the upper limit of the time_t range.
These are the result of the decomposition into a `struct tm' for
the time value 0xFFFFFFFEL ( = (time_t)-2 ).
Note: `(time_t)-1' is reserved for "invalid time"! */
# ifndef TM_YEAR_MAX
# define TM_YEAR_MAX 2106
# endif
# ifndef TM_MON_MAX
# define TM_MON_MAX 1 /* February */
# endif
# ifndef TM_MDAY_MAX
# define TM_MDAY_MAX 7
# endif
# ifndef TM_HOUR_MAX
# define TM_HOUR_MAX 6
# endif
# ifndef TM_MIN_MAX
# define TM_MIN_MAX 28
# endif
# ifndef TM_SEC_MAX
# define TM_SEC_MAX 14
# endif
#endif /* NO_TIME_T_MAX */
/* Adjusts out-of-range values for `tm' field `tm_member'. */
#define ADJUST_TM(tm_member, tm_carry, modulus) \
if ((tm_member) < 0) { \
tm_carry -= (1 - ((tm_member)+1) / (modulus)); \
tm_member = (modulus-1) + (((tm_member)+1) % (modulus)); \
} else if ((tm_member) >= (modulus)) { \
tm_carry += (tm_member) / (modulus); \
tm_member = (tm_member) % (modulus); \
}
/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
of the Greenwich Mean time and date in the exploded time structure `tm'.
This function does always put back normalized values into the `tm' struct,
parameter, including the calculated numbers for `tm->tm_yday',
`tm->tm_wday', and `tm->tm_isdst'.
Returns -1 if the time in the `tm' parameter cannot be represented
as valid `time_t' number. */
time_t mkgmtime(tm)
struct tm *tm;
{
int years, months, days, hours, minutes, seconds;
years = tm->tm_year + TM_YEAR_BASE; /* year - 1900 -> year */
months = tm->tm_mon; /* 0..11 */
days = tm->tm_mday - 1; /* 1..31 -> 0..30 */
hours = tm->tm_hour; /* 0..23 */
minutes = tm->tm_min; /* 0..59 */
seconds = tm->tm_sec; /* 0..61 in ANSI C. */
ADJUST_TM(seconds, minutes, 60)
ADJUST_TM(minutes, hours, 60)
ADJUST_TM(hours, days, 24)
ADJUST_TM(months, years, 12)
if (days < 0)
do {
if (--months < 0) {
--years;
months = 11;
}
days += monthlen(months, years);
} while (days < 0);
else
while (days >= monthlen(months, years)) {
days -= monthlen(months, years);
if (++months >= 12) {
++years;
months = 0;
}
}
/* Restore adjusted values in tm structure */
tm->tm_year = years - TM_YEAR_BASE;
tm->tm_mon = months;
tm->tm_mday = days + 1;
tm->tm_hour = hours;
tm->tm_min = minutes;
tm->tm_sec = seconds;
/* Set `days' to the number of days into the year. */
days += YDAYS(months, years);
tm->tm_yday = days;
/* Now calculate `days' to the number of days since Jan 1, 1970. */
days = (unsigned)days + 365 * (unsigned)(years - EPOCH_YEAR) +
(unsigned)(nleap (years));
tm->tm_wday = ((unsigned)days + EPOCH_WDAY) % 7;
tm->tm_isdst = 0;
if (years < EPOCH_YEAR)
return (time_t)-1;
#if (defined(TM_YEAR_MAX) && defined(TM_MON_MAX) && defined(TM_MDAY_MAX))
#if (defined(TM_HOUR_MAX) && defined(TM_MIN_MAX) && defined(TM_SEC_MAX))
if (years > TM_YEAR_MAX ||
(years == TM_YEAR_MAX &&
(tm->tm_yday > (YDAYS(TM_MON_MAX, TM_YEAR_MAX) + (TM_MDAY_MAX - 1)) ||
(tm->tm_yday == (YDAYS(TM_MON_MAX, TM_YEAR_MAX) + (TM_MDAY_MAX - 1)) &&
(hours > TM_HOUR_MAX ||
(hours == TM_HOUR_MAX &&
(minutes > TM_MIN_MAX ||
(minutes == TM_MIN_MAX && seconds > TM_SEC_MAX) )))))))
return (time_t)-1;
#endif
#endif
return (time_t)(SECSPERDAY * (unsigned long)(unsigned)days +
SECSPERHOUR * (unsigned long)hours +
(unsigned long)(SECSPERMIN * minutes + seconds));
}
#endif /* __timezone_c */

84
third_party/zip/timezone.h vendored Normal file
View file

@ -0,0 +1,84 @@
/* clang-format off */
/*
timezone.h - Zip 3
Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2003-May-08 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
*/
#ifndef __timezone_h
#define __timezone_h
#ifndef IZ_MKTIME_ONLY
/* limits for our timezone info data:
* we support only basic standard and daylight time, with max 2 transitions
* per year, but for the maximum range of years a 32-bit second counter
* can cover (these are 136 years plus a bit more than one month)
*/
#define TZ_MAX_TIMES 272 /* (=2*(LastGoodYr + 1 - FirstGoodYr) */
#define TZ_MAX_TYPES 2 /* We only support basic standard and daylight */
#ifdef WIN32 /* Win32 tzinfo supplies at max (2 * 32) chars of tz names */
#define TZ_MAX_CHARS 64 /* Maximum number of abbreviation characters */
#else
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
#endif
/* supported types of transition rules */
#define JULIAN_DAY 0 /* Jn - Julian day */
#define DAY_OF_YEAR 1 /* n - day of year */
#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
struct ttinfo {
long tt_gmtoff; /* UTC offset in seconds */
int tt_isdst; /* used to set tm_isdst */
int tt_abbrind; /* abbreviation list index */
};
struct state {
int timecnt;
int typecnt;
int charcnt;
time_t ats[TZ_MAX_TIMES];
unsigned char types[TZ_MAX_TIMES];
struct ttinfo ttis[TZ_MAX_TYPES];
char chars[TZ_MAX_CHARS];
};
struct rule {
int r_type; /* type of rule--JULIAN_DAY etc */
int r_day; /* day number of rule */
int r_week; /* week number of rule */
int r_mon; /* month number of rule */
long r_time; /* transition time of rule */
};
extern int real_timezone_is_set; /* set by tzset() */
/* prototypes of functions not in time.h */
void __tzset OF((void));
#ifdef NEED__ISINDST
int _isindst OF((struct tm *tb));
#endif
/* callback function to be supplied by the program that uses this library */
int GetPlatformLocalTimezone OF((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)));
#ifdef IZTZ_SETLOCALTZINFO
void set_TZ OF((long time_zone, int day_light));
#endif
#endif /* !IZ_MKTIME_ONLY */
time_t mkgmtime OF((struct tm *tm));
#endif

1475
third_party/zip/trees.c vendored Normal file

File diff suppressed because it is too large Load diff

700
third_party/zip/ttyio.c vendored Normal file
View file

@ -0,0 +1,700 @@
/* clang-format off */
/*
ttyio.c - Zip 3
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2005-Feb-10 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 "third_party/zip/zip.h"
#include "third_party/zip/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 "third_party/zip/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
#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 "libc/calls/termios.h"
#include "libc/sysv/consts/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 "libc/calls/calls.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/f.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) */

115
third_party/zip/ttyio.h vendored Normal file
View file

@ -0,0 +1,115 @@
/* clang-format off */
/*
ttyio.h - Zip 3
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2005-Feb-10 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 "third_party/zip/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 */
/* 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 */

983
third_party/zip/unix.c vendored Normal file
View file

@ -0,0 +1,983 @@
/* clang-format off */
/*
unix/unix.c - Zip 3
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
#include "libc/calls/struct/dirent.h"
#include "third_party/zip/zip.h"
#ifndef UTIL /* the companion #endif is a bit of ways down ... */
#include "libc/time/time.h"
#include "libc/sysv/consts/_posix.h"
#include "libc/calls/struct/stat.macros.h"
#if defined(MINIX) || defined(__mpexl)
# ifdef S_IWRITE
# undef S_IWRITE
# endif /* S_IWRITE */
# define S_IWRITE S_IWUSR
#endif /* MINIX */
#if (!defined(S_IWRITE) && defined(S_IWUSR))
# define S_IWRITE S_IWUSR
#endif
#include "libc/calls/calls.h"
#include "libc/sysv/consts/dt.h"
#define PAD 0
#define PATH_END '/'
/* Library functions not in (most) header files */
extern char *label;
local ulg label_time = 0;
local ulg label_mode = 0;
local time_t label_utim = 0;
/* Local functions */
local char *readd OF((DIR *));
local char *readd(d)
DIR *d; /* directory stream to read from */
/* Return a pointer to the next name in the directory stream d, or NULL if
no more entries or an error occurs. */
{
struct dirent *e;
e = readdir(d);
return e == NULL ? (char *) NULL : e->d_name;
}
int procname(n, caseflag)
char *n; /* name to process */
int caseflag; /* true to force case-sensitive match */
/* Process a name or sh expression to operate on (or exclude). Return
an error code in the ZE_ class. */
{
char *a; /* path and name for recursion */
DIR *d; /* directory stream from opendir() */
char *e; /* pointer to name from readd() */
int m; /* matched flag */
char *p; /* path for recursion */
z_stat s; /* result of stat() */
struct zlist far *z; /* steps through zfiles list */
if (strcmp(n, "-") == 0) /* if compressing stdin */
return newname(n, 0, caseflag);
else if (LSSTAT(n, &s))
{
/* Not a file or directory--search for shell expression in zip file */
p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */
m = 1;
for (z = zfiles; z != NULL; z = z->nxt) {
if (MATCH(p, z->iname, caseflag))
{
z->mark = pcount ? filter(z->zname, caseflag) : 1;
if (verbose)
fprintf(mesg, "zip diagnostic: %scluding %s\n",
z->mark ? "in" : "ex", z->name);
m = 0;
}
}
free((zvoid *)p);
return m ? ZE_MISS : ZE_OK;
}
/* Live name--use if file, recurse if directory */
#ifdef OS390
if (S_ISREG(s.st_mode) || S_ISLNK(s.st_mode))
#else
# ifdef S_IFLNK
if ((s.st_mode & S_IFREG) == S_IFREG || (s.st_mode & S_IFLNK) == S_IFLNK)
# else
if ((s.st_mode & S_IFREG) == S_IFREG)
# endif
#endif
{
/* add or remove name of file */
if ((m = newname(n, 0, caseflag)) != ZE_OK)
return m;
}
#ifdef OS390
else if (S_ISDIR(s.st_mode))
#else
else if ((s.st_mode & S_IFDIR) == S_IFDIR)
#endif
{
/* Add trailing / to the directory name */
if ((p = malloc(strlen(n)+2)) == NULL)
return ZE_MEM;
if (strcmp(n, ".") == 0) {
*p = '\0'; /* avoid "./" prefix and do not create zip entry */
} else {
strcpy(p, n);
a = p + strlen(p);
if (a[-1] != '/')
strcpy(a, "/");
if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) {
free((zvoid *)p);
return m;
}
}
/* recurse into directory */
if (recurse && (d = opendir(n)) != NULL)
{
while ((e = readd(d)) != NULL) {
if (strcmp(e, ".") && strcmp(e, ".."))
{
if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
{
closedir(d);
free((zvoid *)p);
return ZE_MEM;
}
strcat(strcpy(a, p), e);
if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */
{
if (m == ZE_MISS)
zipwarn("name not matched: ", a);
else
ziperr(m, a);
}
free((zvoid *)a);
}
}
closedir(d);
}
free((zvoid *)p);
} /* (s.st_mode & S_IFDIR) */
#ifdef OS390
else if (S_ISFIFO(s.st_mode))
#else
else if ((s.st_mode & S_IFIFO) == S_IFIFO)
#endif
{
if (allow_fifo) {
/* FIFO (Named Pipe) - handle as normal file */
/* add or remove name of FIFO */
/* zip will stop if FIFO is open and wait for pipe to be fed and closed */
if (noisy) zipwarn("Reading FIFO (Named Pipe): ", n);
if ((m = newname(n, 0, caseflag)) != ZE_OK)
return m;
} else {
zipwarn("ignoring FIFO (Named Pipe) - use -FI to read: ", n);
return ZE_OK;
}
} /* S_IFIFO */
else
zipwarn("ignoring special file: ", n);
return ZE_OK;
}
char *ex2in(x, isdir, pdosflag)
char *x; /* external file name */
int isdir; /* input: x is a directory */
int *pdosflag; /* output: force MSDOS file attributes? */
/* Convert the external file name to a zip file name, returning the malloc'ed
string or NULL if not enough memory. */
{
char *n; /* internal file name (malloc'ed) */
char *t = NULL; /* shortened name */
int dosflag;
dosflag = dosify; /* default for non-DOS and non-OS/2 */
/* Find starting point in name before doing malloc */
/* Strip "//host/share/" part of a UNC name */
if (!strncmp(x,"//",2) && (x[2] != '\0' && x[2] != '/')) {
n = x + 2;
while (*n != '\0' && *n != '/')
n++; /* strip host name */
if (*n != '\0') {
n++;
while (*n != '\0' && *n != '/')
n++; /* strip `share' name */
}
if (*n != '\0')
t = n + 1;
} else
t = x;
while (*t == '/')
t++; /* strip leading '/' chars to get a relative path */
while (*t == '.' && t[1] == '/')
t += 2; /* strip redundant leading "./" sections */
/* Make changes, if any, to the copied name (leave original intact) */
if (!pathput)
t = last(t, PATH_END);
/* Malloc space for internal name and copy it */
if ((n = malloc(strlen(t) + 1)) == NULL)
return NULL;
strcpy(n, t);
if (dosify)
msname(n);
#ifdef EBCDIC
strtoasc(n, n); /* here because msname() needs native coding */
#endif
/* Returned malloc'ed name */
if (pdosflag)
*pdosflag = dosflag;
if (isdir) return n; /* avoid warning on unused variable */
return n;
}
char *in2ex(n)
char *n; /* internal file name */
/* Convert the zip file name to an external file name, returning the malloc'ed
string or NULL if not enough memory. */
{
char *x; /* external file name */
if ((x = malloc(strlen(n) + 1 + PAD)) == NULL)
return NULL;
#ifdef EBCDIC
strtoebc(x, n);
#else
strcpy(x, n);
#endif
return x;
}
/*
* XXX use ztimbuf in both POSIX and non POSIX cases ?
*/
void stamp(f, d)
char *f; /* name of file to change */
ulg d; /* dos-style time to change it to */
/* Set last updated and accessed time of file f to the DOS time d. */
{
#ifdef _POSIX_VERSION
struct utimbuf u; /* argument for utime() const ?? */
#else
time_t u[2]; /* argument for utime() */
#endif
/* Convert DOS time to time_t format in u */
#ifdef _POSIX_VERSION
u.actime = u.modtime = dos2unixtime(d);
utime(f, &u);
#else
u[0] = u[1] = dos2unixtime(d);
utime(f, u);
#endif
}
ulg filetime(f, a, n, t)
char *f; /* name of file to get info on */
ulg *a; /* return value: file attributes */
zoff_t *n; /* return value: file size */
iztimes *t; /* return value: access, modific. and creation times */
/* If file *f does not exist, return 0. Else, return the file's last
modified date and time as an MSDOS date and time. The date and
time is returned in a long with the date most significant to allow
unsigned integer comparison of absolute times. Also, if a is not
a NULL pointer, store the file attributes there, with the high two
bytes being the Unix attributes, and the low byte being a mapping
of that to DOS attributes. If n is not NULL, store the file size
there. If t is not NULL, the file's access, modification and creation
times are stored there as UNIX time_t values.
If f is "-", use standard input as the file. If f is a device, return
a file size of -1 */
{
z_stat s; /* results of stat() */
/* converted to pointer from using FNMAX - 11/8/04 EG */
char *name;
int len = strlen(f);
if (f == label) {
if (a != NULL)
*a = label_mode;
if (n != NULL)
*n = -2L; /* convention for a label name */
if (t != NULL)
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
strcpy(name, f);
if (name[len - 1] == '/')
name[len - 1] = '\0';
/* not all systems allow stat'ing a file with / appended */
if (strcmp(f, "-") == 0) {
if (zfstat(fileno(stdin), &s) != 0) {
free(name);
error("fstat(stdin)");
}
}
else if (LSSTAT(name, &s) != 0) {
/* Accept about any file kind including directories
* (stored with trailing / with -r option)
*/
free(name);
return 0;
}
free(name);
if (a != NULL) {
#ifndef OS390
*a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
#else
/*
** The following defines are copied from the unizip source and represent the
** legacy Unix mode flags. These fixed bit masks are no longer required
** by XOPEN standards - the S_IS### macros being the new recommended method.
** The approach here of setting the legacy flags by testing the macros should
** work under any _XOPEN_SOURCE environment (and will just rebuild the same bit
** mask), but is required if the legacy bit flags differ from legacy Unix.
*/
#define UNX_IFDIR 0040000 /* Unix directory */
#define UNX_IFREG 0100000 /* Unix regular file */
#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */
#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */
#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */
#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */
#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */
{
mode_t legacy_modes;
/* Initialize with permission bits--which are not implementation-optional */
legacy_modes = s.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
if (S_ISDIR(s.st_mode))
legacy_modes |= UNX_IFDIR;
if (S_ISREG(s.st_mode))
legacy_modes |= UNX_IFREG;
if (S_ISLNK(s.st_mode))
legacy_modes |= UNX_IFLNK;
if (S_ISBLK(s.st_mode))
legacy_modes |= UNX_IFBLK;
if (S_ISCHR(s.st_mode))
legacy_modes |= UNX_IFCHR;
if (S_ISFIFO(s.st_mode))
legacy_modes |= UNX_IFIFO;
if (S_ISSOCK(s.st_mode))
legacy_modes |= UNX_IFSOCK;
*a = ((ulg)legacy_modes << 16) | !(s.st_mode & S_IWRITE);
}
#endif
if ((s.st_mode & S_IFMT) == S_IFDIR) {
*a |= MSDOS_DIR_ATTR;
}
}
if (n != NULL)
*n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;
if (t != NULL) {
t->atime = s.st_atime;
t->mtime = s.st_mtime;
t->ctime = t->mtime; /* best guess, (s.st_ctime: last status change!!) */
}
return unix2dostime(&s.st_mtime);
}
#ifndef QLZIP /* QLZIP Unix2QDOS cross-Zip supplies an extended variant */
int set_new_unix_extra_field(z, s)
struct zlist far *z;
z_stat *s;
/* New unix extra field.
Currently only UIDs and GIDs are stored. */
{
int uid_size;
int gid_size;
int ef_data_size;
char *extra;
char *cextra;
ulg id;
int b;
uid_size = sizeof(s->st_uid);
gid_size = sizeof(s->st_gid);
/* New extra field
tag (2 bytes)
size (2 bytes)
version (1 byte)
uid_size (1 byte - size in bytes)
uid (variable)
gid_size (1 byte - size in bytes)
gid (variable)
*/
ef_data_size = 1 + 1 + uid_size + 1 + gid_size;
if ((extra = (char *)malloc(z->ext + 4 + ef_data_size)) == NULL)
return ZE_MEM;
if ((cextra = (char *)malloc(z->ext + 4 + ef_data_size)) == NULL)
return ZE_MEM;
if (z->ext)
memcpy(extra, z->extra, z->ext);
if (z->cext)
memcpy(cextra, z->cextra, z->cext);
free(z->extra);
z->extra = extra;
free(z->cextra);
z->cextra = cextra;
z->extra[z->ext + 0] = 'u';
z->extra[z->ext + 1] = 'x';
z->extra[z->ext + 2] = (char)ef_data_size; /* length of data part */
z->extra[z->ext + 3] = 0;
z->extra[z->ext + 4] = 1; /* version */
/* UID */
z->extra[z->ext + 5] = (char)(uid_size); /* uid size in bytes */
b = 6;
id = (ulg)(s->st_uid);
z->extra[z->ext + b] = (char)(id & 0xFF);
if (uid_size > 1) {
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
if (uid_size > 2) {
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
if (uid_size == 8) {
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
}
}
}
/* GID */
b++;
z->extra[z->ext + b] = (char)(gid_size); /* gid size in bytes */
b++;
id = (ulg)(s->st_gid);
z->extra[z->ext + b] = (char)(id & 0xFF);
if (gid_size > 1) {
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
if (gid_size > 2) {
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
if (gid_size == 8) {
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
b++;
id = id >> 8;
z->extra[z->ext + b] = (char)(id & 0xFF);
}
}
}
/* copy local extra field to central directory extra field */
memcpy((z->cextra) + z->cext, (z->extra) + z->ext, 4 + ef_data_size);
z->ext = z->ext + 4 + ef_data_size;
z->cext = z->cext + 4 + ef_data_size;
return ZE_OK;
}
int set_extra_field(z, z_utim)
struct zlist far *z;
iztimes *z_utim;
/* store full data in local header but just modification time stamp info
in central header */
{
z_stat s;
char *name;
int len = strlen(z->name);
/* For the full sized UT local field including the UID/GID fields, we
* have to stat the file again. */
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "set_extra_field");
}
strcpy(name, z->name);
if (name[len - 1] == '/')
name[len - 1] = '\0';
/* not all systems allow stat'ing a file with / appended */
if (LSSTAT(name, &s)) {
free(name);
return ZE_OPEN;
}
free(name);
#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2))
#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1))
/* The flag UIDGID_NOT_16BIT should be set by the pre-compile configuration
script when it detects st_uid or st_gid sizes differing from 16-bit.
*/
#ifndef UIDGID_NOT_16BIT
/* The following "second-level" check for st_uid and st_gid members being
16-bit wide is only added as a safety precaution in case the "first-level"
check failed to define the UIDGID_NOT_16BIT symbol.
The first-level check should have been implemented in the automatic
compile configuration process.
*/
# ifdef UIDGID_ARE_16B
# undef UIDGID_ARE_16B
# endif
/* The following expression is a compile-time constant and should (hopefully)
get optimized away by any sufficiently intelligent compiler!
*/
# define UIDGID_ARE_16B (sizeof(s.st_uid) == 2 && sizeof(s.st_gid) == 2)
# define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN)
# define EB_C_UX2_SIZE EB_HEADSIZE
# define EF_L_UNIX_SIZE (EB_L_UT_SIZE + (UIDGID_ARE_16B ? EB_L_UX2_SIZE : 0))
# define EF_C_UNIX_SIZE (EB_C_UT_SIZE + (UIDGID_ARE_16B ? EB_C_UX2_SIZE : 0))
#else
# define EF_L_UNIX_SIZE EB_L_UT_SIZE
# define EF_C_UNIX_SIZE EB_C_UT_SIZE
#endif /* !UIDGID_NOT_16BIT */
if ((z->extra = (char *)malloc(EF_L_UNIX_SIZE)) == NULL)
return ZE_MEM;
if ((z->cextra = (char *)malloc(EF_C_UNIX_SIZE)) == NULL)
return ZE_MEM;
z->extra[0] = 'U';
z->extra[1] = 'T';
z->extra[2] = (char)EB_UT_LEN(2); /* length of data part of local e.f. */
z->extra[3] = 0;
z->extra[4] = EB_UT_FL_MTIME | EB_UT_FL_ATIME; /* st_ctime != creation */
z->extra[5] = (char)(s.st_mtime);
z->extra[6] = (char)(s.st_mtime >> 8);
z->extra[7] = (char)(s.st_mtime >> 16);
z->extra[8] = (char)(s.st_mtime >> 24);
z->extra[9] = (char)(s.st_atime);
z->extra[10] = (char)(s.st_atime >> 8);
z->extra[11] = (char)(s.st_atime >> 16);
z->extra[12] = (char)(s.st_atime >> 24);
#ifndef UIDGID_NOT_16BIT
/* Only store the UID and GID in the old Ux extra field if the runtime
system provides them in 16-bit wide variables. */
if (UIDGID_ARE_16B) {
z->extra[13] = 'U';
z->extra[14] = 'x';
z->extra[15] = (char)EB_UX2_MINLEN; /* length of data part of local e.f. */
z->extra[16] = 0;
z->extra[17] = (char)(s.st_uid);
z->extra[18] = (char)(s.st_uid >> 8);
z->extra[19] = (char)(s.st_gid);
z->extra[20] = (char)(s.st_gid >> 8);
}
#endif /* !UIDGID_NOT_16BIT */
z->ext = EF_L_UNIX_SIZE;
memcpy(z->cextra, z->extra, EB_C_UT_SIZE);
z->cextra[EB_LEN] = (char)EB_UT_LEN(1);
#ifndef UIDGID_NOT_16BIT
if (UIDGID_ARE_16B) {
/* Copy header of Ux extra field from local to central */
memcpy(z->cextra+EB_C_UT_SIZE, z->extra+EB_L_UT_SIZE, EB_C_UX2_SIZE);
z->cextra[EB_LEN+EB_C_UT_SIZE] = 0;
}
#endif
z->cext = EF_C_UNIX_SIZE;
#if 0 /* UID/GID presence is now signaled by central EF_IZUNIX2 field ! */
/* lower-middle external-attribute byte (unused until now):
* high bit => (have GMT mod/acc times) >>> NO LONGER USED! <<<
* second-high bit => have Unix UID/GID info
* NOTE: The high bit was NEVER used in any official Info-ZIP release,
* but its future use should be avoided (if possible), since it
* was used as "GMT mod/acc times local extra field" flags in Zip beta
* versions 2.0j up to 2.0v, for about 1.5 years.
*/
z->atx |= 0x4000;
#endif /* never */
/* new unix extra field */
set_new_unix_extra_field(z, &s);
return ZE_OK;
}
#endif /* !QLZIP */
int deletedir(d)
char *d; /* directory to delete */
/* Delete the directory *d if it is empty, do nothing otherwise.
Return the result of rmdir(), delete(), or system().
For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]).
*/
{
# ifdef NO_RMDIR
/* code from Greg Roelofs, who horked it from Mark Edwards (unzip) */
int r, len;
char *s; /* malloc'd string for system command */
len = strlen(d);
if ((s = malloc(len + 34)) == NULL)
return 127;
sprintf(s, "IFS=\" \t\n\" /bin/rmdir %s 2>/dev/null", d);
r = system(s);
free(s);
return r;
# else /* !NO_RMDIR */
return rmdir(d);
# endif /* ?NO_RMDIR */
}
#endif /* !UTIL */
/******************************/
/* Function version_local() */
/******************************/
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__386BSD__) || \
defined(__OpenBSD__) || defined(__bsdi__)
/* if we have something newer than NET/2 we'll use uname(3) */
#if (BSD > 199103)
#include "libc/calls/calls.h"
#endif /* BSD > 199103 */
#endif /* __{Net,Free,Open,386}BSD__ || __bsdi__ */
void version_local()
{
#ifdef __GNUC__
# ifdef NX_CURRENT_COMPILER_RELEASE
char compiler_name[80];
# endif
#else
# if (defined( __SUNPRO_C))
char compiler_name[33];
# else
# if (defined( __HP_cc) || defined( __IBMC__))
char compiler_name[33];
# else
# if (defined( __DECC_VER))
char compiler_name[33];
int compiler_typ;
# else
# if ((defined(CRAY) || defined(cray)) && defined(_RELEASE))
char compiler_name[40];
# endif
# endif
# endif
# endif
#endif
#ifdef BSD
# if (BSD > 199103)
struct utsname u;
char os_name[40];
# else
# if defined(__NETBSD__))
static ZCONST char *netbsd[] = { "_ALPHA", "", "A", "B" };
char os_name[40];
# endif /* __NETBSD__ */
# endif /* BSD > 199103 */
#else /* !BSD */
#if ((defined(CRAY) || defined(cray)) && defined(_UNICOS))
char os_name[40];
#endif /* (CRAY && defined(_UNICOS)) */
#endif /* ?BSD */
/* Define the compiler name and version string */
#ifdef __GNUC__
# ifdef NX_CURRENT_COMPILER_RELEASE
sprintf(compiler_name, "NeXT DevKit %d.%02d (gcc " __VERSION__ ")",
NX_CURRENT_COMPILER_RELEASE/100, NX_CURRENT_COMPILER_RELEASE%100);
# define COMPILER_NAME compiler_name
# else
# define COMPILER_NAME "gcc " __VERSION__
# endif
#else /* !__GNUC__ */
# if defined(__SUNPRO_C)
sprintf( compiler_name, "Sun C version %x", __SUNPRO_C);
# define COMPILER_NAME compiler_name
# else
# if (defined( __HP_cc))
if ((__HP_cc% 100) == 0)
{
sprintf( compiler_name, "HP C version A.%02d.%02d",
(__HP_cc/ 10000), ((__HP_cc% 10000)/ 100));
}
else
{
sprintf( compiler_name, "HP C version A.%02d.%02d.%02d",
(__HP_cc/ 10000), ((__HP_cc% 10000)/ 100), (__HP_cc% 100));
}
# define COMPILER_NAME compiler_name
# else
# if (defined( __DECC_VER))
sprintf( compiler_name, "DEC C version %c%d.%d-%03d",
((compiler_typ = (__DECC_VER / 10000) % 10) == 6 ? 'T' :
(compiler_typ == 8 ? 'S' : 'V')),
__DECC_VER / 10000000,
(__DECC_VER % 10000000) / 100000, __DECC_VER % 1000);
# define COMPILER_NAME compiler_name
# else
# if ((defined(CRAY) || defined(cray)) && defined(_RELEASE))
sprintf(compiler_name, "cc version %d", _RELEASE);
# define COMPILER_NAME compiler_name
# else
# ifdef __IBMC__
sprintf( compiler_name, "IBM C version %d.%d.%d",
(__IBMC__/ 100), ((__IBMC__/ 10)% 10), (__IBMC__% 10));
# define COMPILER_NAME compiler_name
# else
# ifdef __VERSION__
# define COMPILER_NAME "cc " __VERSION__
# else
# define COMPILER_NAME "cc "
# endif
# endif
# endif
# endif
# endif
# endif
#endif /* ?__GNUC__ */
/* Define the name to use for the OS we're compiling on */
#if defined(sgi) || defined(__sgi)
# define OS_NAME "Silicon Graphics IRIX"
#else
#ifdef sun
# ifdef sparc
# ifdef __SVR4
# define OS_NAME "Sun SPARC/Solaris"
# else /* may or may not be SunOS */
# define OS_NAME "Sun SPARC"
# endif
# else
# if defined(sun386) || defined(i386)
# define OS_NAME "Sun 386i"
# else
# if defined(mc68020) || defined(__mc68020__)
# define OS_NAME "Sun 3"
# else /* mc68010 or mc68000: Sun 2 or earlier */
# define OS_NAME "Sun 2"
# endif
# endif
# endif
#else
#ifdef __hpux
# define OS_NAME "HP-UX"
#else
#ifdef __osf__
# define OS_NAME "DEC OSF/1"
#else
#ifdef _AIX
# define OS_NAME "IBM AIX"
#else
#ifdef aiws
# define OS_NAME "IBM RT/AIX"
#else
#if defined(CRAY) || defined(cray)
# ifdef _UNICOS
sprintf(os_name, "Cray UNICOS release %d", _UNICOS);
# define OS_NAME os_name
# else
# define OS_NAME "Cray UNICOS"
# endif
#else
#if defined(uts) || defined(UTS)
# define OS_NAME "Amdahl UTS"
#else
#ifdef NeXT
# ifdef mc68000
# define OS_NAME "NeXTStep/black"
# else
# define OS_NAME "NeXTStep for Intel"
# endif
#else
#if defined(linux) || defined(__linux__)
# ifdef __ELF__
# define OS_NAME "Linux ELF"
# else
# define OS_NAME "Linux a.out"
# endif
#else
#ifdef MINIX
# define OS_NAME "Minix"
#else
#ifdef M_UNIX
# define OS_NAME "SCO Unix"
#else
#ifdef M_XENIX
# define OS_NAME "SCO Xenix"
#else
#ifdef BSD
# if (BSD > 199103)
# define OS_NAME os_name
uname(&u);
sprintf(os_name, "%s %s", u.sysname, u.release);
# else
# ifdef __NetBSD__
# define OS_NAME os_name
# ifdef NetBSD0_8
sprintf(os_name, "NetBSD 0.8%s", netbsd[NetBSD0_8]);
# else
# ifdef NetBSD0_9
sprintf(os_name, "NetBSD 0.9%s", netbsd[NetBSD0_9]);
# else
# ifdef NetBSD1_0
sprintf(os_name, "NetBSD 1.0%s", netbsd[NetBSD1_0]);
# endif /* NetBSD1_0 */
# endif /* NetBSD0_9 */
# endif /* NetBSD0_8 */
# else
# ifdef __FreeBSD__
# define OS_NAME "FreeBSD 1.x"
# else
# ifdef __bsdi__
# define OS_NAME "BSD/386 1.0"
# else
# ifdef __386BSD__
# define OS_NAME "386BSD"
# else
# define OS_NAME "Unknown BSD"
# endif /* __386BSD__ */
# endif /* __bsdi__ */
# endif /* FreeBSD */
# endif /* NetBSD */
# endif /* BSD > 199103 */
#else
#ifdef __CYGWIN__
# define OS_NAME "Cygwin"
#else
#if defined(i686) || defined(__i686) || defined(__i686__)
# define OS_NAME "Intel 686"
#else
#if defined(i586) || defined(__i586) || defined(__i586__)
# define OS_NAME "Intel 586"
#else
#if defined(i486) || defined(__i486) || defined(__i486__)
# define OS_NAME "Intel 486"
#else
#if defined(i386) || defined(__i386) || defined(__i386__)
# define OS_NAME "Intel 386"
#else
#ifdef pyr
# define OS_NAME "Pyramid"
#else
#if defined(ultrix) || defined(__ultrix)
# if defined(mips) || defined(__mips)
# define OS_NAME "DEC/MIPS"
# else
# if defined(vax) || defined(__vax)
# define OS_NAME "DEC/VAX"
# else /* __alpha? */
# define OS_NAME "DEC/Alpha"
# endif
# endif
#else
#ifdef gould
# define OS_NAME "Gould"
#else
#ifdef MTS
# define OS_NAME "MTS"
#else
#ifdef __convexc__
# define OS_NAME "Convex"
#else
#ifdef __QNX__
# define OS_NAME "QNX 4"
#else
#ifdef __QNXNTO__
# define OS_NAME "QNX Neutrino"
#else
#ifdef __APPLE__
# ifdef __i386__
# define OS_NAME "Mac OS X Intel"
# else /* __i386__ */
# ifdef __ppc__
# define OS_NAME "Mac OS X PowerPC"
# else /* __ppc__ */
# ifdef __ppc64__
# define OS_NAME "Mac OS X PowerPC64"
# else /* __ppc64__ */
# define OS_NAME "Mac OS X"
# endif /* __ppc64__ */
# endif /* __ppc__ */
# endif /* __i386__ */
#else
# define OS_NAME "Unknown"
#endif /* Apple */
#endif /* QNX Neutrino */
#endif /* QNX 4 */
#endif /* Convex */
#endif /* MTS */
#endif /* Gould */
#endif /* DEC */
#endif /* Pyramid */
#endif /* 386 */
#endif /* 486 */
#endif /* 586 */
#endif /* 686 */
#endif /* Cygwin */
#endif /* BSD */
#endif /* SCO Xenix */
#endif /* SCO Unix */
#endif /* Minix */
#endif /* Linux */
#endif /* NeXT */
#endif /* Amdahl */
#endif /* Cray */
#endif /* RT/AIX */
#endif /* AIX */
#endif /* OSF/1 */
#endif /* HP-UX */
#endif /* Sun */
#endif /* SGI */
/* Define the compile date string */
#ifdef __DATE__
# define COMPILE_DATE " on " __DATE__
#else
# define COMPILE_DATE ""
#endif
printf("Compiled with %s for Unix (%s)%s.\n\n",
COMPILER_NAME, OS_NAME, COMPILE_DATE);
} /* end function version_local() */

1375
third_party/zip/util.c vendored Normal file

File diff suppressed because it is too large Load diff

50
third_party/zip/zbz2err.c vendored Normal file
View file

@ -0,0 +1,50 @@
/* clang-format off */
/*
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
/*---------------------------------------------------------------------------
zbz2err.c
This file contains the "fatal error" callback routine required by the
"minimal" (silent, non-stdio) setup of the bzip2 compression library.
The fatal bzip2 error bail-out routine is provided in a separate code
module, so that it can be easily overridden when the Zip package is
used as a static link library. One example is the WinDLL static library
usage for building a monolithic binary of the Windows application "WiZ"
that supports bzip2 both in compression and decompression operations.
Contains: bz_internal_error() (BZIP2_SUPPORT only)
Adapted from UnZip ubz2err.c, with all the DLL fine print stripped
out.
---------------------------------------------------------------------------*/
#define __ZBZ2ERR_C /* identifies this source module */
#include "libc/fmt/fmt.h"
#include "third_party/zip/zip.h"
#include "third_party/bzip2/bzlib.h"
/**********************************/
/* Function bz_internal_error() */
/**********************************/
/* Call-back function for the bzip2 decompression code (compiled with
* BZ_NO_STDIO), required to handle fatal internal bug-type errors of
* the bzip2 library.
*/
void bz_internal_error(errcode)
int errcode;
{
sprintf(errbuf, "fatal error (code %d) in bzip2 library", errcode);
ziperr(ZE_LOGIC, errbuf);
} /* end function bz_internal_error() */

5985
third_party/zip/zip.c vendored Normal file

File diff suppressed because it is too large Load diff

1078
third_party/zip/zip.h vendored Normal file

File diff suppressed because it is too large Load diff

189
third_party/zip/zip.mk vendored Normal file
View file

@ -0,0 +1,189 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += THIRD_PARTY_ZIP
THIRD_PARTY_ZIP_FILES := $(wildcard third_party/zip/*)
THIRD_PARTY_ZIP_SRCS = $(filter %.c,$(THIRD_PARTY_ZIP_FILES))
THIRD_PARTY_ZIP_HDRS = $(filter %.h,$(THIRD_PARTY_ZIP_FILES))
THIRD_PARTY_ZIP_INCS = $(filter %.inc,$(THIRD_PARTY_ZIP_FILES))
THIRD_PARTY_ZIP_COMS = \
o/$(MODE)/third_party/zip/zip.com \
o/$(MODE)/third_party/zip/zipsplit.com \
o/$(MODE)/third_party/zip/zipnote.com \
o/$(MODE)/third_party/zip/zipcloak.com
THIRD_PARTY_ZIP_BINS = \
$(THIRD_PARTY_ZIP_COMS) \
$(THIRD_PARTY_ZIP_COMS:%=%.dbg)
THIRD_PARTY_ZIP_CHECKS = \
o/$(MODE)/third_party/zip/zip.pkg
THIRD_PARTY_ZIP_OBJS = $(sort \
$(THIRD_PARTY_ZIP_ZIP_OBJS) \
$(THIRD_PARTY_ZIPCLOAK_OBJS) \
$(THIRD_PARTY_ZIPNOTE_OBJS) \
$(THIRD_PARTY_ZIPSPLIT_OBJS) \
)
THIRD_PARTY_ZIP_UTIL_OBJS1 = \
o/$(MODE)/third_party/zip/globals.o \
o/$(MODE)/third_party/zip/unix_.o \
o/$(MODE)/third_party/zip/zipfile_.o \
o/$(MODE)/third_party/zip/fileio_.o \
o/$(MODE)/third_party/zip/util_.o
THIRD_PARTY_ZIP_UTIL_OBJS2 = \
o/$(MODE)/third_party/zip/crypt_.o
THIRD_PARTY_ZIP_UTIL_OBJS = \
$(THIRD_PARTY_ZIP_UTIL_OBJS1) \
$(THIRD_PARTY_ZIP_UTIL_OBJS2)
THIRD_PARTY_ZIP_ZIP_OBJS = \
o/$(MODE)/third_party/zip/zip.o \
o/$(MODE)/third_party/zip/zipfile.o \
o/$(MODE)/third_party/zip/zipup.o \
o/$(MODE)/third_party/zip/fileio.o \
o/$(MODE)/third_party/zip/util.o \
o/$(MODE)/third_party/zip/globals.o \
o/$(MODE)/third_party/zip/crypt.o \
o/$(MODE)/third_party/zip/ttyio.o \
o/$(MODE)/third_party/zip/unix.o \
o/$(MODE)/third_party/zip/crc32.o \
o/$(MODE)/third_party/zip/zbz2err.o \
o/$(MODE)/third_party/zip/deflate.o \
o/$(MODE)/third_party/zip/trees.o
THIRD_PARTY_ZIPSPLIT_OBJS = \
o/$(MODE)/third_party/zip/zipsplit.o \
$(THIRD_PARTY_ZIP_UTIL_OBJS1)
THIRD_PARTY_ZIPNOTE_OBJS = \
o/$(MODE)/third_party/zip/zipnote.o \
$(THIRD_PARTY_ZIP_UTIL_OBJS1)
THIRD_PARTY_ZIPCLOAK_OBJS = \
o/$(MODE)/third_party/zip/zipcloak.o \
o/$(MODE)/third_party/zip/crc32.o \
o/$(MODE)/third_party/zip/ttyio.o \
$(THIRD_PARTY_ZIP_UTIL_OBJS1) \
$(THIRD_PARTY_ZIP_UTIL_OBJS2)
THIRD_PARTY_ZIP_LARGE_OBJS = \
o/$(MODE)/third_party/zip/zip.o \
o/$(MODE)/third_party/zip/zipsplit.o \
o/$(MODE)/third_party/zip/fileio.o \
o/$(MODE)/third_party/zip/fileio_.o
THIRD_PARTY_ZIP_DIRECTDEPS = \
LIBC_CALLS \
LIBC_FMT \
LIBC_INTRIN \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RAND \
LIBC_RUNTIME \
LIBC_STDIO \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TIME \
LIBC_UNICODE \
THIRD_PARTY_BZIP2
THIRD_PARTY_ZIP_DEPS := \
$(call uniq,$(foreach x,$(THIRD_PARTY_ZIP_DIRECTDEPS),$($(x))))
o/$(MODE)/third_party/zip/zip.pkg: \
$(THIRD_PARTY_ZIP_ZIP_OBJS) \
$(foreach x,$(THIRD_PARTY_ZIP_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/third_party/zip/zip.com.dbg: \
$(THIRD_PARTY_ZIP_DEPS) \
$(THIRD_PARTY_ZIP_ZIP_OBJS) \
$(CRT) \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/third_party/zip/zipsplit.com.dbg: \
$(THIRD_PARTY_ZIP_DEPS) \
$(THIRD_PARTY_ZIPSPLIT_OBJS) \
$(CRT) \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/third_party/zip/zipnote.com.dbg: \
$(THIRD_PARTY_ZIP_DEPS) \
$(THIRD_PARTY_ZIPNOTE_OBJS) \
$(CRT) \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/third_party/zip/zipcloak.com.dbg: \
$(THIRD_PARTY_ZIP_DEPS) \
$(THIRD_PARTY_ZIPCLOAK_OBJS) \
$(CRT) \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/third_party/zip/crypt.o \
o/$(MODE)/third_party/zip/crypt_.o \
o/$(MODE)/third_party/zip/fileio.o \
o/$(MODE)/third_party/zip/fileio_.o \
o/$(MODE)/third_party/zip/globals.o \
o/$(MODE)/third_party/zip/timezone.o \
o/$(MODE)/third_party/zip/ttyio.o \
o/$(MODE)/third_party/zip/unix.o \
o/$(MODE)/third_party/zip/unix_.o \
o/$(MODE)/third_party/zip/util.o \
o/$(MODE)/third_party/zip/util_.o \
o/$(MODE)/third_party/zip/zbz2err.o \
o/$(MODE)/third_party/zip/zip.o \
o/$(MODE)/third_party/zip/crc32.o \
o/$(MODE)/third_party/zip/trees.o \
o/$(MODE)/third_party/zip/deflate.o \
o/$(MODE)/third_party/zip/zipcloak.o \
o/$(MODE)/third_party/zip/zipfile.o \
o/$(MODE)/third_party/zip/zipfile_.o \
o/$(MODE)/third_party/zip/zipnote.o \
o/$(MODE)/third_party/zip/zipsplit.o \
o/$(MODE)/third_party/zip/zipup.o: \
OVERRIDE_CPPFLAGS += \
-DUNIX \
-DMMAP \
-DUNICODE_SUPPORT \
-DUSE_EF_UT_TIME \
-DLARGE_FILE_SUPPORT \
-DHAVE_DIRENT_H \
-DHAVE_TERMIOS_H \
-DZIP64_SUPPORT \
-DBZIP2_SUPPORT
o/$(MODE)/third_party/zip/crypt_.o \
o/$(MODE)/third_party/zip/unix_.o \
o/$(MODE)/third_party/zip/zipfile_.o \
o/$(MODE)/third_party/zip/fileio_.o \
o/$(MODE)/third_party/zip/util_.o: \
OVERRIDE_CPPFLAGS += \
-DUTIL
o/$(MODE)/third_party/zip/zip.o \
o/$(MODE)/third_party/zip/zipsplit.o \
o/$(MODE)/third_party/zip/fileio.o \
o/$(MODE)/third_party/zip/fileio_.o: \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
o/$(MODE)/third_party/zip/%_.o: \
third_party/zip/%.c \
o/$(MODE)/third_party/zip/%.o
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
.PHONY: o/$(MODE)/third_party/zip
o/$(MODE)/third_party/zip: \
$(THIRD_PARTY_ZIP_BINS) \
$(THIRD_PARTY_ZIP_CHECKS)

776
third_party/zip/zipcloak.c vendored Normal file
View file

@ -0,0 +1,776 @@
/* clang-format off */
/*
zipcloak.c - Zip 3
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
/*
This code was originally written in Europe and could be freely distributed
from any country except the U.S.A. If this code was imported into the U.S.A,
it could not be re-exported from the U.S.A to another country. (This
restriction might seem curious but this is what US law required.)
Now this code can be freely exported and imported. See README.CR.
*/
#define __ZIPCLOAK_C
#ifndef UTIL
# define UTIL
#endif
#include "third_party/zip/zip.h"
#define DEFCPYRT /* main module: enable copyright string defines! */
#include "third_party/zip/revision.h"
#include "third_party/zip/crc32.h"
#include "third_party/zip/crypt.h"
#include "third_party/zip/ttyio.h"
#include "libc/calls/calls.h"
#include "libc/log/log.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/sysv/consts/sig.h"
#include "libc/stdio/temp.h"
#ifndef NO_STDLIB_H
#include "libc/mem/mem.h"
#endif
#if CRYPT /* defined (as TRUE or FALSE) in crypt.h */
int main OF((int argc, char **argv));
local void handler OF((int sig));
local void license OF((void));
local void help OF((void));
local void version_info OF((void));
/* Temporary zip file pointer */
local FILE *tempzf;
/* Pointer to CRC-32 table (used for decryption/encryption) */
#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
ZCONST ulg near *crc_32_tab;
#else
ZCONST uLongf *crc_32_tab;
#endif
int set_filetype(out_path)
char *out_path;
{
#ifdef __BEOS__
/* Set the filetype of the zipfile to "application/zip" */
setfiletype( out_path, "application/zip" );
#endif
#ifdef __ATHEOS__
/* Set the filetype of the zipfile to "application/x-zip" */
setfiletype(out_path, "application/x-zip");
#endif
#ifdef MACOS
/* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
setfiletype(out_path, 'IZip', 'ZIP ');
#endif
#ifdef RISCOS
/* Set the filetype of the zipfile to &DDC */
setfiletype(out_path, 0xDDC);
#endif
return ZE_OK;
}
/* rename a split
* A split has a tempfile name until it is closed, then
* here rename it as out_path the final name for the split.
*/
int rename_split(temp_name, out_path)
char *temp_name;
char *out_path;
{
int r;
/* Replace old zip file with new zip file, leaving only the new one */
if ((r = replace(out_path, temp_name)) != ZE_OK)
{
zipwarn("new zip file left as: ", temp_name);
free((zvoid *)tempzip);
tempzip = NULL;
ZIPERR(r, "was replacing split file");
}
if (zip_attributes) {
setfileattr(out_path, zip_attributes);
}
return ZE_OK;
}
void zipmessage_nl(a, nl)
ZCONST char *a; /* message string to output */
int nl; /* 1 = add nl to end */
/* If nl false, print a message to mesg without new line.
If nl true, print and add new line. */
{
if (noisy) {
fprintf(mesg, "%s", a);
if (nl) {
fprintf(mesg, "\n");
mesg_line_started = 0;
} else {
mesg_line_started = 1;
}
fflush(mesg);
}
}
void zipmessage(a, b)
ZCONST char *a, *b; /* message strings juxtaposed in output */
/* Print a message to mesg and flush. Write new line first
if current line has output already. */
{
if (noisy) {
if (mesg_line_started)
fprintf(mesg, "\n");
fprintf(mesg, "%s%s\n", a, b);
mesg_line_started = 0;
fflush(mesg);
}
}
/***********************************************************************
* Issue a message for the error, clean up files and memory, and exit.
*/
void ziperr(code, msg)
int code; /* error code from the ZE_ class */
ZCONST char *msg; /* message about how it happened */
{
if (PERR(code)) perror("zipcloak error");
fprintf(mesg, "zipcloak error: %s (%s)\n", ZIPERRORS(code), msg);
if (tempzf != NULL) fclose(tempzf);
if (tempzip != NULL) {
destroy(tempzip);
free((zvoid *)tempzip);
}
if (zipfile != NULL) free((zvoid *)zipfile);
EXIT(code);
}
/***********************************************************************
* Print a warning message to mesg (usually stderr) and return.
*/
void zipwarn(msg1, msg2)
ZCONST char *msg1, *msg2; /* message strings juxtaposed in output */
{
fprintf(mesg, "zipcloak warning: %s%s\n", msg1, msg2);
}
/***********************************************************************
* Upon getting a user interrupt, turn echo back on for tty and abort
* cleanly using ziperr().
*/
local void handler(sig)
int sig; /* signal number (ignored) */
{
#if (!defined(MSDOS) && !defined(__human68k__) && !defined(RISCOS))
echon();
putc('\n', mesg);
#endif
ziperr(ZE_ABORT +sig-sig, "aborting");
/* dummy usage of sig to avoid compiler warnings */
}
static ZCONST char *public[] = {
"The encryption code of this program is not copyrighted and is",
"put in the public domain. It was originally written in Europe",
"and can be freely distributed in both source and object forms",
"from any country, including the USA under License Exception",
"TSU of the U.S. Export Administration Regulations (section",
"740.13(e)) of 6 June 2002. (Prior to January 2000, re-export",
"from the US was a violation of US law.)"
};
/***********************************************************************
* Print license information to stdout.
*/
local void license()
{
extent i; /* counter for copyright array */
for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++) {
puts(swlicense[i]);
}
putchar('\n');
printf("Export notice:\n");
for (i = 0; i < sizeof(public)/sizeof(char *); i++) {
puts(public[i]);
}
}
static ZCONST char *help_info[] = {
"",
"ZipCloak %s (%s)",
#ifdef VM_CMS
"Usage: zipcloak [-dq] [-b fm] zipfile",
#else
"Usage: zipcloak [-dq] [-b path] zipfile",
#endif
" the default action is to encrypt all unencrypted entries in the zip file",
"",
" -d --decrypt decrypt encrypted entries (copy if given wrong password)",
#ifdef VM_CMS
" -b --temp-mode use \"fm\" as the filemode for the temporary zip file",
#else
" -b --temp-path use \"path\" for the temporary zip file",
#endif
" -O --output-file write output to new zip file",
" -q --quiet quiet operation, suppress some informational messages",
" -h --help show this help",
" -v --version show version info",
" -L --license show software license"
};
/***********************************************************************
* Print help (along with license info) to stdout.
*/
local void help()
{
extent i; /* counter for help array */
for (i = 0; i < sizeof(help_info)/sizeof(char *); i++) {
printf(help_info[i], VERSION, REVDATE);
putchar('\n');
}
}
local void version_info()
/* Print verbose info about program version and compile time options
to stdout. */
{
extent i; /* counter in text arrays */
/* Options info array */
static ZCONST char *comp_opts[] = {
#ifdef DEBUG
"DEBUG",
#endif
#if CRYPT && defined(PASSWD_FROM_STDIN)
"PASSWD_FROM_STDIN",
#endif /* CRYPT && PASSWD_FROM_STDIN */
NULL
};
for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
{
printf(copyright[i], "zipcloak");
putchar('\n');
}
putchar('\n');
for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
{
printf(versinfolines[i], "ZipCloak", VERSION, REVDATE);
putchar('\n');
}
version_local();
puts("ZipCloak special compilation options:");
for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
{
printf("\t%s\n",comp_opts[i]);
}
printf("\t[encryption, version %d.%d%s of %s]\n",
CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE);
}
/* options for zipcloak - 3/5/2004 EG */
struct option_struct far options[] = {
/* short longopt value_type negatable ID name */
#ifdef VM_CMS
{"b", "temp-mode", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b', "temp file mode"},
#else
{"b", "temp-path", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b', "path for temp file"},
#endif
{"d", "decrypt", o_NO_VALUE, o_NOT_NEGATABLE, 'd', "decrypt"},
{"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
{"L", "license", o_NO_VALUE, o_NOT_NEGATABLE, 'L', "license"},
{"l", "", o_NO_VALUE, o_NOT_NEGATABLE, 'L', "license"},
{"O", "output-file", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'O', "output to new archive"},
{"v", "version", o_NO_VALUE, o_NOT_NEGATABLE, 'v', "version"},
/* the end of the list */
{NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
};
/***********************************************************************
* Encrypt or decrypt all of the entries in a zip file. See the command
* help in help() above.
*/
int main(argc, argv)
int argc; /* number of tokens in command line */
char **argv; /* command line tokens */
{
int attr; /* attributes of zip file */
zoff_t start_offset; /* start of central directory */
int decrypt; /* decryption flag */
int temp_path; /* 1 if next argument is path for temp files */
char passwd[IZ_PWLEN+1]; /* password for encryption or decryption */
char verify[IZ_PWLEN+1]; /* password for encryption or decryption */
#if 0
char *q; /* steps through option arguments */
int r; /* arg counter */
#endif
int res; /* result code */
zoff_t length; /* length of central directory */
FILE *inzip, *outzip; /* input and output zip files */
struct zlist far *z; /* steps through zfiles linked list */
/* used by get_option */
unsigned long option; /* option ID returned by get_option */
int argcnt = 0; /* current argcnt in args */
int argnum = 0; /* arg number */
int optchar = 0; /* option state */
char *value = NULL; /* non-option arg, option value or NULL */
int negated = 0; /* 1 = option negated */
int fna = 0; /* current first non-opt arg */
int optnum = 0; /* index in table */
char **args; /* copy of argv that can be freed */
#ifdef THEOS
setlocale(LC_CTYPE, "I");
#endif
#ifdef UNICODE_SUPPORT
# ifdef UNIX
/* For Unix, set the locale to UTF-8. Any UTF-8 locale is
OK and they should all be the same. This allows seeing,
writing, and displaying (if the fonts are loaded) all
characters in UTF-8. */
{
char *loc;
/*
loc = setlocale(LC_CTYPE, NULL);
printf(" Initial language locale = '%s'\n", loc);
*/
loc = setlocale(LC_CTYPE, "en_US.UTF-8");
/*
printf("langinfo %s\n", nl_langinfo(CODESET));
*/
if (loc != NULL) {
/* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
using_utf8 = 1;
/*
printf(" Locale set to %s\n", loc);
*/
} else {
/*
printf(" Could not set Unicode UTF-8 locale\n");
*/
}
}
# endif
#endif
/* If no args, show help */
if (argc == 1) {
help();
EXIT(ZE_OK);
}
/* Informational messages are written to stdout. */
mesg = stdout;
#ifndef USE_ZLIB
crc_32_tab = get_crc_table();
/* initialize crc table for crypt */
#endif
/* Go through args */
zipfile = tempzip = NULL;
tempzf = NULL;
#ifdef SIGINT
signal(SIGINT, handler);
#endif
#ifdef SIGTERM /* Some don't have SIGTERM */
signal(SIGTERM, handler);
#endif
#ifdef SIGABRT
signal(SIGABRT, handler);
#endif
#ifdef SIGBREAK
signal(SIGBREAK, handler);
#endif
#ifdef SIGBUS
signal(SIGBUS, handler);
#endif
#ifdef SIGILL
signal(SIGILL, handler);
#endif
#ifdef SIGSEGV
signal(SIGSEGV, handler);
#endif
temp_path = decrypt = 0;
#if 0
/* old command line */
for (r = 1; r < argc; r++) {
if (*argv[r] == '-') {
if (!argv[r][1]) ziperr(ZE_PARMS, "zip file cannot be stdin");
for (q = argv[r]+1; *q; q++) {
switch (*q) {
case 'b': /* Specify path for temporary file */
if (temp_path) {
ziperr(ZE_PARMS, "use -b before zip file name");
}
temp_path = 1; /* Next non-option is path */
break;
case 'd':
decrypt = 1; break;
case 'h': /* Show help */
help();
EXIT(ZE_OK);
case 'l': case 'L': /* Show copyright and disclaimer */
license();
EXIT(ZE_OK);
case 'q': /* Quiet operation, suppress info messages */
noisy = 0; break;
case 'v': /* Show version info */
version_info();
EXIT(ZE_OK);
default:
ziperr(ZE_PARMS, "unknown option");
} /* switch */
} /* for */
} else if (temp_path == 0) {
if (zipfile != NULL) {
ziperr(ZE_PARMS, "can only specify one zip file");
} else if ((zipfile = ziptyp(argv[r])) == NULL) {
ziperr(ZE_MEM, "was processing arguments");
}
} else {
tempath = argv[r];
temp_path = 0;
} /* if */
} /* for */
#else
/* new command line */
zipfile = NULL;
out_path = NULL;
/* make copy of args that can use with insert_arg() */
args = copy_args(argv, 0);
/*
-------------------------------------------
Process command line using get_option
-------------------------------------------
Each call to get_option() returns either a command
line option and possible value or a non-option argument.
Arguments are permuted so that all options (-r, -b temp)
are returned before non-option arguments (zipfile).
Returns 0 when nothing left to read.
*/
/* set argnum = 0 on first call to init get_option */
argnum = 0;
/* get_option returns the option ID and updates parameters:
args - usually same as argv if no argument file support
argcnt - current argc for args
value - char* to value (free() when done with it) or NULL if no value
negated - option was negated with trailing -
*/
while ((option = get_option(&args, &argcnt, &argnum,
&optchar, &value, &negated,
&fna, &optnum, 0)))
{
switch (option)
{
case 'b': /* Specify path for temporary file */
if (temp_path) {
ziperr(ZE_PARMS, "more than one temp_path");
}
temp_path = 1;
tempath = value;
break;
case 'd':
decrypt = 1; break;
case 'h': /* Show help */
help();
EXIT(ZE_OK);
case 'l': case 'L': /* Show copyright and disclaimer */
license();
EXIT(ZE_OK);
case 'O': /* Output to new zip file instead of updating original zip file */
if ((out_path = ziptyp(value)) == NULL) {
ziperr(ZE_MEM, "was processing arguments");
}
free(value);
break;
case 'q': /* Quiet operation, suppress info messages */
noisy = 0; break;
case 'v': /* Show version info */
version_info();
EXIT(ZE_OK);
case o_NON_OPTION_ARG:
/* not an option */
/* no more options as permuting */
/* just dash also ends up here */
if (strcmp(value, "-") == 0) {
ziperr(ZE_PARMS, "zip file cannot be stdin");
} else if (zipfile != NULL) {
ziperr(ZE_PARMS, "can only specify one zip file");
}
if ((zipfile = ziptyp(value)) == NULL) {
ziperr(ZE_MEM, "was processing arguments");
}
free(value);
break;
default:
ziperr(ZE_PARMS, "unknown option");
}
}
free_args(args);
#endif
if (zipfile == NULL) ziperr(ZE_PARMS, "need to specify zip file");
/* in_path is the input zip file */
if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
ziperr(ZE_MEM, "input");
}
strcpy(in_path, zipfile);
/* out_path defaults to in_path */
if (out_path == NULL) {
if ((out_path = malloc(strlen(zipfile) + 1)) == NULL) {
ziperr(ZE_MEM, "output");
}
strcpy(out_path, zipfile);
}
/* Read zip file */
if ((res = readzipfile()) != ZE_OK) ziperr(res, zipfile);
if (zfiles == NULL) ziperr(ZE_NAME, zipfile);
/* Check for something to do */
for (z = zfiles; z != NULL; z = z->nxt) {
if (decrypt ? z->flg & 1 : !(z->flg & 1)) break;
}
if (z == NULL) {
ziperr(ZE_NONE, decrypt ? "no encrypted files"
: "all files encrypted already");
}
/* Before we get carried away, make sure zip file is writeable */
if ((inzip = fopen(zipfile, "a")) == NULL) ziperr(ZE_CREAT, zipfile);
fclose(inzip);
attr = getfileattr(zipfile);
/* Open output zip file for writing */
#if defined(UNIX) && !defined(NO_MKSTEMP)
{
int yd;
int i;
/* use mkstemp to avoid race condition and compiler warning */
if (tempath != NULL)
{
/* if -b used to set temp file dir use that for split temp */
if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
ZIPERR(ZE_MEM, "allocating temp filename");
}
strcpy(tempzip, tempath);
if (lastchar(tempzip) != '/')
strcat(tempzip, "/");
}
else
{
/* create path by stripping name and appending template */
if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
ZIPERR(ZE_MEM, "allocating temp filename");
}
strcpy(tempzip, zipfile);
for(i = strlen(tempzip); i > 0; i--) {
if (tempzip[i - 1] == '/')
break;
}
tempzip[i] = '\0';
}
strcat(tempzip, "ziXXXXXX");
if ((yd = mkstemp(tempzip)) == EOF) {
ZIPERR(ZE_TEMP, tempzip);
}
if ((y = tempzf = outzip = fdopen(yd, FOPW_TMP)) == NULL) {
ZIPERR(ZE_TEMP, tempzip);
}
}
#else
if ((y = tempzf = outzip = fopen(tempzip = tempname(zipfile), FOPW)) == NULL) {
ziperr(ZE_TEMP, tempzip);
}
#endif
/* Get password */
if (getp("Enter password: ", passwd, IZ_PWLEN+1) == NULL)
ziperr(ZE_PARMS,
"stderr is not a tty (you may never see this message!)");
if (decrypt == 0) {
if (getp("Verify password: ", verify, IZ_PWLEN+1) == NULL)
ziperr(ZE_PARMS,
"stderr is not a tty (you may never see this message!)");
if (strcmp(passwd, verify))
ziperr(ZE_PARMS, "password verification failed");
if (*passwd == '\0')
ziperr(ZE_PARMS, "zero length password not allowed");
}
/* Open input zip file again, copy preamble if any */
if ((in_file = fopen(zipfile, FOPR)) == NULL) ziperr(ZE_NAME, zipfile);
if (zipbeg && (res = bfcopy(zipbeg)) != ZE_OK)
{
ziperr(res, res == ZE_TEMP ? tempzip : zipfile);
}
tempzn = zipbeg;
/* Go through local entries, copying, encrypting, or decrypting */
for (z = zfiles; z != NULL; z = z->nxt) {
if (decrypt && (z->flg & 1)) {
printf("decrypting: %s", z->zname);
fflush(stdout);
if ((res = zipbare(z, passwd)) != ZE_OK)
{
if (res != ZE_MISS) ziperr(res, "was decrypting an entry");
printf(" (wrong password--just copying)");
fflush(stdout);
}
putchar('\n');
} else if ((!decrypt) && !(z->flg & 1)) {
printf("encrypting: %s\n", z->zname);
fflush(stdout);
if ((res = zipcloak(z, passwd)) != ZE_OK)
{
ziperr(res, "was encrypting an entry");
}
} else {
printf(" copying: %s\n", z->zname);
fflush(stdout);
if ((res = zipcopy(z)) != ZE_OK)
{
ziperr(res, "was copying an entry");
}
} /* if */
} /* for */
fclose(in_file);
/* Write central directory and end of central directory */
/* get start of central */
if ((start_offset = zftello(outzip)) == (zoff_t)-1)
ziperr(ZE_TEMP, tempzip);
for (z = zfiles; z != NULL; z = z->nxt) {
if ((res = putcentral(z)) != ZE_OK) ziperr(res, tempzip);
}
/* get end of central */
if ((length = zftello(outzip)) == (zoff_t)-1)
ziperr(ZE_TEMP, tempzip);
length -= start_offset; /* compute length of central */
if ((res = putend((zoff_t)zcount, length, start_offset, zcomlen,
zcomment)) != ZE_OK) {
ziperr(res, tempzip);
}
tempzf = NULL;
if (fclose(outzip)) ziperr(ZE_TEMP, tempzip);
if ((res = replace(out_path, tempzip)) != ZE_OK) {
zipwarn("new zip file left as: ", tempzip);
free((zvoid *)tempzip);
tempzip = NULL;
ziperr(res, "was replacing the original zip file");
}
free((zvoid *)tempzip);
tempzip = NULL;
setfileattr(zipfile, attr);
#ifdef RISCOS
/* Set the filetype of the zipfile to &DDC */
setfiletype(zipfile, 0xDDC);
#endif
free((zvoid *)in_path);
free((zvoid *)out_path);
free((zvoid *)zipfile);
zipfile = NULL;
/* Done! */
RETURN(0);
}
#else /* !CRYPT */
/* below is only used if crypt is not enabled */
struct option_struct far options[] = {
/* short longopt value_type negatable ID name */
{"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
/* the end of the list */
{NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
};
int main OF((void));
void zipwarn(msg1, msg2)
ZCONST char *msg1, *msg2;
{
/* Tell picky compilers to shut up about unused variables */
msg1 = msg1; msg2 = msg2;
}
void ziperr(c, h)
int c;
ZCONST char *h;
{
/* Tell picky compilers to shut up about unused variables */
c = c; h = h;
}
int main()
{
fprintf(mesg, "\
This version of ZipCloak does not support encryption. Get the current Zip\n\
source distribution and recompile ZipCloak after you have added an option to\n\
define the symbol USE_CRYPT to the C compiler's command arguments.\n");
RETURN(1);
}
#endif /* ?CRYPT */

116
third_party/zip/ziperr.h vendored Normal file
View file

@ -0,0 +1,116 @@
/* clang-format off */
/*
ziperr.h - Zip 3
Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
/*
* ziperr.h by Mark Adler
*/
/*
* VMS message file ident string. (The "-xxx" suffix should be
* incremented when messages are changed for a particular program
* version.) Used only when generating the VMS message source file, but
* that can be done on a non-VMS system.
*/
#define VMS_MSG_IDENT "V3.0-000"
/* VMS-compatible "severity" values (bits 2:0): */
#define ZE_S_WARNING 0x00
#define ZE_S_SUCCESS 0x01
#define ZE_S_ERROR 0x02
#define ZE_S_INFO 0x03
#define ZE_S_SEVERE 0x04
#define ZE_S_UNUSED 0x07
/* Flags: */
#define ZE_S_PERR 0x10
/* Error return values. The values 0..4 and 12..18 follow the conventions
of PKZIP. The values 4..10 are all assigned to "insufficient memory"
by PKZIP, so the codes 5..10 are used here for other purposes. */
#define ZE_MISS -1 /* used by procname(), zipbare() */
#define ZE_OK 0 /* success */
#define ZE_EOF 2 /* unexpected end of zip file */
#define ZE_FORM 3 /* zip file structure error */
#define ZE_MEM 4 /* out of memory */
#define ZE_LOGIC 5 /* internal logic error */
#define ZE_BIG 6 /* entry too large to split, read, or write */
#define ZE_NOTE 7 /* invalid comment format */
#define ZE_TEST 8 /* zip test (-T) failed or out of memory */
#define ZE_ABORT 9 /* user interrupt or termination */
#define ZE_TEMP 10 /* error using a temp file */
#define ZE_READ 11 /* read or seek error */
#define ZE_NONE 12 /* nothing to do */
#define ZE_NAME 13 /* missing or empty zip file */
#define ZE_WRITE 14 /* error writing to a file */
#define ZE_CREAT 15 /* couldn't open to write */
#define ZE_PARMS 16 /* bad command line */
#define ZE_OPEN 18 /* could not open a specified file to read */
#define ZE_COMPERR 19 /* error in compilation options */
#define ZE_ZIP64 20 /* Zip64 not supported */
#define ZE_MAXERR 20 /* the highest error number */
/* Error messages for the ziperr() function in the zip programs. */
#ifdef GLOBALS
struct
{
char *name;
char *string;
int severity;
} ziperrors[ZE_MAXERR + 1] = {
/* 0 */ { "OK", "Normal successful completion", ZE_S_SUCCESS },
/* 1 */ { "", "", ZE_S_UNUSED },
/* 2 */ { "EOF", "Unexpected end of zip file", ZE_S_SEVERE },
/* 3 */ { "FORM", "Zip file structure invalid", ZE_S_ERROR },
/* 4 */ { "MEM", "Out of memory", ZE_S_SEVERE },
/* 5 */ { "LOGIC", "Internal logic error", ZE_S_SEVERE },
/* 6 */ { "BIG", "Entry too big to split, read, or write",
ZE_S_ERROR },
/* 7 */ { "NOTE", "Invalid comment format", ZE_S_ERROR },
/* 8 */ { "TEST", "Zip file invalid, could not spawn unzip, or wrong unzip",
ZE_S_SEVERE },
/* 9 */ { "ABORT", "Interrupted", ZE_S_ERROR },
/* 10 */ { "TEMP", "Temporary file failure", ZE_S_SEVERE | ZE_S_PERR },
/* 11 */ { "READ", "Input file read failure", ZE_S_SEVERE | ZE_S_PERR },
/* 12 */ { "NONE", "Nothing to do!", ZE_S_WARNING },
/* 13 */ { "NAME", "Missing or empty zip file", ZE_S_ERROR },
/* 14 */ { "WRITE", "Output file write failure", ZE_S_SEVERE | ZE_S_PERR },
/* 15 */ { "CREAT", "Could not create output file", ZE_S_SEVERE | ZE_S_PERR },
/* 16 */ { "PARMS", "Invalid command arguments", ZE_S_ERROR },
/* 17 */ { "", "", ZE_S_UNUSED },
/* 18 */ { "OPEN", "File not found or no read permission",
ZE_S_ERROR | ZE_S_PERR },
/* 19 */ { "COMPERR", "Not supported", ZE_S_SEVERE },
/* 20 */ { "ZIP64", "Attempt to read unsupported Zip64 archive",
ZE_S_SEVERE }
# ifdef AZTEC_C
, /* extremely lame compiler bug workaround */
# endif
};
#else /* !GLOBALS */
/* Error messages for ziperr() */
extern struct
{
char *name;
char *string;
int severity;
} ziperrors[ZE_MAXERR + 1];
#endif /* ?GLOBALS */
/* Macro to determine whether to call perror() or not. */
#define PERR(e) (ziperrors[e].severity & ZE_S_PERR)
/* Macro for easy access to the message string. */
#define ZIPERRORS(e) ziperrors[e].string

6815
third_party/zip/zipfile.c vendored Normal file

File diff suppressed because it is too large Load diff

701
third_party/zip/zipnote.c vendored Normal file
View file

@ -0,0 +1,701 @@
/* clang-format off */
/*
zipnote.c - Zip 3
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
/*
* zipnote.c by Mark Adler.
*/
#define __ZIPNOTE_C
#ifndef UTIL
#define UTIL
#endif
#include "third_party/zip/zip.h"
#define DEFCPYRT /* main module: enable copyright string defines! */
#include "third_party/zip/revision.h"
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/conv.h"
#include "libc/alg/alg.h"
#include "libc/log/log.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/sysv/consts/sig.h"
#include "libc/stdio/temp.h"
/* Calculate size of static line buffer used in write (-w) mode. */
#define WRBUFSIZ 2047
/* The line buffer size should be at least as large as FNMAX. */
#if FNMAX > WRBUFSIZ
# undef WRBUFSIZ
# define WRBUFSIZ FNMAX
#endif
/* Character to mark zip entry names in the comment file */
#define MARK '@'
#define MARKE " (comment above this line)"
#define MARKZ " (zip file comment below this line)"
/* Temporary zip file pointer */
local FILE *tempzf;
/* Local functions */
local void handler OF((int));
local void license OF((void));
local void help OF((void));
local void version_info OF((void));
local void putclean OF((char *, extent));
/* getline name conflicts with GNU getline() function */
local char *zgetline OF((char *, extent));
local int catalloc OF((char * far *, char *));
int main OF((int, char **));
/* keep compiler happy until implement long options - 11/4/2003 EG */
struct option_struct far options[] = {
/* short longopt value_type negatable ID name */
{"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
/* the end of the list */
{NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
};
#ifdef MACOS
#define ziperr(c, h) zipnoteerr(c, h)
#define zipwarn(a, b) zipnotewarn(a, b)
void zipnoteerr(int c, ZCONST char *h);
void zipnotewarn(ZCONST char *a, ZCONST char *b);
#endif
int set_filetype(out_path)
char *out_path;
{
#ifdef __BEOS__
/* Set the filetype of the zipfile to "application/zip" */
setfiletype( out_path, "application/zip" );
#endif
#ifdef __ATHEOS__
/* Set the filetype of the zipfile to "application/x-zip" */
setfiletype(out_path, "application/x-zip");
#endif
#ifdef MACOS
/* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
setfiletype(out_path, 'IZip', 'ZIP ');
#endif
#ifdef RISCOS
/* Set the filetype of the zipfile to &DDC */
setfiletype(out_path, 0xDDC);
#endif
return ZE_OK;
}
/* rename a split
* A split has a tempfile name until it is closed, then
* here rename it as out_path the final name for the split.
*/
int rename_split(temp_name, out_path)
char *temp_name;
char *out_path;
{
int r;
/* Replace old zip file with new zip file, leaving only the new one */
if ((r = replace(out_path, temp_name)) != ZE_OK)
{
zipwarn("new zip file left as: ", temp_name);
free((zvoid *)tempzip);
tempzip = NULL;
ZIPERR(r, "was replacing split file");
}
if (zip_attributes) {
setfileattr(out_path, zip_attributes);
}
return ZE_OK;
}
void zipmessage_nl(a, nl)
ZCONST char *a; /* message string to output */
int nl; /* 1 = add nl to end */
/* If nl false, print a message to mesg without new line.
If nl true, print and add new line. If logfile is
open then also write message to log file. */
{
if (noisy) {
fprintf(mesg, "%s", a);
if (nl) {
fprintf(mesg, "\n");
mesg_line_started = 0;
} else {
mesg_line_started = 1;
}
fflush(mesg);
}
}
void zipmessage(a, b)
ZCONST char *a, *b; /* message strings juxtaposed in output */
/* Print a message to mesg and flush. Also write to log file if
open. Write new line first if current line has output already. */
{
if (noisy) {
if (mesg_line_started)
fprintf(mesg, "\n");
fprintf(mesg, "%s%s\n", a, b);
mesg_line_started = 0;
fflush(mesg);
}
}
void ziperr(c, h)
int c; /* error code from the ZE_ class */
ZCONST char *h; /* message about how it happened */
/* Issue a message for the error, clean up files and memory, and exit. */
{
if (PERR(c))
perror("zipnote error");
fprintf(mesg, "zipnote error: %s (%s)\n", ZIPERRORS(c), h);
if (tempzf != NULL)
fclose(tempzf);
if (tempzip != NULL)
{
destroy(tempzip);
free((zvoid *)tempzip);
}
if (zipfile != NULL)
free((zvoid *)zipfile);
EXIT(c);
}
local void handler(s)
int s; /* signal number (ignored) */
/* Upon getting a user interrupt, abort cleanly using ziperr(). */
{
#ifndef MSDOS
putc('\n', mesg);
#endif /* !MSDOS */
ziperr(ZE_ABORT, "aborting");
s++; /* keep some compilers happy */
}
void zipwarn(a, b)
ZCONST char *a, *b; /* message strings juxtaposed in output */
/* Print a warning message to mesg (usually stderr) and return. */
{
fprintf(mesg, "zipnote warning: %s%s\n", a, b);
}
local void license()
/* Print license information to stdout. */
{
extent i; /* counter for copyright array */
for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++)
puts(swlicense[i]);
}
local void help()
/* Print help (along with license info) to stdout. */
{
extent i; /* counter for help array */
/* help array */
static ZCONST char *text[] = {
"",
"ZipNote %s (%s)",
#ifdef VM_CMS
"Usage: zipnote [-w] [-q] [-b fm] zipfile",
#else
"Usage: zipnote [-w] [-q] [-b path] zipfile",
#endif
" the default action is to write the comments in zipfile to stdout",
" -w write the zipfile comments from stdin",
#ifdef VM_CMS
" -b use \"fm\" as the filemode for the temporary zip file",
#else
" -b use \"path\" for the temporary zip file",
#endif
" -q quieter operation, suppress some informational messages",
" -h show this help -v show version info -L show software license",
"",
"Example:",
#ifdef VMS
" define/user sys$output foo.tmp",
" zipnote foo.zip",
" edit foo.tmp",
" ... then you edit the comments, save, and exit ...",
" define/user sys$input foo.tmp",
" zipnote -w foo.zip",
#else
#ifdef RISCOS
" zipnote foo/zip > foo/tmp",
" <!Edit> foo/tmp",
" ... then you edit the comments, save, and exit ...",
" zipnote -w foo/zip < foo/tmp",
#else
#ifdef VM_CMS
" zipnote foo.zip > foo.tmp",
" xedit foo tmp",
" ... then you edit the comments, save, and exit ...",
" zipnote -w foo.zip < foo.tmp",
#else
" zipnote foo.zip > foo.tmp",
" ed foo.tmp",
" ... then you edit the comments, save, and exit ...",
" zipnote -w foo.zip < foo.tmp",
#endif /* VM_CMS */
#endif /* RISCOS */
#endif /* VMS */
"",
" \"@ name\" can be followed by an \"@=newname\" line to change the name"
};
for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
printf(copyright[i], "zipnote");
putchar('\n');
}
for (i = 0; i < sizeof(text)/sizeof(char *); i++)
{
printf(text[i], VERSION, REVDATE);
putchar('\n');
}
}
/*
* XXX put this in version.c
*/
local void version_info()
/* Print verbose info about program version and compile time options
to stdout. */
{
extent i; /* counter in text arrays */
/* Options info array */
static ZCONST char *comp_opts[] = {
#ifdef DEBUG
"DEBUG",
#endif
NULL
};
for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
{
printf(copyright[i], "zipnote");
putchar('\n');
}
for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
{
printf(versinfolines[i], "ZipNote", VERSION, REVDATE);
putchar('\n');
}
version_local();
puts("ZipNote special compilation options:");
for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
{
printf("\t%s\n",comp_opts[i]);
}
if (i == 0)
puts("\t[none]");
}
local void putclean(s, n)
char *s; /* string to write to stdout */
extent n; /* length of string */
/* Write the string s to stdout, filtering out control characters that are
not tab or newline (mainly to remove carriage returns), and prefix MARK's
and backslashes with a backslash. Also, terminate with a newline if
needed. */
{
int c; /* next character in string */
int e; /* last character written */
e = '\n'; /* if empty, write nothing */
while (n--)
{
c = *(uch *)s++;
if (c == MARK || c == '\\')
putchar('\\');
if (c >= ' ' || c == '\t' || c == '\n')
{ e=c; putchar(e); }
}
if (e != '\n')
putchar('\n');
}
local char *zgetline(buf, size)
char *buf;
extent size;
/* Read a line of text from stdin into string buffer 'buf' of size 'size'.
In case of buffer overflow or EOF, a NULL pointer is returned. */
{
char *line;
unsigned len;
line = fgets(buf, size, stdin);
if (line != NULL && (len = strlen(line)) > 0) {
if (len == size-1 && line[len-1] != '\n') {
/* buffer is full and record delimiter not seen -> overflow */
line = NULL;
} else {
/* delete trailing record delimiter */
if (line[len-1] == '\n') line[len-1] = '\0';
}
}
return line;
}
local int catalloc(a, s)
char * far *a; /* pointer to a pointer to a malloc'ed string */
char *s; /* string to concatenate on a */
/* Concatentate the string s to the malloc'ed string pointed to by a.
Preprocess s by removing backslash escape characters. */
{
char *p; /* temporary pointer */
char *q; /* temporary pointer */
for (p = q = s; *q; *p++ = *q++)
if (*q == '\\' && *(q+1))
q++;
*p = 0;
if ((p = malloc(strlen(*a) + strlen(s) + 3)) == NULL)
return ZE_MEM;
strcat(strcat(strcpy(p, *a), **a ? "\r\n" : ""), s);
free((zvoid *)*a);
*a = p;
return ZE_OK;
}
#ifndef USE_ZIPNOTEMAIN
int main(argc, argv)
#else
int zipnotemain(argc, argv)
#endif
int argc; /* number of tokens in command line */
char **argv; /* command line tokens */
/* Write the comments in the zipfile to stdout, or read them from stdin. */
{
char abf[WRBUFSIZ+1]; /* input line buffer */
char *a; /* pointer to line buffer or NULL */
zoff_t c; /* start of central directory */
int k; /* next argument type */
char *q; /* steps through option arguments */
int r; /* arg counter, temporary variable */
zoff_t s; /* length of central directory */
int t; /* attributes of zip file */
int w; /* true if updating zip file from stdin */
FILE *x; /* input file for testing if can write it */
struct zlist far *z; /* steps through zfiles linked list */
#ifdef THEOS
setlocale(LC_CTYPE, "I");
#endif
#ifdef UNICODE_SUPPORT
# ifdef UNIX
/* For Unix, set the locale to UTF-8. Any UTF-8 locale is
OK and they should all be the same. This allows seeing,
writing, and displaying (if the fonts are loaded) all
characters in UTF-8. */
{
char *loc;
/*
loc = setlocale(LC_CTYPE, NULL);
printf(" Initial language locale = '%s'\n", loc);
*/
loc = setlocale(LC_CTYPE, "en_US.UTF-8");
/*
printf("langinfo %s\n", nl_langinfo(CODESET));
*/
if (loc != NULL) {
/* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
using_utf8 = 1;
/*
printf(" Locale set to %s\n", loc);
*/
} else {
/*
printf(" Could not set Unicode UTF-8 locale\n");
*/
}
}
# endif
#endif
/* If no args, show help */
if (argc == 1)
{
help();
EXIT(ZE_OK);
}
/* Direct info messages to stderr; stdout is used for data output. */
mesg = stderr;
/* Go through args */
zipfile = tempzip = NULL;
tempzf = NULL;
signal(SIGINT, handler);
#ifdef SIGTERM /* AMIGA has no SIGTERM */
signal(SIGTERM, handler);
#endif
#ifdef SIGABRT
signal(SIGABRT, handler);
#endif
#ifdef SIGBREAK
signal(SIGBREAK, handler);
#endif
#ifdef SIGBUS
signal(SIGBUS, handler);
#endif
#ifdef SIGILL
signal(SIGILL, handler);
#endif
#ifdef SIGSEGV
signal(SIGSEGV, handler);
#endif
k = w = 0;
for (r = 1; r < argc; r++)
if (*argv[r] == '-') {
if (argv[r][1])
for (q = argv[r]+1; *q; q++)
switch (*q)
{
case 'b': /* Specify path for temporary file */
if (k)
ziperr(ZE_PARMS, "use -b before zip file name");
else
k = 1; /* Next non-option is path */
break;
case 'h': /* Show help */
help(); EXIT(ZE_OK);
case 'l': case 'L': /* Show copyright and disclaimer */
license(); EXIT(ZE_OK);
case 'q': /* Quiet operation, suppress info messages */
noisy = 0; break;
case 'v': /* Show version info */
version_info(); EXIT(ZE_OK);
case 'w':
w = 1; break;
default:
ziperr(ZE_PARMS, "unknown option");
}
else
ziperr(ZE_PARMS, "zip file cannot be stdin");
} else
if (k == 0)
{
if (zipfile == NULL)
{
if ((zipfile = ziptyp(argv[r])) == NULL)
ziperr(ZE_MEM, "was processing arguments");
}
else
ziperr(ZE_PARMS, "can only specify one zip file");
}
else
{
tempath = argv[r];
k = 0;
}
if (zipfile == NULL)
ziperr(ZE_PARMS, "need to specify zip file");
if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
ziperr(ZE_MEM, "input");
}
strcpy(in_path, zipfile);
/* Read zip file */
if ((r = readzipfile()) != ZE_OK)
ziperr(r, zipfile);
if (zfiles == NULL)
ziperr(ZE_NAME, zipfile);
/* Put comments to stdout, if not -w */
if (!w)
{
for (z = zfiles; z != NULL; z = z->nxt)
{
printf("%c %s\n", MARK, z->zname);
putclean(z->comment, z->com);
printf("%c%s\n", MARK, MARKE);
}
printf("%c%s\n", MARK, MARKZ);
putclean(zcomment, zcomlen);
EXIT(ZE_OK);
}
/* If updating comments, make sure zip file is writeable */
if ((x = fopen(zipfile, "a")) == NULL)
ziperr(ZE_CREAT, zipfile);
fclose(x);
t = getfileattr(zipfile);
/* Process stdin, replacing comments */
z = zfiles;
while ((a = zgetline(abf, WRBUFSIZ+1)) != NULL &&
(a[0] != MARK || strcmp(a + 1, MARKZ)))
{ /* while input and not file comment */
if (a[0] != MARK || a[1] != ' ') /* better be "@ name" */
ziperr(ZE_NOTE, "unexpected input");
while (z != NULL && strcmp(a + 2, z->zname))
z = z->nxt; /* allow missing entries in order */
if (z == NULL)
ziperr(ZE_NOTE, "unknown entry name");
if ((a = zgetline(abf, WRBUFSIZ+1)) != NULL && a[0] == MARK && a[1] == '=')
{
if (z->name != z->iname)
free((zvoid *)z->iname);
if ((z->iname = malloc(strlen(a+1))) == NULL)
ziperr(ZE_MEM, "was changing name");
#ifdef EBCDIC
strtoasc(z->iname, a+2);
#else
strcpy(z->iname, a+2);
#endif
/*
* Don't update z->nam here, we need the old value a little later.....
* The update is handled in zipcopy().
*/
a = zgetline(abf, WRBUFSIZ+1);
}
if (z->com) /* change zip entry comment */
free((zvoid *)z->comment);
z->comment = malloc(1); *(z->comment) = 0;
while (a != NULL && *a != MARK)
{
if ((r = catalloc(&(z->comment), a)) != ZE_OK)
ziperr(r, "was building new zipentry comments");
a = zgetline(abf, WRBUFSIZ+1);
}
z->com = strlen(z->comment);
z = z->nxt; /* point to next entry */
}
if (a != NULL) /* change zip file comment */
{
zcomment = malloc(1); *zcomment = 0;
while ((a = zgetline(abf, WRBUFSIZ+1)) != NULL)
if ((r = catalloc(&zcomment, a)) != ZE_OK)
ziperr(r, "was building new zipfile comment");
zcomlen = strlen(zcomment);
}
/* Open output zip file for writing */
#if defined(UNIX) && !defined(NO_MKSTEMP)
{
int yd;
int i;
/* use mkstemp to avoid race condition and compiler warning */
if (tempath != NULL)
{
/* if -b used to set temp file dir use that for split temp */
if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
ZIPERR(ZE_MEM, "allocating temp filename");
}
strcpy(tempzip, tempath);
if (lastchar(tempzip) != '/')
strcat(tempzip, "/");
}
else
{
/* create path by stripping name and appending template */
if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
ZIPERR(ZE_MEM, "allocating temp filename");
}
strcpy(tempzip, zipfile);
for(i = strlen(tempzip); i > 0; i--) {
if (tempzip[i - 1] == '/')
break;
}
tempzip[i] = '\0';
}
strcat(tempzip, "ziXXXXXX");
if ((yd = mkstemp(tempzip)) == EOF) {
ZIPERR(ZE_TEMP, tempzip);
}
if ((tempzf = y = fdopen(yd, FOPW)) == NULL) {
ZIPERR(ZE_TEMP, tempzip);
}
}
#else
if ((tempzf = y = fopen(tempzip = tempname(zipfile), FOPW)) == NULL)
ziperr(ZE_TEMP, tempzip);
#endif
/* Open input zip file again, copy preamble if any */
if ((in_file = fopen(zipfile, FOPR)) == NULL)
ziperr(ZE_NAME, zipfile);
if (zipbeg && (r = bfcopy(zipbeg)) != ZE_OK)
ziperr(r, r == ZE_TEMP ? tempzip : zipfile);
tempzn = zipbeg;
/* Go through local entries, copying them over as is */
fix = 3; /* needed for zipcopy if name changed */
for (z = zfiles; z != NULL; z = z->nxt) {
if ((r = zipcopy(z)) != ZE_OK)
ziperr(r, "was copying an entry");
}
fclose(x);
/* Write central directory and end of central directory with new comments */
if ((c = zftello(y)) == (zoff_t)-1) /* get start of central */
ziperr(ZE_TEMP, tempzip);
for (z = zfiles; z != NULL; z = z->nxt)
if ((r = putcentral(z)) != ZE_OK)
ziperr(r, tempzip);
if ((s = zftello(y)) == (zoff_t)-1) /* get end of central */
ziperr(ZE_TEMP, tempzip);
s -= c; /* compute length of central */
if ((r = putend((zoff_t)zcount, s, c, zcomlen, zcomment)) != ZE_OK)
ziperr(r, tempzip);
tempzf = NULL;
if (fclose(y))
ziperr(ZE_TEMP, tempzip);
if ((r = replace(zipfile, tempzip)) != ZE_OK)
{
zipwarn("new zip file left as: ", tempzip);
free((zvoid *)tempzip);
tempzip = NULL;
ziperr(r, "was replacing the original zip file");
}
free((zvoid *)tempzip);
tempzip = NULL;
setfileattr(zipfile, t);
#ifdef RISCOS
/* Set the filetype of the zipfile to &DDC */
setfiletype(zipfile,0xDDC);
#endif
free((zvoid *)zipfile);
zipfile = NULL;
/* Done! */
RETURN(0);
}

978
third_party/zip/zipsplit.c vendored Normal file
View file

@ -0,0 +1,978 @@
/* clang-format off */
/*
zipsplit.c - Zip 3
Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2007-Mar-4 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
*/
/*
* zipsplit.c by Mark Adler.
*/
#define __ZIPSPLIT_C
#ifndef UTIL
#define UTIL
#endif
#include "third_party/zip/zip.h"
#define DEFCPYRT /* main module: enable copyright string defines! */
#include "third_party/zip/revision.h"
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/conv.h"
#include "libc/alg/alg.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/sysv/consts/sig.h"
#include "libc/log/log.h"
#define DEFSIZ 36000L /* Default split size (change in help() too) */
#ifdef MSDOS
# define NL 2 /* Number of bytes written for a \n */
#else /* !MSDOS */
# define NL 1 /* Number of bytes written for a \n */
#endif /* ?MSDOS */
#ifdef RISCOS
# define INDEX "zipspl/idx" /* Name of index file */
# define TEMPL_FMT "%%0%dld"
# define TEMPL_SIZ 13
# define ZPATH_SEP '.'
#else
#ifdef QDOS
#else
#ifdef VM_CMS
# define INDEX "zipsplit.idx" /* Name of index file */
# define TEMPL_FMT "%%0%dld.zip"
# define TEMPL_SIZ 21
# define ZPATH_SEP '.'
#else
# define INDEX "zipsplit.idx" /* Name of index file */
# define TEMPL_FMT "%%0%dld.zip"
# define TEMPL_SIZ 17
# define ZPATH_SEP '.'
#endif /* VM_CMS */
#endif /* QDOS */
#endif /* RISCOS */
#ifdef MACOS
#define ziperr(c, h) zipspliterr(c, h)
#define zipwarn(a, b) zipsplitwarn(a, b)
void zipsplitwarn(ZCONST char *a, ZCONST char *b);
void zipspliterr(int c, ZCONST char *h);
#endif /* MACOS */
/* Local functions */
local zvoid *talloc OF((extent));
local void tfree OF((zvoid *));
local void tfreeall OF((void));
local void handler OF((int));
local void license OF((void));
local void help OF((void));
local void version_info OF((void));
local extent simple OF((uzoff_t *, extent, uzoff_t, uzoff_t));
local int descmp OF((ZCONST zvoid *, ZCONST zvoid *));
local extent greedy OF((uzoff_t *, extent, uzoff_t, uzoff_t));
local int retry OF((void));
int main OF((int, char **));
/* Output zip files */
local char template[TEMPL_SIZ]; /* name template for output files */
local int zipsmade = 0; /* number of zip files made */
local int indexmade = 0; /* true if index file made */
local char *path = NULL; /* space for full name */
local char *name; /* where name goes in path[] */
/* The talloc() and tree() routines extend malloc() and free() to keep
track of all allocated memory. Then the tfreeall() routine uses this
information to free all allocated memory before exiting. */
#define TMAX 6 /* set intelligently by examining the code */
zvoid *talls[TMAX]; /* malloc'ed pointers to track */
int talln = 0; /* number of entries in talls[] */
int set_filetype(out_path)
char *out_path;
{
#ifdef __BEOS__
/* Set the filetype of the zipfile to "application/zip" */
setfiletype( out_path, "application/zip" );
#endif
#ifdef __ATHEOS__
/* Set the filetype of the zipfile to "application/x-zip" */
setfiletype(out_path, "application/x-zip");
#endif
#ifdef MACOS
/* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
setfiletype(out_path, 'IZip', 'ZIP ');
#endif
#ifdef RISCOS
/* Set the filetype of the zipfile to &DDC */
setfiletype(out_path, 0xDDC);
#endif
return ZE_OK;
}
/* rename a split
* A split has a tempfile name until it is closed, then
* here rename it as out_path the final name for the split.
*
* This is not used in zipsplit but is referenced by the generic split
* writing code. If zipsplit is made split aware (so can write splits of
* splits, if that makes sense) then this would get used. But if that
* happens these utility versions should be dropped and the main ones
* used.
*/
int rename_split(temp_name, out_path)
char *temp_name;
char *out_path;
{
int r;
/* Replace old zip file with new zip file, leaving only the new one */
if ((r = replace(out_path, temp_name)) != ZE_OK)
{
zipwarn("new zip file left as: ", temp_name);
free((zvoid *)tempzip);
tempzip = NULL;
ZIPERR(r, "was replacing split file");
}
if (zip_attributes) {
setfileattr(out_path, zip_attributes);
}
return ZE_OK;
}
void zipmessage_nl(a, nl)
ZCONST char *a; /* message string to output */
int nl; /* 1 = add nl to end */
/* If nl false, print a message to mesg without new line.
If nl true, print and add new line. If logfile is
open then also write message to log file. */
{
if (noisy) {
fprintf(mesg, "%s", a);
if (nl) {
fprintf(mesg, "\n");
mesg_line_started = 0;
} else {
mesg_line_started = 1;
}
fflush(mesg);
}
}
void zipmessage(a, b)
ZCONST char *a, *b; /* message strings juxtaposed in output */
/* Print a message to mesg and flush. Also write to log file if
open. Write new line first if current line has output already. */
{
if (noisy) {
if (mesg_line_started)
fprintf(mesg, "\n");
fprintf(mesg, "%s%s\n", a, b);
mesg_line_started = 0;
fflush(mesg);
}
}
local zvoid *talloc(s)
extent s;
/* does a malloc() and saves the pointer to free later (does not check
for an overflow of the talls[] list) */
{
zvoid *p;
if ((p = (zvoid *)malloc(s)) != NULL)
talls[talln++] = p;
return p;
}
local void tfree(p)
zvoid *p;
/* does a free() and also removes the pointer from the talloc() list */
{
int i;
free(p);
i = talln;
while (i--)
if (talls[i] == p)
break;
if (i >= 0)
{
while (++i < talln)
talls[i - 1] = talls[i];
talln--;
}
}
local void tfreeall()
/* free everything talloc'ed and not tfree'd */
{
while (talln)
free(talls[--talln]);
}
void ziperr(c, h)
int c; /* error code from the ZE_ class */
ZCONST char *h; /* message about how it happened */
/* Issue a message for the error, clean up files and memory, and exit. */
{
if (PERR(c))
perror("zipsplit error");
fprintf(mesg, "zipsplit error: %s (%s)\n", ZIPERRORS(c), h);
if (indexmade)
{
strcpy(name, INDEX);
destroy(path);
}
for (; zipsmade; zipsmade--)
{
sprintf(name, template, zipsmade);
destroy(path);
}
tfreeall();
if (zipfile != NULL)
free((zvoid *)zipfile);
EXIT(c);
}
local void handler(s)
int s; /* signal number (ignored) */
/* Upon getting a user interrupt, abort cleanly using ziperr(). */
{
#ifndef MSDOS
putc('\n', mesg);
#endif /* !MSDOS */
ziperr(ZE_ABORT, "aborting");
s++; /* keep some compilers happy */
}
void zipwarn(a, b)
ZCONST char *a, *b; /* message strings juxtaposed in output */
/* Print a warning message to mesg (usually stderr) and return. */
{
fprintf(mesg, "zipsplit warning: %s%s\n", a, b);
}
local void license()
/* Print license information to stdout. */
{
extent i; /* counter for copyright array */
for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++)
puts(swlicense[i]);
}
local void help()
/* Print help (along with license info) to stdout. */
{
extent i; /* counter for help array */
/* help array */
static ZCONST char *text[] = {
"",
"ZipSplit %s (%s)",
#ifdef VM_CMS
"Usage: zipsplit [-tipqs] [-n size] [-r room] [-b fm] zipfile",
#else
"Usage: zipsplit [-tipqs] [-n size] [-r room] [-b path] zipfile",
#endif
" -t report how many files it will take, but don't make them",
#ifdef RISCOS
" -i make index (" INDEX ") and count its size against first zip file",
#else
" -i make index (zipsplit.idx) and count its size against first zip file",
#endif
" -n make zip files no larger than \"size\" (default = 36000)",
" -r leave room for \"room\" bytes on the first disk (default = 0)",
#ifdef VM_CMS
" -b use \"fm\" as the filemode for the output zip files",
#else
" -b use \"path\" for the output zip files",
#endif
" -q quieter operation, suppress some informational messages",
" -p pause between output zip files",
" -s do a sequential split even if it takes more zip files",
" -h show this help -v show version info -L show software license"
};
for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
printf(copyright[i], "zipsplit");
putchar('\n');
}
for (i = 0; i < sizeof(text)/sizeof(char *); i++)
{
printf(text[i], VERSION, REVDATE);
putchar('\n');
}
}
local void version_info()
/* Print verbose info about program version and compile time options
to stdout. */
{
extent i; /* counter in text arrays */
/* Options info array */
static ZCONST char *comp_opts[] = {
#ifdef DEBUG
"DEBUG",
#endif
NULL
};
for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
{
printf(versinfolines[i], "ZipSplit", VERSION, REVDATE);
putchar('\n');
}
version_local();
puts("ZipSplit special compilation options:");
for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
{
printf("\t%s\n",comp_opts[i]);
}
if (i == 0)
puts("\t[none]");
}
local extent simple(a, n, c, d)
uzoff_t *a; /* items to put in bins, return value: destination bins */
extent n; /* number of items */
uzoff_t c; /* capacity of each bin */
uzoff_t d; /* amount to deduct from first bin */
/* Return the number of bins of capacity c that are needed to contain the
integers in a[0..n-1] placed sequentially into the bins. The value d
is deducted initially from the first bin (space for index). The entries
in a[] are replaced by the destination bins. */
{
extent k; /* current bin number */
uzoff_t t; /* space used in current bin */
t = k = 0;
while (n--)
{
if (*a + t > c - (k == 0 ? d : 0))
{
k++;
t = 0;
}
t += *a;
*(ulg huge *)a++ = k;
}
return k + 1;
}
local int descmp(a, b)
ZCONST zvoid *a, *b; /* pointers to pointers to ulg's to compare */
/* Used by qsort() in greedy() to do a descending sort. */
{
return **(uzoff_t **)a < **(uzoff_t **)b ? 1 :
(**(uzoff_t **)a > **(uzoff_t **)b ? -1 : 0);
}
local extent greedy(a, n, c, d)
uzoff_t *a; /* items to put in bins, return value: destination bins */
extent n; /* number of items */
uzoff_t c; /* capacity of each bin */
uzoff_t d; /* amount to deduct from first bin */
/* Return the number of bins of capacity c that are needed to contain the
items with sizes a[0..n-1] placed non-sequentially into the bins. The
value d is deducted initially from the first bin (space for index).
The entries in a[] are replaced by the destination bins. */
{
uzoff_t *b; /* space left in each bin (malloc'ed for each m) */
uzoff_t *e; /* copy of argument a[] (malloc'ed) */
extent i; /* steps through items */
extent j; /* steps through bins */
extent k; /* best bin to put current item in */
extent m; /* current number of bins */
uzoff_t **s; /* pointers to e[], sorted descending (malloc'ed) */
uzoff_t t; /* space left in best bin (index k) */
/* Algorithm:
1. Copy a[] to e[] and sort pointers to e[0..n-1] (in s[]), in
descending order.
2. Compute total of s[] and set m to the smallest number of bins of
capacity c that can hold the total.
3. Allocate m bins.
4. For each item in s[], starting with the largest, put it in the
bin with the smallest current capacity greater than or equal to the
item's size. If no bin has enough room, increment m and go to step 4.
5. Else, all items ended up in a bin--return m.
*/
/* Copy a[] to e[], put pointers to e[] in s[], and sort s[]. Also compute
the initial number of bins (minus 1). */
if ((e = (uzoff_t *)malloc(n * sizeof(uzoff_t))) == NULL ||
(s = (uzoff_t **)malloc(n * sizeof(uzoff_t *))) == NULL)
{
if (e != NULL)
free((zvoid *)e);
ziperr(ZE_MEM, "was trying a smart split");
return 0; /* only to make compiler happy */
}
memcpy((char *)e, (char *)a, n * sizeof(uzoff_t));
for (t = i = 0; i < n; i++)
t += *(s[i] = e + i);
m = (extent)((t + c - 1) / c) - 1; /* pre-decrement for loop */
qsort((char *)s, n, sizeof(ulg *), descmp);
/* Stuff bins until successful */
do {
/* Increment the number of bins, allocate and initialize bins */
if ((b = (uzoff_t *)malloc(++m * sizeof(uzoff_t))) == NULL)
{
free((zvoid *)s);
free((zvoid *)e);
ziperr(ZE_MEM, "was trying a smart split");
}
b[0] = c - d; /* leave space in first bin */
for (j = 1; j < m; j++)
b[j] = c;
/* Fill the bins greedily */
for (i = 0; i < n; i++)
{
/* Find smallest bin that will hold item i (size s[i]) */
t = c + 1;
for (k = j = 0; j < m; j++)
if (*s[i] <= b[j] && b[j] < t)
t = b[k = j];
/* If no bins big enough for *s[i], try next m */
if (t == c + 1)
break;
/* Diminish that bin and save where it goes */
b[k] -= *s[i];
a[(int)((uzoff_t huge *)(s[i]) - (uzoff_t huge *)e)] = k;
}
/* Clean up */
free((zvoid *)b);
/* Do until all items put in a bin */
} while (i < n);
/* Done--clean up and return the number of bins needed */
free((zvoid *)s);
free((zvoid *)e);
return m;
}
/* keep compiler happy until implement long options - 11/4/2003 EG */
struct option_struct far options[] = {
/* short longopt value_type negatable ID name */
{"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
/* the end of the list */
{NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
};
local int retry()
{
char m[10];
fputs("Error writing to disk--redo entire disk? ", mesg);
fgets(m, 10, stdin);
return *m == 'y' || *m == 'Y';
}
#ifndef USE_ZIPSPLITMAIN
int main(argc, argv)
#else
int zipsplitmain(argc, argv)
#endif
int argc; /* number of tokens in command line */
char **argv; /* command line tokens */
/* Split a zip file into several zip files less than a specified size. See
the command help in help() above. */
{
uzoff_t *a; /* malloc'ed list of sizes, dest bins */
extent *b; /* heads of bin linked lists (malloc'ed) */
uzoff_t c; /* bin capacity, start of central directory */
int d; /* if true, just report the number of disks */
FILE *e; /* input zip file */
FILE *f; /* output index and zip files */
extent g; /* number of bins from greedy(), entry to write */
int h; /* how to split--true means simple split, counter */
zoff_t i = 0; /* size of index file plus room to leave */
extent j; /* steps through zip entries, bins */
int k; /* next argument type */
extent *n = NULL; /* next item in bin list (heads in b) */
uzoff_t *p; /* malloc'ed list of sizes, dest bins for greedy() */
char *q; /* steps through option characters */
int r; /* temporary variable, counter */
extent s; /* number of bins needed */
zoff_t t; /* total of sizes, end of central directory */
int u; /* flag to wait for user on output files */
struct zlist far **w; /* malloc'ed table for zfiles linked list */
int x; /* if true, make an index file */
struct zlist far *z; /* steps through zfiles linked list */
#ifdef AMIGA
char tailchar; /* temporary variable used in name generation below */
#endif
char errbuf[5000];
#ifdef THEOS
setlocale(LC_CTYPE, "I");
#endif
#ifdef UNICODE_SUPPORT
# ifdef UNIX
/* For Unix, set the locale to UTF-8. Any UTF-8 locale is
OK and they should all be the same. This allows seeing,
writing, and displaying (if the fonts are loaded) all
characters in UTF-8. */
{
char *loc;
/*
loc = setlocale(LC_CTYPE, NULL);
printf(" Initial language locale = '%s'\n", loc);
*/
loc = setlocale(LC_CTYPE, "en_US.UTF-8");
/*
printf("langinfo %s\n", nl_langinfo(CODESET));
*/
if (loc != NULL) {
/* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
using_utf8 = 1;
/*
printf(" Locale set to %s\n", loc);
*/
} else {
/*
printf(" Could not set Unicode UTF-8 locale\n");
*/
}
}
# endif
#endif
/* If no args, show help */
if (argc == 1)
{
help();
EXIT(ZE_OK);
}
/* Informational messages are written to stdout. */
mesg = stdout;
/* Go through args */
signal(SIGINT, handler);
#ifdef SIGTERM /* Amiga has no SIGTERM */
signal(SIGTERM, handler);
#endif
#ifdef SIGABRT
signal(SIGABRT, handler);
#endif
#ifdef SIGBREAK
signal(SIGBREAK, handler);
#endif
#ifdef SIGBUS
signal(SIGBUS, handler);
#endif
#ifdef SIGILL
signal(SIGILL, handler);
#endif
#ifdef SIGSEGV
signal(SIGSEGV, handler);
#endif
k = h = x = d = u = 0;
c = DEFSIZ;
for (r = 1; r < argc; r++)
if (*argv[r] == '-')
{
if (argv[r][1])
for (q = argv[r]+1; *q; q++)
switch (*q)
{
case 'b': /* Specify path for output files */
if (k)
ziperr(ZE_PARMS, "options are separate and precede zip file");
else
k = 1; /* Next non-option is path */
break;
case 'h': /* Show help */
help(); EXIT(ZE_OK);
case 'i': /* Make an index file */
x = 1;
break;
case 'l': case 'L': /* Show copyright and disclaimer */
license(); EXIT(ZE_OK);
case 'n': /* Specify maximum size of resulting zip files */
if (k)
ziperr(ZE_PARMS, "options are separate and precede zip file");
else
k = 2; /* Next non-option is size */
break;
case 'p':
u = 1;
break;
case 'q': /* Quiet operation, suppress info messages */
noisy = 0;
break;
case 'r':
if (k)
ziperr(ZE_PARMS, "options are separate and precede zip file");
else
k = 3; /* Next non-option is room to leave */
break;
case 's':
h = 1; /* Only try simple */
break;
case 't': /* Just report number of disks */
d = 1;
break;
case 'v': /* Show version info */
version_info(); EXIT(ZE_OK);
default:
ziperr(ZE_PARMS, "Use option -h for help.");
}
else
ziperr(ZE_PARMS, "zip file cannot be stdin");
}
else
switch (k)
{
case 0:
if (zipfile == NULL)
{
if ((zipfile = ziptyp(argv[r])) == NULL)
ziperr(ZE_MEM, "was processing arguments");
}
else
ziperr(ZE_PARMS, "can only specify one zip file");
break;
case 1:
tempath = argv[r];
k = 0;
break;
case 2:
if ((c = (ulg)atol(argv[r])) < 100) /* 100 is smallest zip file */
ziperr(ZE_PARMS, "invalid size given. Use option -h for help.");
k = 0;
break;
default: /* k must be 3 */
i = (ulg)atol(argv[r]);
k = 0;
break;
}
if (zipfile == NULL)
ziperr(ZE_PARMS, "need to specify zip file");
if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
ziperr(ZE_MEM, "input");
}
strcpy(in_path, zipfile);
/* Read zip file */
if ((r = readzipfile()) != ZE_OK)
ziperr(r, zipfile);
if (zfiles == NULL)
ziperr(ZE_NAME, zipfile);
/* Make a list of sizes and check against capacity. Also compute the
size of the index file. */
c -= ENDHEAD + 4; /* subtract overhead/zipfile */
if ((a = (uzoff_t *)talloc(zcount * sizeof(uzoff_t))) == NULL ||
(w = (struct zlist far **)talloc(zcount * sizeof(struct zlist far *))) ==
NULL)
{
ziperr(ZE_MEM, "was computing split");
return 1;
}
t = 0;
for (j = 0, z = zfiles; j < zcount; j++, z = z->nxt)
{
w[j] = z;
if (x)
i += z->nam + 6 + NL;
/* New scanzip_reg only reads central directory so use cext for ext */
t += a[j] = 8 + LOCHEAD + CENHEAD +
2 * (zoff_t)z->nam + 2 * (zoff_t)z->cext + z->com + z->siz;
if (a[j] > c) {
sprintf(errbuf, "Entry is larger than max split size of: %s",
zip_fzofft(c, NULL, "u"));
zipwarn(errbuf, "");
zipwarn("use -n to set split size", "");
ziperr(ZE_BIG, z->zname);
}
}
/* Decide on split to use, report number of files */
if (h)
s = simple(a, zcount, c, i);
else
{
if ((p = (uzoff_t *)talloc(zcount * sizeof(uzoff_t))) == NULL)
ziperr(ZE_MEM, "was computing split");
memcpy((char *)p, (char *)a, zcount * sizeof(uzoff_t));
s = simple(a, zcount, c, i);
g = greedy(p, zcount, c, i);
if (s <= g)
tfree((zvoid *)p);
else
{
tfree((zvoid *)a);
a = p;
s = g;
}
}
printf("%ld zip files w%s be made (%s%% efficiency)\n",
(ulg)s, d ? "ould" : "ill",
zip_fzofft( ((200 * ((t + c - 1)/c)) / s + 1) / 2, NULL, "d"));
if (d)
{
tfreeall();
free((zvoid *)zipfile);
zipfile = NULL;
EXIT(ZE_OK);
}
/* Set up path for output files */
/* Point "name" past the path, where the filename should go */
if ((path = (char *)talloc(tempath == NULL ? 13 : strlen(tempath) + 14)) ==
NULL)
ziperr(ZE_MEM, "was making output file names");
if (tempath == NULL)
name = path;
else
{
#ifndef VM_CMS
/* Copy the output path to the target */
strcpy(path, tempath);
#endif
#ifdef AMIGA
tailchar = path[strlen(path) - 1]; /* last character */
if (path[0] && (tailchar != '/') && (tailchar != ':'))
strcat(path, "/");
#else
#ifdef RISCOS
if (path[0] && path[strlen(path) - 1] != '.')
strcat(path, ".");
#else
#ifdef QDOS
if (path[0] && path[strlen(path) - 1] != '_')
strcat(path, "_");
#else
#ifndef VMS
if (path[0] && path[strlen(path) - 1] != '/')
strcat(path, "/");
#endif /* !VMS */
#endif /* ?QDOS */
#endif /* ?RISCOS */
#endif /* ?AMIGA */
name = path + strlen(path);
}
/* Make linked lists of results */
if ((b = (extent *)talloc(s * sizeof(extent))) == NULL ||
(n = (extent *)talloc(zcount * sizeof(extent))) == NULL)
ziperr(ZE_MEM, "was computing split");
for (j = 0; j < s; j++)
b[j] = (extent)-1;
j = zcount;
while (j--)
{
g = (extent)a[j];
n[j] = b[g];
b[g] = j;
}
/* Make a name template for the zip files that is eight or less characters
before the .zip, and that will not overwrite the original zip file. */
for (k = 1, j = s; j >= 10; j /= 10)
k++;
if (k > 7)
ziperr(ZE_PARMS, "way too many zip files must be made");
/*
* XXX, ugly ....
*/
/* Find the final "path" separator character */
#ifdef QDOS
q = LastDir(zipfile);
#else
#ifdef VMS
if ((q = strrchr(zipfile, ']')) != NULL)
#else
#ifdef AMIGA
if (((q = strrchr(zipfile, '/')) != NULL)
|| ((q = strrchr(zipfile, ':'))) != NULL)
#else
#ifdef RISCOS
if ((q = strrchr(zipfile, '.')) != NULL)
#else
#ifdef MVS
if ((q = strrchr(zipfile, '.')) != NULL)
#else
if ((q = strrchr(zipfile, '/')) != NULL)
#endif /* MVS */
#endif /* RISCOS */
#endif /* AMIGA */
#endif /* VMS */
q++;
else
q = zipfile;
#endif /* QDOS */
r = 0;
while ((g = *q++) != '\0' && g != ZPATH_SEP && r < 8 - k)
template[r++] = (char)g;
if (r == 0)
template[r++] = '_';
else if (g >= '0' && g <= '9')
template[r - 1] = (char)(template[r - 1] == '_' ? '-' : '_');
sprintf(template + r, TEMPL_FMT, k);
#ifdef VM_CMS
/* For CMS, add the "path" as the filemode at the end */
if (tempath)
{
strcat(template,".");
strcat(template,tempath);
}
#endif
/* Make the zip files from the linked lists of entry numbers */
if ((e = fopen(zipfile, FOPR)) == NULL)
ziperr(ZE_NAME, zipfile);
free((zvoid *)zipfile);
zipfile = NULL;
for (j = 0; j < s; j++)
{
/* jump here on a disk retry */
redobin:
current_disk = 0;
cd_start_disk = 0;
cd_entries_this_disk = 0;
/* prompt if requested */
if (u)
{
char m[10];
fprintf(mesg, "Insert disk #%ld of %ld and hit return: ",
(ulg)j + 1, (ulg)s);
fgets(m, 10, stdin);
}
/* write index file on first disk if requested */
if (j == 0 && x)
{
strcpy(name, INDEX);
printf("creating: %s\n", path);
indexmade = 1;
if ((f = fopen(path, "w")) == NULL)
{
if (u && retry()) goto redobin;
ziperr(ZE_CREAT, path);
}
for (j = 0; j < zcount; j++)
fprintf(f, "%5s %s\n",
zip_fzofft( (a[j] + 1), NULL, "d"), w[j]->zname);
if ((j = ferror(f)) != 0 || fclose(f))
{
if (j)
fclose(f);
if (u && retry()) goto redobin;
ziperr(ZE_WRITE, path);
}
}
/* create output zip file j */
sprintf(name, template, j + 1L);
printf("creating: %s\n", path);
zipsmade = j + 1;
if ((y = f = fopen(path, FOPW)) == NULL)
{
if (u && retry()) goto redobin;
ziperr(ZE_CREAT, path);
}
bytes_this_split = 0;
tempzn = 0;
/* write local headers and copy compressed data */
for (g = b[j]; g != (extent)-1; g = (extent)n[g])
{
if (zfseeko(e, w[g]->off, SEEK_SET))
ziperr(ferror(e) ? ZE_READ : ZE_EOF, zipfile);
in_file = e;
if ((r = zipcopy(w[g])) != ZE_OK)
{
if (r == ZE_TEMP)
{
if (u && retry()) goto redobin;
ziperr(ZE_WRITE, path);
}
else
ziperr(r, zipfile);
}
}
/* write central headers */
if ((c = zftello(f)) == (uzoff_t)-1)
{
if (u && retry()) goto redobin;
ziperr(ZE_WRITE, path);
}
for (g = b[j], k = 0; g != (extent)-1; g = n[g], k++)
if ((r = putcentral(w[g])) != ZE_OK)
{
if (u && retry()) goto redobin;
ziperr(ZE_WRITE, path);
}
/* write end-of-central header */
cd_start_offset = c;
total_cd_entries = k;
if ((t = zftello(f)) == (zoff_t)-1 ||
(r = putend((zoff_t)k, t - c, c, (extent)0, (char *)NULL)) !=
ZE_OK ||
ferror(f) || fclose(f))
{
if (u && retry()) goto redobin;
ziperr(ZE_WRITE, path);
}
#ifdef RISCOS
/* Set the filetype to &DDC */
setfiletype(path,0xDDC);
#endif
}
fclose(e);
/* Done! */
if (u)
fputs("Done.\n", mesg);
tfreeall();
RETURN(0);
}

1829
third_party/zip/zipup.c vendored Normal file

File diff suppressed because it is too large Load diff

20
third_party/zip/zipup.h vendored Normal file
View file

@ -0,0 +1,20 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_INFOZIP_ZIP_UNIX_ZIPUP_H_
#define COSMOPOLITAN_THIRD_PARTY_INFOZIP_ZIP_UNIX_ZIPUP_H_
#include "libc/calls/calls.h"
#include "libc/sysv/consts/o.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define fhow O_RDONLY
#define fbad (-1)
#define zopen(n, p) open(n, p)
#define zread(f, b, n) read(f, b, n)
#define zclose(f) close(f)
#define zerr(f) (k == (extent)(-1L))
#define zstdin 0
typedef int ftype;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_INFOZIP_ZIP_UNIX_ZIPUP_H_ */