source: branches/3.2/mindi-busybox/util-linux/hexdump.c @ 3232

Last change on this file since 3232 was 3232, checked in by bruno, 5 years ago
  • Update mindi-busybox to 1.21.1
File size: 4.5 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * hexdump implementation for busybox
4 * Based on code from util-linux v 2.11l
5 *
6 * Copyright (c) 1989
7 * The Regents of the University of California.  All rights reserved.
8 *
9 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
10 */
11
12//usage:#define hexdump_trivial_usage
13//usage:       "[-bcCdefnosvx" IF_FEATURE_HEXDUMP_REVERSE("R") "] [FILE]..."
14//usage:#define hexdump_full_usage "\n\n"
15//usage:       "Display FILEs (or stdin) in a user specified format\n"
16//usage:     "\n    -b      One-byte octal display"
17//usage:     "\n    -c      One-byte character display"
18//usage:     "\n    -C      Canonical hex+ASCII, 16 bytes per line"
19//usage:     "\n    -d      Two-byte decimal display"
20//usage:     "\n    -e FORMAT_STRING"
21//usage:     "\n    -f FORMAT_FILE"
22//usage:     "\n    -n LENGTH   Interpret only LENGTH bytes of input"
23//usage:     "\n    -o      Two-byte octal display"
24//usage:     "\n    -s OFFSET   Skip OFFSET bytes"
25//usage:     "\n    -v      Display all input data"
26//usage:     "\n    -x      Two-byte hexadecimal display"
27//usage:    IF_FEATURE_HEXDUMP_REVERSE(
28//usage:     "\n    -R      Reverse of 'hexdump -Cv'")
29//usage:
30//usage:#define hd_trivial_usage
31//usage:       "FILE..."
32//usage:#define hd_full_usage "\n\n"
33//usage:       "hd is an alias for hexdump -C"
34
35#include "libbb.h"
36#include "dump.h"
37
38/* This is a NOEXEC applet. Be very careful! */
39
40static void bb_dump_addfile(dumper_t *dumper, char *name)
41{
42    char *p;
43    FILE *fp;
44    char *buf;
45
46    fp = xfopen_for_read(name);
47    while ((buf = xmalloc_fgetline(fp)) != NULL) {
48        p = skip_whitespace(buf);
49        if (*p && (*p != '#')) {
50            bb_dump_add(dumper, p);
51        }
52        free(buf);
53    }
54    fclose(fp);
55}
56
57static const char *const add_strings[] = {
58    "\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"",   /* b */
59    "\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"",   /* c */
60    "\"%07.7_ax \" 8/2 \"  %05u \" \"\\n\"",  /* d */
61    "\"%07.7_ax \" 8/2 \" %06o \" \"\\n\"",   /* o */
62    "\"%07.7_ax \" 8/2 \"   %04x \" \"\\n\"", /* x */
63};
64
65static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\"";
66
67static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" IF_FEATURE_HEXDUMP_REVERSE("R");
68
69static const struct suffix_mult suffixes[] = {
70    { "b", 512 },
71    { "k", 1024 },
72    { "m", 1024*1024 },
73    { "", 0 }
74};
75
76int hexdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
77int hexdump_main(int argc, char **argv)
78{
79    dumper_t *dumper = alloc_dumper();
80    const char *p;
81    int ch;
82#if ENABLE_FEATURE_HEXDUMP_REVERSE
83    FILE *fp;
84    smallint rdump = 0;
85#endif
86
87    if (ENABLE_HD && !applet_name[2]) { /* we are "hd" */
88        ch = 'C';
89        goto hd_applet;
90    }
91
92    /* We cannot use getopt32: in hexdump options are cumulative.
93     * E.g. "hexdump -C -C file" should dump each line twice */
94    while ((ch = getopt(argc, argv, hexdump_opts)) > 0) {
95        p = strchr(hexdump_opts, ch);
96        if (!p)
97            bb_show_usage();
98        if ((p - hexdump_opts) < 5) {
99            bb_dump_add(dumper, add_first);
100            bb_dump_add(dumper, add_strings[(int)(p - hexdump_opts)]);
101        }
102        /* Save a little bit of space below by omitting the 'else's. */
103        if (ch == 'C') {
104 hd_applet:
105            bb_dump_add(dumper, "\"%08.8_Ax\n\"");
106            bb_dump_add(dumper, "\"%08.8_ax  \" 8/1 \"%02x \" \"  \" 8/1 \"%02x \" ");
107            bb_dump_add(dumper, "\"  |\" 16/1 \"%_p\" \"|\\n\"");
108        }
109        if (ch == 'e') {
110            bb_dump_add(dumper, optarg);
111        } /* else */
112        if (ch == 'f') {
113            bb_dump_addfile(dumper, optarg);
114        } /* else */
115        if (ch == 'n') {
116            dumper->dump_length = xatoi_positive(optarg);
117        } /* else */
118        if (ch == 's') { /* compat: -s accepts hex numbers too */
119            dumper->dump_skip = xstrtoul_range_sfx(optarg, /*base:*/ 0, /*lo:*/ 0, /*hi:*/ LONG_MAX, suffixes);
120        } /* else */
121        if (ch == 'v') {
122            dumper->dump_vflag = ALL;
123        }
124#if ENABLE_FEATURE_HEXDUMP_REVERSE
125        if (ch == 'R') {
126            rdump = 1;
127        }
128#endif
129    }
130
131    if (!dumper->fshead) {
132        bb_dump_add(dumper, add_first);
133        bb_dump_add(dumper, "\"%07.7_ax \" 8/2 \"%04x \" \"\\n\"");
134    }
135
136    argv += optind;
137
138#if !ENABLE_FEATURE_HEXDUMP_REVERSE
139    return bb_dump_dump(dumper, argv);
140#else
141    if (!rdump) {
142        return bb_dump_dump(dumper, argv);
143    }
144
145    /* -R: reverse of 'hexdump -Cv' */
146    fp = stdin;
147    if (!*argv) {
148        argv--;
149        goto jump_in;
150    }
151
152    do {
153        char *buf;
154        fp = xfopen_for_read(*argv);
155 jump_in:
156        while ((buf = xmalloc_fgetline(fp)) != NULL) {
157            p = buf;
158            while (1) {
159                /* skip address or previous byte */
160                while (isxdigit(*p)) p++;
161                while (*p == ' ') p++;
162                /* '|' char will break the line */
163                if (!isxdigit(*p) || sscanf(p, "%x ", &ch) != 1)
164                    break;
165                putchar(ch);
166            }
167            free(buf);
168        }
169        fclose(fp);
170    } while (*++argv);
171
172    fflush_stdout_and_exit(EXIT_SUCCESS);
173#endif
174}
Note: See TracBrowser for help on using the repository browser.