1 /* ------------------------------------------------------------------------ */
2 /* LHa for UNIX */
3 /* crcio.c -- crc input / output */
4 /* */
5 /* Modified Nobutaka Watazaki */
6 /* */
7 /* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
8 /* ------------------------------------------------------------------------ */
9 #include "lha.h"
10
11 /* ------------------------------------------------------------------------ */
12 static unsigned short crctable[UCHAR_MAX + 1];
13 static unsigned char subbitbuf, bitcount;
14 #ifdef EUC
15 static int putc_euc_cache;
16 #endif
17 static int getc_euc_cache;
18
19 /* ------------------------------------------------------------------------ */
20 void
make_crctable()21 make_crctable( /* void */ )
22 {
23 unsigned int i, j, r;
24
25 for (i = 0; i <= UCHAR_MAX; i++) {
26 r = i;
27 for (j = 0; j < CHAR_BIT; j++)
28 if (r & 1)
29 r = (r >> 1) ^ CRCPOLY;
30 else
31 r >>= 1;
32 crctable[i] = r;
33 }
34 }
35
36 /* ------------------------------------------------------------------------ */
37 #ifdef NEED_INCREMENTAL_INDICATOR
38 static void
put_indicator(count)39 put_indicator(count)
40 long int count;
41 {
42 if (!quiet && indicator_threshold) {
43 while (count > indicator_count) {
44 putchar('o');
45 fflush(stdout);
46 indicator_count += indicator_threshold;
47 }
48 }
49 }
50 #endif
51
52 /* ------------------------------------------------------------------------ */
53 unsigned short
calccrc(p,n)54 calccrc(p, n)
55 unsigned char *p;
56 unsigned int n;
57 {
58 reading_size += n;
59 #ifdef NEED_INCREMENTAL_INDICATOR
60 put_indicator(reading_size);
61 #endif
62 while (n-- > 0)
63 UPDATE_CRC(*p++);
64 return crc;
65 }
66
67 /* ------------------------------------------------------------------------ */
68 void
fillbuf(unsigned char n)69 fillbuf(unsigned char n) /* Shift bitbuf n bits left, read n bits */
70 {
71 while (n > bitcount) {
72 n -= bitcount;
73 bitbuf = (bitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
74 if (compsize != 0) {
75 compsize--;
76 subbitbuf = (unsigned char) getc(infile);
77 }
78 else
79 subbitbuf = 0;
80 bitcount = CHAR_BIT;
81 }
82 bitcount -= n;
83 bitbuf = (bitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
84 subbitbuf <<= n;
85 }
86
87 /* ------------------------------------------------------------------------ */
88 unsigned short
getbits(unsigned char n)89 getbits(unsigned char n)
90 {
91 unsigned short x;
92
93 x = bitbuf >> (2 * CHAR_BIT - n);
94 fillbuf(n);
95 return x;
96 }
97
98 /* ------------------------------------------------------------------------ */
99 void
putcode(unsigned char n,unsigned short x)100 putcode(unsigned char n, unsigned short x) /* Write rightmost n bits of x */
101 {
102 while (n >= bitcount) {
103 n -= bitcount;
104 subbitbuf += x >> (USHRT_BIT - bitcount);
105 x <<= bitcount;
106 if (compsize < origsize) {
107 if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
108 /* fileerror(WTERR, outfile); */
109 fatal_error("Write error in crcio.c(putcode)\n");
110 /* exit(errno); */
111 }
112 compsize++;
113 }
114 else
115 unpackable = 1;
116 subbitbuf = 0;
117 bitcount = CHAR_BIT;
118 }
119 subbitbuf += x >> (USHRT_BIT - bitcount);
120 bitcount -= n;
121 }
122
123 /* ------------------------------------------------------------------------ */
124 void
putbits(unsigned char n,unsigned short x)125 putbits(unsigned char n, unsigned short x) /* Write rightmost n bits of x */
126 {
127 x <<= USHRT_BIT - n;
128 while (n >= bitcount) {
129 n -= bitcount;
130 subbitbuf += x >> (USHRT_BIT - bitcount);
131 x <<= bitcount;
132 if (compsize < origsize) {
133 if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
134 /* fileerror(WTERR, outfile); */
135 fatal_error("Write error in crcio.c(putbits)\n");
136 /* exit(errno); */
137 }
138 compsize++;
139 }
140 else
141 unpackable = 1;
142 subbitbuf = 0;
143 bitcount = CHAR_BIT;
144 }
145 subbitbuf += x >> (USHRT_BIT - bitcount);
146 bitcount -= n;
147 }
148
149 /* ------------------------------------------------------------------------ */
150 int
fread_crc(p,n,fp)151 fread_crc(p, n, fp)
152 unsigned char *p;
153 int n;
154 FILE *fp;
155 {
156 if (text_mode)
157 n = fread_txt(p, n, fp);
158 else
159 n = fread(p, 1, n, fp);
160
161 calccrc(p, n);
162 return n;
163 }
164
165 /* ------------------------------------------------------------------------ */
166 void
fwrite_crc(p,n,fp)167 fwrite_crc(p, n, fp)
168 unsigned char *p;
169 int n;
170 FILE *fp;
171 {
172 calccrc(p, n);
173 if (verify_mode)
174 return;
175
176 if (fp) {
177 if (text_mode) {
178 if (fwrite_txt(p, n, fp))
179 fatal_error("File write error\n");
180 }
181 else {
182 if (fwrite(p, 1, n, fp) < n)
183 fatal_error("File write error\n");
184 }
185 }
186 }
187
188 /* ------------------------------------------------------------------------ */
189 void
init_code_cache()190 init_code_cache( /* void */ )
191 { /* called from copyfile() in util.c */
192 #ifdef EUC
193 putc_euc_cache = EOF;
194 #endif
195 getc_euc_cache = EOF;
196 }
197
198 void
init_getbits()199 init_getbits( /* void */ )
200 {
201 bitbuf = 0;
202 subbitbuf = 0;
203 bitcount = 0;
204 fillbuf(2 * CHAR_BIT);
205 #ifdef EUC
206 putc_euc_cache = EOF;
207 #endif
208 }
209
210 /* ------------------------------------------------------------------------ */
211 void
init_putbits()212 init_putbits( /* void */ )
213 {
214 bitcount = CHAR_BIT;
215 subbitbuf = 0;
216 getc_euc_cache = EOF;
217 }
218
219 /* ------------------------------------------------------------------------ */
220 #ifdef EUC
221 void
putc_euc(c,fd)222 putc_euc(c, fd)
223 int c;
224 FILE *fd;
225 {
226 int d;
227
228 if (putc_euc_cache == EOF) {
229 if (!euc_mode || c < 0x81 || c > 0xFC) {
230 putc(c, fd);
231 return;
232 }
233 if (c >= 0xA0 && c < 0xE0) {
234 putc(0x8E, fd); /* single shift */
235 putc(c, fd);
236 return;
237 }
238 putc_euc_cache = c; /* save first byte */
239 return;
240 }
241 d = putc_euc_cache;
242 putc_euc_cache = EOF;
243 if (d >= 0xA0)
244 d -= 0xE0 - 0xA0;
245 if (c > 0x9E) {
246 c = c - 0x9F + 0x21;
247 d = (d - 0x81) * 2 + 0x22;
248 }
249 else {
250 if (c > 0x7E)
251 c--;
252 c -= 0x1F;
253 d = (d - 0x81) * 2 + 0x21;
254 }
255 putc(0x80 | d, fd);
256 putc(0x80 | c, fd);
257 }
258 #endif
259
260 /* ------------------------------------------------------------------------ */
261 int
fwrite_txt(p,n,fp)262 fwrite_txt(p, n, fp)
263 unsigned char *p;
264 int n;
265 FILE *fp;
266 {
267 while (--n >= 0) {
268 if (*p != '\015' && *p != '\032') {
269 #ifdef EUC
270 putc_euc(*p, fp);
271 #else
272 putc(*p, fp);
273 #endif
274 }
275
276 prev_char = *p++;
277 }
278 return (ferror(fp));
279 }
280
281 /* ------------------------------------------------------------------------ */
282 int
fread_txt(p,n,fp)283 fread_txt(p, n, fp)
284 unsigned char *p;
285 int n;
286 FILE *fp;
287 {
288 int c;
289 int cnt = 0;
290
291 while (cnt < n) {
292 if (getc_euc_cache != EOF) {
293 c = getc_euc_cache;
294 getc_euc_cache = EOF;
295 }
296 else {
297 if ((c = fgetc(fp)) == EOF)
298 break;
299 if (c == '\n') {
300 getc_euc_cache = c;
301 ++origsize;
302 c = '\r';
303 }
304 #ifdef EUC
305 else if (euc_mode && (c == 0x8E || (0xA0 < c && c < 0xFF))) {
306 int d = fgetc(fp);
307 if (d == EOF) {
308 *p++ = c;
309 cnt++;
310 break;
311 }
312 if (c == 0x8E) { /* single shift (KANA) */
313 if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
314 c = d | 0x80;
315 else
316 getc_euc_cache = d;
317 }
318 else {
319 if (0xA0 < d && d < 0xFF) { /* if GR */
320 c &= 0x7F; /* convert to MS-kanji */
321 d &= 0x7F;
322 if (!(c & 1)) {
323 c--;
324 d += 0x7F - 0x21;
325 }
326 if ((d += 0x40 - 0x21) > 0x7E)
327 d++;
328 if ((c = (c >> 1) + 0x71) >= 0xA0)
329 c += 0xE0 - 0xA0;
330 }
331 getc_euc_cache = d;
332 }
333 }
334 #endif
335 }
336 *p++ = c;
337 cnt++;
338 }
339 return cnt;
340 }
341
342 /* ------------------------------------------------------------------------ */
343 unsigned short
calc_header_crc(p,n)344 calc_header_crc(p, n) /* Thanks T.Okamoto */
345 unsigned char *p;
346 unsigned int n;
347 {
348 crc = 0;
349 while (n-- > 0)
350 UPDATE_CRC(*p++);
351 return crc;
352 }
353