Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 1 | /* 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 Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 9 | USE_CKSUM(NEWTOY(cksum, "IPLN", TOYFLAG_BIN)) |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 10 | |
| 11 | config CKSUM |
| 12 | bool "cksum" |
| 13 | default y |
| 14 | help |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 15 | usage: cksum [-FL] [file...] |
Rob Landley | 2f638c3 | 2009-01-04 22:45:03 -0600 | [diff] [blame] | 16 | |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 17 | 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 Landley | 2f638c3 | 2009-01-04 22:45:03 -0600 | [diff] [blame] | 19 | |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 20 | -L Little endian (defaults to big endian) |
Rob Landley | ba3ed79 | 2009-01-05 01:47:48 -0600 | [diff] [blame] | 21 | -P Pre-inversion |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 22 | -I Skip post-inversion |
| 23 | -N No length |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 24 | */ |
| 25 | |
| 26 | #include "toys.h" |
| 27 | |
| 28 | DEFINE_GLOBALS( |
| 29 | unsigned crc_table[256]; |
| 30 | ) |
| 31 | |
| 32 | #define TT this.cksum |
| 33 | |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 34 | static unsigned cksum_be(unsigned crc, unsigned char c) |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 35 | { |
| 36 | return (crc<<8)^TT.crc_table[(crc>>24)^c]; |
| 37 | } |
| 38 | |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 39 | static unsigned cksum_le(unsigned crc, unsigned char c) |
| 40 | { |
| 41 | return TT.crc_table[(crc^c)&0xff] ^ (crc>>8); |
| 42 | } |
| 43 | |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 44 | static void do_cksum(int fd, char *name) |
| 45 | { |
Rob Landley | ba3ed79 | 2009-01-05 01:47:48 -0600 | [diff] [blame] | 46 | unsigned crc = (toys.optflags&4) ? 0xffffffff : 0; |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 47 | uint64_t llen = 0, llen2; |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 48 | unsigned (*cksum)(unsigned crc, unsigned char c); |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 49 | |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 50 | |
| 51 | cksum = (toys.optflags&2) ? cksum_le : cksum_be; |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 52 | // 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 Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 71 | if (!(toys.optflags&1)) { |
| 72 | while (llen) { |
| 73 | crc = cksum(crc, llen); |
| 74 | llen >>= 8; |
| 75 | } |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 76 | } |
| 77 | |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 78 | printf("%u %"PRIu64, (toys.optflags&8) ? crc : ~crc, llen2); |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 79 | if (strcmp("-", name)) printf(" %s", name); |
| 80 | xputc('\n'); |
| 81 | } |
| 82 | |
| 83 | void cksum_main(void) |
| 84 | { |
Rob Landley | b15b8fa | 2009-01-05 01:05:43 -0600 | [diff] [blame] | 85 | crc_init(TT.crc_table, toys.optflags&2); |
Rob Landley | 433c030 | 2008-12-27 05:37:47 -0600 | [diff] [blame] | 86 | loopfiles(toys.optargs, do_cksum); |
| 87 | } |