1 /* cksum.c - produce crc32 checksum value for each input 2 * 3 * Copyright 2008 Rob Landley <rob (at) 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 38 GLOBALS( 39 unsigned crc_table[256]; 40 ) 41 42 static unsigned cksum_be(unsigned crc, unsigned char c) 43 { 44 return (crc<<8)^TT.crc_table[(crc>>24)^c]; 45 } 46 47 static unsigned cksum_le(unsigned crc, unsigned char c) 48 { 49 return TT.crc_table[(crc^c)&0xff] ^ (crc>>8); 50 } 51 52 static void do_cksum(int fd, char *name) 53 { 54 unsigned crc = (toys.optflags & FLAG_P) ? 0xffffffff : 0; 55 uint64_t llen = 0, llen2; 56 unsigned (*cksum)(unsigned crc, unsigned char c); 57 int len, i; 58 59 cksum = (toys.optflags & FLAG_L) ? cksum_le : cksum_be; 60 // CRC the data 61 62 for (;;) { 63 len = read(fd, toybuf, sizeof(toybuf)); 64 if (len<0) perror_msg_raw(name); 65 if (len<1) break; 66 67 llen += len; 68 for (i=0; i<len; i++) crc=cksum(crc, toybuf[i]); 69 } 70 71 // CRC the length 72 73 llen2 = llen; 74 if (!(toys.optflags & FLAG_N)) { 75 while (llen) { 76 crc = cksum(crc, llen); 77 llen >>= 8; 78 } 79 } 80 81 printf((toys.optflags & FLAG_H) ? "%08x" : "%u", 82 (toys.optflags & FLAG_I) ? crc : ~crc); 83 if (!(toys.optflags&FLAG_N)) printf(" %"PRIu64, llen2); 84 if (toys.optc) printf(" %s", name); 85 xputc('\n'); 86 } 87 88 void cksum_main(void) 89 { 90 crc_init(TT.crc_table, toys.optflags & FLAG_L); 91 loopfiles(toys.optargs, do_cksum); 92 } 93 94 void crc32_main(void) 95 { 96 toys.optflags |= FLAG_H|FLAG_N|FLAG_P|FLAG_L; 97 if (toys.optc) toys.optc--; 98 cksum_main(); 99 } 100