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 -}