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