xref: /third_party/toybox/toys/posix/cksum.c (revision 0f66f451)
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