1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57#include "libbb.h"
58#include "dump.h"
59
60
61
62#define OPT_l (1 << 0)
63#define OPT_s (1 << 1)
64#define OPT_a (1 << 2)
65#define OPT_p (1 << 3)
66#define OPT_i (1 << 4)
67#define OPT_r (1 << 5)
68#define OPT_g (1 << 6)
69#define OPT_c (1 << 7)
70#define OPT_o (1 << 8)
71
72static void reverse(unsigned opt, const char *filename)
73{
74 FILE *fp;
75 char *buf;
76
77 fp = filename ? xfopen_for_read(filename) : stdin;
78
79 while ((buf = xmalloc_fgetline(fp)) != NULL) {
80 char *p;
81
82 p = buf;
83 if (!(opt & OPT_p)) {
84
85 while (isxdigit(*p)) p++;
86
87
88 if (*p == ':') p++;
89
90
91
92 }
93
94
95 for (;;) {
96 uint8_t val, c;
97 nibble1:
98 p = skip_whitespace(p);
99
100 c = *p++;
101 if (isdigit(c))
102 val = c - '0';
103 else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
104 val = (c|0x20) - ('a' - 10);
105 else {
106
107
108
109
110
111
112
113
114 if (c != '\0')
115 goto nibble1;
116 break;
117 }
118 val <<= 4;
119
120
121
122
123
124
125 nibble2:
126 p = skip_whitespace(p);
127
128 c = *p++;
129 if (isdigit(c))
130 val |= c - '0';
131 else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
132 val |= (c|0x20) - ('a' - 10);
133 else {
134 if (c != '\0') {
135
136 goto nibble1;
137 }
138
139
140
141
142 free(buf);
143 p = buf = xmalloc_fgetline(fp);
144 if (!buf)
145 break;
146 goto nibble2;
147 }
148 putchar(val);
149 }
150 free(buf);
151 }
152
153 fflush_stdout_and_exit(EXIT_SUCCESS);
154}
155
156static void print_C_style(const char *p, const char *hdr)
157{
158 printf(hdr, isdigit(p[0]) ? "__" : "");
159 while (*p) {
160 bb_putchar(isalnum(*p) ? *p : '_');
161 p++;
162 }
163}
164
165int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
166int xxd_main(int argc UNUSED_PARAM, char **argv)
167{
168 char buf[80];
169 dumper_t *dumper;
170 char *opt_l, *opt_s, *opt_o;
171 unsigned bytes = 2;
172 unsigned cols = 0;
173 unsigned opt;
174 int r;
175
176 dumper = alloc_dumper();
177
178 opt = getopt32(argv, "^" "l:s:apirg:+c:+o:" "\0" "?1" ,
179 &opt_l, &opt_s, &bytes, &cols, &opt_o
180 );
181 argv += optind;
182
183 dumper->dump_vflag = ALL;
184
185
186 if (opt & OPT_l) {
187 dumper->dump_length = xstrtou_range(
188 opt_l,
189 0,
190 0, INT_MAX
191 );
192 }
193 if (opt & OPT_s) {
194 dumper->dump_skip = xstrtoull_range(
195 opt_s,
196 0,
197 0, OFF_T_MAX
198 );
199
200 }
201
202 if (opt & OPT_r) {
203 reverse(opt, argv[0]);
204 }
205
206 if (opt & OPT_o) {
207
208 dumper->xxd_displayoff = xstrtoll(opt_o, 0);
209 }
210
211 if (opt & OPT_p) {
212 if (cols == 0)
213 cols = 30;
214 bytes = cols;
215 } else {
216 if (cols == 0)
217 cols = (opt & OPT_i) ? 12 : 16;
218 if (opt & OPT_i) {
219 bytes = 1;
220
221 bb_dump_add(dumper, "\" \"");
222 } else
223 bb_dump_add(dumper, "\"%08.8_ax: \"");
224 }
225
226 if (bytes < 1 || bytes >= cols) {
227 sprintf(buf, "%u/1 \"%%02x\"", cols);
228 bb_dump_add(dumper, buf);
229 }
230 else if (bytes == 1) {
231 if (opt & OPT_i)
232 sprintf(buf, "%u/1 \" 0x%%02x,\"", cols);
233
234 else
235 sprintf(buf, "%u/1 \"%%02x \"", cols);
236 bb_dump_add(dumper, buf);
237 }
238 else {
239
240#define BS "/1 \"%02x \""
241#define B "/1 \"%02x\""
242 unsigned i;
243 char *bigbuf = xmalloc(cols * (sizeof(BS)-1));
244 char *p = bigbuf;
245 for (i = 1; i <= cols; i++) {
246 if (i == cols || i % bytes)
247 p = stpcpy(p, B);
248 else
249 p = stpcpy(p, BS);
250 }
251
252
253
254
255 bb_dump_add(dumper, bigbuf);
256 free(bigbuf);
257 }
258
259 if (!(opt & (OPT_p|OPT_i))) {
260 sprintf(buf, "\" \"%u/1 \"%%_p\"\"\n\"", cols);
261 bb_dump_add(dumper, buf);
262 } else {
263 bb_dump_add(dumper, "\"\n\"");
264 dumper->xxd_eofstring = "\n";
265 }
266
267 if ((opt & OPT_i) && argv[0]) {
268 print_C_style(argv[0], "unsigned char %s");
269 printf("[] = {\n");
270 }
271 r = bb_dump_dump(dumper, argv);
272 if (r == 0 && (opt & OPT_i) && argv[0]) {
273 print_C_style(argv[0], "};\nunsigned int %s");
274 printf("_len = %"OFF_FMT"u;\n", dumper->address);
275 }
276 return r;
277}
278