gzip: use the outsourced packages.
* remove gzip Jamfile from the build and gzip sources from the tree.
This commit is contained in:
parent
45287a58ff
commit
1f56c11b79
2
Jamfile
2
Jamfile
@ -26,7 +26,7 @@ AddHaikuImagePackages [ FFilterByBuildFeatures
|
||||
bash coreutils curl freetype icu libsolv zlib
|
||||
|
||||
regular_image @{
|
||||
bzip2 ctags ffmpeg findutils gawk glu grep gutenprint jasper jpeg
|
||||
bzip2 ctags ffmpeg findutils gawk glu grep gutenprint gzip jasper jpeg
|
||||
less libicns libpcap libpng libpng16 libwebp
|
||||
mesa mesa_devel mesa_swrast
|
||||
netcat
|
||||
|
@ -10,7 +10,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
|
||||
eject error
|
||||
fdinfo ffm filepanel finddir findpaths fortune fstrim
|
||||
ftp ftpd
|
||||
getarch groupadd groupdel groupmod gzip gzexe
|
||||
getarch groupadd groupdel groupmod
|
||||
hd hey
|
||||
ideinfo@ide idestatus@ide ifconfig iroster isvolume
|
||||
kernel_debugger keymap keystore
|
||||
@ -34,7 +34,6 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
|
||||
uptime urlwrapper useradd userdel
|
||||
version vmstat
|
||||
waitfor watch writembr@x86,x86_64 xres
|
||||
zdiff zforce zgrep zmore znew
|
||||
] ;
|
||||
|
||||
SYSTEM_APPS = [ FFilterByBuildFeatures
|
||||
|
@ -122,9 +122,6 @@ AddFilesToPackage bin : install-wifi-firmwares.sh ;
|
||||
|
||||
AddSymlinkToPackage bin : trash : untrash ;
|
||||
AddSymlinkToPackage bin : less : more ;
|
||||
AddSymlinkToPackage bin : gzip : gunzip ;
|
||||
AddSymlinkToPackage bin : gzip : zcat ;
|
||||
AddSymlinkToPackage bin : zdiff : zcmp ;
|
||||
|
||||
# scripts and data files
|
||||
local bootScripts = Bootscript Bootscript.cd SetupEnvironment
|
||||
|
@ -119,9 +119,6 @@ AddFilesToPackage bin : install-wifi-firmwares.sh ;
|
||||
|
||||
AddSymlinkToPackage bin : trash : untrash ;
|
||||
AddSymlinkToPackage bin : less : more ;
|
||||
AddSymlinkToPackage bin : gzip : gunzip ;
|
||||
AddSymlinkToPackage bin : gzip : zcat ;
|
||||
AddSymlinkToPackage bin : zdiff : zcmp ;
|
||||
|
||||
# scripts and data files
|
||||
local bootScripts = Bootscript Bootscript.cd SetupEnvironment
|
||||
|
@ -296,8 +296,5 @@ SubInclude HAIKU_TOP src bin debug ;
|
||||
# Network command line tools
|
||||
SubInclude HAIKU_TOP src bin network ;
|
||||
|
||||
# Compression command line tools
|
||||
SubInclude HAIKU_TOP src bin gzip ;
|
||||
|
||||
# Other stuff
|
||||
SubInclude HAIKU_TOP src bin filteredquery ;
|
||||
|
@ -1,37 +0,0 @@
|
||||
SubDir HAIKU_TOP src bin gzip ;
|
||||
|
||||
SubDirCcFlags -w ;
|
||||
|
||||
BinCommand gzip :
|
||||
gzip.c
|
||||
zip.c
|
||||
deflate.c
|
||||
trees.c
|
||||
bits.c
|
||||
unzip.c
|
||||
inflate.c
|
||||
util.c
|
||||
lzw.c
|
||||
unlzw.c
|
||||
unpack.c
|
||||
unlzh.c
|
||||
crypt.c
|
||||
: be
|
||||
;
|
||||
|
||||
{
|
||||
MakeLocatePlatform <bin>zdiff ;
|
||||
Shell <bin>zdiff : zdiff ;
|
||||
MakeLocatePlatform <bin>zgrep ;
|
||||
Shell <bin>zgrep : zgrep ;
|
||||
MakeLocatePlatform <bin>zmore ;
|
||||
Shell <bin>zmore : zmore ;
|
||||
MakeLocatePlatform <bin>znew ;
|
||||
Shell <bin>znew : znew ;
|
||||
MakeLocatePlatform <bin>zforce ;
|
||||
Shell <bin>zforce : zforce ;
|
||||
MakeLocatePlatform <bin>zfile ;
|
||||
Shell <bin>zfile : zfile ;
|
||||
MakeLocatePlatform <bin>gzexe ;
|
||||
Shell <bin>gzexe : gzexe ;
|
||||
}
|
@ -1,205 +0,0 @@
|
||||
/* bits.c -- output variable-length bit strings
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* PURPOSE
|
||||
*
|
||||
* Output variable-length bit strings. Compression can be done
|
||||
* to a file or to memory. (The latter is not supported in this version.)
|
||||
*
|
||||
* DISCUSSION
|
||||
*
|
||||
* The PKZIP "deflate" file format interprets compressed file data
|
||||
* as a sequence of bits. Multi-bit strings in the file may cross
|
||||
* byte boundaries without restriction.
|
||||
*
|
||||
* The first bit of each byte is the low-order bit.
|
||||
*
|
||||
* The routines in this file allow a variable-length bit value to
|
||||
* be output right-to-left (useful for literal values). For
|
||||
* left-to-right output (useful for code strings from the tree routines),
|
||||
* the bits must have been reversed first with bi_reverse().
|
||||
*
|
||||
* For in-memory compression, the compressed bit stream goes directly
|
||||
* into the requested output buffer. The input data is read in blocks
|
||||
* by the mem_read() function. The buffer is limited to 64K on 16 bit
|
||||
* machines.
|
||||
*
|
||||
* INTERFACE
|
||||
*
|
||||
* void bi_init (FILE *zipfile)
|
||||
* Initialize the bit string routines.
|
||||
*
|
||||
* void send_bits (int value, int length)
|
||||
* Write out a bit string, taking the source bits right to
|
||||
* left.
|
||||
*
|
||||
* int bi_reverse (int value, int length)
|
||||
* Reverse the bits of a bit string, taking the source bits left to
|
||||
* right and emitting them right to left.
|
||||
*
|
||||
* void bi_windup (void)
|
||||
* Write out any remaining bits in an incomplete byte.
|
||||
*
|
||||
* void copy_block(char *buf, unsigned len, int header)
|
||||
* Copy a stored block to the zip file, storing first the length and
|
||||
* its one's complement if requested.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: bits.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Local data used by the "bit string" routines.
|
||||
*/
|
||||
|
||||
local file_t zfile; /* output gzip file */
|
||||
|
||||
local unsigned short bi_buf;
|
||||
/* Output buffer. bits are inserted starting at the bottom (least significant
|
||||
* bits).
|
||||
*/
|
||||
|
||||
#define Buf_size (8 * 2*sizeof(char))
|
||||
/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
||||
* more than 16 bits on some systems.)
|
||||
*/
|
||||
|
||||
local int bi_valid;
|
||||
/* Number of valid bits in bi_buf. All bits above the last valid bit
|
||||
* are always zero.
|
||||
*/
|
||||
|
||||
int (*read_buf) OF((char *buf, unsigned size));
|
||||
/* Current input function. Set to mem_read for in-memory compression */
|
||||
|
||||
#ifdef DEBUG
|
||||
ulg bits_sent; /* bit length of the compressed data */
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Initialize the bit string routines.
|
||||
*/
|
||||
void bi_init (zipfile)
|
||||
file_t zipfile; /* output zip file, NO_FILE for in-memory compression */
|
||||
{
|
||||
zfile = zipfile;
|
||||
bi_buf = 0;
|
||||
bi_valid = 0;
|
||||
#ifdef DEBUG
|
||||
bits_sent = 0L;
|
||||
#endif
|
||||
|
||||
/* Set the defaults for file compression. They are set by memcompress
|
||||
* for in-memory compression.
|
||||
*/
|
||||
if (zfile != NO_FILE) {
|
||||
read_buf = file_read;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Send a value on a given number of bits.
|
||||
* IN assertion: length <= 16 and value fits in length bits.
|
||||
*/
|
||||
void send_bits(value, length)
|
||||
int value; /* value to send */
|
||||
int length; /* number of bits */
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Tracev((stderr," l %2d v %4x ", length, value));
|
||||
Assert(length > 0 && length <= 15, "invalid length");
|
||||
bits_sent += (ulg)length;
|
||||
#endif
|
||||
/* If not enough room in bi_buf, use (valid) bits from bi_buf and
|
||||
* (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
|
||||
* unused bits in value.
|
||||
*/
|
||||
if (bi_valid > (int)Buf_size - length) {
|
||||
bi_buf |= (value << bi_valid);
|
||||
put_short(bi_buf);
|
||||
bi_buf = (ush)value >> (Buf_size - bi_valid);
|
||||
bi_valid += length - Buf_size;
|
||||
} else {
|
||||
bi_buf |= value << bi_valid;
|
||||
bi_valid += length;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Reverse the first len bits of a code, using straightforward code (a faster
|
||||
* method would use a table)
|
||||
* IN assertion: 1 <= len <= 15
|
||||
*/
|
||||
unsigned bi_reverse(code, len)
|
||||
unsigned code; /* the value to invert */
|
||||
int len; /* its bit length */
|
||||
{
|
||||
register unsigned res = 0;
|
||||
do {
|
||||
res |= code & 1;
|
||||
code >>= 1, res <<= 1;
|
||||
} while (--len > 0);
|
||||
return res >> 1;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Write out any remaining bits in an incomplete byte.
|
||||
*/
|
||||
void bi_windup()
|
||||
{
|
||||
if (bi_valid > 8) {
|
||||
put_short(bi_buf);
|
||||
} else if (bi_valid > 0) {
|
||||
put_byte(bi_buf);
|
||||
}
|
||||
bi_buf = 0;
|
||||
bi_valid = 0;
|
||||
#ifdef DEBUG
|
||||
bits_sent = (bits_sent+7) & ~7;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Copy a stored block to the zip file, storing first the length and its
|
||||
* one's complement if requested.
|
||||
*/
|
||||
void copy_block(buf, len, header)
|
||||
char *buf; /* the input data */
|
||||
unsigned len; /* its length */
|
||||
int header; /* true if block header must be written */
|
||||
{
|
||||
bi_windup(); /* align on byte boundary */
|
||||
|
||||
if (header) {
|
||||
put_short((ush)len);
|
||||
put_short((ush)~len);
|
||||
#ifdef DEBUG
|
||||
bits_sent += 2*16;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
bits_sent += (ulg)len<<3;
|
||||
#endif
|
||||
while (len--) {
|
||||
#ifdef CRYPT
|
||||
int t;
|
||||
if (key) zencode(*buf, t);
|
||||
#endif
|
||||
put_byte(*buf++);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
/* crypt.c (dummy version) -- do not perform encryption
|
||||
* Hardly worth copyrighting :-)
|
||||
*/
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: crypt.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
/* crypt.h (dummy version) -- do not perform encryption
|
||||
* Hardly worth copyrighting :-)
|
||||
*/
|
||||
|
||||
#ifdef CRYPT
|
||||
# undef CRYPT /* dummy version */
|
||||
#endif
|
||||
|
||||
#define RAND_HEAD_LEN 12 /* length of encryption random header */
|
||||
|
||||
#define zencode
|
||||
#define zdecode
|
@ -1,763 +0,0 @@
|
||||
/* deflate.c -- compress data using the deflation algorithm
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "lzw.h" /* just for consistency checking */
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: deflate.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* 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
|
||||
|
||||
/* To save space (see unlzw.c), we overlay prev+head with tab_prefix and
|
||||
* window with tab_suffix. Check that we can do this:
|
||||
*/
|
||||
#if (WSIZE<<1) > (1<<BITS)
|
||||
error: cannot overlay window with tab_suffix and prev with tab_prefix0
|
||||
#endif
|
||||
#if HASH_BITS > BITS-1
|
||||
error: cannot overlay head with tab_prefix1
|
||||
#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 */
|
||||
|
||||
/* ===========================================================================
|
||||
* Local data used by the "longest match" routines.
|
||||
*/
|
||||
|
||||
typedef ush Pos;
|
||||
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.
|
||||
*/
|
||||
|
||||
/* DECLARE(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+BSZ if SMALL_MEM (the code would
|
||||
* be less efficient).
|
||||
*/
|
||||
|
||||
/* DECLARE(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.
|
||||
*/
|
||||
|
||||
/* DECLARE(Pos, head, 1<<HASH_BITS); */
|
||||
/* Heads of the hash chains or NIL. */
|
||||
|
||||
ulg window_size = (ulg)2*WSIZE;
|
||||
/* 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 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.
|
||||
*/
|
||||
|
||||
local int compr_level;
|
||||
/* compression level (1..9) */
|
||||
|
||||
unsigned near good_match;
|
||||
/* Use a faster search when the previous match is longer than this */
|
||||
|
||||
|
||||
/* Values for max_lazy_match, good_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;
|
||||
|
||||
#ifdef FULL_SEARCH
|
||||
# define nice_match MAX_MATCH
|
||||
#else
|
||||
int near nice_match; /* Stop searching when current match exceeds this */
|
||||
#endif
|
||||
|
||||
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 ulg deflate_fast OF((void));
|
||||
|
||||
int longest_match OF((IPos cur_match));
|
||||
#ifdef ASMV
|
||||
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
|
||||
*/
|
||||
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");
|
||||
compr_level = pack_level;
|
||||
|
||||
/* Initialize the hash table. */
|
||||
#if defined(MAXSEG_64K) && HASH_BITS == 15
|
||||
for (j = 0; j < HASH_SIZE; j++) head[j] = NIL;
|
||||
#else
|
||||
memzero((char*)head, HASH_SIZE*sizeof(*head));
|
||||
#endif
|
||||
/* prev will be initialized on the fly */
|
||||
|
||||
/* 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 == 1) {
|
||||
*flags |= FAST;
|
||||
} else if (pack_level == 9) {
|
||||
*flags |= SLOW;
|
||||
}
|
||||
/* ??? reduce max_chain_length for binary files */
|
||||
|
||||
strstart = 0;
|
||||
block_start = 0L;
|
||||
#ifdef ASMV
|
||||
match_init(); /* initialize the asm code */
|
||||
#endif
|
||||
|
||||
lookahead = read_buf((char*)window,
|
||||
sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE);
|
||||
|
||||
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.
|
||||
*/
|
||||
while (lookahead < MIN_LOOKAHEAD && !eofile) 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.
|
||||
*/
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* 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 MSDOS, OS/2 and 386 Unix, 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 *scan = window + strstart; /* current string */
|
||||
register uch *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 *strend = window + strstart + MAX_MATCH - 1;
|
||||
register ush scan_start = *(ush*)scan;
|
||||
register ush scan_end = *(ush*)(scan+best_len-1);
|
||||
#else
|
||||
register uch *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*)(match+best_len-1) != scan_end ||
|
||||
*(ush*)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*)(scan+=2) == *(ush*)(match+=2) &&
|
||||
*(ush*)(scan+=2) == *(ush*)(match+=2) &&
|
||||
*(ush*)(scan+=2) == *(ush*)(match+=2) &&
|
||||
*(ush*)(scan+=2) == *(ush*)(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);
|
||||
|
||||
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*)(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(stderr,
|
||||
" start %d, match %d, length %d\n",
|
||||
start, match, length);
|
||||
error("invalid match");
|
||||
}
|
||||
if (verbose > 1) {
|
||||
fprintf(stderr,"\\[%d,%d]", start-match, length);
|
||||
do { putc(window[start++], stderr); } while (--length != 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define check_match(start, match, length)
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* 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: 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 = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart);
|
||||
/* Amount of free space at the end of the window. */
|
||||
|
||||
/* 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--;
|
||||
} else if (strstart >= WSIZE+MAX_DIST) {
|
||||
/* By the IN assertion, the window is not empty so we can't confuse
|
||||
* more == 0 with more == 64K on a 16 bit machine.
|
||||
*/
|
||||
Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM");
|
||||
|
||||
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;
|
||||
}
|
||||
/* At this point, more >= 2 */
|
||||
if (!eofile) {
|
||||
n = read_buf((char*)window+strstart+lookahead, more);
|
||||
if (n == 0 || n == (unsigned)EOF) {
|
||||
eofile = 1;
|
||||
} else {
|
||||
lookahead += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* 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, (long)strstart - block_start, (eof))
|
||||
|
||||
/* ===========================================================================
|
||||
* Processes a new input file and return its compressed length. This
|
||||
* function does not perform lazy evaluationof 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 ulg deflate_fast()
|
||||
{
|
||||
IPos hash_head; /* 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:
|
||||
*/
|
||||
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).
|
||||
*/
|
||||
match_length = longest_match (hash_head);
|
||||
/* longest_match() sets match_start */
|
||||
if (match_length > lookahead) match_length = lookahead;
|
||||
}
|
||||
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) {
|
||||
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. If lookahead < MIN_MATCH
|
||||
* these bytes are garbage, but it does not matter since
|
||||
* the next lookahead bytes will be emitted as literals.
|
||||
*/
|
||||
} 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.
|
||||
*/
|
||||
while (lookahead < MIN_LOOKAHEAD && !eofile) 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.
|
||||
*/
|
||||
ulg deflate()
|
||||
{
|
||||
IPos hash_head; /* 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 long isize; /* byte length of input file, for debug only */
|
||||
#endif
|
||||
|
||||
if (compr_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:
|
||||
*/
|
||||
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).
|
||||
*/
|
||||
match_length = longest_match (hash_head);
|
||||
/* longest_match() sets match_start */
|
||||
if (match_length > lookahead) match_length = lookahead;
|
||||
|
||||
/* Ignore a length 3 match if it is too distant: */
|
||||
if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){
|
||||
/* If prev_match is also MIN_MATCH, match_start is garbage
|
||||
* but we will ignore the current match anyway.
|
||||
*/
|
||||
match_length--;
|
||||
}
|
||||
}
|
||||
/* 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) {
|
||||
|
||||
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;
|
||||
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);
|
||||
match_available = 0;
|
||||
match_length = MIN_MATCH-1;
|
||||
strstart++;
|
||||
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.
|
||||
*/
|
||||
while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window();
|
||||
}
|
||||
if (match_available) ct_tally (0, window[strstart-1]);
|
||||
|
||||
return FLUSH_BLOCK(1); /* eof */
|
||||
}
|
@ -1,755 +0,0 @@
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef __STDC__
|
||||
# ifndef const
|
||||
# define const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tailor.h"
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||
long-named option. Because this is not POSIX.2 compliant, it is
|
||||
being phased out. */
|
||||
/* #define GETOPT_COMPAT */
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = 0;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
#define BAD_OPTION '\0'
|
||||
int optopt = BAD_OPTION;
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#define my_strlen strlen
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
#if __STDC__ || defined(PROTO)
|
||||
extern char *getenv(const char *name);
|
||||
extern int strcmp (const char *s1, const char *s2);
|
||||
extern int strncmp(const char *s1, const char *s2, int n);
|
||||
|
||||
static int my_strlen(const char *s);
|
||||
static char *my_index (const char *str, int chr);
|
||||
#else
|
||||
extern char *getenv ();
|
||||
#endif
|
||||
|
||||
static int
|
||||
my_strlen (str)
|
||||
const char *str;
|
||||
{
|
||||
int n = 0;
|
||||
while (*str++)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved.
|
||||
|
||||
To perform the swap, we first reverse the order of all elements. So
|
||||
all options now come before all non options, but they are in the
|
||||
wrong order. So we put back the options and non options in original
|
||||
order by reversing them again. For example:
|
||||
original input: a b c -x -y
|
||||
reverse all: -y -x c b a
|
||||
reverse options: -x -y c b a
|
||||
reverse non options: -x -y a b c
|
||||
*/
|
||||
|
||||
#if __STDC__ || defined(PROTO)
|
||||
static void exchange (char **argv);
|
||||
#endif
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
char *temp, **first, **last;
|
||||
|
||||
/* Reverse all the elements [first_nonopt, optind) */
|
||||
first = &argv[first_nonopt];
|
||||
last = &argv[optind-1];
|
||||
while (first < last) {
|
||||
temp = *first; *first = *last; *last = temp; first++; last--;
|
||||
}
|
||||
/* Put back the options in order */
|
||||
first = &argv[first_nonopt];
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last = &argv[first_nonopt - 1];
|
||||
while (first < last) {
|
||||
temp = *first; *first = *last; *last = temp; first++; last--;
|
||||
}
|
||||
|
||||
/* Put back the non options in order */
|
||||
first = &argv[first_nonopt];
|
||||
last_nonopt = optind;
|
||||
last = &argv[last_nonopt-1];
|
||||
while (first < last) {
|
||||
temp = *first; *first = *last; *last = temp; first++; last--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return BAD_OPTION after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return BAD_OPTION.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
int option_index;
|
||||
|
||||
optarg = 0;
|
||||
|
||||
/* Initialize the internal data when the first call is made.
|
||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
if (optind == 0)
|
||||
{
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
}
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Now skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
if (longopts != NULL
|
||||
&& ((argv[optind][0] == '-'
|
||||
&& (argv[optind][1] == '-' || long_only))
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
))
|
||||
{
|
||||
const struct option *p;
|
||||
char *s = nextchar;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
const struct option *pfound = NULL;
|
||||
int indfound = 0;
|
||||
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
|
||||
/* Test all options for either exact match or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name;
|
||||
p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||
{
|
||||
if (s - nextchar == my_strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += my_strlen (nextchar);
|
||||
optind++;
|
||||
return BAD_OPTION;
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*s)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = s + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
"%s: option `--%s' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += my_strlen (nextchar);
|
||||
return BAD_OPTION;
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += my_strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : BAD_OPTION;
|
||||
}
|
||||
}
|
||||
nextchar += my_strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return BAD_OPTION;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
return BAD_OPTION;
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = 0;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = BAD_OPTION;
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case BAD_OPTION:
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
@ -1,127 +0,0 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if __STDC__ || defined(PROTO)
|
||||
#if defined(__GNU_LIBRARY__)
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* not __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
@ -1,150 +0,0 @@
|
||||
#!/bin/sh
|
||||
# gzexe: compressor for Unix executables.
|
||||
# Use this only for binaries that you do not use frequently.
|
||||
#
|
||||
# The compressed version is a shell script which decompresses itself after
|
||||
# skipping $skip lines of shell commands. We try invoking the compressed
|
||||
# executable with the original name (for programs looking at their name).
|
||||
# We also try to retain the original file permissions on the compressed file.
|
||||
# For safety reasons, gzexe will not create setuid or setgid shell scripts.
|
||||
|
||||
# WARNING: the first line of this file must be either : or #!/bin/sh
|
||||
# The : is required for some old versions of csh.
|
||||
# On Ultrix, /bin/sh is too buggy, change the first line to: #!/bin/sh5
|
||||
|
||||
x=`basename $0`
|
||||
if test $# = 0; then
|
||||
echo compress executables. original file foo is renamed to foo~
|
||||
echo usage: ${x} [-d] files...
|
||||
echo " -d decompress the executables"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp=gz$$
|
||||
trap "rm -f $tmp; exit 1" 1 2 3 5 10 13 15
|
||||
|
||||
decomp=0
|
||||
res=0
|
||||
test "$x" = "ungzexe" && decomp=1
|
||||
if test "x$1" = "x-d"; then
|
||||
decomp=1
|
||||
shift
|
||||
fi
|
||||
|
||||
echo hi > zfoo1$$
|
||||
echo hi > zfoo2$$
|
||||
if test -z "`(${CPMOD-cpmod} zfoo1$$ zfoo2$$) 2>&1`"; then
|
||||
cpmod=${CPMOD-cpmod}
|
||||
fi
|
||||
rm -f zfoo[12]$$
|
||||
|
||||
tail=""
|
||||
IFS="${IFS= }"; saveifs="$IFS"; IFS="${IFS}:"
|
||||
for dir in $PATH; do
|
||||
test -z "$dir" && dir=.
|
||||
if test -f $dir/tail; then
|
||||
tail="$dir/tail"
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS="$saveifs"
|
||||
if test -z "$tail"; then
|
||||
echo cannot find tail
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for i do
|
||||
if test ! -f "$i" ; then
|
||||
echo ${x}: $i not a file
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
if test $decomp -eq 0; then
|
||||
if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
|
||||
echo "${x}: $i is already gzexe'd"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
if ls -l "$i" | grep '^...[sS]' > /dev/null; then
|
||||
echo "${x}: $i has setuid permission, unchanged"
|
||||
continue
|
||||
fi
|
||||
if ls -l "$i" | grep '^......[sS]' > /dev/null; then
|
||||
echo "${x}: $i has setgid permission, unchanged"
|
||||
continue
|
||||
fi
|
||||
case "`basename $i`" in
|
||||
gzip | tail | chmod | ln | sleep | rm)
|
||||
echo "${x}: $i would depend on itself"; continue ;;
|
||||
esac
|
||||
if test -z "$cpmod"; then
|
||||
cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp
|
||||
if test -w $tmp 2>/dev/null; then
|
||||
writable=1
|
||||
else
|
||||
writable=0
|
||||
chmod u+w $tmp 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
if test $decomp -eq 0; then
|
||||
sed 1q $0 > $tmp
|
||||
sed "s|^if tail|if $tail|" >> $tmp <<'EOF'
|
||||
skip=18
|
||||
if tail +$skip $0 | "/bin"/gzip -cd > /tmp/gztmp$$; then
|
||||
/bin/chmod 700 /tmp/gztmp$$
|
||||
prog="`echo $0 | sed 's|^.*/||'`"
|
||||
if /bin/ln /tmp/gztmp$$ "/tmp/$prog" 2>/dev/null; then
|
||||
trap '/bin/rm -f /tmp/gztmp$$ "/tmp/$prog"; exit $res' 0
|
||||
(/bin/sleep 5; /bin/rm -f /tmp/gztmp$$ "/tmp/$prog") 2>/dev/null &
|
||||
/tmp/"$prog" ${1+"$@"}; res=$?
|
||||
else
|
||||
trap '/bin/rm -f /tmp/gztmp$$; exit $res' 0
|
||||
(/bin/sleep 5; /bin/rm -f /tmp/gztmp$$) 2>/dev/null &
|
||||
/tmp/gztmp$$ ${1+"$@"}; res=$?
|
||||
fi
|
||||
else
|
||||
echo Cannot decompress $0; exit 1
|
||||
fi; exit $res
|
||||
EOF
|
||||
"/bin"/gzip -cv9 "$i" >> $tmp || {
|
||||
/bin/rm -f $tmp
|
||||
echo ${x}: compression not possible for $i, file unchanged.
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
|
||||
else
|
||||
# decompression
|
||||
skip=18
|
||||
if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
|
||||
eval `sed -e 1d -e 2q "$i"`
|
||||
fi
|
||||
if tail +$skip "$i" | "/bin"/gzip -cd > $tmp; then
|
||||
:
|
||||
else
|
||||
echo ${x}: $i probably not in gzexe format, file unchanged.
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
rm -f "$i~"
|
||||
mv "$i" "$i~" || {
|
||||
echo ${x}: cannot backup $i as $i~
|
||||
rm -f $tmp
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
mv $tmp "$i" || cp -p $tmp "$i" 2>/dev/null || cp $tmp "$i" || {
|
||||
echo ${x}: cannot create $i
|
||||
rm -f $tmp
|
||||
res=1
|
||||
continue
|
||||
}
|
||||
rm -f $tmp
|
||||
if test -n "$cpmod"; then
|
||||
$cpmod "$i~" "$i" 2>/dev/null
|
||||
elif test $writable -eq 0; then
|
||||
chmod u-w $i 2>/dev/null
|
||||
fi
|
||||
done
|
||||
exit $res
|
1751
src/bin/gzip/gzip.c
1751
src/bin/gzip/gzip.c
File diff suppressed because it is too large
Load Diff
@ -1,315 +0,0 @@
|
||||
/* gzip.h -- common declarations for all gzip modules
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#if defined(__STDC__) || defined(PROTO)
|
||||
# define OF(args) args
|
||||
#else
|
||||
# define OF(args) ()
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef char *voidp;
|
||||
#endif
|
||||
|
||||
/* I don't like nested includes, but the string and io functions are used
|
||||
* too often
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#if !defined(NO_STRING_H) || defined(STDC_HEADERS)
|
||||
# include <string.h>
|
||||
# if !defined(STDC_HEADERS) && !defined(NO_MEMORY_H) && !defined(__GNUC__)
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# define memzero(s, n) memset ((voidp)(s), 0, (n))
|
||||
#else
|
||||
# include <strings.h>
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# define memcpy(d, s, n) bcopy((s), (d), (n))
|
||||
# define memcmp(s1, s2, n) bcmp((s1), (s2), (n))
|
||||
# define memzero(s, n) bzero((s), (n))
|
||||
#endif
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
# define RETSIGTYPE void
|
||||
#endif
|
||||
|
||||
#define local static
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
/* Return codes from gzip */
|
||||
#define OK 0
|
||||
#define ERROR 1
|
||||
#define WARNING 2
|
||||
|
||||
/* Compression methods (see algorithm.doc) */
|
||||
#define STORED 0
|
||||
#define COMPRESSED 1
|
||||
#define PACKED 2
|
||||
#define LZHED 3
|
||||
/* methods 4 to 7 reserved */
|
||||
#define DEFLATED 8
|
||||
#define MAX_METHODS 9
|
||||
extern int method; /* compression method */
|
||||
|
||||
/* To save memory for 16 bit systems, some arrays are overlaid between
|
||||
* the various modules:
|
||||
* deflate: prev+head window d_buf l_buf outbuf
|
||||
* unlzw: tab_prefix tab_suffix stack inbuf outbuf
|
||||
* inflate: window inbuf
|
||||
* unpack: window inbuf prefix_len
|
||||
* unlzh: left+right window c_table inbuf c_len
|
||||
* For compression, input is done in window[]. For decompression, output
|
||||
* is done in window except for unlzw.
|
||||
*/
|
||||
|
||||
#ifndef INBUFSIZ
|
||||
# ifdef SMALL_MEM
|
||||
# define INBUFSIZ 0x2000 /* input buffer size */
|
||||
# else
|
||||
# define INBUFSIZ 0x8000 /* input buffer size */
|
||||
# endif
|
||||
#endif
|
||||
#define INBUF_EXTRA 64 /* required by unlzw() */
|
||||
|
||||
#ifndef OUTBUFSIZ
|
||||
# ifdef SMALL_MEM
|
||||
# define OUTBUFSIZ 8192 /* output buffer size */
|
||||
# else
|
||||
# define OUTBUFSIZ 16384 /* output buffer size */
|
||||
# endif
|
||||
#endif
|
||||
#define OUTBUF_EXTRA 2048 /* required by unlzw() */
|
||||
|
||||
#ifndef DIST_BUFSIZE
|
||||
# ifdef SMALL_MEM
|
||||
# define DIST_BUFSIZE 0x2000 /* buffer for distances, see trees.c */
|
||||
# else
|
||||
# define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef DYN_ALLOC
|
||||
# define EXTERN(type, array) extern type * near array
|
||||
# define DECLARE(type, array, size) type * near array
|
||||
# define ALLOC(type, array, size) { \
|
||||
array = (type*)fcalloc((size_t)(((size)+1L)/2), 2*sizeof(type)); \
|
||||
if (array == NULL) error("insufficient memory"); \
|
||||
}
|
||||
# define FREE(array) {if (array != NULL) fcfree(array), array=NULL;}
|
||||
#else
|
||||
# define EXTERN(type, array) extern type array[]
|
||||
# define DECLARE(type, array, size) type array[size]
|
||||
# define ALLOC(type, array, size)
|
||||
# define FREE(array)
|
||||
#endif
|
||||
|
||||
EXTERN(uch, inbuf); /* input buffer */
|
||||
EXTERN(uch, outbuf); /* output buffer */
|
||||
EXTERN(ush, d_buf); /* buffer for distances, see trees.c */
|
||||
EXTERN(uch, window); /* Sliding window and suffix table (unlzw) */
|
||||
#define tab_suffix window
|
||||
#ifndef MAXSEG_64K
|
||||
# define tab_prefix prev /* hash link (see deflate.c) */
|
||||
# define head (prev+WSIZE) /* hash head (see deflate.c) */
|
||||
EXTERN(ush, tab_prefix); /* prefix code (see unlzw.c) */
|
||||
#else
|
||||
# define tab_prefix0 prev
|
||||
# define head tab_prefix1
|
||||
EXTERN(ush, tab_prefix0); /* prefix for even codes */
|
||||
EXTERN(ush, tab_prefix1); /* prefix for odd codes */
|
||||
#endif
|
||||
|
||||
extern unsigned insize; /* valid bytes in inbuf */
|
||||
extern unsigned inptr; /* index of next byte to be processed in inbuf */
|
||||
extern unsigned outcnt; /* bytes in output buffer */
|
||||
|
||||
extern long bytes_in; /* number of input bytes */
|
||||
extern long bytes_out; /* number of output bytes */
|
||||
extern long header_bytes;/* number of bytes in gzip header */
|
||||
|
||||
#define isize bytes_in
|
||||
/* for compatibility with old zip sources (to be cleaned) */
|
||||
|
||||
extern int ifd; /* input file descriptor */
|
||||
extern int ofd; /* output file descriptor */
|
||||
extern char ifname[]; /* input file name or "stdin" */
|
||||
extern char ofname[]; /* output file name or "stdout" */
|
||||
extern char *progname; /* program name */
|
||||
|
||||
extern long time_stamp; /* original time stamp (modification time) */
|
||||
extern long ifile_size; /* input file size, -1 for devices (debug only) */
|
||||
|
||||
typedef int file_t; /* Do not use stdio */
|
||||
#define NO_FILE (-1) /* in memory compression */
|
||||
|
||||
|
||||
#define PACK_MAGIC "\037\036" /* Magic header for packed files */
|
||||
#define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */
|
||||
#define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */
|
||||
#define LZH_MAGIC "\037\240" /* Magic header for SCO LZH Compress files*/
|
||||
#define PKZIP_MAGIC "\120\113\003\004" /* Magic header for pkzip files */
|
||||
|
||||
/* gzip flag byte */
|
||||
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
|
||||
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
|
||||
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
|
||||
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
|
||||
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
||||
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
||||
|
||||
/* internal file attribute */
|
||||
#define UNKNOWN 0xffff
|
||||
#define BINARY 0
|
||||
#define ASCII 1
|
||||
|
||||
#ifndef WSIZE
|
||||
# define WSIZE 0x8000 /* window size--must be a power of two, and */
|
||||
#endif /* at least 32K for zip's deflate method */
|
||||
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
||||
/* Minimum amount of lookahead, except at the end of the input file.
|
||||
* See deflate.c for comments about the MIN_MATCH+1.
|
||||
*/
|
||||
|
||||
#define MAX_DIST (WSIZE-MIN_LOOKAHEAD)
|
||||
/* In order to simplify the code, particularly on 16 bit machines, match
|
||||
* distances are limited to MAX_DIST instead of WSIZE.
|
||||
*/
|
||||
|
||||
extern int decrypt; /* flag to turn on decryption */
|
||||
extern int exit_code; /* program exit code */
|
||||
extern int verbose; /* be verbose (-v) */
|
||||
extern int quiet; /* be quiet (-q) */
|
||||
extern int level; /* compression level */
|
||||
extern int test; /* check .z file integrity */
|
||||
extern int to_stdout; /* output to stdout (-c) */
|
||||
extern int save_orig_name; /* set if original name must be saved */
|
||||
|
||||
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0))
|
||||
#define try_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(1))
|
||||
|
||||
/* put_byte is used for the compressed output, put_ubyte for the
|
||||
* uncompressed output. However unlzw() uses window for its
|
||||
* suffix table instead of its output buffer, so it does not use put_ubyte
|
||||
* (to be cleaned up).
|
||||
*/
|
||||
#define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\
|
||||
flush_outbuf();}
|
||||
#define put_ubyte(c) {window[outcnt++]=(uch)(c); if (outcnt==WSIZE)\
|
||||
flush_window();}
|
||||
|
||||
/* Output a 16 bit value, lsb first */
|
||||
#define put_short(w) \
|
||||
{ if (outcnt < OUTBUFSIZ-2) { \
|
||||
outbuf[outcnt++] = (uch) ((w) & 0xff); \
|
||||
outbuf[outcnt++] = (uch) ((ush)(w) >> 8); \
|
||||
} else { \
|
||||
put_byte((uch)((w) & 0xff)); \
|
||||
put_byte((uch)((ush)(w) >> 8)); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Output a 32 bit value to the bit stream, lsb first */
|
||||
#define put_long(n) { \
|
||||
put_short((n) & 0xffff); \
|
||||
put_short(((ulg)(n)) >> 16); \
|
||||
}
|
||||
|
||||
#define seekable() 0 /* force sequential output */
|
||||
#define translate_eol 0 /* no option -a yet */
|
||||
|
||||
#define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */
|
||||
|
||||
/* Macros for getting two-byte and four-byte header values */
|
||||
#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8))
|
||||
#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16))
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# define Assert(cond,msg) {if(!(cond)) error(msg);}
|
||||
# define Trace(x) fprintf x
|
||||
# define Tracev(x) {if (verbose) fprintf x ;}
|
||||
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
#define WARN(msg) {if (!quiet) fprintf msg ; \
|
||||
if (exit_code == OK) exit_code = WARNING;}
|
||||
|
||||
/* in zip.c: */
|
||||
extern int zip OF((int in, int out));
|
||||
extern int file_read OF((char *buf, unsigned size));
|
||||
|
||||
/* in unzip.c */
|
||||
extern int unzip OF((int in, int out));
|
||||
extern int check_zipfile OF((int in));
|
||||
|
||||
/* in unpack.c */
|
||||
extern int unpack OF((int in, int out));
|
||||
|
||||
/* in unlzh.c */
|
||||
extern int unlzh OF((int in, int out));
|
||||
|
||||
/* in gzip.c */
|
||||
RETSIGTYPE abort_gzip OF((void));
|
||||
|
||||
/* in deflate.c */
|
||||
void lm_init OF((int pack_level, ush *flags));
|
||||
ulg deflate OF((void));
|
||||
|
||||
/* in trees.c */
|
||||
void ct_init OF((ush *attr, int *method));
|
||||
int ct_tally OF((int dist, int lc));
|
||||
ulg flush_block OF((char *buf, ulg stored_len, int eof));
|
||||
|
||||
/* in bits.c */
|
||||
void bi_init OF((file_t zipfile));
|
||||
void send_bits OF((int value, int length));
|
||||
unsigned bi_reverse OF((unsigned value, int length));
|
||||
void bi_windup OF((void));
|
||||
void copy_block OF((char *buf, unsigned len, int header));
|
||||
extern int (*read_buf) OF((char *buf, unsigned size));
|
||||
|
||||
/* in util.c: */
|
||||
extern int copy OF((int in, int out));
|
||||
extern ulg updcrc OF((uch *s, unsigned n));
|
||||
extern void clear_bufs OF((void));
|
||||
extern int fill_inbuf OF((int eof_ok));
|
||||
extern void flush_outbuf OF((void));
|
||||
extern void flush_window OF((void));
|
||||
extern void write_buf OF((int fd, voidp buf, unsigned cnt));
|
||||
extern char *strlwr OF((char *s));
|
||||
extern char *our_basename OF((char *fname));
|
||||
extern void make_simple_name OF((char *name));
|
||||
extern char *add_envopt OF((int *argcp, char ***argvp, char *env));
|
||||
extern void error OF((char *m));
|
||||
extern void warn OF((char *a, char *b));
|
||||
extern void read_error OF((void));
|
||||
extern void write_error OF((void));
|
||||
extern void display_ratio OF((long num, long den, FILE *file));
|
||||
extern voidp xmalloc OF((unsigned int size));
|
||||
|
||||
/* in inflate.c */
|
||||
extern int inflate OF((void));
|
@ -1,954 +0,0 @@
|
||||
/* inflate.c -- Not copyrighted 1992 by Mark Adler
|
||||
version c10p1, 10 January 1993 */
|
||||
|
||||
/* You can do whatever you like with this source file, though I would
|
||||
prefer that if you modify it and redistribute it that you include
|
||||
comments to that effect with your name and the date. Thank you.
|
||||
[The history has been moved to the file ChangeLog.]
|
||||
*/
|
||||
|
||||
/*
|
||||
Inflate deflated (PKZIP's method 8 compressed) data. The compression
|
||||
method searches for as much of the current string of bytes (up to a
|
||||
length of 258) in the previous 32K bytes. If it doesn't find any
|
||||
matches (of at least length 3), it codes the next byte. Otherwise, it
|
||||
codes the length of the matched string and its distance backwards from
|
||||
the current position. There is a single Huffman code that codes both
|
||||
single bytes (called "literals") and match lengths. A second Huffman
|
||||
code codes the distance information, which follows a length code. Each
|
||||
length or distance code actually represents a base value and a number
|
||||
of "extra" (sometimes zero) bits to get to add to the base value. At
|
||||
the end of each deflated block is a special end-of-block (EOB) literal/
|
||||
length code. The decoding process is basically: get a literal/length
|
||||
code; if EOB then done; if a literal, emit the decoded byte; if a
|
||||
length then get the distance and emit the referred-to bytes from the
|
||||
sliding window of previously emitted data.
|
||||
|
||||
There are (currently) three kinds of inflate blocks: stored, fixed, and
|
||||
dynamic. The compressor deals with some chunk of data at a time, and
|
||||
decides which method to use on a chunk-by-chunk basis. A chunk might
|
||||
typically be 32K or 64K. If the chunk is uncompressible, then the
|
||||
"stored" method is used. In this case, the bytes are simply stored as
|
||||
is, eight bits per byte, with none of the above coding. The bytes are
|
||||
preceded by a count, since there is no longer an EOB code.
|
||||
|
||||
If the data is compressible, then either the fixed or dynamic methods
|
||||
are used. In the dynamic method, the compressed data is preceded by
|
||||
an encoding of the literal/length and distance Huffman codes that are
|
||||
to be used to decode this block. The representation is itself Huffman
|
||||
coded, and so is preceded by a description of that code. These code
|
||||
descriptions take up a little space, and so for small blocks, there is
|
||||
a predefined set of codes, called the fixed codes. The fixed method is
|
||||
used if the block codes up smaller that way (usually for quite small
|
||||
chunks), otherwise the dynamic method is used. In the latter case, the
|
||||
codes are customized to the probabilities in the current block, and so
|
||||
can code it much better than the pre-determined fixed codes.
|
||||
|
||||
The Huffman codes themselves are decoded using a mutli-level table
|
||||
lookup, in order to maximize the speed of decoding plus the speed of
|
||||
building the decoding tables. See the comments below that precede the
|
||||
lbits and dbits tuning parameters.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Notes beyond the 1.93a appnote.txt:
|
||||
|
||||
1. Distance pointers never point before the beginning of the output
|
||||
stream.
|
||||
2. Distance pointers can point back across blocks, up to 32k away.
|
||||
3. There is an implied maximum of 7 bits for the bit length table and
|
||||
15 bits for the actual data.
|
||||
4. If only one code exists, then it is encoded using one bit. (Zero
|
||||
would be more efficient, but perhaps a little confusing.) If two
|
||||
codes exist, they are coded using one bit each (0 and 1).
|
||||
5. There is no way of sending zero distance codes--a dummy must be
|
||||
sent if there are none. (History: a pre 2.0 version of PKZIP would
|
||||
store blocks with no distance codes, but this was discovered to be
|
||||
too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
|
||||
zero distance codes, which is sent as one code of zero bits in
|
||||
length.
|
||||
6. There are up to 286 literal/length codes. Code 256 represents the
|
||||
end-of-block. Note however that the static length tree defines
|
||||
288 codes just to fill out the Huffman codes. Codes 286 and 287
|
||||
cannot be used though, since there is no length base or extra bits
|
||||
defined for them. Similarly, there are up to 30 distance codes.
|
||||
However, static trees define 32 codes (all 5 bits) to fill out the
|
||||
Huffman codes, but the last two had better not show up in the data.
|
||||
7. Unzip can check dynamic Huffman blocks for complete code sets.
|
||||
The exception is that a single code would not be complete (see #4).
|
||||
8. The five bits following the block type is really the number of
|
||||
literal codes sent minus 257.
|
||||
9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
|
||||
(1+6+6). Therefore, to output three times the length, you output
|
||||
three codes (1+1+1), whereas to output four times the same length,
|
||||
you only need two codes (1+3). Hmm.
|
||||
10. In the tree reconstruction algorithm, Code = Code + Increment
|
||||
only if BitLength(i) is not zero. (Pretty obvious.)
|
||||
11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
|
||||
12. Note: length code 284 can represent 227-258, but length code 285
|
||||
really is 258. The last length deserves its own, short code
|
||||
since it gets used a lot in very redundant files. The length
|
||||
258 is special since 258 - 3 (the min match length) is 255.
|
||||
13. The literal/length and distance code bit lengths are read as a
|
||||
single stream of lengths. It is possible (and advantageous) for
|
||||
a repeat code (16, 17, or 18) to go across the boundary between
|
||||
the two sets of lengths.
|
||||
*/
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: inflate.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tailor.h"
|
||||
|
||||
#if defined(STDC_HEADERS) || !defined(NO_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "gzip.h"
|
||||
#define slide window
|
||||
|
||||
/* Huffman code lookup table entry--this entry is four bytes for machines
|
||||
that have 16-bit pointers (e.g. PC's in the small or medium model).
|
||||
Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16
|
||||
means that v is a literal, 16 < e < 32 means that v is a pointer to
|
||||
the next table, which codes e - 16 bits, and lastly e == 99 indicates
|
||||
an unused code. If a code with e == 99 is looked up, this implies an
|
||||
error in the data. */
|
||||
struct huft {
|
||||
uch e; /* number of extra bits or operation */
|
||||
uch b; /* number of bits in this code or subcode */
|
||||
union {
|
||||
ush n; /* literal, length base, or distance base */
|
||||
struct huft *t; /* pointer to next level of table */
|
||||
} v;
|
||||
};
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *,
|
||||
struct huft **, int *));
|
||||
int huft_free OF((struct huft *));
|
||||
int inflate_codes OF((struct huft *, struct huft *, int, int));
|
||||
int inflate_stored OF((void));
|
||||
int inflate_fixed OF((void));
|
||||
int inflate_dynamic OF((void));
|
||||
int inflate_block OF((int *));
|
||||
int inflate OF((void));
|
||||
|
||||
|
||||
/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
|
||||
stream to find repeated byte strings. This is implemented here as a
|
||||
circular buffer. The index is updated simply by incrementing and then
|
||||
and'ing with 0x7fff (32K-1). */
|
||||
/* It is left to other modules to supply the 32K area. It is assumed
|
||||
to be usable as if it were declared "uch slide[32768];" or as just
|
||||
"uch *slide;" and then malloc'ed in the latter case. The definition
|
||||
must be in unzip.h, included above. */
|
||||
/* unsigned wp; current position in slide */
|
||||
#define wp outcnt
|
||||
#define flush_output(w) (wp=(w),flush_window())
|
||||
|
||||
/* Tables for deflate from PKZIP's appnote.txt. */
|
||||
static unsigned border[] = { /* Order of the bit length code lengths */
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
static ush cplens[] = { /* Copy lengths for literal codes 257..285 */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
/* note: see note #13 above about the 258 in this list. */
|
||||
static ush cplext[] = { /* Extra bits for literal codes 257..285 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
|
||||
static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577};
|
||||
static ush cpdext[] = { /* Extra bits for distance codes */
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
||||
12, 12, 13, 13};
|
||||
|
||||
|
||||
|
||||
/* Macros for inflate() bit peeking and grabbing.
|
||||
The usage is:
|
||||
|
||||
NEEDBITS(j)
|
||||
x = b & mask_bits[j];
|
||||
DUMPBITS(j)
|
||||
|
||||
where NEEDBITS makes sure that b has at least j bits in it, and
|
||||
DUMPBITS removes the bits from b. The macros use the variable k
|
||||
for the number of bits in b. Normally, b and k are register
|
||||
variables for speed, and are initialized at the beginning of a
|
||||
routine that uses these macros from a global bit buffer and count.
|
||||
|
||||
If we assume that EOB will be the longest code, then we will never
|
||||
ask for bits with NEEDBITS that are beyond the end of the stream.
|
||||
So, NEEDBITS should not read any more bytes than are needed to
|
||||
meet the request. Then no bytes need to be "returned" to the buffer
|
||||
at the end of the last block.
|
||||
|
||||
However, this assumption is not true for fixed blocks--the EOB code
|
||||
is 7 bits, but the other literal/length codes can be 8 or 9 bits.
|
||||
(The EOB code is shorter than other codes because fixed blocks are
|
||||
generally short. So, while a block always has an EOB, many other
|
||||
literal/length codes have a significantly lower probability of
|
||||
showing up at all.) However, by making the first table have a
|
||||
lookup of seven bits, the EOB code will be found in that first
|
||||
lookup, and so will not require that too many bits be pulled from
|
||||
the stream.
|
||||
*/
|
||||
|
||||
ulg bb; /* bit buffer */
|
||||
unsigned bk; /* bits in bit buffer */
|
||||
|
||||
ush mask_bits[] = {
|
||||
0x0000,
|
||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
||||
};
|
||||
|
||||
#ifdef CRYPT
|
||||
uch cc;
|
||||
# define NEXTBYTE() \
|
||||
(decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte())
|
||||
#else
|
||||
# define NEXTBYTE() (uch)get_byte()
|
||||
#endif
|
||||
#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
|
||||
#define DUMPBITS(n) {b>>=(n);k-=(n);}
|
||||
|
||||
|
||||
/*
|
||||
Huffman code decoding is performed using a multi-level table lookup.
|
||||
The fastest way to decode is to simply build a lookup table whose
|
||||
size is determined by the longest code. However, the time it takes
|
||||
to build this table can also be a factor if the data being decoded
|
||||
is not very long. The most common codes are necessarily the
|
||||
shortest codes, so those codes dominate the decoding time, and hence
|
||||
the speed. The idea is you can have a shorter table that decodes the
|
||||
shorter, more probable codes, and then point to subsidiary tables for
|
||||
the longer codes. The time it costs to decode the longer codes is
|
||||
then traded against the time it takes to make longer tables.
|
||||
|
||||
This results of this trade are in the variables lbits and dbits
|
||||
below. lbits is the number of bits the first level table for literal/
|
||||
length codes can decode in one step, and dbits is the same thing for
|
||||
the distance codes. Subsequent tables are also less than or equal to
|
||||
those sizes. These values may be adjusted either when all of the
|
||||
codes are shorter than that, in which case the longest code length in
|
||||
bits is used, or when the shortest code is *longer* than the requested
|
||||
table size, in which case the length of the shortest code in bits is
|
||||
used.
|
||||
|
||||
There are two different values for the two tables, since they code a
|
||||
different number of possibilities each. The literal/length table
|
||||
codes 286 possible values, or in a flat code, a little over eight
|
||||
bits. The distance table codes 30 possible values, or a little less
|
||||
than five bits, flat. The optimum values for speed end up being
|
||||
about one bit more than those, so lbits is 8+1 and dbits is 5+1.
|
||||
The optimum values may differ though from machine to machine, and
|
||||
possibly even between compilers. Your mileage may vary.
|
||||
*/
|
||||
|
||||
|
||||
int lbits = 9; /* bits in base literal/length lookup table */
|
||||
int dbits = 6; /* bits in base distance lookup table */
|
||||
|
||||
|
||||
/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
|
||||
#define BMAX 16 /* maximum bit length of any code (16 for explode) */
|
||||
#define N_MAX 288 /* maximum number of codes in any set */
|
||||
|
||||
|
||||
unsigned hufts; /* track memory usage */
|
||||
|
||||
|
||||
int huft_build(b, n, s, d, e, t, m)
|
||||
unsigned *b; /* code lengths in bits (all assumed <= BMAX) */
|
||||
unsigned n; /* number of codes (assumed <= N_MAX) */
|
||||
unsigned s; /* number of simple-valued codes (0..s-1) */
|
||||
ush *d; /* list of base values for non-simple codes */
|
||||
ush *e; /* list of extra bits for non-simple codes */
|
||||
struct huft **t; /* result: starting table */
|
||||
int *m; /* maximum lookup bits, returns actual */
|
||||
/* Given a list of code lengths and a maximum table size, make a set of
|
||||
tables to decode that set of codes. Return zero on success, one if
|
||||
the given code set is incomplete (the tables are still built in this
|
||||
case), two if the input is invalid (all zero length codes or an
|
||||
oversubscribed set of lengths), and three if not enough memory. */
|
||||
{
|
||||
unsigned a; /* counter for codes of length k */
|
||||
unsigned c[BMAX+1]; /* bit length count table */
|
||||
unsigned f; /* i repeats in table every f entries */
|
||||
int g; /* maximum code length */
|
||||
int h; /* table level */
|
||||
register unsigned i; /* counter, current code */
|
||||
register unsigned j; /* counter */
|
||||
register int k; /* number of bits in current code */
|
||||
int l; /* bits per table (returned in m) */
|
||||
register unsigned *p; /* pointer into c[], b[], or v[] */
|
||||
register struct huft *q; /* points to current table */
|
||||
struct huft r; /* table entry for structure assignment */
|
||||
struct huft *u[BMAX]; /* table stack */
|
||||
unsigned v[N_MAX]; /* values in order of bit length */
|
||||
register int w; /* bits before this table == (l * h) */
|
||||
unsigned x[BMAX+1]; /* bit offsets, then code stack */
|
||||
unsigned *xp; /* pointer into x */
|
||||
int y; /* number of dummy codes added */
|
||||
unsigned z; /* number of entries in current table */
|
||||
|
||||
|
||||
/* Generate counts for each bit length */
|
||||
memzero(c, sizeof(c));
|
||||
p = b; i = n;
|
||||
do {
|
||||
Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"),
|
||||
n-i, *p));
|
||||
c[*p]++; /* assume all entries <= BMAX */
|
||||
p++; /* Can't combine with above line (Solaris bug) */
|
||||
} while (--i);
|
||||
if (c[0] == n) /* null input--all zero length codes */
|
||||
{
|
||||
*t = (struct huft *)NULL;
|
||||
*m = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Find minimum and maximum length, bound *m by those */
|
||||
l = *m;
|
||||
for (j = 1; j <= BMAX; j++)
|
||||
if (c[j])
|
||||
break;
|
||||
k = j; /* minimum code length */
|
||||
if ((unsigned)l < j)
|
||||
l = j;
|
||||
for (i = BMAX; i; i--)
|
||||
if (c[i])
|
||||
break;
|
||||
g = i; /* maximum code length */
|
||||
if ((unsigned)l > i)
|
||||
l = i;
|
||||
*m = l;
|
||||
|
||||
|
||||
/* Adjust last length count to fill out codes, if needed */
|
||||
for (y = 1 << j; j < i; j++, y <<= 1)
|
||||
if ((y -= c[j]) < 0)
|
||||
return 2; /* bad input: more codes than bits */
|
||||
if ((y -= c[i]) < 0)
|
||||
return 2;
|
||||
c[i] += y;
|
||||
|
||||
|
||||
/* Generate starting offsets into the value table for each length */
|
||||
x[1] = j = 0;
|
||||
p = c + 1; xp = x + 2;
|
||||
while (--i) { /* note that i == g from above */
|
||||
*xp++ = (j += *p++);
|
||||
}
|
||||
|
||||
|
||||
/* Make a table of values in order of bit lengths */
|
||||
p = b; i = 0;
|
||||
do {
|
||||
if ((j = *p++) != 0)
|
||||
v[x[j]++] = i;
|
||||
} while (++i < n);
|
||||
|
||||
|
||||
/* Generate the Huffman codes and for each, make the table entries */
|
||||
x[0] = i = 0; /* first Huffman code is zero */
|
||||
p = v; /* grab values in bit order */
|
||||
h = -1; /* no tables yet--level -1 */
|
||||
w = -l; /* bits decoded == (l * h) */
|
||||
u[0] = (struct huft *)NULL; /* just to keep compilers happy */
|
||||
q = (struct huft *)NULL; /* ditto */
|
||||
z = 0; /* ditto */
|
||||
|
||||
/* go through the bit lengths (k already is bits in shortest code) */
|
||||
for (; k <= g; k++)
|
||||
{
|
||||
a = c[k];
|
||||
while (a--)
|
||||
{
|
||||
/* here i is the Huffman code of length k bits for value *p */
|
||||
/* make tables up to required level */
|
||||
while (k > w + l)
|
||||
{
|
||||
h++;
|
||||
w += l; /* previous table always l bits */
|
||||
|
||||
/* compute minimum size table less than or equal to l bits */
|
||||
z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */
|
||||
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
|
||||
{ /* too few codes for k-w bit table */
|
||||
f -= a + 1; /* deduct codes from patterns left */
|
||||
xp = c + k;
|
||||
while (++j < z) /* try smaller tables up to z bits */
|
||||
{
|
||||
if ((f <<= 1) <= *++xp)
|
||||
break; /* enough codes to use up j bits */
|
||||
f -= *xp; /* else deduct codes from patterns */
|
||||
}
|
||||
}
|
||||
z = 1 << j; /* table entries for j-bit table */
|
||||
|
||||
/* allocate and link in new table */
|
||||
if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
|
||||
(struct huft *)NULL)
|
||||
{
|
||||
if (h)
|
||||
huft_free(u[0]);
|
||||
return 3; /* not enough memory */
|
||||
}
|
||||
hufts += z + 1; /* track memory usage */
|
||||
*t = q + 1; /* link to list for huft_free() */
|
||||
*(t = &(q->v.t)) = (struct huft *)NULL;
|
||||
u[h] = ++q; /* table starts after link */
|
||||
|
||||
/* connect to last table, if there is one */
|
||||
if (h)
|
||||
{
|
||||
x[h] = i; /* save pattern for backing up */
|
||||
r.b = (uch)l; /* bits to dump before this table */
|
||||
r.e = (uch)(16 + j); /* bits in this table */
|
||||
r.v.t = q; /* pointer to this table */
|
||||
j = i >> (w - l); /* (get around Turbo C bug) */
|
||||
u[h-1][j] = r; /* connect to last table */
|
||||
}
|
||||
}
|
||||
|
||||
/* set up table entry in r */
|
||||
r.b = (uch)(k - w);
|
||||
if (p >= v + n)
|
||||
r.e = 99; /* out of values--invalid code */
|
||||
else if (*p < s)
|
||||
{
|
||||
r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
|
||||
r.v.n = (ush)(*p); /* simple code is just the value */
|
||||
p++; /* one compiler does not like *p++ */
|
||||
}
|
||||
else
|
||||
{
|
||||
r.e = (uch)e[*p - s]; /* non-simple--look up in lists */
|
||||
r.v.n = d[*p++ - s];
|
||||
}
|
||||
|
||||
/* fill code-like entries with r */
|
||||
f = 1 << (k - w);
|
||||
for (j = i >> w; j < z; j += f)
|
||||
q[j] = r;
|
||||
|
||||
/* backwards increment the k-bit code i */
|
||||
for (j = 1 << (k - 1); i & j; j >>= 1)
|
||||
i ^= j;
|
||||
i ^= j;
|
||||
|
||||
/* backup over finished tables */
|
||||
while ((i & ((1 << w) - 1)) != x[h])
|
||||
{
|
||||
h--; /* don't need to update q */
|
||||
w -= l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return true (1) if we were given an incomplete table */
|
||||
return y != 0 && g != 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int huft_free(t)
|
||||
struct huft *t; /* table to free */
|
||||
/* Free the malloc'ed tables built by huft_build(), which makes a linked
|
||||
list of the tables it made, with the links in a dummy first entry of
|
||||
each table. */
|
||||
{
|
||||
register struct huft *p, *q;
|
||||
|
||||
|
||||
/* Go through linked list, freeing from the malloced (t[-1]) address. */
|
||||
p = t;
|
||||
while (p != (struct huft *)NULL)
|
||||
{
|
||||
q = (--p)->v.t;
|
||||
free((char*)p);
|
||||
p = q;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int inflate_codes(tl, td, bl, bd)
|
||||
struct huft *tl, *td; /* literal/length and distance decoder tables */
|
||||
int bl, bd; /* number of bits decoded by tl[] and td[] */
|
||||
/* inflate (decompress) the codes in a deflated (compressed) block.
|
||||
Return an error code or zero if it all goes ok. */
|
||||
{
|
||||
register unsigned e; /* table entry flag/number of extra bits */
|
||||
unsigned n, d; /* length and index for copy */
|
||||
unsigned w; /* current window position */
|
||||
struct huft *t; /* pointer to table entry */
|
||||
unsigned ml, md; /* masks for bl and bd bits */
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
/* make local copies of globals */
|
||||
b = bb; /* initialize bit buffer */
|
||||
k = bk;
|
||||
w = wp; /* initialize window position */
|
||||
|
||||
/* inflate the coded data */
|
||||
ml = mask_bits[bl]; /* precompute masks for speed */
|
||||
md = mask_bits[bd];
|
||||
for (;;) /* do until end of block */
|
||||
{
|
||||
NEEDBITS((unsigned)bl)
|
||||
if ((e = (t = tl + ((unsigned)b & ml))->e) > 16)
|
||||
do {
|
||||
if (e == 99)
|
||||
return 1;
|
||||
DUMPBITS(t->b)
|
||||
e -= 16;
|
||||
NEEDBITS(e)
|
||||
} while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
|
||||
DUMPBITS(t->b)
|
||||
if (e == 16) /* then it's a literal */
|
||||
{
|
||||
slide[w++] = (uch)t->v.n;
|
||||
Tracevv((stderr, "%c", slide[w-1]));
|
||||
if (w == WSIZE)
|
||||
{
|
||||
flush_output(w);
|
||||
w = 0;
|
||||
}
|
||||
}
|
||||
else /* it's an EOB or a length */
|
||||
{
|
||||
/* exit if end of block */
|
||||
if (e == 15)
|
||||
break;
|
||||
|
||||
/* get length of block to copy */
|
||||
NEEDBITS(e)
|
||||
n = t->v.n + ((unsigned)b & mask_bits[e]);
|
||||
DUMPBITS(e);
|
||||
|
||||
/* decode distance of block to copy */
|
||||
NEEDBITS((unsigned)bd)
|
||||
if ((e = (t = td + ((unsigned)b & md))->e) > 16)
|
||||
do {
|
||||
if (e == 99)
|
||||
return 1;
|
||||
DUMPBITS(t->b)
|
||||
e -= 16;
|
||||
NEEDBITS(e)
|
||||
} while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
|
||||
DUMPBITS(t->b)
|
||||
NEEDBITS(e)
|
||||
d = w - t->v.n - ((unsigned)b & mask_bits[e]);
|
||||
DUMPBITS(e)
|
||||
Tracevv((stderr,"\\[%d,%d]", w-d, n));
|
||||
|
||||
/* do the copy */
|
||||
do {
|
||||
n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
|
||||
#if !defined(NOMEMCPY) && !defined(DEBUG)
|
||||
if (w - d >= e) /* (this test assumes unsigned comparison) */
|
||||
{
|
||||
memcpy(slide + w, slide + d, e);
|
||||
w += e;
|
||||
d += e;
|
||||
}
|
||||
else /* do it slow to avoid memcpy() overlap */
|
||||
#endif /* !NOMEMCPY */
|
||||
do {
|
||||
slide[w++] = slide[d++];
|
||||
Tracevv((stderr, "%c", slide[w-1]));
|
||||
} while (--e);
|
||||
if (w == WSIZE)
|
||||
{
|
||||
flush_output(w);
|
||||
w = 0;
|
||||
}
|
||||
} while (n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* restore the globals from the locals */
|
||||
wp = w; /* restore global window pointer */
|
||||
bb = b; /* restore global bit buffer */
|
||||
bk = k;
|
||||
|
||||
/* done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate_stored()
|
||||
/* "decompress" an inflated type 0 (stored) block. */
|
||||
{
|
||||
unsigned n; /* number of bytes in block */
|
||||
unsigned w; /* current window position */
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
/* make local copies of globals */
|
||||
b = bb; /* initialize bit buffer */
|
||||
k = bk;
|
||||
w = wp; /* initialize window position */
|
||||
|
||||
|
||||
/* go to byte boundary */
|
||||
n = k & 7;
|
||||
DUMPBITS(n);
|
||||
|
||||
|
||||
/* get the length and its complement */
|
||||
NEEDBITS(16)
|
||||
n = ((unsigned)b & 0xffff);
|
||||
DUMPBITS(16)
|
||||
NEEDBITS(16)
|
||||
if (n != (unsigned)((~b) & 0xffff))
|
||||
return 1; /* error in compressed data */
|
||||
DUMPBITS(16)
|
||||
|
||||
|
||||
/* read and output the compressed data */
|
||||
while (n--)
|
||||
{
|
||||
NEEDBITS(8)
|
||||
slide[w++] = (uch)b;
|
||||
if (w == WSIZE)
|
||||
{
|
||||
flush_output(w);
|
||||
w = 0;
|
||||
}
|
||||
DUMPBITS(8)
|
||||
}
|
||||
|
||||
|
||||
/* restore the globals from the locals */
|
||||
wp = w; /* restore global window pointer */
|
||||
bb = b; /* restore global bit buffer */
|
||||
bk = k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate_fixed()
|
||||
/* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
||||
either replace this with a custom decoder, or at least precompute the
|
||||
Huffman tables. */
|
||||
{
|
||||
int i; /* temporary variable */
|
||||
struct huft *tl; /* literal/length code table */
|
||||
struct huft *td; /* distance code table */
|
||||
int bl; /* lookup bits for tl */
|
||||
int bd; /* lookup bits for td */
|
||||
unsigned l[288]; /* length list for huft_build */
|
||||
|
||||
|
||||
/* set up literal table */
|
||||
for (i = 0; i < 144; i++)
|
||||
l[i] = 8;
|
||||
for (; i < 256; i++)
|
||||
l[i] = 9;
|
||||
for (; i < 280; i++)
|
||||
l[i] = 7;
|
||||
for (; i < 288; i++) /* make a complete, but wrong code set */
|
||||
l[i] = 8;
|
||||
bl = 7;
|
||||
if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0)
|
||||
return i;
|
||||
|
||||
|
||||
/* set up distance table */
|
||||
for (i = 0; i < 30; i++) /* make an incomplete code set */
|
||||
l[i] = 5;
|
||||
bd = 5;
|
||||
if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
|
||||
{
|
||||
huft_free(tl);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
if (inflate_codes(tl, td, bl, bd))
|
||||
return 1;
|
||||
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate_dynamic()
|
||||
/* decompress an inflated type 2 (dynamic Huffman codes) block. */
|
||||
{
|
||||
int i; /* temporary variables */
|
||||
unsigned j;
|
||||
unsigned l; /* last length */
|
||||
unsigned m; /* mask for bit lengths table */
|
||||
unsigned n; /* number of lengths to get */
|
||||
struct huft *tl; /* literal/length code table */
|
||||
struct huft *td; /* distance code table */
|
||||
int bl; /* lookup bits for tl */
|
||||
int bd; /* lookup bits for td */
|
||||
unsigned nb; /* number of bit length codes */
|
||||
unsigned nl; /* number of literal/length codes */
|
||||
unsigned nd; /* number of distance codes */
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
unsigned ll[288+32]; /* literal/length and distance code lengths */
|
||||
#else
|
||||
unsigned ll[286+30]; /* literal/length and distance code lengths */
|
||||
#endif
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
/* make local bit buffer */
|
||||
b = bb;
|
||||
k = bk;
|
||||
|
||||
|
||||
/* read in table lengths */
|
||||
NEEDBITS(5)
|
||||
nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */
|
||||
DUMPBITS(5)
|
||||
NEEDBITS(5)
|
||||
nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */
|
||||
DUMPBITS(5)
|
||||
NEEDBITS(4)
|
||||
nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */
|
||||
DUMPBITS(4)
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
if (nl > 288 || nd > 32)
|
||||
#else
|
||||
if (nl > 286 || nd > 30)
|
||||
#endif
|
||||
return 1; /* bad lengths */
|
||||
|
||||
|
||||
/* read in bit-length-code lengths */
|
||||
for (j = 0; j < nb; j++)
|
||||
{
|
||||
NEEDBITS(3)
|
||||
ll[border[j]] = (unsigned)b & 7;
|
||||
DUMPBITS(3)
|
||||
}
|
||||
for (; j < 19; j++)
|
||||
ll[border[j]] = 0;
|
||||
|
||||
|
||||
/* build decoding table for trees--single level, 7 bit lookup */
|
||||
bl = 7;
|
||||
if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
|
||||
{
|
||||
if (i == 1)
|
||||
huft_free(tl);
|
||||
return i; /* incomplete code set */
|
||||
}
|
||||
|
||||
|
||||
/* read in literal and distance code lengths */
|
||||
n = nl + nd;
|
||||
m = mask_bits[bl];
|
||||
i = l = 0;
|
||||
while ((unsigned)i < n)
|
||||
{
|
||||
NEEDBITS((unsigned)bl)
|
||||
j = (td = tl + ((unsigned)b & m))->b;
|
||||
DUMPBITS(j)
|
||||
j = td->v.n;
|
||||
if (j < 16) /* length of code in bits (0..15) */
|
||||
ll[i++] = l = j; /* save last length in l */
|
||||
else if (j == 16) /* repeat last length 3 to 6 times */
|
||||
{
|
||||
NEEDBITS(2)
|
||||
j = 3 + ((unsigned)b & 3);
|
||||
DUMPBITS(2)
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
ll[i++] = l;
|
||||
}
|
||||
else if (j == 17) /* 3 to 10 zero length codes */
|
||||
{
|
||||
NEEDBITS(3)
|
||||
j = 3 + ((unsigned)b & 7);
|
||||
DUMPBITS(3)
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
ll[i++] = 0;
|
||||
l = 0;
|
||||
}
|
||||
else /* j == 18: 11 to 138 zero length codes */
|
||||
{
|
||||
NEEDBITS(7)
|
||||
j = 11 + ((unsigned)b & 0x7f);
|
||||
DUMPBITS(7)
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
ll[i++] = 0;
|
||||
l = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* free decoding table for trees */
|
||||
huft_free(tl);
|
||||
|
||||
|
||||
/* restore the global bit buffer */
|
||||
bb = b;
|
||||
bk = k;
|
||||
|
||||
|
||||
/* build the decoding tables for literal/length and distance codes */
|
||||
bl = lbits;
|
||||
if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
|
||||
{
|
||||
if (i == 1) {
|
||||
fprintf(stderr, " incomplete literal tree\n");
|
||||
huft_free(tl);
|
||||
}
|
||||
return i; /* incomplete code set */
|
||||
}
|
||||
bd = dbits;
|
||||
if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
|
||||
{
|
||||
if (i == 1) {
|
||||
fprintf(stderr, " incomplete distance tree\n");
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
i = 0;
|
||||
}
|
||||
#else
|
||||
huft_free(td);
|
||||
}
|
||||
huft_free(tl);
|
||||
return i; /* incomplete code set */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
if (inflate_codes(tl, td, bl, bd))
|
||||
return 1;
|
||||
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate_block(e)
|
||||
int *e; /* last block flag */
|
||||
/* decompress an inflated block */
|
||||
{
|
||||
unsigned t; /* block type */
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
/* make local bit buffer */
|
||||
b = bb;
|
||||
k = bk;
|
||||
|
||||
|
||||
/* read in last block bit */
|
||||
NEEDBITS(1)
|
||||
*e = (int)b & 1;
|
||||
DUMPBITS(1)
|
||||
|
||||
|
||||
/* read in block type */
|
||||
NEEDBITS(2)
|
||||
t = (unsigned)b & 3;
|
||||
DUMPBITS(2)
|
||||
|
||||
|
||||
/* restore the global bit buffer */
|
||||
bb = b;
|
||||
bk = k;
|
||||
|
||||
|
||||
/* inflate that block type */
|
||||
if (t == 2)
|
||||
return inflate_dynamic();
|
||||
if (t == 0)
|
||||
return inflate_stored();
|
||||
if (t == 1)
|
||||
return inflate_fixed();
|
||||
|
||||
|
||||
/* bad block type */
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int inflate()
|
||||
/* decompress an inflated entry */
|
||||
{
|
||||
int e; /* last block flag */
|
||||
int r; /* result code */
|
||||
unsigned h; /* maximum struct huft's malloc'ed */
|
||||
|
||||
|
||||
/* initialize window, bit buffer */
|
||||
wp = 0;
|
||||
bk = 0;
|
||||
bb = 0;
|
||||
|
||||
|
||||
/* decompress until the last block */
|
||||
h = 0;
|
||||
do {
|
||||
hufts = 0;
|
||||
if ((r = inflate_block(&e)) != 0)
|
||||
return r;
|
||||
if (hufts > h)
|
||||
h = hufts;
|
||||
} while (!e);
|
||||
|
||||
/* Undo too much lookahead. The next read will be byte aligned so we
|
||||
* can discard unused bits in the last meaningful byte.
|
||||
*/
|
||||
while (bk >= 8) {
|
||||
bk -= 8;
|
||||
inptr--;
|
||||
}
|
||||
|
||||
/* flush out slide */
|
||||
flush_output(wp);
|
||||
|
||||
|
||||
/* return success */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "<%u> ", h);
|
||||
#endif /* DEBUG */
|
||||
return 0;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/* lzw.c -- compress files in LZW format.
|
||||
* This is a dummy version avoiding patent problems.
|
||||
*/
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: lzw.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "lzw.h"
|
||||
|
||||
static int msg_done = 0;
|
||||
|
||||
/* Compress in to out with lzw method. */
|
||||
int lzw(in, out)
|
||||
int in, out;
|
||||
{
|
||||
if (msg_done) return ERROR;
|
||||
msg_done = 1;
|
||||
fprintf(stderr,"output in compress .Z format not supported\n");
|
||||
if (in != out) { /* avoid warnings on unused variables */
|
||||
exit_code = ERROR;
|
||||
}
|
||||
return ERROR;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/* lzw.h -- define the lzw functions.
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#if !defined(OF) && defined(lint)
|
||||
# include "gzip.h"
|
||||
#endif
|
||||
|
||||
#ifndef BITS
|
||||
# define BITS 16
|
||||
#endif
|
||||
#define INIT_BITS 9 /* Initial number of bits per code */
|
||||
|
||||
#define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */
|
||||
|
||||
#define BIT_MASK 0x1f /* Mask for 'number of compression bits' */
|
||||
/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
|
||||
* It's a pity that old uncompress does not check bit 0x20. That makes
|
||||
* extension of the format actually undesirable because old compress
|
||||
* would just crash on the new format instead of giving a meaningful
|
||||
* error message. It does check the number of bits, but it's more
|
||||
* helpful to say "unsupported format, get a new version" than
|
||||
* "can only handle 16 bits".
|
||||
*/
|
||||
|
||||
#define BLOCK_MODE 0x80
|
||||
/* Block compression: if table is full and compression rate is dropping,
|
||||
* clear the dictionary.
|
||||
*/
|
||||
|
||||
#define LZW_RESERVED 0x60 /* reserved bits */
|
||||
|
||||
#define CLEAR 256 /* flush the dictionary */
|
||||
#define FIRST (CLEAR+1) /* first free entry */
|
||||
|
||||
extern int maxbits; /* max bits per code for LZW */
|
||||
extern int block_mode; /* block compress mode -C compatible with 2.0 */
|
||||
|
||||
extern int lzw OF((int in, int out));
|
||||
extern int unlzw OF((int in, int out));
|
@ -1,379 +0,0 @@
|
||||
/* match.s -- optional optimized asm version of longest match in deflate.c
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*
|
||||
* The 68020 version has been written by Francesco Potorti` <pot@cnuce.cnr.it>
|
||||
* with adaptations by Carsten Steger <stegerc@informatik.tu-muenchen.de>,
|
||||
* Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de> and
|
||||
* Kristoffer Eriksson <ske@pkmab.se>
|
||||
*/
|
||||
|
||||
/* $Id: match.S 3476 2003-06-11 15:56:10Z darkwyrm $ */
|
||||
|
||||
/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
|
||||
* external symbols with an underline character '_'.
|
||||
*/
|
||||
#ifdef NO_UNDERLINE
|
||||
# define _prev prev
|
||||
# define _window window
|
||||
# define _match_start match_start
|
||||
# define _prev_length prev_length
|
||||
# define _good_match good_match
|
||||
# define _nice_match nice_match
|
||||
# define _strstart strstart
|
||||
# define _max_chain_length max_chain_length
|
||||
|
||||
# define _match_init match_init
|
||||
# define _longest_match longest_match
|
||||
#endif
|
||||
|
||||
#ifdef DYN_ALLOC
|
||||
error: DYN_ALLOC not yet supported in match.s
|
||||
#endif
|
||||
|
||||
#if defined(i386) || defined(_I386)
|
||||
|
||||
/* This version is for 386 Unix or OS/2 in 32 bit mode.
|
||||
* Warning: it uses the AT&T syntax: mov source,dest
|
||||
* This file is only optional. If you want to force the C version,
|
||||
* add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
|
||||
* If you have reduced WSIZE in gzip.h, then change its value below.
|
||||
* This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
|
||||
*/
|
||||
|
||||
.file "match.S"
|
||||
|
||||
#define MAX_MATCH 258
|
||||
#define MAX_MATCH2 $128 /* MAX_MATCH/2-1 */
|
||||
#define MIN_MATCH 3
|
||||
#define WSIZE $32768
|
||||
#define MAX_DIST WSIZE - MAX_MATCH - MIN_MATCH - 1
|
||||
|
||||
.globl _match_init
|
||||
.globl _longest_match
|
||||
|
||||
.text
|
||||
|
||||
_match_init:
|
||||
ret
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* 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
|
||||
*/
|
||||
|
||||
_longest_match: /* int longest_match(cur_match) */
|
||||
|
||||
#define cur_match 20(%esp)
|
||||
/* return address */ /* esp+16 */
|
||||
push %ebp /* esp+12 */
|
||||
push %edi /* esp+8 */
|
||||
push %esi /* esp+4 */
|
||||
push %ebx /* esp */
|
||||
|
||||
/*
|
||||
* match equ esi
|
||||
* scan equ edi
|
||||
* chain_length equ ebp
|
||||
* best_len equ ebx
|
||||
* limit equ edx
|
||||
*/
|
||||
mov cur_match,%esi
|
||||
mov _max_chain_length,%ebp /* chain_length = max_chain_length */
|
||||
mov _strstart,%edi
|
||||
mov %edi,%edx
|
||||
sub MAX_DIST,%edx /* limit = strstart-MAX_DIST */
|
||||
jae limit_ok
|
||||
sub %edx,%edx /* limit = NIL */
|
||||
limit_ok:
|
||||
add $2+_window,%edi /* edi = offset(window+strstart+2) */
|
||||
mov _prev_length,%ebx /* best_len = prev_length */
|
||||
movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */
|
||||
movw -2(%edi),%cx /* cx = scan[0..1] */
|
||||
cmp _good_match,%ebx /* do we have a good match already? */
|
||||
jb do_scan
|
||||
shr $2,%ebp /* chain_length >>= 2 */
|
||||
jmp do_scan
|
||||
|
||||
.align 4
|
||||
long_loop:
|
||||
/* at this point, edi == scan+2, esi == cur_match */
|
||||
movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */
|
||||
movw -2(%edi),%cx /* cx = scan[0..1] */
|
||||
short_loop:
|
||||
/*
|
||||
* at this point, di == scan+2, si == cur_match,
|
||||
* ax = scan[best_len-1..best_len] and cx = scan[0..1]
|
||||
*/
|
||||
and WSIZE-1, %esi
|
||||
movw _prev(%esi,%esi),%si /* cur_match = prev[cur_match] */
|
||||
/* top word of esi is still 0 */
|
||||
cmp %edx,%esi /* cur_match <= limit ? */
|
||||
jbe the_end
|
||||
dec %ebp /* --chain_length */
|
||||
jz the_end
|
||||
do_scan:
|
||||
cmpw _window-1(%ebx,%esi),%ax/* check match at best_len-1 */
|
||||
jne short_loop
|
||||
cmpw _window(%esi),%cx /* check min_match_length match */
|
||||
jne short_loop
|
||||
|
||||
lea _window+2(%esi),%esi /* si = match */
|
||||
mov %edi,%eax /* ax = scan+2 */
|
||||
mov MAX_MATCH2,%ecx /* scan for at most MAX_MATCH bytes */
|
||||
rep; cmpsw /* loop until mismatch */
|
||||
je maxmatch /* match of length MAX_MATCH? */
|
||||
mismatch:
|
||||
movb -2(%edi),%cl /* mismatch on first or second byte? */
|
||||
subb -2(%esi),%cl /* cl = 0 if first bytes equal */
|
||||
xchg %edi,%eax /* edi = scan+2, eax = end of scan */
|
||||
sub %edi,%eax /* eax = len */
|
||||
sub %eax,%esi /* esi = cur_match + 2 + offset(window) */
|
||||
sub $2+_window,%esi /* esi = cur_match */
|
||||
subb $1,%cl /* set carry if cl == 0 (cannot use DEC) */
|
||||
adc $0,%eax /* eax = carry ? len+1 : len */
|
||||
cmp %ebx,%eax /* len > best_len ? */
|
||||
jle long_loop
|
||||
mov %esi,_match_start /* match_start = cur_match */
|
||||
mov %eax,%ebx /* ebx = best_len = len */
|
||||
cmp _nice_match,%eax /* len >= nice_match ? */
|
||||
jl long_loop
|
||||
the_end:
|
||||
mov %ebx,%eax /* result = eax = best_len */
|
||||
pop %ebx
|
||||
pop %esi
|
||||
pop %edi
|
||||
pop %ebp
|
||||
ret
|
||||
maxmatch:
|
||||
cmpsb
|
||||
jmp mismatch
|
||||
|
||||
#else
|
||||
|
||||
/* ======================== 680x0 version ================================= */
|
||||
|
||||
#if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__)
|
||||
# ifndef mc68000
|
||||
# define mc68000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68)
|
||||
# ifndef mc68020
|
||||
# define mc68020
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(mc68020) || defined(mc68000)
|
||||
|
||||
#if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK)
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef sysV68 /* Try Motorola Delta style */
|
||||
|
||||
# define GLOBAL(symbol) global symbol
|
||||
# define TEXT text
|
||||
# define FILE(filename) file filename
|
||||
# define invert_maybe(src,dst) dst,src
|
||||
# define imm(data) &data
|
||||
# define reg(register) %register
|
||||
|
||||
# define addl add.l
|
||||
# define addql addq.l
|
||||
# define blos blo.b
|
||||
# define bhis bhi.b
|
||||
# define bras bra.b
|
||||
# define clrl clr.l
|
||||
# define cmpmb cmpm.b
|
||||
# define cmpw cmp.w
|
||||
# define cmpl cmp.l
|
||||
# define lslw lsl.w
|
||||
# define lsrl lsr.l
|
||||
# define movel move.l
|
||||
# define movew move.w
|
||||
# define moveb move.b
|
||||
# define moveml movem.l
|
||||
# define subl sub.l
|
||||
# define subw sub.w
|
||||
# define subql subq.l
|
||||
|
||||
# define IndBase(bd,An) (bd,An)
|
||||
# define IndBaseNdxl(bd,An,Xn) (bd,An,Xn.l)
|
||||
# define IndBaseNdxw(bd,An,Xn) (bd,An,Xn.w)
|
||||
# define predec(An) -(An)
|
||||
# define postinc(An) (An)+
|
||||
|
||||
#else /* default style (Sun 3, NeXT, Amiga, Atari) */
|
||||
|
||||
# define GLOBAL(symbol) .globl symbol
|
||||
# define TEXT .text
|
||||
# define FILE(filename) .even
|
||||
# define invert_maybe(src,dst) src,dst
|
||||
# if defined(sun) || defined(mc68k)
|
||||
# define imm(data) #data
|
||||
# else
|
||||
# define imm(data) \#data
|
||||
# endif
|
||||
# define reg(register) register
|
||||
|
||||
# define blos bcss
|
||||
# if defined(sun) || defined(mc68k)
|
||||
# define movel movl
|
||||
# define movew movw
|
||||
# define moveb movb
|
||||
# endif
|
||||
# define IndBase(bd,An) An@(bd)
|
||||
# define IndBaseNdxl(bd,An,Xn) An@(bd,Xn:l)
|
||||
# define IndBaseNdxw(bd,An,Xn) An@(bd,Xn:w)
|
||||
# define predec(An) An@-
|
||||
# define postinc(An) An@+
|
||||
|
||||
#endif /* styles */
|
||||
|
||||
#define Best_Len reg(d0) /* unsigned */
|
||||
#define Cur_Match reg(d1) /* Ipos */
|
||||
#define Loop_Counter reg(d2) /* int */
|
||||
#define Scan_Start reg(d3) /* unsigned short */
|
||||
#define Scan_End reg(d4) /* unsigned short */
|
||||
#define Limit reg(d5) /* IPos */
|
||||
#define Chain_Length reg(d6) /* unsigned */
|
||||
#define Scan_Test reg(d7)
|
||||
#define Scan reg(a0) /* *uch */
|
||||
#define Match reg(a1) /* *uch */
|
||||
#define Prev_Address reg(a2) /* *Pos */
|
||||
#define Scan_Ini reg(a3) /* *uch */
|
||||
#define Match_Ini reg(a4) /* *uch */
|
||||
#define Stack_Pointer reg(sp)
|
||||
|
||||
#define MAX_MATCH 258
|
||||
#define MIN_MATCH 3
|
||||
#define WSIZE 32768
|
||||
#define MAX_DIST (WSIZE - MAX_MATCH - MIN_MATCH - 1)
|
||||
|
||||
GLOBAL (_match_init)
|
||||
GLOBAL (_longest_match)
|
||||
|
||||
TEXT
|
||||
|
||||
FILE ("match.S")
|
||||
|
||||
_match_init:
|
||||
rts
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* int longest_match (cur_match) */
|
||||
|
||||
#ifdef UNALIGNED_OK
|
||||
# define pushreg 15928 /* d2-d6/a2-a4 */
|
||||
# define popreg 7292
|
||||
#else
|
||||
# define pushreg 16184 /* d2-d7/a2-a4 */
|
||||
# define popreg 7420
|
||||
#endif
|
||||
|
||||
_longest_match:
|
||||
movel IndBase(4,Stack_Pointer),Cur_Match
|
||||
moveml imm(pushreg),predec(Stack_Pointer)
|
||||
movel _max_chain_length,Chain_Length
|
||||
movel _prev_length,Best_Len
|
||||
movel imm(_prev),Prev_Address
|
||||
movel imm(_window+MIN_MATCH),Match_Ini
|
||||
movel _strstart,Limit
|
||||
movel Match_Ini,Scan_Ini
|
||||
addl Limit,Scan_Ini
|
||||
subw imm(MAX_DIST),Limit
|
||||
bhis L__limit_ok
|
||||
clrl Limit
|
||||
L__limit_ok:
|
||||
cmpl invert_maybe(_good_match,Best_Len)
|
||||
blos L__length_ok
|
||||
lsrl imm(2),Chain_Length
|
||||
L__length_ok:
|
||||
subql imm(1),Chain_Length
|
||||
#ifdef UNALIGNED_OK
|
||||
movew IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
|
||||
movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
|
||||
#else
|
||||
moveb IndBase(-MIN_MATCH,Scan_Ini),Scan_Start
|
||||
lslw imm(8),Scan_Start
|
||||
moveb IndBase(-MIN_MATCH+1,Scan_Ini),Scan_Start
|
||||
moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
|
||||
lslw imm(8),Scan_End
|
||||
moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
|
||||
#endif
|
||||
bras L__do_scan
|
||||
|
||||
L__long_loop:
|
||||
#ifdef UNALIGNED_OK
|
||||
movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
|
||||
#else
|
||||
moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End
|
||||
lslw imm(8),Scan_End
|
||||
moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End
|
||||
#endif
|
||||
|
||||
L__short_loop:
|
||||
lslw imm(1),Cur_Match
|
||||
movew IndBaseNdxl(0,Prev_Address,Cur_Match),Cur_Match
|
||||
cmpw invert_maybe(Limit,Cur_Match)
|
||||
dbls Chain_Length,L__do_scan
|
||||
bras L__return
|
||||
|
||||
L__do_scan:
|
||||
movel Match_Ini,Match
|
||||
addl Cur_Match,Match
|
||||
#ifdef UNALIGNED_OK
|
||||
cmpw invert_maybe(IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_End)
|
||||
bne L__short_loop
|
||||
cmpw invert_maybe(IndBase(-MIN_MATCH,Match),Scan_Start)
|
||||
bne L__short_loop
|
||||
#else
|
||||
moveb IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_Test
|
||||
lslw imm(8),Scan_Test
|
||||
moveb IndBaseNdxw(-MIN_MATCH,Match,Best_Len),Scan_Test
|
||||
cmpw invert_maybe(Scan_Test,Scan_End)
|
||||
bne L__short_loop
|
||||
moveb IndBase(-MIN_MATCH,Match),Scan_Test
|
||||
lslw imm(8),Scan_Test
|
||||
moveb IndBase(-MIN_MATCH+1,Match),Scan_Test
|
||||
cmpw invert_maybe(Scan_Test,Scan_Start)
|
||||
bne L__short_loop
|
||||
#endif
|
||||
|
||||
movew imm((MAX_MATCH-MIN_MATCH+1)-1),Loop_Counter
|
||||
movel Scan_Ini,Scan
|
||||
L__scan_loop:
|
||||
cmpmb postinc(Match),postinc(Scan)
|
||||
dbne Loop_Counter,L__scan_loop
|
||||
|
||||
subl Scan_Ini,Scan
|
||||
addql imm(MIN_MATCH-1),Scan
|
||||
cmpl invert_maybe(Best_Len,Scan)
|
||||
bls L__short_loop
|
||||
movel Scan,Best_Len
|
||||
movel Cur_Match,_match_start
|
||||
cmpl invert_maybe(_nice_match,Best_Len)
|
||||
blos L__long_loop
|
||||
L__return:
|
||||
moveml postinc(Stack_Pointer),imm(popreg)
|
||||
rts
|
||||
|
||||
#else
|
||||
error: this asm version is for 386 or 680x0 only
|
||||
#endif /* mc68000 || mc68020 */
|
||||
#endif /* i386 || _I386 */
|
@ -1,16 +0,0 @@
|
||||
/* revision.h -- define the version number
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#define VERSION "1.2.4"
|
||||
#define PATCHLEVEL 0
|
||||
#define REVDATE "18 Aug 93"
|
||||
|
||||
/* This version does not support compression into old compress format: */
|
||||
#ifdef LZW
|
||||
# undef LZW
|
||||
#endif
|
||||
|
||||
/* $Id: revision.h 3476 2003-06-11 15:56:10Z darkwyrm $ */
|
@ -1,327 +0,0 @@
|
||||
/* tailor.h -- target dependent definitions
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly.
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
/* The target dependent definitions should be defined here only.
|
||||
* The target dependent functions should be defined in tailor.c.
|
||||
*/
|
||||
|
||||
/* $Id: tailor.h 3476 2003-06-11 15:56:10Z darkwyrm $ */
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
|
||||
#if defined(__OS2__) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
|
||||
#if defined(OS2) && defined(MSDOS) /* MS C under OS/2 */
|
||||
# undef MSDOS
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
# ifdef __GNUC__
|
||||
/* DJGPP version 1.09+ on MS-DOS.
|
||||
* The DJGPP 1.09 stat() function must be upgraded before gzip will
|
||||
* fully work.
|
||||
* No need for DIRENT, since <unistd.h> defines POSIX_SOURCE which
|
||||
* implies DIRENT.
|
||||
*/
|
||||
# define near
|
||||
# else
|
||||
# define MAXSEG_64K
|
||||
# ifdef __TURBOC__
|
||||
# define NO_OFF_T
|
||||
# ifdef __BORLANDC__
|
||||
# define DIRENT
|
||||
# else
|
||||
# define NO_UTIME
|
||||
# endif
|
||||
# else /* MSC */
|
||||
# define HAVE_SYS_UTIME_H
|
||||
# define NO_UTIME_H
|
||||
# endif
|
||||
# endif
|
||||
# define PATH_SEP2 '\\'
|
||||
# define PATH_SEP3 ':'
|
||||
# define MAX_PATH_LEN 128
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define MAX_EXT_CHARS 3
|
||||
# define Z_SUFFIX "z"
|
||||
# define NO_CHOWN
|
||||
# define PROTO
|
||||
# define STDC_HEADERS
|
||||
# define NO_SIZE_CHECK
|
||||
# define casemap(c) tolow(c) /* Force file names to lower case */
|
||||
# include <io.h>
|
||||
# define OS_CODE 0x00
|
||||
# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
|
||||
# if !defined(NO_ASM) && !defined(ASMV)
|
||||
# define ASMV
|
||||
# endif
|
||||
#else
|
||||
# define near
|
||||
#endif
|
||||
|
||||
#ifdef OS2
|
||||
# define PATH_SEP2 '\\'
|
||||
# define PATH_SEP3 ':'
|
||||
# define MAX_PATH_LEN 260
|
||||
# ifdef OS2FAT
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define MAX_EXT_CHARS 3
|
||||
# define Z_SUFFIX "z"
|
||||
# define casemap(c) tolow(c)
|
||||
# endif
|
||||
# define NO_CHOWN
|
||||
# define PROTO
|
||||
# define STDC_HEADERS
|
||||
# include <io.h>
|
||||
# define OS_CODE 0x06
|
||||
# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
|
||||
# ifdef _MSC_VER
|
||||
# define HAVE_SYS_UTIME_H
|
||||
# define NO_UTIME_H
|
||||
# define MAXSEG_64K
|
||||
# undef near
|
||||
# define near _near
|
||||
# endif
|
||||
# ifdef __EMX__
|
||||
# define HAVE_SYS_UTIME_H
|
||||
# define NO_UTIME_H
|
||||
# define DIRENT
|
||||
# define EXPAND(argc,argv) \
|
||||
{_response(&argc, &argv); _wildcard(&argc, &argv);}
|
||||
# endif
|
||||
# ifdef __BORLANDC__
|
||||
# define DIRENT
|
||||
# endif
|
||||
# ifdef __ZTC__
|
||||
# define NO_DIR
|
||||
# define NO_UTIME_H
|
||||
# include <dos.h>
|
||||
# define EXPAND(argc,argv) \
|
||||
{response_expand(&argc, &argv);}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32 /* Windows NT */
|
||||
# define HAVE_SYS_UTIME_H
|
||||
# define NO_UTIME_H
|
||||
# define PATH_SEP2 '\\'
|
||||
# define PATH_SEP3 ':'
|
||||
# define MAX_PATH_LEN 260
|
||||
# define NO_CHOWN
|
||||
# define PROTO
|
||||
# define STDC_HEADERS
|
||||
# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY)
|
||||
# include <io.h>
|
||||
# include <malloc.h>
|
||||
# ifdef NTFAT
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define MAX_EXT_CHARS 3
|
||||
# define Z_SUFFIX "z"
|
||||
# define casemap(c) tolow(c) /* Force file names to lower case */
|
||||
# endif
|
||||
# define OS_CODE 0x0b
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
# ifdef __TURBOC__
|
||||
# include <alloc.h>
|
||||
# define DYN_ALLOC
|
||||
/* Turbo C 2.0 does not accept static allocations of large arrays */
|
||||
void * fcalloc (unsigned items, unsigned size);
|
||||
void fcfree (void *ptr);
|
||||
# else /* MSC */
|
||||
# include <malloc.h>
|
||||
# define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize))
|
||||
# define fcfree(ptr) hfree(ptr)
|
||||
# endif
|
||||
#else
|
||||
# ifdef MAXSEG_64K
|
||||
# define fcalloc(items,size) calloc((items),(size))
|
||||
# else
|
||||
# define fcalloc(items,size) malloc((size_t)(items)*(size_t)(size))
|
||||
# endif
|
||||
# define fcfree(ptr) free(ptr)
|
||||
#endif
|
||||
|
||||
#if defined(VAXC) || defined(VMS)
|
||||
# define PATH_SEP ']'
|
||||
# define PATH_SEP2 ':'
|
||||
# define SUFFIX_SEP ';'
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define Z_SUFFIX "-gz"
|
||||
# define RECORD_IO 1
|
||||
# define casemap(c) tolow(c)
|
||||
# define OS_CODE 0x02
|
||||
# define OPTIONS_VAR "GZIP_OPT"
|
||||
# define STDC_HEADERS
|
||||
# define NO_UTIME
|
||||
# define EXPAND(argc,argv) vms_expand_args(&argc,&argv);
|
||||
# include <file.h>
|
||||
# define unlink delete
|
||||
# ifdef VAXC
|
||||
# define NO_FCNTL_H
|
||||
# include <unixio.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The Amiga version using gcc can just use the normal configure to
|
||||
set ASMV, HAVE_UNISTD_H, and DIRENT */
|
||||
|
||||
#ifdef AMIGA
|
||||
# define PATH_SEP2 ':'
|
||||
# define STDC_HEADERS
|
||||
# define OS_CODE 0x01
|
||||
# ifndef __GNUC__ /* SASC */
|
||||
# define NO_STDIN_FSTAT
|
||||
# define SYSDIR
|
||||
# define NO_SYMLINK
|
||||
# define NO_CHOWN
|
||||
# define NO_FCNTL_H
|
||||
# include <fcntl.h> /* for read() and write() */
|
||||
# define direct dirent
|
||||
extern void _expand_args(int *argc, char ***argv);
|
||||
# define EXPAND(argc,argv) _expand_args(&argc,&argv);
|
||||
# undef O_BINARY /* disable useless --ascii option */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(ATARI) || defined(atarist)
|
||||
# ifndef STDC_HEADERS
|
||||
# define STDC_HEADERS
|
||||
# define HAVE_UNISTD_H
|
||||
# define DIRENT
|
||||
# endif
|
||||
# define ASMV
|
||||
# define OS_CODE 0x05
|
||||
# ifdef TOSFS
|
||||
# define PATH_SEP2 '\\'
|
||||
# define PATH_SEP3 ':'
|
||||
# define MAX_PATH_LEN 128
|
||||
# define NO_MULTIPLE_DOTS
|
||||
# define MAX_EXT_CHARS 3
|
||||
# define Z_SUFFIX "z"
|
||||
# define NO_CHOWN
|
||||
# define casemap(c) tolow(c) /* Force file names to lower case */
|
||||
# define NO_SYMLINK
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef MACOS
|
||||
# define PATH_SEP ':'
|
||||
# define DYN_ALLOC
|
||||
# define PROTO
|
||||
# define NO_STDIN_FSTAT
|
||||
# define NO_CHOWN
|
||||
# define NO_UTIME
|
||||
# define chmod(file, mode) (0)
|
||||
# define OPEN(name, flags, mode) open(name, flags)
|
||||
# define OS_CODE 0x07
|
||||
# ifdef MPW
|
||||
# define isatty(fd) ((fd) <= 2)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __50SERIES /* Prime/PRIMOS */
|
||||
# define PATH_SEP '>'
|
||||
# define STDC_HEADERS
|
||||
# define NO_MEMORY_H
|
||||
# define NO_UTIME_H
|
||||
# define NO_UTIME
|
||||
# define NO_CHOWN
|
||||
# define NO_STDIN_FSTAT
|
||||
# define NO_SIZE_CHECK
|
||||
# define NO_SYMLINK
|
||||
# define RECORD_IO 1
|
||||
# define casemap(c) tolow(c) /* Force file names to lower case */
|
||||
# define put_char(c) put_byte((c) & 0x7F)
|
||||
# define get_char(c) ascii2pascii(get_byte())
|
||||
# define OS_CODE 0x0F /* temporary, subject to change */
|
||||
# ifdef SIGTERM
|
||||
# undef SIGTERM /* We don't want a signal handler for SIGTERM */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(pyr) && !defined(NOMEMCPY) /* Pyramid */
|
||||
# define NOMEMCPY /* problem with overlapping copies */
|
||||
#endif
|
||||
|
||||
#ifdef TOPS20
|
||||
# define OS_CODE 0x0a
|
||||
#endif
|
||||
|
||||
#ifndef unix
|
||||
# define NO_ST_INO /* don't rely on inode numbers */
|
||||
#endif
|
||||
|
||||
|
||||
/* Common defaults */
|
||||
|
||||
#ifndef OS_CODE
|
||||
# define OS_CODE 0x03 /* assume Unix */
|
||||
#endif
|
||||
|
||||
#ifndef PATH_SEP
|
||||
# define PATH_SEP '/'
|
||||
#endif
|
||||
|
||||
#ifndef casemap
|
||||
# define casemap(c) (c)
|
||||
#endif
|
||||
|
||||
#ifndef OPTIONS_VAR
|
||||
# define OPTIONS_VAR "GZIP"
|
||||
#endif
|
||||
|
||||
#ifndef Z_SUFFIX
|
||||
# define Z_SUFFIX ".gz"
|
||||
#endif
|
||||
|
||||
#ifdef MAX_EXT_CHARS
|
||||
# define MAX_SUFFIX MAX_EXT_CHARS
|
||||
#else
|
||||
# define MAX_SUFFIX 30
|
||||
#endif
|
||||
|
||||
#ifndef MAKE_LEGAL_NAME
|
||||
# ifdef NO_MULTIPLE_DOTS
|
||||
# define MAKE_LEGAL_NAME(name) make_simple_name(name)
|
||||
# else
|
||||
# define MAKE_LEGAL_NAME(name)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef MIN_PART
|
||||
# define MIN_PART 3
|
||||
/* keep at least MIN_PART chars between dots in a file name. */
|
||||
#endif
|
||||
|
||||
#ifndef EXPAND
|
||||
# define EXPAND(argc,argv)
|
||||
#endif
|
||||
|
||||
#ifndef RECORD_IO
|
||||
# define RECORD_IO 0
|
||||
#endif
|
||||
|
||||
#ifndef SET_BINARY_MODE
|
||||
# define SET_BINARY_MODE(fd)
|
||||
#endif
|
||||
|
||||
#ifndef OPEN
|
||||
# define OPEN(name, flags, mode) open(name, flags, mode)
|
||||
#endif
|
||||
|
||||
#ifndef get_char
|
||||
# define get_char() get_byte()
|
||||
#endif
|
||||
|
||||
#ifndef put_char
|
||||
# define put_char(c) put_byte(c)
|
||||
#endif
|
1075
src/bin/gzip/trees.c
1075
src/bin/gzip/trees.c
File diff suppressed because it is too large
Load Diff
@ -1,401 +0,0 @@
|
||||
/* unlzh.c -- decompress files in SCO compress -H (LZH) format.
|
||||
* The code in this file is directly derived from the public domain 'ar002'
|
||||
* written by Haruhiko Okumura.
|
||||
*/
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: unlzh.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "lzw.h" /* just for consistency checking */
|
||||
|
||||
/* decode.c */
|
||||
|
||||
local unsigned decode OF((unsigned count, uch buffer[]));
|
||||
local void decode_start OF((void));
|
||||
|
||||
/* huf.c */
|
||||
local void huf_decode_start OF((void));
|
||||
local unsigned decode_c OF((void));
|
||||
local unsigned decode_p OF((void));
|
||||
local void read_pt_len OF((int nn, int nbit, int i_special));
|
||||
local void read_c_len OF((void));
|
||||
|
||||
/* io.c */
|
||||
local void fillbuf OF((int n));
|
||||
local unsigned getbits OF((int n));
|
||||
local void init_getbits OF((void));
|
||||
|
||||
/* maketbl.c */
|
||||
|
||||
local void make_table OF((int nchar, uch bitlen[],
|
||||
int tablebits, ush table[]));
|
||||
|
||||
|
||||
#define DICBIT 13 /* 12(-lh4-) or 13(-lh5-) */
|
||||
#define DICSIZ ((unsigned) 1 << DICBIT)
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
# define CHAR_BIT 8
|
||||
#endif
|
||||
|
||||
#ifndef UCHAR_MAX
|
||||
# define UCHAR_MAX 255
|
||||
#endif
|
||||
|
||||
#define BITBUFSIZ (CHAR_BIT * 2 * sizeof(char))
|
||||
/* Do not use CHAR_BIT * sizeof(bitbuf), does not work on machines
|
||||
* for which short is not on 16 bits (Cray).
|
||||
*/
|
||||
|
||||
/* encode.c and decode.c */
|
||||
|
||||
#define MAXMATCH 256 /* formerly F (not more than UCHAR_MAX + 1) */
|
||||
#define THRESHOLD 3 /* choose optimal value */
|
||||
|
||||
/* huf.c */
|
||||
|
||||
#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
|
||||
/* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
#define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */
|
||||
#define CODE_BIT 16 /* codeword length */
|
||||
|
||||
#define NP (DICBIT + 1)
|
||||
#define NT (CODE_BIT + 3)
|
||||
#define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */
|
||||
#define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */
|
||||
#if NT > NP
|
||||
# define NPT NT
|
||||
#else
|
||||
# define NPT NP
|
||||
#endif
|
||||
|
||||
/* local ush left[2 * NC - 1]; */
|
||||
/* local ush right[2 * NC - 1]; */
|
||||
#define left prev
|
||||
#define right head
|
||||
#if NC > (1<<(BITS-2))
|
||||
error cannot overlay left+right and prev
|
||||
#endif
|
||||
|
||||
/* local uch c_len[NC]; */
|
||||
#define c_len outbuf
|
||||
#if NC > OUTBUFSIZ
|
||||
error cannot overlay c_len and outbuf
|
||||
#endif
|
||||
|
||||
local uch pt_len[NPT];
|
||||
local unsigned blocksize;
|
||||
local ush pt_table[256];
|
||||
|
||||
/* local ush c_table[4096]; */
|
||||
#define c_table d_buf
|
||||
#if (DIST_BUFSIZE-1) < 4095
|
||||
error cannot overlay c_table and d_buf
|
||||
#endif
|
||||
|
||||
/***********************************************************
|
||||
io.c -- input/output
|
||||
***********************************************************/
|
||||
|
||||
local ush bitbuf;
|
||||
local unsigned subbitbuf;
|
||||
local int bitcount;
|
||||
|
||||
local void fillbuf(n) /* Shift bitbuf n bits left, read n bits */
|
||||
int n;
|
||||
{
|
||||
bitbuf <<= n;
|
||||
while (n > bitcount) {
|
||||
bitbuf |= subbitbuf << (n -= bitcount);
|
||||
subbitbuf = (unsigned)try_byte();
|
||||
if ((int)subbitbuf == EOF) subbitbuf = 0;
|
||||
bitcount = CHAR_BIT;
|
||||
}
|
||||
bitbuf |= subbitbuf >> (bitcount -= n);
|
||||
}
|
||||
|
||||
local unsigned getbits(n)
|
||||
int n;
|
||||
{
|
||||
unsigned x;
|
||||
|
||||
x = bitbuf >> (BITBUFSIZ - n); fillbuf(n);
|
||||
return x;
|
||||
}
|
||||
|
||||
local void init_getbits()
|
||||
{
|
||||
bitbuf = 0; subbitbuf = 0; bitcount = 0;
|
||||
fillbuf(BITBUFSIZ);
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
maketbl.c -- make table for decoding
|
||||
***********************************************************/
|
||||
|
||||
local void make_table(nchar, bitlen, tablebits, table)
|
||||
int nchar;
|
||||
uch bitlen[];
|
||||
int tablebits;
|
||||
ush table[];
|
||||
{
|
||||
ush count[17], weight[17], start[18], *p;
|
||||
unsigned i, k, len, ch, jutbits, avail, nextcode, mask;
|
||||
|
||||
for (i = 1; i <= 16; i++) count[i] = 0;
|
||||
for (i = 0; i < (unsigned)nchar; i++) count[bitlen[i]]++;
|
||||
|
||||
start[1] = 0;
|
||||
for (i = 1; i <= 16; i++)
|
||||
start[i + 1] = start[i] + (count[i] << (16 - i));
|
||||
if ((start[17] & 0xffff) != 0)
|
||||
error("Bad table\n");
|
||||
|
||||
jutbits = 16 - tablebits;
|
||||
for (i = 1; i <= (unsigned)tablebits; i++) {
|
||||
start[i] >>= jutbits;
|
||||
weight[i] = (unsigned) 1 << (tablebits - i);
|
||||
}
|
||||
while (i <= 16) {
|
||||
weight[i] = (unsigned) 1 << (16 - i);
|
||||
i++;
|
||||
}
|
||||
|
||||
i = start[tablebits + 1] >> jutbits;
|
||||
if (i != 0) {
|
||||
k = 1 << tablebits;
|
||||
while (i != k) table[i++] = 0;
|
||||
}
|
||||
|
||||
avail = nchar;
|
||||
mask = (unsigned) 1 << (15 - tablebits);
|
||||
for (ch = 0; ch < (unsigned)nchar; ch++) {
|
||||
if ((len = bitlen[ch]) == 0) continue;
|
||||
nextcode = start[len] + weight[len];
|
||||
if (len <= (unsigned)tablebits) {
|
||||
for (i = start[len]; i < nextcode; i++) table[i] = ch;
|
||||
} else {
|
||||
k = start[len];
|
||||
p = &table[k >> jutbits];
|
||||
i = len - tablebits;
|
||||
while (i != 0) {
|
||||
if (*p == 0) {
|
||||
right[avail] = left[avail] = 0;
|
||||
*p = avail++;
|
||||
}
|
||||
if (k & mask) p = &right[*p];
|
||||
else p = &left[*p];
|
||||
k <<= 1; i--;
|
||||
}
|
||||
*p = ch;
|
||||
}
|
||||
start[len] = nextcode;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
huf.c -- static Huffman
|
||||
***********************************************************/
|
||||
|
||||
local void read_pt_len(nn, nbit, i_special)
|
||||
int nn;
|
||||
int nbit;
|
||||
int i_special;
|
||||
{
|
||||
int i, c, n;
|
||||
unsigned mask;
|
||||
|
||||
n = getbits(nbit);
|
||||
if (n == 0) {
|
||||
c = getbits(nbit);
|
||||
for (i = 0; i < nn; i++) pt_len[i] = 0;
|
||||
for (i = 0; i < 256; i++) pt_table[i] = c;
|
||||
} else {
|
||||
i = 0;
|
||||
while (i < n) {
|
||||
c = bitbuf >> (BITBUFSIZ - 3);
|
||||
if (c == 7) {
|
||||
mask = (unsigned) 1 << (BITBUFSIZ - 1 - 3);
|
||||
while (mask & bitbuf) { mask >>= 1; c++; }
|
||||
}
|
||||
fillbuf((c < 7) ? 3 : c - 3);
|
||||
pt_len[i++] = c;
|
||||
if (i == i_special) {
|
||||
c = getbits(2);
|
||||
while (--c >= 0) pt_len[i++] = 0;
|
||||
}
|
||||
}
|
||||
while (i < nn) pt_len[i++] = 0;
|
||||
make_table(nn, pt_len, 8, pt_table);
|
||||
}
|
||||
}
|
||||
|
||||
local void read_c_len()
|
||||
{
|
||||
int i, c, n;
|
||||
unsigned mask;
|
||||
|
||||
n = getbits(CBIT);
|
||||
if (n == 0) {
|
||||
c = getbits(CBIT);
|
||||
for (i = 0; i < NC; i++) c_len[i] = 0;
|
||||
for (i = 0; i < 4096; i++) c_table[i] = c;
|
||||
} else {
|
||||
i = 0;
|
||||
while (i < n) {
|
||||
c = pt_table[bitbuf >> (BITBUFSIZ - 8)];
|
||||
if (c >= NT) {
|
||||
mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
|
||||
do {
|
||||
if (bitbuf & mask) c = right[c];
|
||||
else c = left [c];
|
||||
mask >>= 1;
|
||||
} while (c >= NT);
|
||||
}
|
||||
fillbuf((int) pt_len[c]);
|
||||
if (c <= 2) {
|
||||
if (c == 0) c = 1;
|
||||
else if (c == 1) c = getbits(4) + 3;
|
||||
else c = getbits(CBIT) + 20;
|
||||
while (--c >= 0) c_len[i++] = 0;
|
||||
} else c_len[i++] = c - 2;
|
||||
}
|
||||
while (i < NC) c_len[i++] = 0;
|
||||
make_table(NC, c_len, 12, c_table);
|
||||
}
|
||||
}
|
||||
|
||||
local unsigned decode_c()
|
||||
{
|
||||
unsigned j, mask;
|
||||
|
||||
if (blocksize == 0) {
|
||||
blocksize = getbits(16);
|
||||
if (blocksize == 0) {
|
||||
return NC; /* end of file */
|
||||
}
|
||||
read_pt_len(NT, TBIT, 3);
|
||||
read_c_len();
|
||||
read_pt_len(NP, PBIT, -1);
|
||||
}
|
||||
blocksize--;
|
||||
j = c_table[bitbuf >> (BITBUFSIZ - 12)];
|
||||
if (j >= NC) {
|
||||
mask = (unsigned) 1 << (BITBUFSIZ - 1 - 12);
|
||||
do {
|
||||
if (bitbuf & mask) j = right[j];
|
||||
else j = left [j];
|
||||
mask >>= 1;
|
||||
} while (j >= NC);
|
||||
}
|
||||
fillbuf((int) c_len[j]);
|
||||
return j;
|
||||
}
|
||||
|
||||
local unsigned decode_p()
|
||||
{
|
||||
unsigned j, mask;
|
||||
|
||||
j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
|
||||
if (j >= NP) {
|
||||
mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
|
||||
do {
|
||||
if (bitbuf & mask) j = right[j];
|
||||
else j = left [j];
|
||||
mask >>= 1;
|
||||
} while (j >= NP);
|
||||
}
|
||||
fillbuf((int) pt_len[j]);
|
||||
if (j != 0) j = ((unsigned) 1 << (j - 1)) + getbits((int) (j - 1));
|
||||
return j;
|
||||
}
|
||||
|
||||
local void huf_decode_start()
|
||||
{
|
||||
init_getbits(); blocksize = 0;
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
decode.c
|
||||
***********************************************************/
|
||||
|
||||
local int j; /* remaining bytes to copy */
|
||||
local int done; /* set at end of input */
|
||||
|
||||
local void decode_start()
|
||||
{
|
||||
huf_decode_start();
|
||||
j = 0;
|
||||
done = 0;
|
||||
}
|
||||
|
||||
/* Decode the input and return the number of decoded bytes put in buffer
|
||||
*/
|
||||
local unsigned decode(count, buffer)
|
||||
unsigned count;
|
||||
uch buffer[];
|
||||
/* The calling function must keep the number of
|
||||
bytes to be processed. This function decodes
|
||||
either 'count' bytes or 'DICSIZ' bytes, whichever
|
||||
is smaller, into the array 'buffer[]' of size
|
||||
'DICSIZ' or more.
|
||||
Call decode_start() once for each new file
|
||||
before calling this function.
|
||||
*/
|
||||
{
|
||||
local unsigned i;
|
||||
unsigned r, c;
|
||||
|
||||
r = 0;
|
||||
while (--j >= 0) {
|
||||
buffer[r] = buffer[i];
|
||||
i = (i + 1) & (DICSIZ - 1);
|
||||
if (++r == count) return r;
|
||||
}
|
||||
for ( ; ; ) {
|
||||
c = decode_c();
|
||||
if (c == NC) {
|
||||
done = 1;
|
||||
return r;
|
||||
}
|
||||
if (c <= UCHAR_MAX) {
|
||||
buffer[r] = c;
|
||||
if (++r == count) return r;
|
||||
} else {
|
||||
j = c - (UCHAR_MAX + 1 - THRESHOLD);
|
||||
i = (r - decode_p() - 1) & (DICSIZ - 1);
|
||||
while (--j >= 0) {
|
||||
buffer[r] = buffer[i];
|
||||
i = (i + 1) & (DICSIZ - 1);
|
||||
if (++r == count) return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Unlzh in to out. Return OK or ERROR.
|
||||
*/
|
||||
int unlzh(in, out)
|
||||
int in;
|
||||
int out;
|
||||
{
|
||||
unsigned n;
|
||||
ifd = in;
|
||||
ofd = out;
|
||||
|
||||
decode_start();
|
||||
while (!done) {
|
||||
n = decode((unsigned) DICSIZ, window);
|
||||
if (!test && n > 0) {
|
||||
write_buf(out, (char*)window, n);
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
@ -1,377 +0,0 @@
|
||||
/* unlzw.c -- decompress files in LZW format.
|
||||
* The code in this file is directly derived from the public domain 'compress'
|
||||
* written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
|
||||
* Ken Turkowski, Dave Mack and Peter Jannesen.
|
||||
*
|
||||
* This is a temporary version which will be rewritten in some future version
|
||||
* to accommodate in-memory decompression.
|
||||
*/
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: unlzw.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tailor.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifndef NO_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "gzip.h"
|
||||
#include "lzw.h"
|
||||
|
||||
typedef unsigned char char_type;
|
||||
typedef long code_int;
|
||||
typedef unsigned long count_int;
|
||||
typedef unsigned short count_short;
|
||||
typedef unsigned long cmp_code_int;
|
||||
|
||||
#define MAXCODE(n) (1L << (n))
|
||||
|
||||
#ifndef REGISTERS
|
||||
# define REGISTERS 2
|
||||
#endif
|
||||
#define REG1
|
||||
#define REG2
|
||||
#define REG3
|
||||
#define REG4
|
||||
#define REG5
|
||||
#define REG6
|
||||
#define REG7
|
||||
#define REG8
|
||||
#define REG9
|
||||
#define REG10
|
||||
#define REG11
|
||||
#define REG12
|
||||
#define REG13
|
||||
#define REG14
|
||||
#define REG15
|
||||
#define REG16
|
||||
#if REGISTERS >= 1
|
||||
# undef REG1
|
||||
# define REG1 register
|
||||
#endif
|
||||
#if REGISTERS >= 2
|
||||
# undef REG2
|
||||
# define REG2 register
|
||||
#endif
|
||||
#if REGISTERS >= 3
|
||||
# undef REG3
|
||||
# define REG3 register
|
||||
#endif
|
||||
#if REGISTERS >= 4
|
||||
# undef REG4
|
||||
# define REG4 register
|
||||
#endif
|
||||
#if REGISTERS >= 5
|
||||
# undef REG5
|
||||
# define REG5 register
|
||||
#endif
|
||||
#if REGISTERS >= 6
|
||||
# undef REG6
|
||||
# define REG6 register
|
||||
#endif
|
||||
#if REGISTERS >= 7
|
||||
# undef REG7
|
||||
# define REG7 register
|
||||
#endif
|
||||
#if REGISTERS >= 8
|
||||
# undef REG8
|
||||
# define REG8 register
|
||||
#endif
|
||||
#if REGISTERS >= 9
|
||||
# undef REG9
|
||||
# define REG9 register
|
||||
#endif
|
||||
#if REGISTERS >= 10
|
||||
# undef REG10
|
||||
# define REG10 register
|
||||
#endif
|
||||
#if REGISTERS >= 11
|
||||
# undef REG11
|
||||
# define REG11 register
|
||||
#endif
|
||||
#if REGISTERS >= 12
|
||||
# undef REG12
|
||||
# define REG12 register
|
||||
#endif
|
||||
#if REGISTERS >= 13
|
||||
# undef REG13
|
||||
# define REG13 register
|
||||
#endif
|
||||
#if REGISTERS >= 14
|
||||
# undef REG14
|
||||
# define REG14 register
|
||||
#endif
|
||||
#if REGISTERS >= 15
|
||||
# undef REG15
|
||||
# define REG15 register
|
||||
#endif
|
||||
#if REGISTERS >= 16
|
||||
# undef REG16
|
||||
# define REG16 register
|
||||
#endif
|
||||
|
||||
#ifndef BYTEORDER
|
||||
# define BYTEORDER 0000
|
||||
#endif
|
||||
|
||||
#ifndef NOALLIGN
|
||||
# define NOALLIGN 0
|
||||
#endif
|
||||
|
||||
|
||||
union bytes {
|
||||
long word;
|
||||
struct {
|
||||
#if BYTEORDER == 4321
|
||||
char_type b1;
|
||||
char_type b2;
|
||||
char_type b3;
|
||||
char_type b4;
|
||||
#else
|
||||
#if BYTEORDER == 1234
|
||||
char_type b4;
|
||||
char_type b3;
|
||||
char_type b2;
|
||||
char_type b1;
|
||||
#else
|
||||
# undef BYTEORDER
|
||||
int dummy;
|
||||
#endif
|
||||
#endif
|
||||
} bytes;
|
||||
};
|
||||
|
||||
#if BYTEORDER == 4321 && NOALLIGN == 1
|
||||
# define input(b,o,c,n,m){ \
|
||||
(c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \
|
||||
(o) += (n); \
|
||||
}
|
||||
#else
|
||||
# define input(b,o,c,n,m){ \
|
||||
REG1 char_type *p = &(b)[(o)>>3]; \
|
||||
(c) = ((((long)(p[0]))|((long)(p[1])<<8)| \
|
||||
((long)(p[2])<<16))>>((o)&0x7))&(m); \
|
||||
(o) += (n); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MAXSEG_64K
|
||||
/* DECLARE(ush, tab_prefix, (1<<BITS)); -- prefix code */
|
||||
# define tab_prefixof(i) tab_prefix[i]
|
||||
# define clear_tab_prefixof() memzero(tab_prefix, 256);
|
||||
#else
|
||||
/* DECLARE(ush, tab_prefix0, (1<<(BITS-1)); -- prefix for even codes */
|
||||
/* DECLARE(ush, tab_prefix1, (1<<(BITS-1)); -- prefix for odd codes */
|
||||
ush *tab_prefix[2];
|
||||
# define tab_prefixof(i) tab_prefix[(i)&1][(i)>>1]
|
||||
# define clear_tab_prefixof() \
|
||||
memzero(tab_prefix0, 128), \
|
||||
memzero(tab_prefix1, 128);
|
||||
#endif
|
||||
#define de_stack ((char_type *)(&d_buf[DIST_BUFSIZE-1]))
|
||||
#define tab_suffixof(i) tab_suffix[i]
|
||||
|
||||
int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */
|
||||
|
||||
/* ============================================================================
|
||||
* Decompress in to out. This routine adapts to the codes in the
|
||||
* file building the "string" table on-the-fly; requiring no table to
|
||||
* be stored in the compressed file.
|
||||
* IN assertions: the buffer inbuf contains already the beginning of
|
||||
* the compressed data, from offsets iptr to insize-1 included.
|
||||
* The magic header has already been checked and skipped.
|
||||
* bytes_in and bytes_out have been initialized.
|
||||
*/
|
||||
int unlzw(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
REG2 char_type *stackp;
|
||||
REG3 code_int code;
|
||||
REG4 int finchar;
|
||||
REG5 code_int oldcode;
|
||||
REG6 code_int incode;
|
||||
REG7 long inbits;
|
||||
REG8 long posbits;
|
||||
REG9 int outpos;
|
||||
/* REG10 int insize; (global) */
|
||||
REG11 unsigned bitmask;
|
||||
REG12 code_int free_ent;
|
||||
REG13 code_int maxcode;
|
||||
REG14 code_int maxmaxcode;
|
||||
REG15 int n_bits;
|
||||
REG16 int rsize;
|
||||
|
||||
#ifdef MAXSEG_64K
|
||||
tab_prefix[0] = tab_prefix0;
|
||||
tab_prefix[1] = tab_prefix1;
|
||||
#endif
|
||||
maxbits = get_byte();
|
||||
block_mode = maxbits & BLOCK_MODE;
|
||||
if ((maxbits & LZW_RESERVED) != 0) {
|
||||
WARN((stderr, "\n%s: %s: warning, unknown flags 0x%x\n",
|
||||
progname, ifname, maxbits & LZW_RESERVED));
|
||||
}
|
||||
maxbits &= BIT_MASK;
|
||||
maxmaxcode = MAXCODE(maxbits);
|
||||
|
||||
if (maxbits > BITS) {
|
||||
fprintf(stderr,
|
||||
"\n%s: %s: compressed with %d bits, can only handle %d bits\n",
|
||||
progname, ifname, maxbits, BITS);
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
rsize = insize;
|
||||
maxcode = MAXCODE(n_bits = INIT_BITS)-1;
|
||||
bitmask = (1<<n_bits)-1;
|
||||
oldcode = -1;
|
||||
finchar = 0;
|
||||
outpos = 0;
|
||||
posbits = inptr<<3;
|
||||
|
||||
free_ent = ((block_mode) ? FIRST : 256);
|
||||
|
||||
clear_tab_prefixof(); /* Initialize the first 256 entries in the table. */
|
||||
|
||||
for (code = 255 ; code >= 0 ; --code) {
|
||||
tab_suffixof(code) = (char_type)code;
|
||||
}
|
||||
do {
|
||||
REG1 int i;
|
||||
int e;
|
||||
int o;
|
||||
|
||||
resetbuf:
|
||||
e = insize-(o = (posbits>>3));
|
||||
|
||||
for (i = 0 ; i < e ; ++i) {
|
||||
inbuf[i] = inbuf[i+o];
|
||||
}
|
||||
insize = e;
|
||||
posbits = 0;
|
||||
|
||||
if (insize < INBUF_EXTRA) {
|
||||
if ((rsize = read(in, (char*)inbuf+insize, INBUFSIZ)) == EOF) {
|
||||
read_error();
|
||||
}
|
||||
insize += rsize;
|
||||
bytes_in += (ulg)rsize;
|
||||
}
|
||||
inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 :
|
||||
((long)insize<<3)-(n_bits-1));
|
||||
|
||||
while (inbits > posbits) {
|
||||
if (free_ent > maxcode) {
|
||||
posbits = ((posbits-1) +
|
||||
((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
|
||||
++n_bits;
|
||||
if (n_bits == maxbits) {
|
||||
maxcode = maxmaxcode;
|
||||
} else {
|
||||
maxcode = MAXCODE(n_bits)-1;
|
||||
}
|
||||
bitmask = (1<<n_bits)-1;
|
||||
goto resetbuf;
|
||||
}
|
||||
input(inbuf,posbits,code,n_bits,bitmask);
|
||||
Tracev((stderr, "%d ", code));
|
||||
|
||||
if (oldcode == -1) {
|
||||
if (code >= 256) error("corrupt input.");
|
||||
outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code));
|
||||
continue;
|
||||
}
|
||||
if (code == CLEAR && block_mode) {
|
||||
clear_tab_prefixof();
|
||||
free_ent = FIRST - 1;
|
||||
posbits = ((posbits-1) +
|
||||
((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
|
||||
maxcode = MAXCODE(n_bits = INIT_BITS)-1;
|
||||
bitmask = (1<<n_bits)-1;
|
||||
goto resetbuf;
|
||||
}
|
||||
incode = code;
|
||||
stackp = de_stack;
|
||||
|
||||
if (code >= free_ent) { /* Special case for KwKwK string. */
|
||||
if (code > free_ent) {
|
||||
#ifdef DEBUG
|
||||
char_type *p;
|
||||
|
||||
posbits -= n_bits;
|
||||
p = &inbuf[posbits>>3];
|
||||
fprintf(stderr,
|
||||
"code:%ld free_ent:%ld n_bits:%d insize:%u\n",
|
||||
code, free_ent, n_bits, insize);
|
||||
fprintf(stderr,
|
||||
"posbits:%ld inbuf:%02X %02X %02X %02X %02X\n",
|
||||
posbits, p[-1],p[0],p[1],p[2],p[3]);
|
||||
#endif
|
||||
if (!test && outpos > 0) {
|
||||
write_buf(out, (char*)outbuf, outpos);
|
||||
bytes_out += (ulg)outpos;
|
||||
}
|
||||
error(to_stdout ? "corrupt input." :
|
||||
"corrupt input. Use zcat to recover some data.");
|
||||
}
|
||||
*--stackp = (char_type)finchar;
|
||||
code = oldcode;
|
||||
}
|
||||
|
||||
while ((cmp_code_int)code >= (cmp_code_int)256) {
|
||||
/* Generate output characters in reverse order */
|
||||
*--stackp = tab_suffixof(code);
|
||||
code = tab_prefixof(code);
|
||||
}
|
||||
*--stackp = (char_type)(finchar = tab_suffixof(code));
|
||||
|
||||
/* And put them out in forward order */
|
||||
{
|
||||
REG1 int i;
|
||||
|
||||
if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) {
|
||||
do {
|
||||
if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos;
|
||||
|
||||
if (i > 0) {
|
||||
memcpy(outbuf+outpos, stackp, i);
|
||||
outpos += i;
|
||||
}
|
||||
if (outpos >= OUTBUFSIZ) {
|
||||
if (!test) {
|
||||
write_buf(out, (char*)outbuf, outpos);
|
||||
bytes_out += (ulg)outpos;
|
||||
}
|
||||
outpos = 0;
|
||||
}
|
||||
stackp+= i;
|
||||
} while ((i = (de_stack-stackp)) > 0);
|
||||
} else {
|
||||
memcpy(outbuf+outpos, stackp, i);
|
||||
outpos += i;
|
||||
}
|
||||
}
|
||||
|
||||
if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */
|
||||
|
||||
tab_prefixof(code) = (unsigned short)oldcode;
|
||||
tab_suffixof(code) = (char_type)finchar;
|
||||
free_ent = code+1;
|
||||
}
|
||||
oldcode = incode; /* Remember previous code. */
|
||||
}
|
||||
} while (rsize != 0);
|
||||
|
||||
if (!test && outpos > 0) {
|
||||
write_buf(out, (char*)outbuf, outpos);
|
||||
bytes_out += (ulg)outpos;
|
||||
}
|
||||
return OK;
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
/* unpack.c -- decompress files in pack format.
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: unpack.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
#define MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||
/* The arguments must not have side effects. */
|
||||
|
||||
#define MAX_BITLEN 25
|
||||
/* Maximum length of Huffman codes. (Minor modifications to the code
|
||||
* would be needed to support 32 bits codes, but pack never generates
|
||||
* more than 24 bits anyway.)
|
||||
*/
|
||||
|
||||
#define LITERALS 256
|
||||
/* Number of literals, excluding the End of Block (EOB) code */
|
||||
|
||||
#define MAX_PEEK 12
|
||||
/* Maximum number of 'peek' bits used to optimize traversal of the
|
||||
* Huffman tree.
|
||||
*/
|
||||
|
||||
local ulg orig_len; /* original uncompressed length */
|
||||
local int max_len; /* maximum bit length of Huffman codes */
|
||||
|
||||
local uch literal[LITERALS];
|
||||
/* The literal bytes present in the Huffman tree. The EOB code is not
|
||||
* represented.
|
||||
*/
|
||||
|
||||
local int lit_base[MAX_BITLEN+1];
|
||||
/* All literals of a given bit length are contiguous in literal[] and
|
||||
* have contiguous codes. literal[code+lit_base[len]] is the literal
|
||||
* for a code of len bits.
|
||||
*/
|
||||
|
||||
local int leaves [MAX_BITLEN+1]; /* Number of leaves for each bit length */
|
||||
local int parents[MAX_BITLEN+1]; /* Number of parents for each bit length */
|
||||
|
||||
local int peek_bits; /* Number of peek bits currently used */
|
||||
|
||||
/* local uch prefix_len[1 << MAX_PEEK]; */
|
||||
#define prefix_len outbuf
|
||||
/* For each bit pattern b of peek_bits bits, prefix_len[b] is the length
|
||||
* of the Huffman code starting with a prefix of b (upper bits), or 0
|
||||
* if all codes of prefix b have more than peek_bits bits. It is not
|
||||
* necessary to have a huge table (large MAX_PEEK) because most of the
|
||||
* codes encountered in the input stream are short codes (by construction).
|
||||
* So for most codes a single lookup will be necessary.
|
||||
*/
|
||||
#if (1<<MAX_PEEK) > OUTBUFSIZ
|
||||
error cannot overlay prefix_len and outbuf
|
||||
#endif
|
||||
|
||||
local ulg bitbuf;
|
||||
/* Bits are added on the low part of bitbuf and read from the high part. */
|
||||
|
||||
local int valid; /* number of valid bits in bitbuf */
|
||||
/* all bits above the last valid bit are always zero */
|
||||
|
||||
/* Set code to the next 'bits' input bits without skipping them. code
|
||||
* must be the name of a simple variable and bits must not have side effects.
|
||||
* IN assertions: bits <= 25 (so that we still have room for an extra byte
|
||||
* when valid is only 24), and mask = (1<<bits)-1.
|
||||
*/
|
||||
#define look_bits(code,bits,mask) \
|
||||
{ \
|
||||
while (valid < (bits)) bitbuf = (bitbuf<<8) | (ulg)get_byte(), valid += 8; \
|
||||
code = (bitbuf >> (valid-(bits))) & (mask); \
|
||||
}
|
||||
|
||||
/* Skip the given number of bits (after having peeked at them): */
|
||||
#define skip_bits(bits) (valid -= (bits))
|
||||
|
||||
#define clear_bitbuf() (valid = 0, bitbuf = 0)
|
||||
|
||||
/* Local functions */
|
||||
|
||||
local void read_tree OF((void));
|
||||
local void build_tree OF((void));
|
||||
|
||||
/* ===========================================================================
|
||||
* Read the Huffman tree.
|
||||
*/
|
||||
local void read_tree()
|
||||
{
|
||||
int len; /* bit length */
|
||||
int base; /* base offset for a sequence of leaves */
|
||||
int n;
|
||||
|
||||
/* Read the original input size, MSB first */
|
||||
orig_len = 0;
|
||||
for (n = 1; n <= 4; n++) orig_len = (orig_len << 8) | (ulg)get_byte();
|
||||
|
||||
max_len = (int)get_byte(); /* maximum bit length of Huffman codes */
|
||||
if (max_len > MAX_BITLEN) {
|
||||
error("invalid compressed data -- Huffman code > 32 bits");
|
||||
}
|
||||
|
||||
/* Get the number of leaves at each bit length */
|
||||
n = 0;
|
||||
for (len = 1; len <= max_len; len++) {
|
||||
leaves[len] = (int)get_byte();
|
||||
n += leaves[len];
|
||||
}
|
||||
if (n > LITERALS) {
|
||||
error("too many leaves in Huffman tree");
|
||||
}
|
||||
Trace((stderr, "orig_len %ld, max_len %d, leaves %d\n",
|
||||
orig_len, max_len, n));
|
||||
/* There are at least 2 and at most 256 leaves of length max_len.
|
||||
* (Pack arbitrarily rejects empty files and files consisting of
|
||||
* a single byte even repeated.) To fit the last leaf count in a
|
||||
* byte, it is offset by 2. However, the last literal is the EOB
|
||||
* code, and is not transmitted explicitly in the tree, so we must
|
||||
* adjust here by one only.
|
||||
*/
|
||||
leaves[max_len]++;
|
||||
|
||||
/* Now read the leaves themselves */
|
||||
base = 0;
|
||||
for (len = 1; len <= max_len; len++) {
|
||||
/* Remember where the literals of this length start in literal[] : */
|
||||
lit_base[len] = base;
|
||||
/* And read the literals: */
|
||||
for (n = leaves[len]; n > 0; n--) {
|
||||
literal[base++] = (uch)get_byte();
|
||||
}
|
||||
}
|
||||
leaves[max_len]++; /* Now include the EOB code in the Huffman tree */
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Build the Huffman tree and the prefix table.
|
||||
*/
|
||||
local void build_tree()
|
||||
{
|
||||
int nodes = 0; /* number of nodes (parents+leaves) at current bit length */
|
||||
int len; /* current bit length */
|
||||
uch *prefixp; /* pointer in prefix_len */
|
||||
|
||||
for (len = max_len; len >= 1; len--) {
|
||||
/* The number of parent nodes at this level is half the total
|
||||
* number of nodes at parent level:
|
||||
*/
|
||||
nodes >>= 1;
|
||||
parents[len] = nodes;
|
||||
/* Update lit_base by the appropriate bias to skip the parent nodes
|
||||
* (which are not represented in the literal array):
|
||||
*/
|
||||
lit_base[len] -= nodes;
|
||||
/* Restore nodes to be parents+leaves: */
|
||||
nodes += leaves[len];
|
||||
}
|
||||
/* Construct the prefix table, from shortest leaves to longest ones.
|
||||
* The shortest code is all ones, so we start at the end of the table.
|
||||
*/
|
||||
peek_bits = MIN(max_len, MAX_PEEK);
|
||||
prefixp = &prefix_len[1<<peek_bits];
|
||||
for (len = 1; len <= peek_bits; len++) {
|
||||
int prefixes = leaves[len] << (peek_bits-len); /* may be 0 */
|
||||
while (prefixes--) *--prefixp = (uch)len;
|
||||
}
|
||||
/* The length of all other codes is unknown: */
|
||||
while (prefixp > prefix_len) *--prefixp = 0;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Unpack in to out. This routine does not support the old pack format
|
||||
* with magic header \037\037.
|
||||
*
|
||||
* IN assertions: the buffer inbuf contains already the beginning of
|
||||
* the compressed data, from offsets inptr to insize-1 included.
|
||||
* The magic header has already been checked. The output buffer is cleared.
|
||||
*/
|
||||
int unpack(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
int len; /* Bit length of current code */
|
||||
unsigned eob; /* End Of Block code */
|
||||
register unsigned peek; /* lookahead bits */
|
||||
unsigned peek_mask; /* Mask for peek_bits bits */
|
||||
|
||||
ifd = in;
|
||||
ofd = out;
|
||||
|
||||
read_tree(); /* Read the Huffman tree */
|
||||
build_tree(); /* Build the prefix table */
|
||||
clear_bitbuf(); /* Initialize bit input */
|
||||
peek_mask = (1<<peek_bits)-1;
|
||||
|
||||
/* The eob code is the largest code among all leaves of maximal length: */
|
||||
eob = leaves[max_len]-1;
|
||||
Trace((stderr, "eob %d %x\n", max_len, eob));
|
||||
|
||||
/* Decode the input data: */
|
||||
for (;;) {
|
||||
/* Since eob is the longest code and not shorter than max_len,
|
||||
* we can peek at max_len bits without having the risk of reading
|
||||
* beyond the end of file.
|
||||
*/
|
||||
look_bits(peek, peek_bits, peek_mask);
|
||||
len = prefix_len[peek];
|
||||
if (len > 0) {
|
||||
peek >>= peek_bits - len; /* discard the extra bits */
|
||||
} else {
|
||||
/* Code of more than peek_bits bits, we must traverse the tree */
|
||||
ulg mask = peek_mask;
|
||||
len = peek_bits;
|
||||
do {
|
||||
len++, mask = (mask<<1)+1;
|
||||
look_bits(peek, len, mask);
|
||||
} while (peek < (unsigned)parents[len]);
|
||||
/* loop as long as peek is a parent node */
|
||||
}
|
||||
/* At this point, peek is the next complete code, of len bits */
|
||||
if (peek == eob && len == max_len) break; /* end of file? */
|
||||
put_ubyte(literal[peek+lit_base[len]]);
|
||||
Tracev((stderr,"%02d %04x %c\n", len, peek,
|
||||
literal[peek+lit_base[len]]));
|
||||
skip_bits(len);
|
||||
} /* for (;;) */
|
||||
|
||||
flush_window();
|
||||
Trace((stderr, "bytes_out %ld\n", bytes_out));
|
||||
if (orig_len != (ulg)bytes_out) {
|
||||
error("invalid compressed data--length error");
|
||||
}
|
||||
return OK;
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
/* unzip.c -- decompress files in gzip or pkzip format.
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*
|
||||
* The code in this file is derived from the file funzip.c written
|
||||
* and put in the public domain by Mark Adler.
|
||||
*/
|
||||
|
||||
/*
|
||||
This version can extract files in gzip or pkzip format.
|
||||
For the latter, only the first entry is extracted, and it has to be
|
||||
either deflated or stored.
|
||||
*/
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: unzip.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
/* PKZIP header definitions */
|
||||
#define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */
|
||||
#define LOCFLG 6 /* offset of bit flag */
|
||||
#define CRPFLG 1 /* bit for encrypted entry */
|
||||
#define EXTFLG 8 /* bit for extended local header */
|
||||
#define LOCHOW 8 /* offset of compression method */
|
||||
#define LOCTIM 10 /* file mod time (for decryption) */
|
||||
#define LOCCRC 14 /* offset of crc */
|
||||
#define LOCSIZ 18 /* offset of compressed size */
|
||||
#define LOCLEN 22 /* offset of uncompressed length */
|
||||
#define LOCFIL 26 /* offset of file name field length */
|
||||
#define LOCEXT 28 /* offset of extra field length */
|
||||
#define LOCHDR 30 /* size of local header, including sig */
|
||||
#define EXTHDR 16 /* size of extended local header, inc sig */
|
||||
|
||||
|
||||
/* Globals */
|
||||
|
||||
int decrypt; /* flag to turn on decryption */
|
||||
char *key; /* not used--needed to link crypt.c */
|
||||
int pkzip = 0; /* set for a pkzip file */
|
||||
int ext_header = 0; /* set if extended local header */
|
||||
|
||||
/* ===========================================================================
|
||||
* Check zip file and advance inptr to the start of the compressed data.
|
||||
* Get ofname from the local header if necessary.
|
||||
*/
|
||||
int check_zipfile(in)
|
||||
int in; /* input file descriptors */
|
||||
{
|
||||
uch *h = inbuf + inptr; /* first local header */
|
||||
|
||||
ifd = in;
|
||||
|
||||
/* Check validity of local header, and skip name and extra fields */
|
||||
inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT);
|
||||
|
||||
if (inptr > insize || LG(h) != LOCSIG) {
|
||||
fprintf(stderr, "\n%s: %s: not a valid zip file\n",
|
||||
progname, ifname);
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
method = h[LOCHOW];
|
||||
if (method != STORED && method != DEFLATED) {
|
||||
fprintf(stderr,
|
||||
"\n%s: %s: first entry not deflated or stored -- use unzip\n",
|
||||
progname, ifname);
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* If entry encrypted, decrypt and validate encryption header */
|
||||
if ((decrypt = h[LOCFLG] & CRPFLG) != 0) {
|
||||
fprintf(stderr, "\n%s: %s: encrypted file -- use unzip\n",
|
||||
progname, ifname);
|
||||
exit_code = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Save flags for unzip() */
|
||||
ext_header = (h[LOCFLG] & EXTFLG) != 0;
|
||||
pkzip = 1;
|
||||
|
||||
/* Get ofname and time stamp from local header (to be done) */
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Unzip in to out. This routine works on both gzip and pkzip files.
|
||||
*
|
||||
* IN assertions: the buffer inbuf contains already the beginning of
|
||||
* the compressed data, from offsets inptr to insize-1 included.
|
||||
* The magic header has already been checked. The output buffer is cleared.
|
||||
*/
|
||||
int unzip(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
ulg orig_crc = 0; /* original crc */
|
||||
ulg orig_len = 0; /* original uncompressed length */
|
||||
int n;
|
||||
uch buf[EXTHDR]; /* extended local header */
|
||||
|
||||
ifd = in;
|
||||
ofd = out;
|
||||
|
||||
updcrc(NULL, 0); /* initialize crc */
|
||||
|
||||
if (pkzip && !ext_header) { /* crc and length at the end otherwise */
|
||||
orig_crc = LG(inbuf + LOCCRC);
|
||||
orig_len = LG(inbuf + LOCLEN);
|
||||
}
|
||||
|
||||
/* Decompress */
|
||||
if (method == DEFLATED) {
|
||||
|
||||
int res = inflate();
|
||||
|
||||
if (res == 3) {
|
||||
error("out of memory");
|
||||
} else if (res != 0) {
|
||||
error("invalid compressed data--format violated");
|
||||
}
|
||||
|
||||
} else if (pkzip && method == STORED) {
|
||||
|
||||
register ulg n = LG(inbuf + LOCLEN);
|
||||
|
||||
if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) {
|
||||
|
||||
fprintf(stderr, "len %ld, siz %ld\n", n, LG(inbuf + LOCSIZ));
|
||||
error("invalid compressed data--length mismatch");
|
||||
}
|
||||
while (n--) {
|
||||
uch c = (uch)get_byte();
|
||||
#ifdef CRYPT
|
||||
if (decrypt) zdecode(c);
|
||||
#endif
|
||||
put_ubyte(c);
|
||||
}
|
||||
flush_window();
|
||||
} else {
|
||||
error("internal error, invalid method");
|
||||
}
|
||||
|
||||
/* Get the crc and original length */
|
||||
if (!pkzip) {
|
||||
/* crc32 (see algorithm.doc)
|
||||
* uncompressed input size modulo 2^32
|
||||
*/
|
||||
for (n = 0; n < 8; n++) {
|
||||
buf[n] = (uch)get_byte(); /* may cause an error if EOF */
|
||||
}
|
||||
orig_crc = LG(buf);
|
||||
orig_len = LG(buf+4);
|
||||
|
||||
} else if (ext_header) { /* If extended header, check it */
|
||||
/* signature - 4bytes: 0x50 0x4b 0x07 0x08
|
||||
* CRC-32 value
|
||||
* compressed size 4-bytes
|
||||
* uncompressed size 4-bytes
|
||||
*/
|
||||
for (n = 0; n < EXTHDR; n++) {
|
||||
buf[n] = (uch)get_byte(); /* may cause an error if EOF */
|
||||
}
|
||||
orig_crc = LG(buf+4);
|
||||
orig_len = LG(buf+12);
|
||||
}
|
||||
|
||||
/* Validate decompression */
|
||||
if (orig_crc != updcrc(outbuf, 0)) {
|
||||
error("invalid compressed data--crc error");
|
||||
}
|
||||
if (orig_len != (ulg)bytes_out) {
|
||||
error("invalid compressed data--length error");
|
||||
}
|
||||
|
||||
/* Check if there are more entries in a pkzip file */
|
||||
if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) {
|
||||
if (to_stdout) {
|
||||
WARN((stderr,
|
||||
"%s: %s has more than one entry--rest ignored\n",
|
||||
progname, ifname));
|
||||
} else {
|
||||
/* Don't destroy the input zip file */
|
||||
fprintf(stderr,
|
||||
"%s: %s has more than one entry -- unchanged\n",
|
||||
progname, ifname);
|
||||
exit_code = ERROR;
|
||||
ext_header = pkzip = 0;
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
ext_header = pkzip = 0; /* for next file */
|
||||
return OK;
|
||||
}
|
@ -1,462 +0,0 @@
|
||||
/* util.c -- utility functions for gzip support
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: util.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tailor.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifndef NO_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(STDC_HEADERS) || !defined(NO_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
extern ulg crc_32_tab[]; /* crc table, defined below */
|
||||
|
||||
/* ===========================================================================
|
||||
* Copy input to output unchanged: zcat == cat with --force.
|
||||
* IN assertion: insize bytes have already been read in inbuf.
|
||||
*/
|
||||
int copy(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
errno = 0;
|
||||
while (insize != 0 && (int)insize != EOF) {
|
||||
write_buf(out, (char*)inbuf, insize);
|
||||
bytes_out += insize;
|
||||
insize = read(in, (char*)inbuf, INBUFSIZ);
|
||||
}
|
||||
if ((int)insize == EOF && errno != 0) {
|
||||
read_error();
|
||||
}
|
||||
bytes_in = bytes_out;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Run a set of bytes through the crc shift register. If s is a NULL
|
||||
* pointer, then initialize the crc shift register contents instead.
|
||||
* Return the current crc in either case.
|
||||
*/
|
||||
ulg updcrc(s, n)
|
||||
uch *s; /* pointer to bytes to pump through */
|
||||
unsigned n; /* number of bytes in s[] */
|
||||
{
|
||||
register ulg c; /* temporary variable */
|
||||
|
||||
static ulg crc = (ulg)0xffffffffL; /* shift register contents */
|
||||
|
||||
if (s == NULL) {
|
||||
c = 0xffffffffL;
|
||||
} else {
|
||||
c = crc;
|
||||
if (n) do {
|
||||
c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
|
||||
} while (--n);
|
||||
}
|
||||
crc = c;
|
||||
return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Clear input and output buffers
|
||||
*/
|
||||
void clear_bufs()
|
||||
{
|
||||
outcnt = 0;
|
||||
insize = inptr = 0;
|
||||
bytes_in = bytes_out = 0L;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Fill the input buffer. This is called only when the buffer is empty.
|
||||
*/
|
||||
int fill_inbuf(eof_ok)
|
||||
int eof_ok; /* set if EOF acceptable as a result */
|
||||
{
|
||||
int len;
|
||||
|
||||
/* Read as much as possible */
|
||||
insize = 0;
|
||||
errno = 0;
|
||||
do {
|
||||
len = read(ifd, (char*)inbuf+insize, INBUFSIZ-insize);
|
||||
if (len == 0 || len == EOF) break;
|
||||
insize += len;
|
||||
} while (insize < INBUFSIZ);
|
||||
|
||||
if (insize == 0) {
|
||||
if (eof_ok) return EOF;
|
||||
read_error();
|
||||
}
|
||||
bytes_in += (ulg)insize;
|
||||
inptr = 1;
|
||||
return inbuf[0];
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
|
||||
* (used for the compressed data only)
|
||||
*/
|
||||
void flush_outbuf()
|
||||
{
|
||||
if (outcnt == 0) return;
|
||||
|
||||
write_buf(ofd, (char *)outbuf, outcnt);
|
||||
bytes_out += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
|
||||
* (Used for the decompressed data only.)
|
||||
*/
|
||||
void flush_window()
|
||||
{
|
||||
if (outcnt == 0) return;
|
||||
updcrc(window, outcnt);
|
||||
|
||||
if (!test) {
|
||||
write_buf(ofd, (char *)window, outcnt);
|
||||
}
|
||||
bytes_out += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Does the same as write(), but also handles partial pipe writes and checks
|
||||
* for error return.
|
||||
*/
|
||||
void write_buf(fd, buf, cnt)
|
||||
int fd;
|
||||
voidp buf;
|
||||
unsigned cnt;
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
while ((n = write(fd, buf, cnt)) != cnt) {
|
||||
if (n == (unsigned)(-1)) {
|
||||
write_error();
|
||||
}
|
||||
cnt -= n;
|
||||
buf = (voidp)((char*)buf+n);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Put string s in lower case, return s.
|
||||
*/
|
||||
char *strlwr(s)
|
||||
char *s;
|
||||
{
|
||||
char *t;
|
||||
for (t = s; *t; t++) *t = tolow(*t);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Return the base name of a file (remove any directory prefix and
|
||||
* any version suffix). For systems with file names that are not
|
||||
* case sensitive, force the base name to lower case.
|
||||
*/
|
||||
char *our_basename(fname)
|
||||
char *fname;
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1;
|
||||
#ifdef PATH_SEP2
|
||||
if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1;
|
||||
#endif
|
||||
#ifdef PATH_SEP3
|
||||
if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1;
|
||||
#endif
|
||||
#ifdef SUFFIX_SEP
|
||||
if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0';
|
||||
#endif
|
||||
if (casemap('A') == 'a') strlwr(fname);
|
||||
return fname;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Make a file name legal for file systems not allowing file names with
|
||||
* multiple dots or starting with a dot (such as MSDOS), by changing
|
||||
* all dots except the last one into underlines. A target dependent
|
||||
* function can be used instead of this simple function by defining the macro
|
||||
* MAKE_LEGAL_NAME in tailor.h and providing the function in a target
|
||||
* dependent module.
|
||||
*/
|
||||
void make_simple_name(name)
|
||||
char *name;
|
||||
{
|
||||
char *p = strrchr(name, '.');
|
||||
if (p == NULL) return;
|
||||
if (p == name) p++;
|
||||
do {
|
||||
if (*--p == '.') *p = '_';
|
||||
} while (p != name);
|
||||
}
|
||||
|
||||
|
||||
#if defined(NO_STRING_H) && !defined(STDC_HEADERS)
|
||||
|
||||
/* Provide missing strspn and strcspn functions. */
|
||||
|
||||
# ifndef __STDC__
|
||||
# define const
|
||||
# endif
|
||||
|
||||
int strspn OF((const char *s, const char *accept));
|
||||
int strcspn OF((const char *s, const char *reject));
|
||||
|
||||
/* ========================================================================
|
||||
* Return the length of the maximum initial segment
|
||||
* of s which contains only characters in accept.
|
||||
*/
|
||||
int strspn(s, accept)
|
||||
const char *s;
|
||||
const char *accept;
|
||||
{
|
||||
register const char *p;
|
||||
register const char *a;
|
||||
register int count = 0;
|
||||
|
||||
for (p = s; *p != '\0'; ++p) {
|
||||
for (a = accept; *a != '\0'; ++a) {
|
||||
if (*p == *a) break;
|
||||
}
|
||||
if (*a == '\0') return count;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Return the length of the maximum inital segment of s
|
||||
* which contains no characters from reject.
|
||||
*/
|
||||
int strcspn(s, reject)
|
||||
const char *s;
|
||||
const char *reject;
|
||||
{
|
||||
register int count = 0;
|
||||
|
||||
while (*s != '\0') {
|
||||
if (strchr(reject, *s++) != NULL) return count;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif /* NO_STRING_H */
|
||||
|
||||
/* ========================================================================
|
||||
* Add an environment variable (if any) before argv, and update argc.
|
||||
* Return the expanded environment variable to be freed later, or NULL
|
||||
* if no options were added to argv.
|
||||
*/
|
||||
#define SEPARATOR " \t" /* separators in env variable */
|
||||
|
||||
char *add_envopt(argcp, argvp, env)
|
||||
int *argcp; /* pointer to argc */
|
||||
char ***argvp; /* pointer to argv */
|
||||
char *env; /* name of environment variable */
|
||||
{
|
||||
char *p; /* running pointer through env variable */
|
||||
char **oargv; /* runs through old argv array */
|
||||
char **nargv; /* runs through new argv array */
|
||||
int oargc = *argcp; /* old argc */
|
||||
int nargc = 0; /* number of arguments in env variable */
|
||||
|
||||
env = (char*)getenv(env);
|
||||
if (env == NULL) return NULL;
|
||||
|
||||
p = (char*)xmalloc(strlen(env)+1);
|
||||
env = strcpy(p, env); /* keep env variable intact */
|
||||
|
||||
for (p = env; *p; nargc++ ) { /* move through env */
|
||||
p += strspn(p, SEPARATOR); /* skip leading separators */
|
||||
if (*p == '\0') break;
|
||||
|
||||
p += strcspn(p, SEPARATOR); /* find end of word */
|
||||
if (*p) *p++ = '\0'; /* mark it */
|
||||
}
|
||||
if (nargc == 0) {
|
||||
free(env);
|
||||
return NULL;
|
||||
}
|
||||
*argcp += nargc;
|
||||
/* Allocate the new argv array, with an extra element just in case
|
||||
* the original arg list did not end with a NULL.
|
||||
*/
|
||||
nargv = (char**)calloc(*argcp+1, sizeof(char *));
|
||||
if (nargv == NULL) error("out of memory");
|
||||
oargv = *argvp;
|
||||
*argvp = nargv;
|
||||
|
||||
/* Copy the program name first */
|
||||
if (oargc-- < 0) error("argc<=0");
|
||||
*(nargv++) = *(oargv++);
|
||||
|
||||
/* Then copy the environment args */
|
||||
for (p = env; nargc > 0; nargc--) {
|
||||
p += strspn(p, SEPARATOR); /* skip separators */
|
||||
*(nargv++) = p; /* store start */
|
||||
while (*p++) ; /* skip over word */
|
||||
}
|
||||
|
||||
/* Finally copy the old args and add a NULL (usual convention) */
|
||||
while (oargc--) *(nargv++) = *(oargv++);
|
||||
*nargv = NULL;
|
||||
return env;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Error handlers.
|
||||
*/
|
||||
void error(m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "\n%s: %s: %s\n", progname, ifname, m);
|
||||
abort_gzip();
|
||||
}
|
||||
|
||||
void warn(a, b)
|
||||
char *a, *b; /* message strings juxtaposed in output */
|
||||
{
|
||||
WARN((stderr, "%s: %s: warning: %s%s\n", progname, ifname, a, b));
|
||||
}
|
||||
|
||||
void read_error()
|
||||
{
|
||||
fprintf(stderr, "\n%s: ", progname);
|
||||
if (errno != 0) {
|
||||
perror(ifname);
|
||||
} else {
|
||||
fprintf(stderr, "%s: unexpected end of file\n", ifname);
|
||||
}
|
||||
abort_gzip();
|
||||
}
|
||||
|
||||
void write_error()
|
||||
{
|
||||
fprintf(stderr, "\n%s: ", progname);
|
||||
perror(ofname);
|
||||
abort_gzip();
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Display compression ratio on the given stream on 6 characters.
|
||||
*/
|
||||
void display_ratio(num, den, file)
|
||||
long num;
|
||||
long den;
|
||||
FILE *file;
|
||||
{
|
||||
long ratio; /* 1000 times the compression ratio */
|
||||
|
||||
if (den == 0) {
|
||||
ratio = 0; /* no compression */
|
||||
} else if (den < 2147483L) { /* (2**31 -1)/1000 */
|
||||
ratio = 1000L*num/den;
|
||||
} else {
|
||||
ratio = num/(den/1000L);
|
||||
}
|
||||
if (ratio < 0) {
|
||||
putc('-', file);
|
||||
ratio = -ratio;
|
||||
} else {
|
||||
putc(' ', file);
|
||||
}
|
||||
fprintf(file, "%2ld.%1ld%%", ratio / 10L, ratio % 10L);
|
||||
}
|
||||
|
||||
|
||||
/* ========================================================================
|
||||
* Semi-safe malloc -- never returns NULL.
|
||||
*/
|
||||
voidp xmalloc (size)
|
||||
unsigned size;
|
||||
{
|
||||
voidp cp = (voidp)malloc (size);
|
||||
|
||||
if (cp == NULL) error("out of memory");
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Table of CRC-32's of all single-byte values (made by makecrc.c)
|
||||
*/
|
||||
ulg crc_32_tab[] = {
|
||||
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
|
||||
};
|
@ -1,69 +0,0 @@
|
||||
#!/bin/sh
|
||||
# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh
|
||||
|
||||
# Zcmp and zdiff are used to invoke the cmp or the diff pro-
|
||||
# gram on compressed files. All options specified are passed
|
||||
# directly to cmp or diff. If only 1 file is specified, then
|
||||
# the files compared are file1 and an uncompressed file1.gz.
|
||||
# If two files are specified, then they are uncompressed (if
|
||||
# necessary) and fed to cmp or diff. The exit status from cmp
|
||||
# or diff is preserved.
|
||||
|
||||
PATH="/bin:$PATH"; export PATH
|
||||
prog=`echo $0 | sed 's|.*/||'`
|
||||
case "$prog" in
|
||||
*cmp) comp=${CMP-cmp} ;;
|
||||
*) comp=${DIFF-diff} ;;
|
||||
esac
|
||||
|
||||
OPTIONS=
|
||||
FILES=
|
||||
for ARG
|
||||
do
|
||||
case "$ARG" in
|
||||
-*) OPTIONS="$OPTIONS $ARG";;
|
||||
*) if test -f "$ARG"; then
|
||||
FILES="$FILES $ARG"
|
||||
else
|
||||
echo "${prog}: $ARG not found or not a regular file"
|
||||
exit 1
|
||||
fi ;;
|
||||
esac
|
||||
done
|
||||
if test -z "$FILES"; then
|
||||
echo "Usage: $prog [${comp}_options] file [file]"
|
||||
exit 1
|
||||
fi
|
||||
set $FILES
|
||||
if test $# -eq 1; then
|
||||
FILE=`echo "$1" | sed 's/[-.][zZtga]*$//'`
|
||||
gzip -cd "$1" | $comp $OPTIONS - "$FILE"
|
||||
STAT="$?"
|
||||
|
||||
elif test $# -eq 2; then
|
||||
case "$1" in
|
||||
*[-.]gz* | *[-.][zZ] | *.t[ga]z)
|
||||
case "$2" in
|
||||
*[-.]gz* | *[-.][zZ] | *.t[ga]z)
|
||||
F=`echo "$2" | sed 's|.*/||;s|[-.][zZtga]*||'`
|
||||
gzip -cdfq "$2" > /tmp/"$F".$$
|
||||
gzip -cdfq "$1" | $comp $OPTIONS - /tmp/"$F".$$
|
||||
STAT="$?"
|
||||
/bin/rm -f /tmp/"$F".$$;;
|
||||
|
||||
*) gzip -cdfq "$1" | $comp $OPTIONS - "$2"
|
||||
STAT="$?";;
|
||||
esac;;
|
||||
*) case "$2" in
|
||||
*[-.]gz* | *[-.][zZ] | *.t[ga]z)
|
||||
gzip -cdfq "$2" | $comp $OPTIONS "$1" -
|
||||
STAT="$?";;
|
||||
*) $comp $OPTIONS "$1" "$2"
|
||||
STAT="$?";;
|
||||
esac;;
|
||||
esac
|
||||
exit "$STAT"
|
||||
else
|
||||
echo "Usage: $prog [${comp}_options] file [file]"
|
||||
exit 1
|
||||
fi
|
@ -1,28 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test $# = 0; then
|
||||
echo 'zfile: file(1) for programs which may be compressed with gzexe'
|
||||
echo usage: `basename $0` files...
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp=/tmp/gz$$
|
||||
|
||||
for i do
|
||||
if test ! -f "$i" ; then
|
||||
echo `basename $0`: $i not a file
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
skip=18
|
||||
if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
|
||||
eval `sed -e 1d -e 2q "$i"`
|
||||
fi
|
||||
if tail +$skip "$i" | gzip --list >/dev/null 2>&1; then
|
||||
tail +$skip "$i" | gzip -cd | dd count=1 >$tmp 2>/dev/null
|
||||
file $tmp | sed "s|^$tmp|$i|"
|
||||
else
|
||||
file "$i"
|
||||
fi
|
||||
rm -f $tmp
|
||||
done
|
@ -1,41 +0,0 @@
|
||||
#!/bin/sh
|
||||
# zforce: force a gz extension on all gzip files so that gzip will not
|
||||
# compress them twice.
|
||||
#
|
||||
# This can be useful for files with names truncated after a file transfer.
|
||||
# 12345678901234 is renamed to 12345678901.gz
|
||||
|
||||
PATH="/bin:$PATH"; export PATH
|
||||
x=`basename $0`
|
||||
if test $# = 0; then
|
||||
echo "force a '.gz' extension on all gzip files"
|
||||
echo usage: $x files...
|
||||
exit 1
|
||||
fi
|
||||
|
||||
res=0
|
||||
for i do
|
||||
if test ! -f "$i" ; then
|
||||
echo ${x}: $i not a file
|
||||
res=1
|
||||
continue
|
||||
fi
|
||||
test `expr "$i" : '.*[.-]z$'` -eq 0 || continue
|
||||
test `expr "$i" : '.*[.-]gz$'` -eq 0 || continue
|
||||
test `expr "$i" : '.*[.]t[ag]z$'` -eq 0 || continue
|
||||
|
||||
if gzip -l < "$i" 2>/dev/null | grep '^defl' > /dev/null; then
|
||||
|
||||
if test `expr "$i" : '^............'` -eq 12; then
|
||||
new=`expr "$i" : '\(.*\)...$`.gz
|
||||
else
|
||||
new="$i.gz"
|
||||
fi
|
||||
if mv "$i" "$new" 2>/dev/null; then
|
||||
echo $i -- replaced with $new
|
||||
continue
|
||||
fi
|
||||
res=1; echo ${x}: cannot rename $i to $new
|
||||
fi
|
||||
done
|
||||
exit $res
|
@ -1,66 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# zgrep -- a wrapper around a grep program that decompresses files as needed
|
||||
# Adapted from a version sent by Charles Levert <charles@comm.polymtl.ca>
|
||||
|
||||
PATH="/bin:$PATH"; export PATH
|
||||
|
||||
prog=`echo $0 | sed 's|.*/||'`
|
||||
case "$prog" in
|
||||
*egrep) grep=${EGREP-egrep} ;;
|
||||
*fgrep) grep=${FGREP-fgrep} ;;
|
||||
*) grep=${GREP-grep} ;;
|
||||
esac
|
||||
pat=""
|
||||
while test $# -ne 0; do
|
||||
case "$1" in
|
||||
-e | -f) opt="$opt $1"; shift; pat="$1"
|
||||
if test "$grep" = grep; then # grep is buggy with -e on SVR4
|
||||
grep=egrep
|
||||
fi;;
|
||||
-*) opt="$opt $1";;
|
||||
*) if test -z "$pat"; then
|
||||
pat="$1"
|
||||
else
|
||||
break;
|
||||
fi;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$pat"; then
|
||||
echo "grep through gzip files"
|
||||
echo "usage: $prog [grep_options] pattern [files]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
list=0
|
||||
silent=0
|
||||
op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
|
||||
case "$op" in
|
||||
*l*) list=1
|
||||
esac
|
||||
case "$op" in
|
||||
*h*) silent=1
|
||||
esac
|
||||
|
||||
if test $# -eq 0; then
|
||||
gzip -cdfq | $grep $opt "$pat"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
res=0
|
||||
for i do
|
||||
if test $list -eq 1; then
|
||||
gzip -cdfq "$i" | $grep $opt "$pat" > /dev/null && echo $i
|
||||
r=$?
|
||||
elif test $# -eq 1 -o $silent -eq 1; then
|
||||
gzip -cdfq "$i" | $grep $opt "$pat"
|
||||
r=$?
|
||||
else
|
||||
gzip -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${i}:|"
|
||||
r=$?
|
||||
fi
|
||||
test "$r" -ne 0 && res="$r"
|
||||
done
|
||||
exit $res
|
@ -1,117 +0,0 @@
|
||||
/* zip.c -- compress files to the gzip or pkzip format
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License, see the file COPYING.
|
||||
*/
|
||||
|
||||
#ifdef RCSID
|
||||
static char rcsid[] = "$Id: zip.c 3476 2003-06-11 15:56:10Z darkwyrm $";
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tailor.h"
|
||||
#include "gzip.h"
|
||||
#include "crypt.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifndef NO_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
local ulg crc; /* crc on uncompressed file data */
|
||||
long header_bytes; /* number of bytes in gzip header */
|
||||
|
||||
/* ===========================================================================
|
||||
* Deflate in to out.
|
||||
* IN assertions: the input and output buffers are cleared.
|
||||
* The variables time_stamp and save_orig_name are initialized.
|
||||
*/
|
||||
int zip(in, out)
|
||||
int in, out; /* input and output file descriptors */
|
||||
{
|
||||
uch flags = 0; /* general purpose bit flags */
|
||||
ush attr = 0; /* ascii/binary flag */
|
||||
ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */
|
||||
|
||||
ifd = in;
|
||||
ofd = out;
|
||||
outcnt = 0;
|
||||
|
||||
/* Write the header to the gzip file. See algorithm.doc for the format */
|
||||
|
||||
method = DEFLATED;
|
||||
put_byte(GZIP_MAGIC[0]); /* magic header */
|
||||
put_byte(GZIP_MAGIC[1]);
|
||||
put_byte(DEFLATED); /* compression method */
|
||||
|
||||
if (save_orig_name) {
|
||||
flags |= ORIG_NAME;
|
||||
}
|
||||
put_byte(flags); /* general flags */
|
||||
put_long(time_stamp);
|
||||
|
||||
/* Write deflated file to zip file */
|
||||
crc = updcrc(0, 0);
|
||||
|
||||
bi_init(out);
|
||||
ct_init(&attr, &method);
|
||||
lm_init(level, &deflate_flags);
|
||||
|
||||
put_byte((uch)deflate_flags); /* extra flags */
|
||||
put_byte(OS_CODE); /* OS identifier */
|
||||
|
||||
if (save_orig_name) {
|
||||
char *p = our_basename(ifname); /* Don't save the directory part. */
|
||||
do {
|
||||
put_char(*p);
|
||||
} while (*p++);
|
||||
}
|
||||
header_bytes = (long)outcnt;
|
||||
|
||||
(void)deflate();
|
||||
|
||||
#if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO)
|
||||
/* Check input size (but not in VMS -- variable record lengths mess it up)
|
||||
* and not on MSDOS -- diet in TSR mode reports an incorrect file size)
|
||||
*/
|
||||
if (ifile_size != -1L && isize != (ulg)ifile_size) {
|
||||
Trace((stderr, " actual=%ld, read=%ld ", ifile_size, isize));
|
||||
fprintf(stderr, "%s: %s: file size changed while zipping\n",
|
||||
progname, ifname);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the crc and uncompressed size */
|
||||
put_long(crc);
|
||||
put_long(isize);
|
||||
header_bytes += 2*sizeof(long);
|
||||
|
||||
flush_outbuf();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Read a new buffer from the current input file, perform end-of-line
|
||||
* translation, and update the crc and input file size.
|
||||
* IN assertion: size >= 2 (for end-of-line translation)
|
||||
*/
|
||||
int file_read(buf, size)
|
||||
char *buf;
|
||||
unsigned size;
|
||||
{
|
||||
unsigned len;
|
||||
|
||||
Assert(insize == 0, "inbuf not empty");
|
||||
|
||||
len = read(ifd, buf, size);
|
||||
if (len == (unsigned)(-1) || len == 0) return (int)len;
|
||||
|
||||
crc = updcrc((uch*)buf, len);
|
||||
isize += (ulg)len;
|
||||
return (int)len;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/bin:$PATH"; export PATH
|
||||
if test "`echo -n a`" = "-n a"; then
|
||||
# looks like a SysV system:
|
||||
n1=''; n2='\c'
|
||||
else
|
||||
n1='-n'; n2=''
|
||||
fi
|
||||
oldtty=`stty -g 2>/dev/null`
|
||||
if stty -cbreak 2>/dev/null; then
|
||||
cb='cbreak'; ncb='-cbreak'
|
||||
else
|
||||
# 'stty min 1' resets eof to ^a on both SunOS and SysV!
|
||||
cb='min 1 -icanon'; ncb='icanon eof ^d'
|
||||
fi
|
||||
if test $? -eq 0 -a -n "$oldtty"; then
|
||||
trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
|
||||
else
|
||||
trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
|
||||
fi
|
||||
|
||||
if test $# = 0; then
|
||||
if test -t 0; then
|
||||
echo usage: zmore files...
|
||||
else
|
||||
gzip -cdfq | eval ${PAGER-less}
|
||||
fi
|
||||
else
|
||||
FIRST=1
|
||||
for FILE
|
||||
do
|
||||
if test $FIRST -eq 0; then
|
||||
echo $n1 "--More--(Next file: $FILE)$n2"
|
||||
stty $cb -echo 2>/dev/null
|
||||
ANS=`dd bs=1 count=1 2>/dev/null`
|
||||
stty $ncb echo 2>/dev/null
|
||||
echo " "
|
||||
if test "$ANS" = 'e' -o "$ANS" = 'q'; then
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
if test "$ANS" != 's'; then
|
||||
echo "------> $FILE <------"
|
||||
gzip -cdfq "$FILE" | eval ${PAGER-less}
|
||||
fi
|
||||
if test -t; then
|
||||
FIRST=0
|
||||
fi
|
||||
done
|
||||
fi
|
@ -1,145 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/bin:$PATH"; export PATH
|
||||
check=0
|
||||
pipe=0
|
||||
opt=
|
||||
files=
|
||||
keep=0
|
||||
res=0
|
||||
old=0
|
||||
new=0
|
||||
block=1024
|
||||
# block is the disk block size (best guess, need not be exact)
|
||||
|
||||
warn="(does not preserve modes and timestamp)"
|
||||
tmp=/tmp/zfoo.$$
|
||||
echo hi > $tmp.1
|
||||
echo hi > $tmp.2
|
||||
if test -z "`(${CPMOD-cpmod} $tmp.1 $tmp.2) 2>&1`"; then
|
||||
cpmod=${CPMOD-cpmod}
|
||||
warn=""
|
||||
fi
|
||||
|
||||
if test -z "$cpmod" && ${TOUCH-touch} -r $tmp.1 $tmp.2 2>/dev/null; then
|
||||
cpmod="${TOUCH-touch}"
|
||||
cpmodarg="-r"
|
||||
warn="(does not preserve file modes)"
|
||||
fi
|
||||
|
||||
# check if GZIP env. variable uses -S or --suffix
|
||||
gzip -q $tmp.1
|
||||
ext=`echo $tmp.1* | sed "s|$tmp.1||"`
|
||||
rm -f $tmp.[12]*
|
||||
if test -z "$ext"; then
|
||||
echo znew: error determining gzip extension
|
||||
exit 1
|
||||
fi
|
||||
if test "$ext" = ".Z"; then
|
||||
echo znew: cannot use .Z as gzip extension.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-*) opt="$opt $arg"; shift;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo "recompress .Z files into $ext (gzip) files"
|
||||
echo usage: `echo $0 | sed 's,^.*/,,'` "[-tv9KP]" file.Z...
|
||||
echo " -t tests the new files before deleting originals"
|
||||
echo " -v be verbose"
|
||||
echo " -9 use the slowest compression method (optimal compression)"
|
||||
echo " -K keep a .Z file when it is smaller than the $ext file"
|
||||
echo " -P use pipes for the conversion $warn"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
opt=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
|
||||
case "$opt" in
|
||||
*t*) check=1; opt=`echo "$opt" | sed 's/t//g'`
|
||||
esac
|
||||
case "$opt" in
|
||||
*K*) keep=1; opt=`echo "$opt" | sed 's/K//g'`
|
||||
esac
|
||||
case "$opt" in
|
||||
*P*) pipe=1; opt=`echo "$opt" | sed 's/P//g'`
|
||||
esac
|
||||
if test -n "$opt"; then
|
||||
opt="-$opt"
|
||||
fi
|
||||
|
||||
for i do
|
||||
n=`echo $i | sed 's/.Z$//'`
|
||||
if test ! -f "$n.Z" ; then
|
||||
echo $n.Z not found
|
||||
res=1; continue
|
||||
fi
|
||||
test $keep -eq 1 && old=`wc -c < "$n.Z"`
|
||||
if test $pipe -eq 1; then
|
||||
if gzip -d < "$n.Z" | gzip $opt > "$n$ext"; then
|
||||
# Copy file attributes from old file to new one, if possible.
|
||||
test -n "$cpmod" && $cpmod $cpmodarg "$n.Z" "$n$ext" 2> /dev/null
|
||||
else
|
||||
echo error while recompressing $n.Z
|
||||
res=1; continue
|
||||
fi
|
||||
else
|
||||
if test $check -eq 1; then
|
||||
if cp -p "$n.Z" "$n.$$" 2> /dev/null || cp "$n.Z" "$n.$$"; then
|
||||
:
|
||||
else
|
||||
echo cannot backup "$n.Z"
|
||||
res=1; continue
|
||||
fi
|
||||
fi
|
||||
if gzip -d "$n.Z"; then
|
||||
:
|
||||
else
|
||||
test $check -eq 1 && mv "$n.$$" "$n.Z"
|
||||
echo error while uncompressing $n.Z
|
||||
res=1; continue
|
||||
fi
|
||||
if gzip $opt "$n"; then
|
||||
:
|
||||
else
|
||||
if test $check -eq 1; then
|
||||
mv "$n.$$" "$n.Z" && rm -f "$n"
|
||||
echo error while recompressing $n
|
||||
else
|
||||
# compress $n (might be dangerous if disk full)
|
||||
echo error while recompressing $n, left uncompressed
|
||||
fi
|
||||
res=1; continue
|
||||
fi
|
||||
fi
|
||||
test $keep -eq 1 && new=`wc -c < "$n$ext"`
|
||||
if test $keep -eq 1 -a `expr \( $old + $block - 1 \) / $block` -lt \
|
||||
`expr \( $new + $block - 1 \) / $block`; then
|
||||
if test $pipe -eq 1; then
|
||||
rm -f "$n$ext"
|
||||
elif test $check -eq 1; then
|
||||
mv "$n.$$" "$n.Z" && rm -f "$n$ext"
|
||||
else
|
||||
gzip -d "$n$ext" && compress "$n" && rm -f "$n$ext"
|
||||
fi
|
||||
echo "$n.Z smaller than $n$ext -- unchanged"
|
||||
|
||||
elif test $check -eq 1; then
|
||||
if gzip -t "$n$ext" ; then
|
||||
rm -f "$n.$$" "$n.Z"
|
||||
else
|
||||
test $pipe -eq 0 && mv "$n.$$" "$n.Z"
|
||||
rm -f "$n$ext"
|
||||
echo error while testing $n$ext, $n.Z unchanged
|
||||
res=1; continue
|
||||
fi
|
||||
elif test $pipe -eq 1; then
|
||||
rm -f "$n.Z"
|
||||
fi
|
||||
done
|
||||
exit $res
|
@ -31,9 +31,6 @@ provides {
|
||||
cmd:diff3
|
||||
cmd:ftp
|
||||
cmd:ftpd
|
||||
cmd:gunzip
|
||||
cmd:gzexe
|
||||
cmd:gzip
|
||||
cmd:hd
|
||||
cmd:hey
|
||||
cmd:login
|
||||
@ -58,13 +55,6 @@ provides {
|
||||
cmd:useradd
|
||||
cmd:watch
|
||||
cmd:xres
|
||||
cmd:zcat
|
||||
cmd:zcmp
|
||||
cmd:zdiff
|
||||
cmd:zforce
|
||||
cmd:zgrep
|
||||
cmd:zmore
|
||||
cmd:znew
|
||||
}
|
||||
|
||||
requires {
|
||||
@ -72,6 +62,7 @@ requires {
|
||||
cmd:sh
|
||||
#ifdef HAIKU_REGULAR_BUILD
|
||||
cmd:bunzip2
|
||||
cmd:gunzip
|
||||
cmd:tar
|
||||
cmd:unzip
|
||||
#endif
|
||||
|
@ -31,9 +31,6 @@ provides {
|
||||
cmd:diff3
|
||||
cmd:ftp
|
||||
cmd:ftpd
|
||||
cmd:gunzip
|
||||
cmd:gzexe
|
||||
cmd:gzip
|
||||
cmd:hd
|
||||
cmd:hey
|
||||
cmd:login
|
||||
@ -58,13 +55,6 @@ provides {
|
||||
cmd:useradd
|
||||
cmd:watch
|
||||
cmd:xres
|
||||
cmd:zcat
|
||||
cmd:zcmp
|
||||
cmd:zdiff
|
||||
cmd:zforce
|
||||
cmd:zgrep
|
||||
cmd:zmore
|
||||
cmd:znew
|
||||
}
|
||||
|
||||
requires {
|
||||
@ -72,6 +62,7 @@ requires {
|
||||
cmd:sh
|
||||
#ifdef HAIKU_REGULAR_BUILD
|
||||
cmd:bunzip2
|
||||
cmd:gunzip
|
||||
cmd:tar
|
||||
cmd:unzip
|
||||
#endif
|
||||
|
@ -31,9 +31,6 @@ provides {
|
||||
cmd:diff3
|
||||
cmd:ftp
|
||||
cmd:ftpd
|
||||
cmd:gunzip
|
||||
cmd:gzexe
|
||||
cmd:gzip
|
||||
cmd:hd
|
||||
cmd:hey
|
||||
cmd:login
|
||||
@ -58,13 +55,6 @@ provides {
|
||||
cmd:useradd
|
||||
cmd:watch
|
||||
cmd:xres
|
||||
cmd:zcat
|
||||
cmd:zcmp
|
||||
cmd:zdiff
|
||||
cmd:zforce
|
||||
cmd:zgrep
|
||||
cmd:zmore
|
||||
cmd:znew
|
||||
}
|
||||
|
||||
requires {
|
||||
@ -72,6 +62,7 @@ requires {
|
||||
cmd:sh
|
||||
#ifdef HAIKU_REGULAR_BUILD
|
||||
cmd:bunzip2
|
||||
cmd:gunzip
|
||||
cmd:tar
|
||||
cmd:unzip
|
||||
#endif
|
||||
|
@ -31,9 +31,6 @@ provides {
|
||||
cmd:diff3
|
||||
cmd:ftp
|
||||
cmd:ftpd
|
||||
cmd:gunzip
|
||||
cmd:gzexe
|
||||
cmd:gzip
|
||||
cmd:hd
|
||||
cmd:hey
|
||||
cmd:login
|
||||
@ -58,13 +55,6 @@ provides {
|
||||
cmd:useradd
|
||||
cmd:watch
|
||||
cmd:xres
|
||||
cmd:zcat
|
||||
cmd:zcmp
|
||||
cmd:zdiff
|
||||
cmd:zforce
|
||||
cmd:zgrep
|
||||
cmd:zmore
|
||||
cmd:znew
|
||||
}
|
||||
|
||||
requires {
|
||||
@ -72,6 +62,7 @@ requires {
|
||||
cmd:sh
|
||||
#ifdef HAIKU_REGULAR_BUILD
|
||||
cmd:bunzip2
|
||||
cmd:gunzip
|
||||
cmd:tar
|
||||
cmd:unzip
|
||||
#endif
|
||||
|
@ -30,9 +30,6 @@ provides {
|
||||
cmd:diff3
|
||||
cmd:ftp
|
||||
cmd:ftpd
|
||||
cmd:gunzip
|
||||
cmd:gzexe
|
||||
cmd:gzip
|
||||
cmd:hd
|
||||
cmd:hey
|
||||
cmd:login
|
||||
@ -57,13 +54,6 @@ provides {
|
||||
cmd:useradd
|
||||
cmd:watch
|
||||
cmd:xres
|
||||
cmd:zcat
|
||||
cmd:zcmp
|
||||
cmd:zdiff
|
||||
cmd:zforce
|
||||
cmd:zgrep
|
||||
cmd:zmore
|
||||
cmd:znew
|
||||
}
|
||||
|
||||
requires {
|
||||
@ -71,6 +61,7 @@ requires {
|
||||
cmd:sh
|
||||
#ifdef HAIKU_REGULAR_BUILD
|
||||
cmd:bunzip2
|
||||
cmd:gunzip
|
||||
cmd:tar
|
||||
cmd:unzip
|
||||
#endif
|
||||
|
@ -31,9 +31,6 @@ provides {
|
||||
cmd:diff3
|
||||
cmd:ftp
|
||||
cmd:ftpd
|
||||
cmd:gunzip
|
||||
cmd:gzexe
|
||||
cmd:gzip
|
||||
cmd:hd
|
||||
cmd:hey
|
||||
cmd:login
|
||||
@ -58,13 +55,6 @@ provides {
|
||||
cmd:useradd
|
||||
cmd:watch
|
||||
cmd:xres
|
||||
cmd:zcat
|
||||
cmd:zcmp
|
||||
cmd:zdiff
|
||||
cmd:zforce
|
||||
cmd:zgrep
|
||||
cmd:zmore
|
||||
cmd:znew
|
||||
lib:libstdc++
|
||||
}
|
||||
|
||||
@ -73,6 +63,7 @@ requires {
|
||||
cmd:sh
|
||||
#ifdef HAIKU_REGULAR_BUILD
|
||||
cmd:bunzip2
|
||||
cmd:gunzip
|
||||
cmd:tar
|
||||
cmd:unzip
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user