aboutsummaryrefslogtreecommitdiff
path: root/libbb/dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/dump.c')
-rw-r--r--libbb/dump.c517
1 files changed, 204 insertions, 313 deletions
diff --git a/libbb/dump.c b/libbb/dump.c
index 1afad83fd..26dabe57f 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -25,94 +25,80 @@
25#include <stdlib.h> 25#include <stdlib.h>
26#include <string.h> 26#include <string.h>
27#include <ctype.h> /* for isdigit() */ 27#include <ctype.h> /* for isdigit() */
28#include "dump.h"
29#include "libbb.h" 28#include "libbb.h"
29#include "dump.h"
30 30
31enum _vflag vflag = FIRST; 31enum _vflag bb_dump_vflag = FIRST;
32FS *fshead; /* head of format strings */ 32FS *bb_dump_fshead; /* head of format strings */
33extern FS *fshead; /* head of format strings */
34extern int blocksize;
35static FU *endfu; 33static FU *endfu;
36static char **_argv; 34static char **_argv;
37static off_t savaddress; /* saved address/offset in stream */ 35static off_t savaddress; /* saved address/offset in stream */
38static off_t eaddress; /* end address */ 36static off_t eaddress; /* end address */
39static off_t address; /* address/offset in stream */ 37static off_t address; /* address/offset in stream */
40off_t skip; /* bytes to skip */ 38off_t bb_dump_skip; /* bytes to skip */
41off_t saveaddress; 39static int exitval; /* final exit value */
42int exitval; /* final exit value */ 40int bb_dump_blocksize; /* data block size */
43int blocksize; /* data block size */ 41int bb_dump_length = -1; /* max bytes to read */
44int length = -1; /* max bytes to read */ 42
43static const char index_str[] = ".#-+ 0123456789";
45 44
45static const char size_conv_str[] =
46"\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG";
46 47
47int size(FS * fs) 48static const char lcc[] = "diouxX";
49
50int bb_dump_size(FS * fs)
48{ 51{
49 register FU *fu; 52 register FU *fu;
50 register int bcnt, cursize; 53 register int bcnt, cur_size;
51 register char *fmt; 54 register char *fmt;
55 const char *p;
52 int prec; 56 int prec;
53 57
54 /* figure out the data block size needed for each format unit */ 58 /* figure out the data block bb_dump_size needed for each format unit */
55 for (cursize = 0, fu = fs->nextfu; fu; fu = fu->nextfu) { 59 for (cur_size = 0, fu = fs->nextfu; fu; fu = fu->nextfu) {
56 if (fu->bcnt) { 60 if (fu->bcnt) {
57 cursize += fu->bcnt * fu->reps; 61 cur_size += fu->bcnt * fu->reps;
58 continue; 62 continue;
59 } 63 }
60 for (bcnt = prec = 0, fmt = fu->fmt; *fmt; ++fmt) { 64 for (bcnt = prec = 0, fmt = fu->fmt; *fmt; ++fmt) {
61 if (*fmt != '%') 65 if (*fmt != '%')
62 continue; 66 continue;
63 /* 67 /*
64 * skip any special chars -- save precision in 68 * bb_dump_skip any special chars -- save precision in
65 * case it's a %s format. 69 * case it's a %s format.
66 */ 70 */
67 while (index(".#-+ 0123456789" + 1, *++fmt)); 71 while (strchr(index_str + 1, *++fmt));
68 if (*fmt == '.' && isdigit(*++fmt)) { 72 if (*fmt == '.' && isdigit(*++fmt)) {
69 prec = atoi(fmt); 73 prec = atoi(fmt);
70 while (isdigit(*++fmt)); 74 while (isdigit(*++fmt));
71 } 75 }
72 switch (*fmt) { 76 if (!(p = strchr(size_conv_str + 12, *fmt))) {
73 case 'c': 77 if (*fmt == 's') {
74 bcnt += 1; 78 bcnt += prec;
75 break; 79 } else if (*fmt == '_') {
76 case 'd': 80 ++fmt;
77 case 'i': 81 if ((*fmt == 'c') || (*fmt == 'p') || (*fmt == 'u')) {
78 case 'o': 82 bcnt += 1;
79 case 'u': 83 }
80 case 'x':
81 case 'X':
82 bcnt += 4;
83 break;
84 case 'e':
85 case 'E':
86 case 'f':
87 case 'g':
88 case 'G':
89 bcnt += 8;
90 break;
91 case 's':
92 bcnt += prec;
93 break;
94 case '_':
95 switch (*++fmt) {
96 case 'c':
97 case 'p':
98 case 'u':
99 bcnt += 1;
100 break;
101 } 84 }
85 } else {
86 bcnt += size_conv_str[p - (size_conv_str + 12)];
102 } 87 }
103 } 88 }
104 cursize += bcnt * fu->reps; 89 cur_size += bcnt * fu->reps;
105 } 90 }
106 return (cursize); 91 return (cur_size);
107} 92}
108 93
109void rewrite(FS * fs) 94static void rewrite(FS * fs)
110{ 95{
111 enum { NOTOKAY, USEBCNT, USEPREC } sokay; 96 enum { NOTOKAY, USEBCNT, USEPREC } sokay;
112 register PR *pr, **nextpr = NULL; 97 register PR *pr, **nextpr = NULL;
113 register FU *fu; 98 register FU *fu;
114 register char *p1, *p2; 99 register char *p1, *p2;
115 char savech, *fmtp; 100 char savech, *fmtp;
101 const char *byte_count_str;
116 int nconv, prec = 0; 102 int nconv, prec = 0;
117 103
118 for (fu = fs->nextfu; fu; fu = fu->nextfu) { 104 for (fu = fs->nextfu; fu; fu = fu->nextfu) {
@@ -128,7 +114,7 @@ void rewrite(FS * fs)
128 else 114 else
129 *nextpr = pr; 115 *nextpr = pr;
130 116
131 /* skip preceding text and up to the next % sign */ 117 /* bb_dump_skip preceding text and up to the next % sign */
132 for (p1 = fmtp; *p1 && *p1 != '%'; ++p1); 118 for (p1 = fmtp; *p1 && *p1 != '%'; ++p1);
133 119
134 /* only text in the string */ 120 /* only text in the string */
@@ -144,11 +130,11 @@ void rewrite(FS * fs)
144 */ 130 */
145 if (fu->bcnt) { 131 if (fu->bcnt) {
146 sokay = USEBCNT; 132 sokay = USEBCNT;
147 /* skip to conversion character */ 133 /* bb_dump_skip to conversion character */
148 for (++p1; index(".#-+ 0123456789", *p1); ++p1); 134 for (++p1; strchr(index_str, *p1); ++p1);
149 } else { 135 } else {
150 /* skip any special chars, field width */ 136 /* bb_dump_skip any special chars, field width */
151 while (index(".#-+ 0123456789" + 1, *++p1)); 137 while (strchr(index_str + 1, *++p1));
152 if (*p1 == '.' && isdigit(*++p1)) { 138 if (*p1 == '.' && isdigit(*++p1)) {
153 sokay = USEPREC; 139 sokay = USEPREC;
154 prec = atoi(p1); 140 prec = atoi(p1);
@@ -162,104 +148,59 @@ void rewrite(FS * fs)
162 /* 148 /*
163 * figure out the byte count for each conversion; 149 * figure out the byte count for each conversion;
164 * rewrite the format as necessary, set up blank- 150 * rewrite the format as necessary, set up blank-
165 * padding for end of data. 151 * pbb_dump_adding for end of data.
166 */ 152 */
167 switch (*p1) { 153
168 case 'c': 154 if (*p1 == 'c') {
169 pr->flags = F_CHAR; 155 pr->flags = F_CHAR;
170 switch (fu->bcnt) { 156 DO_BYTE_COUNT_1:
171 case 0: 157 byte_count_str = "\001";
172 case 1: 158 DO_BYTE_COUNT:
173 pr->bcnt = 1; 159 if (fu->bcnt) {
174 break; 160 do {
175 default: 161 if (fu->bcnt == *byte_count_str) {
176 p1[1] = '\0'; 162 break;
177 error_msg_and_die 163 }
178 ("bad byte count for conversion character %s.", p1); 164 } while (*++byte_count_str);
179 } 165 }
180 break; 166 /* Unlike the original, output the remainder of the format string. */
181 case 'd': 167 if (!*byte_count_str) {
182 case 'i': 168 bb_error_msg_and_die("bad byte count for conversion character %s.", p1);
183 pr->flags = F_INT; 169 }
184 goto sw1; 170 pr->bcnt = *byte_count_str;
185 case 'l': 171 } else if (*p1 == 'l') {
186 ++p2; 172 ++p2;
187 switch (p1[1]) { 173 ++p1;
188 case 'd': 174 DO_INT_CONV:
189 case 'i': 175 {
190 ++p1; 176 const char *e;
177 if (!(e = strchr(lcc, *p1))) {
178 goto DO_BAD_CONV_CHAR;
179 }
191 pr->flags = F_INT; 180 pr->flags = F_INT;
192 goto sw1; 181 if (e > lcc + 1) {
193 case 'o': 182 pr->flags = F_UINT;
194 case 'u': 183 }
195 case 'x': 184 byte_count_str = "\004\002\001";
196 case 'X': 185 goto DO_BYTE_COUNT;
197 ++p1;
198 pr->flags = F_UINT;
199 goto sw1;
200 default:
201 p1[2] = '\0';
202 error_msg_and_die
203 ("hexdump: bad conversion character %%%s.\n", p1);
204 } 186 }
205 /* NOTREACHED */ 187 /* NOTREACHED */
206 case 'o': 188 } else if (strchr(lcc, *p1)) {
207 case 'u': 189 goto DO_INT_CONV;
208 case 'x': 190 } else if (strchr("eEfgG", *p1)) {
209 case 'X':
210 pr->flags = F_UINT;
211 sw1:switch (fu->bcnt) {
212 case 0:
213 case 4:
214 pr->bcnt = 4;
215 break;
216 case 1:
217 pr->bcnt = 1;
218 break;
219 case 2:
220 pr->bcnt = 2;
221 break;
222 default:
223 p1[1] = '\0';
224 error_msg_and_die
225 ("bad byte count for conversion character %s.", p1);
226 }
227 break;
228 case 'e':
229 case 'E':
230 case 'f':
231 case 'g':
232 case 'G':
233 pr->flags = F_DBL; 191 pr->flags = F_DBL;
234 switch (fu->bcnt) { 192 byte_count_str = "\010\004";
235 case 0: 193 goto DO_BYTE_COUNT;
236 case 8: 194 } else if (*p1 == 's') {
237 pr->bcnt = 8;
238 break;
239 case 4:
240 pr->bcnt = 4;
241 break;
242 default:
243 p1[1] = '\0';
244 error_msg_and_die
245 ("bad byte count for conversion character %s.", p1);
246 }
247 break;
248 case 's':
249 pr->flags = F_STR; 195 pr->flags = F_STR;
250 switch (sokay) { 196 if (sokay == USEBCNT) {
251 case NOTOKAY:
252 error_msg_and_die
253 ("%%s requires a precision or a byte count.");
254 case USEBCNT:
255 pr->bcnt = fu->bcnt; 197 pr->bcnt = fu->bcnt;
256 break; 198 } else if (sokay == USEPREC) {
257 case USEPREC:
258 pr->bcnt = prec; 199 pr->bcnt = prec;
259 break; 200 } else { /* NOTOKAY */
201 bb_error_msg_and_die("%%s requires a precision or a byte count.");
260 } 202 }
261 break; 203 } else if (*p1 == '_') {
262 case '_':
263 ++p2; 204 ++p2;
264 switch (p1[1]) { 205 switch (p1[1]) {
265 case 'A': 206 case 'A':
@@ -269,51 +210,29 @@ void rewrite(FS * fs)
269 case 'a': 210 case 'a':
270 pr->flags = F_ADDRESS; 211 pr->flags = F_ADDRESS;
271 ++p2; 212 ++p2;
272 switch (p1[2]) { 213 if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) {
273 case 'd': 214 goto DO_BAD_CONV_CHAR;
274 case 'o':
275 case 'x':
276 *p1 = p1[2];
277 break;
278 default:
279 p1[3] = '\0';
280 error_msg_and_die
281 ("hexdump: bad conversion character %%%s.\n", p1);
282 } 215 }
216 *p1 = p1[2];
283 break; 217 break;
284 case 'c': 218 case 'c':
285 pr->flags = F_C; 219 pr->flags = F_C;
286 /* *p1 = 'c'; set in conv_c */ 220 /* *p1 = 'c'; set in conv_c */
287 goto sw2; 221 goto DO_BYTE_COUNT_1;
288 case 'p': 222 case 'p':
289 pr->flags = F_P; 223 pr->flags = F_P;
290 *p1 = 'c'; 224 *p1 = 'c';
291 goto sw2; 225 goto DO_BYTE_COUNT_1;
292 case 'u': 226 case 'u':
293 pr->flags = F_U; 227 pr->flags = F_U;
294 /* *p1 = 'c'; set in conv_u */ 228 /* *p1 = 'c'; set in conv_u */
295 sw2:switch (fu->bcnt) { 229 goto DO_BYTE_COUNT_1;
296 case 0:
297 case 1:
298 pr->bcnt = 1;
299 break;
300 default:
301 p1[2] = '\0';
302 error_msg_and_die
303 ("bad byte count for conversion character %s.",
304 p1);
305 }
306 break;
307 default: 230 default:
308 p1[2] = '\0'; 231 goto DO_BAD_CONV_CHAR;
309 error_msg_and_die
310 ("hexdump: bad conversion character %%%s.\n", p1);
311 } 232 }
312 break; 233 } else {
313 default: 234 DO_BAD_CONV_CHAR:
314 p1[1] = '\0'; 235 bb_error_msg_and_die("bad conversion character %%%s.\n", p1);
315 error_msg_and_die("hexdump: bad conversion character %%%s.\n",
316 p1);
317 } 236 }
318 237
319 /* 238 /*
@@ -322,16 +241,14 @@ void rewrite(FS * fs)
322 */ 241 */
323 savech = *p2; 242 savech = *p2;
324 p1[1] = '\0'; 243 p1[1] = '\0';
325 if (!(pr->fmt = strdup(fmtp))) 244 pr->fmt = bb_xstrdup(fmtp);
326 perror_msg_and_die("hexdump");
327 *p2 = savech; 245 *p2 = savech;
328 pr->cchar = pr->fmt + (p1 - fmtp); 246 pr->cchar = pr->fmt + (p1 - fmtp);
329 fmtp = p2; 247 fmtp = p2;
330 248
331 /* only one conversion character if byte count */ 249 /* only one conversion character if byte count */
332 if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) { 250 if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) {
333 error_msg_and_die 251 bb_error_msg_and_die("byte count with multiple conversion characters.\n");
334 ("hexdump: byte count with multiple conversion characters.\n");
335 } 252 }
336 } 253 }
337 /* 254 /*
@@ -344,7 +261,7 @@ void rewrite(FS * fs)
344 } 261 }
345 /* 262 /*
346 * if the format string interprets any data at all, and it's 263 * if the format string interprets any data at all, and it's
347 * not the same as the blocksize, and its last format unit 264 * not the same as the bb_dump_blocksize, and its last format unit
348 * interprets any data at all, and has no iteration count, 265 * interprets any data at all, and has no iteration count,
349 * repeat it as necessary. 266 * repeat it as necessary.
350 * 267 *
@@ -352,9 +269,9 @@ void rewrite(FS * fs)
352 * gets output from the last iteration of the format unit. 269 * gets output from the last iteration of the format unit.
353 */ 270 */
354 for (fu = fs->nextfu;; fu = fu->nextfu) { 271 for (fu = fs->nextfu;; fu = fu->nextfu) {
355 if (!fu->nextfu && fs->bcnt < blocksize && 272 if (!fu->nextfu && fs->bcnt < bb_dump_blocksize &&
356 !(fu->flags & F_SETREP) && fu->bcnt) 273 !(fu->flags & F_SETREP) && fu->bcnt)
357 fu->reps += (blocksize - fs->bcnt) / fu->bcnt; 274 fu->reps += (bb_dump_blocksize - fs->bcnt) / fu->bcnt;
358 if (fu->reps > 1) { 275 if (fu->reps > 1) {
359 for (pr = fu->nextpr;; pr = pr->nextpr) 276 for (pr = fu->nextpr;; pr = pr->nextpr)
360 if (!pr->nextpr) 277 if (!pr->nextpr)
@@ -369,31 +286,31 @@ void rewrite(FS * fs)
369 } 286 }
370} 287}
371 288
372static void doskip(char *fname, int statok) 289static void do_skip(char *fname, int statok)
373{ 290{
374 struct stat sbuf; 291 struct stat sbuf;
375 292
376 if (statok) { 293 if (statok) {
377 if (fstat(fileno(stdin), &sbuf)) { 294 if (fstat(fileno(stdin), &sbuf)) {
378 perror_msg_and_die("hexdump: %s", fname); 295 bb_perror_msg_and_die("%s", fname);
379 } 296 }
380 if ((!(S_ISCHR(sbuf.st_mode) || 297 if ((!(S_ISCHR(sbuf.st_mode) ||
381 S_ISBLK(sbuf.st_mode) || 298 S_ISBLK(sbuf.st_mode) ||
382 S_ISFIFO(sbuf.st_mode))) && skip >= sbuf.st_size) { 299 S_ISFIFO(sbuf.st_mode))) && bb_dump_skip >= sbuf.st_size) {
383 /* If size valid and skip >= size */ 300 /* If bb_dump_size valid and bb_dump_skip >= size */
384 skip -= sbuf.st_size; 301 bb_dump_skip -= sbuf.st_size;
385 address += sbuf.st_size; 302 address += sbuf.st_size;
386 return; 303 return;
387 } 304 }
388 } 305 }
389 if (fseek(stdin, skip, SEEK_SET)) { 306 if (fseek(stdin, bb_dump_skip, SEEK_SET)) {
390 perror_msg_and_die("hexdump: %s", fname); 307 bb_perror_msg_and_die("%s", fname);
391 } 308 }
392 savaddress = address += skip; 309 savaddress = address += bb_dump_skip;
393 skip = 0; 310 bb_dump_skip = 0;
394} 311}
395 312
396int next(char **argv) 313static int next(char **argv)
397{ 314{
398 static int done; 315 static int done;
399 int statok; 316 int statok;
@@ -405,7 +322,7 @@ int next(char **argv)
405 for (;;) { 322 for (;;) {
406 if (*_argv) { 323 if (*_argv) {
407 if (!(freopen(*_argv, "r", stdin))) { 324 if (!(freopen(*_argv, "r", stdin))) {
408 perror_msg("%s", *_argv); 325 bb_perror_msg("%s", *_argv);
409 exitval = 1; 326 exitval = 1;
410 ++_argv; 327 ++_argv;
411 continue; 328 continue;
@@ -416,11 +333,11 @@ int next(char **argv)
416 return (0); 333 return (0);
417 statok = 0; 334 statok = 0;
418 } 335 }
419 if (skip) 336 if (bb_dump_skip)
420 doskip(statok ? *_argv : "stdin", statok); 337 do_skip(statok ? *_argv : "stdin", statok);
421 if (*_argv) 338 if (*_argv)
422 ++_argv; 339 ++_argv;
423 if (!skip) 340 if (!bb_dump_skip)
424 return (1); 341 return (1);
425 } 342 }
426 /* NOTREACHED */ 343 /* NOTREACHED */
@@ -435,26 +352,26 @@ static u_char *get(void)
435 u_char *tmpp; 352 u_char *tmpp;
436 353
437 if (!curp) { 354 if (!curp) {
438 curp = (u_char *) xmalloc(blocksize); 355 curp = (u_char *) xmalloc(bb_dump_blocksize);
439 savp = (u_char *) xmalloc(blocksize); 356 savp = (u_char *) xmalloc(bb_dump_blocksize);
440 } else { 357 } else {
441 tmpp = curp; 358 tmpp = curp;
442 curp = savp; 359 curp = savp;
443 savp = tmpp; 360 savp = tmpp;
444 address = savaddress += blocksize; 361 address = savaddress += bb_dump_blocksize;
445 } 362 }
446 for (need = blocksize, nread = 0;;) { 363 for (need = bb_dump_blocksize, nread = 0;;) {
447 /* 364 /*
448 * if read the right number of bytes, or at EOF for one file, 365 * if read the right number of bytes, or at EOF for one file,
449 * and no other files are available, zero-pad the rest of the 366 * and no other files are available, zero-pad the rest of the
450 * block and set the end flag. 367 * block and set the end flag.
451 */ 368 */
452 if (!length || (ateof && !next((char **) NULL))) { 369 if (!bb_dump_length || (ateof && !next((char **) NULL))) {
453 if (need == blocksize) { 370 if (need == bb_dump_blocksize) {
454 return ((u_char *) NULL); 371 return ((u_char *) NULL);
455 } 372 }
456 if (vflag != ALL && !bcmp(curp, savp, nread)) { 373 if (bb_dump_vflag != ALL && !bcmp(curp, savp, nread)) {
457 if (vflag != DUP) { 374 if (bb_dump_vflag != DUP) {
458 printf("*\n"); 375 printf("*\n");
459 } 376 }
460 return ((u_char *) NULL); 377 return ((u_char *) NULL);
@@ -464,31 +381,32 @@ static u_char *get(void)
464 return (curp); 381 return (curp);
465 } 382 }
466 n = fread((char *) curp + nread, sizeof(u_char), 383 n = fread((char *) curp + nread, sizeof(u_char),
467 length == -1 ? need : MIN(length, need), stdin); 384 bb_dump_length == -1 ? need : MIN(bb_dump_length, need), stdin);
468 if (!n) { 385 if (!n) {
469 if (ferror(stdin)) { 386 if (ferror(stdin)) {
470 perror_msg("%s", _argv[-1]); 387 bb_perror_msg("%s", _argv[-1]);
471 } 388 }
472 ateof = 1; 389 ateof = 1;
473 continue; 390 continue;
474 } 391 }
475 ateof = 0; 392 ateof = 0;
476 if (length != -1) { 393 if (bb_dump_length != -1) {
477 length -= n; 394 bb_dump_length -= n;
478 } 395 }
479 if (!(need -= n)) { 396 if (!(need -= n)) {
480 if (vflag == ALL || vflag == FIRST || bcmp(curp, savp, blocksize)) { 397 if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST
481 if (vflag == DUP || vflag == FIRST) { 398 || bcmp(curp, savp, bb_dump_blocksize)) {
482 vflag = WAIT; 399 if (bb_dump_vflag == DUP || bb_dump_vflag == FIRST) {
400 bb_dump_vflag = WAIT;
483 } 401 }
484 return (curp); 402 return (curp);
485 } 403 }
486 if (vflag == WAIT) { 404 if (bb_dump_vflag == WAIT) {
487 printf("*\n"); 405 printf("*\n");
488 } 406 }
489 vflag = DUP; 407 bb_dump_vflag = DUP;
490 address = savaddress += blocksize; 408 address = savaddress += bb_dump_blocksize;
491 need = blocksize; 409 need = bb_dump_blocksize;
492 nread = 0; 410 nread = 0;
493 } else { 411 } else {
494 nread += n; 412 nread += n;
@@ -507,67 +425,59 @@ static void bpad(PR * pr)
507 pr->flags = F_BPAD; 425 pr->flags = F_BPAD;
508 *pr->cchar = 's'; 426 *pr->cchar = 's';
509 for (p1 = pr->fmt; *p1 != '%'; ++p1); 427 for (p1 = pr->fmt; *p1 != '%'; ++p1);
510 for (p2 = ++p1; *p1 && index(" -0+#", *p1); ++p1); 428 for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1);
511 while ((*p2++ = *p1++) != 0); 429 while ((*p2++ = *p1++) != 0);
512} 430}
513 431
514void conv_c(PR * pr, u_char * p) 432static const char conv_str[] =
433 "\0\\0\0"
434 "\007\\a\0" /* \a */
435 "\b\\b\0"
436 "\f\\b\0"
437 "\n\\n\0"
438 "\r\\r\0"
439 "\t\\t\0"
440 "\v\\v\0"
441 "\0";
442
443
444static void conv_c(PR * pr, u_char * p)
515{ 445{
516 char buf[10], *str; 446 const char *str = conv_str;
517 447 char buf[10];
518 switch (*p) { 448
519 case '\0': 449 do {
520 str = "\\0"; 450 if (*p == *str) {
521 goto strpr; 451 ++str;
522 /* case '\a': */ 452 goto strpr;
523 case '\007': 453 }
524 str = "\\a"; 454 str += 4;
525 goto strpr; 455 } while (*str);
526 case '\b': 456
527 str = "\\b";
528 goto strpr;
529 case '\f':
530 str = "\\f";
531 goto strpr;
532 case '\n':
533 str = "\\n";
534 goto strpr;
535 case '\r':
536 str = "\\r";
537 goto strpr;
538 case '\t':
539 str = "\\t";
540 goto strpr;
541 case '\v':
542 str = "\\v";
543 goto strpr;
544 default:
545 break;
546 }
547 if (isprint(*p)) { 457 if (isprint(*p)) {
548 *pr->cchar = 'c'; 458 *pr->cchar = 'c';
549 (void) printf(pr->fmt, *p); 459 (void) printf(pr->fmt, *p);
550 } else { 460 } else {
551 sprintf(str = buf, "%03o", (int) *p); 461 sprintf(buf, "%03o", (int) *p);
462 str = buf;
552 strpr: 463 strpr:
553 *pr->cchar = 's'; 464 *pr->cchar = 's';
554 printf(pr->fmt, str); 465 printf(pr->fmt, str);
555 } 466 }
556} 467}
557 468
558void conv_u(PR * pr, u_char * p) 469static void conv_u(PR * pr, u_char * p)
559{ 470{
560 static char *list[] = { 471 static const char list[] =
561 "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 472 "nul\0soh\0stx\0etx\0eot\0enq\0ack\0bel\0"
562 "bs", "ht", "lf", "vt", "ff", "cr", "so", "si", 473 "bs\0_ht\0_lf\0_vt\0_ff\0_cr\0_so\0_si\0_"
563 "dle", "dcl", "dc2", "dc3", "dc4", "nak", "syn", "etb", 474 "dle\0dcl\0dc2\0dc3\0dc4\0nak\0syn\0etb\0"
564 "can", "em", "sub", "esc", "fs", "gs", "rs", "us", 475 "can\0em\0_sub\0esc\0fs\0_gs\0_rs\0_us";
565 };
566 476
567 /* od used nl, not lf */ 477 /* od used nl, not lf */
568 if (*p <= 0x1f) { 478 if (*p <= 0x1f) {
569 *pr->cchar = 's'; 479 *pr->cchar = 's';
570 printf(pr->fmt, list[*p]); 480 printf(pr->fmt, list[4 * (int)(*p)]);
571 } else if (*p == 0x7f) { 481 } else if (*p == 0x7f) {
572 *pr->cchar = 's'; 482 *pr->cchar = 's';
573 printf(pr->fmt, "del"); 483 printf(pr->fmt, "del");
@@ -580,7 +490,7 @@ void conv_u(PR * pr, u_char * p)
580 } 490 }
581} 491}
582 492
583void display(void) 493static void display(void)
584{ 494{
585/* extern FU *endfu; */ 495/* extern FU *endfu; */
586 register FS *fs; 496 register FS *fs;
@@ -589,11 +499,11 @@ void display(void)
589 register int cnt; 499 register int cnt;
590 register u_char *bp; 500 register u_char *bp;
591 501
592/* off_t saveaddress; */ 502 off_t saveaddress;
593 u_char savech = 0, *savebp; 503 u_char savech = 0, *savebp;
594 504
595 while ((bp = get()) != NULL) { 505 while ((bp = get()) != NULL) {
596 for (fs = fshead, savebp = bp, saveaddress = address; fs; 506 for (fs = bb_dump_fshead, savebp = bp, saveaddress = address; fs;
597 fs = fs->nextfs, bp = savebp, address = saveaddress) { 507 fs = fs->nextfs, bp = savebp, address = saveaddress) {
598 for (fu = fs->nextfu; fu; fu = fu->nextfu) { 508 for (fu = fs->nextfu; fu; fu = fu->nextfu) {
599 if (fu->flags & F_IGNORE) { 509 if (fu->flags & F_IGNORE) {
@@ -707,8 +617,8 @@ void display(void)
707 } 617 }
708 if (endfu) { 618 if (endfu) {
709 /* 619 /*
710 * if eaddress not set, error or file size was multiple of 620 * if eaddress not set, error or file bb_dump_size was multiple of
711 * blocksize, and no partial block ever found. 621 * bb_dump_blocksize, and no partial block ever found.
712 */ 622 */
713 if (!eaddress) { 623 if (!eaddress) {
714 if (!address) { 624 if (!address) {
@@ -729,19 +639,19 @@ void display(void)
729 } 639 }
730} 640}
731 641
732int dump(char **argv) 642int bb_dump_dump(char **argv)
733{ 643{
734 register FS *tfs; 644 register FS *tfs;
735 645
736 /* figure out the data block size */ 646 /* figure out the data block bb_dump_size */
737 for (blocksize = 0, tfs = fshead; tfs; tfs = tfs->nextfs) { 647 for (bb_dump_blocksize = 0, tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) {
738 tfs->bcnt = size(tfs); 648 tfs->bcnt = bb_dump_size(tfs);
739 if (blocksize < tfs->bcnt) { 649 if (bb_dump_blocksize < tfs->bcnt) {
740 blocksize = tfs->bcnt; 650 bb_dump_blocksize = tfs->bcnt;
741 } 651 }
742 } 652 }
743 /* rewrite the rules, do syntax checking */ 653 /* rewrite the rules, do syntax checking */
744 for (tfs = fshead; tfs; tfs = tfs->nextfs) { 654 for (tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) {
745 rewrite(tfs); 655 rewrite(tfs);
746 } 656 }
747 657
@@ -751,21 +661,21 @@ int dump(char **argv)
751 return (exitval); 661 return (exitval);
752} 662}
753 663
754void add(char *fmt) 664void bb_dump_add(const char *fmt)
755{ 665{
756 register char *p; 666 register const char *p;
757 register char *p1; 667 register char *p1;
758 register char *p2; 668 register char *p2;
759 static FS **nextfs; 669 static FS **nextfs;
760 FS *tfs; 670 FS *tfs;
761 FU *tfu, **nextfu; 671 FU *tfu, **nextfu;
762 char *savep; 672 const char *savep;
763 673
764 /* start new linked list of format units */ 674 /* start new linked list of format units */
765 /* NOSTRICT */ 675 /* NOSTRICT */
766 tfs = (FS *) xmalloc(sizeof(FS)); 676 tfs = (FS *) xmalloc(sizeof(FS));
767 if (!fshead) { 677 if (!bb_dump_fshead) {
768 fshead = tfs; 678 bb_dump_fshead = tfs;
769 } else { 679 } else {
770 *nextfs = tfs; 680 *nextfs = tfs;
771 } 681 }
@@ -774,8 +684,8 @@ void add(char *fmt)
774 684
775 /* take the format string and break it up into format units */ 685 /* take the format string and break it up into format units */
776 for (p = fmt;;) { 686 for (p = fmt;;) {
777 /* skip leading white space */ 687 /* bb_dump_skip leading white space */
778 for (; isspace(*p); ++p); 688 p = bb_skip_whitespace(p);
779 if (!*p) { 689 if (!*p) {
780 break; 690 break;
781 } 691 }
@@ -791,43 +701,41 @@ void add(char *fmt)
791 if (isdigit(*p)) { 701 if (isdigit(*p)) {
792 for (savep = p; isdigit(*p); ++p); 702 for (savep = p; isdigit(*p); ++p);
793 if (!isspace(*p) && *p != '/') { 703 if (!isspace(*p) && *p != '/') {
794 error_msg_and_die("hexdump: bad format {%s}", fmt); 704 bb_error_msg_and_die("bad format {%s}", fmt);
795 } 705 }
796 /* may overwrite either white space or slash */ 706 /* may overwrite either white space or slash */
797 tfu->reps = atoi(savep); 707 tfu->reps = atoi(savep);
798 tfu->flags = F_SETREP; 708 tfu->flags = F_SETREP;
799 /* skip trailing white space */ 709 /* bb_dump_skip trailing white space */
800 for (++p; isspace(*p); ++p); 710 p = bb_skip_whitespace(++p);
801 } 711 }
802 712
803 /* skip slash and trailing white space */ 713 /* bb_dump_skip slash and trailing white space */
804 if (*p == '/') { 714 if (*p == '/') {
805 while (isspace(*++p)); 715 p = bb_skip_whitespace(++p);
806 } 716 }
807 717
808 /* byte count */ 718 /* byte count */
809 if (isdigit(*p)) { 719 if (isdigit(*p)) {
810 for (savep = p; isdigit(*p); ++p); 720 for (savep = p; isdigit(*p); ++p);
811 if (!isspace(*p)) { 721 if (!isspace(*p)) {
812 error_msg_and_die("hexdump: bad format {%s}", fmt); 722 bb_error_msg_and_die("bad format {%s}", fmt);
813 } 723 }
814 tfu->bcnt = atoi(savep); 724 tfu->bcnt = atoi(savep);
815 /* skip trailing white space */ 725 /* bb_dump_skip trailing white space */
816 for (++p; isspace(*p); ++p); 726 p = bb_skip_whitespace(++p);
817 } 727 }
818 728
819 /* format */ 729 /* format */
820 if (*p != '"') { 730 if (*p != '"') {
821 error_msg_and_die("hexdump: bad format {%s}", fmt); 731 bb_error_msg_and_die("bad format {%s}", fmt);
822 } 732 }
823 for (savep = ++p; *p != '"';) { 733 for (savep = ++p; *p != '"';) {
824 if (*p++ == 0) { 734 if (*p++ == 0) {
825 error_msg_and_die("hexdump: bad format {%s}", fmt); 735 bb_error_msg_and_die("bad format {%s}", fmt);
826 } 736 }
827 } 737 }
828 if (!(tfu->fmt = malloc(p - savep + 1))) { 738 tfu->fmt = xmalloc(p - savep + 1);
829 perror_msg_and_die("hexdump");
830 }
831 strncpy(tfu->fmt, savep, p - savep); 739 strncpy(tfu->fmt, savep, p - savep);
832 tfu->fmt[p - savep] = '\0'; 740 tfu->fmt[p - savep] = '\0';
833/* escape(tfu->fmt); */ 741/* escape(tfu->fmt); */
@@ -841,33 +749,16 @@ void add(char *fmt)
841 break; 749 break;
842 } 750 }
843 if (*p1 == '\\') { 751 if (*p1 == '\\') {
844 switch (*++p1) { 752 const char *cs = conv_str + 4;
845 case 'a': 753 ++p1;
846 /* *p2 = '\a'; */ 754 *p2 = *p1;
847 *p2 = '\007'; 755 do {
848 break; 756 if (*p1 == cs[2]) {
849 case 'b': 757 *p2 = cs[0];
850 *p2 = '\b'; 758 break;
851 break; 759 }
852 case 'f': 760 cs += 4;
853 *p2 = '\f'; 761 } while (*cs);
854 break;
855 case 'n':
856 *p2 = '\n';
857 break;
858 case 'r':
859 *p2 = '\r';
860 break;
861 case 't':
862 *p2 = '\t';
863 break;
864 case 'v':
865 *p2 = '\v';
866 break;
867 default:
868 *p2 = *p1;
869 break;
870 }
871 } 762 }
872 } 763 }
873 764