00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef RCSID
00022 static char rcsid[] = "$Id: util.c,v 1.6 2006/12/11 18:54:39 eggert Exp $";
00023 #endif
00024
00025 #include <config.h>
00026 #include <ctype.h>
00027 #include <errno.h>
00028
00029 #include "tailor.h"
00030
00031 #ifdef HAVE_LIMITS_H
00032 # include <limits.h>
00033 #endif
00034 #ifdef HAVE_UNISTD_H
00035 # include <unistd.h>
00036 #endif
00037 #ifdef HAVE_FCNTL_H
00038 # include <fcntl.h>
00039 #endif
00040
00041 #if defined STDC_HEADERS || defined HAVE_STDLIB_H
00042 # include <stdlib.h>
00043 #else
00044 extern int errno;
00045 #endif
00046
00047 #include "gzip.h"
00048 #include "crypt.h"
00049 #include <xalloc.h>
00050
00051 #ifndef CHAR_BIT
00052 # define CHAR_BIT 8
00053 #endif
00054
00055 static int write_buffer OF((int, voidp, unsigned int));
00056
00057 extern ulg crc_32_tab[];
00058
00059
00060
00061
00062
00063 int copy(in, out)
00064 int in, out;
00065 {
00066 errno = 0;
00067 while (insize != 0 && (int)insize != -1) {
00068 write_buf(out, (char*)inbuf, insize);
00069 bytes_out += insize;
00070 insize = read_buffer (in, (char *) inbuf, INBUFSIZ);
00071 }
00072 if ((int)insize == -1) {
00073 read_error();
00074 }
00075 bytes_in = bytes_out;
00076 return OK;
00077 }
00078
00079
00080
00081
00082
00083
00084 ulg updcrc(s, n)
00085 uch *s;
00086 unsigned n;
00087 {
00088 register ulg c;
00089
00090 static ulg crc = (ulg)0xffffffffL;
00091
00092 if (s == NULL) {
00093 c = 0xffffffffL;
00094 } else {
00095 c = crc;
00096 if (n) do {
00097 c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
00098 } while (--n);
00099 }
00100 crc = c;
00101 return c ^ 0xffffffffL;
00102 }
00103
00104
00105
00106
00107 void clear_bufs()
00108 {
00109 outcnt = 0;
00110 insize = inptr = 0;
00111 bytes_in = bytes_out = 0L;
00112 }
00113
00114
00115
00116
00117 int fill_inbuf(eof_ok)
00118 int eof_ok;
00119 {
00120 int len;
00121
00122
00123 insize = 0;
00124 do {
00125 len = read_buffer (ifd, (char *) inbuf + insize, INBUFSIZ - insize);
00126 if (len == 0) break;
00127 if (len == -1) {
00128 read_error();
00129 break;
00130 }
00131 insize += len;
00132 } while (insize < INBUFSIZ);
00133
00134 if (insize == 0) {
00135 if (eof_ok) return EOF;
00136 flush_window();
00137 errno = 0;
00138 read_error();
00139 }
00140 bytes_in += (off_t)insize;
00141 inptr = 1;
00142 return inbuf[0];
00143 }
00144
00145
00146
00147 int
00148 read_buffer (fd, buf, cnt)
00149 int fd;
00150 voidp buf;
00151 unsigned int cnt;
00152 {
00153 #ifdef SSIZE_MAX
00154 if (SSIZE_MAX < cnt)
00155 cnt = SSIZE_MAX;
00156 #endif
00157 return read (fd, buf, cnt);
00158 }
00159
00160
00161 static int
00162 write_buffer (fd, buf, cnt)
00163 int fd;
00164 voidp buf;
00165 unsigned int cnt;
00166 {
00167 #ifdef SSIZE_MAX
00168 if (SSIZE_MAX < cnt)
00169 cnt = SSIZE_MAX;
00170 #endif
00171 return write (fd, buf, cnt);
00172 }
00173
00174
00175
00176
00177
00178 void flush_outbuf()
00179 {
00180 if (outcnt == 0) return;
00181
00182 write_buf(ofd, (char *)outbuf, outcnt);
00183 bytes_out += (off_t)outcnt;
00184 outcnt = 0;
00185 }
00186
00187
00188
00189
00190
00191 void flush_window()
00192 {
00193 if (outcnt == 0) return;
00194 updcrc(window, outcnt);
00195
00196 if (!test) {
00197 write_buf(ofd, (char *)window, outcnt);
00198 }
00199 bytes_out += (off_t)outcnt;
00200 outcnt = 0;
00201 }
00202
00203
00204
00205
00206
00207 void write_buf(fd, buf, cnt)
00208 int fd;
00209 voidp buf;
00210 unsigned cnt;
00211 {
00212 unsigned n;
00213
00214 while ((n = write_buffer (fd, buf, cnt)) != cnt) {
00215 if (n == (unsigned)(-1)) {
00216 write_error();
00217 }
00218 cnt -= n;
00219 buf = (voidp)((char*)buf+n);
00220 }
00221 }
00222
00223
00224
00225
00226 char *strlwr(s)
00227 char *s;
00228 {
00229 char *t;
00230 for (t = s; *t; t++)
00231 *t = tolow ((unsigned char) *t);
00232 return s;
00233 }
00234
00235
00236
00237
00238
00239
00240 char *
00241 gzip_base_name (fname)
00242 char *fname;
00243 {
00244 char *p;
00245
00246 if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1;
00247 #ifdef PATH_SEP2
00248 if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1;
00249 #endif
00250 #ifdef PATH_SEP3
00251 if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1;
00252 #endif
00253 #ifdef SUFFIX_SEP
00254 if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0';
00255 #endif
00256 if (casemap('A') == 'a') strlwr(fname);
00257 return fname;
00258 }
00259
00260
00261
00262
00263 int xunlink (filename)
00264 char *filename;
00265 {
00266 int r = unlink (filename);
00267
00268 #ifdef UNLINK_READONLY_BUG
00269 if (r != 0)
00270 {
00271 int e = errno;
00272 if (chmod (filename, S_IWUSR) != 0)
00273 {
00274 errno = e;
00275 return -1;
00276 }
00277
00278 r = unlink (filename);
00279 }
00280 #endif
00281
00282 return r;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 void make_simple_name(name)
00294 char *name;
00295 {
00296 char *p = strrchr(name, '.');
00297 if (p == NULL) return;
00298 if (p == name) p++;
00299 do {
00300 if (*--p == '.') *p = '_';
00301 } while (p != name);
00302 }
00303
00304
00305 #if !defined HAVE_STRING_H && !defined STDC_HEADERS
00306
00307
00308
00309 # ifndef __STDC__
00310 # define const
00311 # endif
00312
00313 int strspn OF((const char *s, const char *accept));
00314 int strcspn OF((const char *s, const char *reject));
00315
00316
00317
00318
00319
00320 int strspn(s, accept)
00321 const char *s;
00322 const char *accept;
00323 {
00324 register const char *p;
00325 register const char *a;
00326 register int count = 0;
00327
00328 for (p = s; *p != '\0'; ++p) {
00329 for (a = accept; *a != '\0'; ++a) {
00330 if (*p == *a) break;
00331 }
00332 if (*a == '\0') return count;
00333 ++count;
00334 }
00335 return count;
00336 }
00337
00338
00339
00340
00341
00342 int strcspn(s, reject)
00343 const char *s;
00344 const char *reject;
00345 {
00346 register int count = 0;
00347
00348 while (*s != '\0') {
00349 if (strchr(reject, *s++) != NULL) return count;
00350 ++count;
00351 }
00352 return count;
00353 }
00354
00355 #endif
00356
00357
00358
00359
00360
00361
00362 #define SEPARATOR " \t"
00363
00364 char *add_envopt(argcp, argvp, env)
00365 int *argcp;
00366 char ***argvp;
00367 char *env;
00368 {
00369 char *p;
00370 char **oargv;
00371 char **nargv;
00372 int oargc = *argcp;
00373 int nargc = 0;
00374
00375 env = (char*)getenv(env);
00376 if (env == NULL) return NULL;
00377
00378 env = xstrdup (env);
00379
00380 for (p = env; *p; nargc++ ) {
00381 p += strspn(p, SEPARATOR);
00382 if (*p == '\0') break;
00383
00384 p += strcspn(p, SEPARATOR);
00385 if (*p) *p++ = '\0';
00386 }
00387 if (nargc == 0) {
00388 free(env);
00389 return NULL;
00390 }
00391 *argcp += nargc;
00392
00393
00394
00395 nargv = (char **) xcalloc (*argcp + 1, sizeof (char *));
00396 oargv = *argvp;
00397 *argvp = nargv;
00398
00399
00400 if (oargc-- < 0)
00401 gzip_error ("argc<=0");
00402 *(nargv++) = *(oargv++);
00403
00404
00405 for (p = env; nargc > 0; nargc--) {
00406 p += strspn(p, SEPARATOR);
00407 *(nargv++) = p;
00408 while (*p++) ;
00409 }
00410
00411
00412 while (oargc--) *(nargv++) = *(oargv++);
00413 *nargv = NULL;
00414 return env;
00415 }
00416
00417
00418
00419
00420 void
00421 gzip_error (m)
00422 char *m;
00423 {
00424 fprintf (stderr, "\n%s: %s: %s\n", program_name, ifname, m);
00425 abort_gzip();
00426 }
00427
00428 void
00429 xalloc_die ()
00430 {
00431 fprintf (stderr, "\n%s: memory_exhausted\n", program_name);
00432 abort_gzip ();
00433 }
00434
00435 void warning (m)
00436 char *m;
00437 {
00438 WARN ((stderr, "%s: %s: warning: %s\n", program_name, ifname, m));
00439 }
00440
00441 void read_error()
00442 {
00443 int e = errno;
00444 fprintf (stderr, "\n%s: ", program_name);
00445 if (e != 0) {
00446 errno = e;
00447 perror(ifname);
00448 } else {
00449 fprintf(stderr, "%s: unexpected end of file\n", ifname);
00450 }
00451 abort_gzip();
00452 }
00453
00454 void write_error()
00455 {
00456 int e = errno;
00457 fprintf (stderr, "\n%s: ", program_name);
00458 errno = e;
00459 perror(ofname);
00460 abort_gzip();
00461 }
00462
00463
00464
00465
00466 void display_ratio(num, den, file)
00467 off_t num;
00468 off_t den;
00469 FILE *file;
00470 {
00471 fprintf(file, "%5.1f%%", den == 0 ? 0 : 100.0 * num / den);
00472 }
00473
00474
00475
00476
00477
00478 void fprint_off(file, offset, width)
00479 FILE *file;
00480 off_t offset;
00481 int width;
00482 {
00483 char buf[CHAR_BIT * sizeof (off_t)];
00484 char *p = buf + sizeof buf;
00485
00486
00487 if (offset < 0) {
00488 do
00489 *--p = '0' - offset % 10;
00490 while ((offset /= 10) != 0);
00491
00492 *--p = '-';
00493 } else {
00494 do
00495 *--p = '0' + offset % 10;
00496 while ((offset /= 10) != 0);
00497 }
00498
00499 width -= buf + sizeof buf - p;
00500 while (0 < width--) {
00501 putc (' ', file);
00502 }
00503 for (; p < buf + sizeof buf; p++)
00504 putc (*p, file);
00505 }
00506
00507
00508
00509
00510 ulg crc_32_tab[] = {
00511 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
00512 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
00513 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
00514 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
00515 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
00516 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
00517 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
00518 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
00519 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
00520 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
00521 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
00522 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
00523 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
00524 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
00525 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
00526 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
00527 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
00528 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
00529 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
00530 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
00531 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
00532 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
00533 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
00534 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
00535 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
00536 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
00537 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
00538 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
00539 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
00540 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
00541 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
00542 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
00543 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
00544 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
00545 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
00546 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
00547 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
00548 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
00549 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
00550 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
00551 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
00552 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
00553 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
00554 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
00555 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
00556 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
00557 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
00558 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
00559 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
00560 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
00561 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
00562 0x2d02ef8dL
00563 };