9 |
* Licensed under GPLv2 or later, see file License in this tarball for details. |
* Licensed under GPLv2 or later, see file License in this tarball for details. |
10 |
*/ |
*/ |
11 |
|
|
12 |
#include "busybox.h" |
#include "libbb.h" |
|
#include <getopt.h> |
|
13 |
#include "dump.h" |
#include "dump.h" |
14 |
|
|
15 |
static void bb_dump_addfile(char *name) |
/* This is a NOEXEC applet. Be very careful! */ |
16 |
|
|
17 |
|
static void bb_dump_addfile(dumper_t *dumper, char *name) |
18 |
{ |
{ |
19 |
char *p; |
char *p; |
20 |
FILE *fp; |
FILE *fp; |
21 |
char *buf; |
char *buf; |
22 |
|
|
23 |
fp = xfopen(name, "r"); |
fp = xfopen_for_read(name); |
24 |
|
while ((buf = xmalloc_fgetline(fp)) != NULL) { |
|
while ((buf = xmalloc_getline(fp)) != NULL) { |
|
25 |
p = skip_whitespace(buf); |
p = skip_whitespace(buf); |
|
|
|
26 |
if (*p && (*p != '#')) { |
if (*p && (*p != '#')) { |
27 |
bb_dump_add(p); |
bb_dump_add(dumper, p); |
28 |
} |
} |
29 |
free(buf); |
free(buf); |
30 |
} |
} |
31 |
fclose(fp); |
fclose(fp); |
32 |
} |
} |
33 |
|
|
34 |
static const char * const add_strings[] = { |
static const char *const add_strings[] = { |
35 |
"\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"", /* b */ |
"\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"", /* b */ |
36 |
"\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"", /* c */ |
"\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"", /* c */ |
37 |
"\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"", /* d */ |
"\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"", /* d */ |
39 |
"\"%07.7_ax \" 8/2 \" %04x \" \"\\n\"", /* x */ |
"\"%07.7_ax \" 8/2 \" %04x \" \"\\n\"", /* x */ |
40 |
}; |
}; |
41 |
|
|
42 |
static const char add_first[] = "\"%07.7_Ax\n\""; |
static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; |
43 |
|
|
44 |
static const char hexdump_opts[] = "bcdoxCe:f:n:s:v"; |
static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" IF_FEATURE_HEXDUMP_REVERSE("R"); |
45 |
|
|
46 |
static const struct suffix_mult suffixes[] = { |
static const struct suffix_mult suffixes[] = { |
47 |
{"b", 512 }, |
{ "b", 512 }, |
48 |
{"k", 1024 }, |
{ "k", 1024 }, |
49 |
{"m", 1024*1024 }, |
{ "m", 1024*1024 }, |
50 |
{NULL, 0 } |
{ "", 0 } |
51 |
}; |
}; |
52 |
|
|
53 |
|
int hexdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
54 |
int hexdump_main(int argc, char **argv) |
int hexdump_main(int argc, char **argv) |
55 |
{ |
{ |
56 |
|
dumper_t *dumper = alloc_dumper(); |
57 |
const char *p; |
const char *p; |
58 |
int ch; |
int ch; |
59 |
|
#if ENABLE_FEATURE_HEXDUMP_REVERSE |
60 |
|
FILE *fp; |
61 |
|
smallint rdump = 0; |
62 |
|
#endif |
63 |
|
|
64 |
bb_dump_vflag = FIRST; |
if (ENABLE_HD && !applet_name[2]) { /* we are "hd" */ |
65 |
bb_dump_length = -1; |
ch = 'C'; |
66 |
|
goto hd_applet; |
67 |
|
} |
68 |
|
|
69 |
|
/* We cannot use getopt32: in hexdump options are cumulative. |
70 |
|
* E.g. "hexdump -C -C file" should dump each line twice */ |
71 |
while ((ch = getopt(argc, argv, hexdump_opts)) > 0) { |
while ((ch = getopt(argc, argv, hexdump_opts)) > 0) { |
72 |
p = strchr(hexdump_opts, ch); |
p = strchr(hexdump_opts, ch); |
73 |
if (!p) |
if (!p) |
74 |
bb_show_usage(); |
bb_show_usage(); |
75 |
if ((p - hexdump_opts) < 5) { |
if ((p - hexdump_opts) < 5) { |
76 |
bb_dump_add(add_first); |
bb_dump_add(dumper, add_first); |
77 |
bb_dump_add(add_strings[(int)(p - hexdump_opts)]); |
bb_dump_add(dumper, add_strings[(int)(p - hexdump_opts)]); |
78 |
} else if (ch == 'C') { |
} |
79 |
bb_dump_add("\"%08.8_Ax\n\""); |
/* Save a little bit of space below by omitting the 'else's. */ |
80 |
bb_dump_add("\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" "); |
if (ch == 'C') { |
81 |
bb_dump_add("\" |\" 16/1 \"%_p\" \"|\\n\""); |
hd_applet: |
82 |
} else { |
bb_dump_add(dumper, "\"%08.8_Ax\n\""); |
83 |
/* Save a little bit of space below by omitting the 'else's. */ |
bb_dump_add(dumper, "\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" "); |
84 |
if (ch == 'e') { |
bb_dump_add(dumper, "\" |\" 16/1 \"%_p\" \"|\\n\""); |
85 |
bb_dump_add(optarg); |
} |
86 |
} /* else */ |
if (ch == 'e') { |
87 |
if (ch == 'f') { |
bb_dump_add(dumper, optarg); |
88 |
bb_dump_addfile(optarg); |
} /* else */ |
89 |
} /* else */ |
if (ch == 'f') { |
90 |
if (ch == 'n') { |
bb_dump_addfile(dumper, optarg); |
91 |
bb_dump_length = xatoi_u(optarg); |
} /* else */ |
92 |
} /* else */ |
if (ch == 'n') { |
93 |
if (ch == 's') { |
dumper->dump_length = xatoi_u(optarg); |
94 |
bb_dump_skip = xatoul_range_sfx(optarg, 0, LONG_MAX, suffixes); |
} /* else */ |
95 |
} /* else */ |
if (ch == 's') { |
96 |
if (ch == 'v') { |
dumper->dump_skip = xatoul_range_sfx(optarg, 0, LONG_MAX, suffixes); |
97 |
bb_dump_vflag = ALL; |
} /* else */ |
98 |
} |
if (ch == 'v') { |
99 |
|
dumper->dump_vflag = ALL; |
100 |
} |
} |
101 |
|
#if ENABLE_FEATURE_HEXDUMP_REVERSE |
102 |
|
if (ch == 'R') { |
103 |
|
rdump = 1; |
104 |
|
} |
105 |
|
#endif |
106 |
} |
} |
107 |
|
|
108 |
if (!bb_dump_fshead) { |
if (!dumper->fshead) { |
109 |
bb_dump_add(add_first); |
bb_dump_add(dumper, add_first); |
110 |
bb_dump_add("\"%07.7_ax \" 8/2 \"%04x \" \"\\n\""); |
bb_dump_add(dumper, "\"%07.7_ax \" 8/2 \"%04x \" \"\\n\""); |
111 |
} |
} |
112 |
|
|
113 |
argv += optind; |
argv += optind; |
114 |
|
|
115 |
return bb_dump_dump(argv); |
#if !ENABLE_FEATURE_HEXDUMP_REVERSE |
116 |
|
return bb_dump_dump(dumper, argv); |
117 |
|
#else |
118 |
|
if (!rdump) { |
119 |
|
return bb_dump_dump(dumper, argv); |
120 |
|
} |
121 |
|
|
122 |
|
/* -R: reverse of 'hexdump -Cv' */ |
123 |
|
fp = stdin; |
124 |
|
if (!*argv) { |
125 |
|
argv--; |
126 |
|
goto jump_in; |
127 |
|
} |
128 |
|
|
129 |
|
do { |
130 |
|
char *buf; |
131 |
|
fp = xfopen_for_read(*argv); |
132 |
|
jump_in: |
133 |
|
while ((buf = xmalloc_fgetline(fp)) != NULL) { |
134 |
|
p = buf; |
135 |
|
while (1) { |
136 |
|
/* skip address or previous byte */ |
137 |
|
while (isxdigit(*p)) p++; |
138 |
|
while (*p == ' ') p++; |
139 |
|
/* '|' char will break the line */ |
140 |
|
if (!isxdigit(*p) || sscanf(p, "%x ", &ch) != 1) |
141 |
|
break; |
142 |
|
putchar(ch); |
143 |
|
} |
144 |
|
free(buf); |
145 |
|
} |
146 |
|
fclose(fp); |
147 |
|
} while (*++argv); |
148 |
|
|
149 |
|
fflush_stdout_and_exit(EXIT_SUCCESS); |
150 |
|
#endif |
151 |
} |
} |