make ANSI compatible
[unix-history] / usr / src / old / compact / uncompact / uncompact.c
CommitLineData
524aa063 1#ifndef lint
90b67bab 2static char sccsid[] = "@(#)uncompact.c 4.8 (Berkeley) %G%";
524aa063
SL
3#endif
4
c3a7147a
BS
5/*
6 * Uncompact adaptive Huffman code input to output
7 *
8 * On - line algorithm
9 *
10 * Input file does not contain decoding tree
11 *
12 * Written by Colin L. Mc Master (UCB) February 14, 1979
13 */
c3a7147a 14#include "compact.h"
3e76178c
SL
15#include <strings.h>
16
17union cio c;
18union cio d;
19char *infname; /* input file's name */
20char fname[MAXPATHLEN+1]; /* output file's name */
21struct stat status; /* compacted file status */
c3a7147a 22
3e76178c 23int verbose = 0;
c3a7147a 24
3e76178c
SL
25main(argc, argv)
26 int argc;
27 char *argv[];
c3a7147a 28{
c3a7147a 29 register short j;
c3a7147a 30
3e76178c
SL
31 argc--, argv++;
32 if (argc > 0 && strcmp(*argv, "-v") == 0) {
33 verbose++;
34 argc--, argv++;
35 }
36 dir[513].next = NULL;
c3a7147a
BS
37 for (head = dir + (j = 513); j--; ) {
38 dirp = head--;
3e76178c 39 head->next = dirp;
c3a7147a 40 }
3e76178c 41 bottom = dirp->pt = dict;
7047739d 42 dict[0].sons[LEFT].top = dict[0].sons[RIGHT].top = dirp;
3e76178c
SL
43 dirq = dirp->next;
44 in[EF].flags = FBIT | SEEN;
45 if (argc == 0)
46 exit(uncompact("-"));
47 for (j = 0; j < argc; j++) {
48 if (uncompact(argv[j]))
49 exit(1);
50 if (verbose && argc > 0)
51 printf("%s uncompacted to %s\n", argv[j], fname);
52 }
53 exit(0);
54}
c3a7147a 55
3e76178c
SL
56uncompact(file)
57 char *file;
58{
59 int ignore;
60 FILE *setup();
61
7047739d
SL
62 bottom->sons[RIGHT].top->next = flist;
63 bottom->sons[RIGHT].top = dirp;
3e76178c 64 flist = dirq;
7047739d 65 uncfp = cfp = NULL;
3e76178c
SL
66 if (strcmp(file, "-") != 0) {
67 char *cp;
68
69 strcpy(fname, file);
70 cp = rindex(fname, '.');
71 if (cp == 0 || strcmp(cp, ".C") != 0) {
72 fprintf(stderr,
73 "uncompact: %s: File must have .C suffix.\n", file);
7047739d 74 goto bad;
c3a7147a 75 }
3e76178c
SL
76 *cp = '\0';
77 cfp = fopen(file, "r");
78 if (cfp == NULL) {
79 fprintf(stderr, "uncompact: "), perror(file);
7047739d 80 goto bad;
c3a7147a 81 }
3e76178c
SL
82 (void) fstat(fileno(cfp), &status);
83 } else
84 cfp = stdin;
85 infname = file;
86 uncfp = setup(cfp, &ignore);
87 if (uncfp == NULL) {
88 if (ignore)
89 goto done;
90 goto bad;
91 }
92 decompress(cfp, uncfp);
93 fflush(uncfp);
94 if (ferror(uncfp) || ferror(cfp)) {
7047739d 95 fprintf(stderr, "uncompact: ");
3e76178c
SL
96 if (uncfp != stdout) {
97 if (ferror(uncfp))
98 perror(fname);
99 else
100 perror(infname);
101 (void) unlink(fname);
7047739d
SL
102 } else
103 fprintf(stderr,
104 "Unsuccessful uncompact of standard input to standard output.\n");
3e76178c
SL
105 goto bad;
106 }
107 if (uncfp != stdout && unlink(infname) < 0)
108 fprintf(stderr, "uncompact: "), perror(infname);
109done:
110 if (uncfp != NULL && uncfp != stdout)
111 fclose(uncfp);
112 if (cfp != NULL)
113 fclose(cfp);
114 return (0);
115bad:
7047739d
SL
116 if (cfp != NULL)
117 fclose(cfp);
3e76178c
SL
118 return (1);
119}
120
121decompress(cfp, uncfp)
122 register FILE *cfp, *uncfp;
123{
124 register struct node *p;
125 register short j;
126 register int m;
90b67bab 127 register union cio *dp = &d;
3e76178c 128 char b;
c3a7147a 129
3e76178c
SL
130 p = dict;
131 while ((c.integ = getc (cfp)) != EOF) {
132 for (m = 0200; m; ) {
133 b = (m & c.integ ? 1 : 0);
134 m >>= 1;
135 if (p->fath.flags & (b ? RLEAF : LLEAF)) {
7047739d 136 dp->integ = p->sons[b].sp.ch;
3e76178c
SL
137 if (dp->integ == EF)
138 break;
139 if (dp->integ == NC) {
140 uptree(NC);
141 dp->integ = 0;
142 for (j = 8; j--; m >>= 1) {
143 if (m == 0) {
144 c.integ = getc(cfp);
145 m = 0200;
c3a7147a 146 }
3e76178c
SL
147 dp->integ <<= 1;
148 if (m & c.integ)
149 dp->integ++;
c3a7147a 150 }
3e76178c 151 insert(dp->integ);
c3a7147a 152 }
3e76178c
SL
153 uptree(dp->integ);
154 putc(dp->chars.lob, uncfp);
155 p = dict;
156 } else
7047739d 157 p = p->sons[b].sp.p;
c3a7147a 158 }
3e76178c
SL
159 }
160}
161
162FILE *
163setup(cfp, ignore)
164 FILE *cfp;
165 int *ignore;
166{
167 FILE *uncfp = NULL;
168 register union cio *dp = &d;
169 register union cio *cp = &c;
170
7047739d 171 *ignore = 0;
3e76178c 172 dp->integ = getc(cfp);
7047739d
SL
173 if (dp->integ != EOF) {
174 cp->integ = getc(cfp);
175 if (cp->integ != EOF)
176 dp->chars.hib = cp->integ & 0377;
177 } else
178 dp->integ = 0;
3e76178c 179 if ((dp->integ &= 0177777) != COMPACTED) {
7047739d 180 fprintf(stderr, "uncompact: ");
3e76178c
SL
181 if (dp->integ == PACKED)
182 fprintf(stderr, "%s: File is packed, use unpack.\n",
183 infname);
184 else
185 fprintf(stderr, "%s: Not a compacted file.\n", infname);
186 *ignore = 1;
187 goto bad;
188 }
189 if (strcmp(infname, "-") != 0) {
190 uncfp = fopen(fname, "w");
7047739d
SL
191 if (uncfp == NULL)
192 goto bad2;
3e76178c
SL
193 (void) fchmod(fileno(uncfp), status.st_mode);
194 } else
195 uncfp = stdout;
196 cp->integ = getc(cfp);
197 if (cp->integ == EOF)
7047739d 198 goto bad2;
3e76178c
SL
199 putc(cp->chars.lob, uncfp);
200
7047739d
SL
201 in[NC].fp = in[EF].fp = dict[0].sons[LEFT].sp.p = bottom = dict + 1;
202 bottom->sons[LEFT].count = bottom->sons[RIGHT].count =
203 dict[0].sons[RIGHT].count = 1;
204 dirp->next = dict[0].sons[RIGHT].top = bottom->sons[LEFT].top =
205 bottom->sons[RIGHT].top = dirq = NEW;
3e76178c
SL
206 dirq->next = NULL;
207 dict[0].fath.fp = NULL;
208 dirq->pt = bottom->fath.fp = in[cp->integ].fp = dict;
209 in[cp->integ].flags = (FBIT | SEEN);
210 in[NC].flags = SEEN;
211 dict[0].fath.flags = RLEAF;
212 bottom->fath.flags = (LLEAF | RLEAF);
7047739d 213 dict[0].sons[LEFT].count = 2;
c3a7147a 214
7047739d
SL
215 dict[0].sons[RIGHT].sp.ch = cp->integ;
216 bottom->sons[LEFT].sp.ch = NC;
217 bottom->sons[RIGHT].sp.ch = EF;
3e76178c 218 return (uncfp);
7047739d
SL
219bad2:
220 fprintf(stderr, "uncompact: ");
221 perror(fname);
3e76178c
SL
222bad:
223 if (uncfp && uncfp != stdout) {
3e76178c
SL
224 (void) unlink(fname);
225 fclose(uncfp);
c3a7147a 226 }
3e76178c 227 return (NULL);
c3a7147a 228}