Annotation of /trunk/mkinitrd-magellan/busybox/coreutils/md5_sha1_sum.c
Parent Directory | Revision Log
Revision 532 -
(hide annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 4521 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 4521 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | niro | 532 | /* 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 the GPL v2 or later, see the file LICENSE in this tarball. | ||
7 | */ | ||
8 | |||
9 | #include "busybox.h" | ||
10 | |||
11 | typedef enum { HASH_SHA1, HASH_MD5 } hash_algo_t; | ||
12 | |||
13 | #define FLAG_SILENT 1 | ||
14 | #define FLAG_CHECK 2 | ||
15 | #define FLAG_WARN 4 | ||
16 | |||
17 | /* This might be useful elsewhere */ | ||
18 | static unsigned char *hash_bin_to_hex(unsigned char *hash_value, | ||
19 | unsigned hash_length) | ||
20 | { | ||
21 | /* xzalloc zero-terminates */ | ||
22 | char *hex_value = xzalloc((hash_length * 2) + 1); | ||
23 | bin2hex(hex_value, (char*)hash_value, hash_length); | ||
24 | return hex_value; | ||
25 | } | ||
26 | |||
27 | static uint8_t *hash_file(const char *filename, hash_algo_t hash_algo) | ||
28 | { | ||
29 | int src_fd, hash_len, count; | ||
30 | union _ctx_ { | ||
31 | sha1_ctx_t sha1; | ||
32 | md5_ctx_t md5; | ||
33 | } context; | ||
34 | uint8_t *hash_value = NULL; | ||
35 | RESERVE_CONFIG_UBUFFER(in_buf, 4096); | ||
36 | void (*update)(const void*, size_t, void*); | ||
37 | void (*final)(void*, void*); | ||
38 | |||
39 | src_fd = STDIN_FILENO; | ||
40 | if (NOT_LONE_DASH(filename)) { | ||
41 | src_fd = open(filename, O_RDONLY); | ||
42 | if (src_fd < 0) { | ||
43 | bb_perror_msg("%s", filename); | ||
44 | return NULL; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | /* figure specific hash algorithims */ | ||
49 | if (ENABLE_MD5SUM && hash_algo==HASH_MD5) { | ||
50 | md5_begin(&context.md5); | ||
51 | update = (void (*)(const void*, size_t, void*))md5_hash; | ||
52 | final = (void (*)(void*, void*))md5_end; | ||
53 | hash_len = 16; | ||
54 | } else if (ENABLE_SHA1SUM && hash_algo==HASH_SHA1) { | ||
55 | sha1_begin(&context.sha1); | ||
56 | update = (void (*)(const void*, size_t, void*))sha1_hash; | ||
57 | final = (void (*)(void*, void*))sha1_end; | ||
58 | hash_len = 20; | ||
59 | } else { | ||
60 | bb_error_msg_and_die("algorithm not supported"); | ||
61 | } | ||
62 | |||
63 | while (0 < (count = safe_read(src_fd, in_buf, 4096))) { | ||
64 | update(in_buf, count, &context); | ||
65 | } | ||
66 | |||
67 | if (count == 0) { | ||
68 | final(in_buf, &context); | ||
69 | hash_value = hash_bin_to_hex(in_buf, hash_len); | ||
70 | } | ||
71 | |||
72 | RELEASE_CONFIG_BUFFER(in_buf); | ||
73 | |||
74 | if (src_fd != STDIN_FILENO) { | ||
75 | close(src_fd); | ||
76 | } | ||
77 | |||
78 | return hash_value; | ||
79 | } | ||
80 | |||
81 | int md5_sha1_sum_main(int argc, char **argv) | ||
82 | { | ||
83 | int return_value = EXIT_SUCCESS; | ||
84 | uint8_t *hash_value; | ||
85 | unsigned flags; | ||
86 | hash_algo_t hash_algo = ENABLE_MD5SUM | ||
87 | ? (ENABLE_SHA1SUM ? (**argv=='m' ? HASH_MD5 : HASH_SHA1) : HASH_MD5) | ||
88 | : HASH_SHA1; | ||
89 | |||
90 | if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) | ||
91 | flags = getopt32(argc, argv, "scw"); | ||
92 | else optind = 1; | ||
93 | |||
94 | if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) { | ||
95 | if (flags & FLAG_SILENT) { | ||
96 | bb_error_msg_and_die | ||
97 | ("-%c is meaningful only when verifying checksums", 's'); | ||
98 | } else if (flags & FLAG_WARN) { | ||
99 | bb_error_msg_and_die | ||
100 | ("-%c is meaningful only when verifying checksums", 'w'); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | if (argc == optind) { | ||
105 | argv[argc++] = "-"; | ||
106 | } | ||
107 | |||
108 | if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) { | ||
109 | FILE *pre_computed_stream; | ||
110 | int count_total = 0; | ||
111 | int count_failed = 0; | ||
112 | char *file_ptr = argv[optind]; | ||
113 | char *line; | ||
114 | |||
115 | if (optind + 1 != argc) { | ||
116 | bb_error_msg_and_die | ||
117 | ("only one argument may be specified when using -c"); | ||
118 | } | ||
119 | |||
120 | pre_computed_stream = stdin; | ||
121 | if (NOT_LONE_DASH(file_ptr)) { | ||
122 | pre_computed_stream = xfopen(file_ptr, "r"); | ||
123 | } | ||
124 | |||
125 | while ((line = xmalloc_getline(pre_computed_stream)) != NULL) { | ||
126 | char *filename_ptr; | ||
127 | |||
128 | count_total++; | ||
129 | filename_ptr = strstr(line, " "); | ||
130 | /* handle format for binary checksums */ | ||
131 | if (filename_ptr == NULL) { | ||
132 | filename_ptr = strstr(line, " *"); | ||
133 | } | ||
134 | if (filename_ptr == NULL) { | ||
135 | if (flags & FLAG_WARN) { | ||
136 | bb_error_msg("invalid format"); | ||
137 | } | ||
138 | count_failed++; | ||
139 | return_value = EXIT_FAILURE; | ||
140 | free(line); | ||
141 | continue; | ||
142 | } | ||
143 | *filename_ptr = '\0'; | ||
144 | filename_ptr += 2; | ||
145 | |||
146 | hash_value = hash_file(filename_ptr, hash_algo); | ||
147 | |||
148 | if (hash_value && (strcmp((char*)hash_value, line) == 0)) { | ||
149 | if (!(flags & FLAG_SILENT)) | ||
150 | printf("%s: OK\n", filename_ptr); | ||
151 | } else { | ||
152 | if (!(flags & FLAG_SILENT)) | ||
153 | printf("%s: FAILED\n", filename_ptr); | ||
154 | count_failed++; | ||
155 | return_value = EXIT_FAILURE; | ||
156 | } | ||
157 | /* possible free(NULL) */ | ||
158 | free(hash_value); | ||
159 | free(line); | ||
160 | } | ||
161 | if (count_failed && !(flags & FLAG_SILENT)) { | ||
162 | bb_error_msg("WARNING: %d of %d computed checksums did NOT match", | ||
163 | count_failed, count_total); | ||
164 | } | ||
165 | /* | ||
166 | if (fclose_if_not_stdin(pre_computed_stream) == EOF) { | ||
167 | bb_perror_msg_and_die("cannot close file %s", file_ptr); | ||
168 | } | ||
169 | */ | ||
170 | } else { | ||
171 | while (optind < argc) { | ||
172 | char *file_ptr = argv[optind++]; | ||
173 | |||
174 | hash_value = hash_file(file_ptr, hash_algo); | ||
175 | if (hash_value == NULL) { | ||
176 | return_value = EXIT_FAILURE; | ||
177 | } else { | ||
178 | printf("%s %s\n", hash_value, file_ptr); | ||
179 | free(hash_value); | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | return return_value; | ||
184 | } |