aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/applets.h1
-rw-r--r--include/usage.h33
-rw-r--r--util-linux/Config.in16
-rw-r--r--util-linux/hexdump.c90
4 files changed, 108 insertions, 32 deletions
diff --git a/include/applets.h b/include/applets.h
index 587ccbf51..f188232c4 100644
--- a/include/applets.h
+++ b/include/applets.h
@@ -171,6 +171,7 @@ USE_GREP(APPLET(grep, _BB_DIR_BIN, _BB_SUID_NEVER))
171USE_GUNZIP(APPLET(gunzip, _BB_DIR_BIN, _BB_SUID_NEVER)) 171USE_GUNZIP(APPLET(gunzip, _BB_DIR_BIN, _BB_SUID_NEVER))
172USE_GZIP(APPLET(gzip, _BB_DIR_BIN, _BB_SUID_NEVER)) 172USE_GZIP(APPLET(gzip, _BB_DIR_BIN, _BB_SUID_NEVER))
173USE_HALT(APPLET(halt, _BB_DIR_SBIN, _BB_SUID_NEVER)) 173USE_HALT(APPLET(halt, _BB_DIR_SBIN, _BB_SUID_NEVER))
174USE_HD(APPLET_ODDNAME(hd, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hd))
174USE_HDPARM(APPLET(hdparm, _BB_DIR_SBIN, _BB_SUID_NEVER)) 175USE_HDPARM(APPLET(hdparm, _BB_DIR_SBIN, _BB_SUID_NEVER))
175USE_HEAD(APPLET(head, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) 176USE_HEAD(APPLET(head, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
176USE_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hexdump)) 177USE_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hexdump))
diff --git a/include/usage.h b/include/usage.h
index 592316ace..d0eecdb4a 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -1384,21 +1384,28 @@
1384 "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n" 1384 "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n"
1385 1385
1386#define hexdump_trivial_usage \ 1386#define hexdump_trivial_usage \
1387 "[-[bcCdefnosvx]] [OPTION] FILE" 1387 "[-bcCdefnosvx" USE_FEATURE_HEXDUMP_REVERSE("R") "] FILE..."
1388#define hexdump_full_usage \ 1388#define hexdump_full_usage \
1389 "Display file(s) or standard input in a user specified format" \ 1389 "Display file(s) or standard input in a user specified format" \
1390 "\n\nOptions:\n" \ 1390 "\n\nOptions:" \
1391 " -b One-byte octal display\n" \ 1391 "\n -b One-byte octal display" \
1392 " -c One-byte character display\n" \ 1392 "\n -c One-byte character display" \
1393 " -C Canonical hex+ASCII, 16 bytes per line\n" \ 1393 "\n -C Canonical hex+ASCII, 16 bytes per line" \
1394 " -d Two-byte decimal display\n" \ 1394 "\n -d Two-byte decimal display" \
1395 " -e FORMAT STRING\n" \ 1395 "\n -e FORMAT STRING" \
1396 " -f FORMAT FILE\n" \ 1396 "\n -f FORMAT FILE" \
1397 " -n LENGTH Interpret only LENGTH bytes of input\n" \ 1397 "\n -n LENGTH Interpret only LENGTH bytes of input" \
1398 " -o Two-byte octal display\n" \ 1398 "\n -o Two-byte octal display" \
1399 " -s OFFSET Skip OFFSET bytes\n" \ 1399 "\n -s OFFSET Skip OFFSET bytes" \
1400 " -v Display all input data\n" \ 1400 "\n -v Display all input data" \
1401 " -x Two-byte hexadecimal display" 1401 "\n -x Two-byte hexadecimal display" \
1402 USE_FEATURE_HEXDUMP_REVERSE( \
1403 "\n -R Reverse of 'hexdump -Cv'") \
1404
1405#define hd_trivial_usage \
1406 "FILE..."
1407#define hd_full_usage \
1408 "hd is an alias for hexdump -C"
1402 1409
1403#define hostid_trivial_usage \ 1410#define hostid_trivial_usage \
1404 "" 1411 ""
diff --git a/util-linux/Config.in b/util-linux/Config.in
index 107382f51..8b0bbd65d 100644
--- a/util-linux/Config.in
+++ b/util-linux/Config.in
@@ -210,6 +210,22 @@ config HEXDUMP
210 The hexdump utility is used to display binary data in a readable 210 The hexdump utility is used to display binary data in a readable
211 way that is comparable to the output from most hex editors. 211 way that is comparable to the output from most hex editors.
212 212
213config HD
214 bool "hd"
215 default n
216 help
217 hd is an alias to hexdump -C.
218
219config FEATURE_HEXDUMP_REVERSE
220 bool "Support -R, reverse of 'hexdump -Cv'"
221 default n
222 depends on HEXDUMP
223 help
224 The hexdump utility is used to display binary data in an ascii
225 readable way. This option creates binary data from an ascii input.
226 NB: this option is non-standard. It's unwise to use it in scripts
227 aimed to be portable.
228
213config HWCLOCK 229config HWCLOCK
214 bool "hwclock" 230 bool "hwclock"
215 default n 231 default n
diff --git a/util-linux/hexdump.c b/util-linux/hexdump.c
index e6820ae8d..670867054 100644
--- a/util-linux/hexdump.c
+++ b/util-linux/hexdump.c
@@ -45,7 +45,7 @@ static const char *const add_strings[] = {
45 45
46static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; 46static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\"";
47 47
48static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v"; 48static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" USE_FEATURE_HEXDUMP_REVERSE("R");
49 49
50static const struct suffix_mult suffixes[] = { 50static const struct suffix_mult suffixes[] = {
51 { "b", 512 }, 51 { "b", 512 },
@@ -59,10 +59,21 @@ int hexdump_main(int argc, char **argv)
59{ 59{
60 const char *p; 60 const char *p;
61 int ch; 61 int ch;
62#if ENABLE_FEATURE_HEXDUMP_REVERSE
63 FILE *fp;
64 smallint rdump = 0;
65#endif
62 66
63 bb_dump_vflag = FIRST; 67 bb_dump_vflag = FIRST;
64 bb_dump_length = -1; 68 bb_dump_length = -1;
65 69
70 if (ENABLE_HD && !applet_name[2]) { /* we are "hd" */
71 ch = 'C';
72 goto hd_applet;
73 }
74
75 /* We cannot use getopt32: in hexdump options are cumulative.
76 * E.g. hexdump -C -C file should dump each line twice */
66 while ((ch = getopt(argc, argv, hexdump_opts)) > 0) { 77 while ((ch = getopt(argc, argv, hexdump_opts)) > 0) {
67 p = strchr(hexdump_opts, ch); 78 p = strchr(hexdump_opts, ch);
68 if (!p) 79 if (!p)
@@ -70,28 +81,34 @@ int hexdump_main(int argc, char **argv)
70 if ((p - hexdump_opts) < 5) { 81 if ((p - hexdump_opts) < 5) {
71 bb_dump_add(add_first); 82 bb_dump_add(add_first);
72 bb_dump_add(add_strings[(int)(p - hexdump_opts)]); 83 bb_dump_add(add_strings[(int)(p - hexdump_opts)]);
73 } else if (ch == 'C') { 84 }
85 /* Save a little bit of space below by omitting the 'else's. */
86 if (ch == 'C') {
87 hd_applet:
74 bb_dump_add("\"%08.8_Ax\n\""); 88 bb_dump_add("\"%08.8_Ax\n\"");
75 bb_dump_add("\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" "); 89 bb_dump_add("\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" ");
76 bb_dump_add("\" |\" 16/1 \"%_p\" \"|\\n\""); 90 bb_dump_add("\" |\" 16/1 \"%_p\" \"|\\n\"");
77 } else {
78 /* Save a little bit of space below by omitting the 'else's. */
79 if (ch == 'e') {
80 bb_dump_add(optarg);
81 } /* else */
82 if (ch == 'f') {
83 bb_dump_addfile(optarg);
84 } /* else */
85 if (ch == 'n') {
86 bb_dump_length = xatoi_u(optarg);
87 } /* else */
88 if (ch == 's') {
89 bb_dump_skip = xatoul_range_sfx(optarg, 0, LONG_MAX, suffixes);
90 } /* else */
91 if (ch == 'v') {
92 bb_dump_vflag = ALL;
93 }
94 } 91 }
92 if (ch == 'e') {
93 bb_dump_add(optarg);
94 } /* else */
95 if (ch == 'f') {
96 bb_dump_addfile(optarg);
97 } /* else */
98 if (ch == 'n') {
99 bb_dump_length = xatoi_u(optarg);
100 } /* else */
101 if (ch == 's') {
102 bb_dump_skip = xatoul_range_sfx(optarg, 0, LONG_MAX, suffixes);
103 } /* else */
104 if (ch == 'v') {
105 bb_dump_vflag = ALL;
106 }
107#if ENABLE_FEATURE_HEXDUMP_REVERSE
108 if (ch == 'R') {
109 rdump = 1;
110 }
111#endif
95 } 112 }
96 113
97 if (!bb_dump_fshead) { 114 if (!bb_dump_fshead) {
@@ -101,5 +118,40 @@ int hexdump_main(int argc, char **argv)
101 118
102 argv += optind; 119 argv += optind;
103 120
121#if !ENABLE_FEATURE_HEXDUMP_REVERSE
104 return bb_dump_dump(argv); 122 return bb_dump_dump(argv);
123#else
124 if (!rdump) {
125 return bb_dump_dump(argv);
126 }
127
128 /* -R: reverse of 'hexdump -Cv' */
129 fp = stdin;
130 if (!*argv) {
131 argv--;
132 goto jump_in;
133 }
134
135 do {
136 char *buf;
137 fp = xfopen(*argv, "r");
138 jump_in:
139 while ((buf = xmalloc_getline(fp)) != NULL) {
140 p = buf;
141 while (1) {
142 /* skip address or previous byte */
143 while (isxdigit(*p)) p++;
144 while (*p == ' ') p++;
145 /* '|' char will break the line */
146 if (!isxdigit(*p) || sscanf(p, "%x ", &ch) != 1)
147 break;
148 putchar(ch);
149 }
150 free(buf);
151 }
152 fclose(fp);
153 } while (*++argv);
154
155 fflush_stdout_and_exit(EXIT_SUCCESS);
156#endif
105} 157}