blob: 69609a288330fa25d9a88f6bdcab79e9b833ffc0 [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
Rob Landleyb15b8fa2009-01-05 01:05:43 -06009USE_CKSUM(NEWTOY(cksum, "IPLN", TOYFLAG_BIN))
Rob Landley433c0302008-12-27 05:37:47 -060010
11config CKSUM
12 bool "cksum"
13 default y
14 help
Rob Landleyb15b8fa2009-01-05 01:05:43 -060015 usage: cksum [-FL] [file...]
Rob Landley2f638c32009-01-04 22:45:03 -060016
Rob Landley433c0302008-12-27 05:37:47 -060017 For each file, output crc32 checksum value, length and name of file.
18 If no files listed, copy from stdin. Filename "-" is a synonym for stdin.
Rob Landley2f638c32009-01-04 22:45:03 -060019
Rob Landleyb15b8fa2009-01-05 01:05:43 -060020 -L Little endian (defaults to big endian)
Rob Landleyba3ed792009-01-05 01:47:48 -060021 -P Pre-inversion
Rob Landleyb15b8fa2009-01-05 01:05:43 -060022 -I Skip post-inversion
23 -N No length
Rob Landley433c0302008-12-27 05:37:47 -060024*/
25
26#include "toys.h"
27
28DEFINE_GLOBALS(
29 unsigned crc_table[256];
30)
31
32#define TT this.cksum
33
Rob Landleyb15b8fa2009-01-05 01:05:43 -060034static unsigned cksum_be(unsigned crc, unsigned char c)
Rob Landley433c0302008-12-27 05:37:47 -060035{
36 return (crc<<8)^TT.crc_table[(crc>>24)^c];
37}
38
Rob Landleyb15b8fa2009-01-05 01:05:43 -060039static unsigned cksum_le(unsigned crc, unsigned char c)
40{
41 return TT.crc_table[(crc^c)&0xff] ^ (crc>>8);
42}
43
Rob Landley433c0302008-12-27 05:37:47 -060044static void do_cksum(int fd, char *name)
45{
Rob Landleyba3ed792009-01-05 01:47:48 -060046 unsigned crc = (toys.optflags&4) ? 0xffffffff : 0;
Rob Landley433c0302008-12-27 05:37:47 -060047 uint64_t llen = 0, llen2;
Rob Landleyb15b8fa2009-01-05 01:05:43 -060048 unsigned (*cksum)(unsigned crc, unsigned char c);
Rob Landley433c0302008-12-27 05:37:47 -060049
Rob Landleyb15b8fa2009-01-05 01:05:43 -060050
51 cksum = (toys.optflags&2) ? cksum_le : cksum_be;
Rob Landley433c0302008-12-27 05:37:47 -060052 // CRC the data
53
54 for (;;) {
55 int len, i;
56
57 len = read(fd, toybuf, sizeof(toybuf));
58 if (len<0) {
59 perror_msg("%s",name);
60 toys.exitval = EXIT_FAILURE;
61 }
62 if (len<1) break;
63
64 llen += len;
65 for (i=0; i<len; i++) crc=cksum(crc, toybuf[i]);
66 }
67
68 // CRC the length
69
70 llen2 = llen;
Rob Landleyb15b8fa2009-01-05 01:05:43 -060071 if (!(toys.optflags&1)) {
72 while (llen) {
73 crc = cksum(crc, llen);
74 llen >>= 8;
75 }
Rob Landley433c0302008-12-27 05:37:47 -060076 }
77
Rob Landleyb15b8fa2009-01-05 01:05:43 -060078 printf("%u %"PRIu64, (toys.optflags&8) ? crc : ~crc, llen2);
Rob Landley433c0302008-12-27 05:37:47 -060079 if (strcmp("-", name)) printf(" %s", name);
80 xputc('\n');
81}
82
83void cksum_main(void)
84{
Rob Landleyb15b8fa2009-01-05 01:05:43 -060085 crc_init(TT.crc_table, toys.optflags&2);
Rob Landley433c0302008-12-27 05:37:47 -060086 loopfiles(toys.optargs, do_cksum);
87}