1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/zlib/minigzip.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,440 @@ 1.4 +/* minigzip.c -- simulate gzip using the zlib compression library 1.5 + * Copyright (C) 1995-2006, 2010 Jean-loup Gailly. 1.6 + * For conditions of distribution and use, see copyright notice in zlib.h 1.7 + */ 1.8 + 1.9 +/* 1.10 + * minigzip is a minimal implementation of the gzip utility. This is 1.11 + * only an example of using zlib and isn't meant to replace the 1.12 + * full-featured gzip. No attempt is made to deal with file systems 1.13 + * limiting names to 14 or 8+3 characters, etc... Error checking is 1.14 + * very limited. So use minigzip only for testing; use gzip for the 1.15 + * real thing. On MSDOS, use only on file names without extension 1.16 + * or in pipe mode. 1.17 + */ 1.18 + 1.19 +/* @(#) $Id$ */ 1.20 + 1.21 +#include "zlib.h" 1.22 +#include <stdio.h> 1.23 + 1.24 +#ifdef STDC 1.25 +# include <string.h> 1.26 +# include <stdlib.h> 1.27 +#endif 1.28 + 1.29 +#ifdef USE_MMAP 1.30 +# include <sys/types.h> 1.31 +# include <sys/mman.h> 1.32 +# include <sys/stat.h> 1.33 +#endif 1.34 + 1.35 +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) 1.36 +# include <fcntl.h> 1.37 +# include <io.h> 1.38 +# ifdef UNDER_CE 1.39 +# include <stdlib.h> 1.40 +# endif 1.41 +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) 1.42 +#else 1.43 +# define SET_BINARY_MODE(file) 1.44 +#endif 1.45 + 1.46 +#ifdef VMS 1.47 +# define unlink delete 1.48 +# define GZ_SUFFIX "-gz" 1.49 +#endif 1.50 +#ifdef RISCOS 1.51 +# define unlink remove 1.52 +# define GZ_SUFFIX "-gz" 1.53 +# define fileno(file) file->__file 1.54 +#endif 1.55 +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os 1.56 +# include <unix.h> /* for fileno */ 1.57 +#endif 1.58 + 1.59 +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) 1.60 +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ 1.61 + extern int unlink OF((const char *)); 1.62 +#endif 1.63 +#endif 1.64 + 1.65 +#if defined(UNDER_CE) 1.66 +# include <windows.h> 1.67 +# define perror(s) pwinerror(s) 1.68 + 1.69 +/* Map the Windows error number in ERROR to a locale-dependent error 1.70 + message string and return a pointer to it. Typically, the values 1.71 + for ERROR come from GetLastError. 1.72 + 1.73 + The string pointed to shall not be modified by the application, 1.74 + but may be overwritten by a subsequent call to strwinerror 1.75 + 1.76 + The strwinerror function does not change the current setting 1.77 + of GetLastError. */ 1.78 + 1.79 +static char *strwinerror (error) 1.80 + DWORD error; 1.81 +{ 1.82 + static char buf[1024]; 1.83 + 1.84 + wchar_t *msgbuf; 1.85 + DWORD lasterr = GetLastError(); 1.86 + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 1.87 + | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1.88 + NULL, 1.89 + error, 1.90 + 0, /* Default language */ 1.91 + (LPVOID)&msgbuf, 1.92 + 0, 1.93 + NULL); 1.94 + if (chars != 0) { 1.95 + /* If there is an \r\n appended, zap it. */ 1.96 + if (chars >= 2 1.97 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { 1.98 + chars -= 2; 1.99 + msgbuf[chars] = 0; 1.100 + } 1.101 + 1.102 + if (chars > sizeof (buf) - 1) { 1.103 + chars = sizeof (buf) - 1; 1.104 + msgbuf[chars] = 0; 1.105 + } 1.106 + 1.107 + wcstombs(buf, msgbuf, chars + 1); 1.108 + LocalFree(msgbuf); 1.109 + } 1.110 + else { 1.111 + sprintf(buf, "unknown win32 error (%ld)", error); 1.112 + } 1.113 + 1.114 + SetLastError(lasterr); 1.115 + return buf; 1.116 +} 1.117 + 1.118 +static void pwinerror (s) 1.119 + const char *s; 1.120 +{ 1.121 + if (s && *s) 1.122 + fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); 1.123 + else 1.124 + fprintf(stderr, "%s\n", strwinerror(GetLastError ())); 1.125 +} 1.126 + 1.127 +#endif /* UNDER_CE */ 1.128 + 1.129 +#ifndef GZ_SUFFIX 1.130 +# define GZ_SUFFIX ".gz" 1.131 +#endif 1.132 +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) 1.133 + 1.134 +#define BUFLEN 16384 1.135 +#define MAX_NAME_LEN 1024 1.136 + 1.137 +#ifdef MAXSEG_64K 1.138 +# define local static 1.139 + /* Needed for systems with limitation on stack size. */ 1.140 +#else 1.141 +# define local 1.142 +#endif 1.143 + 1.144 +char *prog; 1.145 + 1.146 +void error OF((const char *msg)); 1.147 +void gz_compress OF((FILE *in, gzFile out)); 1.148 +#ifdef USE_MMAP 1.149 +int gz_compress_mmap OF((FILE *in, gzFile out)); 1.150 +#endif 1.151 +void gz_uncompress OF((gzFile in, FILE *out)); 1.152 +void file_compress OF((char *file, char *mode)); 1.153 +void file_uncompress OF((char *file)); 1.154 +int main OF((int argc, char *argv[])); 1.155 + 1.156 +/* =========================================================================== 1.157 + * Display error message and exit 1.158 + */ 1.159 +void error(msg) 1.160 + const char *msg; 1.161 +{ 1.162 + fprintf(stderr, "%s: %s\n", prog, msg); 1.163 + exit(1); 1.164 +} 1.165 + 1.166 +/* =========================================================================== 1.167 + * Compress input to output then close both files. 1.168 + */ 1.169 + 1.170 +void gz_compress(in, out) 1.171 + FILE *in; 1.172 + gzFile out; 1.173 +{ 1.174 + local char buf[BUFLEN]; 1.175 + int len; 1.176 + int err; 1.177 + 1.178 +#ifdef USE_MMAP 1.179 + /* Try first compressing with mmap. If mmap fails (minigzip used in a 1.180 + * pipe), use the normal fread loop. 1.181 + */ 1.182 + if (gz_compress_mmap(in, out) == Z_OK) return; 1.183 +#endif 1.184 + for (;;) { 1.185 + len = (int)fread(buf, 1, sizeof(buf), in); 1.186 + if (ferror(in)) { 1.187 + perror("fread"); 1.188 + exit(1); 1.189 + } 1.190 + if (len == 0) break; 1.191 + 1.192 + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); 1.193 + } 1.194 + fclose(in); 1.195 + if (gzclose(out) != Z_OK) error("failed gzclose"); 1.196 +} 1.197 + 1.198 +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */ 1.199 + 1.200 +/* Try compressing the input file at once using mmap. Return Z_OK if 1.201 + * if success, Z_ERRNO otherwise. 1.202 + */ 1.203 +int gz_compress_mmap(in, out) 1.204 + FILE *in; 1.205 + gzFile out; 1.206 +{ 1.207 + int len; 1.208 + int err; 1.209 + int ifd = fileno(in); 1.210 + caddr_t buf; /* mmap'ed buffer for the entire input file */ 1.211 + off_t buf_len; /* length of the input file */ 1.212 + struct stat sb; 1.213 + 1.214 + /* Determine the size of the file, needed for mmap: */ 1.215 + if (fstat(ifd, &sb) < 0) return Z_ERRNO; 1.216 + buf_len = sb.st_size; 1.217 + if (buf_len <= 0) return Z_ERRNO; 1.218 + 1.219 + /* Now do the actual mmap: */ 1.220 + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); 1.221 + if (buf == (caddr_t)(-1)) return Z_ERRNO; 1.222 + 1.223 + /* Compress the whole file at once: */ 1.224 + len = gzwrite(out, (char *)buf, (unsigned)buf_len); 1.225 + 1.226 + if (len != (int)buf_len) error(gzerror(out, &err)); 1.227 + 1.228 + munmap(buf, buf_len); 1.229 + fclose(in); 1.230 + if (gzclose(out) != Z_OK) error("failed gzclose"); 1.231 + return Z_OK; 1.232 +} 1.233 +#endif /* USE_MMAP */ 1.234 + 1.235 +/* =========================================================================== 1.236 + * Uncompress input to output then close both files. 1.237 + */ 1.238 +void gz_uncompress(in, out) 1.239 + gzFile in; 1.240 + FILE *out; 1.241 +{ 1.242 + local char buf[BUFLEN]; 1.243 + int len; 1.244 + int err; 1.245 + 1.246 + for (;;) { 1.247 + len = gzread(in, buf, sizeof(buf)); 1.248 + if (len < 0) error (gzerror(in, &err)); 1.249 + if (len == 0) break; 1.250 + 1.251 + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { 1.252 + error("failed fwrite"); 1.253 + } 1.254 + } 1.255 + if (fclose(out)) error("failed fclose"); 1.256 + 1.257 + if (gzclose(in) != Z_OK) error("failed gzclose"); 1.258 +} 1.259 + 1.260 + 1.261 +/* =========================================================================== 1.262 + * Compress the given file: create a corresponding .gz file and remove the 1.263 + * original. 1.264 + */ 1.265 +void file_compress(file, mode) 1.266 + char *file; 1.267 + char *mode; 1.268 +{ 1.269 + local char outfile[MAX_NAME_LEN]; 1.270 + FILE *in; 1.271 + gzFile out; 1.272 + 1.273 + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { 1.274 + fprintf(stderr, "%s: filename too long\n", prog); 1.275 + exit(1); 1.276 + } 1.277 + 1.278 + strcpy(outfile, file); 1.279 + strcat(outfile, GZ_SUFFIX); 1.280 + 1.281 + in = fopen(file, "rb"); 1.282 + if (in == NULL) { 1.283 + perror(file); 1.284 + exit(1); 1.285 + } 1.286 + out = gzopen(outfile, mode); 1.287 + if (out == NULL) { 1.288 + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); 1.289 + exit(1); 1.290 + } 1.291 + gz_compress(in, out); 1.292 + 1.293 + unlink(file); 1.294 +} 1.295 + 1.296 + 1.297 +/* =========================================================================== 1.298 + * Uncompress the given file and remove the original. 1.299 + */ 1.300 +void file_uncompress(file) 1.301 + char *file; 1.302 +{ 1.303 + local char buf[MAX_NAME_LEN]; 1.304 + char *infile, *outfile; 1.305 + FILE *out; 1.306 + gzFile in; 1.307 + size_t len = strlen(file); 1.308 + 1.309 + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { 1.310 + fprintf(stderr, "%s: filename too long\n", prog); 1.311 + exit(1); 1.312 + } 1.313 + 1.314 + strcpy(buf, file); 1.315 + 1.316 + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { 1.317 + infile = file; 1.318 + outfile = buf; 1.319 + outfile[len-3] = '\0'; 1.320 + } else { 1.321 + outfile = file; 1.322 + infile = buf; 1.323 + strcat(infile, GZ_SUFFIX); 1.324 + } 1.325 + in = gzopen(infile, "rb"); 1.326 + if (in == NULL) { 1.327 + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); 1.328 + exit(1); 1.329 + } 1.330 + out = fopen(outfile, "wb"); 1.331 + if (out == NULL) { 1.332 + perror(file); 1.333 + exit(1); 1.334 + } 1.335 + 1.336 + gz_uncompress(in, out); 1.337 + 1.338 + unlink(infile); 1.339 +} 1.340 + 1.341 + 1.342 +/* =========================================================================== 1.343 + * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] 1.344 + * -c : write to standard output 1.345 + * -d : decompress 1.346 + * -f : compress with Z_FILTERED 1.347 + * -h : compress with Z_HUFFMAN_ONLY 1.348 + * -r : compress with Z_RLE 1.349 + * -1 to -9 : compression level 1.350 + */ 1.351 + 1.352 +int main(argc, argv) 1.353 + int argc; 1.354 + char *argv[]; 1.355 +{ 1.356 + int copyout = 0; 1.357 + int uncompr = 0; 1.358 + gzFile file; 1.359 + char *bname, outmode[20]; 1.360 + 1.361 + strcpy(outmode, "wb6 "); 1.362 + 1.363 + prog = argv[0]; 1.364 + bname = strrchr(argv[0], '/'); 1.365 + if (bname) 1.366 + bname++; 1.367 + else 1.368 + bname = argv[0]; 1.369 + argc--, argv++; 1.370 + 1.371 + if (!strcmp(bname, "gunzip")) 1.372 + uncompr = 1; 1.373 + else if (!strcmp(bname, "zcat")) 1.374 + copyout = uncompr = 1; 1.375 + 1.376 + while (argc > 0) { 1.377 + if (strcmp(*argv, "-c") == 0) 1.378 + copyout = 1; 1.379 + else if (strcmp(*argv, "-d") == 0) 1.380 + uncompr = 1; 1.381 + else if (strcmp(*argv, "-f") == 0) 1.382 + outmode[3] = 'f'; 1.383 + else if (strcmp(*argv, "-h") == 0) 1.384 + outmode[3] = 'h'; 1.385 + else if (strcmp(*argv, "-r") == 0) 1.386 + outmode[3] = 'R'; 1.387 + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && 1.388 + (*argv)[2] == 0) 1.389 + outmode[2] = (*argv)[1]; 1.390 + else 1.391 + break; 1.392 + argc--, argv++; 1.393 + } 1.394 + if (outmode[3] == ' ') 1.395 + outmode[3] = 0; 1.396 + if (argc == 0) { 1.397 + SET_BINARY_MODE(stdin); 1.398 + SET_BINARY_MODE(stdout); 1.399 + if (uncompr) { 1.400 + file = gzdopen(fileno(stdin), "rb"); 1.401 + if (file == NULL) error("can't gzdopen stdin"); 1.402 + gz_uncompress(file, stdout); 1.403 + } else { 1.404 + file = gzdopen(fileno(stdout), outmode); 1.405 + if (file == NULL) error("can't gzdopen stdout"); 1.406 + gz_compress(stdin, file); 1.407 + } 1.408 + } else { 1.409 + if (copyout) { 1.410 + SET_BINARY_MODE(stdout); 1.411 + } 1.412 + do { 1.413 + if (uncompr) { 1.414 + if (copyout) { 1.415 + file = gzopen(*argv, "rb"); 1.416 + if (file == NULL) 1.417 + fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); 1.418 + else 1.419 + gz_uncompress(file, stdout); 1.420 + } else { 1.421 + file_uncompress(*argv); 1.422 + } 1.423 + } else { 1.424 + if (copyout) { 1.425 + FILE * in = fopen(*argv, "rb"); 1.426 + 1.427 + if (in == NULL) { 1.428 + perror(*argv); 1.429 + } else { 1.430 + file = gzdopen(fileno(stdout), outmode); 1.431 + if (file == NULL) error("can't gzdopen stdout"); 1.432 + 1.433 + gz_compress(in, file); 1.434 + } 1.435 + 1.436 + } else { 1.437 + file_compress(*argv, outmode); 1.438 + } 1.439 + } 1.440 + } while (argv++, --argc); 1.441 + } 1.442 + return 0; 1.443 +}