1 /* cksum.c - produce crc32 checksum value for each input
2 *
3 * Copyright 2008 Rob Landley <[email protected]>
4 *
5 * See http://opengroup.org/onlinepubs/9699919799/utilities/cksum.html
6
7 USE_CKSUM(NEWTOY(cksum, "HIPLN", TOYFLAG_BIN))
8 USE_CRC32(NEWTOY(crc32, 0, TOYFLAG_BIN))
9
10 config CKSUM
11 bool "cksum"
12 default y
13 help
14 usage: cksum [-HIPLN] [FILE...]
15
16 For each file, output crc32 checksum value, length and name of file.
17 If no files listed, copy from stdin. Filename "-" is a synonym for stdin.
18
19 -H Hexadecimal checksum (defaults to decimal)
20 -I Skip post-inversion
21 -P Pre-inversion
22 -L Little endian (defaults to big endian)
23 -N Do not include length in CRC calculation (or output)
24
25 config CRC32
26 bool "crc32"
27 default y
28 help
29 usage: crc32 [file...]
30
31 Output crc32 checksum for each file.
32 */
33
34 #define FOR_cksum
35 #define FORCE_FLAGS
36 #include "toys.h"
37
do_cksum(int fd,char * name)38 static void do_cksum(int fd, char *name)
39 {
40 unsigned crc_table[256], crc = FLAG(P) ? ~0 : 0;
41 unsigned long long llen = 0, llen2 = 0;
42 int len, i, done = 0;
43
44 // Init table, loop through data
45 crc_init(crc_table, FLAG(L));
46 for (;;) {
47 len = read(fd, toybuf, sizeof(toybuf));
48 if (len<0) perror_msg_raw(name);
49 if (len<1) {
50 // CRC the length at end
51 if (FLAG(N)) break;
52 for (llen2 = llen, len = 0; llen2; llen2 >>= 8) toybuf[len++] = llen2;
53 done++;
54 } else llen += len;
55 for (i = 0; i<len; i++)
56 crc = FLAG(L) ? crc_table[(crc^toybuf[i])&0xff] ^ (crc>>8)
57 : (crc<<8) ^ crc_table[(crc>>24)^toybuf[i]];
58 if (done) break;
59 }
60
61 printf(FLAG(H) ? "%08x" : "%u", FLAG(I) ? crc : ~crc);
62 if (!FLAG(N)) printf(" %llu", llen);
63 if (toys.optc) printf(" %s", name);
64 xputc('\n');
65 }
66
cksum_main(void)67 void cksum_main(void)
68 {
69 loopfiles(toys.optargs, do_cksum);
70 }
71
crc32_main(void)72 void crc32_main(void)
73 {
74 toys.optflags |= FLAG_H|FLAG_N|FLAG_P|FLAG_L;
75 if (toys.optc) toys.optc--;
76 cksum_main();
77 }
78