wok rev 12215
syslinux/md5sum.c32: add a status line
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Tue Apr 03 13:12:44 2012 +0200 (2012-04-03) |
parents | 297bc4cc8984 |
children | d64d0a05e432 |
files | syslinux/stuff/extra/md5sum.c |
line diff
1.1 --- a/syslinux/stuff/extra/md5sum.c Mon Apr 02 22:48:21 2012 +0200 1.2 +++ b/syslinux/stuff/extra/md5sum.c Tue Apr 03 13:12:44 2012 +0200 1.3 @@ -1,12 +1,19 @@ 1.4 -/* vi: set sw=4 ts=4: */ 1.5 /* 1.6 - * Based on busybox code 1.7 + * Based on busybox code. 1.8 * 1.9 - * Utility routines. 1.10 + * Compute MD5 checksum of strings according to the 1.11 + * definition of MD5 in RFC 1321 from April 1992. 1.12 * 1.13 + * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. 1.14 + * 1.15 + * Copyright (C) 1995-1999 Free Software Foundation, Inc. 1.16 + * Copyright (C) 2001 Manuel Novoa III 1.17 + * Copyright (C) 2003 Glenn L. McGrath 1.18 + * Copyright (C) 2003 Erik Andersen 1.19 * Copyright (C) 2010 Denys Vlasenko 1.20 + * Copyright (C) 2012 Pascal Bellard 1.21 * 1.22 - * Licensed under GPLv2 or later, see file LICENSE in this source tree. 1.23 + * Licensed under GPLv2 or later 1.24 */ 1.25 1.26 #include <stdio.h> 1.27 @@ -18,16 +25,22 @@ 1.28 #include <com32.h> 1.29 1.30 #define ALIGN1 1.31 -const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF"; 1.32 + 1.33 +static uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ 1.34 +static uint64_t total64; /* must be directly before hash[] */ 1.35 +static uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */ 1.36 1.37 /* Emit a string of hex representation of bytes */ 1.38 -char* bin2hex(char *p, const char *cp, int count) 1.39 +static char* bin2hex(char *p) 1.40 { 1.41 + static const char bb_hexdigits_upcase[] ALIGN1 = "0123456789abcdef"; 1.42 + int count = 16; 1.43 + const char *cp = (const char *) hash; 1.44 while (count) { 1.45 unsigned char c = *cp++; 1.46 /* put lowercase hex digits */ 1.47 - *p++ = 0x20 | bb_hexdigits_upcase[c >> 4]; 1.48 - *p++ = 0x20 | bb_hexdigits_upcase[c & 0xf]; 1.49 + *p++ = bb_hexdigits_upcase[c >> 4]; 1.50 + *p++ = bb_hexdigits_upcase[c & 0xf]; 1.51 count--; 1.52 } 1.53 return p; 1.54 @@ -39,30 +52,24 @@ 1.55 return (x << n) | (x >> (32 - n)); 1.56 } 1.57 1.58 -typedef struct md5_ctx_t { 1.59 - uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ 1.60 - uint64_t total64; /* must be directly before hash[] */ 1.61 - uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */ 1.62 -} md5_ctx_t; 1.63 - 1.64 -static void md5_process_block64(md5_ctx_t *ctx); 1.65 +static void md5_process_block64(void); 1.66 1.67 /* Feed data through a temporary buffer. 1.68 * The internal buffer remembers previous data until it has 64 1.69 * bytes worth to pass on. 1.70 */ 1.71 -static void common64_hash(md5_ctx_t *ctx, const void *buffer, size_t len) 1.72 +static void common64_hash(const void *buffer, size_t len) 1.73 { 1.74 - unsigned bufpos = ctx->total64 & 63; 1.75 + unsigned bufpos = total64 & 63; 1.76 1.77 - ctx->total64 += len; 1.78 + total64 += len; 1.79 1.80 while (1) { 1.81 unsigned remaining = 64 - bufpos; 1.82 if (remaining > len) 1.83 remaining = len; 1.84 /* Copy data into aligned buffer */ 1.85 - memcpy(ctx->wbuffer + bufpos, buffer, remaining); 1.86 + memcpy(wbuffer + bufpos, buffer, remaining); 1.87 len -= remaining; 1.88 buffer = (const char *)buffer + remaining; 1.89 bufpos += remaining; 1.90 @@ -71,51 +78,36 @@ 1.91 if (bufpos != 0) 1.92 break; 1.93 /* Buffer is filled up, process it */ 1.94 - md5_process_block64(ctx); 1.95 + md5_process_block64(); 1.96 /*bufpos = 0; - already is */ 1.97 } 1.98 } 1.99 1.100 /* Process the remaining bytes in the buffer */ 1.101 -static void common64_end(md5_ctx_t *ctx) 1.102 +static void common64_end(void) 1.103 { 1.104 - unsigned bufpos = ctx->total64 & 63; 1.105 + unsigned bufpos = total64 & 63; 1.106 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ 1.107 - ctx->wbuffer[bufpos++] = 0x80; 1.108 + wbuffer[bufpos++] = 0x80; 1.109 1.110 /* This loop iterates either once or twice, no more, no less */ 1.111 while (1) { 1.112 unsigned remaining = 64 - bufpos; 1.113 - memset(ctx->wbuffer + bufpos, 0, remaining); 1.114 + memset(wbuffer + bufpos, 0, remaining); 1.115 /* Do we have enough space for the length count? */ 1.116 if (remaining >= 8) { 1.117 /* Store the 64-bit counter of bits in the buffer */ 1.118 - uint64_t t = ctx->total64 << 3; 1.119 + uint64_t t = total64 << 3; 1.120 /* wbuffer is suitably aligned for this */ 1.121 - *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; 1.122 + *(uint64_t *) (&wbuffer[64 - 8]) = t; 1.123 } 1.124 - md5_process_block64(ctx); 1.125 + md5_process_block64(); 1.126 if (remaining >= 8) 1.127 break; 1.128 bufpos = 0; 1.129 } 1.130 } 1.131 1.132 - 1.133 -/* 1.134 - * Compute MD5 checksum of strings according to the 1.135 - * definition of MD5 in RFC 1321 from April 1992. 1.136 - * 1.137 - * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. 1.138 - * 1.139 - * Copyright (C) 1995-1999 Free Software Foundation, Inc. 1.140 - * Copyright (C) 2001 Manuel Novoa III 1.141 - * Copyright (C) 2003 Glenn L. McGrath 1.142 - * Copyright (C) 2003 Erik Andersen 1.143 - * 1.144 - * Licensed under GPLv2 or later, see file LICENSE in this source tree. 1.145 - */ 1.146 - 1.147 /* These are the four functions used in the four steps of the MD5 algorithm 1.148 * and defined in the RFC 1321. The first function is a little bit optimized 1.149 * (as found in Colin Plumbs public domain implementation). 1.150 @@ -131,7 +123,7 @@ 1.151 #define FI(b, c, d) (c ^ (b | ~d)) 1.152 1.153 /* Hash a single block, 64 bytes long and 4-byte aligned */ 1.154 -static void md5_process_block64(md5_ctx_t *ctx) 1.155 +static void md5_process_block64(void) 1.156 { 1.157 /* Before we start, one word to the strange constants. 1.158 They are defined in RFC 1321 as 1.159 @@ -165,11 +157,11 @@ 1.160 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ 1.161 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ 1.162 }; 1.163 - uint32_t *words = (void*) ctx->wbuffer; 1.164 - uint32_t A = ctx->hash[0]; 1.165 - uint32_t B = ctx->hash[1]; 1.166 - uint32_t C = ctx->hash[2]; 1.167 - uint32_t D = ctx->hash[3]; 1.168 + uint32_t *words = (void*) wbuffer; 1.169 + uint32_t A = hash[0]; 1.170 + uint32_t B = hash[1]; 1.171 + uint32_t C = hash[2]; 1.172 + uint32_t D = hash[3]; 1.173 1.174 static const char S_array[] ALIGN1 = { 1.175 7, 12, 17, 22, 1.176 @@ -214,10 +206,10 @@ 1.177 B = temp; 1.178 } 1.179 /* Add checksum to the starting values */ 1.180 - ctx->hash[0] += A; 1.181 - ctx->hash[1] += B; 1.182 - ctx->hash[2] += C; 1.183 - ctx->hash[3] += D; 1.184 + hash[0] += A; 1.185 + hash[1] += B; 1.186 + hash[2] += C; 1.187 + hash[3] += D; 1.188 1.189 } 1.190 #undef FF 1.191 @@ -228,34 +220,24 @@ 1.192 /* Initialize structure containing state of computation. 1.193 * (RFC 1321, 3.3: Step 3) 1.194 */ 1.195 -void md5_begin(md5_ctx_t *ctx) 1.196 +static void md5_begin(void) 1.197 { 1.198 - ctx->hash[0] = 0x67452301; 1.199 - ctx->hash[1] = 0xefcdab89; 1.200 - ctx->hash[2] = 0x98badcfe; 1.201 - ctx->hash[3] = 0x10325476; 1.202 - ctx->total64 = 0; 1.203 + hash[0] = 0x67452301; 1.204 + hash[1] = 0xefcdab89; 1.205 + hash[2] = 0x98badcfe; 1.206 + hash[3] = 0x10325476; 1.207 + total64 = 0; 1.208 } 1.209 1.210 /* Used also for sha1 and sha256 */ 1.211 -void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) 1.212 -{ 1.213 - common64_hash(ctx, buffer, len); 1.214 -} 1.215 +#define md5_hash common64_hash 1.216 1.217 /* Process the remaining bytes in the buffer and put result from CTX 1.218 * in first 16 bytes following RESBUF. The result is always in little 1.219 * endian byte order, so that a byte-wise output yields to the wanted 1.220 * ASCII representation of the message digest. 1.221 */ 1.222 -void md5_end(md5_ctx_t *ctx, void *resbuf) 1.223 -{ 1.224 - /* MD5 stores total in LE, need to swap on BE arches: */ 1.225 - common64_end(ctx); 1.226 - 1.227 - /* The MD5 result is in little endian byte order */ 1.228 - memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); 1.229 -} 1.230 +#define md5_end common64_end 1.231 1.232 /* 1.233 * Copyright (C) 2003 Glenn L. McGrath 1.234 @@ -264,77 +246,63 @@ 1.235 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 1.236 */ 1.237 1.238 -/* This might be useful elsewhere */ 1.239 -static unsigned char *hash_bin_to_hex(unsigned char *hash_value, 1.240 - unsigned hash_length) 1.241 -{ 1.242 - static char hex_value[16*2+1]; 1.243 - bin2hex(hex_value, (char*)hash_value, hash_length); 1.244 - return (unsigned char *)hex_value; 1.245 -} 1.246 - 1.247 -static char *unrock(const char *name) 1.248 +static char *unrockridge(const char *name) 1.249 { 1.250 static char buffer[256]; 1.251 - char *out = buffer; 1.252 - int i, j; 1.253 - for (i = 0, j = 8; *name && (buffer + 255) > (out + i); name++) { 1.254 - if (*name == '/') { 1.255 - out[i++] = *name; 1.256 - out += i; 1.257 - i = 0; j = 8; 1.258 + int i = 0, j = 8; 1.259 + while (*name && i < 255) { 1.260 + char c = *name++; 1.261 + //if (c == '\\') c = '/'; 1.262 + if (c == '.') { 1.263 + for (j = i; --j >= 0 && buffer[j] != '/';) 1.264 + if (buffer[j] == '.') buffer[j] = '_'; 1.265 + if (i - j > 9) i = j + 9; 1.266 + j = i + 4; 1.267 } 1.268 - else if (*name == '.') { 1.269 - if (i > 8) i = 8; 1.270 - for (j = 0; j < i; j++) 1.271 - if (out[j] == '.') out[j] = '_'; 1.272 - out[i++] = *name; 1.273 - j = i + 3; 1.274 - } 1.275 + else if (c == '/') j = i + 9; 1.276 else if (i >= j) continue; 1.277 - else if ((*name >= 'A' && *name <= 'Z') || *name == '_' || 1.278 - (*name >= '0' && *name <= '9')) 1.279 - out[i++] = *name; 1.280 - else if (*name >= 'a' && *name <= 'z') 1.281 - out[i++] = *name + 'A' - 'a'; 1.282 - else out[i++] = '_'; 1.283 + else if (c >= 'a' && c <= 'z') c += 'A' - 'a'; 1.284 + else if ((c < 'A' || c > 'Z') && (c < '0' || c > '9')) c = '_'; 1.285 + buffer[i++] = c; 1.286 } 1.287 - out[i] = 0; 1.288 + buffer[i] = 0; 1.289 return buffer; 1.290 } 1.291 1.292 static uint8_t *hash_file(const char *filename) 1.293 { 1.294 int src_fd, count; 1.295 - md5_ctx_t context; 1.296 - uint8_t *hash_value, in_buf[4096]; 1.297 + uint8_t in_buf[4096]; 1.298 + static uint8_t hash_value[16*2+1]; 1.299 1.300 src_fd = open(filename, O_RDONLY); 1.301 if (src_fd < 0) { 1.302 - src_fd = open(unrock(filename), O_RDONLY); 1.303 + src_fd = open(unrockridge(filename), O_RDONLY); 1.304 } 1.305 if (src_fd < 0) { 1.306 return NULL; 1.307 } 1.308 1.309 - md5_begin(&context); 1.310 + md5_begin(); 1.311 while ((count = read(src_fd, in_buf, 4096)) > 0) { 1.312 - md5_hash(&context, in_buf, count); 1.313 - } 1.314 - hash_value = NULL; 1.315 - if (count == 0) { 1.316 - md5_end(&context, in_buf); 1.317 - hash_value = hash_bin_to_hex(in_buf, 16); 1.318 + md5_hash(in_buf, count); 1.319 } 1.320 1.321 close(src_fd); 1.322 + 1.323 + if (count) 1.324 + return NULL; 1.325 + 1.326 + md5_end(); 1.327 + bin2hex((char *)hash_value); 1.328 1.329 return hash_value; 1.330 } 1.331 1.332 int main(int argc, char **argv) 1.333 { 1.334 - int return_value = EXIT_SUCCESS; 1.335 + int files = 0, tested = 0, good = 0; 1.336 + static char clear_eol[] = " "; 1.337 1.338 (void) argc; 1.339 /* -c implied */ 1.340 @@ -342,16 +310,15 @@ 1.341 1.342 do { 1.343 FILE *fp; 1.344 - char *line, buffer[256]; 1.345 + char eol, *line, buffer[256]; 1.346 fp = fopen(*argv,"r"); 1.347 if (fp == NULL) 1.348 - fp = fopen(unrock(*argv),"r"); 1.349 + fp = fopen(unrockridge(*argv),"r"); 1.350 1.351 while ((line = fgets(buffer,256,fp)) != NULL) { 1.352 uint8_t *hash_value; 1.353 char *filename_ptr, *status; 1.354 int len = strlen(line); 1.355 -#define BLANK " " 1.356 1.357 if (line[0] < '0') 1.358 continue; 1.359 @@ -363,7 +330,6 @@ 1.360 filename_ptr = strstr(line, " *"); 1.361 } 1.362 if (filename_ptr == NULL) { 1.363 - return_value = EXIT_FAILURE; 1.364 continue; 1.365 } 1.366 *filename_ptr = '\0'; 1.367 @@ -371,20 +337,24 @@ 1.368 if (filename_ptr[1] == '/') 1.369 filename_ptr++; 1.370 1.371 - status = "NOT CHECKED" BLANK "\n"; 1.372 + files++; 1.373 + status = "NOT CHECKED"; 1.374 + eol = '\n'; 1.375 hash_value = hash_file(filename_ptr); 1.376 if (hash_value) { 1.377 - status = "OK" BLANK; 1.378 - if (strcmp((char*)hash_value, line)) { 1.379 - return_value = EXIT_FAILURE; 1.380 - status = "FAILED" BLANK "\n"; 1.381 + tested++; 1.382 + status = "BROKEN"; 1.383 + if (!strcmp((char*)hash_value, line)) { 1.384 + good++; 1.385 + status = "OK"; 1.386 + eol = ' '; 1.387 } 1.388 } 1.389 - printf("\r%s: %s", filename_ptr, status); 1.390 + printf("\r%s: %s%s%c", filename_ptr, status, clear_eol, eol); 1.391 } 1.392 fclose(fp); 1.393 } while (*++argv); 1.394 - printf("\r" BLANK "\r"); 1.395 + printf("\r%d files OK, %d broken, %d not checked.%s\n", 1.396 + good, tested - good, files - tested, clear_eol); 1.397 +} 1.398 1.399 - return return_value; 1.400 -}