*
*/
-#include "busybox.h"
-#define BB_DECLARE_EXTERN
-#define bb_need_memory_exhausted
-#include "messages.c"
-
/* These defines are very important for BusyBox. Without these,
* huge chunks of ram are pre-allocated making the BusyBox bss
* size Freaking Huge(tm), which is a bad thing.*/
/* I don't like nested includes, but the string and io functions are used
* too often
*/
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <errno.h>
+#include "busybox.h"
+#define BB_DECLARE_EXTERN
+#define bb_need_memory_exhausted
+#include "messages.c"
+
#define memzero(s, n) memset ((void *)(s), 0, (n))
#ifndef RETSIGTYPE
/* methods 4 to 7 reserved */
#define DEFLATED 8
#define MAX_METHODS 9
-extern int method; /* compression method */
+static int method; /* compression method */
/* To save memory for 16 bit systems, some arrays are overlaid between
* the various modules:
#endif
extern unsigned insize; /* valid bytes in inbuf */
-extern unsigned inptr; /* index of next byte to be processed in inbuf */
+static 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 int file_read (char *buf, unsigned size);
/* in unzip.c */
-extern int unzip (int in, int out);
extern int check_zipfile (int in);
/* in unpack.c */
ulg deflate (void);
/* in trees.c */
-void ct_init (ush * attr, int *method);
+void ct_init (ush * attr, int *methodp);
int ct_tally (int dist, int lc);
ulg flush_block (char *buf, ulg stored_len, int eof);
/* in util.c: */
extern int copy (int in, int out);
-extern ulg updcrc (uch * s, unsigned n);
-extern void clear_bufs (void);
+//extern ulg updcrc (uch * s, unsigned n);
+//extern void clear_bufs (void);
extern int fill_inbuf (int eof_ok);
extern void flush_outbuf (void);
extern void flush_window (void);
-extern void write_buf (int fd, void * buf, unsigned cnt);
+//extern void write_buf (int fd, void * buf, unsigned cnt);
extern char *strlwr (char *s);
extern char *add_envopt (int *argcp, char ***argvp, char *env);
-extern void read_error_msg (void);
-extern void write_error_msg (void);
+//extern void read_error_msg (void);
+//extern void write_error_msg (void);
extern void display_ratio (long num, long den, FILE * file);
/* in inflate.c */
#ifndef put_char
# define put_char(c) put_byte(c)
#endif
+
+int crc_table_empty = 1;
+
+/* ========================================================================
+ * Signal and error handler.
+ */
+void abort_gzip()
+{
+ exit(ERROR);
+}
+
+/* ===========================================================================
+ * Clear input and output buffers
+ */
+static void clear_bufs(void)
+{
+ outcnt = 0;
+ insize = inptr = 0;
+ bytes_in = bytes_out = 0L;
+}
+
+static void write_error_msg()
+{
+ fprintf(stderr, "\n");
+ perror("");
+ abort_gzip();
+}
+
+/* ===========================================================================
+ * Does the same as write(), but also handles partial pipe writes and checks
+ * for error return.
+ */
+static void write_buf(fd, buf, cnt)
+int fd;
+void * buf;
+unsigned cnt;
+{
+ unsigned n;
+
+ while ((n = write(fd, buf, cnt)) != cnt) {
+ if (n == (unsigned) (-1)) {
+ write_error_msg();
+ }
+ cnt -= n;
+ buf = (void *) ((char *) buf + n);
+ }
+}
+
+/* ========================================================================
+ * Error handlers.
+ */
+static void read_error_msg()
+{
+ fprintf(stderr, "\n");
+ if (errno != 0) {
+ perror("");
+ } else {
+ fprintf(stderr, "unexpected end of file\n");
+ }
+ abort_gzip();
+}
+
+/* ===========================================================================
+ * 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.
+ */
+static ulg updcrc(s, n)
+uch *s; /* pointer to bytes to pump through */
+unsigned n; /* number of bytes in s[] */
+{
+ static ulg crc = (ulg) 0xffffffffL; /* shift register contents */
+ register ulg c; /* temporary variable */
+ static unsigned long crc_32_tab[256];
+ if (crc_table_empty) {
+ unsigned long csr; /* crc shift register */
+ unsigned long e; /* polynomial exclusive-or pattern */
+ int i; /* counter for all possible eight bit values */
+ int k; /* byte being shifted into crc apparatus */
+
+ /* terms of polynomial defining this crc (except x^32): */
+ static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* Make exclusive-or pattern from polynomial (0xedb88320) */
+ e = 0;
+ for (i = 0; i < sizeof(p)/sizeof(int); i++)
+ e |= 1L << (31 - p[i]);
+
+ /* Compute and print table of CRC's, five per line */
+ crc_32_tab[0] = 0x00000000L;
+ for (i = 1; i < 256; i++) {
+ csr = i;
+ /* The idea to initialize the register with the byte instead of
+ * zero was stolen from Haruhiko Okumura's ar002
+ */
+ for (k = 8; k; k--)
+ csr = csr & 1 ? (csr >> 1) ^ e : csr >> 1;
+ crc_32_tab[i]=csr;
+ }
+ }
+
+ 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) */
+}
+
/* 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
# include <unistd.h>
#endif
-#if defined(STDC_HEADERS) || !defined(NO_STDLIB_H)
-# include <stdlib.h>
-#else
-extern int errno;
-#endif
-
#if defined(DIRENT)
# include <dirent.h>
typedef struct dirent dir_type;
int tostdout = 0;
int fromstdin = 0;
int force = 0;
+ int opt;
- /* Parse any options */
- while (--argc > 0 && **(++argv) == '-') {
- if (*((*argv) + 1) == '\0') {
+ while ((opt = getopt(argc, argv, "cf123456789d")) != -1) {
+ switch (opt) {
+ case 'c':
tostdout = 1;
- }
- while (*(++(*argv))) {
- switch (**argv) {
- case 'c':
- tostdout = 1;
- break;
- case 'f':
- force = 1;
- break;
- /* Ignore 1-9 (compression level) options */
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- break;
- case 'd':
- exit(gunzip_main(argc, argv));
- default:
- usage(gzip_usage);
- }
+ break;
+ case 'f':
+ force = 1;
+ break;
+ /* Ignore 1-9 (compression level) options */
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ break;
+#ifdef BB_GUNZIP
+ case 'd':
+ optind = 1;
+ return gunzip_main(argc, argv);
+#endif
+ default:
+ show_usage();
}
}
- if (argc <= 0 ) {
+ if (optind == argc) {
fromstdin = 1;
tostdout = 1;
}
- if (isatty(fileno(stdin)) && fromstdin==1 && force==0)
- error_msg_and_die( "data not read from terminal. Use -f to force it.");
if (isatty(fileno(stdout)) && tostdout==1 && force==0)
- error_msg_and_die( "data not written to terminal. Use -f to force it.");
+ error_msg_and_die( "compressed data not written to terminal. Use -f to force it.");
foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
if (foreground) {
ifile_size = -1L; /* convention for unknown size */
} else {
/* Open up the input file */
- if (argc <= 0)
- usage(gzip_usage);
- strncpy(ifname, *argv, MAX_PATH_LEN);
+ strncpy(ifname, argv[optind], MAX_PATH_LEN);
/* Open input file */
inFileNum = open(ifname, O_RDONLY);
# include <fcntl.h>
#endif
-#if defined(STDC_HEADERS) || !defined(NO_STDLIB_H)
-# include <stdlib.h>
-#else
-extern int errno;
-#endif
-
/* ===========================================================================
* Copy input to output unchanged: zcat == cat with --force.
* IN assertion: insize bytes have already been read in inbuf.
int zip(in, out)
int in, out; /* input and output file descriptors */
{
- uch flags = 0; /* general purpose bit flags */
+ uch my_flags = 0; /* general purpose bit flags */
ush attr = 0; /* ascii/binary flag */
ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */
put_byte(GZIP_MAGIC[1]);
put_byte(DEFLATED); /* compression method */
- put_byte(flags); /* general flags */
+ put_byte(my_flags); /* general flags */
put_long(time_stamp);
/* Write deflated file to zip file */