1 /* vi: set sw=4 ts=4: */
3 * Copyright (C) 2003 Glenn L. McGrath
4 * Copyright (C) 2003-2004 Erik Andersen
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9 //usage:#define md5sum_trivial_usage
10 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
11 //usage:#define md5sum_full_usage "\n\n"
12 //usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " MD5 checksums"
13 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
14 //usage: "\n -c Check sums against list in FILEs"
15 //usage: "\n -s Don't output anything, status code shows success"
16 //usage: "\n -w Warn about improperly formatted checksum lines"
19 //usage:#define md5sum_example_usage
20 //usage: "$ md5sum < busybox\n"
21 //usage: "6fd11e98b98a58f64ff3398d7b324003\n"
22 //usage: "$ md5sum busybox\n"
23 //usage: "6fd11e98b98a58f64ff3398d7b324003 busybox\n"
24 //usage: "$ md5sum -c -\n"
25 //usage: "6fd11e98b98a58f64ff3398d7b324003 busybox\n"
26 //usage: "busybox: OK\n"
29 //usage:#define sha1sum_trivial_usage
30 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
31 //usage:#define sha1sum_full_usage "\n\n"
32 //usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums"
33 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
34 //usage: "\n -c Check sums against list in FILEs"
35 //usage: "\n -s Don't output anything, status code shows success"
36 //usage: "\n -w Warn about improperly formatted checksum lines"
39 //usage:#define sha256sum_trivial_usage
40 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
41 //usage:#define sha256sum_full_usage "\n\n"
42 //usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA256 checksums"
43 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
44 //usage: "\n -c Check sums against list in FILEs"
45 //usage: "\n -s Don't output anything, status code shows success"
46 //usage: "\n -w Warn about improperly formatted checksum lines"
49 //usage:#define sha512sum_trivial_usage
50 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
51 //usage:#define sha512sum_full_usage "\n\n"
52 //usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA512 checksums"
53 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
54 //usage: "\n -c Check sums against list in FILEs"
55 //usage: "\n -s Don't output anything, status code shows success"
56 //usage: "\n -w Warn about improperly formatted checksum lines"
59 //usage:#define sha3sum_trivial_usage
60 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
61 //usage:#define sha3sum_full_usage "\n\n"
62 //usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3-512 checksums"
63 //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
64 //usage: "\n -c Check sums against list in FILEs"
65 //usage: "\n -s Don't output anything, status code shows success"
66 //usage: "\n -w Warn about improperly formatted checksum lines"
69 //FIXME: GNU coreutils 8.25 has no -s option, it has only these two long opts:
70 // --quiet don't print OK for each successfully verified file
71 // --status don't output anything, status code shows success
75 /* This is a NOEXEC applet. Be very careful! */
78 /* 4th letter of applet_name is... */
79 HASH_MD5 = 's', /* "md5>s<um" */
90 /* This might be useful elsewhere */
91 static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
94 /* xzalloc zero-terminates */
95 char *hex_value = xzalloc((hash_length * 2) + 1);
96 bin2hex(hex_value, (char*)hash_value, hash_length);
97 return (unsigned char *)hex_value;
100 static uint8_t *hash_file(const char *filename)
102 int src_fd, hash_len, count;
111 void FAST_FUNC (*update)(void*, const void*, size_t);
112 void FAST_FUNC (*final)(void*, void*);
115 src_fd = open_or_warn_stdin(filename);
120 hash_algo = applet_name[3];
122 /* figure specific hash algorithms */
123 if (ENABLE_MD5SUM && hash_algo == HASH_MD5) {
124 md5_begin(&context.md5);
125 update = (void*)md5_hash;
126 final = (void*)md5_end;
128 } else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) {
129 sha1_begin(&context.sha1);
130 update = (void*)sha1_hash;
131 final = (void*)sha1_end;
133 } else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) {
134 sha256_begin(&context.sha256);
135 update = (void*)sha256_hash;
136 final = (void*)sha256_end;
138 } else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) {
139 sha512_begin(&context.sha512);
140 update = (void*)sha512_hash;
141 final = (void*)sha512_end;
143 } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) {
144 sha3_begin(&context.sha3);
145 update = (void*)sha3_hash;
146 final = (void*)sha3_end;
149 xfunc_die(); /* can't reach this */
153 RESERVE_CONFIG_UBUFFER(in_buf, 4096);
154 while ((count = safe_read(src_fd, in_buf, 4096)) > 0) {
155 update(&context, in_buf, count);
159 bb_perror_msg("can't read '%s'", filename);
160 else /* count == 0 */ {
161 final(&context, in_buf);
162 hash_value = hash_bin_to_hex(in_buf, hash_len);
164 RELEASE_CONFIG_BUFFER(in_buf);
167 if (src_fd != STDIN_FILENO) {
174 int md5_sha1_sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
175 int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
177 int return_value = EXIT_SUCCESS;
180 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) {
181 /* -s and -w require -c */
182 opt_complementary = "s?c:w?c";
183 /* -b "binary", -t "text" are ignored (shaNNNsum compat) */
184 flags = getopt32(argv, "scwbt");
192 *--argv = (char*)"-";
195 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
196 FILE *pre_computed_stream;
199 int count_failed = 0;
201 pre_computed_stream = xfopen_stdin(*argv);
203 while ((line = xmalloc_fgetline(pre_computed_stream)) != NULL) {
208 filename_ptr = strstr(line, " ");
209 /* handle format for binary checksums */
210 if (filename_ptr == NULL) {
211 filename_ptr = strstr(line, " *");
213 if (filename_ptr == NULL) {
214 if (flags & FLAG_WARN) {
215 bb_error_msg("invalid format");
218 return_value = EXIT_FAILURE;
222 *filename_ptr = '\0';
225 hash_value = hash_file(filename_ptr);
227 if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
228 if (!(flags & FLAG_SILENT))
229 printf("%s: OK\n", filename_ptr);
231 if (!(flags & FLAG_SILENT))
232 printf("%s: FAILED\n", filename_ptr);
234 return_value = EXIT_FAILURE;
236 /* possible free(NULL) */
240 if (count_failed && !(flags & FLAG_SILENT)) {
241 bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
242 count_failed, count_total);
244 if (count_total == 0) {
245 return_value = EXIT_FAILURE;
247 * md5sum from GNU coreutils 8.25 says:
248 * md5sum: <FILE>: no properly formatted MD5 checksum lines found
250 bb_error_msg("%s: no checksum lines found", *argv);
252 fclose_if_not_stdin(pre_computed_stream);
254 uint8_t *hash_value = hash_file(*argv);
255 if (hash_value == NULL) {
256 return_value = EXIT_FAILURE;
258 printf("%s %s\n", hash_value, *argv);