1 /* util.c -- utility functions for gzip support
2 * Copyright (C) 1992-1993 Jean-loup Gailly
3 * This is free software; you can redistribute it and/or modify it under the
4 * terms of the GNU General Public License, see the file COPYING.
6 * $FreeBSD: src/gnu/usr.bin/gzip/util.c,v 1.8 1999/08/27 23:35:54 peter Exp $
7 * $DragonFly: src/gnu/usr.bin/gzip/Attic/util.c,v 1.2 2003/06/17 04:25:46 dillon Exp $
12 #include <sys/types.h>
23 #if defined(STDC_HEADERS) || !defined(NO_STDLIB_H)
32 extern ulg crc_32_tab[]; /* crc table, defined below */
34 /* ===========================================================================
35 * Copy input to output unchanged: zcat == cat with --force.
36 * IN assertion: insize bytes have already been read in inbuf.
39 int in, out; /* input and output file descriptors */
42 while (insize != 0 && (int)insize != EOF) {
43 write_buf(out, (char*)inbuf, insize);
45 insize = read(in, (char*)inbuf, INBUFSIZ);
47 if ((int)insize == EOF && errno != 0) {
54 /* ===========================================================================
55 * Run a set of bytes through the crc shift register. If s is a NULL
56 * pointer, then initialize the crc shift register contents instead.
57 * Return the current crc in either case.
60 uch *s; /* pointer to bytes to pump through */
61 unsigned n; /* number of bytes in s[] */
63 register ulg c; /* temporary variable */
65 static ulg crc = (ulg)0xffffffffL; /* shift register contents */
72 c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
76 return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
79 /* ===========================================================================
80 * Clear input and output buffers
86 bytes_in = bytes_out = 0L;
89 /* ===========================================================================
90 * Fill the input buffer. This is called only when the buffer is empty.
92 int fill_inbuf(eof_ok)
93 int eof_ok; /* set if EOF acceptable as a result */
97 /* Read as much as possible */
101 len = read(ifd, (char*)inbuf+insize, INBUFSIZ-insize);
102 if (len == 0 || len == EOF) break;
104 } while (insize < INBUFSIZ);
107 if (eof_ok) return EOF;
110 bytes_in += (ulg)insize;
115 /* ===========================================================================
116 * Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
117 * (used for the compressed data only)
121 if (outcnt == 0) return;
123 write_buf(ofd, (char *)outbuf, outcnt);
124 bytes_out += (ulg)outcnt;
128 /* ===========================================================================
129 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
130 * (Used for the decompressed data only.)
134 if (outcnt == 0) return;
135 updcrc(window, outcnt);
138 write_buf(ofd, (char *)window, outcnt);
140 bytes_out += (ulg)outcnt;
144 /* ===========================================================================
145 * Does the same as write(), but also handles partial pipe writes and checks
148 void write_buf(fd, buf, cnt)
155 while ((n = write(fd, buf, cnt)) != cnt) {
156 if (n == (unsigned)(-1)) {
160 buf = (voidp)((char*)buf+n);
164 /* ========================================================================
165 * Put string s in lower case, return s.
171 for (t = s; *t; t++) *t = tolow(*t);
175 /* ========================================================================
176 * Return the base name of a file (remove any directory prefix and
177 * any version suffix). For systems with file names that are not
178 * case sensitive, force the base name to lower case.
180 char *basename(fname)
185 if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1;
187 if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1;
190 if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1;
193 if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0';
195 if (casemap('A') == 'a') strlwr(fname);
199 /* ========================================================================
200 * Make a file name legal for file systems not allowing file names with
201 * multiple dots or starting with a dot (such as MSDOS), by changing
202 * all dots except the last one into underlines. A target dependent
203 * function can be used instead of this simple function by defining the macro
204 * MAKE_LEGAL_NAME in tailor.h and providing the function in a target
207 void make_simple_name(name)
210 char *p = strrchr(name, '.');
211 if (p == NULL) return;
214 if (*--p == '.') *p = '_';
219 #if defined(NO_STRING_H) && !defined(STDC_HEADERS)
221 /* Provide missing strspn and strcspn functions. */
227 int strspn OF((const char *s, const char *accept));
228 int strcspn OF((const char *s, const char *reject));
230 /* ========================================================================
231 * Return the length of the maximum initial segment
232 * of s which contains only characters in accept.
234 int strspn(s, accept)
238 register const char *p;
239 register const char *a;
240 register int count = 0;
242 for (p = s; *p != '\0'; ++p) {
243 for (a = accept; *a != '\0'; ++a) {
246 if (*a == '\0') return count;
252 /* ========================================================================
253 * Return the length of the maximum inital segment of s
254 * which contains no characters from reject.
256 int strcspn(s, reject)
260 register int count = 0;
263 if (strchr(reject, *s++) != NULL) return count;
269 #endif /* NO_STRING_H */
271 /* ========================================================================
272 * Add an environment variable (if any) before argv, and update argc.
273 * Return the expanded environment variable to be freed later, or NULL
274 * if no options were added to argv.
276 #define SEPARATOR " \t" /* separators in env variable */
278 char *add_envopt(argcp, argvp, env)
279 int *argcp; /* pointer to argc */
280 char ***argvp; /* pointer to argv */
281 char *env; /* name of environment variable */
283 char *p; /* running pointer through env variable */
284 char **oargv; /* runs through old argv array */
285 char **nargv; /* runs through new argv array */
286 int oargc = *argcp; /* old argc */
287 int nargc = 0; /* number of arguments in env variable */
289 env = (char*)getenv(env);
290 if (env == NULL) return NULL;
292 p = (char*)xmalloc(strlen(env)+1);
293 env = strcpy(p, env); /* keep env variable intact */
295 for (p = env; *p; nargc++ ) { /* move through env */
296 p += strspn(p, SEPARATOR); /* skip leading separators */
297 if (*p == '\0') break;
299 p += strcspn(p, SEPARATOR); /* find end of word */
300 if (*p) *p++ = '\0'; /* mark it */
307 /* Allocate the new argv array, with an extra element just in case
308 * the original arg list did not end with a NULL.
310 nargv = (char**)calloc(*argcp+1, sizeof(char *));
311 if (nargv == NULL) error("out of memory");
315 /* Copy the program name first */
316 if (oargc-- < 0) error("argc<=0");
317 *(nargv++) = *(oargv++);
319 /* Then copy the environment args */
320 for (p = env; nargc > 0; nargc--) {
321 p += strspn(p, SEPARATOR); /* skip separators */
322 *(nargv++) = p; /* store start */
323 while (*p++) ; /* skip over word */
326 /* Finally copy the old args and add a NULL (usual convention) */
327 while (oargc--) *(nargv++) = *(oargv++);
332 /* ========================================================================
338 fprintf(stderr, "\n%s: %s: %s\n", progname, ifname, m);
344 fprintf(stderr, "\n%s: ", progname);
348 fprintf(stderr, "%s: unexpected end of file\n", ifname);
355 fprintf(stderr, "\n%s: ", progname);
360 /* ========================================================================
361 * Display compression ratio on the given stream on 6 characters.
363 void display_ratio(num, den, file)
368 long ratio; /* 1000 times the compression ratio */
371 ratio = 0; /* no compression */
372 } else if (den < 2147483L) { /* (2**31 -1)/1000 */
373 ratio = 1000L*num/den;
375 ratio = num/(den/1000L);
383 fprintf(file, "%2ld.%1ld%%", ratio / 10L, ratio % 10L);
387 /* ========================================================================
388 * Semi-safe malloc -- never returns NULL.
393 voidp cp = (voidp)malloc (size);
395 if (cp == NULL) error("out of memory");
399 /* ========================================================================
400 * Table of CRC-32's of all single-byte values (made by makecrc.c)
403 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
404 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
405 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
406 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
407 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
408 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
409 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
410 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
411 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
412 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
413 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
414 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
415 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
416 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
417 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
418 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
419 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
420 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
421 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
422 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
423 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
424 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
425 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
426 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
427 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
428 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
429 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
430 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
431 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
432 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
433 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
434 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
435 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
436 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
437 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
438 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
439 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
440 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
441 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
442 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
443 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
444 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
445 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
446 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
447 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
448 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
449 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
450 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
451 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
452 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
453 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,