1 /* vi: set sw=4 ts=4: */
3 * Copyright (C) 2003 Glenn L. McGrath
4 * Copyright (C) 2003-2004 Erik Andersen
6 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
12 /* 4th letter of applet_name is... */
13 HASH_MD5
= 's', /* "md5>s<um" */
23 /* This might be useful elsewhere */
24 static unsigned char *hash_bin_to_hex(unsigned char *hash_value
,
27 /* xzalloc zero-terminates */
28 char *hex_value
= xzalloc((hash_length
* 2) + 1);
29 bin2hex(hex_value
, (char*)hash_value
, hash_length
);
30 return (unsigned char *)hex_value
;
33 static uint8_t *hash_file(const char *filename
/*, hash_algo_t hash_algo*/)
35 int src_fd
, hash_len
, count
;
42 uint8_t *hash_value
= NULL
;
43 RESERVE_CONFIG_UBUFFER(in_buf
, 4096);
44 void FAST_FUNC (*update
)(const void*, size_t, void*);
45 void FAST_FUNC (*final
)(void*, void*);
46 hash_algo_t hash_algo
= applet_name
[3];
48 src_fd
= open_or_warn_stdin(filename
);
53 /* figure specific hash algorithims */
54 if (ENABLE_MD5SUM
&& hash_algo
== HASH_MD5
) {
55 md5_begin(&context
.md5
);
56 update
= (void*)md5_hash
;
57 final
= (void*)md5_end
;
59 } else if (ENABLE_SHA1SUM
&& hash_algo
== HASH_SHA1
) {
60 sha1_begin(&context
.sha1
);
61 update
= (void*)sha1_hash
;
62 final
= (void*)sha1_end
;
64 } else if (ENABLE_SHA256SUM
&& hash_algo
== HASH_SHA256
) {
65 sha256_begin(&context
.sha256
);
66 update
= (void*)sha256_hash
;
67 final
= (void*)sha256_end
;
69 } else if (ENABLE_SHA512SUM
&& hash_algo
== HASH_SHA512
) {
70 sha512_begin(&context
.sha512
);
71 update
= (void*)sha512_hash
;
72 final
= (void*)sha512_end
;
75 bb_error_msg_and_die("algorithm not supported");
78 while (0 < (count
= safe_read(src_fd
, in_buf
, 4096))) {
79 update(in_buf
, count
, &context
);
83 final(in_buf
, &context
);
84 hash_value
= hash_bin_to_hex(in_buf
, hash_len
);
87 RELEASE_CONFIG_BUFFER(in_buf
);
89 if (src_fd
!= STDIN_FILENO
) {
96 int md5_sha1_sum_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
97 int md5_sha1_sum_main(int argc UNUSED_PARAM
, char **argv
)
99 int return_value
= EXIT_SUCCESS
;
102 /*hash_algo_t hash_algo = applet_name[3];*/
104 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK
)
105 flags
= getopt32(argv
, "scw");
110 *--argv
= (char*)"-";
112 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK
&& !(flags
& FLAG_CHECK
)) {
113 if (flags
& FLAG_SILENT
) {
115 ("-%c is meaningful only when verifying checksums", 's');
116 } else if (flags
& FLAG_WARN
) {
118 ("-%c is meaningful only when verifying checksums", 'w');
122 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK
&& (flags
& FLAG_CHECK
)) {
123 FILE *pre_computed_stream
;
125 int count_failed
= 0;
130 ("only one argument may be specified when using -c");
133 pre_computed_stream
= xfopen_stdin(argv
[0]);
135 while ((line
= xmalloc_fgetline(pre_computed_stream
)) != NULL
) {
139 filename_ptr
= strstr(line
, " ");
140 /* handle format for binary checksums */
141 if (filename_ptr
== NULL
) {
142 filename_ptr
= strstr(line
, " *");
144 if (filename_ptr
== NULL
) {
145 if (flags
& FLAG_WARN
) {
146 bb_error_msg("invalid format");
149 return_value
= EXIT_FAILURE
;
153 *filename_ptr
= '\0';
156 hash_value
= hash_file(filename_ptr
/*, hash_algo*/);
158 if (hash_value
&& (strcmp((char*)hash_value
, line
) == 0)) {
159 if (!(flags
& FLAG_SILENT
))
160 printf("%s: OK\n", filename_ptr
);
162 if (!(flags
& FLAG_SILENT
))
163 printf("%s: FAILED\n", filename_ptr
);
165 return_value
= EXIT_FAILURE
;
167 /* possible free(NULL) */
171 if (count_failed
&& !(flags
& FLAG_SILENT
)) {
172 bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
173 count_failed
, count_total
);
176 if (fclose_if_not_stdin(pre_computed_stream) == EOF) {
177 bb_perror_msg_and_die("cannot close file %s", file_ptr);
182 hash_value
= hash_file(*argv
/*, hash_algo*/);
183 if (hash_value
== NULL
) {
184 return_value
= EXIT_FAILURE
;
186 printf("%s %s\n", hash_value
, *argv
);