10f66f451Sopenharmony_ci/* cksum.c - produce crc32 checksum value for each input 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2008 Rob Landley <rob@landley.net> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/cksum.html 60f66f451Sopenharmony_ci 70f66f451Sopenharmony_ciUSE_CKSUM(NEWTOY(cksum, "HIPLN", TOYFLAG_BIN)) 80f66f451Sopenharmony_ciUSE_CRC32(NEWTOY(crc32, 0, TOYFLAG_BIN)) 90f66f451Sopenharmony_ci 100f66f451Sopenharmony_ciconfig CKSUM 110f66f451Sopenharmony_ci bool "cksum" 120f66f451Sopenharmony_ci default y 130f66f451Sopenharmony_ci help 140f66f451Sopenharmony_ci usage: cksum [-IPLN] [FILE...] 150f66f451Sopenharmony_ci 160f66f451Sopenharmony_ci For each file, output crc32 checksum value, length and name of file. 170f66f451Sopenharmony_ci If no files listed, copy from stdin. Filename "-" is a synonym for stdin. 180f66f451Sopenharmony_ci 190f66f451Sopenharmony_ci -H Hexadecimal checksum (defaults to decimal) 200f66f451Sopenharmony_ci -L Little endian (defaults to big endian) 210f66f451Sopenharmony_ci -P Pre-inversion 220f66f451Sopenharmony_ci -I Skip post-inversion 230f66f451Sopenharmony_ci -N Do not include length in CRC calculation (or output) 240f66f451Sopenharmony_ci 250f66f451Sopenharmony_ciconfig CRC32 260f66f451Sopenharmony_ci bool "crc32" 270f66f451Sopenharmony_ci default y 280f66f451Sopenharmony_ci help 290f66f451Sopenharmony_ci usage: crc32 [file...] 300f66f451Sopenharmony_ci 310f66f451Sopenharmony_ci Output crc32 checksum for each file. 320f66f451Sopenharmony_ci*/ 330f66f451Sopenharmony_ci 340f66f451Sopenharmony_ci#define FOR_cksum 350f66f451Sopenharmony_ci#define FORCE_FLAGS 360f66f451Sopenharmony_ci#include "toys.h" 370f66f451Sopenharmony_ci 380f66f451Sopenharmony_ciGLOBALS( 390f66f451Sopenharmony_ci unsigned crc_table[256]; 400f66f451Sopenharmony_ci) 410f66f451Sopenharmony_ci 420f66f451Sopenharmony_cistatic unsigned cksum_be(unsigned crc, unsigned char c) 430f66f451Sopenharmony_ci{ 440f66f451Sopenharmony_ci return (crc<<8)^TT.crc_table[(crc>>24)^c]; 450f66f451Sopenharmony_ci} 460f66f451Sopenharmony_ci 470f66f451Sopenharmony_cistatic unsigned cksum_le(unsigned crc, unsigned char c) 480f66f451Sopenharmony_ci{ 490f66f451Sopenharmony_ci return TT.crc_table[(crc^c)&0xff] ^ (crc>>8); 500f66f451Sopenharmony_ci} 510f66f451Sopenharmony_ci 520f66f451Sopenharmony_cistatic void do_cksum(int fd, char *name) 530f66f451Sopenharmony_ci{ 540f66f451Sopenharmony_ci unsigned crc = (toys.optflags & FLAG_P) ? 0xffffffff : 0; 550f66f451Sopenharmony_ci uint64_t llen = 0, llen2; 560f66f451Sopenharmony_ci unsigned (*cksum)(unsigned crc, unsigned char c); 570f66f451Sopenharmony_ci int len, i; 580f66f451Sopenharmony_ci 590f66f451Sopenharmony_ci cksum = (toys.optflags & FLAG_L) ? cksum_le : cksum_be; 600f66f451Sopenharmony_ci // CRC the data 610f66f451Sopenharmony_ci 620f66f451Sopenharmony_ci for (;;) { 630f66f451Sopenharmony_ci len = read(fd, toybuf, sizeof(toybuf)); 640f66f451Sopenharmony_ci if (len<0) perror_msg_raw(name); 650f66f451Sopenharmony_ci if (len<1) break; 660f66f451Sopenharmony_ci 670f66f451Sopenharmony_ci llen += len; 680f66f451Sopenharmony_ci for (i=0; i<len; i++) crc=cksum(crc, toybuf[i]); 690f66f451Sopenharmony_ci } 700f66f451Sopenharmony_ci 710f66f451Sopenharmony_ci // CRC the length 720f66f451Sopenharmony_ci 730f66f451Sopenharmony_ci llen2 = llen; 740f66f451Sopenharmony_ci if (!(toys.optflags & FLAG_N)) { 750f66f451Sopenharmony_ci while (llen) { 760f66f451Sopenharmony_ci crc = cksum(crc, llen); 770f66f451Sopenharmony_ci llen >>= 8; 780f66f451Sopenharmony_ci } 790f66f451Sopenharmony_ci } 800f66f451Sopenharmony_ci 810f66f451Sopenharmony_ci printf((toys.optflags & FLAG_H) ? "%08x" : "%u", 820f66f451Sopenharmony_ci (toys.optflags & FLAG_I) ? crc : ~crc); 830f66f451Sopenharmony_ci if (!(toys.optflags&FLAG_N)) printf(" %"PRIu64, llen2); 840f66f451Sopenharmony_ci if (toys.optc) printf(" %s", name); 850f66f451Sopenharmony_ci xputc('\n'); 860f66f451Sopenharmony_ci} 870f66f451Sopenharmony_ci 880f66f451Sopenharmony_civoid cksum_main(void) 890f66f451Sopenharmony_ci{ 900f66f451Sopenharmony_ci crc_init(TT.crc_table, toys.optflags & FLAG_L); 910f66f451Sopenharmony_ci loopfiles(toys.optargs, do_cksum); 920f66f451Sopenharmony_ci} 930f66f451Sopenharmony_ci 940f66f451Sopenharmony_civoid crc32_main(void) 950f66f451Sopenharmony_ci{ 960f66f451Sopenharmony_ci toys.optflags |= FLAG_H|FLAG_N|FLAG_P|FLAG_L; 970f66f451Sopenharmony_ci if (toys.optc) toys.optc--; 980f66f451Sopenharmony_ci cksum_main(); 990f66f451Sopenharmony_ci} 100