blob: a3e53de8b6a7c91221dc7b6cc64eb90320dc926c [file] [log] [blame]
Rob Landley433c0302008-12-27 05:37:47 -06001/* vi: set sw=4 ts=4:
2 *
3 * cksum.c - produce crc32 checksum value for each input
4 *
5 * Copyright 2008 Rob Landley <rob@landley.net>
6 *
7 * See http://www.opengroup.org/onlinepubs/009695399/utilities/cksum.html
8
9USE_CKSUM(NEWTOY(cksum, NULL, TOYFLAG_BIN))
10
11config CKSUM
12 bool "cksum"
13 default y
14 help
15 usage: cksum [file...]
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
20#include "toys.h"
21
22DEFINE_GLOBALS(
23 unsigned crc_table[256];
24)
25
26#define TT this.cksum
27
28static unsigned cksum(unsigned crc, unsigned char c)
29{
30 return (crc<<8)^TT.crc_table[(crc>>24)^c];
31}
32
33static void do_cksum(int fd, char *name)
34{
35 unsigned crc = 0;
36 uint64_t llen = 0, llen2;
37
38 // CRC the data
39
40 for (;;) {
41 int len, i;
42
43 len = read(fd, toybuf, sizeof(toybuf));
44 if (len<0) {
45 perror_msg("%s",name);
46 toys.exitval = EXIT_FAILURE;
47 }
48 if (len<1) break;
49
50 llen += len;
51 for (i=0; i<len; i++) crc=cksum(crc, toybuf[i]);
52 }
53
54 // CRC the length
55
56 llen2 = llen;
57 while (llen) {
58 crc = cksum(crc, llen);
59 llen >>= 8;
60 }
61
62 printf("%u %"PRIu64, ~crc, llen2);
63 if (strcmp("-", name)) printf(" %s", name);
64 xputc('\n');
65}
66
67void cksum_main(void)
68{
69 crc_init(TT.crc_table);
70 loopfiles(toys.optargs, do_cksum);
71}