1 /* cksum.c - produce crc32 checksum value for each input
2 *
3 * Copyright 2008 Rob Landley <rob@landley.net>
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 [-IPLN] [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 -L Little endian (defaults to big endian)
21 -P Pre-inversion
22 -I Skip post-inversion
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
GLOBALS(unsigned crc_table[256];)38 GLOBALS(
39 unsigned crc_table[256];
40 )
41
42 static unsigned cksum_be(unsigned crc, char c)
43 {
44 return (crc<<8) ^ TT.crc_table[(crc>>24)^c];
45 }
46
cksum_le(unsigned crc,char c)47 static unsigned cksum_le(unsigned crc, char c)
48 {
49 return TT.crc_table[(crc^c)&0xff] ^ (crc>>8);
50 }
51
do_cksum(int fd,char * name)52 static void do_cksum(int fd, char *name)
53 {
54 unsigned (*cksum)(unsigned crc, char c), crc = FLAG(P) ? ~0 : 0;
55 unsigned long long llen = 0, llen2;
56 int len, i;
57
58 cksum = FLAG(L) ? cksum_le : cksum_be;
59 // CRC the data
60
61 for (;;) {
62 len = read(fd, toybuf, sizeof(toybuf));
63 if (len<0) perror_msg_raw(name);
64 if (len<1) break;
65
66 llen += len;
67 for (i = 0; i<len; i++) crc = cksum(crc, toybuf[i]);
68 }
69
70 // CRC the length
71
72 if (!FLAG(N)) for (llen2 = llen; llen2; llen2 >>= 8) crc = cksum(crc, llen2);
73
74 printf(FLAG(H) ? "%08x" : "%u", FLAG(I) ? crc : ~crc);
75 if (!FLAG(N)) printf(" %llu", llen);
76 if (toys.optc) printf(" %s", name);
77 xputc('\n');
78 }
79
cksum_main(void)80 void cksum_main(void)
81 {
82 crc_init(TT.crc_table, FLAG(L));
83 loopfiles(toys.optargs, do_cksum);
84 }
85
crc32_main(void)86 void crc32_main(void)
87 {
88 toys.optflags |= FLAG_H|FLAG_N|FLAG_P|FLAG_L;
89 if (toys.optc) toys.optc--;
90 cksum_main();
91 }
92