summaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-06-08 13:32:12 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-06-08 13:32:12 +0000
commit6c43f743a3f607f91ee22a53db880fce2df645f0 (patch)
treed0fcd64f90041aea39e1110fc4ce03860377647e /coreutils
parenta721204ec502238198b5703cfea99fd97cbca266 (diff)
downloadbusybox-w32-6c43f743a3f607f91ee22a53db880fce2df645f0.tar.gz
busybox-w32-6c43f743a3f607f91ee22a53db880fce2df645f0.tar.bz2
busybox-w32-6c43f743a3f607f91ee22a53db880fce2df645f0.zip
sha1sum option to compare checksums
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/Config.in7
-rw-r--r--coreutils/sha1sum.c162
2 files changed, 123 insertions, 46 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in
index 0d5eff3c9..2bcc48a62 100644
--- a/coreutils/Config.in
+++ b/coreutils/Config.in
@@ -342,6 +342,13 @@ config CONFIG_SHA1SUM
342 help 342 help
343 Compute and check SHA1 message digest 343 Compute and check SHA1 message digest
344 344
345config CONFIG_FEATURE_SHA1SUM_CHECK
346 bool " Enale -c and -w options"
347 default n
348 help
349 Enabling the -c and -w options allow files to be checked
350 against pre-calculated hash values.
351
345config CONFIG_SLEEP 352config CONFIG_SLEEP
346 bool "sleep (single integer arg with no suffix)" 353 bool "sleep (single integer arg with no suffix)"
347 default n 354 default n
diff --git a/coreutils/sha1sum.c b/coreutils/sha1sum.c
index 1c31e3c55..7071fb6b7 100644
--- a/coreutils/sha1sum.c
+++ b/coreutils/sha1sum.c
@@ -148,81 +148,151 @@ static char sha1sum_stream(FILE *fd, unsigned int *hashval)
148 return(EXIT_SUCCESS); 148 return(EXIT_SUCCESS);
149} 149}
150 150
151static void print_hash(unsigned int *hash_value, unsigned char hash_length, unsigned char *filename) 151#define FLAG_SILENT 1
152#define FLAG_CHECK 2
153#define FLAG_WARN 4
154
155static unsigned char *hash_bin_to_hex(unsigned int *hash_value, unsigned char hash_length)
152{ 156{
153 unsigned char x; 157 unsigned char x;
158 unsigned char *hex_value;
154 159
160 hex_value = xmalloc(hash_length * 8);
155 for (x = 0; x < hash_length; x++) { 161 for (x = 0; x < hash_length; x++) {
156 printf("%08x", hash_value[x]); 162 sprintf(&hex_value[x * 8], "%08x", hash_value[x]);
157 } 163 }
158 putchar(' '); 164 return(hex_value);
159 putchar(' ');
160 puts(filename);
161} 165}
162 166
163#define FLAG_SILENT 1 167FILE *wfopen_file_or_stdin(const char *file_ptr)
164#define FLAG_CHECK 2 168{
165#define FLAG_WARN 3 169 FILE *stream;
166 170
167/* This should become a common function used by sha1sum and md5sum, 171 if ((file_ptr[0] == '-') && (file_ptr[1] == '\0')) {
168 * it needs extra functionality first 172 stream = stdin;
169 */ 173 } else {
174 stream = bb_wfopen(file_ptr, "r");
175 }
176
177 return(stream);
178}
179
180/* This could become a common function for md5 as well, by using md5_stream */
170extern int authenticate(int argc, char **argv, char (*hash_ptr)(FILE *stream, unsigned int *hashval), const unsigned char hash_length) 181extern int authenticate(int argc, char **argv, char (*hash_ptr)(FILE *stream, unsigned int *hashval), const unsigned char hash_length)
171{ 182{
172 unsigned int hash_value[hash_length]; 183 unsigned int hash_value[hash_length];
173 unsigned char flags = 0; 184 unsigned int flags;
174 int opt; 185 int return_value = EXIT_SUCCESS;
175 int return_value; 186
176 187#ifdef CONFIG_FEATURE_SHA1SUM_CHECK
177 while ((opt = getopt(argc, argv, "sc:w")) != -1) { 188 flags = bb_getopt_ulflags(argc, argv, "scw");
178 switch (opt) { 189#else
179 case 's': /* Dont output anything, status code shows success */ 190 flags = bb_getopt_ulflags(argc, argv, "s");
180 flags |= FLAG_SILENT;
181 break;
182#if 0
183 case 'c': /* Check a list of checksums against stored values */
184 break;
185 case 'w': /* Warn of bad formatting when checking files */
186 break;
187#endif 191#endif
188 default: 192
189 bb_show_usage(); 193#ifdef CONFIG_FEATURE_SHA1SUM_CHECK
194 if (!(flags & FLAG_CHECK)) {
195 if (flags & FLAG_SILENT) {
196 bb_error_msg_and_die("the -s option is meaningful only when verifying checksums");
197 }
198 else if (flags & FLAG_WARN) {
199 bb_error_msg_and_die("the -w option is meaningful only when verifying checksums");
190 } 200 }
191 } 201 }
202#endif
192 203
193 if (argc == optind) { 204 if (argc == optind) {
194 argv[argc++] = "-"; 205 argv[argc++] = "-";
195 } 206 }
196 207
197 return_value = EXIT_SUCCESS; 208#ifdef CONFIG_FEATURE_SHA1SUM_CHECK
198 while (optind < argc) { 209 if (flags & FLAG_CHECK) {
199 FILE *stream; 210 FILE *pre_computed_stream;
211 int count_total = 0;
212 int count_failed = 0;
200 unsigned char *file_ptr = argv[optind]; 213 unsigned char *file_ptr = argv[optind];
201 214
202 optind++; 215 if (optind + 1 != argc) {
216 bb_error_msg_and_die("only one argument may be specified when using -c");
217 }
218 pre_computed_stream = wfopen_file_or_stdin(file_ptr);
219 while (!feof(pre_computed_stream) && !ferror(pre_computed_stream)) {
220 FILE *stream;
221 char *line;
222 char *line_ptr;
223 char *hex_value;
203 224
204 if ((file_ptr[0] == '-') && (file_ptr[1] == '\0')) { 225 line = bb_get_chomped_line_from_file(pre_computed_stream);
205 stream = stdin; 226 if (line == NULL) {
206 } else { 227 break;
207 stream = bb_wfopen(file_ptr, "r"); 228 }
208 if (stream == NULL) { 229 count_total++;
209 return_value = EXIT_FAILURE; 230 line_ptr = strchr(line, ' ');
231 if (line_ptr == NULL) {
232 if (flags & FLAG_WARN) {
233 bb_error_msg("Invalid format");
234 }
235 free(line);
236 continue;
237 }
238 *line_ptr = '\0';
239 line_ptr++;
240 if ((flags & FLAG_WARN) && (*line_ptr != ' ')) {
241 bb_error_msg("Invalid format");
242 free(line);
210 continue; 243 continue;
211 } 244 }
245 line_ptr++;
246 stream = bb_wfopen(line_ptr, "r");
247 if (hash_ptr(stream, hash_value) == EXIT_FAILURE) {
248 return_value = EXIT_FAILURE;
249 }
250 if (fclose(stream) == EOF) {
251 bb_perror_msg("Couldnt close file %s", file_ptr);
252 }
253 hex_value = hash_bin_to_hex(hash_value, hash_length);
254 printf("%s: ", line_ptr);
255 if (strcmp(hex_value, line) != 0) {
256 puts("FAILED");
257 count_failed++;
258 } else {
259 puts("ok");
260 }
261 free(line);
212 } 262 }
213 if (hash_ptr(stream, hash_value) == EXIT_FAILURE) { 263 if (count_failed) {
214 return_value = EXIT_FAILURE; 264 bb_error_msg("WARNING: %d of %d computed checksum did NOT match", count_failed, count_total);
215 } 265 }
216 else if (!flags & FLAG_SILENT) { 266 if (bb_fclose_nonstdin(pre_computed_stream) == EOF) {
217 print_hash(hash_value, hash_length, file_ptr); 267 bb_perror_msg_and_die("Couldnt close file %s", file_ptr);
218 } 268 }
269 } else
270#endif
271 while (optind < argc) {
272 FILE *stream;
273 unsigned char *file_ptr = argv[optind];
219 274
220 if (fclose(stream) == EOF) { 275 optind++;
221 bb_perror_msg("Couldnt close file %s", file_ptr);
222 return_value = EXIT_FAILURE;
223 }
224 276
225 } 277 stream = wfopen_file_or_stdin(file_ptr);
278 if (stream == NULL) {
279 return_value = EXIT_FAILURE;
280 continue;
281 }
282 if (hash_ptr(stream, hash_value) == EXIT_FAILURE) {
283 return_value = EXIT_FAILURE;
284 }
285 else if (!flags & FLAG_SILENT) {
286 char *hex_value = hash_bin_to_hex(hash_value, hash_length);
287 printf("%s %s\n", hex_value, file_ptr);
288 free(hex_value);
289 }
290
291 if (bb_fclose_nonstdin(stream) == EOF) {
292 bb_perror_msg("Couldnt close file %s", file_ptr);
293 return_value = EXIT_FAILURE;
294 }
295 }
226 296
227 return(return_value); 297 return(return_value);
228} 298}