diff options
author | nobody | 2004-10-13 09:42:10 +0000 |
---|---|---|
committer | nobody | 2004-10-13 09:42:10 +0000 |
commit | 8c59a0bf0e9e2d87b0ff273ea3f0bf05bbbf6373 (patch) | |
tree | 1826706cd4fd009fcd14f4f8021005ec8ec0fa59 /busybox/coreutils/md5_sha1_sum.c | |
download | busybox-8c59a0bf0e9e2d87b0ff273ea3f0bf05bbbf6373.zip busybox-8c59a0bf0e9e2d87b0ff273ea3f0bf05bbbf6373.tar.gz |
This commit was manufactured by cvs2svn to create tag 'busybox_1_00'.
Diffstat (limited to 'busybox/coreutils/md5_sha1_sum.c')
-rw-r--r-- | busybox/coreutils/md5_sha1_sum.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/busybox/coreutils/md5_sha1_sum.c b/busybox/coreutils/md5_sha1_sum.c new file mode 100644 index 0000000..bd1c9fc --- /dev/null +++ b/busybox/coreutils/md5_sha1_sum.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2003 Glenn L. McGrath + * Copyright (C) 2003-2004 Erik Andersen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "busybox.h" + + +#define FLAG_SILENT 1 +#define FLAG_CHECK 2 +#define FLAG_WARN 4 + +/* This might be useful elsewhere */ +static unsigned char *hash_bin_to_hex(unsigned char *hash_value, + unsigned char hash_length) +{ + int x, len, max; + unsigned char *hex_value; + + max = (hash_length * 2) + 2; + hex_value = xmalloc(max); + for (x = len = 0; x < hash_length; x++) { + len += snprintf(hex_value + len, max - len, "%02x", hash_value[x]); + } + return (hex_value); +} + +static uint8_t *hash_file(const char *filename, uint8_t hash_algo) +{ + uint8_t *hash_value_bin; + uint8_t *hash_value = NULL; + uint8_t hash_length; + int src_fd; + + if (strcmp(filename, "-") == 0) { + src_fd = STDIN_FILENO; + } else { + src_fd = open(filename, O_RDONLY); + } + + if (hash_algo == HASH_MD5) { + hash_length = 16; + } else { + hash_length = 20; + } + + hash_value_bin = xmalloc(hash_length); + + if ((src_fd != -1) && (hash_fd(src_fd, -1, hash_algo, hash_value_bin) != -2)) { + hash_value = hash_bin_to_hex(hash_value_bin, hash_length); + } else { + bb_perror_msg("%s", filename); + } + + close(src_fd); + + return(hash_value); +} + +/* This could become a common function for md5 as well, by using md5_stream */ +extern int hash_files(int argc, char **argv, const uint8_t hash_algo) +{ + int return_value = EXIT_SUCCESS; + uint8_t *hash_value; + +#ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK + unsigned int flags; + + flags = bb_getopt_ulflags(argc, argv, "scw"); +#endif + +#ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK + if (!(flags & FLAG_CHECK)) { + if (flags & FLAG_SILENT) { + bb_error_msg_and_die + ("the -s option is meaningful only when verifying checksums"); + } else if (flags & FLAG_WARN) { + bb_error_msg_and_die + ("the -w option is meaningful only when verifying checksums"); + } + } +#endif + + if (argc == optind) { + argv[argc++] = "-"; + } +#ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK + if (flags & FLAG_CHECK) { + FILE *pre_computed_stream; + int count_total = 0; + int count_failed = 0; + unsigned char *file_ptr = argv[optind]; + char *line; + + if (optind + 1 != argc) { + bb_error_msg_and_die + ("only one argument may be specified when using -c"); + } + + if (strcmp(file_ptr, "-") == 0) { + pre_computed_stream = stdin; + } else { + pre_computed_stream = bb_xfopen(file_ptr, "r"); + } + + while ((line = bb_get_chomped_line_from_file(pre_computed_stream)) != NULL) { + char *filename_ptr; + + count_total++; + filename_ptr = strstr(line, " "); + if (filename_ptr == NULL) { + if (flags & FLAG_WARN) { + bb_error_msg("Invalid format"); + } + free(line); + continue; + } + *filename_ptr = '\0'; + filename_ptr += 2; + + hash_value = hash_file(filename_ptr, hash_algo); + + if (hash_value && (strcmp(hash_value, line) == 0)) { + if (!(flags & FLAG_SILENT)) + printf("%s: OK\n", filename_ptr); + } else { + if (!(flags & FLAG_SILENT)) + printf("%s: FAILED\n", filename_ptr); + count_failed++; + return_value = EXIT_FAILURE; + } + /* possible free(NULL) */ + free(hash_value); + free(line); + } + if (count_failed && !(flags & FLAG_SILENT)) { + bb_error_msg("WARNING: %d of %d computed checksums did NOT match", + count_failed, count_total); + } + if (bb_fclose_nonstdin(pre_computed_stream) == EOF) { + bb_perror_msg_and_die("Couldnt close file %s", file_ptr); + } + } else +#endif + { + uint8_t hash_length; + + if (hash_algo == HASH_MD5) { + hash_length = 16; + } else { + hash_length = 20; + } + hash_value = xmalloc(hash_length); + + while (optind < argc) { + unsigned char *file_ptr = argv[optind++]; + + hash_value = hash_file(file_ptr, hash_algo); + if (hash_value == NULL) { + return_value = EXIT_FAILURE; + } else { + printf("%s %s\n", hash_value, file_ptr); + free(hash_value); + } + } + } + return (return_value); +} + +#ifdef CONFIG_MD5SUM +extern int md5sum_main(int argc, char **argv) +{ + return(hash_files(argc, argv, HASH_MD5)); +} +#endif + +#ifdef CONFIG_SHA1SUM +extern int sha1sum_main(int argc, char **argv) +{ + return(hash_files(argc, argv, HASH_SHA1)); +} +#endif |