ffa9e6bce65b276e7232f586c72518ea6f883834
[oweals/busybox.git] / coreutils / md5sum.c
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.
4  *
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)
8  * any later version.
9  *
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.
14  *
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.
18  */
19
20 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu> */
21 /* Hacked to work with BusyBox by Alfred M. Szmidt <ams@trillian.itslinux.org> */
22
23 #include "internal.h"
24 #include <stdio.h>
25 #include <errno.h>
26 #include <ctype.h>
27
28 //----------------------------------------------------------------------------
29 //--------md5.c
30 //----------------------------------------------------------------------------
31
32 /* md5.c - Functions to compute MD5 message digest of files or memory blocks
33  *         according to the definition of MD5 in RFC 1321 from April 1992.
34  * Copyright (C) 1995, 1996 Free Software Foundation, Inc.
35  *
36  * NOTE: The canonical source of this file is maintained with the GNU C
37  * Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
38  *
39  * This program is free software; you can redistribute it and/or modify it
40  * under the terms of the GNU General Public License as published by the
41  * Free Software Foundation; either version 2, or (at your option) any
42  * later version.
43  *
44  * This program is distributed in the hope that it will be useful,
45  * but WITHOUT ANY WARRANTY; without even the implied warranty of
46  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
47  * GNU General Public License for more details.
48  *
49  * You should have received a copy of the GNU General Public License
50  * along with this program; if not, write to the Free Software Foundation,
51  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
52  */
53
54 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
55
56 #include <sys/types.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <endian.h>
60
61 #include "internal.h"
62 //----------------------------------------------------------------------------
63 //--------md5.h
64 //----------------------------------------------------------------------------
65
66 /* md5.h - Declaration of functions and data types used for MD5 sum
67    computing library functions.
68    Copyright (C) 1995, 1996 Free Software Foundation, Inc.
69    NOTE: The canonical source of this file is maintained with the GNU C
70    Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
71
72    This program is free software; you can redistribute it and/or modify it
73    under the terms of the GNU General Public License as published by the
74    Free Software Foundation; either version 2, or (at your option) any
75    later version.
76
77    This program is distributed in the hope that it will be useful,
78    but WITHOUT ANY WARRANTY; without even the implied warranty of
79    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
80    GNU General Public License for more details.
81
82    You should have received a copy of the GNU General Public License
83    along with this program; if not, write to the Free Software Foundation,
84    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
85
86 #ifndef _MD5_H
87 #define _MD5_H 1
88
89 #include <stdio.h>
90
91 #if defined HAVE_LIMITS_H || _LIBC
92 # include <limits.h>
93 #endif
94
95 /* The following contortions are an attempt to use the C preprocessor
96    to determine an unsigned integral type that is 32 bits wide.  An
97    alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
98    doing that would require that the configure script compile and *run*
99    the resulting executable.  Locally running cross-compiled executables
100    is usually not possible.  */
101
102 #ifdef _LIBC
103 # include <sys/types.h>
104 typedef u_int32_t md5_uint32;
105 #else
106 # if defined __STDC__ && __STDC__
107 #  define UINT_MAX_32_BITS 4294967295U
108 # else
109 #  define UINT_MAX_32_BITS 0xFFFFFFFF
110 # endif
111
112 /* If UINT_MAX isn't defined, assume it's a 32-bit type.
113    This should be valid for all systems GNU cares about because
114    that doesn't include 16-bit systems, and only modern systems
115    (that certainly have <limits.h>) have 64+-bit integral types.  */
116
117 # ifndef UINT_MAX
118 #  define UINT_MAX UINT_MAX_32_BITS
119 # endif
120
121 # if UINT_MAX == UINT_MAX_32_BITS
122    typedef unsigned int md5_uint32;
123 # else
124 #  if USHRT_MAX == UINT_MAX_32_BITS
125     typedef unsigned short md5_uint32;
126 #  else
127 #   if ULONG_MAX == UINT_MAX_32_BITS
128      typedef unsigned long md5_uint32;
129 #   else
130      /* The following line is intended to evoke an error.
131         Using #error is not portable enough.  */
132      "Cannot determine unsigned 32-bit data type."
133 #   endif
134 #  endif
135 # endif
136 #endif
137
138 #undef __P
139 #if defined (__STDC__) && __STDC__
140 #define __P(x) x
141 #else
142 #define __P(x) ()
143 #endif
144
145 /* Structure to save state of computation between the single steps.  */
146 struct md5_ctx
147 {
148   md5_uint32 A;
149   md5_uint32 B;
150   md5_uint32 C;
151   md5_uint32 D;
152
153   md5_uint32 total[2];
154   md5_uint32 buflen;
155   char buffer[128];
156 };
157
158 /*
159  * The following three functions are build up the low level used in
160  * the functions `md5_stream' and `md5_buffer'.
161  */
162
163 /* Initialize structure containing state of computation.
164    (RFC 1321, 3.3: Step 3)  */
165 extern void md5_init_ctx __P ((struct md5_ctx *ctx));
166
167 /* Starting with the result of former calls of this function (or the
168    initialization function update the context for the next LEN bytes
169    starting at BUFFER.
170    It is necessary that LEN is a multiple of 64!!! */
171 extern void md5_process_block __P ((const void *buffer, size_t len,
172                                     struct md5_ctx *ctx));
173
174 /* Starting with the result of former calls of this function (or the
175    initialization function update the context for the next LEN bytes
176    starting at BUFFER.
177    It is NOT required that LEN is a multiple of 64.  */
178 extern void md5_process_bytes __P ((const void *buffer, size_t len,
179                                     struct md5_ctx *ctx));
180
181 /* Process the remaining bytes in the buffer and put result from CTX
182    in first 16 bytes following RESBUF.  The result is always in little
183    endian byte order, so that a byte-wise output yields to the wanted
184    ASCII representation of the message digest.
185
186    IMPORTANT: On some systems it is required that RESBUF is correctly
187    aligned for a 32 bits value.  */
188 extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
189
190
191 /* Put result from CTX in first 16 bytes following RESBUF.  The result is
192    always in little endian byte order, so that a byte-wise output yields
193    to the wanted ASCII representation of the message digest.
194
195    IMPORTANT: On some systems it is required that RESBUF is correctly
196    aligned for a 32 bits value.  */
197 extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
198
199
200 /* Compute MD5 message digest for bytes read from STREAM.  The
201    resulting message digest number will be written into the 16 bytes
202    beginning at RESBLOCK.  */
203 extern int md5_stream __P ((FILE *stream, void *resblock));
204
205 /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
206    result is always in little endian byte order, so that a byte-wise
207    output yields to the wanted ASCII representation of the message
208    digest.  */
209 extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
210
211 #endif
212
213 //----------------------------------------------------------------------------
214 //--------end of md5.h
215 //----------------------------------------------------------------------------
216
217 #define SWAP(n) (n)
218
219 /* This array contains the bytes used to pad the buffer to the next
220    64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
221 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */  };
222
223 /* Initialize structure containing state of computation.
224    (RFC 1321, 3.3: Step 3)  */
225 void md5_init_ctx(struct md5_ctx *ctx)
226 {
227   ctx->A = 0x67452301;
228   ctx->B = 0xefcdab89;
229   ctx->C = 0x98badcfe;
230   ctx->D = 0x10325476;
231
232   ctx->total[0] = ctx->total[1] = 0;
233   ctx->buflen = 0;
234 }
235
236 /* Put result from CTX in first 16 bytes following RESBUF.  The result
237    must be in little endian byte order.
238
239    IMPORTANT: On some systems it is required that RESBUF is correctly
240    aligned for a 32 bits value.  */
241 void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
242 {
243   ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
244   ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
245   ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
246   ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
247
248   return resbuf;
249 }
250
251 /* Process the remaining bytes in the internal buffer and the usual
252    prolog according to the standard and write the result to RESBUF.
253
254    IMPORTANT: On some systems it is required that RESBUF is correctly
255    aligned for a 32 bits value.  */
256 void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
257 {
258   /* Take yet unprocessed bytes into account.  */
259   md5_uint32 bytes = ctx->buflen;
260   size_t pad;
261
262   /* Now count remaining bytes.  */
263   ctx->total[0] += bytes;
264   if (ctx->total[0] < bytes)
265     ++ctx->total[1];
266
267   pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
268   memcpy(&ctx->buffer[bytes], fillbuf, pad);
269
270   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
271   *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3);
272   *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] =
273     SWAP((ctx->total[1] << 3) | (ctx->total[0] >> 29));
274
275   /* Process last bytes.  */
276   md5_process_block(ctx->buffer, bytes + pad + 8, ctx);
277
278   return md5_read_ctx(ctx, resbuf);
279 }
280
281 /* Compute MD5 message digest for bytes read from STREAM.  The
282    resulting message digest number will be written into the 16 bytes
283    beginning at RESBLOCK.  */
284 int md5_stream(FILE *stream, void *resblock)
285 {
286   /* Important: BLOCKSIZE must be a multiple of 64.  */
287 #define BLOCKSIZE 4096
288   struct md5_ctx ctx;
289   char buffer[BLOCKSIZE + 72];
290   size_t sum;
291
292   /* Initialize the computation context.  */
293   md5_init_ctx(&ctx);
294
295   /* Iterate over full file contents.  */
296   while (1) {
297     /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
298        computation function processes the whole buffer so that with the
299        next round of the loop another block can be read.  */
300     size_t n;
301     sum = 0;
302
303     /* Read block.  Take care for partial reads.  */
304     do {
305       n = fread(buffer + sum, 1, BLOCKSIZE - sum, stream);
306
307       sum += n;
308     }
309     while (sum < BLOCKSIZE && n != 0);
310     if (n == 0 && ferror(stream))
311       return 1;
312
313     /* If end of file is reached, end the loop.  */
314     if (n == 0)
315       break;
316
317     /* Process buffer with BLOCKSIZE bytes.  Note that
318        BLOCKSIZE % 64 == 0
319     */
320     md5_process_block(buffer, BLOCKSIZE, &ctx);
321   }
322
323   /* Add the last bytes if necessary.  */
324   if (sum > 0)
325     md5_process_bytes(buffer, sum, &ctx);
326
327   /* Construct result in desired memory.  */
328   md5_finish_ctx(&ctx, resblock);
329   return 0;
330 }
331
332 /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
333    result is always in little endian byte order, so that a byte-wise
334    output yields to the wanted ASCII representation of the message
335    digest.  */
336 void *md5_buffer(const char *buffer, size_t len, void *resblock)
337 {
338   struct md5_ctx ctx;
339
340   /* Initialize the computation context.  */
341   md5_init_ctx(&ctx);
342
343   /* Process whole buffer but last len % 64 bytes.  */
344   md5_process_bytes(buffer, len, &ctx);
345
346   /* Put result in desired memory area.  */
347   return md5_finish_ctx(&ctx, resblock);
348 }
349
350 void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx)
351 {
352   /* When we already have some bits in our internal buffer concatenate
353      both inputs first.  */
354   if (ctx->buflen != 0) {
355     size_t left_over = ctx->buflen;
356     size_t add = 128 - left_over > len ? len : 128 - left_over;
357
358     memcpy(&ctx->buffer[left_over], buffer, add);
359     ctx->buflen += add;
360
361     if (left_over + add > 64) {
362       md5_process_block(ctx->buffer, (left_over + add) & ~63, ctx);
363       /* The regions in the following copy operation cannot overlap.  */
364       memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
365              (left_over + add) & 63);
366       ctx->buflen = (left_over + add) & 63;
367     }
368
369     buffer = (const char *) buffer + add;
370     len -= add;
371   }
372
373   /* Process available complete blocks.  */
374   if (len > 64) {
375     md5_process_block(buffer, len & ~63, ctx);
376     buffer = (const char *) buffer + (len & ~63);
377     len &= 63;
378   }
379
380   /* Move remaining bytes in internal buffer.  */
381   if (len > 0) {
382     memcpy(ctx->buffer, buffer, len);
383     ctx->buflen = len;
384   }
385 }
386
387 /* These are the four functions used in the four steps of the MD5 algorithm
388    and defined in the RFC 1321.  The first function is a little bit optimized
389    (as found in Colin Plumbs public domain implementation).  */
390 /* #define FF(b, c, d) ((b & c) | (~b & d)) */
391 #define FF(b, c, d) (d ^ (b & (c ^ d)))
392 #define FG(b, c, d) FF (d, b, c)
393 #define FH(b, c, d) (b ^ c ^ d)
394 #define FI(b, c, d) (c ^ (b | ~d))
395
396 /* Process LEN bytes of BUFFER, accumulating context into CTX.
397    It is assumed that LEN % 64 == 0.  */
398 void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
399 {
400   md5_uint32 correct_words[16];
401   const md5_uint32 *words = buffer;
402   size_t nwords = len / sizeof(md5_uint32);
403   const md5_uint32 *endp = words + nwords;
404   md5_uint32 A = ctx->A;
405   md5_uint32 B = ctx->B;
406   md5_uint32 C = ctx->C;
407   md5_uint32 D = ctx->D;
408
409   /* First increment the byte count.  RFC 1321 specifies the possible
410      length of the file up to 2^64 bits.  Here we only compute the
411      number of bytes.  Do a double word increment.  */
412   ctx->total[0] += len;
413   if (ctx->total[0] < len)
414     ++ctx->total[1];
415
416   /* Process all bytes in the buffer with 64 bytes in each round of
417      the loop.  */
418   while (words < endp) {
419     md5_uint32 *cwp = correct_words;
420     md5_uint32 A_save = A;
421     md5_uint32 B_save = B;
422     md5_uint32 C_save = C;
423     md5_uint32 D_save = D;
424
425     /* First round: using the given function, the context and a constant
426        the next context is computed.  Because the algorithms processing
427        unit is a 32-bit word and it is determined to work on words in
428        little endian byte order we perhaps have to change the byte order
429        before the computation.  To reduce the work for the next steps
430        we store the swapped words in the array CORRECT_WORDS.  */
431
432 #define OP(a, b, c, d, s, T)                                            \
433       do                                                                \
434         {                                                               \
435           a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;             \
436           ++words;                                                      \
437           CYCLIC (a, s);                                                \
438           a += b;                                                       \
439         }                                                               \
440       while (0)
441
442     /* It is unfortunate that C does not provide an operator for
443        cyclic rotation.  Hope the C compiler is smart enough.  */
444 #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
445
446     /* Before we start, one word to the strange constants.
447        They are defined in RFC 1321 as
448
449        T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
450     */
451
452     /* Round 1.  */
453     OP(A, B, C, D, 7, 0xd76aa478);
454     OP(D, A, B, C, 12, 0xe8c7b756);
455     OP(C, D, A, B, 17, 0x242070db);
456     OP(B, C, D, A, 22, 0xc1bdceee);
457     OP(A, B, C, D, 7, 0xf57c0faf);
458     OP(D, A, B, C, 12, 0x4787c62a);
459     OP(C, D, A, B, 17, 0xa8304613);
460     OP(B, C, D, A, 22, 0xfd469501);
461     OP(A, B, C, D, 7, 0x698098d8);
462     OP(D, A, B, C, 12, 0x8b44f7af);
463     OP(C, D, A, B, 17, 0xffff5bb1);
464     OP(B, C, D, A, 22, 0x895cd7be);
465     OP(A, B, C, D, 7, 0x6b901122);
466     OP(D, A, B, C, 12, 0xfd987193);
467     OP(C, D, A, B, 17, 0xa679438e);
468     OP(B, C, D, A, 22, 0x49b40821);
469
470     /* For the second to fourth round we have the possibly swapped words
471        in CORRECT_WORDS.  Redefine the macro to take an additional first
472        argument specifying the function to use.  */
473 #undef OP
474 #define OP(f, a, b, c, d, k, s, T)                                      \
475       do                                                                \
476         {                                                               \
477           a += f (b, c, d) + correct_words[k] + T;                      \
478           CYCLIC (a, s);                                                \
479           a += b;                                                       \
480         }                                                               \
481       while (0)
482
483     /* Round 2.  */
484     OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
485     OP(FG, D, A, B, C, 6, 9, 0xc040b340);
486     OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
487     OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
488     OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
489     OP(FG, D, A, B, C, 10, 9, 0x02441453);
490     OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
491     OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
492     OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
493     OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
494     OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
495     OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
496     OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
497     OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
498     OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
499     OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
500
501     /* Round 3.  */
502     OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
503     OP(FH, D, A, B, C, 8, 11, 0x8771f681);
504     OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
505     OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
506     OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
507     OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
508     OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
509     OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
510     OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
511     OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
512     OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
513     OP(FH, B, C, D, A, 6, 23, 0x04881d05);
514     OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
515     OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
516     OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
517     OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
518
519     /* Round 4.  */
520     OP(FI, A, B, C, D, 0, 6, 0xf4292244);
521     OP(FI, D, A, B, C, 7, 10, 0x432aff97);
522     OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
523     OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
524     OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
525     OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
526     OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
527     OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
528     OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
529     OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
530     OP(FI, C, D, A, B, 6, 15, 0xa3014314);
531     OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
532     OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
533     OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
534     OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
535     OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
536
537     /* Add the starting values of the context.  */
538     A += A_save;
539     B += B_save;
540     C += C_save;
541     D += D_save;
542   }
543
544   /* Put checksum in context given as argument.  */
545   ctx->A = A;
546   ctx->B = B;
547   ctx->C = C;
548   ctx->D = D;
549 }
550
551 //----------------------------------------------------------------------------
552 //--------end of md5.c
553 //----------------------------------------------------------------------------
554
555 #define ISWHITE(c) ((c) == ' ' || (c) == '\t')
556 #define IN_CTYPE_DOMAIN(c) 1
557 #define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
558 #define STREQ(a, b) (strcmp ((a), (b)) == 0)
559 #define TOLOWER(Ch) tolower (Ch)
560 #define OPENOPTS(BINARY) "r"
561
562 /* The minimum length of a valid digest line in a file produced
563    by `md5sum FILE' and read by `md5sum -c'.  This length does
564    not include any newline character at the end of a line.  */
565 #define MIN_DIGEST_LINE_LENGTH 35 /* 32 - message digest length
566                                       2 - blank and binary indicator
567                                       1 - minimum filename length */
568
569 static int have_read_stdin; /* Nonzero if any of the files read were
570                                the standard input. */
571
572 static int status_only = 0; /* With -c, don't generate any output.
573                                The exit code indicates success or failure */
574 static int warn = 0; /* With -w, print a message to standard error warning
575                         about each improperly formatted MD5 checksum line */
576
577 static const char md5sum_usage[] =
578     "md5sum [OPTION] [FILE]...\n"
579     "or:    md5sum [OPTION] -c [FILE]\n"
580 #ifndef BB_FEATURE_TRIVIAL_HELP
581     "\nPrint or check MD5 checksums.\n\n"
582     "Options:\n"
583     "With no FILE, or when FILE is -, read standard input.\n\n"
584     "\t-b\tread files in binary mode\n"
585     "\t-c\tcheck MD5 sums against given list\n"
586     "\t-t\tread files in text mode (default)\n"
587     "\t-g\tread a string\n"
588     "\nThe following two options are useful only when verifying checksums:\n"
589     "\t-s,\tdon't output anything, status code shows success\n"
590     "\t-w,\twarn about improperly formated MD5 checksum lines\n"
591 #endif
592 ;
593
594 static int split_3(char *s,
595                    size_t s_len,
596                    unsigned char **u,
597                    int *binary,
598                    char **w)
599 {
600   size_t i = 0;
601   int escaped_filename = 0;
602
603   while (ISWHITE(s[i]))
604     ++i;
605
606   /* The line must have at least 35 (36 if the first is a backslash)
607      more characters to contain correct message digest information.
608      Ignore this line if it is too short.  */
609   if (!(s_len - i >= MIN_DIGEST_LINE_LENGTH
610         || (s[i] == '\\' && s_len - i >= 1 + MIN_DIGEST_LINE_LENGTH)))
611     return FALSE;
612
613   if (s[i] == '\\') {
614     ++i;
615     escaped_filename = 1;
616   }
617   *u = (unsigned char *) &s[i];
618
619   /* The first field has to be the 32-character hexadecimal
620      representation of the message digest.  If it is not followed
621      immediately by a white space it's an error.  */
622   i += 32;
623   if (!ISWHITE(s[i]))
624     return FALSE;
625
626   s[i++] = '\0';
627
628   if (s[i] != ' ' && s[i] != '*')
629     return FALSE;
630   *binary = (s[i++] == '*');
631
632   /* All characters between the type indicator and end of line are
633      significant -- that includes leading and trailing white space.  */
634   *w = &s[i];
635
636   if (escaped_filename) {
637     /* Translate each `\n' string in the file name to a NEWLINE,
638        and each `\\' string to a backslash.  */
639
640     char *dst = &s[i];
641
642     while (i < s_len) {
643       switch (s[i]) {
644        case '\\':
645         if (i == s_len - 1) {
646           /* A valid line does not end with a backslash.  */
647           return FALSE;
648         }
649         ++i;
650         switch (s[i++]) {
651          case 'n':
652           *dst++ = '\n';
653           break;
654          case '\\':
655           *dst++ = '\\';
656           break;
657          default:
658           /* Only `\' or `n' may follow a backslash.  */
659           return FALSE;
660         }
661         break;
662
663        case '\0':
664         /* The file name may not contain a NUL.  */
665         return FALSE;
666         break;
667
668        default:
669         *dst++ = s[i++];
670         break;
671       }
672     }
673     *dst = '\0';
674   }
675   return TRUE;
676 }
677
678 static int hex_digits(unsigned char const *s)
679 {
680   while (*s) {
681     if (!ISXDIGIT(*s))
682       return TRUE;
683     ++s;
684   }
685   return FALSE;
686 }
687
688 /* An interface to md5_stream.  Operate on FILENAME (it may be "-") and
689    put the result in *MD5_RESULT.  Return non-zero upon failure, zero
690    to indicate success.  */
691 static int md5_file(const char *filename,
692                     int binary,
693                     unsigned char *md5_result)
694 {
695   FILE *fp;
696
697   if (STREQ(filename, "-")) {
698     have_read_stdin = 1;
699     fp = stdin;
700   } else {
701     fp = fopen(filename, OPENOPTS(binary));
702     if (fp == NULL) {
703       errorMsg("md5sum: %s: %s\n", filename, strerror(errno));
704       return FALSE;
705     }
706   }
707
708   if (md5_stream(fp, md5_result)) {
709     errorMsg("md5sum: %s: %s\n", filename, strerror(errno));
710
711     if (fp != stdin)
712       fclose(fp);
713     return FALSE;
714   }
715
716   if (fp != stdin && fclose(fp) == EOF) {
717     errorMsg("md5sum: %s: %s\n", filename, strerror(errno));
718     return FALSE;
719   }
720
721   return TRUE;
722 }
723
724 static int md5_check(const char *checkfile_name)
725 {
726   FILE *checkfile_stream;
727   int n_properly_formated_lines = 0;
728   int n_mismatched_checksums = 0;
729   int n_open_or_read_failures = 0;
730   unsigned char md5buffer[16];
731   size_t line_number;
732   char *line;
733   size_t line_chars_allocated;
734
735   if (STREQ(checkfile_name, "-")) {
736     have_read_stdin = 1;
737     checkfile_stream = stdin;
738   } else {
739     checkfile_stream = fopen(checkfile_name, "r");
740     if (checkfile_stream == NULL) {
741       errorMsg("md5sum: %s: %s\n", checkfile_name, strerror(errno));
742       return FALSE;
743     }
744   }
745
746   line_number = 0;
747   line = 0;
748   line_chars_allocated = 0;
749
750   do {
751     char *filename;
752     int binary;
753     unsigned char *md5num;
754     int line_length;
755
756     ++line_number;
757
758     line_length = getline(&line, &line_chars_allocated, checkfile_stream);
759
760     if (line_length <= 0)
761       break;
762
763     /* Ignore comment lines, which begin with a '#' character.  */
764     if (line[0] == '#')
765       continue;
766
767     /* Remove any trailing newline.  */
768     if (line[line_length - 1] == '\n')
769       line[--line_length] = '\0';
770
771     if (split_3(line, line_length, &md5num, &binary, &filename)
772         || !hex_digits(md5num)) {
773       if (warn) {
774         errorMsg("%s: %lu: improperly formatted MD5 checksum line\n",
775                  checkfile_name, (unsigned long) line_number);
776       }
777     } else {
778       static const char bin2hex[] = {
779         '0', '1', '2', '3',
780         '4', '5', '6', '7',
781         '8', '9', 'a', 'b',
782         'c', 'd', 'e', 'f'
783       };
784
785       ++n_properly_formated_lines;
786
787       if (md5_file(filename, binary, md5buffer)) {
788         ++n_open_or_read_failures;
789         if (!status_only) {
790           printf("%s: FAILED open or read\n", filename);
791           fflush(stdout);
792         }
793       } else {
794         size_t cnt;
795         /* Compare generated binary number with text representation
796            in check file.  Ignore case of hex digits.  */
797         for (cnt = 0; cnt < 16; ++cnt) {
798           if (TOLOWER(md5num[2 * cnt])
799               != bin2hex[md5buffer[cnt] >> 4]
800               || (TOLOWER(md5num[2 * cnt + 1])
801                   != (bin2hex[md5buffer[cnt] & 0xf])))
802             break;
803         }
804         if (cnt != 16)
805           ++n_mismatched_checksums;
806
807         if (!status_only) {
808           printf("%s: %s\n", filename,
809                  (cnt != 16 ? "FAILED" : "OK"));
810           fflush(stdout);
811         }
812       }
813     }
814   }
815
816   while (!feof(checkfile_stream) && !ferror(checkfile_stream));
817
818   if (line)
819     free(line);
820
821   if (ferror(checkfile_stream)) {
822     errorMsg("%s: read error", checkfile_name); /* */
823     return FALSE;
824   }
825
826   if (checkfile_stream != stdin && fclose(checkfile_stream) == EOF) {
827     errorMsg("md5sum: %s: %s\n", checkfile_name, strerror(errno));
828     return FALSE;
829   }
830
831   if (n_properly_formated_lines == 0) {
832     /* Warn if no tests are found.  */
833     errorMsg("%s: no properly formatted MD5 checksum lines found\n",
834              checkfile_name);
835     return FALSE;
836   } else {
837     if (!status_only) {
838       int n_computed_checkums = (n_properly_formated_lines
839                                  - n_open_or_read_failures);
840
841       if (n_open_or_read_failures > 0) {
842         errorMsg("WARNING: %d of %d listed files could not be read\n",
843                  n_open_or_read_failures, n_properly_formated_lines);
844         return FALSE;
845       }
846
847       if (n_mismatched_checksums > 0) {
848         errorMsg("WARNING: %d of %d computed checksums did NOT match\n",
849                  n_mismatched_checksums, n_computed_checkums);
850         return FALSE;
851       }
852     }
853   }
854
855   return ((n_properly_formated_lines > 0 && n_mismatched_checksums == 0
856            && n_open_or_read_failures == 0) ? 0 : 1);
857 }
858
859 int md5sum_main(int argc,
860                 char **argv)
861 {
862   unsigned char md5buffer[16];
863   int do_check = 0;
864   int opt;
865   char **string = NULL;
866   size_t n_strings = 0;
867   size_t err = 0;
868   int file_type_specified = 0;
869   int binary = 0;
870
871   while ((opt = getopt(argc, argv, "g:bcstw")) != -1) {
872     switch (opt) {
873      case 'g': { /* read a string */
874        if (string == NULL)
875          string = (char **) xmalloc ((argc - 1) * sizeof (char *));
876
877        if (optarg == NULL)
878          optarg = "";
879        string[n_strings++] = optarg;
880        break;
881      }
882
883      case 'b': /* read files in binary mode */
884       file_type_specified = 1;
885       binary = 1;
886       break;
887
888      case 'c': /* check MD5 sums against given list */
889       do_check = 1;
890       break;
891
892      case 's':  /* don't output anything, status code shows success */
893       status_only = 1;
894       warn = 0;
895       break;
896
897      case 't': /* read files in text mode (default) */
898       file_type_specified = 1;
899       binary = 0;
900       break;
901
902      case 'w': /* warn about improperly formated MD5 checksum lines */
903       status_only = 0;
904       warn = 1;
905       break;
906
907      default:
908       usage(md5sum_usage);
909     }
910   }
911
912   if (file_type_specified && do_check) {
913     errorMsg("the -b and -t options are meaningless when verifying checksums\n");
914     exit FALSE;
915   }
916
917   if (n_strings > 0 && do_check) {
918     errorMsg("the -g and -c options are mutually exclusive\n");
919     exit FALSE;
920   }
921
922   if (status_only && !do_check) {
923     errorMsg("the -s option is meaningful only when verifying checksums\n");
924     exit FALSE;
925   }
926
927   if (warn && !do_check) {
928     errorMsg("the -w option is meaningful only when verifying checksums\n");
929     exit FALSE;
930   }
931
932   if (n_strings > 0) {
933     size_t i;
934
935     if (optind < argc) {
936       errorMsg("no files may be specified when using -g\n");
937       exit FALSE;
938     }
939     for (i = 0; i < n_strings; ++i) {
940       size_t cnt;
941       md5_buffer (string[i], strlen (string[i]), md5buffer);
942
943       for (cnt = 0; cnt < 16; ++cnt)
944         printf ("%02x", md5buffer[cnt]);
945
946       printf ("  \"%s\"\n", string[i]);
947     }
948   } else if (do_check) {
949     if (optind + 1 < argc) {
950       errorMsg("only one argument may be specified when using -c\n");
951     }
952
953     err = md5_check ((optind == argc) ? "-" : argv[optind]);
954   } else {
955     if (optind == argc)
956       argv[argc++] = "-";
957
958     for (; optind < argc; ++optind) {
959       int fail;
960       char *file = argv[optind];
961
962       fail = md5_file (file, binary, md5buffer);
963       err |= fail;
964       if (!fail) {
965         size_t i;
966         /* Output a leading backslash if the file name contains
967            a newline or backslash.  */
968         if (strchr (file, '\n') || strchr (file, '\\'))
969           putchar ('\\');
970
971         for (i = 0; i < 16; ++i)
972           printf ("%02x", md5buffer[i]);
973
974         putchar (' ');
975         if (binary)
976           putchar ('*');
977         else
978           putchar (' ');
979
980         /* Translate each NEWLINE byte to the string, "\\n",
981            and each backslash to "\\\\".  */
982         for (i = 0; i < strlen (file); ++i) {
983           switch (file[i]) {
984            case '\n':
985             fputs ("\\n", stdout);
986             break;
987
988            case '\\':
989             fputs ("\\\\", stdout);
990             break;
991
992            default:
993             putchar (file[i]);
994             break;
995           }
996         }
997         putchar ('\n');
998       }
999     }
1000   }
1001
1002   if (fclose (stdout) == EOF) {
1003     errorMsg("write error");
1004     exit FALSE;
1005   }
1006
1007   if (have_read_stdin && fclose (stdin) == EOF) {
1008     errorMsg("standard input");
1009     exit FALSE;
1010   }
1011
1012   exit (err == 0 ? TRUE : FALSE);
1013 }