summaryrefslogtreecommitdiff
path: root/third_party/rust/libz-sys/src/zlib-1.2.8/examples
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/libz-sys/src/zlib-1.2.8/examples')
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/README.examples49
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/enough.c572
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/fitblk.c233
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/gun.c702
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzappend.c504
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzjoin.c449
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzlog.c1059
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzlog.h91
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/zlib_how.html545
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/zpipe.c205
-rw-r--r--third_party/rust/libz-sys/src/zlib-1.2.8/examples/zran.c409
11 files changed, 0 insertions, 4818 deletions
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/README.examples b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/README.examples
deleted file mode 100644
index 56a31714e5..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/README.examples
+++ /dev/null
@@ -1,49 +0,0 @@
-This directory contains examples of the use of zlib and other relevant
-programs and documentation.
-
-enough.c
- calculation and justification of ENOUGH parameter in inftrees.h
- - calculates the maximum table space used in inflate tree
- construction over all possible Huffman codes
-
-fitblk.c
- compress just enough input to nearly fill a requested output size
- - zlib isn't designed to do this, but fitblk does it anyway
-
-gun.c
- uncompress a gzip file
- - illustrates the use of inflateBack() for high speed file-to-file
- decompression using call-back functions
- - is approximately twice as fast as gzip -d
- - also provides Unix uncompress functionality, again twice as fast
-
-gzappend.c
- append to a gzip file
- - illustrates the use of the Z_BLOCK flush parameter for inflate()
- - illustrates the use of deflatePrime() to start at any bit
-
-gzjoin.c
- join gzip files without recalculating the crc or recompressing
- - illustrates the use of the Z_BLOCK flush parameter for inflate()
- - illustrates the use of crc32_combine()
-
-gzlog.c
-gzlog.h
- efficiently and robustly maintain a message log file in gzip format
- - illustrates use of raw deflate, Z_PARTIAL_FLUSH, deflatePrime(),
- and deflateSetDictionary()
- - illustrates use of a gzip header extra field
-
-zlib_how.html
- painfully comprehensive description of zpipe.c (see below)
- - describes in excruciating detail the use of deflate() and inflate()
-
-zpipe.c
- reads and writes zlib streams from stdin to stdout
- - illustrates the proper use of deflate() and inflate()
- - deeply commented in zlib_how.html (see above)
-
-zran.c
- index a zlib or gzip stream and randomly access it
- - illustrates the use of Z_BLOCK, inflatePrime(), and
- inflateSetDictionary() to provide random access
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/enough.c b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/enough.c
deleted file mode 100644
index b991144305..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/enough.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/* enough.c -- determine the maximum size of inflate's Huffman code tables over
- * all possible valid and complete Huffman codes, subject to a length limit.
- * Copyright (C) 2007, 2008, 2012 Mark Adler
- * Version 1.4 18 August 2012 Mark Adler
- */
-
-/* Version history:
- 1.0 3 Jan 2007 First version (derived from codecount.c version 1.4)
- 1.1 4 Jan 2007 Use faster incremental table usage computation
- Prune examine() search on previously visited states
- 1.2 5 Jan 2007 Comments clean up
- As inflate does, decrease root for short codes
- Refuse cases where inflate would increase root
- 1.3 17 Feb 2008 Add argument for initial root table size
- Fix bug for initial root table size == max - 1
- Use a macro to compute the history index
- 1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!)
- Clean up comparisons of different types
- Clean up code indentation
- */
-
-/*
- Examine all possible Huffman codes for a given number of symbols and a
- maximum code length in bits to determine the maximum table size for zilb's
- inflate. Only complete Huffman codes are counted.
-
- Two codes are considered distinct if the vectors of the number of codes per
- length are not identical. So permutations of the symbol assignments result
- in the same code for the counting, as do permutations of the assignments of
- the bit values to the codes (i.e. only canonical codes are counted).
-
- We build a code from shorter to longer lengths, determining how many symbols
- are coded at each length. At each step, we have how many symbols remain to
- be coded, what the last code length used was, and how many bit patterns of
- that length remain unused. Then we add one to the code length and double the
- number of unused patterns to graduate to the next code length. We then
- assign all portions of the remaining symbols to that code length that
- preserve the properties of a correct and eventually complete code. Those
- properties are: we cannot use more bit patterns than are available; and when
- all the symbols are used, there are exactly zero possible bit patterns
- remaining.
-
- The inflate Huffman decoding algorithm uses two-level lookup tables for
- speed. There is a single first-level table to decode codes up to root bits
- in length (root == 9 in the current inflate implementation). The table
- has 1 << root entries and is indexed by the next root bits of input. Codes
- shorter than root bits have replicated table entries, so that the correct
- entry is pointed to regardless of the bits that follow the short code. If
- the code is longer than root bits, then the table entry points to a second-
- level table. The size of that table is determined by the longest code with
- that root-bit prefix. If that longest code has length len, then the table
- has size 1 << (len - root), to index the remaining bits in that set of
- codes. Each subsequent root-bit prefix then has its own sub-table. The
- total number of table entries required by the code is calculated
- incrementally as the number of codes at each bit length is populated. When
- all of the codes are shorter than root bits, then root is reduced to the
- longest code length, resulting in a single, smaller, one-level table.
-
- The inflate algorithm also provides for small values of root (relative to
- the log2 of the number of symbols), where the shortest code has more bits
- than root. In that case, root is increased to the length of the shortest
- code. This program, by design, does not handle that case, so it is verified
- that the number of symbols is less than 2^(root + 1).
-
- In order to speed up the examination (by about ten orders of magnitude for
- the default arguments), the intermediate states in the build-up of a code
- are remembered and previously visited branches are pruned. The memory
- required for this will increase rapidly with the total number of symbols and
- the maximum code length in bits. However this is a very small price to pay
- for the vast speedup.
-
- First, all of the possible Huffman codes are counted, and reachable
- intermediate states are noted by a non-zero count in a saved-results array.
- Second, the intermediate states that lead to (root + 1) bit or longer codes
- are used to look at all sub-codes from those junctures for their inflate
- memory usage. (The amount of memory used is not affected by the number of
- codes of root bits or less in length.) Third, the visited states in the
- construction of those sub-codes and the associated calculation of the table
- size is recalled in order to avoid recalculating from the same juncture.
- Beginning the code examination at (root + 1) bit codes, which is enabled by
- identifying the reachable nodes, accounts for about six of the orders of
- magnitude of improvement for the default arguments. About another four
- orders of magnitude come from not revisiting previous states. Out of
- approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes
- need to be examined to cover all of the possible table memory usage cases
- for the default arguments of 286 symbols limited to 15-bit codes.
-
- Note that an unsigned long long type is used for counting. It is quite easy
- to exceed the capacity of an eight-byte integer with a large number of
- symbols and a large maximum code length, so multiple-precision arithmetic
- would need to replace the unsigned long long arithmetic in that case. This
- program will abort if an overflow occurs. The big_t type identifies where
- the counting takes place.
-
- An unsigned long long type is also used for calculating the number of
- possible codes remaining at the maximum length. This limits the maximum
- code length to the number of bits in a long long minus the number of bits
- needed to represent the symbols in a flat code. The code_t type identifies
- where the bit pattern counting takes place.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#define local static
-
-/* special data types */
-typedef unsigned long long big_t; /* type for code counting */
-typedef unsigned long long code_t; /* type for bit pattern counting */
-struct tab { /* type for been here check */
- size_t len; /* length of bit vector in char's */
- char *vec; /* allocated bit vector */
-};
-
-/* The array for saving results, num[], is indexed with this triplet:
-
- syms: number of symbols remaining to code
- left: number of available bit patterns at length len
- len: number of bits in the codes currently being assigned
-
- Those indices are constrained thusly when saving results:
-
- syms: 3..totsym (totsym == total symbols to code)
- left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6)
- len: 1..max - 1 (max == maximum code length in bits)
-
- syms == 2 is not saved since that immediately leads to a single code. left
- must be even, since it represents the number of available bit patterns at
- the current length, which is double the number at the previous length.
- left ends at syms-1 since left == syms immediately results in a single code.
- (left > sym is not allowed since that would result in an incomplete code.)
- len is less than max, since the code completes immediately when len == max.
-
- The offset into the array is calculated for the three indices with the
- first one (syms) being outermost, and the last one (len) being innermost.
- We build the array with length max-1 lists for the len index, with syms-3
- of those for each symbol. There are totsym-2 of those, with each one
- varying in length as a function of sym. See the calculation of index in
- count() for the index, and the calculation of size in main() for the size
- of the array.
-
- For the deflate example of 286 symbols limited to 15-bit codes, the array
- has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than
- half of the space allocated for saved results is actually used -- not all
- possible triplets are reached in the generation of valid Huffman codes.
- */
-
-/* The array for tracking visited states, done[], is itself indexed identically
- to the num[] array as described above for the (syms, left, len) triplet.
- Each element in the array is further indexed by the (mem, rem) doublet,
- where mem is the amount of inflate table space used so far, and rem is the
- remaining unused entries in the current inflate sub-table. Each indexed
- element is simply one bit indicating whether the state has been visited or
- not. Since the ranges for mem and rem are not known a priori, each bit
- vector is of a variable size, and grows as needed to accommodate the visited
- states. mem and rem are used to calculate a single index in a triangular
- array. Since the range of mem is expected in the default case to be about
- ten times larger than the range of rem, the array is skewed to reduce the
- memory usage, with eight times the range for mem than for rem. See the
- calculations for offset and bit in beenhere() for the details.
-
- For the deflate example of 286 symbols limited to 15-bit codes, the bit
- vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[]
- array itself.
- */
-
-/* Globals to avoid propagating constants or constant pointers recursively */
-local int max; /* maximum allowed bit length for the codes */
-local int root; /* size of base code table in bits */
-local int large; /* largest code table so far */
-local size_t size; /* number of elements in num and done */
-local int *code; /* number of symbols assigned to each bit length */
-local big_t *num; /* saved results array for code counting */
-local struct tab *done; /* states already evaluated array */
-
-/* Index function for num[] and done[] */
-#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1)
-
-/* Free allocated space. Uses globals code, num, and done. */
-local void cleanup(void)
-{
- size_t n;
-
- if (done != NULL) {
- for (n = 0; n < size; n++)
- if (done[n].len)
- free(done[n].vec);
- free(done);
- }
- if (num != NULL)
- free(num);
- if (code != NULL)
- free(code);
-}
-
-/* Return the number of possible Huffman codes using bit patterns of lengths
- len through max inclusive, coding syms symbols, with left bit patterns of
- length len unused -- return -1 if there is an overflow in the counting.
- Keep a record of previous results in num to prevent repeating the same
- calculation. Uses the globals max and num. */
-local big_t count(int syms, int len, int left)
-{
- big_t sum; /* number of possible codes from this juncture */
- big_t got; /* value returned from count() */
- int least; /* least number of syms to use at this juncture */
- int most; /* most number of syms to use at this juncture */
- int use; /* number of bit patterns to use in next call */
- size_t index; /* index of this case in *num */
-
- /* see if only one possible code */
- if (syms == left)
- return 1;
-
- /* note and verify the expected state */
- assert(syms > left && left > 0 && len < max);
-
- /* see if we've done this one already */
- index = INDEX(syms, left, len);
- got = num[index];
- if (got)
- return got; /* we have -- return the saved result */
-
- /* we need to use at least this many bit patterns so that the code won't be
- incomplete at the next length (more bit patterns than symbols) */
- least = (left << 1) - syms;
- if (least < 0)
- least = 0;
-
- /* we can use at most this many bit patterns, lest there not be enough
- available for the remaining symbols at the maximum length (if there were
- no limit to the code length, this would become: most = left - 1) */
- most = (((code_t)left << (max - len)) - syms) /
- (((code_t)1 << (max - len)) - 1);
-
- /* count all possible codes from this juncture and add them up */
- sum = 0;
- for (use = least; use <= most; use++) {
- got = count(syms - use, len + 1, (left - use) << 1);
- sum += got;
- if (got == (big_t)0 - 1 || sum < got) /* overflow */
- return (big_t)0 - 1;
- }
-
- /* verify that all recursive calls are productive */
- assert(sum != 0);
-
- /* save the result and return it */
- num[index] = sum;
- return sum;
-}
-
-/* Return true if we've been here before, set to true if not. Set a bit in a
- bit vector to indicate visiting this state. Each (syms,len,left) state
- has a variable size bit vector indexed by (mem,rem). The bit vector is
- lengthened if needed to allow setting the (mem,rem) bit. */
-local int beenhere(int syms, int len, int left, int mem, int rem)
-{
- size_t index; /* index for this state's bit vector */
- size_t offset; /* offset in this state's bit vector */
- int bit; /* mask for this state's bit */
- size_t length; /* length of the bit vector in bytes */
- char *vector; /* new or enlarged bit vector */
-
- /* point to vector for (syms,left,len), bit in vector for (mem,rem) */
- index = INDEX(syms, left, len);
- mem -= 1 << root;
- offset = (mem >> 3) + rem;
- offset = ((offset * (offset + 1)) >> 1) + rem;
- bit = 1 << (mem & 7);
-
- /* see if we've been here */
- length = done[index].len;
- if (offset < length && (done[index].vec[offset] & bit) != 0)
- return 1; /* done this! */
-
- /* we haven't been here before -- set the bit to show we have now */
-
- /* see if we need to lengthen the vector in order to set the bit */
- if (length <= offset) {
- /* if we have one already, enlarge it, zero out the appended space */
- if (length) {
- do {
- length <<= 1;
- } while (length <= offset);
- vector = realloc(done[index].vec, length);
- if (vector != NULL)
- memset(vector + done[index].len, 0, length - done[index].len);
- }
-
- /* otherwise we need to make a new vector and zero it out */
- else {
- length = 1 << (len - root);
- while (length <= offset)
- length <<= 1;
- vector = calloc(length, sizeof(char));
- }
-
- /* in either case, bail if we can't get the memory */
- if (vector == NULL) {
- fputs("abort: unable to allocate enough memory\n", stderr);
- cleanup();
- exit(1);
- }
-
- /* install the new vector */
- done[index].len = length;
- done[index].vec = vector;
- }
-
- /* set the bit */
- done[index].vec[offset] |= bit;
- return 0;
-}
-
-/* Examine all possible codes from the given node (syms, len, left). Compute
- the amount of memory required to build inflate's decoding tables, where the
- number of code structures used so far is mem, and the number remaining in
- the current sub-table is rem. Uses the globals max, code, root, large, and
- done. */
-local void examine(int syms, int len, int left, int mem, int rem)
-{
- int least; /* least number of syms to use at this juncture */
- int most; /* most number of syms to use at this juncture */
- int use; /* number of bit patterns to use in next call */
-
- /* see if we have a complete code */
- if (syms == left) {
- /* set the last code entry */
- code[len] = left;
-
- /* complete computation of memory used by this code */
- while (rem < left) {
- left -= rem;
- rem = 1 << (len - root);
- mem += rem;
- }
- assert(rem == left);
-
- /* if this is a new maximum, show the entries used and the sub-code */
- if (mem > large) {
- large = mem;
- printf("max %d: ", mem);
- for (use = root + 1; use <= max; use++)
- if (code[use])
- printf("%d[%d] ", code[use], use);
- putchar('\n');
- fflush(stdout);
- }
-
- /* remove entries as we drop back down in the recursion */
- code[len] = 0;
- return;
- }
-
- /* prune the tree if we can */
- if (beenhere(syms, len, left, mem, rem))
- return;
-
- /* we need to use at least this many bit patterns so that the code won't be
- incomplete at the next length (more bit patterns than symbols) */
- least = (left << 1) - syms;
- if (least < 0)
- least = 0;
-
- /* we can use at most this many bit patterns, lest there not be enough
- available for the remaining symbols at the maximum length (if there were
- no limit to the code length, this would become: most = left - 1) */
- most = (((code_t)left << (max - len)) - syms) /
- (((code_t)1 << (max - len)) - 1);
-
- /* occupy least table spaces, creating new sub-tables as needed */
- use = least;
- while (rem < use) {
- use -= rem;
- rem = 1 << (len - root);
- mem += rem;
- }
- rem -= use;
-
- /* examine codes from here, updating table space as we go */
- for (use = least; use <= most; use++) {
- code[len] = use;
- examine(syms - use, len + 1, (left - use) << 1,
- mem + (rem ? 1 << (len - root) : 0), rem << 1);
- if (rem == 0) {
- rem = 1 << (len - root);
- mem += rem;
- }
- rem--;
- }
-
- /* remove entries as we drop back down in the recursion */
- code[len] = 0;
-}
-
-/* Look at all sub-codes starting with root + 1 bits. Look at only the valid
- intermediate code states (syms, left, len). For each completed code,
- calculate the amount of memory required by inflate to build the decoding
- tables. Find the maximum amount of memory required and show the code that
- requires that maximum. Uses the globals max, root, and num. */
-local void enough(int syms)
-{
- int n; /* number of remaing symbols for this node */
- int left; /* number of unused bit patterns at this length */
- size_t index; /* index of this case in *num */
-
- /* clear code */
- for (n = 0; n <= max; n++)
- code[n] = 0;
-
- /* look at all (root + 1) bit and longer codes */
- large = 1 << root; /* base table */
- if (root < max) /* otherwise, there's only a base table */
- for (n = 3; n <= syms; n++)
- for (left = 2; left < n; left += 2)
- {
- /* look at all reachable (root + 1) bit nodes, and the
- resulting codes (complete at root + 2 or more) */
- index = INDEX(n, left, root + 1);
- if (root + 1 < max && num[index]) /* reachable node */
- examine(n, root + 1, left, 1 << root, 0);
-
- /* also look at root bit codes with completions at root + 1
- bits (not saved in num, since complete), just in case */
- if (num[index - 1] && n <= left << 1)
- examine((n - left) << 1, root + 1, (n - left) << 1,
- 1 << root, 0);
- }
-
- /* done */
- printf("done: maximum of %d table entries\n", large);
-}
-
-/*
- Examine and show the total number of possible Huffman codes for a given
- maximum number of symbols, initial root table size, and maximum code length
- in bits -- those are the command arguments in that order. The default
- values are 286, 9, and 15 respectively, for the deflate literal/length code.
- The possible codes are counted for each number of coded symbols from two to
- the maximum. The counts for each of those and the total number of codes are
- shown. The maximum number of inflate table entires is then calculated
- across all possible codes. Each new maximum number of table entries and the
- associated sub-code (starting at root + 1 == 10 bits) is shown.
-
- To count and examine Huffman codes that are not length-limited, provide a
- maximum length equal to the number of symbols minus one.
-
- For the deflate literal/length code, use "enough". For the deflate distance
- code, use "enough 30 6".
-
- This uses the %llu printf format to print big_t numbers, which assumes that
- big_t is an unsigned long long. If the big_t type is changed (for example
- to a multiple precision type), the method of printing will also need to be
- updated.
- */
-int main(int argc, char **argv)
-{
- int syms; /* total number of symbols to code */
- int n; /* number of symbols to code for this run */
- big_t got; /* return value of count() */
- big_t sum; /* accumulated number of codes over n */
- code_t word; /* for counting bits in code_t */
-
- /* set up globals for cleanup() */
- code = NULL;
- num = NULL;
- done = NULL;
-
- /* get arguments -- default to the deflate literal/length code */
- syms = 286;
- root = 9;
- max = 15;
- if (argc > 1) {
- syms = atoi(argv[1]);
- if (argc > 2) {
- root = atoi(argv[2]);
- if (argc > 3)
- max = atoi(argv[3]);
- }
- }
- if (argc > 4 || syms < 2 || root < 1 || max < 1) {
- fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
- stderr);
- return 1;
- }
-
- /* if not restricting the code length, the longest is syms - 1 */
- if (max > syms - 1)
- max = syms - 1;
-
- /* determine the number of bits in a code_t */
- for (n = 0, word = 1; word; n++, word <<= 1)
- ;
-
- /* make sure that the calculation of most will not overflow */
- if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) {
- fputs("abort: code length too long for internal types\n", stderr);
- return 1;
- }
-
- /* reject impossible code requests */
- if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) {
- fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
- syms, max);
- return 1;
- }
-
- /* allocate code vector */
- code = calloc(max + 1, sizeof(int));
- if (code == NULL) {
- fputs("abort: unable to allocate enough memory\n", stderr);
- return 1;
- }
-
- /* determine size of saved results array, checking for overflows,
- allocate and clear the array (set all to zero with calloc()) */
- if (syms == 2) /* iff max == 1 */
- num = NULL; /* won't be saving any results */
- else {
- size = syms >> 1;
- if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) ||
- (size *= n, size > ((size_t)0 - 1) / (n = max - 1)) ||
- (size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) ||
- (num = calloc(size, sizeof(big_t))) == NULL) {
- fputs("abort: unable to allocate enough memory\n", stderr);
- cleanup();
- return 1;
- }
- }
-
- /* count possible codes for all numbers of symbols, add up counts */
- sum = 0;
- for (n = 2; n <= syms; n++) {
- got = count(n, 1, 2);
- sum += got;
- if (got == (big_t)0 - 1 || sum < got) { /* overflow */
- fputs("abort: can't count that high!\n", stderr);
- cleanup();
- return 1;
- }
- printf("%llu %d-codes\n", got, n);
- }
- printf("%llu total codes for 2 to %d symbols", sum, syms);
- if (max < syms - 1)
- printf(" (%d-bit length limit)\n", max);
- else
- puts(" (no length limit)");
-
- /* allocate and clear done array for beenhere() */
- if (syms == 2)
- done = NULL;
- else if (size > ((size_t)0 - 1) / sizeof(struct tab) ||
- (done = calloc(size, sizeof(struct tab))) == NULL) {
- fputs("abort: unable to allocate enough memory\n", stderr);
- cleanup();
- return 1;
- }
-
- /* find and show maximum inflate table usage */
- if (root > max) /* reduce root to max length */
- root = max;
- if ((code_t)syms < ((code_t)1 << (root + 1)))
- enough(syms);
- else
- puts("cannot handle minimum code lengths > root");
-
- /* done */
- cleanup();
- return 0;
-}
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/fitblk.c b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/fitblk.c
deleted file mode 100644
index c61de5c996..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/fitblk.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/* fitblk.c: example of fitting compressed output to a specified size
- Not copyrighted -- provided to the public domain
- Version 1.1 25 November 2004 Mark Adler */
-
-/* Version history:
- 1.0 24 Nov 2004 First version
- 1.1 25 Nov 2004 Change deflateInit2() to deflateInit()
- Use fixed-size, stack-allocated raw buffers
- Simplify code moving compression to subroutines
- Use assert() for internal errors
- Add detailed description of approach
- */
-
-/* Approach to just fitting a requested compressed size:
-
- fitblk performs three compression passes on a portion of the input
- data in order to determine how much of that input will compress to
- nearly the requested output block size. The first pass generates
- enough deflate blocks to produce output to fill the requested
- output size plus a specfied excess amount (see the EXCESS define
- below). The last deflate block may go quite a bit past that, but
- is discarded. The second pass decompresses and recompresses just
- the compressed data that fit in the requested plus excess sized
- buffer. The deflate process is terminated after that amount of
- input, which is less than the amount consumed on the first pass.
- The last deflate block of the result will be of a comparable size
- to the final product, so that the header for that deflate block and
- the compression ratio for that block will be about the same as in
- the final product. The third compression pass decompresses the
- result of the second step, but only the compressed data up to the
- requested size minus an amount to allow the compressed stream to
- complete (see the MARGIN define below). That will result in a
- final compressed stream whose length is less than or equal to the
- requested size. Assuming sufficient input and a requested size
- greater than a few hundred bytes, the shortfall will typically be
- less than ten bytes.
-
- If the input is short enough that the first compression completes
- before filling the requested output size, then that compressed
- stream is return with no recompression.
-
- EXCESS is chosen to be just greater than the shortfall seen in a
- two pass approach similar to the above. That shortfall is due to
- the last deflate block compressing more efficiently with a smaller
- header on the second pass. EXCESS is set to be large enough so
- that there is enough uncompressed data for the second pass to fill
- out the requested size, and small enough so that the final deflate
- block of the second pass will be close in size to the final deflate
- block of the third and final pass. MARGIN is chosen to be just
- large enough to assure that the final compression has enough room
- to complete in all cases.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include "zlib.h"
-
-#define local static
-
-/* print nastygram and leave */
-local void quit(char *why)
-{
- fprintf(stderr, "fitblk abort: %s\n", why);
- exit(1);
-}
-
-#define RAWLEN 4096 /* intermediate uncompressed buffer size */
-
-/* compress from file to def until provided buffer is full or end of
- input reached; return last deflate() return value, or Z_ERRNO if
- there was read error on the file */
-local int partcompress(FILE *in, z_streamp def)
-{
- int ret, flush;
- unsigned char raw[RAWLEN];
-
- flush = Z_NO_FLUSH;
- do {
- def->avail_in = fread(raw, 1, RAWLEN, in);
- if (ferror(in))
- return Z_ERRNO;
- def->next_in = raw;
- if (feof(in))
- flush = Z_FINISH;
- ret = deflate(def, flush);
- assert(ret != Z_STREAM_ERROR);
- } while (def->avail_out != 0 && flush == Z_NO_FLUSH);
- return ret;
-}
-
-/* recompress from inf's input to def's output; the input for inf and
- the output for def are set in those structures before calling;
- return last deflate() return value, or Z_MEM_ERROR if inflate()
- was not able to allocate enough memory when it needed to */
-local int recompress(z_streamp inf, z_streamp def)
-{
- int ret, flush;
- unsigned char raw[RAWLEN];
-
- flush = Z_NO_FLUSH;
- do {
- /* decompress */
- inf->avail_out = RAWLEN;
- inf->next_out = raw;
- ret = inflate(inf, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
- ret != Z_NEED_DICT);
- if (ret == Z_MEM_ERROR)
- return ret;
-
- /* compress what was decompresed until done or no room */
- def->avail_in = RAWLEN - inf->avail_out;
- def->next_in = raw;
- if (inf->avail_out != 0)
- flush = Z_FINISH;
- ret = deflate(def, flush);
- assert(ret != Z_STREAM_ERROR);
- } while (ret != Z_STREAM_END && def->avail_out != 0);
- return ret;
-}
-
-#define EXCESS 256 /* empirically determined stream overage */
-#define MARGIN 8 /* amount to back off for completion */
-
-/* compress from stdin to fixed-size block on stdout */
-int main(int argc, char **argv)
-{
- int ret; /* return code */
- unsigned size; /* requested fixed output block size */
- unsigned have; /* bytes written by deflate() call */
- unsigned char *blk; /* intermediate and final stream */
- unsigned char *tmp; /* close to desired size stream */
- z_stream def, inf; /* zlib deflate and inflate states */
-
- /* get requested output size */
- if (argc != 2)
- quit("need one argument: size of output block");
- ret = strtol(argv[1], argv + 1, 10);
- if (argv[1][0] != 0)
- quit("argument must be a number");
- if (ret < 8) /* 8 is minimum zlib stream size */
- quit("need positive size of 8 or greater");
- size = (unsigned)ret;
-
- /* allocate memory for buffers and compression engine */
- blk = malloc(size + EXCESS);
- def.zalloc = Z_NULL;
- def.zfree = Z_NULL;
- def.opaque = Z_NULL;
- ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
- if (ret != Z_OK || blk == NULL)
- quit("out of memory");
-
- /* compress from stdin until output full, or no more input */
- def.avail_out = size + EXCESS;
- def.next_out = blk;
- ret = partcompress(stdin, &def);
- if (ret == Z_ERRNO)
- quit("error reading input");
-
- /* if it all fit, then size was undersubscribed -- done! */
- if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
- /* write block to stdout */
- have = size + EXCESS - def.avail_out;
- if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
- quit("error writing output");
-
- /* clean up and print results to stderr */
- ret = deflateEnd(&def);
- assert(ret != Z_STREAM_ERROR);
- free(blk);
- fprintf(stderr,
- "%u bytes unused out of %u requested (all input)\n",
- size - have, size);
- return 0;
- }
-
- /* it didn't all fit -- set up for recompression */
- inf.zalloc = Z_NULL;
- inf.zfree = Z_NULL;
- inf.opaque = Z_NULL;
- inf.avail_in = 0;
- inf.next_in = Z_NULL;
- ret = inflateInit(&inf);
- tmp = malloc(size + EXCESS);
- if (ret != Z_OK || tmp == NULL)
- quit("out of memory");
- ret = deflateReset(&def);
- assert(ret != Z_STREAM_ERROR);
-
- /* do first recompression close to the right amount */
- inf.avail_in = size + EXCESS;
- inf.next_in = blk;
- def.avail_out = size + EXCESS;
- def.next_out = tmp;
- ret = recompress(&inf, &def);
- if (ret == Z_MEM_ERROR)
- quit("out of memory");
-
- /* set up for next reocmpression */
- ret = inflateReset(&inf);
- assert(ret != Z_STREAM_ERROR);
- ret = deflateReset(&def);
- assert(ret != Z_STREAM_ERROR);
-
- /* do second and final recompression (third compression) */
- inf.avail_in = size - MARGIN; /* assure stream will complete */
- inf.next_in = tmp;
- def.avail_out = size;
- def.next_out = blk;
- ret = recompress(&inf, &def);
- if (ret == Z_MEM_ERROR)
- quit("out of memory");
- assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
-
- /* done -- write block to stdout */
- have = size - def.avail_out;
- if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
- quit("error writing output");
-
- /* clean up and print results to stderr */
- free(tmp);
- ret = inflateEnd(&inf);
- assert(ret != Z_STREAM_ERROR);
- ret = deflateEnd(&def);
- assert(ret != Z_STREAM_ERROR);
- free(blk);
- fprintf(stderr,
- "%u bytes unused out of %u requested (%lu input)\n",
- size - have, size, def.total_in);
- return 0;
-}
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gun.c b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gun.c
deleted file mode 100644
index 89e484fee6..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gun.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/* gun.c -- simple gunzip to give an example of the use of inflateBack()
- * Copyright (C) 2003, 2005, 2008, 2010, 2012 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- Version 1.7 12 August 2012 Mark Adler */
-
-/* Version history:
- 1.0 16 Feb 2003 First version for testing of inflateBack()
- 1.1 21 Feb 2005 Decompress concatenated gzip streams
- Remove use of "this" variable (C++ keyword)
- Fix return value for in()
- Improve allocation failure checking
- Add typecasting for void * structures
- Add -h option for command version and usage
- Add a bunch of comments
- 1.2 20 Mar 2005 Add Unix compress (LZW) decompression
- Copy file attributes from input file to output file
- 1.3 12 Jun 2005 Add casts for error messages [Oberhumer]
- 1.4 8 Dec 2006 LZW decompression speed improvements
- 1.5 9 Feb 2008 Avoid warning in latest version of gcc
- 1.6 17 Jan 2010 Avoid signed/unsigned comparison warnings
- 1.7 12 Aug 2012 Update for z_const usage in zlib 1.2.8
- */
-
-/*
- gun [ -t ] [ name ... ]
-
- decompresses the data in the named gzip files. If no arguments are given,
- gun will decompress from stdin to stdout. The names must end in .gz, -gz,
- .z, -z, _z, or .Z. The uncompressed data will be written to a file name
- with the suffix stripped. On success, the original file is deleted. On
- failure, the output file is deleted. For most failures, the command will
- continue to process the remaining names on the command line. A memory
- allocation failure will abort the command. If -t is specified, then the
- listed files or stdin will be tested as gzip files for integrity (without
- checking for a proper suffix), no output will be written, and no files
- will be deleted.
-
- Like gzip, gun allows concatenated gzip streams and will decompress them,
- writing all of the uncompressed data to the output. Unlike gzip, gun allows
- an empty file on input, and will produce no error writing an empty output
- file.
-
- gun will also decompress files made by Unix compress, which uses LZW
- compression. These files are automatically detected by virtue of their
- magic header bytes. Since the end of Unix compress stream is marked by the
- end-of-file, they cannot be concantenated. If a Unix compress stream is
- encountered in an input file, it is the last stream in that file.
-
- Like gunzip and uncompress, the file attributes of the orignal compressed
- file are maintained in the final uncompressed file, to the extent that the
- user permissions allow it.
-
- On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version
- 1.2.4) is on the same file, when gun is linked with zlib 1.2.2. Also the
- LZW decompression provided by gun is about twice as fast as the standard
- Unix uncompress command.
- */
-
-/* external functions and related types and constants */
-#include <stdio.h> /* fprintf() */
-#include <stdlib.h> /* malloc(), free() */
-#include <string.h> /* strerror(), strcmp(), strlen(), memcpy() */
-#include <errno.h> /* errno */
-#include <fcntl.h> /* open() */
-#include <unistd.h> /* read(), write(), close(), chown(), unlink() */
-#include <sys/types.h>
-#include <sys/stat.h> /* stat(), chmod() */
-#include <utime.h> /* utime() */
-#include "zlib.h" /* inflateBackInit(), inflateBack(), */
- /* inflateBackEnd(), crc32() */
-
-/* function declaration */
-#define local static
-
-/* buffer constants */
-#define SIZE 32768U /* input and output buffer sizes */
-#define PIECE 16384 /* limits i/o chunks for 16-bit int case */
-
-/* structure for infback() to pass to input function in() -- it maintains the
- input file and a buffer of size SIZE */
-struct ind {
- int infile;
- unsigned char *inbuf;
-};
-
-/* Load input buffer, assumed to be empty, and return bytes loaded and a
- pointer to them. read() is called until the buffer is full, or until it
- returns end-of-file or error. Return 0 on error. */
-local unsigned in(void *in_desc, z_const unsigned char **buf)
-{
- int ret;
- unsigned len;
- unsigned char *next;
- struct ind *me = (struct ind *)in_desc;
-
- next = me->inbuf;
- *buf = next;
- len = 0;
- do {
- ret = PIECE;
- if ((unsigned)ret > SIZE - len)
- ret = (int)(SIZE - len);
- ret = (int)read(me->infile, next, ret);
- if (ret == -1) {
- len = 0;
- break;
- }
- next += ret;
- len += ret;
- } while (ret != 0 && len < SIZE);
- return len;
-}
-
-/* structure for infback() to pass to output function out() -- it maintains the
- output file, a running CRC-32 check on the output and the total number of
- bytes output, both for checking against the gzip trailer. (The length in
- the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and
- the output is greater than 4 GB.) */
-struct outd {
- int outfile;
- int check; /* true if checking crc and total */
- unsigned long crc;
- unsigned long total;
-};
-
-/* Write output buffer and update the CRC-32 and total bytes written. write()
- is called until all of the output is written or an error is encountered.
- On success out() returns 0. For a write failure, out() returns 1. If the
- output file descriptor is -1, then nothing is written.
- */
-local int out(void *out_desc, unsigned char *buf, unsigned len)
-{
- int ret;
- struct outd *me = (struct outd *)out_desc;
-
- if (me->check) {
- me->crc = crc32(me->crc, buf, len);
- me->total += len;
- }
- if (me->outfile != -1)
- do {
- ret = PIECE;
- if ((unsigned)ret > len)
- ret = (int)len;
- ret = (int)write(me->outfile, buf, ret);
- if (ret == -1)
- return 1;
- buf += ret;
- len -= ret;
- } while (len != 0);
- return 0;
-}
-
-/* next input byte macro for use inside lunpipe() and gunpipe() */
-#define NEXT() (have ? 0 : (have = in(indp, &next)), \
- last = have ? (have--, (int)(*next++)) : -1)
-
-/* memory for gunpipe() and lunpipe() --
- the first 256 entries of prefix[] and suffix[] are never used, could
- have offset the index, but it's faster to waste the memory */
-unsigned char inbuf[SIZE]; /* input buffer */
-unsigned char outbuf[SIZE]; /* output buffer */
-unsigned short prefix[65536]; /* index to LZW prefix string */
-unsigned char suffix[65536]; /* one-character LZW suffix */
-unsigned char match[65280 + 2]; /* buffer for reversed match or gzip
- 32K sliding window */
-
-/* throw out what's left in the current bits byte buffer (this is a vestigial
- aspect of the compressed data format derived from an implementation that
- made use of a special VAX machine instruction!) */
-#define FLUSHCODE() \
- do { \
- left = 0; \
- rem = 0; \
- if (chunk > have) { \
- chunk -= have; \
- have = 0; \
- if (NEXT() == -1) \
- break; \
- chunk--; \
- if (chunk > have) { \
- chunk = have = 0; \
- break; \
- } \
- } \
- have -= chunk; \
- next += chunk; \
- chunk = 0; \
- } while (0)
-
-/* Decompress a compress (LZW) file from indp to outfile. The compress magic
- header (two bytes) has already been read and verified. There are have bytes
- of buffered input at next. strm is used for passing error information back
- to gunpipe().
-
- lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of
- file, read error, or write error (a write error indicated by strm->next_in
- not equal to Z_NULL), or Z_DATA_ERROR for invalid input.
- */
-local int lunpipe(unsigned have, z_const unsigned char *next, struct ind *indp,
- int outfile, z_stream *strm)
-{
- int last; /* last byte read by NEXT(), or -1 if EOF */
- unsigned chunk; /* bytes left in current chunk */
- int left; /* bits left in rem */
- unsigned rem; /* unused bits from input */
- int bits; /* current bits per code */
- unsigned code; /* code, table traversal index */
- unsigned mask; /* mask for current bits codes */
- int max; /* maximum bits per code for this stream */
- unsigned flags; /* compress flags, then block compress flag */
- unsigned end; /* last valid entry in prefix/suffix tables */
- unsigned temp; /* current code */
- unsigned prev; /* previous code */
- unsigned final; /* last character written for previous code */
- unsigned stack; /* next position for reversed string */
- unsigned outcnt; /* bytes in output buffer */
- struct outd outd; /* output structure */
- unsigned char *p;
-
- /* set up output */
- outd.outfile = outfile;
- outd.check = 0;
-
- /* process remainder of compress header -- a flags byte */
- flags = NEXT();
- if (last == -1)
- return Z_BUF_ERROR;
- if (flags & 0x60) {
- strm->msg = (char *)"unknown lzw flags set";
- return Z_DATA_ERROR;
- }
- max = flags & 0x1f;
- if (max < 9 || max > 16) {
- strm->msg = (char *)"lzw bits out of range";
- return Z_DATA_ERROR;
- }
- if (max == 9) /* 9 doesn't really mean 9 */
- max = 10;
- flags &= 0x80; /* true if block compress */
-
- /* clear table */
- bits = 9;
- mask = 0x1ff;
- end = flags ? 256 : 255;
-
- /* set up: get first 9-bit code, which is the first decompressed byte, but
- don't create a table entry until the next code */
- if (NEXT() == -1) /* no compressed data is ok */
- return Z_OK;
- final = prev = (unsigned)last; /* low 8 bits of code */
- if (NEXT() == -1) /* missing a bit */
- return Z_BUF_ERROR;
- if (last & 1) { /* code must be < 256 */
- strm->msg = (char *)"invalid lzw code";
- return Z_DATA_ERROR;
- }
- rem = (unsigned)last >> 1; /* remaining 7 bits */
- left = 7;
- chunk = bits - 2; /* 7 bytes left in this chunk */
- outbuf[0] = (unsigned char)final; /* write first decompressed byte */
- outcnt = 1;
-
- /* decode codes */
- stack = 0;
- for (;;) {
- /* if the table will be full after this, increment the code size */
- if (end >= mask && bits < max) {
- FLUSHCODE();
- bits++;
- mask <<= 1;
- mask++;
- }
-
- /* get a code of length bits */
- if (chunk == 0) /* decrement chunk modulo bits */
- chunk = bits;
- code = rem; /* low bits of code */
- if (NEXT() == -1) { /* EOF is end of compressed data */
- /* write remaining buffered output */
- if (outcnt && out(&outd, outbuf, outcnt)) {
- strm->next_in = outbuf; /* signal write error */
- return Z_BUF_ERROR;
- }
- return Z_OK;
- }
- code += (unsigned)last << left; /* middle (or high) bits of code */
- left += 8;
- chunk--;
- if (bits > left) { /* need more bits */
- if (NEXT() == -1) /* can't end in middle of code */
- return Z_BUF_ERROR;
- code += (unsigned)last << left; /* high bits of code */
- left += 8;
- chunk--;
- }
- code &= mask; /* mask to current code length */
- left -= bits; /* number of unused bits */
- rem = (unsigned)last >> (8 - left); /* unused bits from last byte */
-
- /* process clear code (256) */
- if (code == 256 && flags) {
- FLUSHCODE();
- bits = 9; /* initialize bits and mask */
- mask = 0x1ff;
- end = 255; /* empty table */
- continue; /* get next code */
- }
-
- /* special code to reuse last match */
- temp = code; /* save the current code */
- if (code > end) {
- /* Be picky on the allowed code here, and make sure that the code
- we drop through (prev) will be a valid index so that random
- input does not cause an exception. The code != end + 1 check is
- empirically derived, and not checked in the original uncompress
- code. If this ever causes a problem, that check could be safely
- removed. Leaving this check in greatly improves gun's ability
- to detect random or corrupted input after a compress header.
- In any case, the prev > end check must be retained. */
- if (code != end + 1 || prev > end) {
- strm->msg = (char *)"invalid lzw code";
- return Z_DATA_ERROR;
- }
- match[stack++] = (unsigned char)final;
- code = prev;
- }
-
- /* walk through linked list to generate output in reverse order */
- p = match + stack;
- while (code >= 256) {
- *p++ = suffix[code];
- code = prefix[code];
- }
- stack = p - match;
- match[stack++] = (unsigned char)code;
- final = code;
-
- /* link new table entry */
- if (end < mask) {
- end++;
- prefix[end] = (unsigned short)prev;
- suffix[end] = (unsigned char)final;
- }
-
- /* set previous code for next iteration */
- prev = temp;
-
- /* write output in forward order */
- while (stack > SIZE - outcnt) {
- while (outcnt < SIZE)
- outbuf[outcnt++] = match[--stack];
- if (out(&outd, outbuf, outcnt)) {
- strm->next_in = outbuf; /* signal write error */
- return Z_BUF_ERROR;
- }
- outcnt = 0;
- }
- p = match + stack;
- do {
- outbuf[outcnt++] = *--p;
- } while (p > match);
- stack = 0;
-
- /* loop for next code with final and prev as the last match, rem and
- left provide the first 0..7 bits of the next code, end is the last
- valid table entry */
- }
-}
-
-/* Decompress a gzip file from infile to outfile. strm is assumed to have been
- successfully initialized with inflateBackInit(). The input file may consist
- of a series of gzip streams, in which case all of them will be decompressed
- to the output file. If outfile is -1, then the gzip stream(s) integrity is
- checked and nothing is written.
-
- The return value is a zlib error code: Z_MEM_ERROR if out of memory,
- Z_DATA_ERROR if the header or the compressed data is invalid, or if the
- trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends
- prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip
- stream) follows a valid gzip stream.
- */
-local int gunpipe(z_stream *strm, int infile, int outfile)
-{
- int ret, first, last;
- unsigned have, flags, len;
- z_const unsigned char *next = NULL;
- struct ind ind, *indp;
- struct outd outd;
-
- /* setup input buffer */
- ind.infile = infile;
- ind.inbuf = inbuf;
- indp = &ind;
-
- /* decompress concatenated gzip streams */
- have = 0; /* no input data read in yet */
- first = 1; /* looking for first gzip header */
- strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
- for (;;) {
- /* look for the two magic header bytes for a gzip stream */
- if (NEXT() == -1) {
- ret = Z_OK;
- break; /* empty gzip stream is ok */
- }
- if (last != 31 || (NEXT() != 139 && last != 157)) {
- strm->msg = (char *)"incorrect header check";
- ret = first ? Z_DATA_ERROR : Z_ERRNO;
- break; /* not a gzip or compress header */
- }
- first = 0; /* next non-header is junk */
-
- /* process a compress (LZW) file -- can't be concatenated after this */
- if (last == 157) {
- ret = lunpipe(have, next, indp, outfile, strm);
- break;
- }
-
- /* process remainder of gzip header */
- ret = Z_BUF_ERROR;
- if (NEXT() != 8) { /* only deflate method allowed */
- if (last == -1) break;
- strm->msg = (char *)"unknown compression method";
- ret = Z_DATA_ERROR;
- break;
- }
- flags = NEXT(); /* header flags */
- NEXT(); /* discard mod time, xflgs, os */
- NEXT();
- NEXT();
- NEXT();
- NEXT();
- NEXT();
- if (last == -1) break;
- if (flags & 0xe0) {
- strm->msg = (char *)"unknown header flags set";
- ret = Z_DATA_ERROR;
- break;
- }
- if (flags & 4) { /* extra field */
- len = NEXT();
- len += (unsigned)(NEXT()) << 8;
- if (last == -1) break;
- while (len > have) {
- len -= have;
- have = 0;
- if (NEXT() == -1) break;
- len--;
- }
- if (last == -1) break;
- have -= len;
- next += len;
- }
- if (flags & 8) /* file name */
- while (NEXT() != 0 && last != -1)
- ;
- if (flags & 16) /* comment */
- while (NEXT() != 0 && last != -1)
- ;
- if (flags & 2) { /* header crc */
- NEXT();
- NEXT();
- }
- if (last == -1) break;
-
- /* set up output */
- outd.outfile = outfile;
- outd.check = 1;
- outd.crc = crc32(0L, Z_NULL, 0);
- outd.total = 0;
-
- /* decompress data to output */
- strm->next_in = next;
- strm->avail_in = have;
- ret = inflateBack(strm, in, indp, out, &outd);
- if (ret != Z_STREAM_END) break;
- next = strm->next_in;
- have = strm->avail_in;
- strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
-
- /* check trailer */
- ret = Z_BUF_ERROR;
- if (NEXT() != (int)(outd.crc & 0xff) ||
- NEXT() != (int)((outd.crc >> 8) & 0xff) ||
- NEXT() != (int)((outd.crc >> 16) & 0xff) ||
- NEXT() != (int)((outd.crc >> 24) & 0xff)) {
- /* crc error */
- if (last != -1) {
- strm->msg = (char *)"incorrect data check";
- ret = Z_DATA_ERROR;
- }
- break;
- }
- if (NEXT() != (int)(outd.total & 0xff) ||
- NEXT() != (int)((outd.total >> 8) & 0xff) ||
- NEXT() != (int)((outd.total >> 16) & 0xff) ||
- NEXT() != (int)((outd.total >> 24) & 0xff)) {
- /* length error */
- if (last != -1) {
- strm->msg = (char *)"incorrect length check";
- ret = Z_DATA_ERROR;
- }
- break;
- }
-
- /* go back and look for another gzip stream */
- }
-
- /* clean up and return */
- return ret;
-}
-
-/* Copy file attributes, from -> to, as best we can. This is best effort, so
- no errors are reported. The mode bits, including suid, sgid, and the sticky
- bit are copied (if allowed), the owner's user id and group id are copied
- (again if allowed), and the access and modify times are copied. */
-local void copymeta(char *from, char *to)
-{
- struct stat was;
- struct utimbuf when;
-
- /* get all of from's Unix meta data, return if not a regular file */
- if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG)
- return;
-
- /* set to's mode bits, ignore errors */
- (void)chmod(to, was.st_mode & 07777);
-
- /* copy owner's user and group, ignore errors */
- (void)chown(to, was.st_uid, was.st_gid);
-
- /* copy access and modify times, ignore errors */
- when.actime = was.st_atime;
- when.modtime = was.st_mtime;
- (void)utime(to, &when);
-}
-
-/* Decompress the file inname to the file outnname, of if test is true, just
- decompress without writing and check the gzip trailer for integrity. If
- inname is NULL or an empty string, read from stdin. If outname is NULL or
- an empty string, write to stdout. strm is a pre-initialized inflateBack
- structure. When appropriate, copy the file attributes from inname to
- outname.
-
- gunzip() returns 1 if there is an out-of-memory error or an unexpected
- return code from gunpipe(). Otherwise it returns 0.
- */
-local int gunzip(z_stream *strm, char *inname, char *outname, int test)
-{
- int ret;
- int infile, outfile;
-
- /* open files */
- if (inname == NULL || *inname == 0) {
- inname = "-";
- infile = 0; /* stdin */
- }
- else {
- infile = open(inname, O_RDONLY, 0);
- if (infile == -1) {
- fprintf(stderr, "gun cannot open %s\n", inname);
- return 0;
- }
- }
- if (test)
- outfile = -1;
- else if (outname == NULL || *outname == 0) {
- outname = "-";
- outfile = 1; /* stdout */
- }
- else {
- outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666);
- if (outfile == -1) {
- close(infile);
- fprintf(stderr, "gun cannot create %s\n", outname);
- return 0;
- }
- }
- errno = 0;
-
- /* decompress */
- ret = gunpipe(strm, infile, outfile);
- if (outfile > 2) close(outfile);
- if (infile > 2) close(infile);
-
- /* interpret result */
- switch (ret) {
- case Z_OK:
- case Z_ERRNO:
- if (infile > 2 && outfile > 2) {
- copymeta(inname, outname); /* copy attributes */
- unlink(inname);
- }
- if (ret == Z_ERRNO)
- fprintf(stderr, "gun warning: trailing garbage ignored in %s\n",
- inname);
- break;
- case Z_DATA_ERROR:
- if (outfile > 2) unlink(outname);
- fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg);
- break;
- case Z_MEM_ERROR:
- if (outfile > 2) unlink(outname);
- fprintf(stderr, "gun out of memory error--aborting\n");
- return 1;
- case Z_BUF_ERROR:
- if (outfile > 2) unlink(outname);
- if (strm->next_in != Z_NULL) {
- fprintf(stderr, "gun write error on %s: %s\n",
- outname, strerror(errno));
- }
- else if (errno) {
- fprintf(stderr, "gun read error on %s: %s\n",
- inname, strerror(errno));
- }
- else {
- fprintf(stderr, "gun unexpected end of file on %s\n",
- inname);
- }
- break;
- default:
- if (outfile > 2) unlink(outname);
- fprintf(stderr, "gun internal error--aborting\n");
- return 1;
- }
- return 0;
-}
-
-/* Process the gun command line arguments. See the command syntax near the
- beginning of this source file. */
-int main(int argc, char **argv)
-{
- int ret, len, test;
- char *outname;
- unsigned char *window;
- z_stream strm;
-
- /* initialize inflateBack state for repeated use */
- window = match; /* reuse LZW match buffer */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- ret = inflateBackInit(&strm, 15, window);
- if (ret != Z_OK) {
- fprintf(stderr, "gun out of memory error--aborting\n");
- return 1;
- }
-
- /* decompress each file to the same name with the suffix removed */
- argc--;
- argv++;
- test = 0;
- if (argc && strcmp(*argv, "-h") == 0) {
- fprintf(stderr, "gun 1.6 (17 Jan 2010)\n");
- fprintf(stderr, "Copyright (C) 2003-2010 Mark Adler\n");
- fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n");
- return 0;
- }
- if (argc && strcmp(*argv, "-t") == 0) {
- test = 1;
- argc--;
- argv++;
- }
- if (argc)
- do {
- if (test)
- outname = NULL;
- else {
- len = (int)strlen(*argv);
- if (strcmp(*argv + len - 3, ".gz") == 0 ||
- strcmp(*argv + len - 3, "-gz") == 0)
- len -= 3;
- else if (strcmp(*argv + len - 2, ".z") == 0 ||
- strcmp(*argv + len - 2, "-z") == 0 ||
- strcmp(*argv + len - 2, "_z") == 0 ||
- strcmp(*argv + len - 2, ".Z") == 0)
- len -= 2;
- else {
- fprintf(stderr, "gun error: no gz type on %s--skipping\n",
- *argv);
- continue;
- }
- outname = malloc(len + 1);
- if (outname == NULL) {
- fprintf(stderr, "gun out of memory error--aborting\n");
- ret = 1;
- break;
- }
- memcpy(outname, *argv, len);
- outname[len] = 0;
- }
- ret = gunzip(&strm, *argv, outname, test);
- if (outname != NULL) free(outname);
- if (ret) break;
- } while (argv++, --argc);
- else
- ret = gunzip(&strm, NULL, NULL, test);
-
- /* clean up */
- inflateBackEnd(&strm);
- return ret;
-}
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzappend.c b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzappend.c
deleted file mode 100644
index 662dec3794..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzappend.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/* gzappend -- command to append to a gzip file
-
- Copyright (C) 2003, 2012 Mark Adler, all rights reserved
- version 1.2, 11 Oct 2012
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-/*
- * Change history:
- *
- * 1.0 19 Oct 2003 - First version
- * 1.1 4 Nov 2003 - Expand and clarify some comments and notes
- * - Add version and copyright to help
- * - Send help to stdout instead of stderr
- * - Add some preemptive typecasts
- * - Add L to constants in lseek() calls
- * - Remove some debugging information in error messages
- * - Use new data_type definition for zlib 1.2.1
- * - Simplfy and unify file operations
- * - Finish off gzip file in gztack()
- * - Use deflatePrime() instead of adding empty blocks
- * - Keep gzip file clean on appended file read errors
- * - Use in-place rotate instead of auxiliary buffer
- * (Why you ask? Because it was fun to write!)
- * 1.2 11 Oct 2012 - Fix for proper z_const usage
- * - Check for input buffer malloc failure
- */
-
-/*
- gzappend takes a gzip file and appends to it, compressing files from the
- command line or data from stdin. The gzip file is written to directly, to
- avoid copying that file, in case it's large. Note that this results in the
- unfriendly behavior that if gzappend fails, the gzip file is corrupted.
-
- This program was written to illustrate the use of the new Z_BLOCK option of
- zlib 1.2.x's inflate() function. This option returns from inflate() at each
- block boundary to facilitate locating and modifying the last block bit at
- the start of the final deflate block. Also whether using Z_BLOCK or not,
- another required feature of zlib 1.2.x is that inflate() now provides the
- number of unusued bits in the last input byte used. gzappend will not work
- with versions of zlib earlier than 1.2.1.
-
- gzappend first decompresses the gzip file internally, discarding all but
- the last 32K of uncompressed data, and noting the location of the last block
- bit and the number of unused bits in the last byte of the compressed data.
- The gzip trailer containing the CRC-32 and length of the uncompressed data
- is verified. This trailer will be later overwritten.
-
- Then the last block bit is cleared by seeking back in the file and rewriting
- the byte that contains it. Seeking forward, the last byte of the compressed
- data is saved along with the number of unused bits to initialize deflate.
-
- A deflate process is initialized, using the last 32K of the uncompressed
- data from the gzip file to initialize the dictionary. If the total
- uncompressed data was less than 32K, then all of it is used to initialize
- the dictionary. The deflate output bit buffer is also initialized with the
- last bits from the original deflate stream. From here on, the data to
- append is simply compressed using deflate, and written to the gzip file.
- When that is complete, the new CRC-32 and uncompressed length are written
- as the trailer of the gzip file.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "zlib.h"
-
-#define local static
-#define LGCHUNK 14
-#define CHUNK (1U << LGCHUNK)
-#define DSIZE 32768U
-
-/* print an error message and terminate with extreme prejudice */
-local void bye(char *msg1, char *msg2)
-{
- fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2);
- exit(1);
-}
-
-/* return the greatest common divisor of a and b using Euclid's algorithm,
- modified to be fast when one argument much greater than the other, and
- coded to avoid unnecessary swapping */
-local unsigned gcd(unsigned a, unsigned b)
-{
- unsigned c;
-
- while (a && b)
- if (a > b) {
- c = b;
- while (a - c >= c)
- c <<= 1;
- a -= c;
- }
- else {
- c = a;
- while (b - c >= c)
- c <<= 1;
- b -= c;
- }
- return a + b;
-}
-
-/* rotate list[0..len-1] left by rot positions, in place */
-local void rotate(unsigned char *list, unsigned len, unsigned rot)
-{
- unsigned char tmp;
- unsigned cycles;
- unsigned char *start, *last, *to, *from;
-
- /* normalize rot and handle degenerate cases */
- if (len < 2) return;
- if (rot >= len) rot %= len;
- if (rot == 0) return;
-
- /* pointer to last entry in list */
- last = list + (len - 1);
-
- /* do simple left shift by one */
- if (rot == 1) {
- tmp = *list;
- memcpy(list, list + 1, len - 1);
- *last = tmp;
- return;
- }
-
- /* do simple right shift by one */
- if (rot == len - 1) {
- tmp = *last;
- memmove(list + 1, list, len - 1);
- *list = tmp;
- return;
- }
-
- /* otherwise do rotate as a set of cycles in place */
- cycles = gcd(len, rot); /* number of cycles */
- do {
- start = from = list + cycles; /* start index is arbitrary */
- tmp = *from; /* save entry to be overwritten */
- for (;;) {
- to = from; /* next step in cycle */
- from += rot; /* go right rot positions */
- if (from > last) from -= len; /* (pointer better not wrap) */
- if (from == start) break; /* all but one shifted */
- *to = *from; /* shift left */
- }
- *to = tmp; /* complete the circle */
- } while (--cycles);
-}
-
-/* structure for gzip file read operations */
-typedef struct {
- int fd; /* file descriptor */
- int size; /* 1 << size is bytes in buf */
- unsigned left; /* bytes available at next */
- unsigned char *buf; /* buffer */
- z_const unsigned char *next; /* next byte in buffer */
- char *name; /* file name for error messages */
-} file;
-
-/* reload buffer */
-local int readin(file *in)
-{
- int len;
-
- len = read(in->fd, in->buf, 1 << in->size);
- if (len == -1) bye("error reading ", in->name);
- in->left = (unsigned)len;
- in->next = in->buf;
- return len;
-}
-
-/* read from file in, exit if end-of-file */
-local int readmore(file *in)
-{
- if (readin(in) == 0) bye("unexpected end of ", in->name);
- return 0;
-}
-
-#define read1(in) (in->left == 0 ? readmore(in) : 0, \
- in->left--, *(in->next)++)
-
-/* skip over n bytes of in */
-local void skip(file *in, unsigned n)
-{
- unsigned bypass;
-
- if (n > in->left) {
- n -= in->left;
- bypass = n & ~((1U << in->size) - 1);
- if (bypass) {
- if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1)
- bye("seeking ", in->name);
- n -= bypass;
- }
- readmore(in);
- if (n > in->left)
- bye("unexpected end of ", in->name);
- }
- in->left -= n;
- in->next += n;
-}
-
-/* read a four-byte unsigned integer, little-endian, from in */
-unsigned long read4(file *in)
-{
- unsigned long val;
-
- val = read1(in);
- val += (unsigned)read1(in) << 8;
- val += (unsigned long)read1(in) << 16;
- val += (unsigned long)read1(in) << 24;
- return val;
-}
-
-/* skip over gzip header */
-local void gzheader(file *in)
-{
- int flags;
- unsigned n;
-
- if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file");
- if (read1(in) != 8) bye("unknown compression method in", in->name);
- flags = read1(in);
- if (flags & 0xe0) bye("unknown header flags set in", in->name);
- skip(in, 6);
- if (flags & 4) {
- n = read1(in);
- n += (unsigned)(read1(in)) << 8;
- skip(in, n);
- }
- if (flags & 8) while (read1(in) != 0) ;
- if (flags & 16) while (read1(in) != 0) ;
- if (flags & 2) skip(in, 2);
-}
-
-/* decompress gzip file "name", return strm with a deflate stream ready to
- continue compression of the data in the gzip file, and return a file
- descriptor pointing to where to write the compressed data -- the deflate
- stream is initialized to compress using level "level" */
-local int gzscan(char *name, z_stream *strm, int level)
-{
- int ret, lastbit, left, full;
- unsigned have;
- unsigned long crc, tot;
- unsigned char *window;
- off_t lastoff, end;
- file gz;
-
- /* open gzip file */
- gz.name = name;
- gz.fd = open(name, O_RDWR, 0);
- if (gz.fd == -1) bye("cannot open ", name);
- gz.buf = malloc(CHUNK);
- if (gz.buf == NULL) bye("out of memory", "");
- gz.size = LGCHUNK;
- gz.left = 0;
-
- /* skip gzip header */
- gzheader(&gz);
-
- /* prepare to decompress */
- window = malloc(DSIZE);
- if (window == NULL) bye("out of memory", "");
- strm->zalloc = Z_NULL;
- strm->zfree = Z_NULL;
- strm->opaque = Z_NULL;
- ret = inflateInit2(strm, -15);
- if (ret != Z_OK) bye("out of memory", " or library mismatch");
-
- /* decompress the deflate stream, saving append information */
- lastbit = 0;
- lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
- left = 0;
- strm->avail_in = gz.left;
- strm->next_in = gz.next;
- crc = crc32(0L, Z_NULL, 0);
- have = full = 0;
- do {
- /* if needed, get more input */
- if (strm->avail_in == 0) {
- readmore(&gz);
- strm->avail_in = gz.left;
- strm->next_in = gz.next;
- }
-
- /* set up output to next available section of sliding window */
- strm->avail_out = DSIZE - have;
- strm->next_out = window + have;
-
- /* inflate and check for errors */
- ret = inflate(strm, Z_BLOCK);
- if (ret == Z_STREAM_ERROR) bye("internal stream error!", "");
- if (ret == Z_MEM_ERROR) bye("out of memory", "");
- if (ret == Z_DATA_ERROR)
- bye("invalid compressed data--format violated in", name);
-
- /* update crc and sliding window pointer */
- crc = crc32(crc, window + have, DSIZE - have - strm->avail_out);
- if (strm->avail_out)
- have = DSIZE - strm->avail_out;
- else {
- have = 0;
- full = 1;
- }
-
- /* process end of block */
- if (strm->data_type & 128) {
- if (strm->data_type & 64)
- left = strm->data_type & 0x1f;
- else {
- lastbit = strm->data_type & 0x1f;
- lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in;
- }
- }
- } while (ret != Z_STREAM_END);
- inflateEnd(strm);
- gz.left = strm->avail_in;
- gz.next = strm->next_in;
-
- /* save the location of the end of the compressed data */
- end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
-
- /* check gzip trailer and save total for deflate */
- if (crc != read4(&gz))
- bye("invalid compressed data--crc mismatch in ", name);
- tot = strm->total_out;
- if ((tot & 0xffffffffUL) != read4(&gz))
- bye("invalid compressed data--length mismatch in", name);
-
- /* if not at end of file, warn */
- if (gz.left || readin(&gz))
- fprintf(stderr,
- "gzappend warning: junk at end of gzip file overwritten\n");
-
- /* clear last block bit */
- lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET);
- if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
- *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7)));
- lseek(gz.fd, -1L, SEEK_CUR);
- if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name);
-
- /* if window wrapped, build dictionary from window by rotating */
- if (full) {
- rotate(window, DSIZE, have);
- have = DSIZE;
- }
-
- /* set up deflate stream with window, crc, total_in, and leftover bits */
- ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
- if (ret != Z_OK) bye("out of memory", "");
- deflateSetDictionary(strm, window, have);
- strm->adler = crc;
- strm->total_in = tot;
- if (left) {
- lseek(gz.fd, --end, SEEK_SET);
- if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
- deflatePrime(strm, 8 - left, *gz.buf);
- }
- lseek(gz.fd, end, SEEK_SET);
-
- /* clean up and return */
- free(window);
- free(gz.buf);
- return gz.fd;
-}
-
-/* append file "name" to gzip file gd using deflate stream strm -- if last
- is true, then finish off the deflate stream at the end */
-local void gztack(char *name, int gd, z_stream *strm, int last)
-{
- int fd, len, ret;
- unsigned left;
- unsigned char *in, *out;
-
- /* open file to compress and append */
- fd = 0;
- if (name != NULL) {
- fd = open(name, O_RDONLY, 0);
- if (fd == -1)
- fprintf(stderr, "gzappend warning: %s not found, skipping ...\n",
- name);
- }
-
- /* allocate buffers */
- in = malloc(CHUNK);
- out = malloc(CHUNK);
- if (in == NULL || out == NULL) bye("out of memory", "");
-
- /* compress input file and append to gzip file */
- do {
- /* get more input */
- len = read(fd, in, CHUNK);
- if (len == -1) {
- fprintf(stderr,
- "gzappend warning: error reading %s, skipping rest ...\n",
- name);
- len = 0;
- }
- strm->avail_in = (unsigned)len;
- strm->next_in = in;
- if (len) strm->adler = crc32(strm->adler, in, (unsigned)len);
-
- /* compress and write all available output */
- do {
- strm->avail_out = CHUNK;
- strm->next_out = out;
- ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH);
- left = CHUNK - strm->avail_out;
- while (left) {
- len = write(gd, out + CHUNK - strm->avail_out - left, left);
- if (len == -1) bye("writing gzip file", "");
- left -= (unsigned)len;
- }
- } while (strm->avail_out == 0 && ret != Z_STREAM_END);
- } while (len != 0);
-
- /* write trailer after last entry */
- if (last) {
- deflateEnd(strm);
- out[0] = (unsigned char)(strm->adler);
- out[1] = (unsigned char)(strm->adler >> 8);
- out[2] = (unsigned char)(strm->adler >> 16);
- out[3] = (unsigned char)(strm->adler >> 24);
- out[4] = (unsigned char)(strm->total_in);
- out[5] = (unsigned char)(strm->total_in >> 8);
- out[6] = (unsigned char)(strm->total_in >> 16);
- out[7] = (unsigned char)(strm->total_in >> 24);
- len = 8;
- do {
- ret = write(gd, out + 8 - len, len);
- if (ret == -1) bye("writing gzip file", "");
- len -= ret;
- } while (len);
- close(gd);
- }
-
- /* clean up and return */
- free(out);
- free(in);
- if (fd > 0) close(fd);
-}
-
-/* process the compression level option if present, scan the gzip file, and
- append the specified files, or append the data from stdin if no other file
- names are provided on the command line -- the gzip file must be writable
- and seekable */
-int main(int argc, char **argv)
-{
- int gd, level;
- z_stream strm;
-
- /* ignore command name */
- argc--; argv++;
-
- /* provide usage if no arguments */
- if (*argv == NULL) {
- printf(
- "gzappend 1.2 (11 Oct 2012) Copyright (C) 2003, 2012 Mark Adler\n"
- );
- printf(
- "usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n");
- return 0;
- }
-
- /* set compression level */
- level = Z_DEFAULT_COMPRESSION;
- if (argv[0][0] == '-') {
- if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0)
- bye("invalid compression level", "");
- level = argv[0][1] - '0';
- if (*++argv == NULL) bye("no gzip file name after options", "");
- }
-
- /* prepare to append to gzip file */
- gd = gzscan(*argv++, &strm, level);
-
- /* append files on command line, or from stdin if none */
- if (*argv == NULL)
- gztack(NULL, gd, &strm, 1);
- else
- do {
- gztack(*argv, gd, &strm, argv[1] == NULL);
- } while (*++argv != NULL);
- return 0;
-}
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzjoin.c b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzjoin.c
deleted file mode 100644
index 89e8098441..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzjoin.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/* gzjoin -- command to join gzip files into one gzip file
-
- Copyright (C) 2004, 2005, 2012 Mark Adler, all rights reserved
- version 1.2, 14 Aug 2012
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-/*
- * Change history:
- *
- * 1.0 11 Dec 2004 - First version
- * 1.1 12 Jun 2005 - Changed ssize_t to long for portability
- * 1.2 14 Aug 2012 - Clean up for z_const usage
- */
-
-/*
- gzjoin takes one or more gzip files on the command line and writes out a
- single gzip file that will uncompress to the concatenation of the
- uncompressed data from the individual gzip files. gzjoin does this without
- having to recompress any of the data and without having to calculate a new
- crc32 for the concatenated uncompressed data. gzjoin does however have to
- decompress all of the input data in order to find the bits in the compressed
- data that need to be modified to concatenate the streams.
-
- gzjoin does not do an integrity check on the input gzip files other than
- checking the gzip header and decompressing the compressed data. They are
- otherwise assumed to be complete and correct.
-
- Each joint between gzip files removes at least 18 bytes of previous trailer
- and subsequent header, and inserts an average of about three bytes to the
- compressed data in order to connect the streams. The output gzip file
- has a minimal ten-byte gzip header with no file name or modification time.
-
- This program was written to illustrate the use of the Z_BLOCK option of
- inflate() and the crc32_combine() function. gzjoin will not compile with
- versions of zlib earlier than 1.2.3.
- */
-
-#include <stdio.h> /* fputs(), fprintf(), fwrite(), putc() */
-#include <stdlib.h> /* exit(), malloc(), free() */
-#include <fcntl.h> /* open() */
-#include <unistd.h> /* close(), read(), lseek() */
-#include "zlib.h"
- /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */
-
-#define local static
-
-/* exit with an error (return a value to allow use in an expression) */
-local int bail(char *why1, char *why2)
-{
- fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2);
- exit(1);
- return 0;
-}
-
-/* -- simple buffered file input with access to the buffer -- */
-
-#define CHUNK 32768 /* must be a power of two and fit in unsigned */
-
-/* bin buffered input file type */
-typedef struct {
- char *name; /* name of file for error messages */
- int fd; /* file descriptor */
- unsigned left; /* bytes remaining at next */
- unsigned char *next; /* next byte to read */
- unsigned char *buf; /* allocated buffer of length CHUNK */
-} bin;
-
-/* close a buffered file and free allocated memory */
-local void bclose(bin *in)
-{
- if (in != NULL) {
- if (in->fd != -1)
- close(in->fd);
- if (in->buf != NULL)
- free(in->buf);
- free(in);
- }
-}
-
-/* open a buffered file for input, return a pointer to type bin, or NULL on
- failure */
-local bin *bopen(char *name)
-{
- bin *in;
-
- in = malloc(sizeof(bin));
- if (in == NULL)
- return NULL;
- in->buf = malloc(CHUNK);
- in->fd = open(name, O_RDONLY, 0);
- if (in->buf == NULL || in->fd == -1) {
- bclose(in);
- return NULL;
- }
- in->left = 0;
- in->next = in->buf;
- in->name = name;
- return in;
-}
-
-/* load buffer from file, return -1 on read error, 0 or 1 on success, with
- 1 indicating that end-of-file was reached */
-local int bload(bin *in)
-{
- long len;
-
- if (in == NULL)
- return -1;
- if (in->left != 0)
- return 0;
- in->next = in->buf;
- do {
- len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left);
- if (len < 0)
- return -1;
- in->left += (unsigned)len;
- } while (len != 0 && in->left < CHUNK);
- return len == 0 ? 1 : 0;
-}
-
-/* get a byte from the file, bail if end of file */
-#define bget(in) (in->left ? 0 : bload(in), \
- in->left ? (in->left--, *(in->next)++) : \
- bail("unexpected end of file on ", in->name))
-
-/* get a four-byte little-endian unsigned integer from file */
-local unsigned long bget4(bin *in)
-{
- unsigned long val;
-
- val = bget(in);
- val += (unsigned long)(bget(in)) << 8;
- val += (unsigned long)(bget(in)) << 16;
- val += (unsigned long)(bget(in)) << 24;
- return val;
-}
-
-/* skip bytes in file */
-local void bskip(bin *in, unsigned skip)
-{
- /* check pointer */
- if (in == NULL)
- return;
-
- /* easy case -- skip bytes in buffer */
- if (skip <= in->left) {
- in->left -= skip;
- in->next += skip;
- return;
- }
-
- /* skip what's in buffer, discard buffer contents */
- skip -= in->left;
- in->left = 0;
-
- /* seek past multiples of CHUNK bytes */
- if (skip > CHUNK) {
- unsigned left;
-
- left = skip & (CHUNK - 1);
- if (left == 0) {
- /* exact number of chunks: seek all the way minus one byte to check
- for end-of-file with a read */
- lseek(in->fd, skip - 1, SEEK_CUR);
- if (read(in->fd, in->buf, 1) != 1)
- bail("unexpected end of file on ", in->name);
- return;
- }
-
- /* skip the integral chunks, update skip with remainder */
- lseek(in->fd, skip - left, SEEK_CUR);
- skip = left;
- }
-
- /* read more input and skip remainder */
- bload(in);
- if (skip > in->left)
- bail("unexpected end of file on ", in->name);
- in->left -= skip;
- in->next += skip;
-}
-
-/* -- end of buffered input functions -- */
-
-/* skip the gzip header from file in */
-local void gzhead(bin *in)
-{
- int flags;
-
- /* verify gzip magic header and compression method */
- if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)
- bail(in->name, " is not a valid gzip file");
-
- /* get and verify flags */
- flags = bget(in);
- if ((flags & 0xe0) != 0)
- bail("unknown reserved bits set in ", in->name);
-
- /* skip modification time, extra flags, and os */
- bskip(in, 6);
-
- /* skip extra field if present */
- if (flags & 4) {
- unsigned len;
-
- len = bget(in);
- len += (unsigned)(bget(in)) << 8;
- bskip(in, len);
- }
-
- /* skip file name if present */
- if (flags & 8)
- while (bget(in) != 0)
- ;
-
- /* skip comment if present */
- if (flags & 16)
- while (bget(in) != 0)
- ;
-
- /* skip header crc if present */
- if (flags & 2)
- bskip(in, 2);
-}
-
-/* write a four-byte little-endian unsigned integer to out */
-local void put4(unsigned long val, FILE *out)
-{
- putc(val & 0xff, out);
- putc((val >> 8) & 0xff, out);
- putc((val >> 16) & 0xff, out);
- putc((val >> 24) & 0xff, out);
-}
-
-/* Load up zlib stream from buffered input, bail if end of file */
-local void zpull(z_streamp strm, bin *in)
-{
- if (in->left == 0)
- bload(in);
- if (in->left == 0)
- bail("unexpected end of file on ", in->name);
- strm->avail_in = in->left;
- strm->next_in = in->next;
-}
-
-/* Write header for gzip file to out and initialize trailer. */
-local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)
-{
- fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
- *crc = crc32(0L, Z_NULL, 0);
- *tot = 0;
-}
-
-/* Copy the compressed data from name, zeroing the last block bit of the last
- block if clr is true, and adding empty blocks as needed to get to a byte
- boundary. If clr is false, then the last block becomes the last block of
- the output, and the gzip trailer is written. crc and tot maintains the
- crc and length (modulo 2^32) of the output for the trailer. The resulting
- gzip file is written to out. gzinit() must be called before the first call
- of gzcopy() to write the gzip header and to initialize crc and tot. */
-local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
- FILE *out)
-{
- int ret; /* return value from zlib functions */
- int pos; /* where the "last block" bit is in byte */
- int last; /* true if processing the last block */
- bin *in; /* buffered input file */
- unsigned char *start; /* start of compressed data in buffer */
- unsigned char *junk; /* buffer for uncompressed data -- discarded */
- z_off_t len; /* length of uncompressed data (support > 4 GB) */
- z_stream strm; /* zlib inflate stream */
-
- /* open gzip file and skip header */
- in = bopen(name);
- if (in == NULL)
- bail("could not open ", name);
- gzhead(in);
-
- /* allocate buffer for uncompressed data and initialize raw inflate
- stream */
- junk = malloc(CHUNK);
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit2(&strm, -15);
- if (junk == NULL || ret != Z_OK)
- bail("out of memory", "");
-
- /* inflate and copy compressed data, clear last-block bit if requested */
- len = 0;
- zpull(&strm, in);
- start = in->next;
- last = start[0] & 1;
- if (last && clr)
- start[0] &= ~1;
- strm.avail_out = 0;
- for (;;) {
- /* if input used and output done, write used input and get more */
- if (strm.avail_in == 0 && strm.avail_out != 0) {
- fwrite(start, 1, strm.next_in - start, out);
- start = in->buf;
- in->left = 0;
- zpull(&strm, in);
- }
-
- /* decompress -- return early when end-of-block reached */
- strm.avail_out = CHUNK;
- strm.next_out = junk;
- ret = inflate(&strm, Z_BLOCK);
- switch (ret) {
- case Z_MEM_ERROR:
- bail("out of memory", "");
- case Z_DATA_ERROR:
- bail("invalid compressed data in ", in->name);
- }
-
- /* update length of uncompressed data */
- len += CHUNK - strm.avail_out;
-
- /* check for block boundary (only get this when block copied out) */
- if (strm.data_type & 128) {
- /* if that was the last block, then done */
- if (last)
- break;
-
- /* number of unused bits in last byte */
- pos = strm.data_type & 7;
-
- /* find the next last-block bit */
- if (pos != 0) {
- /* next last-block bit is in last used byte */
- pos = 0x100 >> pos;
- last = strm.next_in[-1] & pos;
- if (last && clr)
- in->buf[strm.next_in - in->buf - 1] &= ~pos;
- }
- else {
- /* next last-block bit is in next unused byte */
- if (strm.avail_in == 0) {
- /* don't have that byte yet -- get it */
- fwrite(start, 1, strm.next_in - start, out);
- start = in->buf;
- in->left = 0;
- zpull(&strm, in);
- }
- last = strm.next_in[0] & 1;
- if (last && clr)
- in->buf[strm.next_in - in->buf] &= ~1;
- }
- }
- }
-
- /* update buffer with unused input */
- in->left = strm.avail_in;
- in->next = in->buf + (strm.next_in - in->buf);
-
- /* copy used input, write empty blocks to get to byte boundary */
- pos = strm.data_type & 7;
- fwrite(start, 1, in->next - start - 1, out);
- last = in->next[-1];
- if (pos == 0 || !clr)
- /* already at byte boundary, or last file: write last byte */
- putc(last, out);
- else {
- /* append empty blocks to last byte */
- last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */
- if (pos & 1) {
- /* odd -- append an empty stored block */
- putc(last, out);
- if (pos == 1)
- putc(0, out); /* two more bits in block header */
- fwrite("\0\0\xff\xff", 1, 4, out);
- }
- else {
- /* even -- append 1, 2, or 3 empty fixed blocks */
- switch (pos) {
- case 6:
- putc(last | 8, out);
- last = 0;
- case 4:
- putc(last | 0x20, out);
- last = 0;
- case 2:
- putc(last | 0x80, out);
- putc(0, out);
- }
- }
- }
-
- /* update crc and tot */
- *crc = crc32_combine(*crc, bget4(in), len);
- *tot += (unsigned long)len;
-
- /* clean up */
- inflateEnd(&strm);
- free(junk);
- bclose(in);
-
- /* write trailer if this is the last gzip file */
- if (!clr) {
- put4(*crc, out);
- put4(*tot, out);
- }
-}
-
-/* join the gzip files on the command line, write result to stdout */
-int main(int argc, char **argv)
-{
- unsigned long crc, tot; /* running crc and total uncompressed length */
-
- /* skip command name */
- argc--;
- argv++;
-
- /* show usage if no arguments */
- if (argc == 0) {
- fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n",
- stderr);
- return 0;
- }
-
- /* join gzip files on command line and write to stdout */
- gzinit(&crc, &tot, stdout);
- while (argc--)
- gzcopy(*argv++, argc, &crc, &tot, stdout);
-
- /* done */
- return 0;
-}
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzlog.c b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzlog.c
deleted file mode 100644
index 922f878dde..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzlog.c
+++ /dev/null
@@ -1,1059 +0,0 @@
-/*
- * gzlog.c
- * Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved
- * For conditions of distribution and use, see copyright notice in gzlog.h
- * version 2.2, 14 Aug 2012
- */
-
-/*
- gzlog provides a mechanism for frequently appending short strings to a gzip
- file that is efficient both in execution time and compression ratio. The
- strategy is to write the short strings in an uncompressed form to the end of
- the gzip file, only compressing when the amount of uncompressed data has
- reached a given threshold.
-
- gzlog also provides protection against interruptions in the process due to
- system crashes. The status of the operation is recorded in an extra field
- in the gzip file, and is only updated once the gzip file is brought to a
- valid state. The last data to be appended or compressed is saved in an
- auxiliary file, so that if the operation is interrupted, it can be completed
- the next time an append operation is attempted.
-
- gzlog maintains another auxiliary file with the last 32K of data from the
- compressed portion, which is preloaded for the compression of the subsequent
- data. This minimizes the impact to the compression ratio of appending.
- */
-
-/*
- Operations Concept:
-
- Files (log name "foo"):
- foo.gz -- gzip file with the complete log
- foo.add -- last message to append or last data to compress
- foo.dict -- dictionary of the last 32K of data for next compression
- foo.temp -- temporary dictionary file for compression after this one
- foo.lock -- lock file for reading and writing the other files
- foo.repairs -- log file for log file recovery operations (not compressed)
-
- gzip file structure:
- - fixed-length (no file name) header with extra field (see below)
- - compressed data ending initially with empty stored block
- - uncompressed data filling out originally empty stored block and
- subsequent stored blocks as needed (16K max each)
- - gzip trailer
- - no junk at end (no other gzip streams)
-
- When appending data, the information in the first three items above plus the
- foo.add file are sufficient to recover an interrupted append operation. The
- extra field has the necessary information to restore the start of the last
- stored block and determine where to append the data in the foo.add file, as
- well as the crc and length of the gzip data before the append operation.
-
- The foo.add file is created before the gzip file is marked for append, and
- deleted after the gzip file is marked as complete. So if the append
- operation is interrupted, the data to add will still be there. If due to
- some external force, the foo.add file gets deleted between when the append
- operation was interrupted and when recovery is attempted, the gzip file will
- still be restored, but without the appended data.
-
- When compressing data, the information in the first two items above plus the
- foo.add file are sufficient to recover an interrupted compress operation.
- The extra field has the necessary information to find the end of the
- compressed data, and contains both the crc and length of just the compressed
- data and of the complete set of data including the contents of the foo.add
- file.
-
- Again, the foo.add file is maintained during the compress operation in case
- of an interruption. If in the unlikely event the foo.add file with the data
- to be compressed is missing due to some external force, a gzip file with
- just the previous compressed data will be reconstructed. In this case, all
- of the data that was to be compressed is lost (approximately one megabyte).
- This will not occur if all that happened was an interruption of the compress
- operation.
-
- The third state that is marked is the replacement of the old dictionary with
- the new dictionary after a compress operation. Once compression is
- complete, the gzip file is marked as being in the replace state. This
- completes the gzip file, so an interrupt after being so marked does not
- result in recompression. Then the dictionary file is replaced, and the gzip
- file is marked as completed. This state prevents the possibility of
- restarting compression with the wrong dictionary file.
-
- All three operations are wrapped by a lock/unlock procedure. In order to
- gain exclusive access to the log files, first a foo.lock file must be
- exclusively created. When all operations are complete, the lock is
- released by deleting the foo.lock file. If when attempting to create the
- lock file, it already exists and the modify time of the lock file is more
- than five minutes old (set by the PATIENCE define below), then the old
- lock file is considered stale and deleted, and the exclusive creation of
- the lock file is retried. To assure that there are no false assessments
- of the staleness of the lock file, the operations periodically touch the
- lock file to update the modified date.
-
- Following is the definition of the extra field with all of the information
- required to enable the above append and compress operations and their
- recovery if interrupted. Multi-byte values are stored little endian
- (consistent with the gzip format). File pointers are eight bytes long.
- The crc's and lengths for the gzip trailer are four bytes long. (Note that
- the length at the end of a gzip file is used for error checking only, and
- for large files is actually the length modulo 2^32.) The stored block
- length is two bytes long. The gzip extra field two-byte identification is
- "ap" for append. It is assumed that writing the extra field to the file is
- an "atomic" operation. That is, either all of the extra field is written
- to the file, or none of it is, if the operation is interrupted right at the
- point of updating the extra field. This is a reasonable assumption, since
- the extra field is within the first 52 bytes of the file, which is smaller
- than any expected block size for a mass storage device (usually 512 bytes or
- larger).
-
- Extra field (35 bytes):
- - Pointer to first stored block length -- this points to the two-byte length
- of the first stored block, which is followed by the two-byte, one's
- complement of that length. The stored block length is preceded by the
- three-bit header of the stored block, which is the actual start of the
- stored block in the deflate format. See the bit offset field below.
- - Pointer to the last stored block length. This is the same as above, but
- for the last stored block of the uncompressed data in the gzip file.
- Initially this is the same as the first stored block length pointer.
- When the stored block gets to 16K (see the MAX_STORE define), then a new
- stored block as added, at which point the last stored block length pointer
- is different from the first stored block length pointer. When they are
- different, the first bit of the last stored block header is eight bits, or
- one byte back from the block length.
- - Compressed data crc and length. This is the crc and length of the data
- that is in the compressed portion of the deflate stream. These are used
- only in the event that the foo.add file containing the data to compress is
- lost after a compress operation is interrupted.
- - Total data crc and length. This is the crc and length of all of the data
- stored in the gzip file, compressed and uncompressed. It is used to
- reconstruct the gzip trailer when compressing, as well as when recovering
- interrupted operations.
- - Final stored block length. This is used to quickly find where to append,
- and allows the restoration of the original final stored block state when
- an append operation is interrupted.
- - First stored block start as the number of bits back from the final stored
- block first length byte. This value is in the range of 3..10, and is
- stored as the low three bits of the final byte of the extra field after
- subtracting three (0..7). This allows the last-block bit of the stored
- block header to be updated when a new stored block is added, for the case
- when the first stored block and the last stored block are the same. (When
- they are different, the numbers of bits back is known to be eight.) This
- also allows for new compressed data to be appended to the old compressed
- data in the compress operation, overwriting the previous first stored
- block, or for the compressed data to be terminated and a valid gzip file
- reconstructed on the off chance that a compression operation was
- interrupted and the data to compress in the foo.add file was deleted.
- - The operation in process. This is the next two bits in the last byte (the
- bits under the mask 0x18). The are interpreted as 0: nothing in process,
- 1: append in process, 2: compress in process, 3: replace in process.
- - The top three bits of the last byte in the extra field are reserved and
- are currently set to zero.
-
- Main procedure:
- - Exclusively create the foo.lock file using the O_CREAT and O_EXCL modes of
- the system open() call. If the modify time of an existing lock file is
- more than PATIENCE seconds old, then the lock file is deleted and the
- exclusive create is retried.
- - Load the extra field from the foo.gz file, and see if an operation was in
- progress but not completed. If so, apply the recovery procedure below.
- - Perform the append procedure with the provided data.
- - If the uncompressed data in the foo.gz file is 1MB or more, apply the
- compress procedure.
- - Delete the foo.lock file.
-
- Append procedure:
- - Put what to append in the foo.add file so that the operation can be
- restarted if this procedure is interrupted.
- - Mark the foo.gz extra field with the append operation in progress.
- + Restore the original last-block bit and stored block length of the last
- stored block from the information in the extra field, in case a previous
- append operation was interrupted.
- - Append the provided data to the last stored block, creating new stored
- blocks as needed and updating the stored blocks last-block bits and
- lengths.
- - Update the crc and length with the new data, and write the gzip trailer.
- - Write over the extra field (with a single write operation) with the new
- pointers, lengths, and crc's, and mark the gzip file as not in process.
- Though there is still a foo.add file, it will be ignored since nothing
- is in process. If a foo.add file is leftover from a previously
- completed operation, it is truncated when writing new data to it.
- - Delete the foo.add file.
-
- Compress and replace procedures:
- - Read all of the uncompressed data in the stored blocks in foo.gz and write
- it to foo.add. Also write foo.temp with the last 32K of that data to
- provide a dictionary for the next invocation of this procedure.
- - Rewrite the extra field marking foo.gz with a compression in process.
- * If there is no data provided to compress (due to a missing foo.add file
- when recovering), reconstruct and truncate the foo.gz file to contain
- only the previous compressed data and proceed to the step after the next
- one. Otherwise ...
- - Compress the data with the dictionary in foo.dict, and write to the
- foo.gz file starting at the bit immediately following the last previously
- compressed block. If there is no foo.dict, proceed anyway with the
- compression at slightly reduced efficiency. (For the foo.dict file to be
- missing requires some external failure beyond simply the interruption of
- a compress operation.) During this process, the foo.lock file is
- periodically touched to assure that that file is not considered stale by
- another process before we're done. The deflation is terminated with a
- non-last empty static block (10 bits long), that is then located and
- written over by a last-bit-set empty stored block.
- - Append the crc and length of the data in the gzip file (previously
- calculated during the append operations).
- - Write over the extra field with the updated stored block offsets, bits
- back, crc's, and lengths, and mark foo.gz as in process for a replacement
- of the dictionary.
- @ Delete the foo.add file.
- - Replace foo.dict with foo.temp.
- - Write over the extra field, marking foo.gz as complete.
-
- Recovery procedure:
- - If not a replace recovery, read in the foo.add file, and provide that data
- to the appropriate recovery below. If there is no foo.add file, provide
- a zero data length to the recovery. In that case, the append recovery
- restores the foo.gz to the previous compressed + uncompressed data state.
- For the the compress recovery, a missing foo.add file results in foo.gz
- being restored to the previous compressed-only data state.
- - Append recovery:
- - Pick up append at + step above
- - Compress recovery:
- - Pick up compress at * step above
- - Replace recovery:
- - Pick up compress at @ step above
- - Log the repair with a date stamp in foo.repairs
- */
-
-#include <sys/types.h>
-#include <stdio.h> /* rename, fopen, fprintf, fclose */
-#include <stdlib.h> /* malloc, free */
-#include <string.h> /* strlen, strrchr, strcpy, strncpy, strcmp */
-#include <fcntl.h> /* open */
-#include <unistd.h> /* lseek, read, write, close, unlink, sleep, */
- /* ftruncate, fsync */
-#include <errno.h> /* errno */
-#include <time.h> /* time, ctime */
-#include <sys/stat.h> /* stat */
-#include <sys/time.h> /* utimes */
-#include "zlib.h" /* crc32 */
-
-#include "gzlog.h" /* header for external access */
-
-#define local static
-typedef unsigned int uint;
-typedef unsigned long ulong;
-
-/* Macro for debugging to deterministically force recovery operations */
-#ifdef DEBUG
- #include <setjmp.h> /* longjmp */
- jmp_buf gzlog_jump; /* where to go back to */
- int gzlog_bail = 0; /* which point to bail at (1..8) */
- int gzlog_count = -1; /* number of times through to wait */
-# define BAIL(n) do { if (n == gzlog_bail && gzlog_count-- == 0) \
- longjmp(gzlog_jump, gzlog_bail); } while (0)
-#else
-# define BAIL(n)
-#endif
-
-/* how old the lock file can be in seconds before considering it stale */
-#define PATIENCE 300
-
-/* maximum stored block size in Kbytes -- must be in 1..63 */
-#define MAX_STORE 16
-
-/* number of stored Kbytes to trigger compression (must be >= 32 to allow
- dictionary construction, and <= 204 * MAX_STORE, in order for >> 10 to
- discard the stored block headers contribution of five bytes each) */
-#define TRIGGER 1024
-
-/* size of a deflate dictionary (this cannot be changed) */
-#define DICT 32768U
-
-/* values for the operation (2 bits) */
-#define NO_OP 0
-#define APPEND_OP 1
-#define COMPRESS_OP 2
-#define REPLACE_OP 3
-
-/* macros to extract little-endian integers from an unsigned byte buffer */
-#define PULL2(p) ((p)[0]+((uint)((p)[1])<<8))
-#define PULL4(p) (PULL2(p)+((ulong)PULL2(p+2)<<16))
-#define PULL8(p) (PULL4(p)+((off_t)PULL4(p+4)<<32))
-
-/* macros to store integers into a byte buffer in little-endian order */
-#define PUT2(p,a) do {(p)[0]=a;(p)[1]=(a)>>8;} while(0)
-#define PUT4(p,a) do {PUT2(p,a);PUT2(p+2,a>>16);} while(0)
-#define PUT8(p,a) do {PUT4(p,a);PUT4(p+4,a>>32);} while(0)
-
-/* internal structure for log information */
-#define LOGID "\106\035\172" /* should be three non-zero characters */
-struct log {
- char id[4]; /* contains LOGID to detect inadvertent overwrites */
- int fd; /* file descriptor for .gz file, opened read/write */
- char *path; /* allocated path, e.g. "/var/log/foo" or "foo" */
- char *end; /* end of path, for appending suffices such as ".gz" */
- off_t first; /* offset of first stored block first length byte */
- int back; /* location of first block id in bits back from first */
- uint stored; /* bytes currently in last stored block */
- off_t last; /* offset of last stored block first length byte */
- ulong ccrc; /* crc of compressed data */
- ulong clen; /* length (modulo 2^32) of compressed data */
- ulong tcrc; /* crc of total data */
- ulong tlen; /* length (modulo 2^32) of total data */
- time_t lock; /* last modify time of our lock file */
-};
-
-/* gzip header for gzlog */
-local unsigned char log_gzhead[] = {
- 0x1f, 0x8b, /* magic gzip id */
- 8, /* compression method is deflate */
- 4, /* there is an extra field (no file name) */
- 0, 0, 0, 0, /* no modification time provided */
- 0, 0xff, /* no extra flags, no OS specified */
- 39, 0, 'a', 'p', 35, 0 /* extra field with "ap" subfield */
- /* 35 is EXTRA, 39 is EXTRA + 4 */
-};
-
-#define HEAD sizeof(log_gzhead) /* should be 16 */
-
-/* initial gzip extra field content (52 == HEAD + EXTRA + 1) */
-local unsigned char log_gzext[] = {
- 52, 0, 0, 0, 0, 0, 0, 0, /* offset of first stored block length */
- 52, 0, 0, 0, 0, 0, 0, 0, /* offset of last stored block length */
- 0, 0, 0, 0, 0, 0, 0, 0, /* compressed data crc and length */
- 0, 0, 0, 0, 0, 0, 0, 0, /* total data crc and length */
- 0, 0, /* final stored block data length */
- 5 /* op is NO_OP, last bit 8 bits back */
-};
-
-#define EXTRA sizeof(log_gzext) /* should be 35 */
-
-/* initial gzip data and trailer */
-local unsigned char log_gzbody[] = {
- 1, 0, 0, 0xff, 0xff, /* empty stored block (last) */
- 0, 0, 0, 0, /* crc */
- 0, 0, 0, 0 /* uncompressed length */
-};
-
-#define BODY sizeof(log_gzbody)
-
-/* Exclusively create foo.lock in order to negotiate exclusive access to the
- foo.* files. If the modify time of an existing lock file is greater than
- PATIENCE seconds in the past, then consider the lock file to have been
- abandoned, delete it, and try the exclusive create again. Save the lock
- file modify time for verification of ownership. Return 0 on success, or -1
- on failure, usually due to an access restriction or invalid path. Note that
- if stat() or unlink() fails, it may be due to another process noticing the
- abandoned lock file a smidge sooner and deleting it, so those are not
- flagged as an error. */
-local int log_lock(struct log *log)
-{
- int fd;
- struct stat st;
-
- strcpy(log->end, ".lock");
- while ((fd = open(log->path, O_CREAT | O_EXCL, 0644)) < 0) {
- if (errno != EEXIST)
- return -1;
- if (stat(log->path, &st) == 0 && time(NULL) - st.st_mtime > PATIENCE) {
- unlink(log->path);
- continue;
- }
- sleep(2); /* relinquish the CPU for two seconds while waiting */
- }
- close(fd);
- if (stat(log->path, &st) == 0)
- log->lock = st.st_mtime;
- return 0;
-}
-
-/* Update the modify time of the lock file to now, in order to prevent another
- task from thinking that the lock is stale. Save the lock file modify time
- for verification of ownership. */
-local void log_touch(struct log *log)
-{
- struct stat st;
-
- strcpy(log->end, ".lock");
- utimes(log->path, NULL);
- if (stat(log->path, &st) == 0)
- log->lock = st.st_mtime;
-}
-
-/* Check the log file modify time against what is expected. Return true if
- this is not our lock. If it is our lock, touch it to keep it. */
-local int log_check(struct log *log)
-{
- struct stat st;
-
- strcpy(log->end, ".lock");
- if (stat(log->path, &st) || st.st_mtime != log->lock)
- return 1;
- log_touch(log);
- return 0;
-}
-
-/* Unlock a previously acquired lock, but only if it's ours. */
-local void log_unlock(struct log *log)
-{
- if (log_check(log))
- return;
- strcpy(log->end, ".lock");
- unlink(log->path);
- log->lock = 0;
-}
-
-/* Check the gzip header and read in the extra field, filling in the values in
- the log structure. Return op on success or -1 if the gzip header was not as
- expected. op is the current operation in progress last written to the extra
- field. This assumes that the gzip file has already been opened, with the
- file descriptor log->fd. */
-local int log_head(struct log *log)
-{
- int op;
- unsigned char buf[HEAD + EXTRA];
-
- if (lseek(log->fd, 0, SEEK_SET) < 0 ||
- read(log->fd, buf, HEAD + EXTRA) != HEAD + EXTRA ||
- memcmp(buf, log_gzhead, HEAD)) {
- return -1;
- }
- log->first = PULL8(buf + HEAD);
- log->last = PULL8(buf + HEAD + 8);
- log->ccrc = PULL4(buf + HEAD + 16);
- log->clen = PULL4(buf + HEAD + 20);
- log->tcrc = PULL4(buf + HEAD + 24);
- log->tlen = PULL4(buf + HEAD + 28);
- log->stored = PULL2(buf + HEAD + 32);
- log->back = 3 + (buf[HEAD + 34] & 7);
- op = (buf[HEAD + 34] >> 3) & 3;
- return op;
-}
-
-/* Write over the extra field contents, marking the operation as op. Use fsync
- to assure that the device is written to, and in the requested order. This
- operation, and only this operation, is assumed to be atomic in order to
- assure that the log is recoverable in the event of an interruption at any
- point in the process. Return -1 if the write to foo.gz failed. */
-local int log_mark(struct log *log, int op)
-{
- int ret;
- unsigned char ext[EXTRA];
-
- PUT8(ext, log->first);
- PUT8(ext + 8, log->last);
- PUT4(ext + 16, log->ccrc);
- PUT4(ext + 20, log->clen);
- PUT4(ext + 24, log->tcrc);
- PUT4(ext + 28, log->tlen);
- PUT2(ext + 32, log->stored);
- ext[34] = log->back - 3 + (op << 3);
- fsync(log->fd);
- ret = lseek(log->fd, HEAD, SEEK_SET) < 0 ||
- write(log->fd, ext, EXTRA) != EXTRA ? -1 : 0;
- fsync(log->fd);
- return ret;
-}
-
-/* Rewrite the last block header bits and subsequent zero bits to get to a byte
- boundary, setting the last block bit if last is true, and then write the
- remainder of the stored block header (length and one's complement). Leave
- the file pointer after the end of the last stored block data. Return -1 if
- there is a read or write failure on the foo.gz file */
-local int log_last(struct log *log, int last)
-{
- int back, len, mask;
- unsigned char buf[6];
-
- /* determine the locations of the bytes and bits to modify */
- back = log->last == log->first ? log->back : 8;
- len = back > 8 ? 2 : 1; /* bytes back from log->last */
- mask = 0x80 >> ((back - 1) & 7); /* mask for block last-bit */
-
- /* get the byte to modify (one or two back) into buf[0] -- don't need to
- read the byte if the last-bit is eight bits back, since in that case
- the entire byte will be modified */
- buf[0] = 0;
- if (back != 8 && (lseek(log->fd, log->last - len, SEEK_SET) < 0 ||
- read(log->fd, buf, 1) != 1))
- return -1;
-
- /* change the last-bit of the last stored block as requested -- note
- that all bits above the last-bit are set to zero, per the type bits
- of a stored block being 00 and per the convention that the bits to
- bring the stream to a byte boundary are also zeros */
- buf[1] = 0;
- buf[2 - len] = (*buf & (mask - 1)) + (last ? mask : 0);
-
- /* write the modified stored block header and lengths, move the file
- pointer to after the last stored block data */
- PUT2(buf + 2, log->stored);
- PUT2(buf + 4, log->stored ^ 0xffff);
- return lseek(log->fd, log->last - len, SEEK_SET) < 0 ||
- write(log->fd, buf + 2 - len, len + 4) != len + 4 ||
- lseek(log->fd, log->stored, SEEK_CUR) < 0 ? -1 : 0;
-}
-
-/* Append len bytes from data to the locked and open log file. len may be zero
- if recovering and no .add file was found. In that case, the previous state
- of the foo.gz file is restored. The data is appended uncompressed in
- deflate stored blocks. Return -1 if there was an error reading or writing
- the foo.gz file. */
-local int log_append(struct log *log, unsigned char *data, size_t len)
-{
- uint put;
- off_t end;
- unsigned char buf[8];
-
- /* set the last block last-bit and length, in case recovering an
- interrupted append, then position the file pointer to append to the
- block */
- if (log_last(log, 1))
- return -1;
-
- /* append, adding stored blocks and updating the offset of the last stored
- block as needed, and update the total crc and length */
- while (len) {
- /* append as much as we can to the last block */
- put = (MAX_STORE << 10) - log->stored;
- if (put > len)
- put = (uint)len;
- if (put) {
- if (write(log->fd, data, put) != put)
- return -1;
- BAIL(1);
- log->tcrc = crc32(log->tcrc, data, put);
- log->tlen += put;
- log->stored += put;
- data += put;
- len -= put;
- }
-
- /* if we need to, add a new empty stored block */
- if (len) {
- /* mark current block as not last */
- if (log_last(log, 0))
- return -1;
-
- /* point to new, empty stored block */
- log->last += 4 + log->stored + 1;
- log->stored = 0;
- }
-
- /* mark last block as last, update its length */
- if (log_last(log, 1))
- return -1;
- BAIL(2);
- }
-
- /* write the new crc and length trailer, and truncate just in case (could
- be recovering from partial append with a missing foo.add file) */
- PUT4(buf, log->tcrc);
- PUT4(buf + 4, log->tlen);
- if (write(log->fd, buf, 8) != 8 ||
- (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))
- return -1;
-
- /* write the extra field, marking the log file as done, delete .add file */
- if (log_mark(log, NO_OP))
- return -1;
- strcpy(log->end, ".add");
- unlink(log->path); /* ignore error, since may not exist */
- return 0;
-}
-
-/* Replace the foo.dict file with the foo.temp file. Also delete the foo.add
- file, since the compress operation may have been interrupted before that was
- done. Returns 1 if memory could not be allocated, or -1 if reading or
- writing foo.gz fails, or if the rename fails for some reason other than
- foo.temp not existing. foo.temp not existing is a permitted error, since
- the replace operation may have been interrupted after the rename is done,
- but before foo.gz is marked as complete. */
-local int log_replace(struct log *log)
-{
- int ret;
- char *dest;
-
- /* delete foo.add file */
- strcpy(log->end, ".add");
- unlink(log->path); /* ignore error, since may not exist */
- BAIL(3);
-
- /* rename foo.name to foo.dict, replacing foo.dict if it exists */
- strcpy(log->end, ".dict");
- dest = malloc(strlen(log->path) + 1);
- if (dest == NULL)
- return -2;
- strcpy(dest, log->path);
- strcpy(log->end, ".temp");
- ret = rename(log->path, dest);
- free(dest);
- if (ret && errno != ENOENT)
- return -1;
- BAIL(4);
-
- /* mark the foo.gz file as done */
- return log_mark(log, NO_OP);
-}
-
-/* Compress the len bytes at data and append the compressed data to the
- foo.gz deflate data immediately after the previous compressed data. This
- overwrites the previous uncompressed data, which was stored in foo.add
- and is the data provided in data[0..len-1]. If this operation is
- interrupted, it picks up at the start of this routine, with the foo.add
- file read in again. If there is no data to compress (len == 0), then we
- simply terminate the foo.gz file after the previously compressed data,
- appending a final empty stored block and the gzip trailer. Return -1 if
- reading or writing the log.gz file failed, or -2 if there was a memory
- allocation failure. */
-local int log_compress(struct log *log, unsigned char *data, size_t len)
-{
- int fd;
- uint got, max;
- ssize_t dict;
- off_t end;
- z_stream strm;
- unsigned char buf[DICT];
-
- /* compress and append compressed data */
- if (len) {
- /* set up for deflate, allocating memory */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8,
- Z_DEFAULT_STRATEGY) != Z_OK)
- return -2;
-
- /* read in dictionary (last 32K of data that was compressed) */
- strcpy(log->end, ".dict");
- fd = open(log->path, O_RDONLY, 0);
- if (fd >= 0) {
- dict = read(fd, buf, DICT);
- close(fd);
- if (dict < 0) {
- deflateEnd(&strm);
- return -1;
- }
- if (dict)
- deflateSetDictionary(&strm, buf, (uint)dict);
- }
- log_touch(log);
-
- /* prime deflate with last bits of previous block, position write
- pointer to write those bits and overwrite what follows */
- if (lseek(log->fd, log->first - (log->back > 8 ? 2 : 1),
- SEEK_SET) < 0 ||
- read(log->fd, buf, 1) != 1 || lseek(log->fd, -1, SEEK_CUR) < 0) {
- deflateEnd(&strm);
- return -1;
- }
- deflatePrime(&strm, (8 - log->back) & 7, *buf);
-
- /* compress, finishing with a partial non-last empty static block */
- strm.next_in = data;
- max = (((uint)0 - 1) >> 1) + 1; /* in case int smaller than size_t */
- do {
- strm.avail_in = len > max ? max : (uint)len;
- len -= strm.avail_in;
- do {
- strm.avail_out = DICT;
- strm.next_out = buf;
- deflate(&strm, len ? Z_NO_FLUSH : Z_PARTIAL_FLUSH);
- got = DICT - strm.avail_out;
- if (got && write(log->fd, buf, got) != got) {
- deflateEnd(&strm);
- return -1;
- }
- log_touch(log);
- } while (strm.avail_out == 0);
- } while (len);
- deflateEnd(&strm);
- BAIL(5);
-
- /* find start of empty static block -- scanning backwards the first one
- bit is the second bit of the block, if the last byte is zero, then
- we know the byte before that has a one in the top bit, since an
- empty static block is ten bits long */
- if ((log->first = lseek(log->fd, -1, SEEK_CUR)) < 0 ||
- read(log->fd, buf, 1) != 1)
- return -1;
- log->first++;
- if (*buf) {
- log->back = 1;
- while ((*buf & ((uint)1 << (8 - log->back++))) == 0)
- ; /* guaranteed to terminate, since *buf != 0 */
- }
- else
- log->back = 10;
-
- /* update compressed crc and length */
- log->ccrc = log->tcrc;
- log->clen = log->tlen;
- }
- else {
- /* no data to compress -- fix up existing gzip stream */
- log->tcrc = log->ccrc;
- log->tlen = log->clen;
- }
-
- /* complete and truncate gzip stream */
- log->last = log->first;
- log->stored = 0;
- PUT4(buf, log->tcrc);
- PUT4(buf + 4, log->tlen);
- if (log_last(log, 1) || write(log->fd, buf, 8) != 8 ||
- (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))
- return -1;
- BAIL(6);
-
- /* mark as being in the replace operation */
- if (log_mark(log, REPLACE_OP))
- return -1;
-
- /* execute the replace operation and mark the file as done */
- return log_replace(log);
-}
-
-/* log a repair record to the .repairs file */
-local void log_log(struct log *log, int op, char *record)
-{
- time_t now;
- FILE *rec;
-
- now = time(NULL);
- strcpy(log->end, ".repairs");
- rec = fopen(log->path, "a");
- if (rec == NULL)
- return;
- fprintf(rec, "%.24s %s recovery: %s\n", ctime(&now), op == APPEND_OP ?
- "append" : (op == COMPRESS_OP ? "compress" : "replace"), record);
- fclose(rec);
- return;
-}
-
-/* Recover the interrupted operation op. First read foo.add for recovering an
- append or compress operation. Return -1 if there was an error reading or
- writing foo.gz or reading an existing foo.add, or -2 if there was a memory
- allocation failure. */
-local int log_recover(struct log *log, int op)
-{
- int fd, ret = 0;
- unsigned char *data = NULL;
- size_t len = 0;
- struct stat st;
-
- /* log recovery */
- log_log(log, op, "start");
-
- /* load foo.add file if expected and present */
- if (op == APPEND_OP || op == COMPRESS_OP) {
- strcpy(log->end, ".add");
- if (stat(log->path, &st) == 0 && st.st_size) {
- len = (size_t)(st.st_size);
- if ((off_t)len != st.st_size ||
- (data = malloc(st.st_size)) == NULL) {
- log_log(log, op, "allocation failure");
- return -2;
- }
- if ((fd = open(log->path, O_RDONLY, 0)) < 0) {
- log_log(log, op, ".add file read failure");
- return -1;
- }
- ret = (size_t)read(fd, data, len) != len;
- close(fd);
- if (ret) {
- log_log(log, op, ".add file read failure");
- return -1;
- }
- log_log(log, op, "loaded .add file");
- }
- else
- log_log(log, op, "missing .add file!");
- }
-
- /* recover the interrupted operation */
- switch (op) {
- case APPEND_OP:
- ret = log_append(log, data, len);
- break;
- case COMPRESS_OP:
- ret = log_compress(log, data, len);
- break;
- case REPLACE_OP:
- ret = log_replace(log);
- }
-
- /* log status */
- log_log(log, op, ret ? "failure" : "complete");
-
- /* clean up */
- if (data != NULL)
- free(data);
- return ret;
-}
-
-/* Close the foo.gz file (if open) and release the lock. */
-local void log_close(struct log *log)
-{
- if (log->fd >= 0)
- close(log->fd);
- log->fd = -1;
- log_unlock(log);
-}
-
-/* Open foo.gz, verify the header, and load the extra field contents, after
- first creating the foo.lock file to gain exclusive access to the foo.*
- files. If foo.gz does not exist or is empty, then write the initial header,
- extra, and body content of an empty foo.gz log file. If there is an error
- creating the lock file due to access restrictions, or an error reading or
- writing the foo.gz file, or if the foo.gz file is not a proper log file for
- this object (e.g. not a gzip file or does not contain the expected extra
- field), then return true. If there is an error, the lock is released.
- Otherwise, the lock is left in place. */
-local int log_open(struct log *log)
-{
- int op;
-
- /* release open file resource if left over -- can occur if lock lost
- between gzlog_open() and gzlog_write() */
- if (log->fd >= 0)
- close(log->fd);
- log->fd = -1;
-
- /* negotiate exclusive access */
- if (log_lock(log) < 0)
- return -1;
-
- /* open the log file, foo.gz */
- strcpy(log->end, ".gz");
- log->fd = open(log->path, O_RDWR | O_CREAT, 0644);
- if (log->fd < 0) {
- log_close(log);
- return -1;
- }
-
- /* if new, initialize foo.gz with an empty log, delete old dictionary */
- if (lseek(log->fd, 0, SEEK_END) == 0) {
- if (write(log->fd, log_gzhead, HEAD) != HEAD ||
- write(log->fd, log_gzext, EXTRA) != EXTRA ||
- write(log->fd, log_gzbody, BODY) != BODY) {
- log_close(log);
- return -1;
- }
- strcpy(log->end, ".dict");
- unlink(log->path);
- }
-
- /* verify log file and load extra field information */
- if ((op = log_head(log)) < 0) {
- log_close(log);
- return -1;
- }
-
- /* check for interrupted process and if so, recover */
- if (op != NO_OP && log_recover(log, op)) {
- log_close(log);
- return -1;
- }
-
- /* touch the lock file to prevent another process from grabbing it */
- log_touch(log);
- return 0;
-}
-
-/* See gzlog.h for the description of the external methods below */
-gzlog *gzlog_open(char *path)
-{
- size_t n;
- struct log *log;
-
- /* check arguments */
- if (path == NULL || *path == 0)
- return NULL;
-
- /* allocate and initialize log structure */
- log = malloc(sizeof(struct log));
- if (log == NULL)
- return NULL;
- strcpy(log->id, LOGID);
- log->fd = -1;
-
- /* save path and end of path for name construction */
- n = strlen(path);
- log->path = malloc(n + 9); /* allow for ".repairs" */
- if (log->path == NULL) {
- free(log);
- return NULL;
- }
- strcpy(log->path, path);
- log->end = log->path + n;
-
- /* gain exclusive access and verify log file -- may perform a
- recovery operation if needed */
- if (log_open(log)) {
- free(log->path);
- free(log);
- return NULL;
- }
-
- /* return pointer to log structure */
- return log;
-}
-
-/* gzlog_compress() return values:
- 0: all good
- -1: file i/o error (usually access issue)
- -2: memory allocation failure
- -3: invalid log pointer argument */
-int gzlog_compress(gzlog *logd)
-{
- int fd, ret;
- uint block;
- size_t len, next;
- unsigned char *data, buf[5];
- struct log *log = logd;
-
- /* check arguments */
- if (log == NULL || strcmp(log->id, LOGID))
- return -3;
-
- /* see if we lost the lock -- if so get it again and reload the extra
- field information (it probably changed), recover last operation if
- necessary */
- if (log_check(log) && log_open(log))
- return -1;
-
- /* create space for uncompressed data */
- len = ((size_t)(log->last - log->first) & ~(((size_t)1 << 10) - 1)) +
- log->stored;
- if ((data = malloc(len)) == NULL)
- return -2;
-
- /* do statement here is just a cheap trick for error handling */
- do {
- /* read in the uncompressed data */
- if (lseek(log->fd, log->first - 1, SEEK_SET) < 0)
- break;
- next = 0;
- while (next < len) {
- if (read(log->fd, buf, 5) != 5)
- break;
- block = PULL2(buf + 1);
- if (next + block > len ||
- read(log->fd, (char *)data + next, block) != block)
- break;
- next += block;
- }
- if (lseek(log->fd, 0, SEEK_CUR) != log->last + 4 + log->stored)
- break;
- log_touch(log);
-
- /* write the uncompressed data to the .add file */
- strcpy(log->end, ".add");
- fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (fd < 0)
- break;
- ret = (size_t)write(fd, data, len) != len;
- if (ret | close(fd))
- break;
- log_touch(log);
-
- /* write the dictionary for the next compress to the .temp file */
- strcpy(log->end, ".temp");
- fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (fd < 0)
- break;
- next = DICT > len ? len : DICT;
- ret = (size_t)write(fd, (char *)data + len - next, next) != next;
- if (ret | close(fd))
- break;
- log_touch(log);
-
- /* roll back to compressed data, mark the compress in progress */
- log->last = log->first;
- log->stored = 0;
- if (log_mark(log, COMPRESS_OP))
- break;
- BAIL(7);
-
- /* compress and append the data (clears mark) */
- ret = log_compress(log, data, len);
- free(data);
- return ret;
- } while (0);
-
- /* broke out of do above on i/o error */
- free(data);
- return -1;
-}
-
-/* gzlog_write() return values:
- 0: all good
- -1: file i/o error (usually access issue)
- -2: memory allocation failure
- -3: invalid log pointer argument */
-int gzlog_write(gzlog *logd, void *data, size_t len)
-{
- int fd, ret;
- struct log *log = logd;
-
- /* check arguments */
- if (log == NULL || strcmp(log->id, LOGID))
- return -3;
- if (data == NULL || len <= 0)
- return 0;
-
- /* see if we lost the lock -- if so get it again and reload the extra
- field information (it probably changed), recover last operation if
- necessary */
- if (log_check(log) && log_open(log))
- return -1;
-
- /* create and write .add file */
- strcpy(log->end, ".add");
- fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (fd < 0)
- return -1;
- ret = (size_t)write(fd, data, len) != len;
- if (ret | close(fd))
- return -1;
- log_touch(log);
-
- /* mark log file with append in progress */
- if (log_mark(log, APPEND_OP))
- return -1;
- BAIL(8);
-
- /* append data (clears mark) */
- if (log_append(log, data, len))
- return -1;
-
- /* check to see if it's time to compress -- if not, then done */
- if (((log->last - log->first) >> 10) + (log->stored >> 10) < TRIGGER)
- return 0;
-
- /* time to compress */
- return gzlog_compress(log);
-}
-
-/* gzlog_close() return values:
- 0: ok
- -3: invalid log pointer argument */
-int gzlog_close(gzlog *logd)
-{
- struct log *log = logd;
-
- /* check arguments */
- if (log == NULL || strcmp(log->id, LOGID))
- return -3;
-
- /* close the log file and release the lock */
- log_close(log);
-
- /* free structure and return */
- if (log->path != NULL)
- free(log->path);
- strcpy(log->id, "bad");
- free(log);
- return 0;
-}
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzlog.h b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzlog.h
deleted file mode 100644
index 86f0cecba5..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/gzlog.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* gzlog.h
- Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved
- version 2.2, 14 Aug 2012
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Mark Adler madler@alumni.caltech.edu
- */
-
-/* Version History:
- 1.0 26 Nov 2004 First version
- 2.0 25 Apr 2008 Complete redesign for recovery of interrupted operations
- Interface changed slightly in that now path is a prefix
- Compression now occurs as needed during gzlog_write()
- gzlog_write() now always leaves the log file as valid gzip
- 2.1 8 Jul 2012 Fix argument checks in gzlog_compress() and gzlog_write()
- 2.2 14 Aug 2012 Clean up signed comparisons
- */
-
-/*
- The gzlog object allows writing short messages to a gzipped log file,
- opening the log file locked for small bursts, and then closing it. The log
- object works by appending stored (uncompressed) data to the gzip file until
- 1 MB has been accumulated. At that time, the stored data is compressed, and
- replaces the uncompressed data in the file. The log file is truncated to
- its new size at that time. After each write operation, the log file is a
- valid gzip file that can decompressed to recover what was written.
-
- The gzlog operations can be interupted at any point due to an application or
- system crash, and the log file will be recovered the next time the log is
- opened with gzlog_open().
- */
-
-#ifndef GZLOG_H
-#define GZLOG_H
-
-/* gzlog object type */
-typedef void gzlog;
-
-/* Open a gzlog object, creating the log file if it does not exist. Return
- NULL on error. Note that gzlog_open() could take a while to complete if it
- has to wait to verify that a lock is stale (possibly for five minutes), or
- if there is significant contention with other instantiations of this object
- when locking the resource. path is the prefix of the file names created by
- this object. If path is "foo", then the log file will be "foo.gz", and
- other auxiliary files will be created and destroyed during the process:
- "foo.dict" for a compression dictionary, "foo.temp" for a temporary (next)
- dictionary, "foo.add" for data being added or compressed, "foo.lock" for the
- lock file, and "foo.repairs" to log recovery operations performed due to
- interrupted gzlog operations. A gzlog_open() followed by a gzlog_close()
- will recover a previously interrupted operation, if any. */
-gzlog *gzlog_open(char *path);
-
-/* Write to a gzlog object. Return zero on success, -1 if there is a file i/o
- error on any of the gzlog files (this should not happen if gzlog_open()
- succeeded, unless the device has run out of space or leftover auxiliary
- files have permissions or ownership that prevent their use), -2 if there is
- a memory allocation failure, or -3 if the log argument is invalid (e.g. if
- it was not created by gzlog_open()). This function will write data to the
- file uncompressed, until 1 MB has been accumulated, at which time that data
- will be compressed. The log file will be a valid gzip file upon successful
- return. */
-int gzlog_write(gzlog *log, void *data, size_t len);
-
-/* Force compression of any uncompressed data in the log. This should be used
- sparingly, if at all. The main application would be when a log file will
- not be appended to again. If this is used to compress frequently while
- appending, it will both significantly increase the execution time and
- reduce the compression ratio. The return codes are the same as for
- gzlog_write(). */
-int gzlog_compress(gzlog *log);
-
-/* Close a gzlog object. Return zero on success, -3 if the log argument is
- invalid. The log object is freed, and so cannot be referenced again. */
-int gzlog_close(gzlog *log);
-
-#endif
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zlib_how.html b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zlib_how.html
deleted file mode 100644
index 444ff1c9a3..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zlib_how.html
+++ /dev/null
@@ -1,545 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
- "http://www.w3.org/TR/REC-html40/loose.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<title>zlib Usage Example</title>
-<!-- Copyright (c) 2004, 2005 Mark Adler. -->
-</head>
-<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#00A000">
-<h2 align="center"> zlib Usage Example </h2>
-We often get questions about how the <tt>deflate()</tt> and <tt>inflate()</tt> functions should be used.
-Users wonder when they should provide more input, when they should use more output,
-what to do with a <tt>Z_BUF_ERROR</tt>, how to make sure the process terminates properly, and
-so on. So for those who have read <tt>zlib.h</tt> (a few times), and
-would like further edification, below is an annotated example in C of simple routines to compress and decompress
-from an input file to an output file using <tt>deflate()</tt> and <tt>inflate()</tt> respectively. The
-annotations are interspersed between lines of the code. So please read between the lines.
-We hope this helps explain some of the intricacies of <em>zlib</em>.
-<p>
-Without further adieu, here is the program <a href="zpipe.c"><tt>zpipe.c</tt></a>:
-<pre><b>
-/* zpipe.c: example of proper use of zlib's inflate() and deflate()
- Not copyrighted -- provided to the public domain
- Version 1.4 11 December 2005 Mark Adler */
-
-/* Version history:
- 1.0 30 Oct 2004 First version
- 1.1 8 Nov 2004 Add void casting for unused return values
- Use switch statement for inflate() return values
- 1.2 9 Nov 2004 Add assertions to document zlib guarantees
- 1.3 6 Apr 2005 Remove incorrect assertion in inf()
- 1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions
- Avoid some compiler warnings for input and output buffers
- */
-</b></pre><!-- -->
-We now include the header files for the required definitions. From
-<tt>stdio.h</tt> we use <tt>fopen()</tt>, <tt>fread()</tt>, <tt>fwrite()</tt>,
-<tt>feof()</tt>, <tt>ferror()</tt>, and <tt>fclose()</tt> for file i/o, and
-<tt>fputs()</tt> for error messages. From <tt>string.h</tt> we use
-<tt>strcmp()</tt> for command line argument processing.
-From <tt>assert.h</tt> we use the <tt>assert()</tt> macro.
-From <tt>zlib.h</tt>
-we use the basic compression functions <tt>deflateInit()</tt>,
-<tt>deflate()</tt>, and <tt>deflateEnd()</tt>, and the basic decompression
-functions <tt>inflateInit()</tt>, <tt>inflate()</tt>, and
-<tt>inflateEnd()</tt>.
-<pre><b>
-#include &lt;stdio.h&gt;
-#include &lt;string.h&gt;
-#include &lt;assert.h&gt;
-#include "zlib.h"
-</b></pre><!-- -->
-This is an ugly hack required to avoid corruption of the input and output data on
-Windows/MS-DOS systems. Without this, those systems would assume that the input and output
-files are text, and try to convert the end-of-line characters from one standard to
-another. That would corrupt binary data, and in particular would render the compressed data unusable.
-This sets the input and output to binary which suppresses the end-of-line conversions.
-<tt>SET_BINARY_MODE()</tt> will be used later on <tt>stdin</tt> and <tt>stdout</tt>, at the beginning of <tt>main()</tt>.
-<pre><b>
-#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
-# include &lt;fcntl.h&gt;
-# include &lt;io.h&gt;
-# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-</b></pre><!-- -->
-<tt>CHUNK</tt> is simply the buffer size for feeding data to and pulling data
-from the <em>zlib</em> routines. Larger buffer sizes would be more efficient,
-especially for <tt>inflate()</tt>. If the memory is available, buffers sizes
-on the order of 128K or 256K bytes should be used.
-<pre><b>
-#define CHUNK 16384
-</b></pre><!-- -->
-The <tt>def()</tt> routine compresses data from an input file to an output file. The output data
-will be in the <em>zlib</em> format, which is different from the <em>gzip</em> or <em>zip</em>
-formats. The <em>zlib</em> format has a very small header of only two bytes to identify it as
-a <em>zlib</em> stream and to provide decoding information, and a four-byte trailer with a fast
-check value to verify the integrity of the uncompressed data after decoding.
-<pre><b>
-/* Compress from file source to file dest until EOF on source.
- def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_STREAM_ERROR if an invalid compression
- level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
- version of the library linked do not match, or Z_ERRNO if there is
- an error reading or writing the files. */
-int def(FILE *source, FILE *dest, int level)
-{
-</b></pre>
-Here are the local variables for <tt>def()</tt>. <tt>ret</tt> will be used for <em>zlib</em>
-return codes. <tt>flush</tt> will keep track of the current flushing state for <tt>deflate()</tt>,
-which is either no flushing, or flush to completion after the end of the input file is reached.
-<tt>have</tt> is the amount of data returned from <tt>deflate()</tt>. The <tt>strm</tt> structure
-is used to pass information to and from the <em>zlib</em> routines, and to maintain the
-<tt>deflate()</tt> state. <tt>in</tt> and <tt>out</tt> are the input and output buffers for
-<tt>deflate()</tt>.
-<pre><b>
- int ret, flush;
- unsigned have;
- z_stream strm;
- unsigned char in[CHUNK];
- unsigned char out[CHUNK];
-</b></pre><!-- -->
-The first thing we do is to initialize the <em>zlib</em> state for compression using
-<tt>deflateInit()</tt>. This must be done before the first use of <tt>deflate()</tt>.
-The <tt>zalloc</tt>, <tt>zfree</tt>, and <tt>opaque</tt> fields in the <tt>strm</tt>
-structure must be initialized before calling <tt>deflateInit()</tt>. Here they are
-set to the <em>zlib</em> constant <tt>Z_NULL</tt> to request that <em>zlib</em> use
-the default memory allocation routines. An application may also choose to provide
-custom memory allocation routines here. <tt>deflateInit()</tt> will allocate on the
-order of 256K bytes for the internal state.
-(See <a href="zlib_tech.html"><em>zlib Technical Details</em></a>.)
-<p>
-<tt>deflateInit()</tt> is called with a pointer to the structure to be initialized and
-the compression level, which is an integer in the range of -1 to 9. Lower compression
-levels result in faster execution, but less compression. Higher levels result in
-greater compression, but slower execution. The <em>zlib</em> constant Z_DEFAULT_COMPRESSION,
-equal to -1,
-provides a good compromise between compression and speed and is equivalent to level 6.
-Level 0 actually does no compression at all, and in fact expands the data slightly to produce
-the <em>zlib</em> format (it is not a byte-for-byte copy of the input).
-More advanced applications of <em>zlib</em>
-may use <tt>deflateInit2()</tt> here instead. Such an application may want to reduce how
-much memory will be used, at some price in compression. Or it may need to request a
-<em>gzip</em> header and trailer instead of a <em>zlib</em> header and trailer, or raw
-encoding with no header or trailer at all.
-<p>
-We must check the return value of <tt>deflateInit()</tt> against the <em>zlib</em> constant
-<tt>Z_OK</tt> to make sure that it was able to
-allocate memory for the internal state, and that the provided arguments were valid.
-<tt>deflateInit()</tt> will also check that the version of <em>zlib</em> that the <tt>zlib.h</tt>
-file came from matches the version of <em>zlib</em> actually linked with the program. This
-is especially important for environments in which <em>zlib</em> is a shared library.
-<p>
-Note that an application can initialize multiple, independent <em>zlib</em> streams, which can
-operate in parallel. The state information maintained in the structure allows the <em>zlib</em>
-routines to be reentrant.
-<pre><b>
- /* allocate deflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- ret = deflateInit(&amp;strm, level);
- if (ret != Z_OK)
- return ret;
-</b></pre><!-- -->
-With the pleasantries out of the way, now we can get down to business. The outer <tt>do</tt>-loop
-reads all of the input file and exits at the bottom of the loop once end-of-file is reached.
-This loop contains the only call of <tt>deflate()</tt>. So we must make sure that all of the
-input data has been processed and that all of the output data has been generated and consumed
-before we fall out of the loop at the bottom.
-<pre><b>
- /* compress until end of file */
- do {
-</b></pre>
-We start off by reading data from the input file. The number of bytes read is put directly
-into <tt>avail_in</tt>, and a pointer to those bytes is put into <tt>next_in</tt>. We also
-check to see if end-of-file on the input has been reached. If we are at the end of file, then <tt>flush</tt> is set to the
-<em>zlib</em> constant <tt>Z_FINISH</tt>, which is later passed to <tt>deflate()</tt> to
-indicate that this is the last chunk of input data to compress. We need to use <tt>feof()</tt>
-to check for end-of-file as opposed to seeing if fewer than <tt>CHUNK</tt> bytes have been read. The
-reason is that if the input file length is an exact multiple of <tt>CHUNK</tt>, we will miss
-the fact that we got to the end-of-file, and not know to tell <tt>deflate()</tt> to finish
-up the compressed stream. If we are not yet at the end of the input, then the <em>zlib</em>
-constant <tt>Z_NO_FLUSH</tt> will be passed to <tt>deflate</tt> to indicate that we are still
-in the middle of the uncompressed data.
-<p>
-If there is an error in reading from the input file, the process is aborted with
-<tt>deflateEnd()</tt> being called to free the allocated <em>zlib</em> state before returning
-the error. We wouldn't want a memory leak, now would we? <tt>deflateEnd()</tt> can be called
-at any time after the state has been initialized. Once that's done, <tt>deflateInit()</tt> (or
-<tt>deflateInit2()</tt>) would have to be called to start a new compression process. There is
-no point here in checking the <tt>deflateEnd()</tt> return code. The deallocation can't fail.
-<pre><b>
- strm.avail_in = fread(in, 1, CHUNK, source);
- if (ferror(source)) {
- (void)deflateEnd(&amp;strm);
- return Z_ERRNO;
- }
- flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
- strm.next_in = in;
-</b></pre><!-- -->
-The inner <tt>do</tt>-loop passes our chunk of input data to <tt>deflate()</tt>, and then
-keeps calling <tt>deflate()</tt> until it is done producing output. Once there is no more
-new output, <tt>deflate()</tt> is guaranteed to have consumed all of the input, i.e.,
-<tt>avail_in</tt> will be zero.
-<pre><b>
- /* run deflate() on input until output buffer not full, finish
- compression if all of source has been read in */
- do {
-</b></pre>
-Output space is provided to <tt>deflate()</tt> by setting <tt>avail_out</tt> to the number
-of available output bytes and <tt>next_out</tt> to a pointer to that space.
-<pre><b>
- strm.avail_out = CHUNK;
- strm.next_out = out;
-</b></pre>
-Now we call the compression engine itself, <tt>deflate()</tt>. It takes as many of the
-<tt>avail_in</tt> bytes at <tt>next_in</tt> as it can process, and writes as many as
-<tt>avail_out</tt> bytes to <tt>next_out</tt>. Those counters and pointers are then
-updated past the input data consumed and the output data written. It is the amount of
-output space available that may limit how much input is consumed.
-Hence the inner loop to make sure that
-all of the input is consumed by providing more output space each time. Since <tt>avail_in</tt>
-and <tt>next_in</tt> are updated by <tt>deflate()</tt>, we don't have to mess with those
-between <tt>deflate()</tt> calls until it's all used up.
-<p>
-The parameters to <tt>deflate()</tt> are a pointer to the <tt>strm</tt> structure containing
-the input and output information and the internal compression engine state, and a parameter
-indicating whether and how to flush data to the output. Normally <tt>deflate</tt> will consume
-several K bytes of input data before producing any output (except for the header), in order
-to accumulate statistics on the data for optimum compression. It will then put out a burst of
-compressed data, and proceed to consume more input before the next burst. Eventually,
-<tt>deflate()</tt>
-must be told to terminate the stream, complete the compression with provided input data, and
-write out the trailer check value. <tt>deflate()</tt> will continue to compress normally as long
-as the flush parameter is <tt>Z_NO_FLUSH</tt>. Once the <tt>Z_FINISH</tt> parameter is provided,
-<tt>deflate()</tt> will begin to complete the compressed output stream. However depending on how
-much output space is provided, <tt>deflate()</tt> may have to be called several times until it
-has provided the complete compressed stream, even after it has consumed all of the input. The flush
-parameter must continue to be <tt>Z_FINISH</tt> for those subsequent calls.
-<p>
-There are other values of the flush parameter that are used in more advanced applications. You can
-force <tt>deflate()</tt> to produce a burst of output that encodes all of the input data provided
-so far, even if it wouldn't have otherwise, for example to control data latency on a link with
-compressed data. You can also ask that <tt>deflate()</tt> do that as well as erase any history up to
-that point so that what follows can be decompressed independently, for example for random access
-applications. Both requests will degrade compression by an amount depending on how often such
-requests are made.
-<p>
-<tt>deflate()</tt> has a return value that can indicate errors, yet we do not check it here. Why
-not? Well, it turns out that <tt>deflate()</tt> can do no wrong here. Let's go through
-<tt>deflate()</tt>'s return values and dispense with them one by one. The possible values are
-<tt>Z_OK</tt>, <tt>Z_STREAM_END</tt>, <tt>Z_STREAM_ERROR</tt>, or <tt>Z_BUF_ERROR</tt>. <tt>Z_OK</tt>
-is, well, ok. <tt>Z_STREAM_END</tt> is also ok and will be returned for the last call of
-<tt>deflate()</tt>. This is already guaranteed by calling <tt>deflate()</tt> with <tt>Z_FINISH</tt>
-until it has no more output. <tt>Z_STREAM_ERROR</tt> is only possible if the stream is not
-initialized properly, but we did initialize it properly. There is no harm in checking for
-<tt>Z_STREAM_ERROR</tt> here, for example to check for the possibility that some
-other part of the application inadvertently clobbered the memory containing the <em>zlib</em> state.
-<tt>Z_BUF_ERROR</tt> will be explained further below, but
-suffice it to say that this is simply an indication that <tt>deflate()</tt> could not consume
-more input or produce more output. <tt>deflate()</tt> can be called again with more output space
-or more available input, which it will be in this code.
-<pre><b>
- ret = deflate(&amp;strm, flush); /* no bad return value */
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
-</b></pre>
-Now we compute how much output <tt>deflate()</tt> provided on the last call, which is the
-difference between how much space was provided before the call, and how much output space
-is still available after the call. Then that data, if any, is written to the output file.
-We can then reuse the output buffer for the next call of <tt>deflate()</tt>. Again if there
-is a file i/o error, we call <tt>deflateEnd()</tt> before returning to avoid a memory leak.
-<pre><b>
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
- (void)deflateEnd(&amp;strm);
- return Z_ERRNO;
- }
-</b></pre>
-The inner <tt>do</tt>-loop is repeated until the last <tt>deflate()</tt> call fails to fill the
-provided output buffer. Then we know that <tt>deflate()</tt> has done as much as it can with
-the provided input, and that all of that input has been consumed. We can then fall out of this
-loop and reuse the input buffer.
-<p>
-The way we tell that <tt>deflate()</tt> has no more output is by seeing that it did not fill
-the output buffer, leaving <tt>avail_out</tt> greater than zero. However suppose that
-<tt>deflate()</tt> has no more output, but just so happened to exactly fill the output buffer!
-<tt>avail_out</tt> is zero, and we can't tell that <tt>deflate()</tt> has done all it can.
-As far as we know, <tt>deflate()</tt>
-has more output for us. So we call it again. But now <tt>deflate()</tt> produces no output
-at all, and <tt>avail_out</tt> remains unchanged as <tt>CHUNK</tt>. That <tt>deflate()</tt> call
-wasn't able to do anything, either consume input or produce output, and so it returns
-<tt>Z_BUF_ERROR</tt>. (See, I told you I'd cover this later.) However this is not a problem at
-all. Now we finally have the desired indication that <tt>deflate()</tt> is really done,
-and so we drop out of the inner loop to provide more input to <tt>deflate()</tt>.
-<p>
-With <tt>flush</tt> set to <tt>Z_FINISH</tt>, this final set of <tt>deflate()</tt> calls will
-complete the output stream. Once that is done, subsequent calls of <tt>deflate()</tt> would return
-<tt>Z_STREAM_ERROR</tt> if the flush parameter is not <tt>Z_FINISH</tt>, and do no more processing
-until the state is reinitialized.
-<p>
-Some applications of <em>zlib</em> have two loops that call <tt>deflate()</tt>
-instead of the single inner loop we have here. The first loop would call
-without flushing and feed all of the data to <tt>deflate()</tt>. The second loop would call
-<tt>deflate()</tt> with no more
-data and the <tt>Z_FINISH</tt> parameter to complete the process. As you can see from this
-example, that can be avoided by simply keeping track of the current flush state.
-<pre><b>
- } while (strm.avail_out == 0);
- assert(strm.avail_in == 0); /* all input will be used */
-</b></pre><!-- -->
-Now we check to see if we have already processed all of the input file. That information was
-saved in the <tt>flush</tt> variable, so we see if that was set to <tt>Z_FINISH</tt>. If so,
-then we're done and we fall out of the outer loop. We're guaranteed to get <tt>Z_STREAM_END</tt>
-from the last <tt>deflate()</tt> call, since we ran it until the last chunk of input was
-consumed and all of the output was generated.
-<pre><b>
- /* done when last data in file processed */
- } while (flush != Z_FINISH);
- assert(ret == Z_STREAM_END); /* stream will be complete */
-</b></pre><!-- -->
-The process is complete, but we still need to deallocate the state to avoid a memory leak
-(or rather more like a memory hemorrhage if you didn't do this). Then
-finally we can return with a happy return value.
-<pre><b>
- /* clean up and return */
- (void)deflateEnd(&amp;strm);
- return Z_OK;
-}
-</b></pre><!-- -->
-Now we do the same thing for decompression in the <tt>inf()</tt> routine. <tt>inf()</tt>
-decompresses what is hopefully a valid <em>zlib</em> stream from the input file and writes the
-uncompressed data to the output file. Much of the discussion above for <tt>def()</tt>
-applies to <tt>inf()</tt> as well, so the discussion here will focus on the differences between
-the two.
-<pre><b>
-/* Decompress from file source to file dest until stream ends or EOF.
- inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_DATA_ERROR if the deflate data is
- invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
- the version of the library linked do not match, or Z_ERRNO if there
- is an error reading or writing the files. */
-int inf(FILE *source, FILE *dest)
-{
-</b></pre>
-The local variables have the same functionality as they do for <tt>def()</tt>. The
-only difference is that there is no <tt>flush</tt> variable, since <tt>inflate()</tt>
-can tell from the <em>zlib</em> stream itself when the stream is complete.
-<pre><b>
- int ret;
- unsigned have;
- z_stream strm;
- unsigned char in[CHUNK];
- unsigned char out[CHUNK];
-</b></pre><!-- -->
-The initialization of the state is the same, except that there is no compression level,
-of course, and two more elements of the structure are initialized. <tt>avail_in</tt>
-and <tt>next_in</tt> must be initialized before calling <tt>inflateInit()</tt>. This
-is because the application has the option to provide the start of the zlib stream in
-order for <tt>inflateInit()</tt> to have access to information about the compression
-method to aid in memory allocation. In the current implementation of <em>zlib</em>
-(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of
-<tt>inflate()</tt> anyway. However those fields must be initialized since later versions
-of <em>zlib</em> that provide more compression methods may take advantage of this interface.
-In any case, no decompression is performed by <tt>inflateInit()</tt>, so the
-<tt>avail_out</tt> and <tt>next_out</tt> fields do not need to be initialized before calling.
-<p>
-Here <tt>avail_in</tt> is set to zero and <tt>next_in</tt> is set to <tt>Z_NULL</tt> to
-indicate that no input data is being provided.
-<pre><b>
- /* allocate inflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit(&amp;strm);
- if (ret != Z_OK)
- return ret;
-</b></pre><!-- -->
-The outer <tt>do</tt>-loop decompresses input until <tt>inflate()</tt> indicates
-that it has reached the end of the compressed data and has produced all of the uncompressed
-output. This is in contrast to <tt>def()</tt> which processes all of the input file.
-If end-of-file is reached before the compressed data self-terminates, then the compressed
-data is incomplete and an error is returned.
-<pre><b>
- /* decompress until deflate stream ends or end of file */
- do {
-</b></pre>
-We read input data and set the <tt>strm</tt> structure accordingly. If we've reached the
-end of the input file, then we leave the outer loop and report an error, since the
-compressed data is incomplete. Note that we may read more data than is eventually consumed
-by <tt>inflate()</tt>, if the input file continues past the <em>zlib</em> stream.
-For applications where <em>zlib</em> streams are embedded in other data, this routine would
-need to be modified to return the unused data, or at least indicate how much of the input
-data was not used, so the application would know where to pick up after the <em>zlib</em> stream.
-<pre><b>
- strm.avail_in = fread(in, 1, CHUNK, source);
- if (ferror(source)) {
- (void)inflateEnd(&amp;strm);
- return Z_ERRNO;
- }
- if (strm.avail_in == 0)
- break;
- strm.next_in = in;
-</b></pre><!-- -->
-The inner <tt>do</tt>-loop has the same function it did in <tt>def()</tt>, which is to
-keep calling <tt>inflate()</tt> until has generated all of the output it can with the
-provided input.
-<pre><b>
- /* run inflate() on input until output buffer not full */
- do {
-</b></pre>
-Just like in <tt>def()</tt>, the same output space is provided for each call of <tt>inflate()</tt>.
-<pre><b>
- strm.avail_out = CHUNK;
- strm.next_out = out;
-</b></pre>
-Now we run the decompression engine itself. There is no need to adjust the flush parameter, since
-the <em>zlib</em> format is self-terminating. The main difference here is that there are
-return values that we need to pay attention to. <tt>Z_DATA_ERROR</tt>
-indicates that <tt>inflate()</tt> detected an error in the <em>zlib</em> compressed data format,
-which means that either the data is not a <em>zlib</em> stream to begin with, or that the data was
-corrupted somewhere along the way since it was compressed. The other error to be processed is
-<tt>Z_MEM_ERROR</tt>, which can occur since memory allocation is deferred until <tt>inflate()</tt>
-needs it, unlike <tt>deflate()</tt>, whose memory is allocated at the start by <tt>deflateInit()</tt>.
-<p>
-Advanced applications may use
-<tt>deflateSetDictionary()</tt> to prime <tt>deflate()</tt> with a set of likely data to improve the
-first 32K or so of compression. This is noted in the <em>zlib</em> header, so <tt>inflate()</tt>
-requests that that dictionary be provided before it can start to decompress. Without the dictionary,
-correct decompression is not possible. For this routine, we have no idea what the dictionary is,
-so the <tt>Z_NEED_DICT</tt> indication is converted to a <tt>Z_DATA_ERROR</tt>.
-<p>
-<tt>inflate()</tt> can also return <tt>Z_STREAM_ERROR</tt>, which should not be possible here,
-but could be checked for as noted above for <tt>def()</tt>. <tt>Z_BUF_ERROR</tt> does not need to be
-checked for here, for the same reasons noted for <tt>def()</tt>. <tt>Z_STREAM_END</tt> will be
-checked for later.
-<pre><b>
- ret = inflate(&amp;strm, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- switch (ret) {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR; /* and fall through */
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- (void)inflateEnd(&amp;strm);
- return ret;
- }
-</b></pre>
-The output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()</tt>.
-<pre><b>
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
- (void)inflateEnd(&amp;strm);
- return Z_ERRNO;
- }
-</b></pre>
-The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated
-by not filling the output buffer, just as for <tt>deflate()</tt>. In this case, we cannot
-assert that <tt>strm.avail_in</tt> will be zero, since the deflate stream may end before the file
-does.
-<pre><b>
- } while (strm.avail_out == 0);
-</b></pre><!-- -->
-The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the
-end of the input <em>zlib</em> stream, has completed the decompression and integrity
-check, and has provided all of the output. This is indicated by the <tt>inflate()</tt>
-return value <tt>Z_STREAM_END</tt>. The inner loop is guaranteed to leave <tt>ret</tt>
-equal to <tt>Z_STREAM_END</tt> if the last chunk of the input file read contained the end
-of the <em>zlib</em> stream. So if the return value is not <tt>Z_STREAM_END</tt>, the
-loop continues to read more input.
-<pre><b>
- /* done when inflate() says it's done */
- } while (ret != Z_STREAM_END);
-</b></pre><!-- -->
-At this point, decompression successfully completed, or we broke out of the loop due to no
-more data being available from the input file. If the last <tt>inflate()</tt> return value
-is not <tt>Z_STREAM_END</tt>, then the <em>zlib</em> stream was incomplete and a data error
-is returned. Otherwise, we return with a happy return value. Of course, <tt>inflateEnd()</tt>
-is called first to avoid a memory leak.
-<pre><b>
- /* clean up and return */
- (void)inflateEnd(&amp;strm);
- return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
-}
-</b></pre><!-- -->
-That ends the routines that directly use <em>zlib</em>. The following routines make this
-a command-line program by running data through the above routines from <tt>stdin</tt> to
-<tt>stdout</tt>, and handling any errors reported by <tt>def()</tt> or <tt>inf()</tt>.
-<p>
-<tt>zerr()</tt> is used to interpret the possible error codes from <tt>def()</tt>
-and <tt>inf()</tt>, as detailed in their comments above, and print out an error message.
-Note that these are only a subset of the possible return values from <tt>deflate()</tt>
-and <tt>inflate()</tt>.
-<pre><b>
-/* report a zlib or i/o error */
-void zerr(int ret)
-{
- fputs("zpipe: ", stderr);
- switch (ret) {
- case Z_ERRNO:
- if (ferror(stdin))
- fputs("error reading stdin\n", stderr);
- if (ferror(stdout))
- fputs("error writing stdout\n", stderr);
- break;
- case Z_STREAM_ERROR:
- fputs("invalid compression level\n", stderr);
- break;
- case Z_DATA_ERROR:
- fputs("invalid or incomplete deflate data\n", stderr);
- break;
- case Z_MEM_ERROR:
- fputs("out of memory\n", stderr);
- break;
- case Z_VERSION_ERROR:
- fputs("zlib version mismatch!\n", stderr);
- }
-}
-</b></pre><!-- -->
-Here is the <tt>main()</tt> routine used to test <tt>def()</tt> and <tt>inf()</tt>. The
-<tt>zpipe</tt> command is simply a compression pipe from <tt>stdin</tt> to <tt>stdout</tt>, if
-no arguments are given, or it is a decompression pipe if <tt>zpipe -d</tt> is used. If any other
-arguments are provided, no compression or decompression is performed. Instead a usage
-message is displayed. Examples are <tt>zpipe < foo.txt > foo.txt.z</tt> to compress, and
-<tt>zpipe -d < foo.txt.z > foo.txt</tt> to decompress.
-<pre><b>
-/* compress or decompress from stdin to stdout */
-int main(int argc, char **argv)
-{
- int ret;
-
- /* avoid end-of-line conversions */
- SET_BINARY_MODE(stdin);
- SET_BINARY_MODE(stdout);
-
- /* do compression if no arguments */
- if (argc == 1) {
- ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
- if (ret != Z_OK)
- zerr(ret);
- return ret;
- }
-
- /* do decompression if -d specified */
- else if (argc == 2 &amp;&amp; strcmp(argv[1], "-d") == 0) {
- ret = inf(stdin, stdout);
- if (ret != Z_OK)
- zerr(ret);
- return ret;
- }
-
- /* otherwise, report usage */
- else {
- fputs("zpipe usage: zpipe [-d] &lt; source &gt; dest\n", stderr);
- return 1;
- }
-}
-</b></pre>
-<hr>
-<i>Copyright (c) 2004, 2005 by Mark Adler<br>Last modified 11 December 2005</i>
-</body>
-</html>
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zpipe.c b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zpipe.c
deleted file mode 100644
index 83535d1693..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zpipe.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* zpipe.c: example of proper use of zlib's inflate() and deflate()
- Not copyrighted -- provided to the public domain
- Version 1.4 11 December 2005 Mark Adler */
-
-/* Version history:
- 1.0 30 Oct 2004 First version
- 1.1 8 Nov 2004 Add void casting for unused return values
- Use switch statement for inflate() return values
- 1.2 9 Nov 2004 Add assertions to document zlib guarantees
- 1.3 6 Apr 2005 Remove incorrect assertion in inf()
- 1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions
- Avoid some compiler warnings for input and output buffers
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include "zlib.h"
-
-#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
-# include <fcntl.h>
-# include <io.h>
-# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-
-#define CHUNK 16384
-
-/* Compress from file source to file dest until EOF on source.
- def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_STREAM_ERROR if an invalid compression
- level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
- version of the library linked do not match, or Z_ERRNO if there is
- an error reading or writing the files. */
-int def(FILE *source, FILE *dest, int level)
-{
- int ret, flush;
- unsigned have;
- z_stream strm;
- unsigned char in[CHUNK];
- unsigned char out[CHUNK];
-
- /* allocate deflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- ret = deflateInit(&strm, level);
- if (ret != Z_OK)
- return ret;
-
- /* compress until end of file */
- do {
- strm.avail_in = fread(in, 1, CHUNK, source);
- if (ferror(source)) {
- (void)deflateEnd(&strm);
- return Z_ERRNO;
- }
- flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
- strm.next_in = in;
-
- /* run deflate() on input until output buffer not full, finish
- compression if all of source has been read in */
- do {
- strm.avail_out = CHUNK;
- strm.next_out = out;
- ret = deflate(&strm, flush); /* no bad return value */
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
- (void)deflateEnd(&strm);
- return Z_ERRNO;
- }
- } while (strm.avail_out == 0);
- assert(strm.avail_in == 0); /* all input will be used */
-
- /* done when last data in file processed */
- } while (flush != Z_FINISH);
- assert(ret == Z_STREAM_END); /* stream will be complete */
-
- /* clean up and return */
- (void)deflateEnd(&strm);
- return Z_OK;
-}
-
-/* Decompress from file source to file dest until stream ends or EOF.
- inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_DATA_ERROR if the deflate data is
- invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
- the version of the library linked do not match, or Z_ERRNO if there
- is an error reading or writing the files. */
-int inf(FILE *source, FILE *dest)
-{
- int ret;
- unsigned have;
- z_stream strm;
- unsigned char in[CHUNK];
- unsigned char out[CHUNK];
-
- /* allocate inflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit(&strm);
- if (ret != Z_OK)
- return ret;
-
- /* decompress until deflate stream ends or end of file */
- do {
- strm.avail_in = fread(in, 1, CHUNK, source);
- if (ferror(source)) {
- (void)inflateEnd(&strm);
- return Z_ERRNO;
- }
- if (strm.avail_in == 0)
- break;
- strm.next_in = in;
-
- /* run inflate() on input until output buffer not full */
- do {
- strm.avail_out = CHUNK;
- strm.next_out = out;
- ret = inflate(&strm, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- switch (ret) {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR; /* and fall through */
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- (void)inflateEnd(&strm);
- return ret;
- }
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
- (void)inflateEnd(&strm);
- return Z_ERRNO;
- }
- } while (strm.avail_out == 0);
-
- /* done when inflate() says it's done */
- } while (ret != Z_STREAM_END);
-
- /* clean up and return */
- (void)inflateEnd(&strm);
- return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
-}
-
-/* report a zlib or i/o error */
-void zerr(int ret)
-{
- fputs("zpipe: ", stderr);
- switch (ret) {
- case Z_ERRNO:
- if (ferror(stdin))
- fputs("error reading stdin\n", stderr);
- if (ferror(stdout))
- fputs("error writing stdout\n", stderr);
- break;
- case Z_STREAM_ERROR:
- fputs("invalid compression level\n", stderr);
- break;
- case Z_DATA_ERROR:
- fputs("invalid or incomplete deflate data\n", stderr);
- break;
- case Z_MEM_ERROR:
- fputs("out of memory\n", stderr);
- break;
- case Z_VERSION_ERROR:
- fputs("zlib version mismatch!\n", stderr);
- }
-}
-
-/* compress or decompress from stdin to stdout */
-int main(int argc, char **argv)
-{
- int ret;
-
- /* avoid end-of-line conversions */
- SET_BINARY_MODE(stdin);
- SET_BINARY_MODE(stdout);
-
- /* do compression if no arguments */
- if (argc == 1) {
- ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
- if (ret != Z_OK)
- zerr(ret);
- return ret;
- }
-
- /* do decompression if -d specified */
- else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
- ret = inf(stdin, stdout);
- if (ret != Z_OK)
- zerr(ret);
- return ret;
- }
-
- /* otherwise, report usage */
- else {
- fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
- return 1;
- }
-}
diff --git a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zran.c b/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zran.c
deleted file mode 100644
index 278f9ad07d..0000000000
--- a/third_party/rust/libz-sys/src/zlib-1.2.8/examples/zran.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/* zran.c -- example of zlib/gzip stream indexing and random access
- * Copyright (C) 2005, 2012 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- Version 1.1 29 Sep 2012 Mark Adler */
-
-/* Version History:
- 1.0 29 May 2005 First version
- 1.1 29 Sep 2012 Fix memory reallocation error
- */
-
-/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary()
- for random access of a compressed file. A file containing a zlib or gzip
- stream is provided on the command line. The compressed stream is decoded in
- its entirety, and an index built with access points about every SPAN bytes
- in the uncompressed output. The compressed file is left open, and can then
- be read randomly, having to decompress on the average SPAN/2 uncompressed
- bytes before getting to the desired block of data.
-
- An access point can be created at the start of any deflate block, by saving
- the starting file offset and bit of that block, and the 32K bytes of
- uncompressed data that precede that block. Also the uncompressed offset of
- that block is saved to provide a referece for locating a desired starting
- point in the uncompressed stream. build_index() works by decompressing the
- input zlib or gzip stream a block at a time, and at the end of each block
- deciding if enough uncompressed data has gone by to justify the creation of
- a new access point. If so, that point is saved in a data structure that
- grows as needed to accommodate the points.
-
- To use the index, an offset in the uncompressed data is provided, for which
- the latest accees point at or preceding that offset is located in the index.
- The input file is positioned to the specified location in the index, and if
- necessary the first few bits of the compressed data is read from the file.
- inflate is initialized with those bits and the 32K of uncompressed data, and
- the decompression then proceeds until the desired offset in the file is
- reached. Then the decompression continues to read the desired uncompressed
- data from the file.
-
- Another approach would be to generate the index on demand. In that case,
- requests for random access reads from the compressed data would try to use
- the index, but if a read far enough past the end of the index is required,
- then further index entries would be generated and added.
-
- There is some fair bit of overhead to starting inflation for the random
- access, mainly copying the 32K byte dictionary. So if small pieces of the
- file are being accessed, it would make sense to implement a cache to hold
- some lookahead and avoid many calls to extract() for small lengths.
-
- Another way to build an index would be to use inflateCopy(). That would
- not be constrained to have access points at block boundaries, but requires
- more memory per access point, and also cannot be saved to file due to the
- use of pointers in the state. The approach here allows for storage of the
- index in a file.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-
-#define local static
-
-#define SPAN 1048576L /* desired distance between access points */
-#define WINSIZE 32768U /* sliding window size */
-#define CHUNK 16384 /* file input buffer size */
-
-/* access point entry */
-struct point {
- off_t out; /* corresponding offset in uncompressed data */
- off_t in; /* offset in input file of first full byte */
- int bits; /* number of bits (1-7) from byte at in - 1, or 0 */
- unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */
-};
-
-/* access point list */
-struct access {
- int have; /* number of list entries filled in */
- int size; /* number of list entries allocated */
- struct point *list; /* allocated list */
-};
-
-/* Deallocate an index built by build_index() */
-local void free_index(struct access *index)
-{
- if (index != NULL) {
- free(index->list);
- free(index);
- }
-}
-
-/* Add an entry to the access point list. If out of memory, deallocate the
- existing list and return NULL. */
-local struct access *addpoint(struct access *index, int bits,
- off_t in, off_t out, unsigned left, unsigned char *window)
-{
- struct point *next;
-
- /* if list is empty, create it (start with eight points) */
- if (index == NULL) {
- index = malloc(sizeof(struct access));
- if (index == NULL) return NULL;
- index->list = malloc(sizeof(struct point) << 3);
- if (index->list == NULL) {
- free(index);
- return NULL;
- }
- index->size = 8;
- index->have = 0;
- }
-
- /* if list is full, make it bigger */
- else if (index->have == index->size) {
- index->size <<= 1;
- next = realloc(index->list, sizeof(struct point) * index->size);
- if (next == NULL) {
- free_index(index);
- return NULL;
- }
- index->list = next;
- }
-
- /* fill in entry and increment how many we have */
- next = index->list + index->have;
- next->bits = bits;
- next->in = in;
- next->out = out;
- if (left)
- memcpy(next->window, window + WINSIZE - left, left);
- if (left < WINSIZE)
- memcpy(next->window + left, window, WINSIZE - left);
- index->have++;
-
- /* return list, possibly reallocated */
- return index;
-}
-
-/* Make one entire pass through the compressed stream and build an index, with
- access points about every span bytes of uncompressed output -- span is
- chosen to balance the speed of random access against the memory requirements
- of the list, about 32K bytes per access point. Note that data after the end
- of the first zlib or gzip stream in the file is ignored. build_index()
- returns the number of access points on success (>= 1), Z_MEM_ERROR for out
- of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
- file read error. On success, *built points to the resulting index. */
-local int build_index(FILE *in, off_t span, struct access **built)
-{
- int ret;
- off_t totin, totout; /* our own total counters to avoid 4GB limit */
- off_t last; /* totout value of last access point */
- struct access *index; /* access points being generated */
- z_stream strm;
- unsigned char input[CHUNK];
- unsigned char window[WINSIZE];
-
- /* initialize inflate */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit2(&strm, 47); /* automatic zlib or gzip decoding */
- if (ret != Z_OK)
- return ret;
-
- /* inflate the input, maintain a sliding window, and build an index -- this
- also validates the integrity of the compressed data using the check
- information at the end of the gzip or zlib stream */
- totin = totout = last = 0;
- index = NULL; /* will be allocated by first addpoint() */
- strm.avail_out = 0;
- do {
- /* get some compressed data from input file */
- strm.avail_in = fread(input, 1, CHUNK, in);
- if (ferror(in)) {
- ret = Z_ERRNO;
- goto build_index_error;
- }
- if (strm.avail_in == 0) {
- ret = Z_DATA_ERROR;
- goto build_index_error;
- }
- strm.next_in = input;
-
- /* process all of that, or until end of stream */
- do {
- /* reset sliding window if necessary */
- if (strm.avail_out == 0) {
- strm.avail_out = WINSIZE;
- strm.next_out = window;
- }
-
- /* inflate until out of input, output, or at end of block --
- update the total input and output counters */
- totin += strm.avail_in;
- totout += strm.avail_out;
- ret = inflate(&strm, Z_BLOCK); /* return at end of block */
- totin -= strm.avail_in;
- totout -= strm.avail_out;
- if (ret == Z_NEED_DICT)
- ret = Z_DATA_ERROR;
- if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
- goto build_index_error;
- if (ret == Z_STREAM_END)
- break;
-
- /* if at end of block, consider adding an index entry (note that if
- data_type indicates an end-of-block, then all of the
- uncompressed data from that block has been delivered, and none
- of the compressed data after that block has been consumed,
- except for up to seven bits) -- the totout == 0 provides an
- entry point after the zlib or gzip header, and assures that the
- index always has at least one access point; we avoid creating an
- access point after the last block by checking bit 6 of data_type
- */
- if ((strm.data_type & 128) && !(strm.data_type & 64) &&
- (totout == 0 || totout - last > span)) {
- index = addpoint(index, strm.data_type & 7, totin,
- totout, strm.avail_out, window);
- if (index == NULL) {
- ret = Z_MEM_ERROR;
- goto build_index_error;
- }
- last = totout;
- }
- } while (strm.avail_in != 0);
- } while (ret != Z_STREAM_END);
-
- /* clean up and return index (release unused entries in list) */
- (void)inflateEnd(&strm);
- index->list = realloc(index->list, sizeof(struct point) * index->have);
- index->size = index->have;
- *built = index;
- return index->size;
-
- /* return error */
- build_index_error:
- (void)inflateEnd(&strm);
- if (index != NULL)
- free_index(index);
- return ret;
-}
-
-/* Use the index to read len bytes from offset into buf, return bytes read or
- negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past
- the end of the uncompressed data, then extract() will return a value less
- than len, indicating how much as actually read into buf. This function
- should not return a data error unless the file was modified since the index
- was generated. extract() may also return Z_ERRNO if there is an error on
- reading or seeking the input file. */
-local int extract(FILE *in, struct access *index, off_t offset,
- unsigned char *buf, int len)
-{
- int ret, skip;
- z_stream strm;
- struct point *here;
- unsigned char input[CHUNK];
- unsigned char discard[WINSIZE];
-
- /* proceed only if something reasonable to do */
- if (len < 0)
- return 0;
-
- /* find where in stream to start */
- here = index->list;
- ret = index->have;
- while (--ret && here[1].out <= offset)
- here++;
-
- /* initialize file and inflate state to start there */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit2(&strm, -15); /* raw inflate */
- if (ret != Z_OK)
- return ret;
- ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
- if (ret == -1)
- goto extract_ret;
- if (here->bits) {
- ret = getc(in);
- if (ret == -1) {
- ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR;
- goto extract_ret;
- }
- (void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits));
- }
- (void)inflateSetDictionary(&strm, here->window, WINSIZE);
-
- /* skip uncompressed bytes until offset reached, then satisfy request */
- offset -= here->out;
- strm.avail_in = 0;
- skip = 1; /* while skipping to offset */
- do {
- /* define where to put uncompressed data, and how much */
- if (offset == 0 && skip) { /* at offset now */
- strm.avail_out = len;
- strm.next_out = buf;
- skip = 0; /* only do this once */
- }
- if (offset > WINSIZE) { /* skip WINSIZE bytes */
- strm.avail_out = WINSIZE;
- strm.next_out = discard;
- offset -= WINSIZE;
- }
- else if (offset != 0) { /* last skip */
- strm.avail_out = (unsigned)offset;
- strm.next_out = discard;
- offset = 0;
- }
-
- /* uncompress until avail_out filled, or end of stream */
- do {
- if (strm.avail_in == 0) {
- strm.avail_in = fread(input, 1, CHUNK, in);
- if (ferror(in)) {
- ret = Z_ERRNO;
- goto extract_ret;
- }
- if (strm.avail_in == 0) {
- ret = Z_DATA_ERROR;
- goto extract_ret;
- }
- strm.next_in = input;
- }
- ret = inflate(&strm, Z_NO_FLUSH); /* normal inflate */
- if (ret == Z_NEED_DICT)
- ret = Z_DATA_ERROR;
- if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
- goto extract_ret;
- if (ret == Z_STREAM_END)
- break;
- } while (strm.avail_out != 0);
-
- /* if reach end of stream, then don't keep trying to get more */
- if (ret == Z_STREAM_END)
- break;
-
- /* do until offset reached and requested data read, or stream ends */
- } while (skip);
-
- /* compute number of uncompressed bytes read after offset */
- ret = skip ? 0 : len - strm.avail_out;
-
- /* clean up and return bytes read or error */
- extract_ret:
- (void)inflateEnd(&strm);
- return ret;
-}
-
-/* Demonstrate the use of build_index() and extract() by processing the file
- provided on the command line, and the extracting 16K from about 2/3rds of
- the way through the uncompressed output, and writing that to stdout. */
-int main(int argc, char **argv)
-{
- int len;
- off_t offset;
- FILE *in;
- struct access *index = NULL;
- unsigned char buf[CHUNK];
-
- /* open input file */
- if (argc != 2) {
- fprintf(stderr, "usage: zran file.gz\n");
- return 1;
- }
- in = fopen(argv[1], "rb");
- if (in == NULL) {
- fprintf(stderr, "zran: could not open %s for reading\n", argv[1]);
- return 1;
- }
-
- /* build index */
- len = build_index(in, SPAN, &index);
- if (len < 0) {
- fclose(in);
- switch (len) {
- case Z_MEM_ERROR:
- fprintf(stderr, "zran: out of memory\n");
- break;
- case Z_DATA_ERROR:
- fprintf(stderr, "zran: compressed data error in %s\n", argv[1]);
- break;
- case Z_ERRNO:
- fprintf(stderr, "zran: read error on %s\n", argv[1]);
- break;
- default:
- fprintf(stderr, "zran: error %d while building index\n", len);
- }
- return 1;
- }
- fprintf(stderr, "zran: built index with %d access points\n", len);
-
- /* use index by reading some bytes from an arbitrary offset */
- offset = (index->list[index->have - 1].out << 1) / 3;
- len = extract(in, index, offset, buf, CHUNK);
- if (len < 0)
- fprintf(stderr, "zran: extraction failed: %s error\n",
- len == Z_MEM_ERROR ? "out of memory" : "input corrupted");
- else {
- fwrite(buf, 1, len, stdout);
- fprintf(stderr, "zran: extracted %d bytes at %llu\n", len, offset);
- }
-
- /* clean up and exit */
- free_index(index);
- fclose(in);
- return 0;
-}