This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.bin / file / compress.c
CommitLineData
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 */
20int
21is_compress(p, b)
22const unsigned char *p;
23int *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
33int
34uncompress(old, newch, n)
35const unsigned char *old;
36unsigned char **newch;
37int 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}