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

Last change on this file since 3647 was 3621, checked in by Bruno Cornec, 10 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
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Copyright (C) 2003 Glenn L. McGrath
4 * Copyright (C) 2003-2004 Erik Andersen
5 *
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7 */
8
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
69#include "libbb.h"
70
71/* This is a NOEXEC applet. Be very careful! */
72
73enum {
74 /* 4th letter of applet_name is... */
75 HASH_MD5 = 's', /* "md5>s<um" */
76 HASH_SHA1 = '1',
77 HASH_SHA256 = '2',
78 HASH_SHA3 = '3',
79 HASH_SHA512 = '5',
80};
81
82#define FLAG_SILENT 1
83#define FLAG_CHECK 2
84#define FLAG_WARN 4
85
86/* This might be useful elsewhere */
87static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
88 unsigned hash_length)
89{
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;
94}
95
96static uint8_t *hash_file(const char *filename)
97{
98 int src_fd, hash_len, count;
99 union _ctx_ {
100 sha3_ctx_t sha3;
101 sha512_ctx_t sha512;
102 sha256_ctx_t sha256;
103 sha1_ctx_t sha1;
104 md5_ctx_t md5;
105 } context;
106 uint8_t *hash_value;
107 void FAST_FUNC (*update)(void*, const void*, size_t);
108 void FAST_FUNC (*final)(void*, void*);
109 char hash_algo;
110
111 src_fd = open_or_warn_stdin(filename);
112 if (src_fd < 0) {
113 return NULL;
114 }
115
116 hash_algo = applet_name[3];
117
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;
123 hash_len = 16;
124 } else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) {
125 sha1_begin(&context.sha1);
126 update = (void*)sha1_hash;
127 final = (void*)sha1_end;
128 hash_len = 20;
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;
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;
144 } else {
145 xfunc_die(); /* can't reach this */
146 }
147
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;
154 if (count < 0)
155 bb_perror_msg("can't read '%s'", filename);
156 else /* count == 0 */ {
157 final(&context, in_buf);
158 hash_value = hash_bin_to_hex(in_buf, hash_len);
159 }
160 RELEASE_CONFIG_BUFFER(in_buf);
161 }
162
163 if (src_fd != STDIN_FILENO) {
164 close(src_fd);
165 }
166
167 return hash_value;
168}
169
170int md5_sha1_sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
171int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
172{
173 int return_value = EXIT_SUCCESS;
174 unsigned flags;
175
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*)"-";
187
188 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) {
189 if (flags & FLAG_SILENT) {
190 bb_error_msg_and_die("-%c is meaningful only with -c", 's');
191 }
192 if (flags & FLAG_WARN) {
193 bb_error_msg_and_die("-%c is meaningful only with -c", 'w');
194 }
195 }
196
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;
203
204 pre_computed_stream = xfopen_stdin(*argv);
205
206 while ((line = xmalloc_fgetline(pre_computed_stream)) != NULL) {
207 uint8_t *hash_value;
208 char *filename_ptr;
209
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;
227
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;
238 }
239 /* possible free(NULL) */
240 free(hash_value);
241 free(line);
242 }
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);
246 }
247 fclose_if_not_stdin(pre_computed_stream);
248 } else {
249 uint8_t *hash_value = hash_file(*argv);
250 if (hash_value == NULL) {
251 return_value = EXIT_FAILURE;
252 } else {
253 printf("%s %s\n", hash_value, *argv);
254 free(hash_value);
255 }
256 }
257 } while (*++argv);
258
259 return return_value;
260}
Note: See TracBrowser for help on using the repository browser.