diff options
author | Shao Miller <sha0.miller@gmail.com> | 2012-11-02 11:59:10 -0400 |
---|---|---|
committer | Shao Miller <sha0.miller@gmail.com> | 2012-11-10 02:04:03 -0500 |
commit | 0b4de4d15b0bbf3b77861eab0e8efe77a626ed21 (patch) | |
tree | fcf149e48e6c06a7992503abe54a9c53fc5edf4f /com32 | |
parent | a6671b7d17293cf3f7fac1083ae16542828987b4 (diff) | |
download | syslinux-ady_cat.tar.gz syslinux-ady_cat.tar.xz syslinux-ady_cat.zip |
ady2.c32: For testing a bug reported by Ady2ady_cat
Ady2 reported a bug with Slitaz' md5sum.c32, but it turns out that
running this special .c32 module on the filename:
/ubcd/custom/syslinux-5.00-pre9/com32/gplinclude/acpi/facs.h
produces an error after 134 iterations, with Ady2's .ISO.
Diffstat (limited to 'com32')
-rw-r--r-- | com32/modules/Makefile | 3 | ||||
-rw-r--r-- | com32/modules/ady2.c | 37 | ||||
-rwxr-xr-x | com32/modules/md5sum.c | 406 |
3 files changed, 445 insertions, 1 deletions
diff --git a/com32/modules/Makefile b/com32/modules/Makefile index f110e584..1c54ee02 100644 --- a/com32/modules/Makefile +++ b/com32/modules/Makefile @@ -24,7 +24,8 @@ MODULES = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \ meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \ kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 ls.c32 gpxecmd.c32 \ ifcpu.c32 cpuid.c32 cat.c32 pwd.c32 ifplop.c32 zzjson.c32 \ - whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32 + whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32 \ + md5sum.c32 ady2.c32 TESTFILES = diff --git a/com32/modules/ady2.c b/com32/modules/ady2.c new file mode 100644 index 00000000..95eb0d17 --- /dev/null +++ b/com32/modules/ady2.c @@ -0,0 +1,37 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <console.h> +#include <errno.h> + +int main(int argc, char *argv[]) +{ + static unsigned char iterations = 1; + int src_fd; + + openconsole(&dev_stdcon_r, &dev_stdcon_w); + + if (argc < 2) { + fprintf(stderr, "Usage: %s filename...\n", argv[0]); + return 1; + } + + while (1) { + + errno = 0; + printf("---OPEN---"); + src_fd = open(argv[1], O_RDONLY); + if (src_fd < 0) { + printf("Finally failed after %u iterations with error: %d\n", + iterations, errno); + return 1; + } + close(src_fd); + printf("---CLOSE---"); + if (!iterations++) + return 1; + } + printf("No failure\n"); + return 0; +} diff --git a/com32/modules/md5sum.c b/com32/modules/md5sum.c new file mode 100755 index 00000000..50007dea --- /dev/null +++ b/com32/modules/md5sum.c @@ -0,0 +1,406 @@ +/* + * Based on busybox code. + * + * Compute MD5 checksum of strings according to the + * definition of MD5 in RFC 1321 from April 1992. + * + * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. + * + * Copyright (C) 1995-1999 Free Software Foundation, Inc. + * Copyright (C) 2001 Manuel Novoa III + * Copyright (C) 2003 Glenn L. McGrath + * Copyright (C) 2003 Erik Andersen + * Copyright (C) 2010 Denys Vlasenko + * Copyright (C) 2012 Pascal Bellard + * + * Licensed under GPLv2 or later + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <console.h> +#include <com32.h> +#include <errno.h> + +#define ALIGN1 + +static uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ +static uint64_t total64; /* must be directly before hash[] */ +static uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */ + +/* Emit a string of hex representation of bytes */ +static char* bin2hex(char *p) +{ + static const char bb_hexdigits_upcase[] ALIGN1 = "0123456789abcdef"; + int count = 16; + const char *cp = (const char *) hash; + while (count) { + unsigned char c = *cp++; + /* put lowercase hex digits */ + *p++ = bb_hexdigits_upcase[c >> 4]; + *p++ = bb_hexdigits_upcase[c & 0xf]; + count--; + } + return p; +} + +//#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n)))) +static uint32_t rotl32(uint32_t x, unsigned n) +{ + return (x << n) | (x >> (32 - n)); +} + +static void md5_process_block64(void); + +/* Feed data through a temporary buffer. + * The internal buffer remembers previous data until it has 64 + * bytes worth to pass on. + */ +static void common64_hash(const void *buffer, size_t len) +{ + unsigned bufpos = total64 & 63; + + total64 += len; + + while (1) { + unsigned remaining = 64 - bufpos; + if (remaining > len) + remaining = len; + /* Copy data into aligned buffer */ + memcpy(wbuffer + bufpos, buffer, remaining); + len -= remaining; + buffer = (const char *)buffer + remaining; + bufpos += remaining; + /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ + bufpos -= 64; + if (bufpos != 0) + break; + /* Buffer is filled up, process it */ + md5_process_block64(); + /*bufpos = 0; - already is */ + } +} + +/* Process the remaining bytes in the buffer */ +static void common64_end(void) +{ + unsigned bufpos = total64 & 63; + /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ + wbuffer[bufpos++] = 0x80; + + /* This loop iterates either once or twice, no more, no less */ + while (1) { + unsigned remaining = 64 - bufpos; + memset(wbuffer + bufpos, 0, remaining); + /* Do we have enough space for the length count? */ + if (remaining >= 8) { + /* Store the 64-bit counter of bits in the buffer */ + uint64_t t = total64 << 3; + /* wbuffer is suitably aligned for this */ + *(uint64_t *) (&wbuffer[64 - 8]) = t; + } + md5_process_block64(); + if (remaining >= 8) + break; + bufpos = 0; + } +} + +/* These are the four functions used in the four steps of the MD5 algorithm + * and defined in the RFC 1321. The first function is a little bit optimized + * (as found in Colin Plumbs public domain implementation). + * #define FF(b, c, d) ((b & c) | (~b & d)) + */ +#undef FF +#undef FG +#undef FH +#undef FI +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF(d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* Hash a single block, 64 bytes long and 4-byte aligned */ +static void md5_process_block64(void) +{ + /* Before we start, one word to the strange constants. + They are defined in RFC 1321 as + T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 + */ + static const uint32_t C_array[] = { + /* round 1 */ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + /* round 2 */ + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + /* round 3 */ + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + /* round 4 */ + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + static const char P_array[] ALIGN1 = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ + }; + uint32_t *words = (void*) wbuffer; + uint32_t A = hash[0]; + uint32_t B = hash[1]; + uint32_t C = hash[2]; + uint32_t D = hash[3]; + + static const char S_array[] ALIGN1 = { + 7, 12, 17, 22, + 5, 9, 14, 20, + 4, 11, 16, 23, + 6, 10, 15, 21 + }; + const uint32_t *pc; + const char *pp; + const char *ps; + int i; + uint32_t temp; + + + pc = C_array; + pp = P_array; + ps = S_array - 4; + + for (i = 0; i < 64; i++) { + if ((i & 0x0f) == 0) + ps += 4; + temp = A; + switch (i >> 4) { + case 0: + temp += FF(B, C, D); + break; + case 1: + temp += FG(B, C, D); + break; + case 2: + temp += FH(B, C, D); + break; + case 3: + temp += FI(B, C, D); + } + temp += words[(int) (*pp++)] + *pc++; + temp = rotl32(temp, ps[i & 3]); + temp += B; + A = D; + D = C; + C = B; + B = temp; + } + /* Add checksum to the starting values */ + hash[0] += A; + hash[1] += B; + hash[2] += C; + hash[3] += D; + +} +#undef FF +#undef FG +#undef FH +#undef FI + +/* Initialize structure containing state of computation. + * (RFC 1321, 3.3: Step 3) + */ +static void md5_begin(void) +{ + hash[0] = 0x67452301; + hash[1] = 0xefcdab89; + hash[2] = 0x98badcfe; + hash[3] = 0x10325476; + total64 = 0; +} + +/* Used also for sha1 and sha256 */ +#define md5_hash common64_hash + +/* Process the remaining bytes in the buffer and put result from CTX + * in first 16 bytes following RESBUF. The result is always in little + * endian byte order, so that a byte-wise output yields to the wanted + * ASCII representation of the message digest. + */ +#define md5_end common64_end + +/* + * Copyright (C) 2003 Glenn L. McGrath + * Copyright (C) 2003-2004 Erik Andersen + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +static char *unrockridge(const char *name) +{ + static char buffer[256]; + int i = 0, j = 8; + while (*name && i < 255) { + char c = *name++; + //if (c == '\\') c = '/'; + if (c == '.') { + for (j = i; --j >= 0 && buffer[j] != '/';) + if (buffer[j] == '.') buffer[j] = '_'; + if (i - j > 9) i = j + 9; + j = i + 4; + } + else if (c == '/') j = i + 9; + else if (i >= j) continue; + else if (c >= 'a' && c <= 'z') c += 'A' - 'a'; + else if ((c < 'A' || c > 'Z') && (c < '0' || c > '9')) c = '_'; + buffer[i++] = c; + } + buffer[i] = 0; + return buffer; +} + +static uint8_t *hash_file(const char *filename) +{ + int src_fd, count; + uint8_t in_buf[4096]; + static uint8_t hash_value[16*2+1]; + char *rock = NULL; + int errno2; + + errno = 0; + src_fd = open(filename, O_RDONLY); + if (src_fd < 0) { + errno2 = 0; + rock = unrockridge(filename); + src_fd = open(rock, O_RDONLY); + } + if (src_fd < 0) { + printf("hash_file: Unable to open file:\n %d: [%s]\n %d: [%s]", + errno, filename, errno2, rock); + exit(1); + return NULL; + } + + md5_begin(); + while ((count = read(src_fd, in_buf, 4096)) > 0) { + md5_hash(in_buf, count); + } + + close(src_fd); + + if (count) { + printf("hash_file: Count is non-zero\n"); + sleep(10); + return NULL; + } + + md5_end(); + bin2hex((char *)hash_value); + + return hash_value; +} + +static int main_say(int argc, char **argv) +{ + int i; + for (i = 1; i < argc; i++) { + printf("%s ",argv[i]); + } + sleep(5); + return 0; +} + +static int main_md5sum(int argc, char **argv) +{ + int files = 0, tested = 0, good = 0; + static char clear_eol[] = " "; + + (void) argc; + /* -c implied */ + argv++; + do { + FILE *fp; + char eol, *line, buffer[4096]; + fp = fopen(*argv,"r"); + if (fp == NULL) + fp = fopen(unrockridge(*argv),"r"); + + while ((line = fgets(buffer,sizeof(buffer),fp)) != NULL) { + uint8_t *hash_value; + char *filename_ptr, *status; + int len = strlen(line); + + if (line[0] < '0') + continue; + if (line[len-1] == '\n') + line[len-1] = 0; + filename_ptr = strstr(line, " "); + /* handle format for binary checksums */ + if (filename_ptr == NULL) { + filename_ptr = strstr(line, " *"); + } + if (filename_ptr == NULL) { + continue; + } + *filename_ptr = '\0'; + *++filename_ptr = '/'; + if (filename_ptr[1] == '/') + filename_ptr++; + + files++; + status = "NOT CHECKED"; + eol = '\n'; + hash_value = hash_file(filename_ptr); + if (hash_value) { + tested++; + status = "BROKEN"; + if (!strcmp((char*)hash_value, line)) { + good++; + status = "OK"; + eol = ' '; + } + } + printf("\r%s: %s%s%c", filename_ptr, status, clear_eol, eol); + } + fclose(fp); + } while (*++argv); + printf("\r%d files OK, %d broken, %d not checked.%s\n", + good, tested - good, files - tested, clear_eol); + sleep(5); + return 0; +} + +int main(int argc, char *argv[]) +{ + unsigned i; + static struct { + char *name; + int (*main)(int argc, char *argv[]); + } bin[] = { + { "say", main_say }, + { "md5sum", main_md5sum }, + }; + + openconsole(&dev_null_r, &dev_stdcon_w); + printf("Ady version #2\n"); + sleep(3); + if (strstr(argv[0], "c32box")) { argc--; argv++; } + for (i = 0; i < sizeof(bin)/sizeof(bin[0]); i++) + if (strstr(argv[0], bin[i].name)) + return bin[i].main(argc, argv); + printf("No %s in c32box modules\n", argv[0]); + for (i = 0; i < sizeof(bin)/sizeof(bin[0]); i++) + printf(" %s \n",bin[i].name); + return 1; +} |