source: branches/3.2/mindi-busybox/coreutils/md5_sha1_sum.c @ 3232

Last change on this file since 3232 was 3232, checked in by Bruno Cornec, 7 years ago
  • Update mindi-busybox to 1.21.1
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            final(&context, in_buf);
156            hash_value = hash_bin_to_hex(in_buf, hash_len);
157        }
158        RELEASE_CONFIG_BUFFER(in_buf);
159    }
160
161    if (src_fd != STDIN_FILENO) {
162        close(src_fd);
163    }
164
165    return hash_value;
166}
167
168int md5_sha1_sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
169int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
170{
171    int return_value = EXIT_SUCCESS;
172    unsigned flags;
173
174    if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) {
175        /* -b "binary", -t "text" are ignored (shaNNNsum compat) */
176        flags = getopt32(argv, "scwbt");
177        argv += optind;
178        //argc -= optind;
179    } else {
180        argv += 1;
181        //argc -= 1;
182    }
183    if (!*argv)
184        *--argv = (char*)"-";
185
186    if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) {
187        if (flags & FLAG_SILENT) {
188            bb_error_msg_and_die("-%c is meaningful only with -c", 's');
189        }
190        if (flags & FLAG_WARN) {
191            bb_error_msg_and_die("-%c is meaningful only with -c", 'w');
192        }
193    }
194
195    do {
196        if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
197            FILE *pre_computed_stream;
198            char *line;
199            int count_total = 0;
200            int count_failed = 0;
201
202            pre_computed_stream = xfopen_stdin(*argv);
203
204            while ((line = xmalloc_fgetline(pre_computed_stream)) != NULL) {
205                uint8_t *hash_value;
206                char *filename_ptr;
207
208                count_total++;
209                filename_ptr = strstr(line, "  ");
210                /* handle format for binary checksums */
211                if (filename_ptr == NULL) {
212                    filename_ptr = strstr(line, " *");
213                }
214                if (filename_ptr == NULL) {
215                    if (flags & FLAG_WARN) {
216                        bb_error_msg("invalid format");
217                    }
218                    count_failed++;
219                    return_value = EXIT_FAILURE;
220                    free(line);
221                    continue;
222                }
223                *filename_ptr = '\0';
224                filename_ptr += 2;
225
226                hash_value = hash_file(filename_ptr);
227
228                if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
229                    if (!(flags & FLAG_SILENT))
230                        printf("%s: OK\n", filename_ptr);
231                } else {
232                    if (!(flags & FLAG_SILENT))
233                        printf("%s: FAILED\n", filename_ptr);
234                    count_failed++;
235                    return_value = EXIT_FAILURE;
236                }
237                /* possible free(NULL) */
238                free(hash_value);
239                free(line);
240            }
241            if (count_failed && !(flags & FLAG_SILENT)) {
242                bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
243                        count_failed, count_total);
244            }
245            fclose_if_not_stdin(pre_computed_stream);
246        } else {
247            uint8_t *hash_value = hash_file(*argv);
248            if (hash_value == NULL) {
249                return_value = EXIT_FAILURE;
250            } else {
251                printf("%s  %s\n", hash_value, *argv);
252                free(hash_value);
253            }
254        }
255    } while (*++argv);
256
257    return return_value;
258}
Note: See TracBrowser for help on using the repository browser.