• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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