X-Git-Url: https://git.saurik.com/apple/file_cmds.git/blobdiff_plain/fc155071fbbd3dce883ee597b09ca00b6a85119e..440bd1982b8e55068af44543d97888092d61feee:/file/compress.c?ds=sidebyside diff --git a/file/compress.c b/file/compress.c new file mode 100644 index 0000000..4088f2d --- /dev/null +++ b/file/compress.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 1.1 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* $OpenBSD: compress.c,v 1.3 1997/02/09 23:58:19 millert Exp $ */ + +/* + * compress routines: + * zmagic() - returns 0 if not recognized, uncompresses and prints + * information if recognized + * uncompress(method, old, n, newch) - uncompress old into new, + * using method, return sizeof new + */ +#include +#include +#include +#include +#include + +#include "file.h" + +static struct { + char *magic; + int maglen; + char *argv[3]; + int silent; +} compr[] = { + { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */ + { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */ + { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */ + { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */ + /* the standard pack utilities do not accept standard input */ + { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */ +}; + +static int ncompr = sizeof(compr) / sizeof(compr[0]); + + +static int uncompress __P((int, const unsigned char *, unsigned char **, int)); + +int +zmagic(buf, nbytes) +unsigned char *buf; +int nbytes; +{ + unsigned char *newbuf; + int newsize; + int i; + + for (i = 0; i < ncompr; i++) { + if (nbytes < compr[i].maglen) + continue; + if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0) + break; + } + + if (i == ncompr) + return 0; + + if ((newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) { + tryit(newbuf, newsize, 1); + free(newbuf); + printf(" ("); + tryit(buf, nbytes, 0); + printf(")"); + } + return 1; +} + + +static int +uncompress(method, old, newch, n) +int method; +const unsigned char *old; +unsigned char **newch; +int n; +{ + int fdin[2], fdout[2]; + + if (pipe(fdin) == -1 || pipe(fdout) == -1) { + error("cannot create pipe (%s).\n", strerror(errno)); + /*NOTREACHED*/ + } + switch (fork()) { + case 0: /* child */ + (void) close(0); + (void) dup(fdin[0]); + (void) close(fdin[0]); + (void) close(fdin[1]); + + (void) close(1); + (void) dup(fdout[1]); + (void) close(fdout[0]); + (void) close(fdout[1]); + if (compr[method].silent) + (void) close(2); + + execvp(compr[method].argv[0], compr[method].argv); + error("could not execute `%s' (%s).\n", + compr[method].argv[0], strerror(errno)); + /*NOTREACHED*/ + case -1: + error("could not fork (%s).\n", strerror(errno)); + /*NOTREACHED*/ + + default: /* parent */ + (void) close(fdin[0]); + (void) close(fdout[1]); + if (write(fdin[1], old, n) != n) { + error("write failed (%s).\n", strerror(errno)); + /*NOTREACHED*/ + } + (void) close(fdin[1]); + if ((*newch = (unsigned char *) malloc(n)) == NULL) { + error("out of memory.\n"); + /*NOTREACHED*/ + } + if ((n = read(fdout[0], *newch, n)) <= 0) { + free(*newch); + error("read failed (%s).\n", strerror(errno)); + /*NOTREACHED*/ + } + (void) close(fdout[0]); + (void) wait(NULL); + return n; + } +}