aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-06-07 14:54:24 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-06-07 14:54:24 +0000
commit7aa62cf17395d94f9a138fe8ace149f0be711300 (patch)
tree2dcc763755ef52df501f3b8ff57126be448d97dd
parent233b170a8567c396b0836ec17c82a50d212b8a8d (diff)
downloadbusybox-w32-7aa62cf17395d94f9a138fe8ace149f0be711300.tar.gz
busybox-w32-7aa62cf17395d94f9a138fe8ace149f0be711300.tar.bz2
busybox-w32-7aa62cf17395d94f9a138fe8ace149f0be711300.zip
Run through indent
-rw-r--r--coreutils/md5sum.c1588
1 files changed, 808 insertions, 780 deletions
diff --git a/coreutils/md5sum.c b/coreutils/md5sum.c
index c1480cd32..c0294f4cd 100644
--- a/coreutils/md5sum.c
+++ b/coreutils/md5sum.c
@@ -77,16 +77,15 @@
77typedef u_int32_t md5_uint32; 77typedef u_int32_t md5_uint32;
78 78
79/* Structure to save state of computation between the single steps. */ 79/* Structure to save state of computation between the single steps. */
80struct md5_ctx 80struct md5_ctx {
81{ 81 md5_uint32 A;
82 md5_uint32 A; 82 md5_uint32 B;
83 md5_uint32 B; 83 md5_uint32 C;
84 md5_uint32 C; 84 md5_uint32 D;
85 md5_uint32 D; 85
86 86 md5_uint32 total[2];
87 md5_uint32 total[2]; 87 md5_uint32 buflen;
88 md5_uint32 buflen; 88 char buffer[128];
89 char buffer[128];
90}; 89};
91 90
92/* 91/*
@@ -96,21 +95,21 @@ struct md5_ctx
96 95
97/* Initialize structure containing state of computation. 96/* Initialize structure containing state of computation.
98 (RFC 1321, 3.3: Step 3) */ 97 (RFC 1321, 3.3: Step 3) */
99static void md5_init_ctx __P ((struct md5_ctx *ctx)); 98static void md5_init_ctx __P((struct md5_ctx * ctx));
100 99
101/* Starting with the result of former calls of this function (or the 100/* Starting with the result of former calls of this function (or the
102 initialization function update the context for the next LEN bytes 101 initialization function update the context for the next LEN bytes
103 starting at BUFFER. 102 starting at BUFFER.
104 It is necessary that LEN is a multiple of 64!!! */ 103 It is necessary that LEN is a multiple of 64!!! */
105static void md5_process_block __P ((const void *buffer, size_t len, 104static void md5_process_block __P((const void *buffer, size_t len,
106 struct md5_ctx *ctx)); 105 struct md5_ctx * ctx));
107 106
108/* Starting with the result of former calls of this function (or the 107/* Starting with the result of former calls of this function (or the
109 initialization function update the context for the next LEN bytes 108 initialization function update the context for the next LEN bytes
110 starting at BUFFER. 109 starting at BUFFER.
111 It is NOT required that LEN is a multiple of 64. */ 110 It is NOT required that LEN is a multiple of 64. */
112static void md5_process_bytes __P ((const void *buffer, size_t len, 111static void md5_process_bytes __P((const void *buffer, size_t len,
113 struct md5_ctx *ctx)); 112 struct md5_ctx * ctx));
114 113
115/* Process the remaining bytes in the buffer and put result from CTX 114/* Process the remaining bytes in the buffer and put result from CTX
116 in first 16 bytes following RESBUF. The result is always in little 115 in first 16 bytes following RESBUF. The result is always in little
@@ -119,7 +118,7 @@ static void md5_process_bytes __P ((const void *buffer, size_t len,
119 118
120 IMPORTANT: On some systems it is required that RESBUF is correctly 119 IMPORTANT: On some systems it is required that RESBUF is correctly
121 aligned for a 32 bits value. */ 120 aligned for a 32 bits value. */
122static void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); 121static void *md5_finish_ctx __P((struct md5_ctx * ctx, void *resbuf));
123 122
124 123
125 124
@@ -127,13 +126,13 @@ static void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
127/* Compute MD5 message digest for bytes read from STREAM. The 126/* Compute MD5 message digest for bytes read from STREAM. The
128 resulting message digest number will be written into the 16 bytes 127 resulting message digest number will be written into the 16 bytes
129 beginning at RESBLOCK. */ 128 beginning at RESBLOCK. */
130static int md5_stream __P ((FILE *stream, void *resblock)); 129static int md5_stream __P((FILE * stream, void *resblock));
131 130
132/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The 131/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
133 result is always in little endian byte order, so that a byte-wise 132 result is always in little endian byte order, so that a byte-wise
134 output yields to the wanted ASCII representation of the message 133 output yields to the wanted ASCII representation of the message
135 digest. */ 134 digest. */
136static void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); 135static void *md5_buffer __P((const char *buffer, size_t len, void *resblock));
137 136
138//---------------------------------------------------------------------------- 137//----------------------------------------------------------------------------
139//--------end of md5.h 138//--------end of md5.h
@@ -141,9 +140,9 @@ static void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
141 140
142/* Handle endian-ness */ 141/* Handle endian-ness */
143#if __BYTE_ORDER == __LITTLE_ENDIAN 142#if __BYTE_ORDER == __LITTLE_ENDIAN
144 #define SWAP(n) (n) 143#define SWAP(n) (n)
145#else 144#else
146 #define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24)) 145#define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24))
147#endif 146#endif
148 147
149 148
@@ -158,13 +157,13 @@ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
158 (RFC 1321, 3.3: Step 3) */ 157 (RFC 1321, 3.3: Step 3) */
159void md5_init_ctx(struct md5_ctx *ctx) 158void md5_init_ctx(struct md5_ctx *ctx)
160{ 159{
161 ctx->A = 0x67452301; 160 ctx->A = 0x67452301;
162 ctx->B = 0xefcdab89; 161 ctx->B = 0xefcdab89;
163 ctx->C = 0x98badcfe; 162 ctx->C = 0x98badcfe;
164 ctx->D = 0x10325476; 163 ctx->D = 0x10325476;
165 164
166 ctx->total[0] = ctx->total[1] = 0; 165 ctx->total[0] = ctx->total[1] = 0;
167 ctx->buflen = 0; 166 ctx->buflen = 0;
168} 167}
169 168
170/* Process the remaining bytes in the internal buffer and the usual 169/* Process the remaining bytes in the internal buffer and the usual
@@ -174,30 +173,30 @@ void md5_init_ctx(struct md5_ctx *ctx)
174 aligned for a 32 bits value. */ 173 aligned for a 32 bits value. */
175static void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf) 174static void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
176{ 175{
177 /* Take yet unprocessed bytes into account. */ 176 /* Take yet unprocessed bytes into account. */
178 md5_uint32 bytes = ctx->buflen; 177 md5_uint32 bytes = ctx->buflen;
179 size_t pad; 178 size_t pad;
180 179
181 /* Now count remaining bytes. */ 180 /* Now count remaining bytes. */
182 ctx->total[0] += bytes; 181 ctx->total[0] += bytes;
183 if (ctx->total[0] < bytes) 182 if (ctx->total[0] < bytes)
184 ++ctx->total[1]; 183 ++ctx->total[1];
185 184
186 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; 185 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
187#if MD5SUM_SIZE_VS_SPEED > 0 186#if MD5SUM_SIZE_VS_SPEED > 0
188 memset(&ctx->buffer[bytes], 0, pad); 187 memset(&ctx->buffer[bytes], 0, pad);
189 ctx->buffer[bytes] = 0x80; 188 ctx->buffer[bytes] = 0x80;
190#else 189#else
191 memcpy(&ctx->buffer[bytes], fillbuf, pad); 190 memcpy(&ctx->buffer[bytes], fillbuf, pad);
192#endif 191#endif
193 192
194 /* Put the 64-bit file length in *bits* at the end of the buffer. */ 193 /* Put the 64-bit file length in *bits* at the end of the buffer. */
195 *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3); 194 *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3);
196 *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] = 195 *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] =
197 SWAP( ((ctx->total[1] << 3) | (ctx->total[0] >> 29)) ); 196 SWAP(((ctx->total[1] << 3) | (ctx->total[0] >> 29)));
198 197
199 /* Process last bytes. */ 198 /* Process last bytes. */
200 md5_process_block(ctx->buffer, bytes + pad + 8, ctx); 199 md5_process_block(ctx->buffer, bytes + pad + 8, ctx);
201 200
202/* Put result from CTX in first 16 bytes following RESBUF. The result is 201/* 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 202 always in little endian byte order, so that a byte-wise output yields
@@ -205,63 +204,64 @@ static void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
205 204
206 IMPORTANT: On some systems it is required that RESBUF is correctly 205 IMPORTANT: On some systems it is required that RESBUF is correctly
207 aligned for a 32 bits value. */ 206 aligned for a 32 bits value. */
208 ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A); 207 ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
209 ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B); 208 ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
210 ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C); 209 ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
211 ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D); 210 ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
212 211
213 return resbuf; 212 return resbuf;
214} 213}
215 214
216/* Compute MD5 message digest for bytes read from STREAM. The 215/* Compute MD5 message digest for bytes read from STREAM. The
217 resulting message digest number will be written into the 16 bytes 216 resulting message digest number will be written into the 16 bytes
218 beginning at RESBLOCK. */ 217 beginning at RESBLOCK. */
219static int md5_stream(FILE *stream, void *resblock) 218static int md5_stream(FILE * stream, void *resblock)
220{ 219{
221 /* Important: BLOCKSIZE must be a multiple of 64. */ 220 /* Important: BLOCKSIZE must be a multiple of 64. */
222static const int BLOCKSIZE = 4096; 221 static const int BLOCKSIZE = 4096;
223 struct md5_ctx ctx; 222 struct md5_ctx ctx;
224 char buffer[BLOCKSIZE + 72]; 223 char buffer[BLOCKSIZE + 72];
225 size_t sum; 224 size_t sum;
226 225
227 /* Initialize the computation context. */ 226 /* Initialize the computation context. */
228 md5_init_ctx(&ctx); 227 md5_init_ctx(&ctx);
229 228
230 /* Iterate over full file contents. */ 229 /* Iterate over full file contents. */
231 while (1) { 230 while (1) {
232 /* We read the file in blocks of BLOCKSIZE bytes. One call of the 231 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
233 computation function processes the whole buffer so that with the 232 computation function processes the whole buffer so that with the
234 next round of the loop another block can be read. */ 233 next round of the loop another block can be read. */
235 size_t n; 234 size_t n;
236 sum = 0; 235
237 236 sum = 0;
238 /* Read block. Take care for partial reads. */ 237
239 do { 238 /* Read block. Take care for partial reads. */
240 n = fread(buffer + sum, 1, BLOCKSIZE - sum, stream); 239 do {
241 240 n = fread(buffer + sum, 1, BLOCKSIZE - sum, stream);
242 sum += n; 241
243 } 242 sum += n;
244 while (sum < BLOCKSIZE && n != 0); 243 }
245 if (n == 0 && ferror(stream)) 244 while (sum < BLOCKSIZE && n != 0);
246 return 1; 245 if (n == 0 && ferror(stream))
247 246 return 1;
248 /* If end of file is reached, end the loop. */ 247
249 if (n == 0) 248 /* If end of file is reached, end the loop. */
250 break; 249 if (n == 0)
251 250 break;
252 /* Process buffer with BLOCKSIZE bytes. Note that 251
253 BLOCKSIZE % 64 == 0 252 /* Process buffer with BLOCKSIZE bytes. Note that
254 */ 253 BLOCKSIZE % 64 == 0
255 md5_process_block(buffer, BLOCKSIZE, &ctx); 254 */
256 } 255 md5_process_block(buffer, BLOCKSIZE, &ctx);
257 256 }
258 /* Add the last bytes if necessary. */ 257
259 if (sum > 0) 258 /* Add the last bytes if necessary. */
260 md5_process_bytes(buffer, sum, &ctx); 259 if (sum > 0)
261 260 md5_process_bytes(buffer, sum, &ctx);
262 /* Construct result in desired memory. */ 261
263 md5_finish_ctx(&ctx, resblock); 262 /* Construct result in desired memory. */
264 return 0; 263 md5_finish_ctx(&ctx, resblock);
264 return 0;
265} 265}
266 266
267/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The 267/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
@@ -270,53 +270,54 @@ static const int BLOCKSIZE = 4096;
270 digest. */ 270 digest. */
271static void *md5_buffer(const char *buffer, size_t len, void *resblock) 271static void *md5_buffer(const char *buffer, size_t len, void *resblock)
272{ 272{
273 struct md5_ctx ctx; 273 struct md5_ctx ctx;
274 274
275 /* Initialize the computation context. */ 275 /* Initialize the computation context. */
276 md5_init_ctx(&ctx); 276 md5_init_ctx(&ctx);
277 277
278 /* Process whole buffer but last len % 64 bytes. */ 278 /* Process whole buffer but last len % 64 bytes. */
279 md5_process_bytes(buffer, len, &ctx); 279 md5_process_bytes(buffer, len, &ctx);
280 280
281 /* Put result in desired memory area. */ 281 /* Put result in desired memory area. */
282 return md5_finish_ctx(&ctx, resblock); 282 return md5_finish_ctx(&ctx, resblock);
283} 283}
284 284
285static void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx) 285static void md5_process_bytes(const void *buffer, size_t len,
286 struct md5_ctx *ctx)
286{ 287{
287 /* When we already have some bits in our internal buffer concatenate 288 /* When we already have some bits in our internal buffer concatenate
288 both inputs first. */ 289 both inputs first. */
289 if (ctx->buflen != 0) { 290 if (ctx->buflen != 0) {
290 size_t left_over = ctx->buflen; 291 size_t left_over = ctx->buflen;
291 size_t add = 128 - left_over > len ? len : 128 - left_over; 292 size_t add = 128 - left_over > len ? len : 128 - left_over;
292 293
293 memcpy(&ctx->buffer[left_over], buffer, add); 294 memcpy(&ctx->buffer[left_over], buffer, add);
294 ctx->buflen += add; 295 ctx->buflen += add;
295 296
296 if (left_over + add > 64) { 297 if (left_over + add > 64) {
297 md5_process_block(ctx->buffer, (left_over + add) & ~63, ctx); 298 md5_process_block(ctx->buffer, (left_over + add) & ~63, ctx);
298 /* The regions in the following copy operation cannot overlap. */ 299 /* The regions in the following copy operation cannot overlap. */
299 memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63], 300 memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
300 (left_over + add) & 63); 301 (left_over + add) & 63);
301 ctx->buflen = (left_over + add) & 63; 302 ctx->buflen = (left_over + add) & 63;
302 } 303 }
303 304
304 buffer = (const char *) buffer + add; 305 buffer = (const char *) buffer + add;
305 len -= add; 306 len -= add;
306 } 307 }
307 308
308 /* Process available complete blocks. */ 309 /* Process available complete blocks. */
309 if (len > 64) { 310 if (len > 64) {
310 md5_process_block(buffer, len & ~63, ctx); 311 md5_process_block(buffer, len & ~63, ctx);
311 buffer = (const char *) buffer + (len & ~63); 312 buffer = (const char *) buffer + (len & ~63);
312 len &= 63; 313 len &= 63;
313 } 314 }
314 315
315 /* Move remaining bytes in internal buffer. */ 316 /* Move remaining bytes in internal buffer. */
316 if (len > 0) { 317 if (len > 0) {
317 memcpy(ctx->buffer, buffer, len); 318 memcpy(ctx->buffer, buffer, len);
318 ctx->buflen = len; 319 ctx->buflen = len;
319 } 320 }
320} 321}
321 322
322/* These are the four functions used in the four steps of the MD5 algorithm 323/* These are the four functions used in the four steps of the MD5 algorithm
@@ -330,154 +331,176 @@ static void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ct
330 331
331/* Process LEN bytes of BUFFER, accumulating context into CTX. 332/* Process LEN bytes of BUFFER, accumulating context into CTX.
332 It is assumed that LEN % 64 == 0. */ 333 It is assumed that LEN % 64 == 0. */
333static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx) 334static void md5_process_block(const void *buffer, size_t len,
335 struct md5_ctx *ctx)
334{ 336{
335 md5_uint32 correct_words[16]; 337 md5_uint32 correct_words[16];
336 const md5_uint32 *words = buffer; 338 const md5_uint32 *words = buffer;
337 size_t nwords = len / sizeof(md5_uint32); 339 size_t nwords = len / sizeof(md5_uint32);
338 const md5_uint32 *endp = words + nwords; 340 const md5_uint32 *endp = words + nwords;
341
339#if MD5SUM_SIZE_VS_SPEED > 0 342#if MD5SUM_SIZE_VS_SPEED > 0
340 static const md5_uint32 C_array[] = { 343 static const md5_uint32 C_array[] = {
341 /* round 1 */ 344 /* round 1 */
342 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 345 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
343 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 346 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
344 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 347 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
345 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 348 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
346 /* round 2 */ 349 /* round 2 */
347 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 350 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
348 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, 351 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
349 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 352 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
350 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 353 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
351 /* round 3 */ 354 /* round 3 */
352 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 355 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
353 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 356 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
354 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 357 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
355 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 358 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
356 /* round 4 */ 359 /* round 4 */
357 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 360 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
358 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 361 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
359 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 362 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
360 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 363 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
361 }; 364 };
362 365
363 static const char P_array[] = { 366 static const char P_array[] = {
364#if MD5SUM_SIZE_VS_SPEED > 1 367#if MD5SUM_SIZE_VS_SPEED > 1
365 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ 368 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
366#endif 369#endif
367 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ 370 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
368 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ 371 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
369 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ 372 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */
370 }; 373 };
371 374
372#if MD5SUM_SIZE_VS_SPEED > 1 375#if MD5SUM_SIZE_VS_SPEED > 1
373 static const char S_array[] = { 376 static const char S_array[] = {
374 7, 12, 17, 22, 377 7, 12, 17, 22,
375 5, 9, 14, 20, 378 5, 9, 14, 20,
376 4, 11, 16, 23, 379 4, 11, 16, 23,
377 6, 10, 15, 21 380 6, 10, 15, 21
378 }; 381 };
379#endif 382#endif
380#endif 383#endif
381 384
382 md5_uint32 A = ctx->A; 385 md5_uint32 A = ctx->A;
383 md5_uint32 B = ctx->B; 386 md5_uint32 B = ctx->B;
384 md5_uint32 C = ctx->C; 387 md5_uint32 C = ctx->C;
385 md5_uint32 D = ctx->D; 388 md5_uint32 D = ctx->D;
386 389
387 /* First increment the byte count. RFC 1321 specifies the possible 390 /* First increment the byte count. RFC 1321 specifies the possible
388 length of the file up to 2^64 bits. Here we only compute the 391 length of the file up to 2^64 bits. Here we only compute the
389 number of bytes. Do a double word increment. */ 392 number of bytes. Do a double word increment. */
390 ctx->total[0] += len; 393 ctx->total[0] += len;
391 if (ctx->total[0] < len) 394 if (ctx->total[0] < len)
392 ++ctx->total[1]; 395 ++ctx->total[1];
393 396
394 /* Process all bytes in the buffer with 64 bytes in each round of 397 /* Process all bytes in the buffer with 64 bytes in each round of
395 the loop. */ 398 the loop. */
396 while (words < endp) { 399 while (words < endp) {
397 md5_uint32 *cwp = correct_words; 400 md5_uint32 *cwp = correct_words;
398 md5_uint32 A_save = A; 401 md5_uint32 A_save = A;
399 md5_uint32 B_save = B; 402 md5_uint32 B_save = B;
400 md5_uint32 C_save = C; 403 md5_uint32 C_save = C;
401 md5_uint32 D_save = D; 404 md5_uint32 D_save = D;
402 405
403#if MD5SUM_SIZE_VS_SPEED > 1 406#if MD5SUM_SIZE_VS_SPEED > 1
404#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) 407#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
405 408
406 const md5_uint32 *pc; 409 const md5_uint32 *pc;
407 const char *pp; 410 const char *pp;
408 const char *ps; 411 const char *ps;
409 int i; 412 int i;
410 md5_uint32 temp; 413 md5_uint32 temp;
411 414
412 for ( i=0 ; i < 16 ; i++ ) { 415 for (i = 0; i < 16; i++) {
413 cwp[i] = SWAP(words[i]); 416 cwp[i] = SWAP(words[i]);
414 } 417 }
415 words += 16; 418 words += 16;
416 419
417#if MD5SUM_SIZE_VS_SPEED > 2 420#if MD5SUM_SIZE_VS_SPEED > 2
418 pc = C_array; pp = P_array; ps = S_array - 4; 421 pc = C_array;
419 422 pp = P_array;
420 for ( i = 0 ; i < 64 ; i++ ) { 423 ps = S_array - 4;
421 if ((i&0x0f) == 0) ps += 4; 424
422 temp = A; 425 for (i = 0; i < 64; i++) {
423 switch (i>>4) { 426 if ((i & 0x0f) == 0)
424 case 0: 427 ps += 4;
425 temp += FF(B,C,D); 428 temp = A;
426 break; 429 switch (i >> 4) {
427 case 1: 430 case 0:
428 temp += FG(B,C,D); 431 temp += FF(B, C, D);
429 break; 432 break;
430 case 2: 433 case 1:
431 temp += FH(B,C,D); 434 temp += FG(B, C, D);
432 break; 435 break;
433 case 3: 436 case 2:
434 temp += FI(B,C,D); 437 temp += FH(B, C, D);
435 } 438 break;
436 temp += cwp[(int)(*pp++)] + *pc++; 439 case 3:
437 CYCLIC (temp, ps[i&3]); 440 temp += FI(B, C, D);
438 temp += B; 441 }
439 A = D; D = C; C = B; B = temp; 442 temp += cwp[(int) (*pp++)] + *pc++;
440 } 443 CYCLIC(temp, ps[i & 3]);
444 temp += B;
445 A = D;
446 D = C;
447 C = B;
448 B = temp;
449 }
441#else 450#else
442 pc = C_array; pp = P_array; ps = S_array; 451 pc = C_array;
443 452 pp = P_array;
444 for ( i = 0 ; i < 16 ; i++ ) { 453 ps = S_array;
445 temp = A + FF(B,C,D) + cwp[(int)(*pp++)] + *pc++; 454
446 CYCLIC (temp, ps[i&3]); 455 for (i = 0; i < 16; i++) {
447 temp += B; 456 temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++;
448 A = D; D = C; C = B; B = temp; 457 CYCLIC(temp, ps[i & 3]);
449 } 458 temp += B;
450 459 A = D;
451 ps += 4; 460 D = C;
452 for ( i = 0 ; i < 16 ; i++ ) { 461 C = B;
453 temp = A + FG(B,C,D) + cwp[(int)(*pp++)] + *pc++; 462 B = temp;
454 CYCLIC (temp, ps[i&3]); 463 }
455 temp += B; 464
456 A = D; D = C; C = B; B = temp; 465 ps += 4;
457 } 466 for (i = 0; i < 16; i++) {
458 ps += 4; 467 temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++;
459 for ( i = 0 ; i < 16 ; i++ ) { 468 CYCLIC(temp, ps[i & 3]);
460 temp = A + FH(B,C,D) + cwp[(int)(*pp++)] + *pc++; 469 temp += B;
461 CYCLIC (temp, ps[i&3]); 470 A = D;
462 temp += B; 471 D = C;
463 A = D; D = C; C = B; B = temp; 472 C = B;
464 } 473 B = temp;
465 ps += 4; 474 }
466 for ( i = 0 ; i < 16 ; i++ ) { 475 ps += 4;
467 temp = A + FI(B,C,D) + cwp[(int)(*pp++)] + *pc++; 476 for (i = 0; i < 16; i++) {
468 CYCLIC (temp, ps[i&3]); 477 temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++;
469 temp += B; 478 CYCLIC(temp, ps[i & 3]);
470 A = D; D = C; C = B; B = temp; 479 temp += B;
471 } 480 A = D;
481 D = C;
482 C = B;
483 B = temp;
484 }
485 ps += 4;
486 for (i = 0; i < 16; i++) {
487 temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++;
488 CYCLIC(temp, ps[i & 3]);
489 temp += B;
490 A = D;
491 D = C;
492 C = B;
493 B = temp;
494 }
472 495
473#endif 496#endif
474#else 497#else
475 /* First round: using the given function, the context and a constant 498 /* First round: using the given function, the context and a constant
476 the next context is computed. Because the algorithms processing 499 the next context is computed. Because the algorithms processing
477 unit is a 32-bit word and it is determined to work on words in 500 unit is a 32-bit word and it is determined to work on words in
478 little endian byte order we perhaps have to change the byte order 501 little endian byte order we perhaps have to change the byte order
479 before the computation. To reduce the work for the next steps 502 before the computation. To reduce the work for the next steps
480 we store the swapped words in the array CORRECT_WORDS. */ 503 we store the swapped words in the array CORRECT_WORDS. */
481 504
482#define OP(a, b, c, d, s, T) \ 505#define OP(a, b, c, d, s, T) \
483 do \ 506 do \
@@ -489,54 +512,54 @@ static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ct
489 } \ 512 } \
490 while (0) 513 while (0)
491 514
492 /* It is unfortunate that C does not provide an operator for 515 /* It is unfortunate that C does not provide an operator for
493 cyclic rotation. Hope the C compiler is smart enough. */ 516 cyclic rotation. Hope the C compiler is smart enough. */
494 /* gcc 2.95.4 seems to be --aaronl */ 517 /* gcc 2.95.4 seems to be --aaronl */
495#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) 518#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
496 519
497 /* Before we start, one word to the strange constants. 520 /* Before we start, one word to the strange constants.
498 They are defined in RFC 1321 as 521 They are defined in RFC 1321 as
499 522
500 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 523 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
501 */ 524 */
502 525
503#if MD5SUM_SIZE_VS_SPEED == 1 526#if MD5SUM_SIZE_VS_SPEED == 1
504 const md5_uint32 *pc; 527 const md5_uint32 *pc;
505 const char *pp; 528 const char *pp;
506 int i; 529 int i;
507#endif 530#endif
508 531
509 /* Round 1. */ 532 /* Round 1. */
510#if MD5SUM_SIZE_VS_SPEED == 1 533#if MD5SUM_SIZE_VS_SPEED == 1
511 pc = C_array; 534 pc = C_array;
512 for ( i=0 ; i < 4 ; i++ ) { 535 for (i = 0; i < 4; i++) {
513 OP(A, B, C, D, 7, *pc++); 536 OP(A, B, C, D, 7, *pc++);
514 OP(D, A, B, C, 12, *pc++); 537 OP(D, A, B, C, 12, *pc++);
515 OP(C, D, A, B, 17, *pc++); 538 OP(C, D, A, B, 17, *pc++);
516 OP(B, C, D, A, 22, *pc++); 539 OP(B, C, D, A, 22, *pc++);
517 } 540 }
518#else 541#else
519 OP(A, B, C, D, 7, 0xd76aa478); 542 OP(A, B, C, D, 7, 0xd76aa478);
520 OP(D, A, B, C, 12, 0xe8c7b756); 543 OP(D, A, B, C, 12, 0xe8c7b756);
521 OP(C, D, A, B, 17, 0x242070db); 544 OP(C, D, A, B, 17, 0x242070db);
522 OP(B, C, D, A, 22, 0xc1bdceee); 545 OP(B, C, D, A, 22, 0xc1bdceee);
523 OP(A, B, C, D, 7, 0xf57c0faf); 546 OP(A, B, C, D, 7, 0xf57c0faf);
524 OP(D, A, B, C, 12, 0x4787c62a); 547 OP(D, A, B, C, 12, 0x4787c62a);
525 OP(C, D, A, B, 17, 0xa8304613); 548 OP(C, D, A, B, 17, 0xa8304613);
526 OP(B, C, D, A, 22, 0xfd469501); 549 OP(B, C, D, A, 22, 0xfd469501);
527 OP(A, B, C, D, 7, 0x698098d8); 550 OP(A, B, C, D, 7, 0x698098d8);
528 OP(D, A, B, C, 12, 0x8b44f7af); 551 OP(D, A, B, C, 12, 0x8b44f7af);
529 OP(C, D, A, B, 17, 0xffff5bb1); 552 OP(C, D, A, B, 17, 0xffff5bb1);
530 OP(B, C, D, A, 22, 0x895cd7be); 553 OP(B, C, D, A, 22, 0x895cd7be);
531 OP(A, B, C, D, 7, 0x6b901122); 554 OP(A, B, C, D, 7, 0x6b901122);
532 OP(D, A, B, C, 12, 0xfd987193); 555 OP(D, A, B, C, 12, 0xfd987193);
533 OP(C, D, A, B, 17, 0xa679438e); 556 OP(C, D, A, B, 17, 0xa679438e);
534 OP(B, C, D, A, 22, 0x49b40821); 557 OP(B, C, D, A, 22, 0x49b40821);
535#endif 558#endif
536 559
537 /* For the second to fourth round we have the possibly swapped words 560 /* For the second to fourth round we have the possibly swapped words
538 in CORRECT_WORDS. Redefine the macro to take an additional first 561 in CORRECT_WORDS. Redefine the macro to take an additional first
539 argument specifying the function to use. */ 562 argument specifying the function to use. */
540#undef OP 563#undef OP
541#define OP(f, a, b, c, d, k, s, T) \ 564#define OP(f, a, b, c, d, k, s, T) \
542 do \ 565 do \
@@ -547,101 +570,101 @@ static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ct
547 } \ 570 } \
548 while (0) 571 while (0)
549 572
550 /* Round 2. */ 573 /* Round 2. */
551#if MD5SUM_SIZE_VS_SPEED == 1 574#if MD5SUM_SIZE_VS_SPEED == 1
552 pp = P_array; 575 pp = P_array;
553 for ( i=0 ; i < 4 ; i++ ) { 576 for (i = 0; i < 4; i++) {
554 OP(FG, A, B, C, D, (int)(*pp++), 5, *pc++); 577 OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++);
555 OP(FG, D, A, B, C, (int)(*pp++), 9, *pc++); 578 OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++);
556 OP(FG, C, D, A, B, (int)(*pp++), 14, *pc++); 579 OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++);
557 OP(FG, B, C, D, A, (int)(*pp++), 20, *pc++); 580 OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++);
558 } 581 }
559#else 582#else
560 OP(FG, A, B, C, D, 1, 5, 0xf61e2562); 583 OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
561 OP(FG, D, A, B, C, 6, 9, 0xc040b340); 584 OP(FG, D, A, B, C, 6, 9, 0xc040b340);
562 OP(FG, C, D, A, B, 11, 14, 0x265e5a51); 585 OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
563 OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); 586 OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
564 OP(FG, A, B, C, D, 5, 5, 0xd62f105d); 587 OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
565 OP(FG, D, A, B, C, 10, 9, 0x02441453); 588 OP(FG, D, A, B, C, 10, 9, 0x02441453);
566 OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); 589 OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
567 OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); 590 OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
568 OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); 591 OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
569 OP(FG, D, A, B, C, 14, 9, 0xc33707d6); 592 OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
570 OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); 593 OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
571 OP(FG, B, C, D, A, 8, 20, 0x455a14ed); 594 OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
572 OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); 595 OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
573 OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); 596 OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
574 OP(FG, C, D, A, B, 7, 14, 0x676f02d9); 597 OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
575 OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); 598 OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
576#endif 599#endif
577 600
578 /* Round 3. */ 601 /* Round 3. */
579#if MD5SUM_SIZE_VS_SPEED == 1 602#if MD5SUM_SIZE_VS_SPEED == 1
580 for ( i=0 ; i < 4 ; i++ ) { 603 for (i = 0; i < 4; i++) {
581 OP(FH, A, B, C, D, (int)(*pp++), 4, *pc++); 604 OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++);
582 OP(FH, D, A, B, C, (int)(*pp++), 11, *pc++); 605 OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++);
583 OP(FH, C, D, A, B, (int)(*pp++), 16, *pc++); 606 OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++);
584 OP(FH, B, C, D, A, (int)(*pp++), 23, *pc++); 607 OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++);
585 } 608 }
586#else 609#else
587 OP(FH, A, B, C, D, 5, 4, 0xfffa3942); 610 OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
588 OP(FH, D, A, B, C, 8, 11, 0x8771f681); 611 OP(FH, D, A, B, C, 8, 11, 0x8771f681);
589 OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); 612 OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
590 OP(FH, B, C, D, A, 14, 23, 0xfde5380c); 613 OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
591 OP(FH, A, B, C, D, 1, 4, 0xa4beea44); 614 OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
592 OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); 615 OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
593 OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); 616 OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
594 OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); 617 OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
595 OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); 618 OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
596 OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); 619 OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
597 OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); 620 OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
598 OP(FH, B, C, D, A, 6, 23, 0x04881d05); 621 OP(FH, B, C, D, A, 6, 23, 0x04881d05);
599 OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); 622 OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
600 OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); 623 OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
601 OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); 624 OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
602 OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); 625 OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
603#endif 626#endif
604 627
605 /* Round 4. */ 628 /* Round 4. */
606#if MD5SUM_SIZE_VS_SPEED == 1 629#if MD5SUM_SIZE_VS_SPEED == 1
607 for ( i=0 ; i < 4 ; i++ ) { 630 for (i = 0; i < 4; i++) {
608 OP(FI, A, B, C, D, (int)(*pp++), 6, *pc++); 631 OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++);
609 OP(FI, D, A, B, C, (int)(*pp++), 10, *pc++); 632 OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++);
610 OP(FI, C, D, A, B, (int)(*pp++), 15, *pc++); 633 OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++);
611 OP(FI, B, C, D, A, (int)(*pp++), 21, *pc++); 634 OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++);
612 } 635 }
613#else 636#else
614 OP(FI, A, B, C, D, 0, 6, 0xf4292244); 637 OP(FI, A, B, C, D, 0, 6, 0xf4292244);
615 OP(FI, D, A, B, C, 7, 10, 0x432aff97); 638 OP(FI, D, A, B, C, 7, 10, 0x432aff97);
616 OP(FI, C, D, A, B, 14, 15, 0xab9423a7); 639 OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
617 OP(FI, B, C, D, A, 5, 21, 0xfc93a039); 640 OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
618 OP(FI, A, B, C, D, 12, 6, 0x655b59c3); 641 OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
619 OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); 642 OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
620 OP(FI, C, D, A, B, 10, 15, 0xffeff47d); 643 OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
621 OP(FI, B, C, D, A, 1, 21, 0x85845dd1); 644 OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
622 OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); 645 OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
623 OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); 646 OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
624 OP(FI, C, D, A, B, 6, 15, 0xa3014314); 647 OP(FI, C, D, A, B, 6, 15, 0xa3014314);
625 OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); 648 OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
626 OP(FI, A, B, C, D, 4, 6, 0xf7537e82); 649 OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
627 OP(FI, D, A, B, C, 11, 10, 0xbd3af235); 650 OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
628 OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); 651 OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
629 OP(FI, B, C, D, A, 9, 21, 0xeb86d391); 652 OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
630#endif 653#endif
631#endif 654#endif
632 655
633 /* Add the starting values of the context. */ 656 /* Add the starting values of the context. */
634 A += A_save; 657 A += A_save;
635 B += B_save; 658 B += B_save;
636 C += C_save; 659 C += C_save;
637 D += D_save; 660 D += D_save;
638 } 661 }
639 662
640 /* Put checksum in context given as argument. */ 663 /* Put checksum in context given as argument. */
641 ctx->A = A; 664 ctx->A = A;
642 ctx->B = B; 665 ctx->B = B;
643 ctx->C = C; 666 ctx->C = C;
644 ctx->D = D; 667 ctx->D = D;
645} 668}
646 669
647//---------------------------------------------------------------------------- 670//----------------------------------------------------------------------------
@@ -654,421 +677,426 @@ static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ct
654/* The minimum length of a valid digest line in a file produced 677/* The minimum length of a valid digest line in a file produced
655 by `md5sum FILE' and read by `md5sum -c'. This length does 678 by `md5sum FILE' and read by `md5sum -c'. This length does
656 not include any newline character at the end of a line. */ 679 not include any newline character at the end of a line. */
657static const int MIN_DIGEST_LINE_LENGTH = 35; /* 32 - message digest length 680static const int MIN_DIGEST_LINE_LENGTH = 35; /* 32 - message digest length
658 2 - blank and binary indicator 681 2 - blank and binary indicator
659 1 - minimum filename length */ 682 1 - minimum filename length */
660 683
661static int have_read_stdin; /* Nonzero if any of the files read were 684static int have_read_stdin; /* Nonzero if any of the files read were
662 the standard input. */ 685 the standard input. */
663 686
664static int status_only = 0; /* With -c, don't generate any output. 687static int status_only = 0; /* With -c, don't generate any output.
665 The exit code indicates success or failure */ 688 The exit code indicates success or failure */
666static int warn = 0; /* With -w, print a message to standard error warning 689static int warn = 0; /* With -w, print a message to standard error warning
667 about each improperly formatted MD5 checksum line */ 690 about each improperly formatted MD5 checksum line */
668 691
669static int split_3(char *s, 692static int split_3(char *s, size_t s_len, unsigned char **u, char **w)
670 size_t s_len,
671 unsigned char **u,
672 char **w)
673{ 693{
674 size_t i = 0; 694 size_t i = 0;
675 int escaped_filename = 0; 695 int escaped_filename = 0;
676 696
677 while (ISWHITE(s[i])) 697 while (ISWHITE(s[i]))
678 ++i; 698 ++i;
679 699
680 /* The line must have at least 35 (36 if the first is a backslash) 700 /* The line must have at least 35 (36 if the first is a backslash)
681 more characters to contain correct message digest information. 701 more characters to contain correct message digest information.
682 Ignore this line if it is too short. */ 702 Ignore this line if it is too short. */
683 if (!(s_len - i >= MIN_DIGEST_LINE_LENGTH 703 if (!(s_len - i >= MIN_DIGEST_LINE_LENGTH
684 || (s[i] == '\\' && s_len - i >= 1 + MIN_DIGEST_LINE_LENGTH))) 704 || (s[i] == '\\' && s_len - i >= 1 + MIN_DIGEST_LINE_LENGTH)))
685 return FALSE; 705 return FALSE;
686 706
687 if (s[i] == '\\') { 707 if (s[i] == '\\') {
688 ++i; 708 ++i;
689 escaped_filename = 1; 709 escaped_filename = 1;
690 } 710 }
691 *u = (unsigned char *) &s[i]; 711 *u = (unsigned char *) &s[i];
692 712
693 /* The first field has to be the 32-character hexadecimal 713 /* The first field has to be the 32-character hexadecimal
694 representation of the message digest. If it is not followed 714 representation of the message digest. If it is not followed
695 immediately by a white space it's an error. */ 715 immediately by a white space it's an error. */
696 i += 32; 716 i += 32;
697 if (!ISWHITE(s[i])) 717 if (!ISWHITE(s[i]))
698 return FALSE; 718 return FALSE;
699 719
700 s[i++] = '\0'; 720 s[i++] = '\0';
701 721
702 if (s[i] != ' ' && s[i] != '*') 722 if (s[i] != ' ' && s[i] != '*')
703 return FALSE; 723 return FALSE;
704 724
705 /* All characters between the type indicator and end of line are 725 /* All characters between the type indicator and end of line are
706 significant -- that includes leading and trailing white space. */ 726 significant -- that includes leading and trailing white space. */
707 *w = &s[++i]; 727 *w = &s[++i];
708 728
709 if (escaped_filename) { 729 if (escaped_filename) {
710 /* Translate each `\n' string in the file name to a NEWLINE, 730 /* Translate each `\n' string in the file name to a NEWLINE,
711 and each `\\' string to a backslash. */ 731 and each `\\' string to a backslash. */
712 732
713 char *dst = &s[i]; 733 char *dst = &s[i];
714 734
715 while (i < s_len) { 735 while (i < s_len) {
716 switch (s[i]) { 736 switch (s[i]) {
717 case '\\': 737 case '\\':
718 if (i == s_len - 1) { 738 if (i == s_len - 1) {
719 /* A valid line does not end with a backslash. */ 739 /* A valid line does not end with a backslash. */
720 return FALSE; 740 return FALSE;
721 } 741 }
722 ++i; 742 ++i;
723 switch (s[i++]) { 743 switch (s[i++]) {
724 case 'n': 744 case 'n':
725 *dst++ = '\n'; 745 *dst++ = '\n';
726 break; 746 break;
727 case '\\': 747 case '\\':
728 *dst++ = '\\'; 748 *dst++ = '\\';
729 break; 749 break;
730 default: 750 default:
731 /* Only `\' or `n' may follow a backslash. */ 751 /* Only `\' or `n' may follow a backslash. */
732 return FALSE; 752 return FALSE;
733 } 753 }
734 break; 754 break;
735 755
736 case '\0': 756 case '\0':
737 /* The file name may not contain a NUL. */ 757 /* The file name may not contain a NUL. */
738 return FALSE; 758 return FALSE;
739 break; 759 break;
740 760
741 default: 761 default:
742 *dst++ = s[i++]; 762 *dst++ = s[i++];
743 break; 763 break;
744 } 764 }
745 } 765 }
746 *dst = '\0'; 766 *dst = '\0';
747 } 767 }
748 return TRUE; 768 return TRUE;
749} 769}
750 770
751static inline int hex_digits(unsigned char const *s) 771static inline int hex_digits(unsigned char const *s)
752{ 772{
753 while (*s) { 773 while (*s) {
754 if (!ISXDIGIT(*s)) 774 if (!ISXDIGIT(*s))
755 return TRUE; 775 return TRUE;
756 ++s; 776 ++s;
757 } 777 }
758 return FALSE; 778 return FALSE;
759} 779}
760 780
761/* An interface to md5_stream. Operate on FILENAME (it may be "-") and 781/* An interface to md5_stream. Operate on FILENAME (it may be "-") and
762 put the result in *MD5_RESULT. Return non-zero upon failure, zero 782 put the result in *MD5_RESULT. Return non-zero upon failure, zero
763 to indicate success. */ 783 to indicate success. */
764static int md5_file(const char *filename, 784static int md5_file(const char *filename, unsigned char *md5_result)
765 unsigned char *md5_result)
766{ 785{
767 FILE *fp; 786 FILE *fp;
768 787
769 if (filename[0] == '-' && filename[1] == '\0') { 788 if (filename[0] == '-' && filename[1] == '\0') {
770 have_read_stdin = 1; 789 have_read_stdin = 1;
771 fp = stdin; 790 fp = stdin;
772 } else { 791 } else {
773 fp = bb_wfopen(filename, "r"); 792 fp = bb_wfopen(filename, "r");
774 if (fp == NULL) 793 if (fp == NULL)
775 return FALSE; 794 return FALSE;
776 } 795 }
777 796
778 if (md5_stream(fp, md5_result)) { 797 if (md5_stream(fp, md5_result)) {
779 bb_perror_msg("%s", filename); 798 bb_perror_msg("%s", filename);
780 799
781 if (fp != stdin) 800 if (fp != stdin)
782 fclose(fp); 801 fclose(fp);
783 return FALSE; 802 return FALSE;
784 } 803 }
785 804
786 if (fp != stdin && fclose(fp) == EOF) { 805 if (fp != stdin && fclose(fp) == EOF) {
787 bb_perror_msg("%s", filename); 806 bb_perror_msg("%s", filename);
788 return FALSE; 807 return FALSE;
789 } 808 }
790 809
791 return TRUE; 810 return TRUE;
792} 811}
793 812
794static int md5_check(const char *checkfile_name) 813static int md5_check(const char *checkfile_name)
795{ 814{
796 FILE *checkfile_stream; 815 FILE *checkfile_stream;
797 int n_properly_formated_lines = 0; 816 int n_properly_formated_lines = 0;
798 int n_mismatched_checksums = 0; 817 int n_mismatched_checksums = 0;
799 int n_open_or_read_failures = 0; 818 int n_open_or_read_failures = 0;
800 unsigned char md5buffer[16]; 819 unsigned char md5buffer[16];
801 size_t line_number; 820 size_t line_number;
802 char line[BUFSIZ]; 821 char line[BUFSIZ];
803 822
804 if (checkfile_name[0] == '-' && checkfile_name[1] == '\0') { 823 if (checkfile_name[0] == '-' && checkfile_name[1] == '\0') {
805 have_read_stdin = 1; 824 have_read_stdin = 1;
806 checkfile_stream = stdin; 825 checkfile_stream = stdin;
807 } else { 826 } else {
808 checkfile_stream = bb_wfopen(checkfile_name, "r"); 827 checkfile_stream = bb_wfopen(checkfile_name, "r");
809 if (checkfile_stream == NULL) 828 if (checkfile_stream == NULL)
810 return FALSE; 829 return FALSE;
811 } 830 }
812 831
813 line_number = 0; 832 line_number = 0;
814 833
815 do { 834 do {
816 char *filename; 835 char *filename;
817 unsigned char *md5num; 836 unsigned char *md5num;
818 int line_length; 837 int line_length;
819 838
820 ++line_number; 839 ++line_number;
821 840
822 fgets(line, BUFSIZ-1, checkfile_stream); 841 fgets(line, BUFSIZ - 1, checkfile_stream);
823 line_length = strlen(line); 842 line_length = strlen(line);
824 843
825 if (line_length <= 0 || line==NULL) 844 if (line_length <= 0 || line == NULL)
826 break; 845 break;
827 846
828 /* Ignore comment lines, which begin with a '#' character. */ 847 /* Ignore comment lines, which begin with a '#' character. */
829 if (line[0] == '#') 848 if (line[0] == '#')
830 continue; 849 continue;
831 850
832 /* Remove any trailing newline. */ 851 /* Remove any trailing newline. */
833 if (line[line_length - 1] == '\n') 852 if (line[line_length - 1] == '\n')
834 line[--line_length] = '\0'; 853 line[--line_length] = '\0';
835 854
836 if (split_3(line, line_length, &md5num, &filename) 855 if (split_3(line, line_length, &md5num, &filename)
837 || !hex_digits(md5num)) { 856 || !hex_digits(md5num)) {
838 if (warn) { 857 if (warn) {
839 bb_error_msg("%s: %lu: improperly formatted MD5 checksum line", 858 bb_error_msg
840 checkfile_name, (unsigned long) line_number); 859 ("%s: %lu: improperly formatted MD5 checksum line",
841 } 860 checkfile_name, (unsigned long) line_number);
842 } else { 861 }
843 static const char bin2hex[] = { 862 } else {
844 '0', '1', '2', '3', 863 static const char bin2hex[] = {
845 '4', '5', '6', '7', 864 '0', '1', '2', '3',
846 '8', '9', 'a', 'b', 865 '4', '5', '6', '7',
847 'c', 'd', 'e', 'f' 866 '8', '9', 'a', 'b',
848 }; 867 'c', 'd', 'e', 'f'
849 868 };
850 ++n_properly_formated_lines; 869
851 870 ++n_properly_formated_lines;
852 if (md5_file(filename, md5buffer)) { 871
853 ++n_open_or_read_failures; 872 if (md5_file(filename, md5buffer)) {
854 if (!status_only) { 873 ++n_open_or_read_failures;
855 printf("%s: FAILED open or read\n", filename); 874 if (!status_only) {
856 fflush(stdout); 875 printf("%s: FAILED open or read\n", filename);
857 } 876 fflush(stdout);
858 } else { 877 }
859 size_t cnt; 878 } else {
860 /* Compare generated binary number with text representation 879 size_t cnt;
861 in check file. Ignore case of hex digits. */ 880
862 for (cnt = 0; cnt < 16; ++cnt) { 881 /* Compare generated binary number with text representation
863 if (tolower(md5num[2 * cnt]) 882 in check file. Ignore case of hex digits. */
864 != bin2hex[md5buffer[cnt] >> 4] 883 for (cnt = 0; cnt < 16; ++cnt) {
865 || (tolower(md5num[2 * cnt + 1]) 884 if (tolower(md5num[2 * cnt])
866 != (bin2hex[md5buffer[cnt] & 0xf]))) 885 != bin2hex[md5buffer[cnt] >> 4]
867 break; 886 || (tolower(md5num[2 * cnt + 1])
868 } 887 != (bin2hex[md5buffer[cnt] & 0xf])))
869 if (cnt != 16) 888 break;
870 ++n_mismatched_checksums; 889 }
871 890 if (cnt != 16)
872 if (!status_only) { 891 ++n_mismatched_checksums;
873 printf("%s: %s\n", filename, 892
874 (cnt != 16 ? "FAILED" : "OK")); 893 if (!status_only) {
875 fflush(stdout); 894 printf("%s: %s\n", filename,
876 } 895 (cnt != 16 ? "FAILED" : "OK"));
877 } 896 fflush(stdout);
878 } 897 }
879 } 898 }
880 899 }
881 while (!feof(checkfile_stream) && !ferror(checkfile_stream)); 900 }
882 901
883 if (ferror(checkfile_stream)) { 902 while (!feof(checkfile_stream) && !ferror(checkfile_stream));
884 bb_error_msg("%s: read error", checkfile_name); 903
885 return FALSE; 904 if (ferror(checkfile_stream)) {
886 } 905 bb_error_msg("%s: read error", checkfile_name);
887 906 return FALSE;
888 if (checkfile_stream != stdin && fclose(checkfile_stream) == EOF) { 907 }
889 bb_perror_msg("md5sum: %s", checkfile_name); 908
890 return FALSE; 909 if (checkfile_stream != stdin && fclose(checkfile_stream) == EOF) {
891 } 910 bb_perror_msg("md5sum: %s", checkfile_name);
892 911 return FALSE;
893 if (n_properly_formated_lines == 0) { 912 }
894 /* Warn if no tests are found. */ 913
895 bb_error_msg("%s: no properly formatted MD5 checksum lines found", 914 if (n_properly_formated_lines == 0) {
896 checkfile_name); 915 /* Warn if no tests are found. */
897 return FALSE; 916 bb_error_msg("%s: no properly formatted MD5 checksum lines found",
898 } else { 917 checkfile_name);
899 if (!status_only) { 918 return FALSE;
900 int n_computed_checkums = (n_properly_formated_lines 919 } else {
901 - n_open_or_read_failures); 920 if (!status_only) {
902 921 int n_computed_checkums = (n_properly_formated_lines
903 if (n_open_or_read_failures > 0) { 922 - n_open_or_read_failures);
904 bb_error_msg("WARNING: %d of %d listed files could not be read", 923
905 n_open_or_read_failures, n_properly_formated_lines); 924 if (n_open_or_read_failures > 0) {
906 return FALSE; 925 bb_error_msg
907 } 926 ("WARNING: %d of %d listed files could not be read",
908 927 n_open_or_read_failures, n_properly_formated_lines);
909 if (n_mismatched_checksums > 0) { 928 return FALSE;
910 bb_error_msg("WARNING: %d of %d computed checksums did NOT match", 929 }
911 n_mismatched_checksums, n_computed_checkums); 930
912 return FALSE; 931 if (n_mismatched_checksums > 0) {
913 } 932 bb_error_msg
914 } 933 ("WARNING: %d of %d computed checksums did NOT match",
915 } 934 n_mismatched_checksums, n_computed_checkums);
916 935 return FALSE;
917 return ((n_properly_formated_lines > 0 && n_mismatched_checksums == 0 936 }
918 && n_open_or_read_failures == 0) ? 0 : 1); 937 }
938 }
939
940 return ((n_properly_formated_lines > 0 && n_mismatched_checksums == 0
941 && n_open_or_read_failures == 0) ? 0 : 1);
919} 942}
920 943
921int md5sum_main(int argc, 944int md5sum_main(int argc, char **argv)
922 char **argv)
923{ 945{
924 unsigned char md5buffer[16]; 946 unsigned char md5buffer[16];
925 int do_check = 0; 947 int do_check = 0;
926 int opt; 948 int opt;
927 char **string = NULL; 949 char **string = NULL;
928 size_t n_strings = 0; 950 size_t n_strings = 0;
929 size_t err = 0; 951 size_t err = 0;
930 char file_type_specified = 0; 952 char file_type_specified = 0;
931 char binary = 0; 953 char binary = 0;
932 954
933 while ((opt = getopt(argc, argv, "g:bcstw")) != -1) { 955 while ((opt = getopt(argc, argv, "g:bcstw")) != -1) {
934 switch (opt) { 956 switch (opt) {
935 case 'g': { /* read a string */ 957 case 'g':{ /* read a string */
936 if (string == NULL) 958 if (string == NULL)
937 string = (char **) xmalloc ((argc - 1) * sizeof (char *)); 959 string = (char **) xmalloc((argc - 1) * sizeof(char *));
938 960
939 string[n_strings++] = optarg; 961 string[n_strings++] = optarg;
940 break; 962 break;
941 } 963 }
942 964
943 case 'b': /* read files in binary mode */ 965 case 'b': /* read files in binary mode */
944 file_type_specified = 1; 966 file_type_specified = 1;
945 binary = 1; 967 binary = 1;
946 break; 968 break;
947 969
948 case 'c': /* check MD5 sums against given list */ 970 case 'c': /* check MD5 sums against given list */
949 do_check = 1; 971 do_check = 1;
950 break; 972 break;
951 973
952 case 's': /* don't output anything, status code shows success */ 974 case 's': /* don't output anything, status code shows success */
953 status_only = 1; 975 status_only = 1;
954 warn = 0; 976 warn = 0;
955 break; 977 break;
956 978
957 case 't': /* read files in text mode (default) */ 979 case 't': /* read files in text mode (default) */
958 file_type_specified = 1; 980 file_type_specified = 1;
959 binary = 0; 981 binary = 0;
960 break; 982 break;
961 983
962 case 'w': /* warn about improperly formated MD5 checksum lines */ 984 case 'w': /* warn about improperly formated MD5 checksum lines */
963 status_only = 0; 985 status_only = 0;
964 warn = 1; 986 warn = 1;
965 break; 987 break;
966 988
967 default: 989 default:
968 bb_show_usage(); 990 bb_show_usage();
969 } 991 }
970 } 992 }
971 993
972 if (file_type_specified && do_check) { 994 if (file_type_specified && do_check) {
973 bb_error_msg_and_die("the -b and -t options are meaningless when verifying checksums"); 995 bb_error_msg_and_die
974 } 996 ("the -b and -t options are meaningless when verifying checksums");
975 997 }
976 if (n_strings > 0 && do_check) { 998
977 bb_error_msg_and_die("the -g and -c options are mutually exclusive"); 999 if (n_strings > 0 && do_check) {
978 } 1000 bb_error_msg_and_die("the -g and -c options are mutually exclusive");
979 1001 }
980 if (status_only && !do_check) { 1002
981 bb_error_msg_and_die("the -s option is meaningful only when verifying checksums"); 1003 if (status_only && !do_check) {
982 } 1004 bb_error_msg_and_die
983 1005 ("the -s option is meaningful only when verifying checksums");
984 if (warn && !do_check) { 1006 }
985 bb_error_msg_and_die("the -w option is meaningful only when verifying checksums"); 1007
986 } 1008 if (warn && !do_check) {
987 1009 bb_error_msg_and_die
988 if (n_strings > 0) { 1010 ("the -w option is meaningful only when verifying checksums");
989 size_t i; 1011 }
990 1012
991 if (optind < argc) { 1013 if (n_strings > 0) {
992 bb_error_msg_and_die("no files may be specified when using -g"); 1014 size_t i;
993 } 1015
994 for (i = 0; i < n_strings; ++i) { 1016 if (optind < argc) {
995 size_t cnt; 1017 bb_error_msg_and_die("no files may be specified when using -g");
996 md5_buffer (string[i], strlen (string[i]), md5buffer); 1018 }
997 1019 for (i = 0; i < n_strings; ++i) {
998 for (cnt = 0; cnt < 16; ++cnt) 1020 size_t cnt;
999 printf ("%02x", md5buffer[cnt]); 1021
1000 1022 md5_buffer(string[i], strlen(string[i]), md5buffer);
1001 printf (" \"%s\"\n", string[i]); 1023
1002 } 1024 for (cnt = 0; cnt < 16; ++cnt)
1003 } else if (do_check) { 1025 printf("%02x", md5buffer[cnt]);
1004 if (optind + 1 < argc) { 1026
1005 bb_error_msg("only one argument may be specified when using -c"); 1027 printf(" \"%s\"\n", string[i]);
1006 } 1028 }
1007 1029 } else if (do_check) {
1008 err = md5_check ((optind == argc) ? "-" : argv[optind]); 1030 if (optind + 1 < argc) {
1009 } else { 1031 bb_error_msg("only one argument may be specified when using -c");
1010 if (optind == argc) 1032 }
1011 argv[argc++] = "-"; 1033
1012 1034 err = md5_check((optind == argc) ? "-" : argv[optind]);
1013 for (; optind < argc; ++optind) { 1035 } else {
1014 int fail; 1036 if (optind == argc)
1015 char *file = argv[optind]; 1037 argv[argc++] = "-";
1016 1038
1017 fail = md5_file (file, md5buffer); 1039 for (; optind < argc; ++optind) {
1018 err |= fail; 1040 int fail;
1019 if (!fail && file[0]=='-' && file[1] == '\0') { 1041 char *file = argv[optind];
1020 size_t i; 1042
1021 for (i = 0; i < 16; ++i) 1043 fail = md5_file(file, md5buffer);
1022 printf ("%02x", md5buffer[i]); 1044 err |= fail;
1023 putchar ('\n'); 1045 if (!fail && file[0] == '-' && file[1] == '\0') {
1024 } else if (!fail) { 1046 size_t i;
1025 size_t i; 1047
1026 /* Output a leading backslash if the file name contains 1048 for (i = 0; i < 16; ++i)
1027 a newline or backslash. */ 1049 printf("%02x", md5buffer[i]);
1028 if (strchr (file, '\n') || strchr (file, '\\')) 1050 putchar('\n');
1029 putchar ('\\'); 1051 } else if (!fail) {
1030 1052 size_t i;
1031 for (i = 0; i < 16; ++i) 1053
1032 printf ("%02x", md5buffer[i]); 1054 /* Output a leading backslash if the file name contains
1033 1055 a newline or backslash. */
1034 putchar (' '); 1056 if (strchr(file, '\n') || strchr(file, '\\'))
1035 if (binary) 1057 putchar('\\');
1036 putchar ('*'); 1058
1037 else 1059 for (i = 0; i < 16; ++i)
1038 putchar (' '); 1060 printf("%02x", md5buffer[i]);
1039 1061
1040 /* Translate each NEWLINE byte to the string, "\\n", 1062 putchar(' ');
1041 and each backslash to "\\\\". */ 1063 if (binary)
1042 for (i = 0; i < strlen (file); ++i) { 1064 putchar('*');
1043 switch (file[i]) { 1065 else
1044 case '\n': 1066 putchar(' ');
1045 fputs ("\\n", stdout); 1067
1046 break; 1068 /* Translate each NEWLINE byte to the string, "\\n",
1047 1069 and each backslash to "\\\\". */
1048 case '\\': 1070 for (i = 0; i < strlen(file); ++i) {
1049 fputs ("\\\\", stdout); 1071 switch (file[i]) {
1050 break; 1072 case '\n':
1051 1073 fputs("\\n", stdout);
1052 default: 1074 break;
1053 putchar (file[i]); 1075
1054 break; 1076 case '\\':
1055 } 1077 fputs("\\\\", stdout);
1056 } 1078 break;
1057 putchar ('\n'); 1079
1058 } 1080 default:
1059 } 1081 putchar(file[i]);
1060 } 1082 break;
1061 1083 }
1062 if (fclose (stdout) == EOF) { 1084 }
1063 bb_error_msg_and_die("write error"); 1085 putchar('\n');
1064 } 1086 }
1065 1087 }
1066 if (have_read_stdin && fclose (stdin) == EOF) { 1088 }
1067 bb_error_msg_and_die(bb_msg_standard_input); 1089
1068 } 1090 if (fclose(stdout) == EOF) {
1069 1091 bb_error_msg_and_die("write error");
1070 if (err == 0) 1092 }
1071 return EXIT_SUCCESS; 1093
1072 else 1094 if (have_read_stdin && fclose(stdin) == EOF) {
1073 return EXIT_FAILURE; 1095 bb_error_msg_and_die(bb_msg_standard_input);
1096 }
1097
1098 if (err == 0)
1099 return EXIT_SUCCESS;
1100 else
1101 return EXIT_FAILURE;
1074} 1102}