Commit | Line | Data |
---|---|---|
b5802654 C |
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 | * $Id: compress.c,v 1.7 1993/10/27 20:59:05 christos Exp $ | |
8 | */ | |
9 | #include <stdio.h> | |
10 | #include <stdlib.h> | |
11 | #include <unistd.h> | |
12 | #include <string.h> | |
13 | #include <sys/wait.h> | |
14 | ||
15 | #include "file.h" | |
16 | ||
17 | static struct { | |
18 | char *magic; | |
19 | int maglen; | |
20 | char *argv[3]; | |
21 | int silent; | |
22 | } compr[] = { | |
23 | { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, | |
24 | { "\037\213", 2, { "gzip", "-dq", NULL }, 1 }, | |
25 | #if 0 | |
26 | /* XXX pcat does not work, cause I don't know how to make it read stdin */ | |
27 | { "\037\036", 2, { "pcat", NULL, NULL }, 0 }, | |
28 | #endif | |
29 | }; | |
30 | ||
31 | static int ncompr = sizeof(compr) / sizeof(compr[0]); | |
32 | ||
33 | ||
34 | static int uncompress __P((int, const unsigned char *, unsigned char **, int)); | |
35 | ||
36 | int | |
37 | zmagic(buf, nbytes) | |
38 | unsigned char *buf; | |
39 | int nbytes; | |
40 | { | |
41 | unsigned char *newbuf; | |
42 | int newsize; | |
43 | int i; | |
44 | ||
45 | for (i = 0; i < ncompr; i++) { | |
46 | if (nbytes < compr[i].maglen) | |
47 | continue; | |
48 | if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0) | |
49 | break; | |
50 | } | |
51 | ||
52 | if (i == ncompr) | |
53 | return 0; | |
54 | ||
55 | if ((newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) { | |
56 | tryit(newbuf, newsize, 1); | |
57 | free(newbuf); | |
58 | printf(" ("); | |
59 | tryit(buf, nbytes, 0); | |
60 | printf(")"); | |
61 | } | |
62 | return 1; | |
63 | } | |
64 | ||
65 | ||
66 | static int | |
67 | uncompress(method, old, newch, n) | |
68 | int method; | |
69 | const unsigned char *old; | |
70 | unsigned char **newch; | |
71 | int n; | |
72 | { | |
73 | int fdin[2], fdout[2]; | |
74 | ||
75 | if (pipe(fdin) == -1 || pipe(fdout) == -1) { | |
76 | error("cannot create pipe (%s).\n", strerror(errno)); | |
77 | /*NOTREACHED*/ | |
78 | } | |
79 | switch (fork()) { | |
80 | case 0: /* child */ | |
81 | (void) close(0); | |
82 | (void) dup(fdin[0]); | |
83 | (void) close(fdin[0]); | |
84 | (void) close(fdin[1]); | |
85 | ||
86 | (void) close(1); | |
87 | (void) dup(fdout[1]); | |
88 | (void) close(fdout[0]); | |
89 | (void) close(fdout[1]); | |
90 | if (compr[method].silent) | |
91 | (void) close(2); | |
92 | ||
93 | execvp(compr[method].argv[0], compr[method].argv); | |
94 | error("could not execute `%s' (%s).\n", | |
95 | compr[method].argv[0], strerror(errno)); | |
96 | /*NOTREACHED*/ | |
97 | case -1: | |
98 | error("could not fork (%s).\n", strerror(errno)); | |
99 | /*NOTREACHED*/ | |
100 | ||
101 | default: /* parent */ | |
102 | (void) close(fdin[0]); | |
103 | (void) close(fdout[1]); | |
104 | if (write(fdin[1], old, n) != n) { | |
105 | error("write failed (%s).\n", strerror(errno)); | |
106 | /*NOTREACHED*/ | |
107 | } | |
108 | (void) close(fdin[1]); | |
109 | if ((*newch = (unsigned char *) malloc(n)) == NULL) { | |
110 | error("out of memory.\n"); | |
111 | /*NOTREACHED*/ | |
112 | } | |
113 | if ((n = read(fdout[0], *newch, n)) <= 0) { | |
114 | free(*newch); | |
115 | error("read failed (%s).\n", strerror(errno)); | |
116 | /*NOTREACHED*/ | |
117 | } | |
118 | (void) close(fdout[0]); | |
119 | (void) wait(NULL); | |
120 | return n; | |
121 | } | |
122 | } | |
123 | ||
124 |