diff options
-rw-r--r-- | include/applets.h | 1 | ||||
-rw-r--r-- | include/usage.h | 33 | ||||
-rw-r--r-- | util-linux/Config.in | 16 | ||||
-rw-r--r-- | util-linux/hexdump.c | 90 |
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)) | |||
171 | USE_GUNZIP(APPLET(gunzip, _BB_DIR_BIN, _BB_SUID_NEVER)) | 171 | USE_GUNZIP(APPLET(gunzip, _BB_DIR_BIN, _BB_SUID_NEVER)) |
172 | USE_GZIP(APPLET(gzip, _BB_DIR_BIN, _BB_SUID_NEVER)) | 172 | USE_GZIP(APPLET(gzip, _BB_DIR_BIN, _BB_SUID_NEVER)) |
173 | USE_HALT(APPLET(halt, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 173 | USE_HALT(APPLET(halt, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
174 | USE_HD(APPLET_ODDNAME(hd, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hd)) | ||
174 | USE_HDPARM(APPLET(hdparm, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 175 | USE_HDPARM(APPLET(hdparm, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
175 | USE_HEAD(APPLET(head, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 176 | USE_HEAD(APPLET(head, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
176 | USE_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hexdump)) | 177 | USE_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 | ||
213 | config HD | ||
214 | bool "hd" | ||
215 | default n | ||
216 | help | ||
217 | hd is an alias to hexdump -C. | ||
218 | |||
219 | config 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 | |||
213 | config HWCLOCK | 229 | config 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 | ||
46 | static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; | 46 | static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; |
47 | 47 | ||
48 | static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v"; | 48 | static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" USE_FEATURE_HEXDUMP_REVERSE("R"); |
49 | 49 | ||
50 | static const struct suffix_mult suffixes[] = { | 50 | static 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 | } |