X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=util.c;h=46bc89d687edaa8e30f503184811e60459d98866;hb=503506009abee645fc93e835367237aecb0c8564;hp=3adfb264e958d177eaa818204e13fe12c419cac4;hpb=302189d124ed5849c2589ea92e912eb24fdc4ab3;p=debian%2Fgzip diff --git a/util.c b/util.c index 3adfb26..46bc89d 100644 --- a/util.c +++ b/util.c @@ -1,13 +1,22 @@ /* util.c -- utility functions for gzip support - * Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. - * Copyright (C) 1992-1993 Jean-loup Gailly - * This is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License, see the file COPYING. - */ -#ifdef RCSID -static char rcsid[] = "$Id: util.c,v 0.15 1993/06/15 09:04:13 jloup Exp $"; -#endif + Copyright (C) 1997-1999, 2001-2002, 2006, 2009-2012 Free Software + Foundation, Inc. + Copyright (C) 1992-1993 Jean-loup Gailly + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include @@ -15,48 +24,44 @@ static char rcsid[] = "$Id: util.c,v 0.15 1993/06/15 09:04:13 jloup Exp $"; #include "tailor.h" -#ifdef HAVE_LIMITS_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_FCNTL_H -# include -#endif - -#if defined STDC_HEADERS || defined HAVE_STDLIB_H -# include -#else - extern int errno; -#endif +#include +#include +#include +#include +#include #include "gzip.h" -#include "crypt.h" +#include #ifndef CHAR_BIT # define CHAR_BIT 8 #endif -extern ulg crc_32_tab[]; /* crc table, defined below */ +static int write_buffer (int, voidp, unsigned int); + +static const ulg crc_32_tab[]; /* crc table, defined below */ /* =========================================================================== * Copy input to output unchanged: zcat == cat with --force. - * IN assertion: insize bytes have already been read in inbuf. + * IN assertion: insize bytes have already been read in inbuf and inptr bytes + * already processed or copied. */ int copy(in, out) int in, out; /* input and output file descriptors */ { + int got; + errno = 0; - while (insize != 0 && (int)insize != -1) { - write_buf(out, (char*)inbuf, insize); - bytes_out += insize; - insize = read(in, (char*)inbuf, INBUFSIZ); - } - if ((int)insize == -1) { - read_error(); + while (insize > inptr) { + write_buf(out, (char*)inbuf + inptr, insize - inptr); + bytes_out += insize - inptr; + got = read_buffer (in, (char *) inbuf, INBUFSIZ); + if (got == -1) + read_error(); + bytes_in += got; + insize = (unsigned)got; + inptr = 0; } - bytes_in = bytes_out; return OK; } @@ -74,9 +79,9 @@ ulg updcrc(s, n) static ulg crc = (ulg)0xffffffffL; /* shift register contents */ if (s == NULL) { - c = 0xffffffffL; + c = 0xffffffffL; } else { - c = crc; + c = crc; if (n) do { c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); } while (--n); @@ -106,26 +111,51 @@ int fill_inbuf(eof_ok) /* Read as much as possible */ insize = 0; do { - len = read(ifd, (char*)inbuf+insize, INBUFSIZ-insize); - if (len == 0) break; - if (len == -1) { - read_error(); - break; - } - insize += len; + len = read_buffer (ifd, (char *) inbuf + insize, INBUFSIZ - insize); + if (len == 0) break; + if (len == -1) { + read_error(); + break; + } + insize += len; } while (insize < INBUFSIZ); if (insize == 0) { - if (eof_ok) return EOF; - flush_window(); - errno = 0; - read_error(); + if (eof_ok) return EOF; + flush_window(); + errno = 0; + read_error(); } bytes_in += (off_t)insize; inptr = 1; return inbuf[0]; } +/* Like the standard read function, except do not attempt to read more + than SSIZE_MAX bytes at a time. */ +int +read_buffer (fd, buf, cnt) + int fd; + voidp buf; + unsigned int cnt; +{ + if (INT_MAX < cnt) + cnt = INT_MAX; + return read (fd, buf, cnt); +} + +/* Likewise for 'write'. */ +static int +write_buffer (fd, buf, cnt) + int fd; + voidp buf; + unsigned int cnt; +{ + if (INT_MAX < cnt) + cnt = INT_MAX; + return write (fd, buf, cnt); +} + /* =========================================================================== * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. * (used for the compressed data only) @@ -149,7 +179,7 @@ void flush_window() updcrc(window, outcnt); if (!test) { - write_buf(ofd, (char *)window, outcnt); + write_buf(ofd, (char *)window, outcnt); } bytes_out += (off_t)outcnt; outcnt = 0; @@ -166,12 +196,12 @@ void write_buf(fd, buf, cnt) { unsigned n; - while ((n = write(fd, buf, cnt)) != cnt) { - if (n == (unsigned)(-1)) { - write_error(); - } - cnt -= n; - buf = (voidp)((char*)buf+n); + while ((n = write_buffer (fd, buf, cnt)) != cnt) { + if (n == (unsigned)(-1)) { + write_error(); + } + cnt -= n; + buf = (voidp)((char*)buf+n); } } @@ -192,7 +222,8 @@ char *strlwr(s) * any version suffix). For systems with file names that are not * case sensitive, force the base name to lower case. */ -char *base_name(fname) +char * +gzip_base_name (fname) char *fname; { char *p; @@ -224,10 +255,10 @@ int xunlink (filename) { int e = errno; if (chmod (filename, S_IWUSR) != 0) - { - errno = e; - return -1; - } + { + errno = e; + return -1; + } r = unlink (filename); } @@ -255,145 +286,98 @@ void make_simple_name(name) } while (p != name); } - -#if !defined HAVE_STRING_H && !defined STDC_HEADERS - -/* Provide missing strspn and strcspn functions. */ - -# ifndef __STDC__ -# define const -# endif - -int strspn OF((const char *s, const char *accept)); -int strcspn OF((const char *s, const char *reject)); - -/* ======================================================================== - * Return the length of the maximum initial segment - * of s which contains only characters in accept. - */ -int strspn(s, accept) - const char *s; - const char *accept; -{ - register const char *p; - register const char *a; - register int count = 0; - - for (p = s; *p != '\0'; ++p) { - for (a = accept; *a != '\0'; ++a) { - if (*p == *a) break; - } - if (*a == '\0') return count; - ++count; - } - return count; -} - -/* ======================================================================== - * Return the length of the maximum inital segment of s - * which contains no characters from reject. - */ -int strcspn(s, reject) - const char *s; - const char *reject; -{ - register int count = 0; - - while (*s != '\0') { - if (strchr(reject, *s++) != NULL) return count; - ++count; - } - return count; -} - -#endif - /* ======================================================================== * Add an environment variable (if any) before argv, and update argc. - * Return the expanded environment variable to be freed later, or NULL + * Return the expanded environment variable to be freed later, or NULL * if no options were added to argv. */ #define SEPARATOR " \t" /* separators in env variable */ -char *add_envopt(argcp, argvp, env) - int *argcp; /* pointer to argc */ - char ***argvp; /* pointer to argv */ - char *env; /* name of environment variable */ +char *add_envopt( + int *argcp, /* pointer to argc */ + char ***argvp, /* pointer to argv */ + char const *envvar_name) /* name of environment variable */ { char *p; /* running pointer through env variable */ char **oargv; /* runs through old argv array */ char **nargv; /* runs through new argv array */ int oargc = *argcp; /* old argc */ int nargc = 0; /* number of arguments in env variable */ + char *env_val; - env = (char*)getenv(env); - if (env == NULL) return NULL; + env_val = getenv(envvar_name); + if (env_val == NULL) return NULL; - p = (char*)xmalloc(strlen(env)+1); - env = strcpy(p, env); /* keep env variable intact */ + env_val = xstrdup (env_val); - for (p = env; *p; nargc++ ) { /* move through env */ - p += strspn(p, SEPARATOR); /* skip leading separators */ - if (*p == '\0') break; + for (p = env_val; *p; nargc++ ) { /* move through env_val */ + p += strspn(p, SEPARATOR); /* skip leading separators */ + if (*p == '\0') break; - p += strcspn(p, SEPARATOR); /* find end of word */ - if (*p) *p++ = '\0'; /* mark it */ + p += strcspn(p, SEPARATOR); /* find end of word */ + if (*p) *p++ = '\0'; /* mark it */ } if (nargc == 0) { - free(env); - return NULL; + free(env_val); + return NULL; } *argcp += nargc; /* Allocate the new argv array, with an extra element just in case * the original arg list did not end with a NULL. */ - nargv = (char**)calloc(*argcp+1, sizeof(char *)); - if (nargv == NULL) error("out of memory"); + nargv = xcalloc (*argcp + 1, sizeof (char *)); oargv = *argvp; *argvp = nargv; /* Copy the program name first */ - if (oargc-- < 0) error("argc<=0"); + if (oargc-- < 0) + gzip_error ("argc<=0"); *(nargv++) = *(oargv++); /* Then copy the environment args */ - for (p = env; nargc > 0; nargc--) { - p += strspn(p, SEPARATOR); /* skip separators */ - *(nargv++) = p; /* store start */ - while (*p++) ; /* skip over word */ + for (p = env_val; nargc > 0; nargc--) { + p += strspn(p, SEPARATOR); /* skip separators */ + *(nargv++) = p; /* store start */ + while (*p++) ; /* skip over word */ } /* Finally copy the old args and add a NULL (usual convention) */ while (oargc--) *(nargv++) = *(oargv++); *nargv = NULL; - return env; + return env_val; } /* ======================================================================== * Error handlers. */ -void error(m) - char *m; +void +gzip_error (char const *m) { - fprintf(stderr, "\n%s: %s: %s\n", progname, ifname, m); + fprintf (stderr, "\n%s: %s: %s\n", program_name, ifname, m); abort_gzip(); } -void warning (m) - char *m; +void +xalloc_die () { - WARN ((stderr, "%s: %s: warning: %s\n", progname, ifname, m)); + fprintf (stderr, "\n%s: memory_exhausted\n", program_name); + abort_gzip (); +} + +void warning (char const *m) +{ + WARN ((stderr, "%s: %s: warning: %s\n", program_name, ifname, m)); } void read_error() { int e = errno; - fprintf(stderr, "\n%s: ", progname); + fprintf (stderr, "\n%s: ", program_name); if (e != 0) { - errno = e; - perror(ifname); + errno = e; + perror(ifname); } else { - fprintf(stderr, "%s: unexpected end of file\n", ifname); + fprintf(stderr, "%s: unexpected end of file\n", ifname); } abort_gzip(); } @@ -401,7 +385,7 @@ void read_error() void write_error() { int e = errno; - fprintf(stderr, "\n%s: ", progname); + fprintf (stderr, "\n%s: ", program_name); errno = e; perror(ofname); abort_gzip(); @@ -429,45 +413,32 @@ void fprint_off(file, offset, width) { char buf[CHAR_BIT * sizeof (off_t)]; char *p = buf + sizeof buf; - int negative = offset < 0; + /* Don't negate offset here; it might overflow. */ - do { - int remainder = offset % 10; - int quotient = offset / 10; - if (offset < 0 && 0 < remainder) { - remainder -= 10; - quotient++; - } - *--p = (remainder < 0 ? -remainder : remainder) + '0'; - width--; - offset = quotient; - } while (offset != 0); - for (width -= negative; 0 < width; width--) { - putc (' ', file); + if (offset < 0) { + do + *--p = '0' - offset % 10; + while ((offset /= 10) != 0); + + *--p = '-'; + } else { + do + *--p = '0' + offset % 10; + while ((offset /= 10) != 0); } - if (negative) { - putc ('-', file); + + width -= buf + sizeof buf - p; + while (0 < width--) { + putc (' ', file); } for (; p < buf + sizeof buf; p++) - putc (*p, file); -} - -/* ======================================================================== - * Semi-safe malloc -- never returns NULL. - */ -voidp xmalloc (size) - unsigned size; -{ - voidp cp = (voidp)malloc (size); - - if (cp == NULL) error("out of memory"); - return cp; + putc (*p, file); } /* ======================================================================== * Table of CRC-32's of all single-byte values (made by makecrc.c) */ -ulg crc_32_tab[] = { +static const ulg crc_32_tab[] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,