1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include "libbb.h"
31#include "common_bufsiz.h"
32
33
34
35#define IS_CKSUM (ENABLE_CKSUM && (!ENABLE_CRC32 || applet_name[1] == 'k'))
36#define IS_CRC32 (ENABLE_CRC32 && (!ENABLE_CKSUM || applet_name[1] == 'r'))
37
38int cksum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
39int cksum_main(int argc UNUSED_PARAM, char **argv)
40{
41 uint32_t *crc32_table = crc32_filltable(NULL, IS_CKSUM);
42 int exit_code = EXIT_SUCCESS;
43
44#if ENABLE_DESKTOP
45 getopt32(argv, "");
46 argv += optind;
47#else
48 argv++;
49#endif
50
51 setup_common_bufsiz();
52 do {
53 uint32_t crc;
54 IF_CKSUM(off_t filesize;)
55 const char *fname = *argv ? *argv : bb_msg_standard_input;
56 int fd = open_or_warn_stdin(fname);
57
58 if (fd < 0) {
59 exit_code = EXIT_FAILURE;
60 continue;
61 }
62
63 crc = IS_CKSUM ? 0 : 0xffffffff;
64 IF_CKSUM(filesize = 0;)
65#define read_buf bb_common_bufsiz1
66 for (;;) {
67 int bytes_read = safe_read(fd, read_buf, COMMON_BUFSIZE);
68 if (bytes_read < 0)
69 bb_simple_perror_msg_and_die(fname);
70 if (bytes_read > 0) {
71 IF_CKSUM(filesize += bytes_read;)
72 } else {
73 IF_CKSUM(uoff_t t;)
74
75 close(fd);
76 if (IS_CRC32)
77 break;
78#if ENABLE_CKSUM
79 fd = -1;
80
81 t = filesize;
82
83 while (t != 0) {
84 read_buf[bytes_read++] = (uint8_t)t;
85 t >>= 8;
86 }
87#endif
88 }
89 crc = (IS_CKSUM ? crc32_block_endian1 : crc32_block_endian0)(crc, read_buf, bytes_read, crc32_table);
90 if (ENABLE_CKSUM && fd < 0)
91 break;
92 }
93
94 crc = ~crc;
95#if ENABLE_CKSUM
96 if (IS_CKSUM)
97 printf((*argv ? "%u %"OFF_FMT"u %s\n" : "%u %"OFF_FMT"u\n"),
98 (unsigned)crc, filesize, *argv);
99 else
100#endif
101 printf((*argv ? "%08x %s\n" : "%08x\n"),
102 (unsigned)crc, *argv);
103 } while (*argv && *++argv);
104
105 fflush_stdout_and_exit(exit_code);
106}
107