diff options
Diffstat (limited to 'coreutils/cksum.c')
-rw-r--r-- | coreutils/cksum.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/coreutils/cksum.c b/coreutils/cksum.c new file mode 100644 index 000000000..52213328c --- /dev/null +++ b/coreutils/cksum.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * cksum - calculate the CRC32 checksum of a file | ||
4 | * | ||
5 | * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ | ||
8 | |||
9 | #include "busybox.h" | ||
10 | |||
11 | int cksum_main(int argc, char **argv) | ||
12 | { | ||
13 | |||
14 | uint32_t *crc32_table = crc32_filltable(1); | ||
15 | |||
16 | FILE *fp; | ||
17 | uint32_t crc; | ||
18 | long length, filesize; | ||
19 | int bytes_read; | ||
20 | char *cp; | ||
21 | |||
22 | int inp_stdin = (argc == optind) ? 1 : 0; | ||
23 | |||
24 | do { | ||
25 | fp = fopen_or_warn_stdin((inp_stdin) ? bb_msg_standard_input : *++argv); | ||
26 | |||
27 | crc = 0; | ||
28 | length = 0; | ||
29 | |||
30 | while ((bytes_read = fread(bb_common_bufsiz1, 1, BUFSIZ, fp)) > 0) { | ||
31 | cp = bb_common_bufsiz1; | ||
32 | length += bytes_read; | ||
33 | while (bytes_read--) | ||
34 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL]; | ||
35 | } | ||
36 | |||
37 | filesize = length; | ||
38 | |||
39 | for (; length; length >>= 8) | ||
40 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL]; | ||
41 | crc ^= 0xffffffffL; | ||
42 | |||
43 | if (inp_stdin) { | ||
44 | printf("%" PRIu32 " %li\n", crc, filesize); | ||
45 | break; | ||
46 | } | ||
47 | |||
48 | printf("%" PRIu32 " %li %s\n", crc, filesize, *argv); | ||
49 | fclose(fp); | ||
50 | } while (*(argv + 1)); | ||
51 | |||
52 | fflush_stdout_and_exit(EXIT_SUCCESS); | ||
53 | } | ||