Commit | Line | Data |
---|---|---|
286a6f32 C |
1 | /* |
2 | * compress routines: | |
3 | * is_compress() returns 0 if uncompressed, number of bits if compressed. | |
4 | * uncompress(old, n, newch) - uncompress old into new, return sizeof new | |
5 | * compress.c,v 1.1 1993/06/10 00:38:05 jtc Exp | |
6 | */ | |
7 | #include <stdio.h> | |
8 | #include <stdlib.h> | |
9 | #include <unistd.h> | |
10 | #include <string.h> | |
11 | #include <sys/wait.h> | |
12 | ||
13 | #include "file.h" | |
14 | ||
15 | /* Check for compression, return nbits. Algorithm, in magic(4) format: | |
16 | * 0 string \037\235 compressed data | |
17 | * >2 byte&0x80 >0 block compressed | |
18 | * >2 byte&0x1f x %d bits | |
19 | */ | |
20 | int | |
21 | is_compress(p, b) | |
22 | const unsigned char *p; | |
23 | int *b; | |
24 | { | |
25 | ||
26 | if (*p != '\037' || *(/*signed*/ char*)(p+1) != '\235') | |
27 | return 0; /* not compress()ed */ | |
28 | ||
29 | *b = *(p+2) & 0x80; | |
30 | return *(p+2) & 0x1f; | |
31 | } | |
32 | ||
33 | int | |
34 | uncompress(old, newch, n) | |
35 | const unsigned char *old; | |
36 | unsigned char **newch; | |
37 | int n; | |
38 | { | |
39 | int fdin[2], fdout[2]; | |
40 | ||
41 | if (pipe(fdin) == -1 || pipe(fdout) == -1) { | |
42 | error("cannot create pipe (%s).\n", strerror(errno)); | |
43 | /*NOTREACHED*/ | |
44 | } | |
45 | switch (fork()) { | |
46 | case 0: /* child */ | |
47 | (void) close(0); | |
48 | (void) dup(fdin[0]); | |
49 | (void) close(fdin[0]); | |
50 | (void) close(fdin[1]); | |
51 | ||
52 | (void) close(1); | |
53 | (void) dup(fdout[1]); | |
54 | (void) close(fdout[0]); | |
55 | (void) close(fdout[1]); | |
56 | ||
57 | execlp("uncompress", "uncompress", "-c", NULL); | |
58 | error("could not execute `uncompress' (%s).\n", | |
59 | strerror(errno)); | |
60 | /*NOTREACHED*/ | |
61 | case -1: | |
62 | error("could not fork (%s).\n", strerror(errno)); | |
63 | /*NOTREACHED*/ | |
64 | ||
65 | default: /* parent */ | |
66 | (void) close(fdin[0]); | |
67 | (void) close(fdout[1]); | |
68 | if (write(fdin[1], old, n) != n) { | |
69 | error("write failed (%s).\n", strerror(errno)); | |
70 | /*NOTREACHED*/ | |
71 | } | |
72 | (void) close(fdin[1]); | |
73 | if ((*newch = (unsigned char *) malloc(n)) == NULL) { | |
74 | error("out of memory.\n"); | |
75 | /*NOTREACHED*/ | |
76 | } | |
77 | if ((n = read(fdout[0], *newch, n)) <= 0) { | |
78 | free(*newch); | |
79 | error("read failed (%s).\n", strerror(errno)); | |
80 | /*NOTREACHED*/ | |
81 | } | |
82 | (void) close(fdout[0]); | |
83 | (void) wait(NULL); | |
84 | return n; | |
85 | } | |
86 | } |