source: MondoRescue/branches/3.3/mindi-busybox/coreutils/md5_sha1_sum.c@ 3684

Last change on this file since 3684 was 3621, checked in by Bruno Cornec, 7 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 7.5 KB
RevLine 
[821]1/* vi: set sw=4 ts=4: */
2/*
3 * Copyright (C) 2003 Glenn L. McGrath
4 * Copyright (C) 2003-2004 Erik Andersen
5 *
[2725]6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
[821]7 */
8
[3232]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"
17//usage: )
18//usage:
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"
27//usage: "^D\n"
28//usage:
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"
37//usage: )
38//usage:
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"
47//usage: )
48//usage:
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"
57//usage: )
58//usage:
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"
67//usage: )
68
[1765]69#include "libbb.h"
[821]70
[2725]71/* This is a NOEXEC applet. Be very careful! */
[821]72
[2725]73enum {
74 /* 4th letter of applet_name is... */
75 HASH_MD5 = 's', /* "md5>s<um" */
76 HASH_SHA1 = '1',
77 HASH_SHA256 = '2',
[3232]78 HASH_SHA3 = '3',
[2725]79 HASH_SHA512 = '5',
80};
[821]81
[2725]82#define FLAG_SILENT 1
83#define FLAG_CHECK 2
84#define FLAG_WARN 4
85
[821]86/* This might be useful elsewhere */
87static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
[1765]88 unsigned hash_length)
[821]89{
[1765]90 /* xzalloc zero-terminates */
91 char *hex_value = xzalloc((hash_length * 2) + 1);
92 bin2hex(hex_value, (char*)hash_value, hash_length);
[2725]93 return (unsigned char *)hex_value;
[821]94}
95
[2725]96static uint8_t *hash_file(const char *filename)
[821]97{
98 int src_fd, hash_len, count;
99 union _ctx_ {
[3232]100 sha3_ctx_t sha3;
[2725]101 sha512_ctx_t sha512;
102 sha256_ctx_t sha256;
[821]103 sha1_ctx_t sha1;
104 md5_ctx_t md5;
105 } context;
[3232]106 uint8_t *hash_value;
[2725]107 void FAST_FUNC (*update)(void*, const void*, size_t);
108 void FAST_FUNC (*final)(void*, void*);
109 char hash_algo;
[821]110
[2725]111 src_fd = open_or_warn_stdin(filename);
112 if (src_fd < 0) {
113 return NULL;
[821]114 }
115
[2725]116 hash_algo = applet_name[3];
117
[3232]118 /* figure specific hash algorithms */
[2725]119 if (ENABLE_MD5SUM && hash_algo == HASH_MD5) {
[821]120 md5_begin(&context.md5);
[2725]121 update = (void*)md5_hash;
122 final = (void*)md5_end;
[821]123 hash_len = 16;
[2725]124 } else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) {
[821]125 sha1_begin(&context.sha1);
[2725]126 update = (void*)sha1_hash;
127 final = (void*)sha1_end;
[821]128 hash_len = 20;
[2725]129 } else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) {
130 sha256_begin(&context.sha256);
131 update = (void*)sha256_hash;
132 final = (void*)sha256_end;
133 hash_len = 32;
134 } else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) {
135 sha512_begin(&context.sha512);
136 update = (void*)sha512_hash;
137 final = (void*)sha512_end;
138 hash_len = 64;
[3232]139 } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) {
140 sha3_begin(&context.sha3);
141 update = (void*)sha3_hash;
142 final = (void*)sha3_end;
143 hash_len = 64;
[821]144 } else {
[2725]145 xfunc_die(); /* can't reach this */
[821]146 }
147
[3232]148 {
149 RESERVE_CONFIG_UBUFFER(in_buf, 4096);
150 while ((count = safe_read(src_fd, in_buf, 4096)) > 0) {
151 update(&context, in_buf, count);
152 }
153 hash_value = NULL;
[3621]154 if (count < 0)
155 bb_perror_msg("can't read '%s'", filename);
156 else /* count == 0 */ {
[3232]157 final(&context, in_buf);
158 hash_value = hash_bin_to_hex(in_buf, hash_len);
159 }
160 RELEASE_CONFIG_BUFFER(in_buf);
[821]161 }
162
163 if (src_fd != STDIN_FILENO) {
164 close(src_fd);
165 }
166
167 return hash_value;
168}
169
[2725]170int md5_sha1_sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
171int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
[821]172{
173 int return_value = EXIT_SUCCESS;
[1765]174 unsigned flags;
[821]175
[2725]176 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) {
177 /* -b "binary", -t "text" are ignored (shaNNNsum compat) */
178 flags = getopt32(argv, "scwbt");
179 argv += optind;
180 //argc -= optind;
181 } else {
182 argv += 1;
183 //argc -= 1;
184 }
185 if (!*argv)
186 *--argv = (char*)"-";
[821]187
188 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) {
189 if (flags & FLAG_SILENT) {
[2725]190 bb_error_msg_and_die("-%c is meaningful only with -c", 's');
[821]191 }
[2725]192 if (flags & FLAG_WARN) {
193 bb_error_msg_and_die("-%c is meaningful only with -c", 'w');
194 }
[821]195 }
196
[3232]197 do {
198 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
199 FILE *pre_computed_stream;
200 char *line;
201 int count_total = 0;
202 int count_failed = 0;
[821]203
[3232]204 pre_computed_stream = xfopen_stdin(*argv);
[821]205
[3232]206 while ((line = xmalloc_fgetline(pre_computed_stream)) != NULL) {
207 uint8_t *hash_value;
208 char *filename_ptr;
[821]209
[3232]210 count_total++;
211 filename_ptr = strstr(line, " ");
212 /* handle format for binary checksums */
213 if (filename_ptr == NULL) {
214 filename_ptr = strstr(line, " *");
215 }
216 if (filename_ptr == NULL) {
217 if (flags & FLAG_WARN) {
218 bb_error_msg("invalid format");
219 }
220 count_failed++;
221 return_value = EXIT_FAILURE;
222 free(line);
223 continue;
224 }
225 *filename_ptr = '\0';
226 filename_ptr += 2;
[821]227
[3232]228 hash_value = hash_file(filename_ptr);
229
230 if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
231 if (!(flags & FLAG_SILENT))
232 printf("%s: OK\n", filename_ptr);
233 } else {
234 if (!(flags & FLAG_SILENT))
235 printf("%s: FAILED\n", filename_ptr);
236 count_failed++;
237 return_value = EXIT_FAILURE;
[821]238 }
[3232]239 /* possible free(NULL) */
240 free(hash_value);
[821]241 free(line);
242 }
[3232]243 if (count_failed && !(flags & FLAG_SILENT)) {
244 bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
245 count_failed, count_total);
[821]246 }
[3232]247 fclose_if_not_stdin(pre_computed_stream);
248 } else {
[2725]249 uint8_t *hash_value = hash_file(*argv);
[821]250 if (hash_value == NULL) {
251 return_value = EXIT_FAILURE;
252 } else {
[2725]253 printf("%s %s\n", hash_value, *argv);
[821]254 free(hash_value);
255 }
[3232]256 }
257 } while (*++argv);
258
[1765]259 return return_value;
[821]260}
Note: See TracBrowser for help on using the repository browser.