diff options
author | Shao Miller <sha0.miller@gmail.com> | 2012-11-04 00:26:32 -0400 |
---|---|---|
committer | Shao Miller <sha0.miller@gmail.com> | 2012-11-04 00:26:32 -0400 |
commit | c9c67dd61ba0b11e46d514601cf0722e1b43017c (patch) | |
tree | e36096be2de3a5ceb47a9cd237852f0f28ebd1d8 | |
parent | 28b3a9d4d7eb932b827122f3e641ce14fb2cbd03 (diff) | |
download | syslinux-c9c67dd61ba0b11e46d514601cf0722e1b43017c.tar.gz syslinux-c9c67dd61ba0b11e46d514601cf0722e1b43017c.tar.xz syslinux-c9c67dd61ba0b11e46d514601cf0722e1b43017c.zip |
hexdump.c32: Simple file hex-dumper
Usage: %s [<option> [...]] <filename> [<option> [...]]
Options: -p
--page . . . . . . . Pause output every 24 lines
--no-buffer . . . . Load the entire file before dumping
--extended-ascii . . Use extended ASCII chars in dump
-?
-h
--help . . . . . . Display this help
Signed-off-by: Shao Miller <sha0.miller@gmail.com>
-rw-r--r-- | com32/modules/Makefile | 3 | ||||
-rw-r--r-- | com32/modules/hexdump.c | 245 |
2 files changed, 247 insertions, 1 deletions
diff --git a/com32/modules/Makefile b/com32/modules/Makefile index ee428e30..9cf4da8e 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 \ + hexdump.c32 TESTFILES = diff --git a/com32/modules/hexdump.c b/com32/modules/hexdump.c new file mode 100644 index 00000000..bc2c70dd --- /dev/null +++ b/com32/modules/hexdump.c @@ -0,0 +1,245 @@ +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <console.h> +#include <errno.h> +#include <syslinux/loadfile.h> + +/* Macros */ +#define ROWS_PER_PAGE 24 +#define COLS_PER_ROW 16 +#define BYTES_PER_PAGE (ROWS_PER_PAGE * COLS_PER_ROW) + +/* Functions declarations */ +static int usage(void); +static void eat_stdin(void); +static int do_page(void); +static void hexdump(const void *memory, size_t bytes); + +/* Objects */ +static const char *prog_name; +static int opt_page; +static int opt_no_buffer; +static int opt_extended_ascii; + +int main(int argc, char **argv) +{ + int rc; + const char *filename; + int i; + void *file_data; + size_t file_sz; + FILE *f; + size_t len; + const char *cur_pos; + + /* Assume failure */ + rc = EXIT_FAILURE; + + /* Determine the program name, as invoked */ + if (argc < 1 || !argv || !argv[0]) { + fprintf(stderr, "argc or argv failure!\n"); + goto err_prog_name; + } + prog_name = argv[0]; + + /* Process arguments */ + filename = NULL; + for (i = 1; i < argc; ++i) { + if (!argv[i]) { + fprintf(stderr, "argc and argv mismatch!\n"); + goto err_argv; + } + + if (!strncmp(argv[i], "--page", sizeof "--page") || + !strncmp(argv[i], "-p", sizeof "-p")) { + opt_page = 1; + continue; + } + + if (!strncmp(argv[i], "--no-buffer", sizeof "--no-buffer")) { + opt_no_buffer = 1; + continue; + } + + if (!strncmp(argv[i], "--extended-ascii", sizeof "--extended-ascii")) { + opt_extended_ascii = 1; + continue; + } + + if (!strncmp(argv[i], "--help", sizeof "--help") || + !strncmp(argv[i], "-h", sizeof "-h") || + !strncmp(argv[i], "-?", sizeof "-?")) + return usage(); + + /* Otherwise, interpret as a filename, but only accept one */ + if (filename) + return usage(); + filename = argv[i]; + } + if (!filename) + return usage(); + fprintf(stdout, "Dumping file: %s\n", filename); + + /* Either fetch the whole file, or just allocate a buffer */ + f = NULL; + if (opt_no_buffer) { + errno = 0; + if (loadfile(filename, &file_data, &file_sz)) { + fprintf(stderr, "Couldn't load file. Error: %d\n", errno); + goto err_file_data; + } + } else { + file_sz = BYTES_PER_PAGE; + file_data = malloc(file_sz); + if (!file_data) { + fprintf(stderr, "Couldn't allocate file data buffer\n"); + goto err_file_data; + } + errno = 0; + f = fopen(filename, "r"); + if (!f) { + fprintf(stderr, "Couldn't open file. Error: %d\n", errno); + goto err_f; + } + } + + /* Dump the data */ + len = BYTES_PER_PAGE; + cur_pos = file_data; + do { + if (f) { + /* Buffered */ + len = fread(file_data, 1, file_sz, f); + cur_pos = file_data; + } else { + /* Non-buffered */ + if (file_sz < len) + len = file_sz; + } + if (!len) + break; + + hexdump(cur_pos, len); + + /* Pause, if requested */ + if (opt_page) { + /* The user might choose to quit */ + if (do_page()) + break; + } + + /* Reduce file_sz for non-buffered mode */ + if (!f) + file_sz -= len; + } while (cur_pos += len); + + rc = EXIT_SUCCESS; + + if (f) + fclose(f); + err_f: + + free(file_data); + err_file_data: + + err_argv: + + err_prog_name: + + return rc; +} + +static int usage(void) +{ + static const char usage[] = + "Usage: %s [<option> [...]] <filename> [<option> [...]]\n" + "\n" + "Options: -p\n" + " --page . . . . . . . Pause output every 24 lines\n" + " --no-buffer . . . . Load the entire file before dumping\n" + " --extended-ascii . . Use extended ASCII chars in dump\n" + " -?\n" + " -h\n" + " --help . . . . . . Display this help\n"; + + fprintf(stderr, usage, prog_name); + return EXIT_FAILURE; +} + +static void eat_stdin(void) +{ + int i; + + while (1) { + i = fgetc(stdin); + if (i == EOF || i == '\n') + return; + } +} +static int do_page(void) +{ + int i; + + while (1) { + fprintf(stdout, "Continue? [Y|n]: "); + i = fgetc(stdin); + switch (i) { + case 'n': + case 'N': + eat_stdin(); + return 1; + + case EOF: + fprintf(stderr, "No response. Continuing...\n"); + /* Fall through to "yes" */ + + case 'y': + case 'Y': + eat_stdin(); + case '\n': + return 0; + + default: + fprintf(stderr, "Invalid choice\n"); + eat_stdin(); + } + } +} + +static void hexdump(const void *memory, size_t bytes) +{ + const unsigned char *p, *q; + int i; + + p = memory; + while (bytes) { + q = p; + printf("%p: ", (void *) p); + for (i = 0; i < 16 && bytes; ++i) { + printf("%02X ", *p); + ++p; + --bytes; + } + bytes += i; + while (i < 16) { + printf("XX "); + ++i; + } + printf("| "); + p = q; + for (i = 0; i < 16 && bytes; ++i) { + printf("%c", isprint(*p) && !isspace(*p) ? *p : ' '); + ++p; + --bytes; + } + while (i < 16) { + printf(" "); + ++i; + } + printf("\n"); + } + return; +} |