Deleted Added
full compact
compress.c (75937) compress.c (80588)
1/*
2 * compress routines:
3 * zmagic() - returns 0 if not recognized, uncompresses and prints
4 * information if recognized
5 * uncompress(method, old, n, newch) - uncompress old into new,
6 * using method, return sizeof new
7 */
8#include "file.h"
9#include <stdio.h>
10#include <stdlib.h>
11#ifdef HAVE_UNISTD_H
12#include <unistd.h>
13#endif
14#include <string.h>
15#ifdef HAVE_SYS_WAIT_H
16#include <sys/wait.h>
17#endif
18#ifndef lint
1/*
2 * compress routines:
3 * zmagic() - returns 0 if not recognized, uncompresses and prints
4 * information if recognized
5 * uncompress(method, old, n, newch) - uncompress old into new,
6 * using method, return sizeof new
7 */
8#include "file.h"
9#include <stdio.h>
10#include <stdlib.h>
11#ifdef HAVE_UNISTD_H
12#include <unistd.h>
13#endif
14#include <string.h>
15#ifdef HAVE_SYS_WAIT_H
16#include <sys/wait.h>
17#endif
18#ifndef lint
19FILE_RCSID("@(#)$Id: compress.c,v 1.19 2001/03/20 04:22:02 christos Exp $")
19FILE_RCSID("@(#)$Id: compress.c,v 1.20 2001/07/22 21:04:15 christos Exp $")
20#endif
21
22
23static struct {
24 const char *magic;
25 int maglen;
26 const char *const argv[3];
27 int silent;
28} compr[] = {
29 { "\037\235", 2, { "gzip", "-cdq", NULL }, 1 }, /* compressed */
30 /* Uncompress can get stuck; so use gzip first if we have it
31 * Idea from Damien Clark, thanks! */
32 { "\037\235", 2, { "uncompress", "-c", NULL }, 1 }, /* compressed */
33 { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */
34 { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */
35 { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */
36 /* the standard pack utilities do not accept standard input */
37 { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */
20#endif
21
22
23static struct {
24 const char *magic;
25 int maglen;
26 const char *const argv[3];
27 int silent;
28} compr[] = {
29 { "\037\235", 2, { "gzip", "-cdq", NULL }, 1 }, /* compressed */
30 /* Uncompress can get stuck; so use gzip first if we have it
31 * Idea from Damien Clark, thanks! */
32 { "\037\235", 2, { "uncompress", "-c", NULL }, 1 }, /* compressed */
33 { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */
34 { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */
35 { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */
36 /* the standard pack utilities do not accept standard input */
37 { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */
38 { "BZh", 3, { "bzip2", "-d", NULL }, 1 }, /* bzip2-ed */
38 { "BZh", 3, { "bzip2", "-cd", NULL }, 1 }, /* bzip2-ed */
39};
40
41static int ncompr = sizeof(compr) / sizeof(compr[0]);
42
43
44static int uncompress __P((int, const unsigned char *, unsigned char **, int));
45static int swrite __P((int, const void *, size_t));
46static int sread __P((int, void *, size_t));
47
48int
49zmagic(buf, nbytes)
50 unsigned char *buf;
51 int nbytes;
52{
53 unsigned char *newbuf;
54 int newsize;
55 int i;
56
57 for (i = 0; i < ncompr; i++) {
58 if (nbytes < compr[i].maglen)
59 continue;
60 if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 &&
61 (newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) {
62 tryit(newbuf, newsize, 1);
63 free(newbuf);
64 printf(" (");
65 tryit(buf, nbytes, 0);
66 printf(")");
67 return 1;
68 }
69 }
70
71 if (i == ncompr)
72 return 0;
73
74 return 1;
75}
76
77/*
78 * `safe' write for sockets and pipes.
79 */
80static int
81swrite(fd, buf, n)
82 int fd;
83 const void *buf;
84 size_t n;
85{
86 int rv;
87 size_t rn = n;
88
89 do
90 switch (rv = write(fd, buf, n)) {
91 case -1:
92 if (errno == EINTR)
93 continue;
94 return -1;
95 default:
96 n -= rv;
97 buf = ((char *)buf) + rv;
98 break;
99 }
100 while (n > 0);
101 return rn;
102}
103
104
105/*
106 * `safe' read for sockets and pipes.
107 */
108static int
109sread(fd, buf, n)
110 int fd;
111 void *buf;
112 size_t n;
113{
114 int rv;
115 size_t rn = n;
116
117 do
118 switch (rv = read(fd, buf, n)) {
119 case -1:
120 if (errno == EINTR)
121 continue;
122 return -1;
123 default:
124 n -= rv;
125 buf = ((char *)buf) + rv;
126 break;
127 }
128 while (n > 0);
129 return rn;
130}
131
132static int
133uncompress(method, old, newch, n)
134 int method;
135 const unsigned char *old;
136 unsigned char **newch;
137 int n;
138{
139 int fdin[2], fdout[2];
140
141 if (pipe(fdin) == -1 || pipe(fdout) == -1) {
142 error("cannot create pipe (%s).\n", strerror(errno));
143 /*NOTREACHED*/
144 }
145 switch (fork()) {
146 case 0: /* child */
147 (void) close(0);
148 (void) dup(fdin[0]);
149 (void) close(fdin[0]);
150 (void) close(fdin[1]);
151
152 (void) close(1);
153 (void) dup(fdout[1]);
154 (void) close(fdout[0]);
155 (void) close(fdout[1]);
156 if (compr[method].silent)
157 (void) close(2);
158
159 execvp(compr[method].argv[0],
160 (char *const *)compr[method].argv);
161 exit(1);
162 /*NOTREACHED*/
163 case -1:
164 error("could not fork (%s).\n", strerror(errno));
165 /*NOTREACHED*/
166
167 default: /* parent */
168 (void) close(fdin[0]);
169 (void) close(fdout[1]);
170 if (swrite(fdin[1], old, n) != n) {
171 n = 0;
172 goto err;
173 }
174 (void) close(fdin[1]);
175 fdin[1] = -1;
176 if ((*newch = (unsigned char *) malloc(n)) == NULL) {
177 n = 0;
178 goto err;
179 }
180 if ((n = sread(fdout[0], *newch, n)) <= 0) {
181 free(*newch);
182 n = 0;
183 goto err;
184 }
185err:
186 if (fdin[1] != -1)
187 (void) close(fdin[1]);
188 (void) close(fdout[0]);
189 (void) wait(NULL);
190 return n;
191 }
192}
39};
40
41static int ncompr = sizeof(compr) / sizeof(compr[0]);
42
43
44static int uncompress __P((int, const unsigned char *, unsigned char **, int));
45static int swrite __P((int, const void *, size_t));
46static int sread __P((int, void *, size_t));
47
48int
49zmagic(buf, nbytes)
50 unsigned char *buf;
51 int nbytes;
52{
53 unsigned char *newbuf;
54 int newsize;
55 int i;
56
57 for (i = 0; i < ncompr; i++) {
58 if (nbytes < compr[i].maglen)
59 continue;
60 if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 &&
61 (newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) {
62 tryit(newbuf, newsize, 1);
63 free(newbuf);
64 printf(" (");
65 tryit(buf, nbytes, 0);
66 printf(")");
67 return 1;
68 }
69 }
70
71 if (i == ncompr)
72 return 0;
73
74 return 1;
75}
76
77/*
78 * `safe' write for sockets and pipes.
79 */
80static int
81swrite(fd, buf, n)
82 int fd;
83 const void *buf;
84 size_t n;
85{
86 int rv;
87 size_t rn = n;
88
89 do
90 switch (rv = write(fd, buf, n)) {
91 case -1:
92 if (errno == EINTR)
93 continue;
94 return -1;
95 default:
96 n -= rv;
97 buf = ((char *)buf) + rv;
98 break;
99 }
100 while (n > 0);
101 return rn;
102}
103
104
105/*
106 * `safe' read for sockets and pipes.
107 */
108static int
109sread(fd, buf, n)
110 int fd;
111 void *buf;
112 size_t n;
113{
114 int rv;
115 size_t rn = n;
116
117 do
118 switch (rv = read(fd, buf, n)) {
119 case -1:
120 if (errno == EINTR)
121 continue;
122 return -1;
123 default:
124 n -= rv;
125 buf = ((char *)buf) + rv;
126 break;
127 }
128 while (n > 0);
129 return rn;
130}
131
132static int
133uncompress(method, old, newch, n)
134 int method;
135 const unsigned char *old;
136 unsigned char **newch;
137 int n;
138{
139 int fdin[2], fdout[2];
140
141 if (pipe(fdin) == -1 || pipe(fdout) == -1) {
142 error("cannot create pipe (%s).\n", strerror(errno));
143 /*NOTREACHED*/
144 }
145 switch (fork()) {
146 case 0: /* child */
147 (void) close(0);
148 (void) dup(fdin[0]);
149 (void) close(fdin[0]);
150 (void) close(fdin[1]);
151
152 (void) close(1);
153 (void) dup(fdout[1]);
154 (void) close(fdout[0]);
155 (void) close(fdout[1]);
156 if (compr[method].silent)
157 (void) close(2);
158
159 execvp(compr[method].argv[0],
160 (char *const *)compr[method].argv);
161 exit(1);
162 /*NOTREACHED*/
163 case -1:
164 error("could not fork (%s).\n", strerror(errno));
165 /*NOTREACHED*/
166
167 default: /* parent */
168 (void) close(fdin[0]);
169 (void) close(fdout[1]);
170 if (swrite(fdin[1], old, n) != n) {
171 n = 0;
172 goto err;
173 }
174 (void) close(fdin[1]);
175 fdin[1] = -1;
176 if ((*newch = (unsigned char *) malloc(n)) == NULL) {
177 n = 0;
178 goto err;
179 }
180 if ((n = sread(fdout[0], *newch, n)) <= 0) {
181 free(*newch);
182 n = 0;
183 goto err;
184 }
185err:
186 if (fdin[1] != -1)
187 (void) close(fdin[1]);
188 (void) close(fdout[0]);
189 (void) wait(NULL);
190 return n;
191 }
192}