1 /* md5sum.c - Compute MD5 checksum of files or strings according to the
2 * definition of MD5 in RFC 1321 from April 1992.
3 * Copyright (C) 1995-1999 Free Software Foundation, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu> */
21 /* Hacked to work with BusyBox by Alfred M. Szmidt <ams@trillian.itslinux.org> */
29 /* For some silly reason, this file uses backwards TRUE and FALSE conventions */
32 #define FALSE ((int) 1)
33 #define TRUE ((int) 0)
35 //----------------------------------------------------------------------------
37 //----------------------------------------------------------------------------
39 /* md5.c - Functions to compute MD5 message digest of files or memory blocks
40 * according to the definition of MD5 in RFC 1321 from April 1992.
41 * Copyright (C) 1995, 1996 Free Software Foundation, Inc.
43 * NOTE: The canonical source of this file is maintained with the GNU C
44 * Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
46 * This program is free software; you can redistribute it and/or modify it
47 * under the terms of the GNU General Public License as published by the
48 * Free Software Foundation; either version 2, or (at your option) any
51 * This program is distributed in the hope that it will be useful,
52 * but WITHOUT ANY WARRANTY; without even the implied warranty of
53 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54 * GNU General Public License for more details.
56 * You should have received a copy of the GNU General Public License
57 * along with this program; if not, write to the Free Software Foundation,
58 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
61 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
63 #include <sys/types.h>
69 //----------------------------------------------------------------------------
71 //----------------------------------------------------------------------------
73 /* md5.h - Declaration of functions and data types used for MD5 sum
74 computing library functions.
75 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
76 NOTE: The canonical source of this file is maintained with the GNU C
77 Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
79 This program is free software; you can redistribute it and/or modify it
80 under the terms of the GNU General Public License as published by the
81 Free Software Foundation; either version 2, or (at your option) any
84 This program is distributed in the hope that it will be useful,
85 but WITHOUT ANY WARRANTY; without even the implied warranty of
86 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
87 GNU General Public License for more details.
89 You should have received a copy of the GNU General Public License
90 along with this program; if not, write to the Free Software Foundation,
91 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
94 static const int _MD5_H = 1;
98 #if defined HAVE_LIMITS_H || defined _LIBC
102 /* The following contortions are an attempt to use the C preprocessor
103 to determine an unsigned integral type that is 32 bits wide. An
104 alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
105 doing that would require that the configure script compile and *run*
106 the resulting executable. Locally running cross-compiled executables
107 is usually not possible. */
109 # include <sys/types.h>
110 typedef u_int32_t md5_uint32;
112 /* Structure to save state of computation between the single steps. */
126 * The following three functions are build up the low level used in
127 * the functions `md5_stream' and `md5_buffer'.
130 /* Initialize structure containing state of computation.
131 (RFC 1321, 3.3: Step 3) */
132 extern void md5_init_ctx __P ((struct md5_ctx *ctx));
134 /* Starting with the result of former calls of this function (or the
135 initialization function update the context for the next LEN bytes
137 It is necessary that LEN is a multiple of 64!!! */
138 extern void md5_process_block __P ((const void *buffer, size_t len,
139 struct md5_ctx *ctx));
141 /* Starting with the result of former calls of this function (or the
142 initialization function update the context for the next LEN bytes
144 It is NOT required that LEN is a multiple of 64. */
145 extern void md5_process_bytes __P ((const void *buffer, size_t len,
146 struct md5_ctx *ctx));
148 /* Process the remaining bytes in the buffer and put result from CTX
149 in first 16 bytes following RESBUF. The result is always in little
150 endian byte order, so that a byte-wise output yields to the wanted
151 ASCII representation of the message digest.
153 IMPORTANT: On some systems it is required that RESBUF is correctly
154 aligned for a 32 bits value. */
155 extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
158 /* Put result from CTX in first 16 bytes following RESBUF. The result is
159 always in little endian byte order, so that a byte-wise output yields
160 to the wanted ASCII representation of the message digest.
162 IMPORTANT: On some systems it is required that RESBUF is correctly
163 aligned for a 32 bits value. */
164 extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
167 /* Compute MD5 message digest for bytes read from STREAM. The
168 resulting message digest number will be written into the 16 bytes
169 beginning at RESBLOCK. */
170 extern int md5_stream __P ((FILE *stream, void *resblock));
172 /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
173 result is always in little endian byte order, so that a byte-wise
174 output yields to the wanted ASCII representation of the message
176 extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
180 //----------------------------------------------------------------------------
181 //--------end of md5.h
182 //----------------------------------------------------------------------------
184 /* Handle endian-ness */
185 #if __BYTE_ORDER == __LITTLE_ENDIAN
188 #define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24))
193 /* This array contains the bytes used to pad the buffer to the next
194 64-byte boundary. (RFC 1321, 3.1: Step 1) */
195 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
197 /* Initialize structure containing state of computation.
198 (RFC 1321, 3.3: Step 3) */
199 void md5_init_ctx(struct md5_ctx *ctx)
206 ctx->total[0] = ctx->total[1] = 0;
210 /* Put result from CTX in first 16 bytes following RESBUF. The result
211 must be in little endian byte order.
213 IMPORTANT: On some systems it is required that RESBUF is correctly
214 aligned for a 32 bits value. */
215 void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
217 ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
218 ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
219 ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
220 ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
225 /* Process the remaining bytes in the internal buffer and the usual
226 prolog according to the standard and write the result to RESBUF.
228 IMPORTANT: On some systems it is required that RESBUF is correctly
229 aligned for a 32 bits value. */
230 void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
232 /* Take yet unprocessed bytes into account. */
233 md5_uint32 bytes = ctx->buflen;
236 /* Now count remaining bytes. */
237 ctx->total[0] += bytes;
238 if (ctx->total[0] < bytes)
241 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
242 memcpy(&ctx->buffer[bytes], fillbuf, pad);
244 /* Put the 64-bit file length in *bits* at the end of the buffer. */
245 *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3);
246 *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] =
247 SWAP((ctx->total[1] << 3) | (ctx->total[0] >> 29));
249 /* Process last bytes. */
250 md5_process_block(ctx->buffer, bytes + pad + 8, ctx);
252 return md5_read_ctx(ctx, resbuf);
255 /* Compute MD5 message digest for bytes read from STREAM. The
256 resulting message digest number will be written into the 16 bytes
257 beginning at RESBLOCK. */
258 int md5_stream(FILE *stream, void *resblock)
260 /* Important: BLOCKSIZE must be a multiple of 64. */
261 static const int BLOCKSIZE = 4096;
263 char buffer[BLOCKSIZE + 72];
266 /* Initialize the computation context. */
269 /* Iterate over full file contents. */
271 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
272 computation function processes the whole buffer so that with the
273 next round of the loop another block can be read. */
277 /* Read block. Take care for partial reads. */
279 n = fread(buffer + sum, 1, BLOCKSIZE - sum, stream);
283 while (sum < BLOCKSIZE && n != 0);
284 if (n == 0 && ferror(stream))
287 /* If end of file is reached, end the loop. */
291 /* Process buffer with BLOCKSIZE bytes. Note that
294 md5_process_block(buffer, BLOCKSIZE, &ctx);
297 /* Add the last bytes if necessary. */
299 md5_process_bytes(buffer, sum, &ctx);
301 /* Construct result in desired memory. */
302 md5_finish_ctx(&ctx, resblock);
306 /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
307 result is always in little endian byte order, so that a byte-wise
308 output yields to the wanted ASCII representation of the message
310 void *md5_buffer(const char *buffer, size_t len, void *resblock)
314 /* Initialize the computation context. */
317 /* Process whole buffer but last len % 64 bytes. */
318 md5_process_bytes(buffer, len, &ctx);
320 /* Put result in desired memory area. */
321 return md5_finish_ctx(&ctx, resblock);
324 void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx)
326 /* When we already have some bits in our internal buffer concatenate
327 both inputs first. */
328 if (ctx->buflen != 0) {
329 size_t left_over = ctx->buflen;
330 size_t add = 128 - left_over > len ? len : 128 - left_over;
332 memcpy(&ctx->buffer[left_over], buffer, add);
335 if (left_over + add > 64) {
336 md5_process_block(ctx->buffer, (left_over + add) & ~63, ctx);
337 /* The regions in the following copy operation cannot overlap. */
338 memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
339 (left_over + add) & 63);
340 ctx->buflen = (left_over + add) & 63;
343 buffer = (const char *) buffer + add;
347 /* Process available complete blocks. */
349 md5_process_block(buffer, len & ~63, ctx);
350 buffer = (const char *) buffer + (len & ~63);
354 /* Move remaining bytes in internal buffer. */
356 memcpy(ctx->buffer, buffer, len);
361 /* These are the four functions used in the four steps of the MD5 algorithm
362 and defined in the RFC 1321. The first function is a little bit optimized
363 (as found in Colin Plumbs public domain implementation). */
364 /* #define FF(b, c, d) ((b & c) | (~b & d)) */
365 #define FF(b, c, d) (d ^ (b & (c ^ d)))
366 #define FG(b, c, d) FF (d, b, c)
367 #define FH(b, c, d) (b ^ c ^ d)
368 #define FI(b, c, d) (c ^ (b | ~d))
370 /* Process LEN bytes of BUFFER, accumulating context into CTX.
371 It is assumed that LEN % 64 == 0. */
372 void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
374 md5_uint32 correct_words[16];
375 const md5_uint32 *words = buffer;
376 size_t nwords = len / sizeof(md5_uint32);
377 const md5_uint32 *endp = words + nwords;
378 md5_uint32 A = ctx->A;
379 md5_uint32 B = ctx->B;
380 md5_uint32 C = ctx->C;
381 md5_uint32 D = ctx->D;
383 /* First increment the byte count. RFC 1321 specifies the possible
384 length of the file up to 2^64 bits. Here we only compute the
385 number of bytes. Do a double word increment. */
386 ctx->total[0] += len;
387 if (ctx->total[0] < len)
390 /* Process all bytes in the buffer with 64 bytes in each round of
392 while (words < endp) {
393 md5_uint32 *cwp = correct_words;
394 md5_uint32 A_save = A;
395 md5_uint32 B_save = B;
396 md5_uint32 C_save = C;
397 md5_uint32 D_save = D;
399 /* First round: using the given function, the context and a constant
400 the next context is computed. Because the algorithms processing
401 unit is a 32-bit word and it is determined to work on words in
402 little endian byte order we perhaps have to change the byte order
403 before the computation. To reduce the work for the next steps
404 we store the swapped words in the array CORRECT_WORDS. */
406 #define OP(a, b, c, d, s, T) \
409 a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
416 /* It is unfortunate that C does not provide an operator for
417 cyclic rotation. Hope the C compiler is smart enough. */
418 #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
420 /* Before we start, one word to the strange constants.
421 They are defined in RFC 1321 as
423 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
427 OP(A, B, C, D, 7, 0xd76aa478);
428 OP(D, A, B, C, 12, 0xe8c7b756);
429 OP(C, D, A, B, 17, 0x242070db);
430 OP(B, C, D, A, 22, 0xc1bdceee);
431 OP(A, B, C, D, 7, 0xf57c0faf);
432 OP(D, A, B, C, 12, 0x4787c62a);
433 OP(C, D, A, B, 17, 0xa8304613);
434 OP(B, C, D, A, 22, 0xfd469501);
435 OP(A, B, C, D, 7, 0x698098d8);
436 OP(D, A, B, C, 12, 0x8b44f7af);
437 OP(C, D, A, B, 17, 0xffff5bb1);
438 OP(B, C, D, A, 22, 0x895cd7be);
439 OP(A, B, C, D, 7, 0x6b901122);
440 OP(D, A, B, C, 12, 0xfd987193);
441 OP(C, D, A, B, 17, 0xa679438e);
442 OP(B, C, D, A, 22, 0x49b40821);
444 /* For the second to fourth round we have the possibly swapped words
445 in CORRECT_WORDS. Redefine the macro to take an additional first
446 argument specifying the function to use. */
448 #define OP(f, a, b, c, d, k, s, T) \
451 a += f (b, c, d) + correct_words[k] + T; \
458 OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
459 OP(FG, D, A, B, C, 6, 9, 0xc040b340);
460 OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
461 OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
462 OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
463 OP(FG, D, A, B, C, 10, 9, 0x02441453);
464 OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
465 OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
466 OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
467 OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
468 OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
469 OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
470 OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
471 OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
472 OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
473 OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
476 OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
477 OP(FH, D, A, B, C, 8, 11, 0x8771f681);
478 OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
479 OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
480 OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
481 OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
482 OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
483 OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
484 OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
485 OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
486 OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
487 OP(FH, B, C, D, A, 6, 23, 0x04881d05);
488 OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
489 OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
490 OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
491 OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
494 OP(FI, A, B, C, D, 0, 6, 0xf4292244);
495 OP(FI, D, A, B, C, 7, 10, 0x432aff97);
496 OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
497 OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
498 OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
499 OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
500 OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
501 OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
502 OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
503 OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
504 OP(FI, C, D, A, B, 6, 15, 0xa3014314);
505 OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
506 OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
507 OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
508 OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
509 OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
511 /* Add the starting values of the context. */
518 /* Put checksum in context given as argument. */
525 //----------------------------------------------------------------------------
526 //--------end of md5.c
527 //----------------------------------------------------------------------------
529 #define ISWHITE(c) ((c) == ' ' || (c) == '\t')
530 #define IN_CTYPE_DOMAIN(c) 1
531 #define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
532 #define STREQ(a, b) (strcmp ((a), (b)) == 0)
533 #define TOLOWER(Ch) tolower (Ch)
534 #define OPENOPTS(BINARY) "r"
536 /* The minimum length of a valid digest line in a file produced
537 by `md5sum FILE' and read by `md5sum -c'. This length does
538 not include any newline character at the end of a line. */
539 static const int MIN_DIGEST_LINE_LENGTH = 35; /* 32 - message digest length
540 2 - blank and binary indicator
541 1 - minimum filename length */
543 static int have_read_stdin; /* Nonzero if any of the files read were
544 the standard input. */
546 static int status_only = 0; /* With -c, don't generate any output.
547 The exit code indicates success or failure */
548 static int warn = 0; /* With -w, print a message to standard error warning
549 about each improperly formatted MD5 checksum line */
551 static int split_3(char *s,
558 int escaped_filename = 0;
560 while (ISWHITE(s[i]))
563 /* The line must have at least 35 (36 if the first is a backslash)
564 more characters to contain correct message digest information.
565 Ignore this line if it is too short. */
566 if (!(s_len - i >= MIN_DIGEST_LINE_LENGTH
567 || (s[i] == '\\' && s_len - i >= 1 + MIN_DIGEST_LINE_LENGTH)))
572 escaped_filename = 1;
574 *u = (unsigned char *) &s[i];
576 /* The first field has to be the 32-character hexadecimal
577 representation of the message digest. If it is not followed
578 immediately by a white space it's an error. */
585 if (s[i] != ' ' && s[i] != '*')
587 *binary = (s[i++] == '*');
589 /* All characters between the type indicator and end of line are
590 significant -- that includes leading and trailing white space. */
593 if (escaped_filename) {
594 /* Translate each `\n' string in the file name to a NEWLINE,
595 and each `\\' string to a backslash. */
602 if (i == s_len - 1) {
603 /* A valid line does not end with a backslash. */
615 /* Only `\' or `n' may follow a backslash. */
621 /* The file name may not contain a NUL. */
635 static int hex_digits(unsigned char const *s)
645 /* An interface to md5_stream. Operate on FILENAME (it may be "-") and
646 put the result in *MD5_RESULT. Return non-zero upon failure, zero
647 to indicate success. */
648 static int md5_file(const char *filename,
650 unsigned char *md5_result)
654 if (STREQ(filename, "-")) {
658 fp = fopen(filename, OPENOPTS(binary));
660 perror_msg("%s", filename);
665 if (md5_stream(fp, md5_result)) {
666 perror_msg("%s", filename);
673 if (fp != stdin && fclose(fp) == EOF) {
674 perror_msg("%s", filename);
681 static int md5_check(const char *checkfile_name)
683 FILE *checkfile_stream;
684 int n_properly_formated_lines = 0;
685 int n_mismatched_checksums = 0;
686 int n_open_or_read_failures = 0;
687 unsigned char md5buffer[16];
691 if (STREQ(checkfile_name, "-")) {
693 checkfile_stream = stdin;
695 checkfile_stream = fopen(checkfile_name, "r");
696 if (checkfile_stream == NULL) {
697 perror_msg("%s", checkfile_name);
707 unsigned char *md5num;
712 fgets(line, BUFSIZ-1, checkfile_stream);
713 line_length = strlen(line);
715 if (line_length <= 0 || line==NULL)
718 /* Ignore comment lines, which begin with a '#' character. */
722 /* Remove any trailing newline. */
723 if (line[line_length - 1] == '\n')
724 line[--line_length] = '\0';
726 if (split_3(line, line_length, &md5num, &binary, &filename)
727 || !hex_digits(md5num)) {
729 error_msg("%s: %lu: improperly formatted MD5 checksum line",
730 checkfile_name, (unsigned long) line_number);
733 static const char bin2hex[] = {
740 ++n_properly_formated_lines;
742 if (md5_file(filename, binary, md5buffer)) {
743 ++n_open_or_read_failures;
745 printf("%s: FAILED open or read\n", filename);
750 /* Compare generated binary number with text representation
751 in check file. Ignore case of hex digits. */
752 for (cnt = 0; cnt < 16; ++cnt) {
753 if (TOLOWER(md5num[2 * cnt])
754 != bin2hex[md5buffer[cnt] >> 4]
755 || (TOLOWER(md5num[2 * cnt + 1])
756 != (bin2hex[md5buffer[cnt] & 0xf])))
760 ++n_mismatched_checksums;
763 printf("%s: %s\n", filename,
764 (cnt != 16 ? "FAILED" : "OK"));
771 while (!feof(checkfile_stream) && !ferror(checkfile_stream));
773 if (ferror(checkfile_stream)) {
774 error_msg("%s: read error", checkfile_name);
778 if (checkfile_stream != stdin && fclose(checkfile_stream) == EOF) {
779 perror_msg("md5sum: %s", checkfile_name);
783 if (n_properly_formated_lines == 0) {
784 /* Warn if no tests are found. */
785 error_msg("%s: no properly formatted MD5 checksum lines found",
790 int n_computed_checkums = (n_properly_formated_lines
791 - n_open_or_read_failures);
793 if (n_open_or_read_failures > 0) {
794 error_msg("WARNING: %d of %d listed files could not be read",
795 n_open_or_read_failures, n_properly_formated_lines);
799 if (n_mismatched_checksums > 0) {
800 error_msg("WARNING: %d of %d computed checksums did NOT match",
801 n_mismatched_checksums, n_computed_checkums);
807 return ((n_properly_formated_lines > 0 && n_mismatched_checksums == 0
808 && n_open_or_read_failures == 0) ? 0 : 1);
811 int md5sum_main(int argc,
814 unsigned char md5buffer[16];
817 char **string = NULL;
818 size_t n_strings = 0;
820 int file_type_specified = 0;
823 while ((opt = getopt(argc, argv, "g:bcstw")) != -1) {
825 case 'g': { /* read a string */
827 string = (char **) xmalloc ((argc - 1) * sizeof (char *));
829 string[n_strings++] = optarg;
833 case 'b': /* read files in binary mode */
834 file_type_specified = 1;
838 case 'c': /* check MD5 sums against given list */
842 case 's': /* don't output anything, status code shows success */
847 case 't': /* read files in text mode (default) */
848 file_type_specified = 1;
852 case 'w': /* warn about improperly formated MD5 checksum lines */
862 if (file_type_specified && do_check) {
863 error_msg_and_die("the -b and -t options are meaningless when verifying checksums");
866 if (n_strings > 0 && do_check) {
867 error_msg_and_die("the -g and -c options are mutually exclusive");
870 if (status_only && !do_check) {
871 error_msg_and_die("the -s option is meaningful only when verifying checksums");
874 if (warn && !do_check) {
875 error_msg_and_die("the -w option is meaningful only when verifying checksums");
882 error_msg_and_die("no files may be specified when using -g");
884 for (i = 0; i < n_strings; ++i) {
886 md5_buffer (string[i], strlen (string[i]), md5buffer);
888 for (cnt = 0; cnt < 16; ++cnt)
889 printf ("%02x", md5buffer[cnt]);
891 printf (" \"%s\"\n", string[i]);
893 } else if (do_check) {
894 if (optind + 1 < argc) {
895 error_msg("only one argument may be specified when using -c");
898 err = md5_check ((optind == argc) ? "-" : argv[optind]);
903 for (; optind < argc; ++optind) {
905 char *file = argv[optind];
907 fail = md5_file (file, binary, md5buffer);
909 if (!fail && STREQ(file, "-")) {
911 for (i = 0; i < 16; ++i)
912 printf ("%02x", md5buffer[i]);
916 /* Output a leading backslash if the file name contains
917 a newline or backslash. */
918 if (strchr (file, '\n') || strchr (file, '\\'))
921 for (i = 0; i < 16; ++i)
922 printf ("%02x", md5buffer[i]);
930 /* Translate each NEWLINE byte to the string, "\\n",
931 and each backslash to "\\\\". */
932 for (i = 0; i < strlen (file); ++i) {
935 fputs ("\\n", stdout);
939 fputs ("\\\\", stdout);
952 if (fclose (stdout) == EOF) {
953 error_msg_and_die("write error");
956 if (have_read_stdin && fclose (stdin) == EOF) {
957 error_msg_and_die("standard input");