util.c revision 1.1 1 /* $NetBSD: util.c,v 1.1 2026/06/11 08:29:49 rumble Exp $ */
2
3 /*
4 * Cribbed from 4.4BSD/Net2 and NetBSD 4.99.42 with some stuff ripped out and
5 * cleaned up.
6 */
7
8 /*-
9 * Copyright (c) 1991, 1993
10 * The Regents of the University of California. All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #include <sys/types.h>
38 #include <stdint.h>
39 #include <stdio.h>
40 #include <unistd.h>
41
42 #include "util.h"
43
44 /* 'thecrc' must initially be 0. */
45 int
46 sum1(int thecrc, u_char *buf, uint32_t len)
47 {
48 /*
49 * 16-bit checksum, rotating right before each addition;
50 * overflow is discarded.
51 */
52 for (u_char *p = buf; p < &buf[len]; ++p) {
53 if (thecrc & 1)
54 thecrc |= 0x10000;
55 thecrc = ((thecrc >> 1) + *p) & 0xffff;
56 }
57
58 return (thecrc);
59 }
60
61 /*
62 * Copyright (c) 1985, 1986 The Regents of the University of California.
63 * All rights reserved.
64 *
65 * This code is derived from software contributed to Berkeley by
66 * James A. Woods, derived from original work by Spencer Thomas
67 * and Joseph Orost.
68 *
69 * Redistribution and use in source and binary forms, with or without
70 * modification, are permitted provided that the following conditions
71 * are met:
72 * 1. Redistributions of source code must retain the above copyright
73 * notice, this list of conditions and the following disclaimer.
74 * 2. Redistributions in binary form must reproduce the above copyright
75 * notice, this list of conditions and the following disclaimer in the
76 * documentation and/or other materials provided with the distribution.
77 * 3. All advertising materials mentioning features or use of this software
78 * must display the following acknowledgement:
79 * This product includes software developed by the University of
80 * California, Berkeley and its contributors.
81 * 4. Neither the name of the University nor the names of its contributors
82 * may be used to endorse or promote products derived from this software
83 * without specific prior written permission.
84 *
85 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
86 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
87 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
88 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
89 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
90 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
91 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
92 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
93 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
94 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
95 * SUCH DAMAGE.
96 */
97
98 /*
99 * compress.c - File compression ala IEEE Computer, June 1984.
100 *
101 * Authors: Spencer W. Thomas (decvax!utah-cs!thomas)
102 * Jim McKie (decvax!mcvax!jim)
103 * Steve Davies (decvax!vax135!petsd!peora!srd)
104 * Ken Turkowski (decvax!decwrl!turtlevax!ken)
105 * James A. Woods (decvax!ihnp4!ames!jaw)
106 * Joe Orost (decvax!vax135!petsd!joe)
107 */
108
109 #include <sys/param.h>
110 #include <sys/stat.h>
111 #include <signal.h>
112 #include <utime.h>
113 #include <errno.h>
114 #include <unistd.h>
115 #include <stdio.h>
116 #include <ctype.h>
117 #include <stdlib.h>
118 #include <string.h>
119
120 #define BITS 16
121 #define HSIZE 69001 /* 95% occupancy */
122
123 /*
124 * a code_int must be able to hold 2**BITS values of type int, and also -1
125 */
126 typedef long int code_int;
127 typedef long int count_int;
128
129 static const unsigned char magic_header[] = { "\037\235" }; /* 1F 9D */
130
131 /* Defines for third byte of header */
132 #define BIT_MASK 0x1f
133 #define BLOCK_MASK 0x80
134 /* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
135 a fourth header byte (for expansion).
136 */
137
138 #define INIT_BITS 9 /* initial number of bits/code */
139
140 static int n_bits; /* number of bits/code */
141 static int maxbits = BITS; /* user settable max # bits/code */
142 static code_int maxcode; /* maximum code, given n_bits */
143 static code_int maxmaxcode = 1 << BITS; /* should NEVER generate this code */
144 #define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
145
146 static count_int htab [HSIZE];
147 static unsigned short codetab [HSIZE];
148
149 #define codetabof(i) codetab[i]
150
151 /*
152 * To save much memory, we overlay the table used by compress() with those
153 * used by decompress(). The tab_prefix table is the same size and type
154 * as the codetab. The tab_suffix table needs 2**BITS characters. We
155 * get this from the beginning of htab. The output stack uses the rest
156 * of htab, and contains characters. There is plenty of room for any
157 * possible stack (stack used to be 8000 characters).
158 */
159
160 #define tab_prefixof(i) codetabof(i)
161 #define tab_suffixof(i) ((unsigned char *)(htab))[i]
162 #define de_stack ((unsigned char *)&tab_suffixof(1<<BITS))
163
164 static code_int free_ent = 0; /* first unused entry */
165
166 static code_int getcode(FILE *);
167
168 /*
169 * block compression parameters -- after all codes are used up,
170 * and compression rate changes, start over.
171 */
172 static int block_compress = BLOCK_MASK;
173 static int clear_flg = 0;
174
175 /*
176 * the next two codes should not be changed lightly, as they must not
177 * lie within the contiguous general code space.
178 */
179 #define FIRST 257 /* first free entry */
180 #define CLEAR 256 /* table clear output code */
181
182 /*-
183 * Algorithm from "A Technique for High Performance Data Compression",
184 * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
185 *
186 * Algorithm:
187 * Modified Lempel-Ziv method (LZW). Basically finds common
188 * substrings and replaces them with a variable size code. This is
189 * deterministic, and can be done on the fly. Thus, the decompression
190 * procedure needs no input table, but tracks the way the table was built.
191 */
192
193 static const unsigned char rmask[9] = {
194 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
195 };
196
197 #ifndef BUFFER_SIZE
198 #define BUFFER_SIZE 16384
199 #endif
200
201 /* maximum number of bytes to return from getcode(). if 0, no limit. */
202 static uint32_t getcode_maxreadbytes;
203
204 /* number of bytes getcode has returned since decompress() was called */
205 static uint32_t getcode_readbytes;
206
207 /* this shouldn't be here, but it's faster to just do it on the fly */
208 static int output_checksum;
209
210 /*
211 * Decompress 'input' to 'output'. This routine adapts to the codes in
212 * the file building the "string" table on-the-fly; requiring no table to
213 * be stored in the compressed file. See the definitions above.
214 *
215 * Returns the number of bytes written to 'output'.
216 */
217 static uint32_t
218 do_decompression(FILE *input, FILE *output) {
219 unsigned char *stackp;
220 int finchar;
221 code_int code, oldcode, incode;
222 int n, nwritten, offset; /* Variables for buffered write */
223 char buff[BUFFER_SIZE]; /* Buffer for buffered write */
224 uint32_t byteswritten;
225
226 byteswritten = 0;
227
228 /*
229 * As above, initialize the first 256 entries in the table.
230 */
231 maxcode = MAXCODE(n_bits = INIT_BITS);
232 for ( code = 255; code >= 0; code-- ) {
233 tab_prefixof(code) = 0;
234 tab_suffixof(code) = (unsigned char)code;
235 }
236 free_ent = ((block_compress) ? FIRST : 256 );
237
238 finchar = oldcode = getcode(input);
239 if(oldcode == -1) /* EOF already? */
240 return (0);
241
242 /* first code must be 8 bits = char */
243 n=0;
244 buff[n++] = (char)finchar;
245
246 stackp = de_stack;
247
248 while ( (code = getcode(input)) > -1 ) {
249
250 if ( (code == CLEAR) && block_compress ) {
251 for ( code = 255; code >= 0; code-- )
252 tab_prefixof(code) = 0;
253 clear_flg = 1;
254 free_ent = FIRST - 1;
255 if ( (code = getcode(input)) == -1 ) /* O, untimely death! */
256 break;
257 }
258 incode = code;
259 /*
260 * Special case for KwKwK string.
261 */
262 if ( code >= free_ent ) {
263 *stackp++ = finchar;
264 code = oldcode;
265 }
266
267 /*
268 * Generate output characters in reverse order
269 */
270 while ( code >= 256 ) {
271 *stackp++ = tab_suffixof(code);
272 code = tab_prefixof(code);
273 }
274 *stackp++ = finchar = tab_suffixof(code);
275
276 /*
277 * And put them out in forward order
278 */
279 do {
280 /*
281 * About 60% of the time is spent in the putchar() call
282 * that appeared here. It was originally
283 * putchar ( *--stackp );
284 * If we buffer the writes ourselves, we can go faster (about
285 * 30%).
286 *
287 * At this point, the next line is the next *big* time
288 * sink in the code. It takes up about 10% of the time.
289 */
290 buff[n++] = *--stackp;
291 if (n == BUFFER_SIZE) {
292 offset = 0;
293 do {
294 output_checksum = sum1(output_checksum,
295 (u_char *)&buff[offset], n);
296 if (output == NULL)
297 nwritten = n;
298 else
299 nwritten = write(fileno(output), &buff[offset], n);
300 if (nwritten < 0)
301 return (0);
302 offset += nwritten;
303 byteswritten += nwritten;
304 } while ((n -= nwritten) > 0);
305 }
306 } while ( stackp > de_stack );
307
308 /*
309 * Generate the new entry.
310 */
311 if ( (code=free_ent) < maxmaxcode ) {
312 tab_prefixof(code) = (unsigned short)oldcode;
313 tab_suffixof(code) = finchar;
314 free_ent = code+1;
315 }
316 /*
317 * Remember previous code.
318 */
319 oldcode = incode;
320 }
321 /*
322 * Flush the stuff remaining in our buffer...
323 */
324 offset = 0;
325 while (n > 0) {
326 output_checksum = sum1(output_checksum, (u_char *)&buff[offset], n);
327 if (output == NULL)
328 nwritten = n;
329 else
330 nwritten = write(fileno(output), &buff[offset], n);
331 if (nwritten < 0)
332 return (0);
333 offset += nwritten;
334 n -= nwritten;
335 byteswritten += nwritten;
336 }
337
338 return (byteswritten);
339 }
340
341 /*-
342 * Read one code from the standard input. If EOF, return -1.
343 * Inputs:
344 * FILE stream.
345 * Outputs:
346 * code or -1 is returned.
347 */
348 static code_int
349 getcode(FILE *input)
350 {
351 code_int code;
352 static int offset = 0, size = 0;
353 static unsigned char buf[BITS];
354 int r_off, bits;
355 size_t readbytes;
356 unsigned char *bp = buf;
357
358 if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
359 /*
360 * If the next entry will be too big for the current code
361 * size, then we must increase the size. This implies reading
362 * a new buffer full, too.
363 *
364 * Bail immediately if we've read in our maximum.
365 */
366 if (getcode_maxreadbytes != 0 &&
367 getcode_readbytes == getcode_maxreadbytes)
368 return (-1);
369
370
371 if ( free_ent > maxcode ) {
372 n_bits++;
373 if ( n_bits == maxbits )
374 maxcode = maxmaxcode; /* won't get any bigger now */
375 else
376 maxcode = MAXCODE(n_bits);
377 }
378 if ( clear_flg > 0) {
379 maxcode = MAXCODE (n_bits = INIT_BITS);
380 clear_flg = 0;
381 }
382
383 if (getcode_maxreadbytes != 0 &&
384 n_bits > (getcode_maxreadbytes - getcode_readbytes))
385 readbytes = getcode_maxreadbytes - getcode_readbytes;
386 else
387 readbytes = n_bits;
388
389 size = fread( buf, 1, readbytes, input );
390 if ( size <= 0 )
391 return -1; /* end of file */
392 getcode_readbytes += size;
393 offset = 0;
394 /* Round size down to integral number of codes */
395 size = (size << 3) - (n_bits - 1);
396 }
397 r_off = offset;
398 bits = n_bits;
399 /*
400 * Get to the first byte.
401 */
402 bp += (r_off >> 3);
403 r_off &= 7;
404 /* Get first part (low order bits) */
405 code = (*bp++ >> r_off);
406 bits -= (8 - r_off);
407 r_off = 8 - r_off; /* now, offset into code word */
408 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
409 if ( bits >= 8 ) {
410 code |= *bp++ << r_off;
411 r_off += 8;
412 bits -= 8;
413 }
414 /* high order bits. */
415 code |= (*bp & rmask[bits]) << r_off;
416 offset += n_bits;
417
418 return code;
419 }
420
421 /*
422 * Decompress from stream 'input' into stream 'output', reading at most
423 * 'maxinput' bytes from 'input'.
424 *
425 * The special value 0 for maxinput indicates no limit.
426 *
427 * Returns the number of bytes outputted.
428 */
429 uint32_t
430 decompress(FILE *input, FILE *output, uint32_t maxinput, int *cksum)
431 {
432 uint32_t ret;
433
434 if (maxinput != 0 && maxinput < 4)
435 return (0);
436
437 if ((getc(input) & 0xff) != magic_header[0] ||
438 (getc(input) & 0xff) != magic_header[1])
439 return (0);
440
441 clear_flg = 0;
442 maxbits = getc(input);
443 block_compress = maxbits & BLOCK_MASK;
444 maxbits &= BIT_MASK;
445 maxmaxcode = 1 << maxbits;
446 if (maxbits > BITS)
447 return (0);
448
449 getcode_maxreadbytes = (maxinput == 0) ? 0 : maxinput - 3;
450 getcode_readbytes = 0;
451 output_checksum = 0;
452 ret = do_decompression(input, output);
453 *cksum = output_checksum;
454
455 return (ret);
456 }
457