| 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 | |
| 9 | USE_CKSUM(NEWTOY(cksum, NULL, TOYFLAG_BIN)) |
| 10 | |
| 11 | config 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 | |
| 22 | DEFINE_GLOBALS( |
| 23 | unsigned crc_table[256]; |
| 24 | ) |
| 25 | |
| 26 | #define TT this.cksum |
| 27 | |
| 28 | static unsigned cksum(unsigned crc, unsigned char c) |
| 29 | { |
| 30 | return (crc<<8)^TT.crc_table[(crc>>24)^c]; |
| 31 | } |
| 32 | |
| 33 | static 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 | |
| 67 | void cksum_main(void) |
| 68 | { |
| 69 | crc_init(TT.crc_table); |
| 70 | loopfiles(toys.optargs, do_cksum); |
| 71 | } |