Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/coreutils/md5_sha1_sum.c

Parent Directory Parent Directory | Revision Log 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)
-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     }