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