+
+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) */
+}
+