security/nss/lib/zlib/minigzip.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* minigzip.c -- simulate gzip using the zlib compression library
michael@0 2 * Copyright (C) 1995-2006, 2010 Jean-loup Gailly.
michael@0 3 * For conditions of distribution and use, see copyright notice in zlib.h
michael@0 4 */
michael@0 5
michael@0 6 /*
michael@0 7 * minigzip is a minimal implementation of the gzip utility. This is
michael@0 8 * only an example of using zlib and isn't meant to replace the
michael@0 9 * full-featured gzip. No attempt is made to deal with file systems
michael@0 10 * limiting names to 14 or 8+3 characters, etc... Error checking is
michael@0 11 * very limited. So use minigzip only for testing; use gzip for the
michael@0 12 * real thing. On MSDOS, use only on file names without extension
michael@0 13 * or in pipe mode.
michael@0 14 */
michael@0 15
michael@0 16 /* @(#) $Id$ */
michael@0 17
michael@0 18 #include "zlib.h"
michael@0 19 #include <stdio.h>
michael@0 20
michael@0 21 #ifdef STDC
michael@0 22 # include <string.h>
michael@0 23 # include <stdlib.h>
michael@0 24 #endif
michael@0 25
michael@0 26 #ifdef USE_MMAP
michael@0 27 # include <sys/types.h>
michael@0 28 # include <sys/mman.h>
michael@0 29 # include <sys/stat.h>
michael@0 30 #endif
michael@0 31
michael@0 32 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
michael@0 33 # include <fcntl.h>
michael@0 34 # include <io.h>
michael@0 35 # ifdef UNDER_CE
michael@0 36 # include <stdlib.h>
michael@0 37 # endif
michael@0 38 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
michael@0 39 #else
michael@0 40 # define SET_BINARY_MODE(file)
michael@0 41 #endif
michael@0 42
michael@0 43 #ifdef VMS
michael@0 44 # define unlink delete
michael@0 45 # define GZ_SUFFIX "-gz"
michael@0 46 #endif
michael@0 47 #ifdef RISCOS
michael@0 48 # define unlink remove
michael@0 49 # define GZ_SUFFIX "-gz"
michael@0 50 # define fileno(file) file->__file
michael@0 51 #endif
michael@0 52 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
michael@0 53 # include <unix.h> /* for fileno */
michael@0 54 #endif
michael@0 55
michael@0 56 #if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
michael@0 57 #ifndef WIN32 /* unlink already in stdio.h for WIN32 */
michael@0 58 extern int unlink OF((const char *));
michael@0 59 #endif
michael@0 60 #endif
michael@0 61
michael@0 62 #if defined(UNDER_CE)
michael@0 63 # include <windows.h>
michael@0 64 # define perror(s) pwinerror(s)
michael@0 65
michael@0 66 /* Map the Windows error number in ERROR to a locale-dependent error
michael@0 67 message string and return a pointer to it. Typically, the values
michael@0 68 for ERROR come from GetLastError.
michael@0 69
michael@0 70 The string pointed to shall not be modified by the application,
michael@0 71 but may be overwritten by a subsequent call to strwinerror
michael@0 72
michael@0 73 The strwinerror function does not change the current setting
michael@0 74 of GetLastError. */
michael@0 75
michael@0 76 static char *strwinerror (error)
michael@0 77 DWORD error;
michael@0 78 {
michael@0 79 static char buf[1024];
michael@0 80
michael@0 81 wchar_t *msgbuf;
michael@0 82 DWORD lasterr = GetLastError();
michael@0 83 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
michael@0 84 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
michael@0 85 NULL,
michael@0 86 error,
michael@0 87 0, /* Default language */
michael@0 88 (LPVOID)&msgbuf,
michael@0 89 0,
michael@0 90 NULL);
michael@0 91 if (chars != 0) {
michael@0 92 /* If there is an \r\n appended, zap it. */
michael@0 93 if (chars >= 2
michael@0 94 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
michael@0 95 chars -= 2;
michael@0 96 msgbuf[chars] = 0;
michael@0 97 }
michael@0 98
michael@0 99 if (chars > sizeof (buf) - 1) {
michael@0 100 chars = sizeof (buf) - 1;
michael@0 101 msgbuf[chars] = 0;
michael@0 102 }
michael@0 103
michael@0 104 wcstombs(buf, msgbuf, chars + 1);
michael@0 105 LocalFree(msgbuf);
michael@0 106 }
michael@0 107 else {
michael@0 108 sprintf(buf, "unknown win32 error (%ld)", error);
michael@0 109 }
michael@0 110
michael@0 111 SetLastError(lasterr);
michael@0 112 return buf;
michael@0 113 }
michael@0 114
michael@0 115 static void pwinerror (s)
michael@0 116 const char *s;
michael@0 117 {
michael@0 118 if (s && *s)
michael@0 119 fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
michael@0 120 else
michael@0 121 fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
michael@0 122 }
michael@0 123
michael@0 124 #endif /* UNDER_CE */
michael@0 125
michael@0 126 #ifndef GZ_SUFFIX
michael@0 127 # define GZ_SUFFIX ".gz"
michael@0 128 #endif
michael@0 129 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
michael@0 130
michael@0 131 #define BUFLEN 16384
michael@0 132 #define MAX_NAME_LEN 1024
michael@0 133
michael@0 134 #ifdef MAXSEG_64K
michael@0 135 # define local static
michael@0 136 /* Needed for systems with limitation on stack size. */
michael@0 137 #else
michael@0 138 # define local
michael@0 139 #endif
michael@0 140
michael@0 141 char *prog;
michael@0 142
michael@0 143 void error OF((const char *msg));
michael@0 144 void gz_compress OF((FILE *in, gzFile out));
michael@0 145 #ifdef USE_MMAP
michael@0 146 int gz_compress_mmap OF((FILE *in, gzFile out));
michael@0 147 #endif
michael@0 148 void gz_uncompress OF((gzFile in, FILE *out));
michael@0 149 void file_compress OF((char *file, char *mode));
michael@0 150 void file_uncompress OF((char *file));
michael@0 151 int main OF((int argc, char *argv[]));
michael@0 152
michael@0 153 /* ===========================================================================
michael@0 154 * Display error message and exit
michael@0 155 */
michael@0 156 void error(msg)
michael@0 157 const char *msg;
michael@0 158 {
michael@0 159 fprintf(stderr, "%s: %s\n", prog, msg);
michael@0 160 exit(1);
michael@0 161 }
michael@0 162
michael@0 163 /* ===========================================================================
michael@0 164 * Compress input to output then close both files.
michael@0 165 */
michael@0 166
michael@0 167 void gz_compress(in, out)
michael@0 168 FILE *in;
michael@0 169 gzFile out;
michael@0 170 {
michael@0 171 local char buf[BUFLEN];
michael@0 172 int len;
michael@0 173 int err;
michael@0 174
michael@0 175 #ifdef USE_MMAP
michael@0 176 /* Try first compressing with mmap. If mmap fails (minigzip used in a
michael@0 177 * pipe), use the normal fread loop.
michael@0 178 */
michael@0 179 if (gz_compress_mmap(in, out) == Z_OK) return;
michael@0 180 #endif
michael@0 181 for (;;) {
michael@0 182 len = (int)fread(buf, 1, sizeof(buf), in);
michael@0 183 if (ferror(in)) {
michael@0 184 perror("fread");
michael@0 185 exit(1);
michael@0 186 }
michael@0 187 if (len == 0) break;
michael@0 188
michael@0 189 if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
michael@0 190 }
michael@0 191 fclose(in);
michael@0 192 if (gzclose(out) != Z_OK) error("failed gzclose");
michael@0 193 }
michael@0 194
michael@0 195 #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
michael@0 196
michael@0 197 /* Try compressing the input file at once using mmap. Return Z_OK if
michael@0 198 * if success, Z_ERRNO otherwise.
michael@0 199 */
michael@0 200 int gz_compress_mmap(in, out)
michael@0 201 FILE *in;
michael@0 202 gzFile out;
michael@0 203 {
michael@0 204 int len;
michael@0 205 int err;
michael@0 206 int ifd = fileno(in);
michael@0 207 caddr_t buf; /* mmap'ed buffer for the entire input file */
michael@0 208 off_t buf_len; /* length of the input file */
michael@0 209 struct stat sb;
michael@0 210
michael@0 211 /* Determine the size of the file, needed for mmap: */
michael@0 212 if (fstat(ifd, &sb) < 0) return Z_ERRNO;
michael@0 213 buf_len = sb.st_size;
michael@0 214 if (buf_len <= 0) return Z_ERRNO;
michael@0 215
michael@0 216 /* Now do the actual mmap: */
michael@0 217 buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
michael@0 218 if (buf == (caddr_t)(-1)) return Z_ERRNO;
michael@0 219
michael@0 220 /* Compress the whole file at once: */
michael@0 221 len = gzwrite(out, (char *)buf, (unsigned)buf_len);
michael@0 222
michael@0 223 if (len != (int)buf_len) error(gzerror(out, &err));
michael@0 224
michael@0 225 munmap(buf, buf_len);
michael@0 226 fclose(in);
michael@0 227 if (gzclose(out) != Z_OK) error("failed gzclose");
michael@0 228 return Z_OK;
michael@0 229 }
michael@0 230 #endif /* USE_MMAP */
michael@0 231
michael@0 232 /* ===========================================================================
michael@0 233 * Uncompress input to output then close both files.
michael@0 234 */
michael@0 235 void gz_uncompress(in, out)
michael@0 236 gzFile in;
michael@0 237 FILE *out;
michael@0 238 {
michael@0 239 local char buf[BUFLEN];
michael@0 240 int len;
michael@0 241 int err;
michael@0 242
michael@0 243 for (;;) {
michael@0 244 len = gzread(in, buf, sizeof(buf));
michael@0 245 if (len < 0) error (gzerror(in, &err));
michael@0 246 if (len == 0) break;
michael@0 247
michael@0 248 if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
michael@0 249 error("failed fwrite");
michael@0 250 }
michael@0 251 }
michael@0 252 if (fclose(out)) error("failed fclose");
michael@0 253
michael@0 254 if (gzclose(in) != Z_OK) error("failed gzclose");
michael@0 255 }
michael@0 256
michael@0 257
michael@0 258 /* ===========================================================================
michael@0 259 * Compress the given file: create a corresponding .gz file and remove the
michael@0 260 * original.
michael@0 261 */
michael@0 262 void file_compress(file, mode)
michael@0 263 char *file;
michael@0 264 char *mode;
michael@0 265 {
michael@0 266 local char outfile[MAX_NAME_LEN];
michael@0 267 FILE *in;
michael@0 268 gzFile out;
michael@0 269
michael@0 270 if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
michael@0 271 fprintf(stderr, "%s: filename too long\n", prog);
michael@0 272 exit(1);
michael@0 273 }
michael@0 274
michael@0 275 strcpy(outfile, file);
michael@0 276 strcat(outfile, GZ_SUFFIX);
michael@0 277
michael@0 278 in = fopen(file, "rb");
michael@0 279 if (in == NULL) {
michael@0 280 perror(file);
michael@0 281 exit(1);
michael@0 282 }
michael@0 283 out = gzopen(outfile, mode);
michael@0 284 if (out == NULL) {
michael@0 285 fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
michael@0 286 exit(1);
michael@0 287 }
michael@0 288 gz_compress(in, out);
michael@0 289
michael@0 290 unlink(file);
michael@0 291 }
michael@0 292
michael@0 293
michael@0 294 /* ===========================================================================
michael@0 295 * Uncompress the given file and remove the original.
michael@0 296 */
michael@0 297 void file_uncompress(file)
michael@0 298 char *file;
michael@0 299 {
michael@0 300 local char buf[MAX_NAME_LEN];
michael@0 301 char *infile, *outfile;
michael@0 302 FILE *out;
michael@0 303 gzFile in;
michael@0 304 size_t len = strlen(file);
michael@0 305
michael@0 306 if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
michael@0 307 fprintf(stderr, "%s: filename too long\n", prog);
michael@0 308 exit(1);
michael@0 309 }
michael@0 310
michael@0 311 strcpy(buf, file);
michael@0 312
michael@0 313 if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
michael@0 314 infile = file;
michael@0 315 outfile = buf;
michael@0 316 outfile[len-3] = '\0';
michael@0 317 } else {
michael@0 318 outfile = file;
michael@0 319 infile = buf;
michael@0 320 strcat(infile, GZ_SUFFIX);
michael@0 321 }
michael@0 322 in = gzopen(infile, "rb");
michael@0 323 if (in == NULL) {
michael@0 324 fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
michael@0 325 exit(1);
michael@0 326 }
michael@0 327 out = fopen(outfile, "wb");
michael@0 328 if (out == NULL) {
michael@0 329 perror(file);
michael@0 330 exit(1);
michael@0 331 }
michael@0 332
michael@0 333 gz_uncompress(in, out);
michael@0 334
michael@0 335 unlink(infile);
michael@0 336 }
michael@0 337
michael@0 338
michael@0 339 /* ===========================================================================
michael@0 340 * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
michael@0 341 * -c : write to standard output
michael@0 342 * -d : decompress
michael@0 343 * -f : compress with Z_FILTERED
michael@0 344 * -h : compress with Z_HUFFMAN_ONLY
michael@0 345 * -r : compress with Z_RLE
michael@0 346 * -1 to -9 : compression level
michael@0 347 */
michael@0 348
michael@0 349 int main(argc, argv)
michael@0 350 int argc;
michael@0 351 char *argv[];
michael@0 352 {
michael@0 353 int copyout = 0;
michael@0 354 int uncompr = 0;
michael@0 355 gzFile file;
michael@0 356 char *bname, outmode[20];
michael@0 357
michael@0 358 strcpy(outmode, "wb6 ");
michael@0 359
michael@0 360 prog = argv[0];
michael@0 361 bname = strrchr(argv[0], '/');
michael@0 362 if (bname)
michael@0 363 bname++;
michael@0 364 else
michael@0 365 bname = argv[0];
michael@0 366 argc--, argv++;
michael@0 367
michael@0 368 if (!strcmp(bname, "gunzip"))
michael@0 369 uncompr = 1;
michael@0 370 else if (!strcmp(bname, "zcat"))
michael@0 371 copyout = uncompr = 1;
michael@0 372
michael@0 373 while (argc > 0) {
michael@0 374 if (strcmp(*argv, "-c") == 0)
michael@0 375 copyout = 1;
michael@0 376 else if (strcmp(*argv, "-d") == 0)
michael@0 377 uncompr = 1;
michael@0 378 else if (strcmp(*argv, "-f") == 0)
michael@0 379 outmode[3] = 'f';
michael@0 380 else if (strcmp(*argv, "-h") == 0)
michael@0 381 outmode[3] = 'h';
michael@0 382 else if (strcmp(*argv, "-r") == 0)
michael@0 383 outmode[3] = 'R';
michael@0 384 else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
michael@0 385 (*argv)[2] == 0)
michael@0 386 outmode[2] = (*argv)[1];
michael@0 387 else
michael@0 388 break;
michael@0 389 argc--, argv++;
michael@0 390 }
michael@0 391 if (outmode[3] == ' ')
michael@0 392 outmode[3] = 0;
michael@0 393 if (argc == 0) {
michael@0 394 SET_BINARY_MODE(stdin);
michael@0 395 SET_BINARY_MODE(stdout);
michael@0 396 if (uncompr) {
michael@0 397 file = gzdopen(fileno(stdin), "rb");
michael@0 398 if (file == NULL) error("can't gzdopen stdin");
michael@0 399 gz_uncompress(file, stdout);
michael@0 400 } else {
michael@0 401 file = gzdopen(fileno(stdout), outmode);
michael@0 402 if (file == NULL) error("can't gzdopen stdout");
michael@0 403 gz_compress(stdin, file);
michael@0 404 }
michael@0 405 } else {
michael@0 406 if (copyout) {
michael@0 407 SET_BINARY_MODE(stdout);
michael@0 408 }
michael@0 409 do {
michael@0 410 if (uncompr) {
michael@0 411 if (copyout) {
michael@0 412 file = gzopen(*argv, "rb");
michael@0 413 if (file == NULL)
michael@0 414 fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
michael@0 415 else
michael@0 416 gz_uncompress(file, stdout);
michael@0 417 } else {
michael@0 418 file_uncompress(*argv);
michael@0 419 }
michael@0 420 } else {
michael@0 421 if (copyout) {
michael@0 422 FILE * in = fopen(*argv, "rb");
michael@0 423
michael@0 424 if (in == NULL) {
michael@0 425 perror(*argv);
michael@0 426 } else {
michael@0 427 file = gzdopen(fileno(stdout), outmode);
michael@0 428 if (file == NULL) error("can't gzdopen stdout");
michael@0 429
michael@0 430 gz_compress(in, file);
michael@0 431 }
michael@0 432
michael@0 433 } else {
michael@0 434 file_compress(*argv, outmode);
michael@0 435 }
michael@0 436 }
michael@0 437 } while (argv++, --argc);
michael@0 438 }
michael@0 439 return 0;
michael@0 440 }

mercurial