source: bootcd/isolinux/syslinux-6.03/com32/modules/hexdump.c @ dd1be7c

Last change on this file since dd1be7c was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 4.9 KB
Line 
1#include <stddef.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <ctype.h>
6#include <console.h>
7#include <errno.h>
8#include <syslinux/loadfile.h>
9
10/* Macros */
11#define ROWS_PER_PAGE 24
12#define COLS_PER_ROW 16
13#define BYTES_PER_PAGE (ROWS_PER_PAGE * COLS_PER_ROW)
14
15/* Functions declarations */
16static int usage(void);
17static void eat_stdin(void);
18static int do_page(void);
19static void hexdump(const void *memory, size_t bytes);
20
21/* Objects */
22static const char *prog_name;
23static int opt_page;
24static int opt_no_buffer;
25static int opt_extended_ascii;
26
27int main(int argc, char **argv)
28{
29    int rc;
30    const char *filename;
31    int i;
32    void *file_data;
33    size_t file_sz;
34    FILE *f;
35    size_t len;
36    const char *cur_pos;
37
38    /* Assume failure */
39    rc = EXIT_FAILURE;
40
41    /* Determine the program name, as invoked */
42    if (argc < 1 || !argv || !argv[0]) {
43        fprintf(stderr, "argc or argv failure!\n");
44        goto err_prog_name;
45    }
46    prog_name = argv[0];
47
48    /* Process arguments */
49    filename = NULL;
50    for (i = 1; i < argc; ++i) {
51        if (!argv[i]) {
52            fprintf(stderr, "argc and argv mismatch!\n");
53            goto err_argv;
54        }
55
56        if (!strncmp(argv[i], "--page", sizeof "--page") ||
57            !strncmp(argv[i], "-p", sizeof "-p")) {
58            opt_page = 1;
59            continue;
60        }
61
62        if (!strncmp(argv[i], "--no-buffer", sizeof "--no-buffer")) {
63            opt_no_buffer = 1;
64            continue;
65        }
66
67        if (!strncmp(argv[i], "--extended-ascii", sizeof "--extended-ascii")) {
68            opt_extended_ascii = 1;
69            continue;
70        }
71
72        if (!strncmp(argv[i], "--help", sizeof "--help") ||
73            !strncmp(argv[i], "-h", sizeof "-h") ||
74            !strncmp(argv[i], "-?", sizeof "-?"))
75            return usage();
76
77        /* Otherwise, interpret as a filename, but only accept one */
78        if (filename)
79            return usage();
80        filename = argv[i];
81    }
82    if (!filename)
83        return usage();
84    fprintf(stdout, "Dumping file: %s\n", filename);
85
86    /* Either fetch the whole file, or just allocate a buffer */
87    f = NULL;
88    if (opt_no_buffer) {
89        errno = 0;
90        if (loadfile(filename, &file_data, &file_sz)) {
91            fprintf(stderr, "Couldn't load file.  Error: %d\n", errno);
92            goto err_file_data;
93        }
94    } else {
95        file_sz = BYTES_PER_PAGE;
96        file_data = malloc(file_sz);
97        if (!file_data) {
98            fprintf(stderr, "Couldn't allocate file data buffer\n");
99            goto err_file_data;
100        }
101        errno = 0;
102        f = fopen(filename, "r");
103        if (!f) {
104            fprintf(stderr, "Couldn't open file.  Error: %d\n", errno);
105            goto err_f;
106        }
107    }
108
109    /* Dump the data */
110    len = BYTES_PER_PAGE;
111    cur_pos = file_data;
112    do {
113        if (f) {
114            /* Buffered */
115            len = fread(file_data, 1, file_sz, f);
116            cur_pos = file_data;
117        } else {
118            /* Non-buffered */
119            if (file_sz < len)
120                len = file_sz;
121        }
122        if (!len)
123            break;
124
125        hexdump(cur_pos, len);
126
127        /* Pause, if requested */
128        if (opt_page) {
129            /* The user might choose to quit */
130            if (do_page())
131                break;
132        }
133
134        /* Reduce file_sz for non-buffered mode */
135        if (!f)
136            file_sz -= len;
137    } while (cur_pos += len);
138
139    rc = EXIT_SUCCESS;
140
141    if (f)
142        fclose(f);
143    err_f:
144
145    free(file_data);
146    err_file_data:
147
148    err_argv:
149
150    err_prog_name:
151
152    return rc;
153}
154
155static int usage(void)
156{
157    static const char usage[] =
158        "Usage: %s [<option> [...]] <filename> [<option> [...]]\n"
159        "\n"
160        "Options: -p\n"
161        "         --page . . . . . . . Pause output every 24 lines\n"
162        "         --no-buffer . . . .  Load the entire file before dumping\n"
163        "         --extended-ascii . . Use extended ASCII chars in dump\n"
164        "         -?\n"
165        "         -h\n"
166        "         --help  . . . . . .  Display this help\n";
167
168    fprintf(stderr, usage, prog_name);
169    return EXIT_FAILURE;
170}
171
172static void eat_stdin(void)
173{
174    int i;
175
176    while (1) {
177        i = fgetc(stdin);
178        if (i == EOF || i == '\n')
179            return;
180    }
181}
182static int do_page(void)
183{
184    int i;
185
186    while (1) {
187        fprintf(stdout, "Continue? [Y|n]: ");
188        i = fgetc(stdin);
189        switch (i) {
190            case 'n':
191            case 'N':
192            eat_stdin();
193            return 1;
194
195            case EOF:
196            fprintf(stderr, "No response.  Continuing...\n");
197            /* Fall through to "yes" */
198
199            case 'y':
200            case 'Y':
201            eat_stdin();
202            case '\n':
203            return 0;
204
205            default:
206            fprintf(stderr, "Invalid choice\n");
207            eat_stdin();
208        }
209    }
210}
211
212static void hexdump(const void *memory, size_t bytes)
213{
214    const unsigned char *p, *q;
215    int i;
216 
217    p = memory;
218    while (bytes) {
219        q = p;
220        printf("%p: ", (void *) p);
221        for (i = 0; i < 16 && bytes; ++i) {
222            printf("%02X ", *p);
223            ++p;
224            --bytes;
225          }
226        bytes += i;
227        while (i < 16) {
228            printf("XX ");
229            ++i;
230          }
231        printf("| ");
232        p = q;
233        for (i = 0; i < 16 && bytes; ++i) {
234            printf("%c", isprint(*p) && !isspace(*p) ? *p : ' ');
235            ++p;
236            --bytes;
237          }
238        while (i < 16) {
239            printf(" ");
240            ++i;
241          }
242        printf("\n");
243      }
244    return;
245}
Note: See TracBrowser for help on using the repository browser.