cksum.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /* cksum.c - produce crc32 checksum value for each input
  2. *
  3. * Copyright 2008 Rob Landley <rob@landley.net>
  4. *
  5. * See http://opengroup.org/onlinepubs/9699919799/utilities/cksum.html
  6. USE_CKSUM(NEWTOY(cksum, "HIPLN", TOYFLAG_BIN))
  7. USE_CRC32(NEWTOY(crc32, 0, TOYFLAG_BIN))
  8. config CKSUM
  9. bool "cksum"
  10. default y
  11. help
  12. usage: cksum [-IPLN] [FILE...]
  13. For each file, output crc32 checksum value, length and name of file.
  14. If no files listed, copy from stdin. Filename "-" is a synonym for stdin.
  15. -H Hexadecimal checksum (defaults to decimal)
  16. -L Little endian (defaults to big endian)
  17. -P Pre-inversion
  18. -I Skip post-inversion
  19. -N Do not include length in CRC calculation (or output)
  20. config CRC32
  21. bool "crc32"
  22. default y
  23. help
  24. usage: crc32 [file...]
  25. Output crc32 checksum for each file.
  26. */
  27. #define FOR_cksum
  28. #define FORCE_FLAGS
  29. #include "toys.h"
  30. GLOBALS(
  31. unsigned crc_table[256];
  32. )
  33. static unsigned cksum_be(unsigned crc, unsigned char c)
  34. {
  35. return (crc<<8)^TT.crc_table[(crc>>24)^c];
  36. }
  37. static unsigned cksum_le(unsigned crc, unsigned char c)
  38. {
  39. return TT.crc_table[(crc^c)&0xff] ^ (crc>>8);
  40. }
  41. static void do_cksum(int fd, char *name)
  42. {
  43. unsigned crc = (toys.optflags & FLAG_P) ? 0xffffffff : 0;
  44. uint64_t llen = 0, llen2;
  45. unsigned (*cksum)(unsigned crc, unsigned char c);
  46. int len, i;
  47. cksum = (toys.optflags & FLAG_L) ? cksum_le : cksum_be;
  48. // CRC the data
  49. for (;;) {
  50. len = read(fd, toybuf, sizeof(toybuf));
  51. if (len<0) perror_msg_raw(name);
  52. if (len<1) break;
  53. llen += len;
  54. for (i=0; i<len; i++) crc=cksum(crc, toybuf[i]);
  55. }
  56. // CRC the length
  57. llen2 = llen;
  58. if (!(toys.optflags & FLAG_N)) {
  59. while (llen) {
  60. crc = cksum(crc, llen);
  61. llen >>= 8;
  62. }
  63. }
  64. printf((toys.optflags & FLAG_H) ? "%08x" : "%u",
  65. (toys.optflags & FLAG_I) ? crc : ~crc);
  66. if (!(toys.optflags&FLAG_N)) printf(" %"PRIu64, llen2);
  67. if (toys.optc) printf(" %s", name);
  68. xputc('\n');
  69. }
  70. void cksum_main(void)
  71. {
  72. crc_init(TT.crc_table, toys.optflags & FLAG_L);
  73. loopfiles(toys.optargs, do_cksum);
  74. }
  75. void crc32_main(void)
  76. {
  77. toys.optflags |= FLAG_H|FLAG_N|FLAG_P|FLAG_L;
  78. if (toys.optc) toys.optc--;
  79. cksum_main();
  80. }