gzip cleanup part #8
This commit is contained in:
parent
ef87d46b8c
commit
52933d47bd
346
archival/gzip.c
346
archival/gzip.c
@ -311,11 +311,6 @@ static void check_match(IPos start, IPos match, int length);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* from zip.c: */
|
||||
static int zip(int in, int out);
|
||||
static unsigned file_read(void *buf, unsigned size);
|
||||
|
||||
/* from deflate.c */
|
||||
static void lm_init(ush * flags);
|
||||
static ulg deflate(void);
|
||||
@ -605,22 +600,8 @@ static void copy_block(char *buf, unsigned len, int header)
|
||||
* 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)
|
||||
#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
|
||||
@ -834,9 +815,17 @@ static void fill_window(void)
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Flush the current block, with given end-of-file flag.
|
||||
* IN assertion: strstart is set to the end of the current match.
|
||||
* 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.
|
||||
*
|
||||
* Processes a new input file and return its compressed length. Sets
|
||||
* the compressed length, crc, deflate flags and internal file
|
||||
* attributes.
|
||||
*/
|
||||
|
||||
/* 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 \
|
||||
@ -846,16 +835,19 @@ static void fill_window(void)
|
||||
(eof) \
|
||||
)
|
||||
|
||||
/* 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); \
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* 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.
|
||||
*
|
||||
* Processes a new input file and return its compressed length. Sets
|
||||
* the compressed length, crc, deflate flags and internal file
|
||||
* attributes.
|
||||
*/
|
||||
static ulg deflate(void)
|
||||
{
|
||||
IPos hash_head; /* head of hash chain */
|
||||
@ -959,152 +951,6 @@ static ulg deflate(void)
|
||||
|
||||
return FLUSH_BLOCK(1); /* eof */
|
||||
}
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
static void abort_gzip(int ATTRIBUTE_UNUSED ignored)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int gzip_main(int argc, char **argv)
|
||||
{
|
||||
enum {
|
||||
OPT_tostdout = 0x1,
|
||||
OPT_force = 0x2,
|
||||
};
|
||||
|
||||
unsigned opt;
|
||||
int result;
|
||||
int inFileNum;
|
||||
int outFileNum;
|
||||
struct stat statBuf;
|
||||
char *delFileName;
|
||||
|
||||
opt = getopt32(argc, argv, "cf123456789qv" USE_GUNZIP("d"));
|
||||
//if (opt & 0x1) // -c
|
||||
//if (opt & 0x2) // -f
|
||||
/* Ignore 1-9 (compression level) options */
|
||||
//if (opt & 0x4) // -1
|
||||
//if (opt & 0x8) // -2
|
||||
//if (opt & 0x10) // -3
|
||||
//if (opt & 0x20) // -4
|
||||
//if (opt & 0x40) // -5
|
||||
//if (opt & 0x80) // -6
|
||||
//if (opt & 0x100) // -7
|
||||
//if (opt & 0x200) // -8
|
||||
//if (opt & 0x400) // -9
|
||||
//if (opt & 0x800) // -q
|
||||
//if (opt & 0x1000) // -v
|
||||
#if ENABLE_GUNZIP /* gunzip_main may not be visible... */
|
||||
if (opt & 0x2000) { // -d
|
||||
/* FIXME: getopt32 should not depend on optind */
|
||||
optind = 1;
|
||||
return gunzip_main(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
|
||||
if (foreground) {
|
||||
(void) signal(SIGINT, abort_gzip);
|
||||
}
|
||||
#ifdef SIGTERM
|
||||
if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
|
||||
(void) signal(SIGTERM, abort_gzip);
|
||||
}
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
|
||||
(void) signal(SIGHUP, abort_gzip);
|
||||
}
|
||||
#endif
|
||||
|
||||
strncpy(z_suffix, ".gz", sizeof(z_suffix) - 1);
|
||||
|
||||
/* Allocate all global buffers (for DYN_ALLOC option) */
|
||||
ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
|
||||
ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
|
||||
ALLOC(ush, d_buf, DIST_BUFSIZE);
|
||||
ALLOC(uch, window, 2L * WSIZE);
|
||||
ALLOC(ush, tab_prefix, 1L << BITS);
|
||||
|
||||
/* Initialise the CRC32 table */
|
||||
crc_32_tab = crc32_filltable(0);
|
||||
|
||||
clear_bufs();
|
||||
|
||||
if (optind == argc) {
|
||||
time_stamp = 0;
|
||||
zip(STDIN_FILENO, STDOUT_FILENO);
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = optind; i < argc; i++) {
|
||||
char *path = NULL;
|
||||
|
||||
clear_bufs();
|
||||
if (LONE_DASH(argv[i])) {
|
||||
time_stamp = 0;
|
||||
inFileNum = STDIN_FILENO;
|
||||
outFileNum = STDOUT_FILENO;
|
||||
} else {
|
||||
inFileNum = xopen(argv[i], O_RDONLY);
|
||||
if (fstat(inFileNum, &statBuf) < 0)
|
||||
bb_perror_msg_and_die("%s", argv[i]);
|
||||
time_stamp = statBuf.st_ctime;
|
||||
|
||||
if (!(opt & OPT_tostdout)) {
|
||||
path = xasprintf("%s.gz", argv[i]);
|
||||
|
||||
/* Open output file */
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 && defined(O_NOFOLLOW)
|
||||
outFileNum =
|
||||
open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW);
|
||||
#else
|
||||
outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL);
|
||||
#endif
|
||||
if (outFileNum < 0) {
|
||||
bb_perror_msg("%s", path);
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set permissions on the file */
|
||||
fchmod(outFileNum, statBuf.st_mode);
|
||||
} else
|
||||
outFileNum = STDOUT_FILENO;
|
||||
}
|
||||
|
||||
if (path == NULL && isatty(outFileNum) && !(opt & OPT_force)) {
|
||||
bb_error_msg
|
||||
("compressed data not written to a terminal. Use -f to force compression.");
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
result = zip(inFileNum, outFileNum);
|
||||
|
||||
if (path != NULL) {
|
||||
close(inFileNum);
|
||||
close(outFileNum);
|
||||
|
||||
/* Delete the original file */
|
||||
if (result == 0)
|
||||
delFileName = argv[i];
|
||||
else
|
||||
delFileName = path;
|
||||
|
||||
if (unlink(delFileName) < 0)
|
||||
bb_perror_msg("%s", delFileName);
|
||||
}
|
||||
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
/* trees.c -- output deflated data using Huffman coding
|
||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||
* This is free software; you can redistribute it and/or modify it under the
|
||||
@ -2109,7 +1955,7 @@ static ulg flush_block(char *buf, ulg stored_len, int eof)
|
||||
*/
|
||||
static int ct_tally(int dist, int lc)
|
||||
{
|
||||
l_buf[last_lit++] = (uch) lc;
|
||||
l_buf[last_lit++] = lc;
|
||||
if (dist == 0) {
|
||||
/* lc is the unmatched char */
|
||||
dyn_ltree[lc].Freq++;
|
||||
@ -2278,3 +2124,147 @@ static int zip(int in, int out)
|
||||
flush_outbuf();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
static void abort_gzip(int ATTRIBUTE_UNUSED ignored)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int gzip_main(int argc, char **argv)
|
||||
{
|
||||
enum {
|
||||
OPT_tostdout = 0x1,
|
||||
OPT_force = 0x2,
|
||||
};
|
||||
|
||||
unsigned opt;
|
||||
int result;
|
||||
int inFileNum;
|
||||
int outFileNum;
|
||||
int i;
|
||||
struct stat statBuf;
|
||||
char *delFileName;
|
||||
|
||||
opt = getopt32(argc, argv, "cf123456789qv" USE_GUNZIP("d"));
|
||||
//if (opt & 0x1) // -c
|
||||
//if (opt & 0x2) // -f
|
||||
/* Ignore 1-9 (compression level) options */
|
||||
//if (opt & 0x4) // -1
|
||||
//if (opt & 0x8) // -2
|
||||
//if (opt & 0x10) // -3
|
||||
//if (opt & 0x20) // -4
|
||||
//if (opt & 0x40) // -5
|
||||
//if (opt & 0x80) // -6
|
||||
//if (opt & 0x100) // -7
|
||||
//if (opt & 0x200) // -8
|
||||
//if (opt & 0x400) // -9
|
||||
//if (opt & 0x800) // -q
|
||||
//if (opt & 0x1000) // -v
|
||||
#if ENABLE_GUNZIP /* gunzip_main may not be visible... */
|
||||
if (opt & 0x2000) { // -d
|
||||
/* FIXME: getopt32 should not depend on optind */
|
||||
optind = 1;
|
||||
return gunzip_main(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
|
||||
if (foreground) {
|
||||
signal(SIGINT, abort_gzip);
|
||||
}
|
||||
#ifdef SIGTERM
|
||||
if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
|
||||
signal(SIGTERM, abort_gzip);
|
||||
}
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
|
||||
signal(SIGHUP, abort_gzip);
|
||||
}
|
||||
#endif
|
||||
|
||||
strncpy(z_suffix, ".gz", sizeof(z_suffix) - 1);
|
||||
|
||||
/* Allocate all global buffers (for DYN_ALLOC option) */
|
||||
ALLOC(uch, inbuf, INBUFSIZ + INBUF_EXTRA);
|
||||
ALLOC(uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA);
|
||||
ALLOC(ush, d_buf, DIST_BUFSIZE);
|
||||
ALLOC(uch, window, 2L * WSIZE);
|
||||
ALLOC(ush, tab_prefix, 1L << BITS);
|
||||
|
||||
/* Initialise the CRC32 table */
|
||||
crc_32_tab = crc32_filltable(0);
|
||||
|
||||
clear_bufs();
|
||||
|
||||
if (optind == argc) {
|
||||
time_stamp = 0;
|
||||
zip(STDIN_FILENO, STDOUT_FILENO);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
for (i = optind; i < argc; i++) {
|
||||
char *path = NULL;
|
||||
|
||||
clear_bufs();
|
||||
if (LONE_DASH(argv[i])) {
|
||||
time_stamp = 0;
|
||||
inFileNum = STDIN_FILENO;
|
||||
outFileNum = STDOUT_FILENO;
|
||||
} else {
|
||||
inFileNum = xopen(argv[i], O_RDONLY);
|
||||
if (fstat(inFileNum, &statBuf) < 0)
|
||||
bb_perror_msg_and_die("%s", argv[i]);
|
||||
time_stamp = statBuf.st_ctime;
|
||||
|
||||
if (!(opt & OPT_tostdout)) {
|
||||
path = xasprintf("%s.gz", argv[i]);
|
||||
|
||||
/* Open output file */
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 && defined(O_NOFOLLOW)
|
||||
outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW);
|
||||
#else
|
||||
outFileNum = open(path, O_RDWR | O_CREAT | O_EXCL);
|
||||
#endif
|
||||
if (outFileNum < 0) {
|
||||
bb_perror_msg("%s", path);
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set permissions on the file */
|
||||
fchmod(outFileNum, statBuf.st_mode);
|
||||
} else
|
||||
outFileNum = STDOUT_FILENO;
|
||||
}
|
||||
|
||||
if (path == NULL && isatty(outFileNum) && !(opt & OPT_force)) {
|
||||
bb_error_msg("compressed data not written "
|
||||
"to a terminal. Use -f to force compression.");
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
result = zip(inFileNum, outFileNum);
|
||||
|
||||
if (path != NULL) {
|
||||
close(inFileNum);
|
||||
close(outFileNum);
|
||||
|
||||
/* Delete the original file */
|
||||
if (result == 0)
|
||||
delFileName = argv[i];
|
||||
else
|
||||
delFileName = path;
|
||||
|
||||
if (unlink(delFileName) < 0)
|
||||
bb_perror_msg("%s", delFileName);
|
||||
}
|
||||
|
||||
free(path);
|
||||
}
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user