1 /* od -- dump files in octal and other formats
2 Copyright (C) 92, 1995-2004 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 /* Written by Jim Meyering. */
19 /* Busyboxed by Denys Vlasenko, based on od.c from coreutils-5.2.1 */
22 /* #include "libbb.h" - done in od.c */
23 #include "common_bufsiz.h"
24 #define assert(a) ((void)0)
27 //usage:#if ENABLE_DESKTOP
28 //usage:#define od_trivial_usage
29 //usage: "[-abcdfhilovxs] [-t TYPE] [-A RADIX] [-N SIZE] [-j SKIP] [-S MINSTR] [-w WIDTH] [FILE]..."
31 // ... [FILE] [[+]OFFSET[.][b]]
32 // Support is buggy for:
33 // od --traditional [OPTION]... [FILE] [[+]OFFSET[.][b] [+][LABEL][.][b]]
35 //usage:#define od_full_usage "\n\n"
36 //usage: "Print FILEs (or stdin) unambiguously, as octal bytes by default"
53 /* When zero and two or more consecutive blocks are equal, format
54 only the first block and output an asterisk alone on the following
55 line to indicate that identical blocks have been elided: */
61 OPT_traditional = (1 << 18) * ENABLE_LONG_OPTS,
64 #define OD_GETOPT32() getopt32long(argv, \
65 "A:N:abcdfhij:lot:*vxsS:w:+:", od_longopts, \
66 /* -w with optional param */ \
67 /* -S was -s and also had optional parameter */ \
68 /* but in coreutils 6.3 it was renamed and now has */ \
69 /* _mandatory_ parameter */ \
70 &str_A, &str_N, &str_j, &lst_t, &str_S, &G.bytes_per_block)
73 /* Check for 0x7f is a coreutils 6.3 addition */
74 #define ISPRINT(c) (((c) >= ' ') && (c) < 0x7f)
76 typedef long double longdouble_t;
77 typedef unsigned long long ulonglong_t;
78 typedef long long llong;
81 # define xstrtooff_sfx xstrtoull_sfx
83 # define xstrtooff_sfx xstrtoul_sfx
86 /* The default number of input bytes per output line. */
87 #define DEFAULT_BYTES_PER_BLOCK 16
89 /* The number of decimal digits of precision in a float. */
94 /* The number of decimal digits of precision in a double. */
99 /* The number of decimal digits of precision in a long double. */
101 # define LDBL_DIG DBL_DIG
127 /* Each output format specification (from '-t spec' or from
128 old-style options) is represented by one of these structures. */
130 enum output_format fmt;
132 void (*print_function) (size_t, const char *, const char *);
134 int hexl_mode_trailer;
138 /* Convert the number of 8-bit bytes of a binary representation to
139 the number of characters (digits + sign if the type is signed)
140 required to represent the same quantity in the specified base/type.
141 For example, a 32-bit (4-byte) quantity may require a field width
142 as wide as the following for these types:
146 8 unsigned hexadecimal */
148 static const uint8_t bytes_to_oct_digits[] ALIGN1 =
149 {0, 3, 6, 8, 11, 14, 16, 19, 22, 25, 27, 30, 32, 35, 38, 41, 43};
151 static const uint8_t bytes_to_signed_dec_digits[] ALIGN1 =
152 {1, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 28, 30, 33, 35, 37, 40};
154 static const uint8_t bytes_to_unsigned_dec_digits[] ALIGN1 =
155 {0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39};
157 static const uint8_t bytes_to_hex_digits[] ALIGN1 =
158 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32};
160 /* Convert enum size_spec to the size of the named type. */
161 static const signed char width_bytes[] ALIGN1 = {
172 /* Ensure that for each member of 'enum size_spec' there is an
173 initializer in the width_bytes array. */
174 struct ERR_width_bytes_has_bad_size {
175 char ERR_width_bytes_has_bad_size[ARRAY_SIZE(width_bytes) == N_SIZE_SPECS ? 1 : -1];
183 /* An array of specs describing how to format each input block. */
187 /* Function that accepts an address and an optional following char,
188 and prints the address and char to stdout. */
189 void (*format_address)(off_t, char);
191 /* The difference between the old-style pseudo starting address and
192 the number of bytes to skip. */
195 # define G_pseudo_offset G.pseudo_offset
197 /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
198 input is formatted. */
200 /* The number of input bytes formatted per output line. It must be
201 a multiple of the least common multiple of the sizes associated with
202 the specified output types. It should be as large as possible, but
203 no larger than 16 -- unless specified with the -w option. */
204 unsigned bytes_per_block; /* have to use unsigned, not size_t */
206 /* A NULL-terminated list of the file-arguments from the command line. */
207 const char *const *file_list;
209 /* The input stream associated with the current file. */
213 bool prev_pair_equal;
215 char address_fmt[sizeof("%0n"OFF_FMT"xc")];
217 /* Corresponds to 'x' above */
218 #define address_base_char G.address_fmt[sizeof(G.address_fmt)-3]
219 /* Corresponds to 'n' above */
220 #define address_pad_len_char G.address_fmt[2]
222 #if !ENABLE_LONG_OPTS
223 enum { G_pseudo_offset = 0 };
225 #define G (*(struct globals*)bb_common_bufsiz1)
226 #define INIT_G() do { \
227 setup_common_bufsiz(); \
228 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
229 G.bytes_per_block = 32; \
230 strcpy(G.address_fmt, "%0n"OFF_FMT"xc"); \
234 #define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
235 static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = {
236 [sizeof(char)] = CHAR,
237 #if USHRT_MAX != UCHAR_MAX
238 [sizeof(short)] = SHORT,
240 #if UINT_MAX != USHRT_MAX
243 #if ULONG_MAX != UINT_MAX
244 [sizeof(long)] = LONG,
246 #if ULLONG_MAX != ULONG_MAX
247 [sizeof(ulonglong_t)] = LONG_LONG,
251 #define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
252 static const unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = {
253 /* gcc seems to allow repeated indexes. Last one wins */
254 [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
255 [sizeof(double)] = FLOAT_DOUBLE,
256 [sizeof(float)] = FLOAT_SINGLE
261 gcd(unsigned u, unsigned v)
272 /* Compute the least common multiple of U and V. */
274 lcm(unsigned u, unsigned v) {
275 unsigned t = gcd(u, v);
282 print_s_char(size_t n_bytes, const char *block, const char *fmt_string)
285 int tmp = *(signed char *) block;
286 printf(fmt_string, tmp);
287 block += sizeof(unsigned char);
292 print_char(size_t n_bytes, const char *block, const char *fmt_string)
295 unsigned tmp = *(unsigned char *) block;
296 printf(fmt_string, tmp);
297 block += sizeof(unsigned char);
302 print_s_short(size_t n_bytes, const char *block, const char *fmt_string)
304 n_bytes /= sizeof(signed short);
306 int tmp = *(signed short *) block;
307 printf(fmt_string, tmp);
308 block += sizeof(unsigned short);
313 print_short(size_t n_bytes, const char *block, const char *fmt_string)
315 n_bytes /= sizeof(unsigned short);
317 unsigned tmp = *(unsigned short *) block;
318 printf(fmt_string, tmp);
319 block += sizeof(unsigned short);
324 print_int(size_t n_bytes, const char *block, const char *fmt_string)
326 n_bytes /= sizeof(unsigned);
328 unsigned tmp = *(unsigned *) block;
329 printf(fmt_string, tmp);
330 block += sizeof(unsigned);
334 #if UINT_MAX == ULONG_MAX
335 # define print_long print_int
338 print_long(size_t n_bytes, const char *block, const char *fmt_string)
340 n_bytes /= sizeof(unsigned long);
342 unsigned long tmp = *(unsigned long *) block;
343 printf(fmt_string, tmp);
344 block += sizeof(unsigned long);
349 #if ULONG_MAX == ULLONG_MAX
350 # define print_long_long print_long
353 print_long_long(size_t n_bytes, const char *block, const char *fmt_string)
355 n_bytes /= sizeof(ulonglong_t);
357 ulonglong_t tmp = *(ulonglong_t *) block;
358 printf(fmt_string, tmp);
359 block += sizeof(ulonglong_t);
365 print_float(size_t n_bytes, const char *block, const char *fmt_string)
367 n_bytes /= sizeof(float);
369 float tmp = *(float *) block;
370 printf(fmt_string, tmp);
371 block += sizeof(float);
376 print_double(size_t n_bytes, const char *block, const char *fmt_string)
378 n_bytes /= sizeof(double);
380 double tmp = *(double *) block;
381 printf(fmt_string, tmp);
382 block += sizeof(double);
387 print_long_double(size_t n_bytes, const char *block, const char *fmt_string)
389 n_bytes /= sizeof(longdouble_t);
391 longdouble_t tmp = *(longdouble_t *) block;
392 printf(fmt_string, tmp);
393 block += sizeof(longdouble_t);
397 /* print_[named]_ascii are optimized for speed.
398 * Remember, someday you may want to pump gigabytes through this thing.
399 * Saving a dozen of .text bytes here is counter-productive */
402 print_named_ascii(size_t n_bytes, const char *block,
403 const char *unused_fmt_string UNUSED_PARAM)
405 /* Names for some non-printing characters. */
406 static const char charname[33][3] ALIGN1 = {
407 "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
408 " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
409 "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
410 "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
413 // buf[N] pos: 01234 56789
414 char buf[12] = " x\0 xxx\0";
415 // [12] because we take three 32bit stack slots anyway, and
416 // gcc is too dumb to initialize with constant stores,
417 // it copies initializer from rodata. Oh well.
418 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65410
421 unsigned masked_c = *(unsigned char *) block++;
424 if (masked_c == 0x7f) {
425 fputs(" del", stdout);
428 if (masked_c > ' ') {
433 /* Why? Because printf(" %3.3s") is much slower... */
434 buf[6] = charname[masked_c][0];
435 buf[7] = charname[masked_c][1];
436 buf[8] = charname[masked_c][2];
437 fputs(buf+5, stdout);
442 print_ascii(size_t n_bytes, const char *block,
443 const char *unused_fmt_string UNUSED_PARAM)
445 // buf[N] pos: 01234 56789
446 char buf[12] = " x\0 xxx\0";
450 unsigned c = *(unsigned char *) block++;
483 buf[6] = (c >> 6 & 3) + '0';
484 buf[7] = (c >> 3 & 7) + '0';
485 buf[8] = (c & 7) + '0';
492 /* Given a list of one or more input filenames FILE_LIST, set the global
493 file pointer IN_STREAM and the global string INPUT_FILENAME to the
494 first one that can be successfully opened. Modify FILE_LIST to
495 reference the next filename in the list. A file name of "-" is
496 interpreted as standard input. If any file open fails, give an error
497 message and return nonzero. */
505 G.in_stream = fopen_or_warn_stdin(*G.file_list++);
512 if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N)
513 setbuf(G.in_stream, NULL);
516 /* Test whether there have been errors on in_stream, and close it if
517 it is not standard input. Return nonzero if there has been an error
518 on in_stream or stdout; return zero otherwise. This function will
519 report more than one error only if both a read and a write error
520 have occurred. IN_ERRNO, if nonzero, is the error number
521 corresponding to the most recent action for IN_STREAM. */
524 check_and_close(void)
527 if (ferror(G.in_stream)) {
528 bb_error_msg("%s: read error", (G.in_stream == stdin)
529 ? bb_msg_standard_input
534 fclose_if_not_stdin(G.in_stream);
538 if (ferror(stdout)) {
539 bb_error_msg_and_die(bb_msg_write_error);
543 /* If S points to a single valid modern od format string, put
544 a description of that format in *TSPEC, return pointer to
545 character following the just-decoded format.
546 For example, if S were "d4afL", we will return a rtp to "afL"
549 fmt = SIGNED_DECIMAL;
550 size = INT or LONG; (whichever integral_type_size[4] resolves to)
551 print_function = print_int; (assuming size == INT)
552 fmt_string = "%011d%c";
554 S_ORIG is solely for reporting errors. It should be the full format
557 static NOINLINE const char *
558 decode_one_format(const char *s_orig, const char *s, struct tspec *tspec)
560 enum size_spec size_spec;
562 enum output_format fmt;
565 char *fmt_string = NULL;
566 void (*print_function) (size_t, const char *, const char *);
568 unsigned field_width = 0;
576 static const char CSIL[] ALIGN1 = "CSIL";
579 p = strchr(CSIL, *s);
580 /* if *s == NUL, p != NULL! Testcase: "od -tx" */
581 if (!p || *p == '\0') {
584 size = bb_strtou(s, &end, 0);
586 || MAX_INTEGRAL_TYPE_SIZE < size
587 || integral_type_size[size] == NO_SIZE
589 bb_error_msg_and_die("invalid type string '%s'; "
590 "%u-byte %s type is not supported",
591 s_orig, size, "integral");
596 static const uint8_t CSIL_sizeof[4] = {
602 size = CSIL_sizeof[p - CSIL];
603 s++; /* skip C/S/I/L */
606 #define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format) \
607 ((Spec) == LONG_LONG ? (Max_format) \
608 : ((Spec) == LONG ? (Long_format) : (Min_format)))
610 #define FMT_BYTES_ALLOCATED 9
611 size_spec = integral_type_size[size];
614 static const char doux[] ALIGN1 = "doux";
615 static const char doux_fmt_letter[][4] = {
616 "lld", "llo", "llu", "llx"
618 static const enum output_format doux_fmt[] = {
624 static const uint8_t *const doux_bytes_to_XXX[] = {
625 bytes_to_signed_dec_digits,
627 bytes_to_unsigned_dec_digits,
630 static const char doux_fmtstring[][sizeof(" %%0%u%s")] = {
637 pos = strchr(doux, c) - doux;
639 field_width = doux_bytes_to_XXX[pos][size];
640 p = doux_fmt_letter[pos] + 2;
641 if (size_spec == LONG) p--;
642 if (size_spec == LONG_LONG) p -= 2;
643 fmt_string = xasprintf(doux_fmtstring[pos], field_width, p);
648 print_function = (fmt == SIGNED_DECIMAL
653 print_function = (fmt == SIGNED_DECIMAL
658 print_function = print_int;
661 print_function = print_long;
663 default: /* case LONG_LONG: */
664 print_function = print_long_long;
671 static const char FDL[] ALIGN1 = "FDL";
673 fmt = FLOATING_POINT;
676 if (!p || *p == '\0') {
677 size = sizeof(double);
679 size = bb_strtou(s, &end, 0);
680 if (errno == ERANGE || size > MAX_FP_TYPE_SIZE
681 || fp_type_size[size] == NO_SIZE
683 bb_error_msg_and_die("invalid type string '%s'; "
684 "%u-byte %s type is not supported",
685 s_orig, size, "floating point");
690 static const uint8_t FDL_sizeof[] = {
693 sizeof(longdouble_t),
696 size = FDL_sizeof[p - FDL];
697 s++; /* skip F/D/L */
700 size_spec = fp_type_size[size];
704 print_function = print_float;
705 field_width = FLT_DIG + 8;
706 /* Don't use %#e; not all systems support it. */
707 fmt_string = xasprintf(" %%%d.%de", field_width, FLT_DIG);
710 print_function = print_double;
711 field_width = DBL_DIG + 8;
712 fmt_string = xasprintf(" %%%d.%de", field_width, DBL_DIG);
714 default: /* case FLOAT_LONG_DOUBLE: */
715 print_function = print_long_double;
716 field_width = LDBL_DIG + 8;
717 fmt_string = xasprintf(" %%%d.%dLe", field_width, LDBL_DIG);
725 fmt = NAMED_CHARACTER;
727 print_function = print_named_ascii;
734 print_function = print_ascii;
738 bb_error_msg_and_die("invalid character '%c' "
739 "in type string '%s'", *s, s_orig);
742 tspec->size = size_spec;
744 tspec->print_function = print_function;
745 tspec->fmt_string = fmt_string;
747 tspec->field_width = field_width;
748 tspec->hexl_mode_trailer = (*s == 'z');
749 if (tspec->hexl_mode_trailer)
755 /* Decode the modern od format string S. Append the decoded
756 representation to the global array SPEC, reallocating SPEC if
760 decode_format_string(const char *s)
762 const char *s_orig = s;
768 next = decode_one_format(s_orig, s, &tspec);
772 G.spec = xrealloc_vector(G.spec, 4, G.n_specs);
773 memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0]));
778 /* Given a list of one or more input filenames FILE_LIST, set the global
779 file pointer IN_STREAM to position N_SKIP in the concatenation of
780 those files. If any file operation fails or if there are fewer than
781 N_SKIP bytes in the combined input, give an error message and return
782 nonzero. When possible, use seek rather than read operations to
783 advance IN_STREAM. */
791 while (G.in_stream) { /* !EOF */
792 struct stat file_stats;
794 /* First try seeking. For large offsets, this extra work is
795 worthwhile. If the offset is below some threshold it may be
796 more efficient to move the pointer by reading. There are two
797 issues when trying to seek:
798 - the file must be seekable.
799 - before seeking to the specified position, make sure
800 that the new position is in the current file.
801 Try to do that by getting file's size using fstat.
802 But that will work only for regular files. */
804 /* The st_size field is valid only for regular files
805 (and for symbolic links, which cannot occur here).
806 If the number of bytes left to skip is at least
807 as large as the size of the current file, we can
808 decrement n_skip and go on to the next file. */
809 if (fstat(fileno(G.in_stream), &file_stats) == 0
810 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0
812 if (file_stats.st_size < n_skip) {
813 n_skip -= file_stats.st_size;
814 /* take "check & close / open_next" route */
816 if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0)
821 /* If it's not a regular file with positive size,
822 position the file pointer by reading. */
824 size_t n_bytes_to_read = 1024;
828 if (n_skip < n_bytes_to_read)
829 n_bytes_to_read = n_skip;
830 n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream);
831 n_skip -= n_bytes_read;
832 if (n_bytes_read != n_bytes_to_read)
833 break; /* EOF on this file or error */
844 bb_error_msg_and_die("can't skip past end of combined input");
848 typedef void FN_format_address(off_t address, char c);
851 format_address_none(off_t address UNUSED_PARAM, char c UNUSED_PARAM)
856 format_address_std(off_t address, char c)
858 /* Corresponds to 'c' */
859 G.address_fmt[sizeof(G.address_fmt)-2] = c;
860 printf(G.address_fmt, address);
864 /* only used with --traditional */
866 format_address_paren(off_t address, char c)
869 format_address_std(address, ')');
874 format_address_label(off_t address, char c)
876 format_address_std(address, ' ');
877 format_address_paren(address + G_pseudo_offset, c);
882 dump_hexl_mode_trailer(size_t n_bytes, const char *block)
886 unsigned c = *(unsigned char *) block++;
887 c = (ISPRINT(c) ? c : '.');
893 /* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
894 of the N_SPEC format specs. CURRENT_OFFSET is the byte address of
895 CURR_BLOCK in the concatenation of input files, and it is printed
896 (optionally) only before the output line associated with the first
897 format spec. When duplicate blocks are being abbreviated, the output
898 for a sequence of identical input blocks is the output for the first
899 block followed by an asterisk alone on a line. It is valid to compare
900 the blocks PREV_BLOCK and CURR_BLOCK only when N_BYTES == BYTES_PER_BLOCK.
901 That condition may be false only for the last input block -- and then
902 only when it has not been padded to length BYTES_PER_BLOCK. */
905 write_block(off_t current_offset, size_t n_bytes,
906 const char *prev_block, const char *curr_block)
910 if (!(option_mask32 & OPT_v)
912 && n_bytes == G.bytes_per_block
913 && memcmp(prev_block, curr_block, G.bytes_per_block) == 0
915 if (G.prev_pair_equal) {
916 /* The two preceding blocks were equal, and the current
917 block is the same as the last one, so print nothing. */
920 G.prev_pair_equal = 1;
924 G.prev_pair_equal = 0;
925 for (i = 0; i < G.n_specs; i++) {
927 G.format_address(current_offset, '\0');
929 printf("%*s", address_pad_len_char - '0', "");
930 (*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string);
931 if (G.spec[i].hexl_mode_trailer) {
932 /* space-pad out to full line width, then dump the trailer */
933 unsigned datum_width = width_bytes[G.spec[i].size];
934 unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width;
935 unsigned field_width = G.spec[i].field_width + 1;
936 printf("%*s", blank_fields * field_width, "");
937 dump_hexl_mode_trailer(n_bytes, curr_block);
945 read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
947 assert(0 < n && n <= G.bytes_per_block);
949 *n_bytes_in_buffer = 0;
954 while (G.in_stream != NULL) { /* EOF. */
958 n_needed = n - *n_bytes_in_buffer;
959 n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream);
960 *n_bytes_in_buffer += n_read;
961 if (n_read == n_needed)
963 /* error check is done in check_and_close */
969 /* Return the least common multiple of the sizes associated
970 with the format specs. */
978 for (i = 0; i < G.n_specs; i++)
979 l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]);
983 /* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
984 formatted block to standard output, and repeat until the specified
985 maximum number of bytes has been read or until all input has been
986 processed. If the last block read is smaller than BYTES_PER_BLOCK
987 and its size is not a multiple of the size associated with a format
988 spec, extend the input block with zero bytes until its length is a
989 multiple of all format spec sizes. Write the final block. Finally,
990 write on a line by itself the offset of the byte after the last byte
994 dump(off_t current_offset, off_t end_offset)
1000 block[0] = xmalloc(2 * G.bytes_per_block);
1001 block[1] = block[0] + G.bytes_per_block;
1004 if (option_mask32 & OPT_N) {
1007 if (current_offset >= end_offset) {
1011 n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block);
1012 read_block(n_needed, block[idx], &n_bytes_read);
1013 if (n_bytes_read < G.bytes_per_block)
1015 assert(n_bytes_read == G.bytes_per_block);
1016 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1017 current_offset += n_bytes_read;
1022 read_block(G.bytes_per_block, block[idx], &n_bytes_read);
1023 if (n_bytes_read < G.bytes_per_block)
1025 assert(n_bytes_read == G.bytes_per_block);
1026 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1027 current_offset += n_bytes_read;
1032 if (n_bytes_read > 0) {
1034 size_t bytes_to_write;
1038 /* Make bytes_to_write the smallest multiple of l_c_m that
1039 is at least as large as n_bytes_read. */
1040 bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
1042 memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
1043 write_block(current_offset, bytes_to_write,
1044 block[idx ^ 1], block[idx]);
1045 current_offset += n_bytes_read;
1048 G.format_address(current_offset, '\n');
1050 if ((option_mask32 & OPT_N) && current_offset >= end_offset)
1056 /* Read N bytes into BLOCK from the concatenation of the input files
1057 named in the global array FILE_LIST. On the first call to this
1058 function, the global variable IN_STREAM is expected to be an open
1059 stream associated with the input file INPUT_FILENAME. If all N
1060 bytes cannot be read from IN_STREAM, close IN_STREAM and update
1061 the global variables IN_STREAM and INPUT_FILENAME. Then try to
1062 read the remaining bytes from the newly opened file. Repeat if
1063 necessary until EOF is reached for the last file in FILE_LIST.
1064 On subsequent calls, don't modify BLOCK and return zero. Set
1065 *N_BYTES_IN_BUFFER to the number of bytes read. If an error occurs,
1066 it will be detected through ferror when the stream is about to be
1067 closed. If there is an error, give a message but continue reading
1068 as usual and return nonzero. Otherwise return zero. */
1070 /* STRINGS mode. Find each "string constant" in the input.
1071 A string constant is a run of at least 'string_min' ASCII
1072 graphic (or formatting) characters terminated by a null.
1073 Based on a function written by Richard Stallman for a
1074 traditional version of od. */
1077 dump_strings(off_t address, off_t end_offset)
1079 unsigned bufsize = MAX(100, G.string_min);
1080 unsigned char *buf = xmalloc(bufsize);
1086 /* See if the next 'G.string_min' chars are all printing chars. */
1088 if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address))
1091 while (!(option_mask32 & OPT_N) || address < end_offset) {
1093 bufsize += bufsize/8;
1094 buf = xrealloc(buf, bufsize);
1097 while (G.in_stream) { /* !EOF */
1098 c = fgetc(G.in_stream);
1111 goto tryline; /* It isn't; give up on this string. */
1112 buf[i++] = c; /* String continues; store it all. */
1115 if (i < G.string_min) /* Too short! */
1118 /* If we get here, the string is all printable and NUL-terminated */
1120 G.format_address(address - i - 1, ' ');
1122 for (i = 0; (c = buf[i]); i++) {
1124 case '\007': fputs("\\a", stdout); break;
1125 case '\b': fputs("\\b", stdout); break;
1126 case '\f': fputs("\\f", stdout); break;
1127 case '\n': fputs("\\n", stdout); break;
1128 case '\r': fputs("\\r", stdout); break;
1129 case '\t': fputs("\\t", stdout); break;
1130 case '\v': fputs("\\v", stdout); break;
1131 default: putchar(c);
1137 /* We reach this point only if we search through
1138 (max_bytes_to_format - G.string_min) bytes before reaching EOF. */
1144 #if ENABLE_LONG_OPTS
1145 /* If S is a valid traditional offset specification with an optional
1146 leading '+' return nonzero and set *OFFSET to the offset it denotes. */
1149 parse_old_offset(const char *s, off_t *offset)
1151 static const struct suffix_mult Bb[] = {
1159 /* Skip over any leading '+'. */
1160 if (s[0] == '+') ++s;
1161 if (!isdigit(s[0])) return 0; /* not a number */
1163 /* Determine the radix we'll use to interpret S. If there is a '.',
1164 * it's decimal, otherwise, if the string begins with '0X'or '0x',
1165 * it's hexadecimal, else octal. */
1169 p[0] = '\0'; /* cheating */
1171 } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
1174 *offset = xstrtooff_sfx(s, radix, Bb);
1177 return (*offset >= 0);
1181 int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1182 int od_main(int argc UNUSED_PARAM, char **argv)
1184 #if ENABLE_LONG_OPTS
1185 static const char od_longopts[] ALIGN1 =
1186 "skip-bytes\0" Required_argument "j"
1187 "address-radix\0" Required_argument "A"
1188 "read-bytes\0" Required_argument "N"
1189 "format\0" Required_argument "t"
1190 "output-duplicates\0" No_argument "v"
1191 /* Yes, it's true: -S NUM, but --strings[=NUM]!
1192 * that is, NUM is mandatory for -S but optional for --strings!
1194 "strings\0" Optional_argument "S"
1195 "width\0" Optional_argument "w"
1196 "traditional\0" No_argument "\xff"
1199 const char *str_A, *str_N, *str_j, *str_S = "3";
1200 llist_t *lst_t = NULL;
1203 /* The number of input bytes to skip before formatting and writing. */
1204 off_t n_bytes_to_skip = 0;
1205 /* The offset of the first byte after the last byte to be formatted. */
1206 off_t end_offset = 0;
1207 /* The maximum number of bytes that will be formatted. */
1208 off_t max_bytes_to_format = 0;
1212 /*G.spec = NULL; - already is */
1213 G.format_address = format_address_std;
1214 address_base_char = 'o';
1215 address_pad_len_char = '7';
1217 /* Parse command line */
1218 opt = OD_GETOPT32();
1221 static const char doxn[] ALIGN1 = "doxn";
1222 static const char doxn_address_base_char[] ALIGN1 = {
1223 'u', 'o', 'x', /* '?' fourth one is not important */
1225 static const uint8_t doxn_address_pad_len_char[] ALIGN1 = {
1226 '7', '7', '6', /* '?' */
1230 p = strchr(doxn, str_A[0]);
1232 bb_error_msg_and_die("bad output address radix "
1233 "'%c' (must be [doxn])", str_A[0]);
1235 if (pos == 3) G.format_address = format_address_none;
1236 address_base_char = doxn_address_base_char[pos];
1237 address_pad_len_char = doxn_address_pad_len_char[pos];
1240 max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm_suffixes);
1242 if (opt & OPT_a) decode_format_string("a");
1243 if (opt & OPT_b) decode_format_string("oC");
1244 if (opt & OPT_c) decode_format_string("c");
1245 if (opt & OPT_d) decode_format_string("u2");
1246 if (opt & OPT_f) decode_format_string("fF");
1247 if (opt & OPT_h) decode_format_string("x2");
1248 if (opt & OPT_i) decode_format_string("d2");
1249 if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm_suffixes);
1250 if (opt & OPT_l) decode_format_string("d4");
1251 if (opt & OPT_o) decode_format_string("o2");
1253 decode_format_string(llist_pop(&lst_t));
1255 if (opt & OPT_x) decode_format_string("x2");
1256 if (opt & OPT_s) decode_format_string("d2");
1258 G.string_min = xstrtou_sfx(str_S, 0, bkm_suffixes);
1262 //if ((option_mask32 & OPT_S) && G.n_specs > 0)
1263 // bb_error_msg_and_die("no type may be specified when dumping strings");
1265 /* If the --traditional option is used, there may be from
1266 * 0 to 3 remaining command line arguments; handle each case
1268 * od [FILE] [[+]OFFSET[.][b] [[+]LABEL[.][b]]]
1269 * The offset and pseudo_start have the same syntax.
1271 * FIXME: POSIX 1003.1-2001 with XSI requires support for the
1272 * traditional syntax even if --traditional is not given. */
1274 #if ENABLE_LONG_OPTS
1275 if (opt & OPT_traditional) {
1277 off_t pseudo_start = -1;
1280 if (!argv[1]) { /* one arg */
1281 if (parse_old_offset(argv[0], &o1)) {
1282 /* od --traditional OFFSET */
1283 n_bytes_to_skip = o1;
1286 /* od --traditional FILE */
1287 } else if (!argv[2]) { /* two args */
1288 if (parse_old_offset(argv[0], &o1)
1289 && parse_old_offset(argv[1], &o2)
1291 /* od --traditional OFFSET LABEL */
1292 n_bytes_to_skip = o1;
1295 } else if (parse_old_offset(argv[1], &o2)) {
1296 /* od --traditional FILE OFFSET */
1297 n_bytes_to_skip = o2;
1300 bb_error_msg_and_die("invalid second argument '%s'", argv[1]);
1302 } else if (!argv[3]) { /* three args */
1303 if (parse_old_offset(argv[1], &o1)
1304 && parse_old_offset(argv[2], &o2)
1306 /* od --traditional FILE OFFSET LABEL */
1307 n_bytes_to_skip = o1;
1311 bb_error_msg_and_die("the last two arguments must be offsets");
1313 } else { /* >3 args */
1314 bb_error_msg_and_die("too many arguments");
1317 if (pseudo_start >= 0) {
1318 if (G.format_address == format_address_none) {
1319 address_base_char = 'o';
1320 address_pad_len_char = '7';
1321 G.format_address = format_address_paren;
1323 G.format_address = format_address_label;
1325 G_pseudo_offset = pseudo_start - n_bytes_to_skip;
1328 /* else: od --traditional (without args) */
1332 if (option_mask32 & OPT_N) {
1333 end_offset = n_bytes_to_skip + max_bytes_to_format;
1334 if (end_offset < n_bytes_to_skip)
1335 bb_error_msg_and_die("SKIP + SIZE is too large");
1338 if (G.n_specs == 0) {
1339 decode_format_string("o2");
1340 /*G.n_specs = 1; - done by decode_format_string */
1343 /* If no files were listed on the command line,
1344 set the global pointer FILE_LIST so that it
1345 references the null-terminated list of one name: "-". */
1346 G.file_list = bb_argv_dash;
1348 /* Set the global pointer FILE_LIST so that it
1349 references the first file-argument on the command-line. */
1350 G.file_list = (char const *const *) argv;
1353 /* Open the first input file */
1355 /* Skip over any unwanted header bytes */
1356 skip(n_bytes_to_skip);
1358 return EXIT_FAILURE;
1360 /* Compute output block length */
1363 if (opt & OPT_w) { /* -w: width */
1364 if (!G.bytes_per_block || G.bytes_per_block % l_c_m != 0) {
1365 bb_error_msg("warning: invalid width %u; using %d instead",
1366 (unsigned)G.bytes_per_block, l_c_m);
1367 G.bytes_per_block = l_c_m;
1370 G.bytes_per_block = l_c_m;
1371 if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
1372 G.bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
1378 for (i = 0; i < G.n_specs; i++) {
1379 printf("%d: fmt='%s' width=%d\n",
1380 i, G.spec[i].fmt_string,
1381 width_bytes[G.spec[i].size]);
1386 if (option_mask32 & OPT_S)
1387 dump_strings(n_bytes_to_skip, end_offset);
1389 dump(n_bytes_to_skip, end_offset);
1392 bb_perror_msg_and_die(bb_msg_standard_input);