compress.c (169942) | compress.c (169962) |
---|---|
1/* 2 * Copyright (c) Ian F. Darwin 1986-1995. 3 * Software written by Ian F. Darwin and others; 4 * maintained 1995-present by Christos Zoulas and others. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 32 unchanged lines hidden (view full) --- 41#endif 42#include <string.h> 43#include <errno.h> 44#include <sys/types.h> 45#include <sys/ioctl.h> 46#ifdef HAVE_SYS_WAIT_H 47#include <sys/wait.h> 48#endif | 1/* 2 * Copyright (c) Ian F. Darwin 1986-1995. 3 * Software written by Ian F. Darwin and others; 4 * maintained 1995-present by Christos Zoulas and others. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 32 unchanged lines hidden (view full) --- 41#endif 42#include <string.h> 43#include <errno.h> 44#include <sys/types.h> 45#include <sys/ioctl.h> 46#ifdef HAVE_SYS_WAIT_H 47#include <sys/wait.h> 48#endif |
49#if defined(HAVE_SYS_TIME_H) 50#include <sys/time.h> 51#endif |
|
49#ifdef HAVE_LIBZ 50#include <zlib.h> 51#endif 52 | 52#ifdef HAVE_LIBZ 53#include <zlib.h> 54#endif 55 |
56 |
|
53#ifndef lint | 57#ifndef lint |
54FILE_RCSID("@(#)$Id: compress.c,v 1.45 2006/10/31 19:37:17 christos Exp $") | 58FILE_RCSID("@(#)$File: compress.c,v 1.51 2007/03/05 02:41:29 christos Exp $") |
55#endif 56 57private struct { 58 const char *magic; 59 size_t maglen; 60 const char *const argv[3]; 61 int silent; 62} compr[] = { --- 6 unchanged lines hidden (view full) --- 69 { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */ 70 /* the standard pack utilities do not accept standard input */ 71 { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */ 72 { "PK\3\4", 4, { "gzip", "-cdq", NULL }, 1 }, /* pkzipped, */ 73 /* ...only first file examined */ 74 { "BZh", 3, { "bzip2", "-cd", NULL }, 1 }, /* bzip2-ed */ 75}; 76 | 59#endif 60 61private struct { 62 const char *magic; 63 size_t maglen; 64 const char *const argv[3]; 65 int silent; 66} compr[] = { --- 6 unchanged lines hidden (view full) --- 73 { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */ 74 /* the standard pack utilities do not accept standard input */ 75 { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */ 76 { "PK\3\4", 4, { "gzip", "-cdq", NULL }, 1 }, /* pkzipped, */ 77 /* ...only first file examined */ 78 { "BZh", 3, { "bzip2", "-cd", NULL }, 1 }, /* bzip2-ed */ 79}; 80 |
77private int ncompr = sizeof(compr) / sizeof(compr[0]); | 81private size_t ncompr = sizeof(compr) / sizeof(compr[0]); |
78 79#define NODATA ((size_t)~0) 80 81 82private ssize_t swrite(int, const void *, size_t); 83private size_t uncompressbuf(struct magic_set *, int, size_t, 84 const unsigned char *, unsigned char **, size_t); 85#ifdef HAVE_LIBZ 86private size_t uncompressgzipped(struct magic_set *, const unsigned char *, 87 unsigned char **, size_t); 88#endif 89 90protected int | 82 83#define NODATA ((size_t)~0) 84 85 86private ssize_t swrite(int, const void *, size_t); 87private size_t uncompressbuf(struct magic_set *, int, size_t, 88 const unsigned char *, unsigned char **, size_t); 89#ifdef HAVE_LIBZ 90private size_t uncompressgzipped(struct magic_set *, const unsigned char *, 91 unsigned char **, size_t); 92#endif 93 94protected int |
91file_zmagic(struct magic_set *ms, int fd, const unsigned char *buf, 92 size_t nbytes) | 95file_zmagic(struct magic_set *ms, int fd, const char *name, 96 const unsigned char *buf, size_t nbytes) |
93{ 94 unsigned char *newbuf = NULL; 95 size_t i, nsz; 96 int rv = 0; 97 98 if ((ms->flags & MAGIC_COMPRESS) == 0) 99 return 0; 100 101 for (i = 0; i < ncompr; i++) { 102 if (nbytes < compr[i].maglen) 103 continue; 104 if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 && 105 (nsz = uncompressbuf(ms, fd, i, buf, &newbuf, 106 nbytes)) != NODATA) { 107 ms->flags &= ~MAGIC_COMPRESS; 108 rv = -1; | 97{ 98 unsigned char *newbuf = NULL; 99 size_t i, nsz; 100 int rv = 0; 101 102 if ((ms->flags & MAGIC_COMPRESS) == 0) 103 return 0; 104 105 for (i = 0; i < ncompr; i++) { 106 if (nbytes < compr[i].maglen) 107 continue; 108 if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 && 109 (nsz = uncompressbuf(ms, fd, i, buf, &newbuf, 110 nbytes)) != NODATA) { 111 ms->flags &= ~MAGIC_COMPRESS; 112 rv = -1; |
109 if (file_buffer(ms, -1, newbuf, nsz) == -1) | 113 if (file_buffer(ms, -1, name, newbuf, nsz) == -1) |
110 goto error; 111 if (file_printf(ms, " (") == -1) 112 goto error; | 114 goto error; 115 if (file_printf(ms, " (") == -1) 116 goto error; |
113 if (file_buffer(ms, -1, buf, nbytes) == -1) | 117 if (file_buffer(ms, -1, NULL, buf, nbytes) == -1) |
114 goto error; 115 if (file_printf(ms, ")") == -1) 116 goto error; 117 rv = 1; 118 break; 119 } 120 } 121error: --- 27 unchanged lines hidden (view full) --- 149 return rn; 150} 151 152 153/* 154 * `safe' read for sockets and pipes. 155 */ 156protected ssize_t | 118 goto error; 119 if (file_printf(ms, ")") == -1) 120 goto error; 121 rv = 1; 122 break; 123 } 124 } 125error: --- 27 unchanged lines hidden (view full) --- 153 return rn; 154} 155 156 157/* 158 * `safe' read for sockets and pipes. 159 */ 160protected ssize_t |
157sread(int fd, void *buf, size_t n) | 161sread(int fd, void *buf, size_t n, int canbepipe) |
158{ | 162{ |
159 int rv; | 163 int rv, cnt; |
160#ifdef FIONREAD 161 int t = 0; 162#endif 163 size_t rn = n; 164 165 if (fd == STDIN_FILENO) 166 goto nocheck; 167 168#ifdef FIONREAD | 164#ifdef FIONREAD 165 int t = 0; 166#endif 167 size_t rn = n; 168 169 if (fd == STDIN_FILENO) 170 goto nocheck; 171 172#ifdef FIONREAD |
169 if ((ioctl(fd, FIONREAD, &t) < 0) || (t == 0)) { | 173 if ((canbepipe && (ioctl(fd, FIONREAD, &t) == -1)) || (t == 0)) { |
170#ifdef FD_ZERO | 174#ifdef FD_ZERO |
171 for (;;) { | 175 for (cnt = 0;; cnt++) { |
172 fd_set check; 173 struct timeval tout = {0, 100 * 1000}; | 176 fd_set check; 177 struct timeval tout = {0, 100 * 1000}; |
178 int selrv; |
|
174 175 FD_ZERO(&check); 176 FD_SET(fd, &check); 177 178 /* 179 * Avoid soft deadlock: do not read if there 180 * is nothing to read from sockets and pipes. 181 */ | 179 180 FD_ZERO(&check); 181 FD_SET(fd, &check); 182 183 /* 184 * Avoid soft deadlock: do not read if there 185 * is nothing to read from sockets and pipes. 186 */ |
182 if (select(fd + 1, &check, NULL, NULL, &tout) <= 0) { | 187 selrv = select(fd + 1, &check, NULL, NULL, &tout); 188 if (selrv == -1) { |
183 if (errno == EINTR || errno == EAGAIN) 184 continue; | 189 if (errno == EINTR || errno == EAGAIN) 190 continue; |
191 } else if (selrv == 0 && cnt >= 5) { |
|
185 return 0; | 192 return 0; |
186 } 187 break; | 193 } else 194 break; |
188 } 189#endif 190 (void)ioctl(fd, FIONREAD, &t); 191 } 192 193 if (t > 0 && (size_t)t < n) { 194 n = t; 195 rn = n; --- 44 unchanged lines hidden (view full) --- 240 file_error(ms, errno, 241 "cannot create temporary file for pipe copy"); 242 return -1; 243 } 244 245 if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes) 246 r = 1; 247 else { | 195 } 196#endif 197 (void)ioctl(fd, FIONREAD, &t); 198 } 199 200 if (t > 0 && (size_t)t < n) { 201 n = t; 202 rn = n; --- 44 unchanged lines hidden (view full) --- 247 file_error(ms, errno, 248 "cannot create temporary file for pipe copy"); 249 return -1; 250 } 251 252 if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes) 253 r = 1; 254 else { |
248 while ((r = sread(fd, buf, sizeof(buf))) > 0) | 255 while ((r = sread(fd, buf, sizeof(buf), 1)) > 0) |
249 if (swrite(tfd, buf, (size_t)r) != r) 250 break; 251 } 252 253 switch (r) { 254 case -1: 255 file_error(ms, errno, "error copying from pipe to temp file"); 256 return -1; --- 79 unchanged lines hidden (view full) --- 336 337 rc = inflate(&z, Z_SYNC_FLUSH); 338 if (rc != Z_OK && rc != Z_STREAM_END) { 339 file_error(ms, 0, "zlib: %s", z.msg); 340 return 0; 341 } 342 343 n = (size_t)z.total_out; | 256 if (swrite(tfd, buf, (size_t)r) != r) 257 break; 258 } 259 260 switch (r) { 261 case -1: 262 file_error(ms, errno, "error copying from pipe to temp file"); 263 return -1; --- 79 unchanged lines hidden (view full) --- 343 344 rc = inflate(&z, Z_SYNC_FLUSH); 345 if (rc != Z_OK && rc != Z_STREAM_END) { 346 file_error(ms, 0, "zlib: %s", z.msg); 347 return 0; 348 } 349 350 n = (size_t)z.total_out; |
344 inflateEnd(&z); | 351 (void)inflateEnd(&z); |
345 346 /* let's keep the nul-terminate tradition */ 347 (*newch)[n] = '\0'; 348 349 return n; 350} 351#endif 352 --- 31 unchanged lines hidden (view full) --- 384 (void) dup(fdout[1]); 385 (void) close(fdout[0]); 386 (void) close(fdout[1]); 387#ifndef DEBUG 388 if (compr[method].silent) 389 (void)close(2); 390#endif 391 | 352 353 /* let's keep the nul-terminate tradition */ 354 (*newch)[n] = '\0'; 355 356 return n; 357} 358#endif 359 --- 31 unchanged lines hidden (view full) --- 391 (void) dup(fdout[1]); 392 (void) close(fdout[0]); 393 (void) close(fdout[1]); 394#ifndef DEBUG 395 if (compr[method].silent) 396 (void)close(2); 397#endif 398 |
392 execvp(compr[method].argv[0], 393 (char *const *)(intptr_t)compr[method].argv); | 399 (void)execvp(compr[method].argv[0], 400 (char *const *)(intptr_t)compr[method].argv); |
394#ifdef DEBUG 395 (void)fprintf(stderr, "exec `%s' failed (%s)\n", 396 compr[method].argv[0], strerror(errno)); 397#endif 398 exit(1); 399 /*NOTREACHED*/ 400 case -1: 401 file_error(ms, errno, "could not fork"); --- 5 unchanged lines hidden (view full) --- 407 (void) close(fdin[0]); 408 /* 409 * fork again, to avoid blocking because both 410 * pipes filled 411 */ 412 switch (fork()) { 413 case 0: /* child */ 414 (void)close(fdout[0]); | 401#ifdef DEBUG 402 (void)fprintf(stderr, "exec `%s' failed (%s)\n", 403 compr[method].argv[0], strerror(errno)); 404#endif 405 exit(1); 406 /*NOTREACHED*/ 407 case -1: 408 file_error(ms, errno, "could not fork"); --- 5 unchanged lines hidden (view full) --- 414 (void) close(fdin[0]); 415 /* 416 * fork again, to avoid blocking because both 417 * pipes filled 418 */ 419 switch (fork()) { 420 case 0: /* child */ 421 (void)close(fdout[0]); |
415 if (swrite(fdin[1], old, n) != n) { | 422 if (swrite(fdin[1], old, n) != (ssize_t)n) { |
416#ifdef DEBUG 417 (void)fprintf(stderr, 418 "Write failed (%s)\n", 419 strerror(errno)); 420#endif 421 exit(1); 422 } 423 exit(0); --- 17 unchanged lines hidden (view full) --- 441 if ((*newch = (unsigned char *) malloc(HOWMANY + 1)) == NULL) { 442#ifdef DEBUG 443 (void)fprintf(stderr, "Malloc failed (%s)\n", 444 strerror(errno)); 445#endif 446 n = 0; 447 goto err; 448 } | 423#ifdef DEBUG 424 (void)fprintf(stderr, 425 "Write failed (%s)\n", 426 strerror(errno)); 427#endif 428 exit(1); 429 } 430 exit(0); --- 17 unchanged lines hidden (view full) --- 448 if ((*newch = (unsigned char *) malloc(HOWMANY + 1)) == NULL) { 449#ifdef DEBUG 450 (void)fprintf(stderr, "Malloc failed (%s)\n", 451 strerror(errno)); 452#endif 453 n = 0; 454 goto err; 455 } |
449 if ((r = sread(fdout[0], *newch, HOWMANY)) <= 0) { | 456 if ((r = sread(fdout[0], *newch, HOWMANY, 0)) <= 0) { |
450#ifdef DEBUG 451 (void)fprintf(stderr, "Read failed (%s)\n", 452 strerror(errno)); 453#endif 454 free(*newch); 455 n = 0; 456 newch[0] = '\0'; 457 goto err; --- 18 unchanged lines hidden --- | 457#ifdef DEBUG 458 (void)fprintf(stderr, "Read failed (%s)\n", 459 strerror(errno)); 460#endif 461 free(*newch); 462 n = 0; 463 newch[0] = '\0'; 464 goto err; --- 18 unchanged lines hidden --- |