aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-07-10 16:31:29 +0000
committerEric Andersen <andersen@codepoet.org>2001-07-10 16:31:29 +0000
commit55522080c68f73c9de0a190a3b1b0b3e7e56e9fb (patch)
tree90bdb56543bfebc167f01b6a41e4eb74ffdbb60b
parent5c58d283bbd71db2a43379fc2b804f6c138cf35e (diff)
downloadbusybox-w32-55522080c68f73c9de0a190a3b1b0b3e7e56e9fb.tar.gz
busybox-w32-55522080c68f73c9de0a190a3b1b0b3e7e56e9fb.tar.bz2
busybox-w32-55522080c68f73c9de0a190a3b1b0b3e7e56e9fb.zip
Patch for md5sum from Aaron Lehmann <aaronl@vitelus.com> to slim
it down a little bit.
-rw-r--r--coreutils/md5sum.c144
-rw-r--r--md5sum.c144
2 files changed, 78 insertions, 210 deletions
diff --git a/coreutils/md5sum.c b/coreutils/md5sum.c
index 643f8271d..72bc08624 100644
--- a/coreutils/md5sum.c
+++ b/coreutils/md5sum.c
@@ -63,24 +63,6 @@
63 63
64/* md5.c - Functions to compute MD5 message digest of files or memory blocks 64/* md5.c - Functions to compute MD5 message digest of files or memory blocks
65 * according to the definition of MD5 in RFC 1321 from April 1992. 65 * according to the definition of MD5 in RFC 1321 from April 1992.
66 * Copyright (C) 1995, 1996 Free Software Foundation, Inc.
67 *
68 * NOTE: The canonical source of this file is maintained with the GNU C
69 * Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
70 *
71 * This program is free software; you can redistribute it and/or modify it
72 * under the terms of the GNU General Public License as published by the
73 * Free Software Foundation; either version 2, or (at your option) any
74 * later version.
75 *
76 * This program is distributed in the hope that it will be useful,
77 * but WITHOUT ANY WARRANTY; without even the implied warranty of
78 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
79 * GNU General Public License for more details.
80 *
81 * You should have received a copy of the GNU General Public License
82 * along with this program; if not, write to the Free Software Foundation,
83 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
84 */ 66 */
85 67
86/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ 68/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
@@ -90,34 +72,7 @@
90//---------------------------------------------------------------------------- 72//----------------------------------------------------------------------------
91 73
92/* md5.h - Declaration of functions and data types used for MD5 sum 74/* md5.h - Declaration of functions and data types used for MD5 sum
93 computing library functions. 75 computing library functions. */
94 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
95 NOTE: The canonical source of this file is maintained with the GNU C
96 Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
97
98 This program is free software; you can redistribute it and/or modify it
99 under the terms of the GNU General Public License as published by the
100 Free Software Foundation; either version 2, or (at your option) any
101 later version.
102
103 This program is distributed in the hope that it will be useful,
104 but WITHOUT ANY WARRANTY; without even the implied warranty of
105 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
106 GNU General Public License for more details.
107
108 You should have received a copy of the GNU General Public License
109 along with this program; if not, write to the Free Software Foundation,
110 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
111
112#ifndef _MD5_H
113static const int _MD5_H = 1;
114
115/* The following contortions are an attempt to use the C preprocessor
116 to determine an unsigned integral type that is 32 bits wide. An
117 alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
118 doing that would require that the configure script compile and *run*
119 the resulting executable. Locally running cross-compiled executables
120 is usually not possible. */
121 76
122typedef u_int32_t md5_uint32; 77typedef u_int32_t md5_uint32;
123 78
@@ -141,20 +96,20 @@ struct md5_ctx
141 96
142/* Initialize structure containing state of computation. 97/* Initialize structure containing state of computation.
143 (RFC 1321, 3.3: Step 3) */ 98 (RFC 1321, 3.3: Step 3) */
144extern void md5_init_ctx __P ((struct md5_ctx *ctx)); 99static void md5_init_ctx __P ((struct md5_ctx *ctx));
145 100
146/* Starting with the result of former calls of this function (or the 101/* Starting with the result of former calls of this function (or the
147 initialization function update the context for the next LEN bytes 102 initialization function update the context for the next LEN bytes
148 starting at BUFFER. 103 starting at BUFFER.
149 It is necessary that LEN is a multiple of 64!!! */ 104 It is necessary that LEN is a multiple of 64!!! */
150extern void md5_process_block __P ((const void *buffer, size_t len, 105static void md5_process_block __P ((const void *buffer, size_t len,
151 struct md5_ctx *ctx)); 106 struct md5_ctx *ctx));
152 107
153/* Starting with the result of former calls of this function (or the 108/* Starting with the result of former calls of this function (or the
154 initialization function update the context for the next LEN bytes 109 initialization function update the context for the next LEN bytes
155 starting at BUFFER. 110 starting at BUFFER.
156 It is NOT required that LEN is a multiple of 64. */ 111 It is NOT required that LEN is a multiple of 64. */
157extern void md5_process_bytes __P ((const void *buffer, size_t len, 112static void md5_process_bytes __P ((const void *buffer, size_t len,
158 struct md5_ctx *ctx)); 113 struct md5_ctx *ctx));
159 114
160/* Process the remaining bytes in the buffer and put result from CTX 115/* Process the remaining bytes in the buffer and put result from CTX
@@ -164,30 +119,21 @@ extern void md5_process_bytes __P ((const void *buffer, size_t len,
164 119
165 IMPORTANT: On some systems it is required that RESBUF is correctly 120 IMPORTANT: On some systems it is required that RESBUF is correctly
166 aligned for a 32 bits value. */ 121 aligned for a 32 bits value. */
167extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); 122static void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
168 123
169 124
170/* Put result from CTX in first 16 bytes following RESBUF. The result is
171 always in little endian byte order, so that a byte-wise output yields
172 to the wanted ASCII representation of the message digest.
173
174 IMPORTANT: On some systems it is required that RESBUF is correctly
175 aligned for a 32 bits value. */
176extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
177 125
178 126
179/* Compute MD5 message digest for bytes read from STREAM. The 127/* Compute MD5 message digest for bytes read from STREAM. The
180 resulting message digest number will be written into the 16 bytes 128 resulting message digest number will be written into the 16 bytes
181 beginning at RESBLOCK. */ 129 beginning at RESBLOCK. */
182extern int md5_stream __P ((FILE *stream, void *resblock)); 130static int md5_stream __P ((FILE *stream, void *resblock));
183 131
184/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The 132/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
185 result is always in little endian byte order, so that a byte-wise 133 result is always in little endian byte order, so that a byte-wise
186 output yields to the wanted ASCII representation of the message 134 output yields to the wanted ASCII representation of the message
187 digest. */ 135 digest. */
188extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); 136static void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
189
190#endif
191 137
192//---------------------------------------------------------------------------- 138//----------------------------------------------------------------------------
193//--------end of md5.h 139//--------end of md5.h
@@ -221,27 +167,12 @@ void md5_init_ctx(struct md5_ctx *ctx)
221 ctx->buflen = 0; 167 ctx->buflen = 0;
222} 168}
223 169
224/* Put result from CTX in first 16 bytes following RESBUF. The result
225 must be in little endian byte order.
226
227 IMPORTANT: On some systems it is required that RESBUF is correctly
228 aligned for a 32 bits value. */
229void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
230{
231 ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
232 ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
233 ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
234 ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
235
236 return resbuf;
237}
238
239/* Process the remaining bytes in the internal buffer and the usual 170/* Process the remaining bytes in the internal buffer and the usual
240 prolog according to the standard and write the result to RESBUF. 171 prolog according to the standard and write the result to RESBUF.
241 172
242 IMPORTANT: On some systems it is required that RESBUF is correctly 173 IMPORTANT: On some systems it is required that RESBUF is correctly
243 aligned for a 32 bits value. */ 174 aligned for a 32 bits value. */
244void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf) 175static void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
245{ 176{
246 /* Take yet unprocessed bytes into account. */ 177 /* Take yet unprocessed bytes into account. */
247 md5_uint32 bytes = ctx->buflen; 178 md5_uint32 bytes = ctx->buflen;
@@ -268,13 +199,24 @@ void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
268 /* Process last bytes. */ 199 /* Process last bytes. */
269 md5_process_block(ctx->buffer, bytes + pad + 8, ctx); 200 md5_process_block(ctx->buffer, bytes + pad + 8, ctx);
270 201
271 return md5_read_ctx(ctx, resbuf); 202/* Put result from CTX in first 16 bytes following RESBUF. The result is
203 always in little endian byte order, so that a byte-wise output yields
204 to the wanted ASCII representation of the message digest.
205
206 IMPORTANT: On some systems it is required that RESBUF is correctly
207 aligned for a 32 bits value. */
208 ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
209 ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
210 ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
211 ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
212
213 return resbuf;
272} 214}
273 215
274/* Compute MD5 message digest for bytes read from STREAM. The 216/* Compute MD5 message digest for bytes read from STREAM. The
275 resulting message digest number will be written into the 16 bytes 217 resulting message digest number will be written into the 16 bytes
276 beginning at RESBLOCK. */ 218 beginning at RESBLOCK. */
277int md5_stream(FILE *stream, void *resblock) 219static int md5_stream(FILE *stream, void *resblock)
278{ 220{
279 /* Important: BLOCKSIZE must be a multiple of 64. */ 221 /* Important: BLOCKSIZE must be a multiple of 64. */
280static const int BLOCKSIZE = 4096; 222static const int BLOCKSIZE = 4096;
@@ -326,7 +268,7 @@ static const int BLOCKSIZE = 4096;
326 result is always in little endian byte order, so that a byte-wise 268 result is always in little endian byte order, so that a byte-wise
327 output yields to the wanted ASCII representation of the message 269 output yields to the wanted ASCII representation of the message
328 digest. */ 270 digest. */
329void *md5_buffer(const char *buffer, size_t len, void *resblock) 271static void *md5_buffer(const char *buffer, size_t len, void *resblock)
330{ 272{
331 struct md5_ctx ctx; 273 struct md5_ctx ctx;
332 274
@@ -340,7 +282,7 @@ void *md5_buffer(const char *buffer, size_t len, void *resblock)
340 return md5_finish_ctx(&ctx, resblock); 282 return md5_finish_ctx(&ctx, resblock);
341} 283}
342 284
343void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx) 285static void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx)
344{ 286{
345 /* When we already have some bits in our internal buffer concatenate 287 /* When we already have some bits in our internal buffer concatenate
346 both inputs first. */ 288 both inputs first. */
@@ -388,7 +330,7 @@ void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx)
388 330
389/* Process LEN bytes of BUFFER, accumulating context into CTX. 331/* Process LEN bytes of BUFFER, accumulating context into CTX.
390 It is assumed that LEN % 64 == 0. */ 332 It is assumed that LEN % 64 == 0. */
391void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx) 333static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
392{ 334{
393 md5_uint32 correct_words[16]; 335 md5_uint32 correct_words[16];
394 const md5_uint32 *words = buffer; 336 const md5_uint32 *words = buffer;
@@ -490,7 +432,6 @@ void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
490 break; 432 break;
491 case 3: 433 case 3:
492 temp += FI(B,C,D); 434 temp += FI(B,C,D);
493 break;
494 } 435 }
495 temp += cwp[(int)(*pp++)] + *pc++; 436 temp += cwp[(int)(*pp++)] + *pc++;
496 temp = CYCLIC (temp, ps[i&3]); 437 temp = CYCLIC (temp, ps[i&3]);
@@ -550,6 +491,7 @@ void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
550 491
551 /* It is unfortunate that C does not provide an operator for 492 /* It is unfortunate that C does not provide an operator for
552 cyclic rotation. Hope the C compiler is smart enough. */ 493 cyclic rotation. Hope the C compiler is smart enough. */
494 /* gcc 2.95.4 seems to be --aaronl */
553#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) 495#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
554 496
555 /* Before we start, one word to the strange constants. 497 /* Before we start, one word to the strange constants.
@@ -707,11 +649,7 @@ void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
707//---------------------------------------------------------------------------- 649//----------------------------------------------------------------------------
708 650
709#define ISWHITE(c) ((c) == ' ' || (c) == '\t') 651#define ISWHITE(c) ((c) == ' ' || (c) == '\t')
710#define IN_CTYPE_DOMAIN(c) 1 652#define ISXDIGIT(c) (isxdigit (c))
711#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
712#define STREQ(a, b) (strcmp ((a), (b)) == 0)
713#define TOLOWER(Ch) tolower (Ch)
714#define OPENOPTS(BINARY) "r"
715 653
716/* The minimum length of a valid digest line in a file produced 654/* The minimum length of a valid digest line in a file produced
717 by `md5sum FILE' and read by `md5sum -c'. This length does 655 by `md5sum FILE' and read by `md5sum -c'. This length does
@@ -731,7 +669,6 @@ static int warn = 0; /* With -w, print a message to standard error warning
731static int split_3(char *s, 669static int split_3(char *s,
732 size_t s_len, 670 size_t s_len,
733 unsigned char **u, 671 unsigned char **u,
734 int *binary,
735 char **w) 672 char **w)
736{ 673{
737 size_t i = 0; 674 size_t i = 0;
@@ -762,9 +699,8 @@ static int split_3(char *s,
762 699
763 s[i++] = '\0'; 700 s[i++] = '\0';
764 701
765 if (s[i] != ' ' && s[i] != '*') 702 if (s[i] != ' ' && s[i++] != '*')
766 return FALSE; 703 return FALSE;
767 *binary = (s[i++] == '*');
768 704
769 /* All characters between the type indicator and end of line are 705 /* All characters between the type indicator and end of line are
770 significant -- that includes leading and trailing white space. */ 706 significant -- that includes leading and trailing white space. */
@@ -812,7 +748,7 @@ static int split_3(char *s,
812 return TRUE; 748 return TRUE;
813} 749}
814 750
815static int hex_digits(unsigned char const *s) 751static inline int hex_digits(unsigned char const *s)
816{ 752{
817 while (*s) { 753 while (*s) {
818 if (!ISXDIGIT(*s)) 754 if (!ISXDIGIT(*s))
@@ -826,16 +762,15 @@ static int hex_digits(unsigned char const *s)
826 put the result in *MD5_RESULT. Return non-zero upon failure, zero 762 put the result in *MD5_RESULT. Return non-zero upon failure, zero
827 to indicate success. */ 763 to indicate success. */
828static int md5_file(const char *filename, 764static int md5_file(const char *filename,
829 int binary,
830 unsigned char *md5_result) 765 unsigned char *md5_result)
831{ 766{
832 FILE *fp; 767 FILE *fp;
833 768
834 if (STREQ(filename, "-")) { 769 if (filename[0] == '-' && filename[1] == '\0') {
835 have_read_stdin = 1; 770 have_read_stdin = 1;
836 fp = stdin; 771 fp = stdin;
837 } else { 772 } else {
838 fp = fopen(filename, OPENOPTS(binary)); 773 fp = fopen(filename, "r");
839 if (fp == NULL) { 774 if (fp == NULL) {
840 perror_msg("%s", filename); 775 perror_msg("%s", filename);
841 return FALSE; 776 return FALSE;
@@ -868,7 +803,7 @@ static int md5_check(const char *checkfile_name)
868 size_t line_number; 803 size_t line_number;
869 char line[BUFSIZ]; 804 char line[BUFSIZ];
870 805
871 if (STREQ(checkfile_name, "-")) { 806 if (checkfile_name[0] == '-' && checkfile_name[1] == '\0') {
872 have_read_stdin = 1; 807 have_read_stdin = 1;
873 checkfile_stream = stdin; 808 checkfile_stream = stdin;
874 } else { 809 } else {
@@ -883,7 +818,6 @@ static int md5_check(const char *checkfile_name)
883 818
884 do { 819 do {
885 char *filename; 820 char *filename;
886 int binary;
887 unsigned char *md5num; 821 unsigned char *md5num;
888 int line_length; 822 int line_length;
889 823
@@ -903,7 +837,7 @@ static int md5_check(const char *checkfile_name)
903 if (line[line_length - 1] == '\n') 837 if (line[line_length - 1] == '\n')
904 line[--line_length] = '\0'; 838 line[--line_length] = '\0';
905 839
906 if (split_3(line, line_length, &md5num, &binary, &filename) 840 if (split_3(line, line_length, &md5num, &filename)
907 || !hex_digits(md5num)) { 841 || !hex_digits(md5num)) {
908 if (warn) { 842 if (warn) {
909 error_msg("%s: %lu: improperly formatted MD5 checksum line", 843 error_msg("%s: %lu: improperly formatted MD5 checksum line",
@@ -919,7 +853,7 @@ static int md5_check(const char *checkfile_name)
919 853
920 ++n_properly_formated_lines; 854 ++n_properly_formated_lines;
921 855
922 if (md5_file(filename, binary, md5buffer)) { 856 if (md5_file(filename, md5buffer)) {
923 ++n_open_or_read_failures; 857 ++n_open_or_read_failures;
924 if (!status_only) { 858 if (!status_only) {
925 printf("%s: FAILED open or read\n", filename); 859 printf("%s: FAILED open or read\n", filename);
@@ -930,9 +864,9 @@ static int md5_check(const char *checkfile_name)
930 /* Compare generated binary number with text representation 864 /* Compare generated binary number with text representation
931 in check file. Ignore case of hex digits. */ 865 in check file. Ignore case of hex digits. */
932 for (cnt = 0; cnt < 16; ++cnt) { 866 for (cnt = 0; cnt < 16; ++cnt) {
933 if (TOLOWER(md5num[2 * cnt]) 867 if (tolower(md5num[2 * cnt])
934 != bin2hex[md5buffer[cnt] >> 4] 868 != bin2hex[md5buffer[cnt] >> 4]
935 || (TOLOWER(md5num[2 * cnt + 1]) 869 || (tolower(md5num[2 * cnt + 1])
936 != (bin2hex[md5buffer[cnt] & 0xf]))) 870 != (bin2hex[md5buffer[cnt] & 0xf])))
937 break; 871 break;
938 } 872 }
@@ -997,8 +931,8 @@ int md5sum_main(int argc,
997 char **string = NULL; 931 char **string = NULL;
998 size_t n_strings = 0; 932 size_t n_strings = 0;
999 size_t err = 0; 933 size_t err = 0;
1000 int file_type_specified = 0; 934 char file_type_specified = 0;
1001 int binary = 0; 935 char binary = 0;
1002 936
1003 while ((opt = getopt(argc, argv, "g:bcstw")) != -1) { 937 while ((opt = getopt(argc, argv, "g:bcstw")) != -1) {
1004 switch (opt) { 938 switch (opt) {
@@ -1084,9 +1018,9 @@ int md5sum_main(int argc,
1084 int fail; 1018 int fail;
1085 char *file = argv[optind]; 1019 char *file = argv[optind];
1086 1020
1087 fail = md5_file (file, binary, md5buffer); 1021 fail = md5_file (file, md5buffer);
1088 err |= fail; 1022 err |= fail;
1089 if (!fail && STREQ(file, "-")) { 1023 if (!fail && file[0]=='-' && file[1] == '\0') {
1090 size_t i; 1024 size_t i;
1091 for (i = 0; i < 16; ++i) 1025 for (i = 0; i < 16; ++i)
1092 printf ("%02x", md5buffer[i]); 1026 printf ("%02x", md5buffer[i]);
diff --git a/md5sum.c b/md5sum.c
index 643f8271d..72bc08624 100644
--- a/md5sum.c
+++ b/md5sum.c
@@ -63,24 +63,6 @@
63 63
64/* md5.c - Functions to compute MD5 message digest of files or memory blocks 64/* md5.c - Functions to compute MD5 message digest of files or memory blocks
65 * according to the definition of MD5 in RFC 1321 from April 1992. 65 * according to the definition of MD5 in RFC 1321 from April 1992.
66 * Copyright (C) 1995, 1996 Free Software Foundation, Inc.
67 *
68 * NOTE: The canonical source of this file is maintained with the GNU C
69 * Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
70 *
71 * This program is free software; you can redistribute it and/or modify it
72 * under the terms of the GNU General Public License as published by the
73 * Free Software Foundation; either version 2, or (at your option) any
74 * later version.
75 *
76 * This program is distributed in the hope that it will be useful,
77 * but WITHOUT ANY WARRANTY; without even the implied warranty of
78 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
79 * GNU General Public License for more details.
80 *
81 * You should have received a copy of the GNU General Public License
82 * along with this program; if not, write to the Free Software Foundation,
83 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
84 */ 66 */
85 67
86/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ 68/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
@@ -90,34 +72,7 @@
90//---------------------------------------------------------------------------- 72//----------------------------------------------------------------------------
91 73
92/* md5.h - Declaration of functions and data types used for MD5 sum 74/* md5.h - Declaration of functions and data types used for MD5 sum
93 computing library functions. 75 computing library functions. */
94 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
95 NOTE: The canonical source of this file is maintained with the GNU C
96 Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
97
98 This program is free software; you can redistribute it and/or modify it
99 under the terms of the GNU General Public License as published by the
100 Free Software Foundation; either version 2, or (at your option) any
101 later version.
102
103 This program is distributed in the hope that it will be useful,
104 but WITHOUT ANY WARRANTY; without even the implied warranty of
105 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
106 GNU General Public License for more details.
107
108 You should have received a copy of the GNU General Public License
109 along with this program; if not, write to the Free Software Foundation,
110 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
111
112#ifndef _MD5_H
113static const int _MD5_H = 1;
114
115/* The following contortions are an attempt to use the C preprocessor
116 to determine an unsigned integral type that is 32 bits wide. An
117 alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
118 doing that would require that the configure script compile and *run*
119 the resulting executable. Locally running cross-compiled executables
120 is usually not possible. */
121 76
122typedef u_int32_t md5_uint32; 77typedef u_int32_t md5_uint32;
123 78
@@ -141,20 +96,20 @@ struct md5_ctx
141 96
142/* Initialize structure containing state of computation. 97/* Initialize structure containing state of computation.
143 (RFC 1321, 3.3: Step 3) */ 98 (RFC 1321, 3.3: Step 3) */
144extern void md5_init_ctx __P ((struct md5_ctx *ctx)); 99static void md5_init_ctx __P ((struct md5_ctx *ctx));
145 100
146/* Starting with the result of former calls of this function (or the 101/* Starting with the result of former calls of this function (or the
147 initialization function update the context for the next LEN bytes 102 initialization function update the context for the next LEN bytes
148 starting at BUFFER. 103 starting at BUFFER.
149 It is necessary that LEN is a multiple of 64!!! */ 104 It is necessary that LEN is a multiple of 64!!! */
150extern void md5_process_block __P ((const void *buffer, size_t len, 105static void md5_process_block __P ((const void *buffer, size_t len,
151 struct md5_ctx *ctx)); 106 struct md5_ctx *ctx));
152 107
153/* Starting with the result of former calls of this function (or the 108/* Starting with the result of former calls of this function (or the
154 initialization function update the context for the next LEN bytes 109 initialization function update the context for the next LEN bytes
155 starting at BUFFER. 110 starting at BUFFER.
156 It is NOT required that LEN is a multiple of 64. */ 111 It is NOT required that LEN is a multiple of 64. */
157extern void md5_process_bytes __P ((const void *buffer, size_t len, 112static void md5_process_bytes __P ((const void *buffer, size_t len,
158 struct md5_ctx *ctx)); 113 struct md5_ctx *ctx));
159 114
160/* Process the remaining bytes in the buffer and put result from CTX 115/* Process the remaining bytes in the buffer and put result from CTX
@@ -164,30 +119,21 @@ extern void md5_process_bytes __P ((const void *buffer, size_t len,
164 119
165 IMPORTANT: On some systems it is required that RESBUF is correctly 120 IMPORTANT: On some systems it is required that RESBUF is correctly
166 aligned for a 32 bits value. */ 121 aligned for a 32 bits value. */
167extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); 122static void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
168 123
169 124
170/* Put result from CTX in first 16 bytes following RESBUF. The result is
171 always in little endian byte order, so that a byte-wise output yields
172 to the wanted ASCII representation of the message digest.
173
174 IMPORTANT: On some systems it is required that RESBUF is correctly
175 aligned for a 32 bits value. */
176extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
177 125
178 126
179/* Compute MD5 message digest for bytes read from STREAM. The 127/* Compute MD5 message digest for bytes read from STREAM. The
180 resulting message digest number will be written into the 16 bytes 128 resulting message digest number will be written into the 16 bytes
181 beginning at RESBLOCK. */ 129 beginning at RESBLOCK. */
182extern int md5_stream __P ((FILE *stream, void *resblock)); 130static int md5_stream __P ((FILE *stream, void *resblock));
183 131
184/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The 132/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
185 result is always in little endian byte order, so that a byte-wise 133 result is always in little endian byte order, so that a byte-wise
186 output yields to the wanted ASCII representation of the message 134 output yields to the wanted ASCII representation of the message
187 digest. */ 135 digest. */
188extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); 136static void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
189
190#endif
191 137
192//---------------------------------------------------------------------------- 138//----------------------------------------------------------------------------
193//--------end of md5.h 139//--------end of md5.h
@@ -221,27 +167,12 @@ void md5_init_ctx(struct md5_ctx *ctx)
221 ctx->buflen = 0; 167 ctx->buflen = 0;
222} 168}
223 169
224/* Put result from CTX in first 16 bytes following RESBUF. The result
225 must be in little endian byte order.
226
227 IMPORTANT: On some systems it is required that RESBUF is correctly
228 aligned for a 32 bits value. */
229void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
230{
231 ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
232 ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
233 ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
234 ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
235
236 return resbuf;
237}
238
239/* Process the remaining bytes in the internal buffer and the usual 170/* Process the remaining bytes in the internal buffer and the usual
240 prolog according to the standard and write the result to RESBUF. 171 prolog according to the standard and write the result to RESBUF.
241 172
242 IMPORTANT: On some systems it is required that RESBUF is correctly 173 IMPORTANT: On some systems it is required that RESBUF is correctly
243 aligned for a 32 bits value. */ 174 aligned for a 32 bits value. */
244void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf) 175static void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
245{ 176{
246 /* Take yet unprocessed bytes into account. */ 177 /* Take yet unprocessed bytes into account. */
247 md5_uint32 bytes = ctx->buflen; 178 md5_uint32 bytes = ctx->buflen;
@@ -268,13 +199,24 @@ void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
268 /* Process last bytes. */ 199 /* Process last bytes. */
269 md5_process_block(ctx->buffer, bytes + pad + 8, ctx); 200 md5_process_block(ctx->buffer, bytes + pad + 8, ctx);
270 201
271 return md5_read_ctx(ctx, resbuf); 202/* Put result from CTX in first 16 bytes following RESBUF. The result is
203 always in little endian byte order, so that a byte-wise output yields
204 to the wanted ASCII representation of the message digest.
205
206 IMPORTANT: On some systems it is required that RESBUF is correctly
207 aligned for a 32 bits value. */
208 ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
209 ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
210 ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
211 ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
212
213 return resbuf;
272} 214}
273 215
274/* Compute MD5 message digest for bytes read from STREAM. The 216/* Compute MD5 message digest for bytes read from STREAM. The
275 resulting message digest number will be written into the 16 bytes 217 resulting message digest number will be written into the 16 bytes
276 beginning at RESBLOCK. */ 218 beginning at RESBLOCK. */
277int md5_stream(FILE *stream, void *resblock) 219static int md5_stream(FILE *stream, void *resblock)
278{ 220{
279 /* Important: BLOCKSIZE must be a multiple of 64. */ 221 /* Important: BLOCKSIZE must be a multiple of 64. */
280static const int BLOCKSIZE = 4096; 222static const int BLOCKSIZE = 4096;
@@ -326,7 +268,7 @@ static const int BLOCKSIZE = 4096;
326 result is always in little endian byte order, so that a byte-wise 268 result is always in little endian byte order, so that a byte-wise
327 output yields to the wanted ASCII representation of the message 269 output yields to the wanted ASCII representation of the message
328 digest. */ 270 digest. */
329void *md5_buffer(const char *buffer, size_t len, void *resblock) 271static void *md5_buffer(const char *buffer, size_t len, void *resblock)
330{ 272{
331 struct md5_ctx ctx; 273 struct md5_ctx ctx;
332 274
@@ -340,7 +282,7 @@ void *md5_buffer(const char *buffer, size_t len, void *resblock)
340 return md5_finish_ctx(&ctx, resblock); 282 return md5_finish_ctx(&ctx, resblock);
341} 283}
342 284
343void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx) 285static void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx)
344{ 286{
345 /* When we already have some bits in our internal buffer concatenate 287 /* When we already have some bits in our internal buffer concatenate
346 both inputs first. */ 288 both inputs first. */
@@ -388,7 +330,7 @@ void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx)
388 330
389/* Process LEN bytes of BUFFER, accumulating context into CTX. 331/* Process LEN bytes of BUFFER, accumulating context into CTX.
390 It is assumed that LEN % 64 == 0. */ 332 It is assumed that LEN % 64 == 0. */
391void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx) 333static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
392{ 334{
393 md5_uint32 correct_words[16]; 335 md5_uint32 correct_words[16];
394 const md5_uint32 *words = buffer; 336 const md5_uint32 *words = buffer;
@@ -490,7 +432,6 @@ void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
490 break; 432 break;
491 case 3: 433 case 3:
492 temp += FI(B,C,D); 434 temp += FI(B,C,D);
493 break;
494 } 435 }
495 temp += cwp[(int)(*pp++)] + *pc++; 436 temp += cwp[(int)(*pp++)] + *pc++;
496 temp = CYCLIC (temp, ps[i&3]); 437 temp = CYCLIC (temp, ps[i&3]);
@@ -550,6 +491,7 @@ void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
550 491
551 /* It is unfortunate that C does not provide an operator for 492 /* It is unfortunate that C does not provide an operator for
552 cyclic rotation. Hope the C compiler is smart enough. */ 493 cyclic rotation. Hope the C compiler is smart enough. */
494 /* gcc 2.95.4 seems to be --aaronl */
553#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) 495#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
554 496
555 /* Before we start, one word to the strange constants. 497 /* Before we start, one word to the strange constants.
@@ -707,11 +649,7 @@ void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
707//---------------------------------------------------------------------------- 649//----------------------------------------------------------------------------
708 650
709#define ISWHITE(c) ((c) == ' ' || (c) == '\t') 651#define ISWHITE(c) ((c) == ' ' || (c) == '\t')
710#define IN_CTYPE_DOMAIN(c) 1 652#define ISXDIGIT(c) (isxdigit (c))
711#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
712#define STREQ(a, b) (strcmp ((a), (b)) == 0)
713#define TOLOWER(Ch) tolower (Ch)
714#define OPENOPTS(BINARY) "r"
715 653
716/* The minimum length of a valid digest line in a file produced 654/* The minimum length of a valid digest line in a file produced
717 by `md5sum FILE' and read by `md5sum -c'. This length does 655 by `md5sum FILE' and read by `md5sum -c'. This length does
@@ -731,7 +669,6 @@ static int warn = 0; /* With -w, print a message to standard error warning
731static int split_3(char *s, 669static int split_3(char *s,
732 size_t s_len, 670 size_t s_len,
733 unsigned char **u, 671 unsigned char **u,
734 int *binary,
735 char **w) 672 char **w)
736{ 673{
737 size_t i = 0; 674 size_t i = 0;
@@ -762,9 +699,8 @@ static int split_3(char *s,
762 699
763 s[i++] = '\0'; 700 s[i++] = '\0';
764 701
765 if (s[i] != ' ' && s[i] != '*') 702 if (s[i] != ' ' && s[i++] != '*')
766 return FALSE; 703 return FALSE;
767 *binary = (s[i++] == '*');
768 704
769 /* All characters between the type indicator and end of line are 705 /* All characters between the type indicator and end of line are
770 significant -- that includes leading and trailing white space. */ 706 significant -- that includes leading and trailing white space. */
@@ -812,7 +748,7 @@ static int split_3(char *s,
812 return TRUE; 748 return TRUE;
813} 749}
814 750
815static int hex_digits(unsigned char const *s) 751static inline int hex_digits(unsigned char const *s)
816{ 752{
817 while (*s) { 753 while (*s) {
818 if (!ISXDIGIT(*s)) 754 if (!ISXDIGIT(*s))
@@ -826,16 +762,15 @@ static int hex_digits(unsigned char const *s)
826 put the result in *MD5_RESULT. Return non-zero upon failure, zero 762 put the result in *MD5_RESULT. Return non-zero upon failure, zero
827 to indicate success. */ 763 to indicate success. */
828static int md5_file(const char *filename, 764static int md5_file(const char *filename,
829 int binary,
830 unsigned char *md5_result) 765 unsigned char *md5_result)
831{ 766{
832 FILE *fp; 767 FILE *fp;
833 768
834 if (STREQ(filename, "-")) { 769 if (filename[0] == '-' && filename[1] == '\0') {
835 have_read_stdin = 1; 770 have_read_stdin = 1;
836 fp = stdin; 771 fp = stdin;
837 } else { 772 } else {
838 fp = fopen(filename, OPENOPTS(binary)); 773 fp = fopen(filename, "r");
839 if (fp == NULL) { 774 if (fp == NULL) {
840 perror_msg("%s", filename); 775 perror_msg("%s", filename);
841 return FALSE; 776 return FALSE;
@@ -868,7 +803,7 @@ static int md5_check(const char *checkfile_name)
868 size_t line_number; 803 size_t line_number;
869 char line[BUFSIZ]; 804 char line[BUFSIZ];
870 805
871 if (STREQ(checkfile_name, "-")) { 806 if (checkfile_name[0] == '-' && checkfile_name[1] == '\0') {
872 have_read_stdin = 1; 807 have_read_stdin = 1;
873 checkfile_stream = stdin; 808 checkfile_stream = stdin;
874 } else { 809 } else {
@@ -883,7 +818,6 @@ static int md5_check(const char *checkfile_name)
883 818
884 do { 819 do {
885 char *filename; 820 char *filename;
886 int binary;
887 unsigned char *md5num; 821 unsigned char *md5num;
888 int line_length; 822 int line_length;
889 823
@@ -903,7 +837,7 @@ static int md5_check(const char *checkfile_name)
903 if (line[line_length - 1] == '\n') 837 if (line[line_length - 1] == '\n')
904 line[--line_length] = '\0'; 838 line[--line_length] = '\0';
905 839
906 if (split_3(line, line_length, &md5num, &binary, &filename) 840 if (split_3(line, line_length, &md5num, &filename)
907 || !hex_digits(md5num)) { 841 || !hex_digits(md5num)) {
908 if (warn) { 842 if (warn) {
909 error_msg("%s: %lu: improperly formatted MD5 checksum line", 843 error_msg("%s: %lu: improperly formatted MD5 checksum line",
@@ -919,7 +853,7 @@ static int md5_check(const char *checkfile_name)
919 853
920 ++n_properly_formated_lines; 854 ++n_properly_formated_lines;
921 855
922 if (md5_file(filename, binary, md5buffer)) { 856 if (md5_file(filename, md5buffer)) {
923 ++n_open_or_read_failures; 857 ++n_open_or_read_failures;
924 if (!status_only) { 858 if (!status_only) {
925 printf("%s: FAILED open or read\n", filename); 859 printf("%s: FAILED open or read\n", filename);
@@ -930,9 +864,9 @@ static int md5_check(const char *checkfile_name)
930 /* Compare generated binary number with text representation 864 /* Compare generated binary number with text representation
931 in check file. Ignore case of hex digits. */ 865 in check file. Ignore case of hex digits. */
932 for (cnt = 0; cnt < 16; ++cnt) { 866 for (cnt = 0; cnt < 16; ++cnt) {
933 if (TOLOWER(md5num[2 * cnt]) 867 if (tolower(md5num[2 * cnt])
934 != bin2hex[md5buffer[cnt] >> 4] 868 != bin2hex[md5buffer[cnt] >> 4]
935 || (TOLOWER(md5num[2 * cnt + 1]) 869 || (tolower(md5num[2 * cnt + 1])
936 != (bin2hex[md5buffer[cnt] & 0xf]))) 870 != (bin2hex[md5buffer[cnt] & 0xf])))
937 break; 871 break;
938 } 872 }
@@ -997,8 +931,8 @@ int md5sum_main(int argc,
997 char **string = NULL; 931 char **string = NULL;
998 size_t n_strings = 0; 932 size_t n_strings = 0;
999 size_t err = 0; 933 size_t err = 0;
1000 int file_type_specified = 0; 934 char file_type_specified = 0;
1001 int binary = 0; 935 char binary = 0;
1002 936
1003 while ((opt = getopt(argc, argv, "g:bcstw")) != -1) { 937 while ((opt = getopt(argc, argv, "g:bcstw")) != -1) {
1004 switch (opt) { 938 switch (opt) {
@@ -1084,9 +1018,9 @@ int md5sum_main(int argc,
1084 int fail; 1018 int fail;
1085 char *file = argv[optind]; 1019 char *file = argv[optind];
1086 1020
1087 fail = md5_file (file, binary, md5buffer); 1021 fail = md5_file (file, md5buffer);
1088 err |= fail; 1022 err |= fail;
1089 if (!fail && STREQ(file, "-")) { 1023 if (!fail && file[0]=='-' && file[1] == '\0') {
1090 size_t i; 1024 size_t i;
1091 for (i = 0; i < 16; ++i) 1025 for (i = 0; i < 16; ++i)
1092 printf ("%02x", md5buffer[i]); 1026 printf ("%02x", md5buffer[i]);