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"
71 /* This is a NOEXEC applet. Be very careful! */
74 /* 4th letter of applet_name is... */
75 HASH_MD5
= 's', /* "md5>s<um" */
86 /* This might be useful elsewhere */
87 static unsigned char *hash_bin_to_hex(unsigned char *hash_value
,
90 /* xzalloc zero-terminates */
91 char *hex_value
= xzalloc((hash_length
* 2) + 1);
92 bin2hex(hex_value
, (char*)hash_value
, hash_length
);
93 return (unsigned char *)hex_value
;
96 static uint8_t *hash_file(const char *filename
)
98 int src_fd
, hash_len
, count
;
107 void FAST_FUNC (*update
)(void*, const void*, size_t);
108 void FAST_FUNC (*final
)(void*, void*);
111 src_fd
= open_or_warn_stdin(filename
);
116 hash_algo
= applet_name
[3];
118 /* figure specific hash algorithms */
119 if (ENABLE_MD5SUM
&& hash_algo
== HASH_MD5
) {
120 md5_begin(&context
.md5
);
121 update
= (void*)md5_hash
;
122 final
= (void*)md5_end
;
124 } else if (ENABLE_SHA1SUM
&& hash_algo
== HASH_SHA1
) {
125 sha1_begin(&context
.sha1
);
126 update
= (void*)sha1_hash
;
127 final
= (void*)sha1_end
;
129 } else if (ENABLE_SHA256SUM
&& hash_algo
== HASH_SHA256
) {
130 sha256_begin(&context
.sha256
);
131 update
= (void*)sha256_hash
;
132 final
= (void*)sha256_end
;
134 } else if (ENABLE_SHA512SUM
&& hash_algo
== HASH_SHA512
) {
135 sha512_begin(&context
.sha512
);
136 update
= (void*)sha512_hash
;
137 final
= (void*)sha512_end
;
139 } else if (ENABLE_SHA3SUM
&& hash_algo
== HASH_SHA3
) {
140 sha3_begin(&context
.sha3
);
141 update
= (void*)sha3_hash
;
142 final
= (void*)sha3_end
;
145 xfunc_die(); /* can't reach this */
149 RESERVE_CONFIG_UBUFFER(in_buf
, 4096);
150 while ((count
= safe_read(src_fd
, in_buf
, 4096)) > 0) {
151 update(&context
, in_buf
, count
);
155 final(&context
, in_buf
);
156 hash_value
= hash_bin_to_hex(in_buf
, hash_len
);
158 RELEASE_CONFIG_BUFFER(in_buf
);
161 if (src_fd
!= STDIN_FILENO
) {
168 int md5_sha1_sum_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
169 int md5_sha1_sum_main(int argc UNUSED_PARAM
, char **argv
)
171 int return_value
= EXIT_SUCCESS
;
174 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK
) {
175 /* -b "binary", -t "text" are ignored (shaNNNsum compat) */
176 flags
= getopt32(argv
, "scwbt");
184 *--argv
= (char*)"-";
186 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK
&& !(flags
& FLAG_CHECK
)) {
187 if (flags
& FLAG_SILENT
) {
188 bb_error_msg_and_die("-%c is meaningful only with -c", 's');
190 if (flags
& FLAG_WARN
) {
191 bb_error_msg_and_die("-%c is meaningful only with -c", 'w');
196 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK
&& (flags
& FLAG_CHECK
)) {
197 FILE *pre_computed_stream
;
200 int count_failed
= 0;
202 pre_computed_stream
= xfopen_stdin(*argv
);
204 while ((line
= xmalloc_fgetline(pre_computed_stream
)) != NULL
) {
209 filename_ptr
= strstr(line
, " ");
210 /* handle format for binary checksums */
211 if (filename_ptr
== NULL
) {
212 filename_ptr
= strstr(line
, " *");
214 if (filename_ptr
== NULL
) {
215 if (flags
& FLAG_WARN
) {
216 bb_error_msg("invalid format");
219 return_value
= EXIT_FAILURE
;
223 *filename_ptr
= '\0';
226 hash_value
= hash_file(filename_ptr
);
228 if (hash_value
&& (strcmp((char*)hash_value
, line
) == 0)) {
229 if (!(flags
& FLAG_SILENT
))
230 printf("%s: OK\n", filename_ptr
);
232 if (!(flags
& FLAG_SILENT
))
233 printf("%s: FAILED\n", filename_ptr
);
235 return_value
= EXIT_FAILURE
;
237 /* possible free(NULL) */
241 if (count_failed
&& !(flags
& FLAG_SILENT
)) {
242 bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
243 count_failed
, count_total
);
245 fclose_if_not_stdin(pre_computed_stream
);
247 uint8_t *hash_value
= hash_file(*argv
);
248 if (hash_value
== NULL
) {
249 return_value
= EXIT_FAILURE
;
251 printf("%s %s\n", hash_value
, *argv
);