file_cmds-60.tar.gz
[apple/file_cmds.git] / file / compress.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /* $OpenBSD: compress.c,v 1.3 1997/02/09 23:58:19 millert Exp $ */
25
26 /*
27 * compress routines:
28 * zmagic() - returns 0 if not recognized, uncompresses and prints
29 * information if recognized
30 * uncompress(method, old, n, newch) - uncompress old into new,
31 * using method, return sizeof new
32 */
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include <sys/wait.h>
38
39 #include "file.h"
40
41 static struct {
42 char *magic;
43 int maglen;
44 char *argv[3];
45 int silent;
46 } compr[] = {
47 { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */
48 { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */
49 { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */
50 { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */
51 /* the standard pack utilities do not accept standard input */
52 { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */
53 };
54
55 static int ncompr = sizeof(compr) / sizeof(compr[0]);
56
57
58 static int uncompress __P((int, const unsigned char *, unsigned char **, int));
59
60 int
61 zmagic(buf, nbytes)
62 unsigned char *buf;
63 int nbytes;
64 {
65 unsigned char *newbuf;
66 int newsize;
67 int i;
68
69 for (i = 0; i < ncompr; i++) {
70 if (nbytes < compr[i].maglen)
71 continue;
72 if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0)
73 break;
74 }
75
76 if (i == ncompr)
77 return 0;
78
79 if ((newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) {
80 tryit(newbuf, newsize, 1);
81 free(newbuf);
82 printf(" (");
83 tryit(buf, nbytes, 0);
84 printf(")");
85 }
86 return 1;
87 }
88
89
90 static int
91 uncompress(method, old, newch, n)
92 int method;
93 const unsigned char *old;
94 unsigned char **newch;
95 int n;
96 {
97 int fdin[2], fdout[2];
98
99 if (pipe(fdin) == -1 || pipe(fdout) == -1) {
100 error("cannot create pipe (%s).\n", strerror(errno));
101 /*NOTREACHED*/
102 }
103 switch (fork()) {
104 case 0: /* child */
105 (void) close(0);
106 (void) dup(fdin[0]);
107 (void) close(fdin[0]);
108 (void) close(fdin[1]);
109
110 (void) close(1);
111 (void) dup(fdout[1]);
112 (void) close(fdout[0]);
113 (void) close(fdout[1]);
114 if (compr[method].silent)
115 (void) close(2);
116
117 execvp(compr[method].argv[0], compr[method].argv);
118 error("could not execute `%s' (%s).\n",
119 compr[method].argv[0], strerror(errno));
120 /*NOTREACHED*/
121 case -1:
122 error("could not fork (%s).\n", strerror(errno));
123 /*NOTREACHED*/
124
125 default: /* parent */
126 (void) close(fdin[0]);
127 (void) close(fdout[1]);
128 if (write(fdin[1], old, n) != n) {
129 error("write failed (%s).\n", strerror(errno));
130 /*NOTREACHED*/
131 }
132 (void) close(fdin[1]);
133 if ((*newch = (unsigned char *) malloc(n)) == NULL) {
134 error("out of memory.\n");
135 /*NOTREACHED*/
136 }
137 if ((n = read(fdout[0], *newch, n)) <= 0) {
138 free(*newch);
139 error("read failed (%s).\n", strerror(errno));
140 /*NOTREACHED*/
141 }
142 (void) close(fdout[0]);
143 (void) wait(NULL);
144 return n;
145 }
146 }