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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* from zip.c: */
|
|
||||||
static int zip(int in, int out);
|
|
||||||
static unsigned file_read(void *buf, unsigned size);
|
|
||||||
|
|
||||||
/* from deflate.c */
|
/* from deflate.c */
|
||||||
static void lm_init(ush * flags);
|
static void lm_init(ush * flags);
|
||||||
static ulg deflate(void);
|
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
|
* input characters, so that a running hash key can be computed from the
|
||||||
* previous key instead of complete recalculation each time.
|
* 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
|
* 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.
|
* Same as above, but achieves better compression. We use a lazy
|
||||||
* IN assertion: strstart is set to the end of the current match.
|
* 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) \
|
#define FLUSH_BLOCK(eof) \
|
||||||
flush_block( \
|
flush_block( \
|
||||||
block_start >= 0L \
|
block_start >= 0L \
|
||||||
@ -846,16 +835,19 @@ static void fill_window(void)
|
|||||||
(eof) \
|
(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)
|
static ulg deflate(void)
|
||||||
{
|
{
|
||||||
IPos hash_head; /* head of hash chain */
|
IPos hash_head; /* head of hash chain */
|
||||||
@ -959,152 +951,6 @@ static ulg deflate(void)
|
|||||||
|
|
||||||
return FLUSH_BLOCK(1); /* eof */
|
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
|
/* trees.c -- output deflated data using Huffman coding
|
||||||
* Copyright (C) 1992-1993 Jean-loup Gailly
|
* Copyright (C) 1992-1993 Jean-loup Gailly
|
||||||
* This is free software; you can redistribute it and/or modify it under the
|
* 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)
|
static int ct_tally(int dist, int lc)
|
||||||
{
|
{
|
||||||
l_buf[last_lit++] = (uch) lc;
|
l_buf[last_lit++] = lc;
|
||||||
if (dist == 0) {
|
if (dist == 0) {
|
||||||
/* lc is the unmatched char */
|
/* lc is the unmatched char */
|
||||||
dyn_ltree[lc].Freq++;
|
dyn_ltree[lc].Freq++;
|
||||||
@ -2278,3 +2124,147 @@ static int zip(int in, int out)
|
|||||||
flush_outbuf();
|
flush_outbuf();
|
||||||
return 0;
|
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…
x
Reference in New Issue
Block a user