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() getopt32(argv, \
65 "A:N:abcdfhij:lot:*vxsS:w:+:", \
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 #if !ENABLE_LONG_OPTS
216 enum { G_pseudo_offset = 0 };
218 #define G (*(struct globals*)bb_common_bufsiz1)
219 #define INIT_G() do { \
220 setup_common_bufsiz(); \
221 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
222 G.bytes_per_block = 32; \
226 #define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
227 static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = {
228 [sizeof(char)] = CHAR,
229 #if USHRT_MAX != UCHAR_MAX
230 [sizeof(short)] = SHORT,
232 #if UINT_MAX != USHRT_MAX
235 #if ULONG_MAX != UINT_MAX
236 [sizeof(long)] = LONG,
238 #if ULLONG_MAX != ULONG_MAX
239 [sizeof(ulonglong_t)] = LONG_LONG,
243 #define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
244 static const unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = {
245 /* gcc seems to allow repeated indexes. Last one wins */
246 [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
247 [sizeof(double)] = FLOAT_DOUBLE,
248 [sizeof(float)] = FLOAT_SINGLE
253 gcd(unsigned u, unsigned v)
264 /* Compute the least common multiple of U and V. */
266 lcm(unsigned u, unsigned v) {
267 unsigned t = gcd(u, v);
274 print_s_char(size_t n_bytes, const char *block, const char *fmt_string)
277 int tmp = *(signed char *) block;
278 printf(fmt_string, tmp);
279 block += sizeof(unsigned char);
284 print_char(size_t n_bytes, const char *block, const char *fmt_string)
287 unsigned tmp = *(unsigned char *) block;
288 printf(fmt_string, tmp);
289 block += sizeof(unsigned char);
294 print_s_short(size_t n_bytes, const char *block, const char *fmt_string)
296 n_bytes /= sizeof(signed short);
298 int tmp = *(signed short *) block;
299 printf(fmt_string, tmp);
300 block += sizeof(unsigned short);
305 print_short(size_t n_bytes, const char *block, const char *fmt_string)
307 n_bytes /= sizeof(unsigned short);
309 unsigned tmp = *(unsigned short *) block;
310 printf(fmt_string, tmp);
311 block += sizeof(unsigned short);
316 print_int(size_t n_bytes, const char *block, const char *fmt_string)
318 n_bytes /= sizeof(unsigned);
320 unsigned tmp = *(unsigned *) block;
321 printf(fmt_string, tmp);
322 block += sizeof(unsigned);
326 #if UINT_MAX == ULONG_MAX
327 # define print_long print_int
330 print_long(size_t n_bytes, const char *block, const char *fmt_string)
332 n_bytes /= sizeof(unsigned long);
334 unsigned long tmp = *(unsigned long *) block;
335 printf(fmt_string, tmp);
336 block += sizeof(unsigned long);
341 #if ULONG_MAX == ULLONG_MAX
342 # define print_long_long print_long
345 print_long_long(size_t n_bytes, const char *block, const char *fmt_string)
347 n_bytes /= sizeof(ulonglong_t);
349 ulonglong_t tmp = *(ulonglong_t *) block;
350 printf(fmt_string, tmp);
351 block += sizeof(ulonglong_t);
357 print_float(size_t n_bytes, const char *block, const char *fmt_string)
359 n_bytes /= sizeof(float);
361 float tmp = *(float *) block;
362 printf(fmt_string, tmp);
363 block += sizeof(float);
368 print_double(size_t n_bytes, const char *block, const char *fmt_string)
370 n_bytes /= sizeof(double);
372 double tmp = *(double *) block;
373 printf(fmt_string, tmp);
374 block += sizeof(double);
379 print_long_double(size_t n_bytes, const char *block, const char *fmt_string)
381 n_bytes /= sizeof(longdouble_t);
383 longdouble_t tmp = *(longdouble_t *) block;
384 printf(fmt_string, tmp);
385 block += sizeof(longdouble_t);
389 /* print_[named]_ascii are optimized for speed.
390 * Remember, someday you may want to pump gigabytes through this thing.
391 * Saving a dozen of .text bytes here is counter-productive */
394 print_named_ascii(size_t n_bytes, const char *block,
395 const char *unused_fmt_string UNUSED_PARAM)
397 /* Names for some non-printing characters. */
398 static const char charname[33][3] ALIGN1 = {
399 "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
400 " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
401 "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
402 "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
405 // buf[N] pos: 01234 56789
406 char buf[12] = " x\0 xxx\0";
407 // [12] because we take three 32bit stack slots anyway, and
408 // gcc is too dumb to initialize with constant stores,
409 // it copies initializer from rodata. Oh well.
410 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65410
413 unsigned masked_c = *(unsigned char *) block++;
416 if (masked_c == 0x7f) {
417 fputs(" del", stdout);
420 if (masked_c > ' ') {
425 /* Why? Because printf(" %3.3s") is much slower... */
426 buf[6] = charname[masked_c][0];
427 buf[7] = charname[masked_c][1];
428 buf[8] = charname[masked_c][2];
429 fputs(buf+5, stdout);
434 print_ascii(size_t n_bytes, const char *block,
435 const char *unused_fmt_string UNUSED_PARAM)
437 // buf[N] pos: 01234 56789
438 char buf[12] = " x\0 xxx\0";
442 unsigned c = *(unsigned char *) block++;
475 buf[6] = (c >> 6 & 3) + '0';
476 buf[7] = (c >> 3 & 7) + '0';
477 buf[8] = (c & 7) + '0';
484 /* Given a list of one or more input filenames FILE_LIST, set the global
485 file pointer IN_STREAM and the global string INPUT_FILENAME to the
486 first one that can be successfully opened. Modify FILE_LIST to
487 reference the next filename in the list. A file name of "-" is
488 interpreted as standard input. If any file open fails, give an error
489 message and return nonzero. */
497 G.in_stream = fopen_or_warn_stdin(*G.file_list++);
504 if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N)
505 setbuf(G.in_stream, NULL);
508 /* Test whether there have been errors on in_stream, and close it if
509 it is not standard input. Return nonzero if there has been an error
510 on in_stream or stdout; return zero otherwise. This function will
511 report more than one error only if both a read and a write error
512 have occurred. IN_ERRNO, if nonzero, is the error number
513 corresponding to the most recent action for IN_STREAM. */
516 check_and_close(void)
519 if (ferror(G.in_stream)) {
520 bb_error_msg("%s: read error", (G.in_stream == stdin)
521 ? bb_msg_standard_input
526 fclose_if_not_stdin(G.in_stream);
530 if (ferror(stdout)) {
531 bb_error_msg_and_die(bb_msg_write_error);
535 /* If S points to a single valid modern od format string, put
536 a description of that format in *TSPEC, return pointer to
537 character following the just-decoded format.
538 For example, if S were "d4afL", we will return a rtp to "afL"
541 fmt = SIGNED_DECIMAL;
542 size = INT or LONG; (whichever integral_type_size[4] resolves to)
543 print_function = print_int; (assuming size == INT)
544 fmt_string = "%011d%c";
546 S_ORIG is solely for reporting errors. It should be the full format
549 static NOINLINE const char *
550 decode_one_format(const char *s_orig, const char *s, struct tspec *tspec)
552 enum size_spec size_spec;
554 enum output_format fmt;
557 char *fmt_string = NULL;
558 void (*print_function) (size_t, const char *, const char *);
560 unsigned field_width = 0;
568 static const char CSIL[] ALIGN1 = "CSIL";
571 p = strchr(CSIL, *s);
572 /* if *s == NUL, p != NULL! Testcase: "od -tx" */
573 if (!p || *p == '\0') {
576 size = bb_strtou(s, &end, 0);
578 || MAX_INTEGRAL_TYPE_SIZE < size
579 || integral_type_size[size] == NO_SIZE
581 bb_error_msg_and_die("invalid type string '%s'; "
582 "%u-byte %s type is not supported",
583 s_orig, size, "integral");
588 static const uint8_t CSIL_sizeof[4] = {
594 size = CSIL_sizeof[p - CSIL];
595 s++; /* skip C/S/I/L */
598 #define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format) \
599 ((Spec) == LONG_LONG ? (Max_format) \
600 : ((Spec) == LONG ? (Long_format) : (Min_format)))
602 #define FMT_BYTES_ALLOCATED 9
603 size_spec = integral_type_size[size];
606 static const char doux[] ALIGN1 = "doux";
607 static const char doux_fmt_letter[][4] = {
608 "lld", "llo", "llu", "llx"
610 static const enum output_format doux_fmt[] = {
616 static const uint8_t *const doux_bytes_to_XXX[] = {
617 bytes_to_signed_dec_digits,
619 bytes_to_unsigned_dec_digits,
622 static const char doux_fmtstring[][sizeof(" %%0%u%s")] = {
629 pos = strchr(doux, c) - doux;
631 field_width = doux_bytes_to_XXX[pos][size];
632 p = doux_fmt_letter[pos] + 2;
633 if (size_spec == LONG) p--;
634 if (size_spec == LONG_LONG) p -= 2;
635 fmt_string = xasprintf(doux_fmtstring[pos], field_width, p);
640 print_function = (fmt == SIGNED_DECIMAL
645 print_function = (fmt == SIGNED_DECIMAL
650 print_function = print_int;
653 print_function = print_long;
655 default: /* case LONG_LONG: */
656 print_function = print_long_long;
663 static const char FDL[] ALIGN1 = "FDL";
665 fmt = FLOATING_POINT;
668 if (!p || *p == '\0') {
669 size = sizeof(double);
671 size = bb_strtou(s, &end, 0);
672 if (errno == ERANGE || size > MAX_FP_TYPE_SIZE
673 || fp_type_size[size] == NO_SIZE
675 bb_error_msg_and_die("invalid type string '%s'; "
676 "%u-byte %s type is not supported",
677 s_orig, size, "floating point");
682 static const uint8_t FDL_sizeof[] = {
685 sizeof(longdouble_t),
688 size = FDL_sizeof[p - FDL];
689 s++; /* skip F/D/L */
692 size_spec = fp_type_size[size];
696 print_function = print_float;
697 field_width = FLT_DIG + 8;
698 /* Don't use %#e; not all systems support it. */
699 fmt_string = xasprintf(" %%%d.%de", field_width, FLT_DIG);
702 print_function = print_double;
703 field_width = DBL_DIG + 8;
704 fmt_string = xasprintf(" %%%d.%de", field_width, DBL_DIG);
706 default: /* case FLOAT_LONG_DOUBLE: */
707 print_function = print_long_double;
708 field_width = LDBL_DIG + 8;
709 fmt_string = xasprintf(" %%%d.%dLe", field_width, LDBL_DIG);
717 fmt = NAMED_CHARACTER;
719 print_function = print_named_ascii;
726 print_function = print_ascii;
730 bb_error_msg_and_die("invalid character '%c' "
731 "in type string '%s'", *s, s_orig);
734 tspec->size = size_spec;
736 tspec->print_function = print_function;
737 tspec->fmt_string = fmt_string;
739 tspec->field_width = field_width;
740 tspec->hexl_mode_trailer = (*s == 'z');
741 if (tspec->hexl_mode_trailer)
747 /* Decode the modern od format string S. Append the decoded
748 representation to the global array SPEC, reallocating SPEC if
752 decode_format_string(const char *s)
754 const char *s_orig = s;
760 next = decode_one_format(s_orig, s, &tspec);
764 G.spec = xrealloc_vector(G.spec, 4, G.n_specs);
765 memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0]));
770 /* Given a list of one or more input filenames FILE_LIST, set the global
771 file pointer IN_STREAM to position N_SKIP in the concatenation of
772 those files. If any file operation fails or if there are fewer than
773 N_SKIP bytes in the combined input, give an error message and return
774 nonzero. When possible, use seek rather than read operations to
775 advance IN_STREAM. */
783 while (G.in_stream) { /* !EOF */
784 struct stat file_stats;
786 /* First try seeking. For large offsets, this extra work is
787 worthwhile. If the offset is below some threshold it may be
788 more efficient to move the pointer by reading. There are two
789 issues when trying to seek:
790 - the file must be seekable.
791 - before seeking to the specified position, make sure
792 that the new position is in the current file.
793 Try to do that by getting file's size using fstat.
794 But that will work only for regular files. */
796 /* The st_size field is valid only for regular files
797 (and for symbolic links, which cannot occur here).
798 If the number of bytes left to skip is at least
799 as large as the size of the current file, we can
800 decrement n_skip and go on to the next file. */
801 if (fstat(fileno(G.in_stream), &file_stats) == 0
802 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0
804 if (file_stats.st_size < n_skip) {
805 n_skip -= file_stats.st_size;
806 /* take "check & close / open_next" route */
808 if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0)
813 /* If it's not a regular file with positive size,
814 position the file pointer by reading. */
816 size_t n_bytes_to_read = 1024;
820 if (n_skip < n_bytes_to_read)
821 n_bytes_to_read = n_skip;
822 n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream);
823 n_skip -= n_bytes_read;
824 if (n_bytes_read != n_bytes_to_read)
825 break; /* EOF on this file or error */
836 bb_error_msg_and_die("can't skip past end of combined input");
840 typedef void FN_format_address(off_t address, char c);
843 format_address_none(off_t address UNUSED_PARAM, char c UNUSED_PARAM)
847 static char address_fmt[] ALIGN1 = "%0n"OFF_FMT"xc";
848 /* Corresponds to 'x' above */
849 #define address_base_char address_fmt[sizeof(address_fmt)-3]
850 /* Corresponds to 'n' above */
851 #define address_pad_len_char address_fmt[2]
854 format_address_std(off_t address, char c)
856 /* Corresponds to 'c' */
857 address_fmt[sizeof(address_fmt)-2] = c;
858 printf(address_fmt, address);
862 /* only used with --traditional */
864 format_address_paren(off_t address, char c)
867 format_address_std(address, ')');
872 format_address_label(off_t address, char c)
874 format_address_std(address, ' ');
875 format_address_paren(address + G_pseudo_offset, c);
880 dump_hexl_mode_trailer(size_t n_bytes, const char *block)
884 unsigned c = *(unsigned char *) block++;
885 c = (ISPRINT(c) ? c : '.');
891 /* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
892 of the N_SPEC format specs. CURRENT_OFFSET is the byte address of
893 CURR_BLOCK in the concatenation of input files, and it is printed
894 (optionally) only before the output line associated with the first
895 format spec. When duplicate blocks are being abbreviated, the output
896 for a sequence of identical input blocks is the output for the first
897 block followed by an asterisk alone on a line. It is valid to compare
898 the blocks PREV_BLOCK and CURR_BLOCK only when N_BYTES == BYTES_PER_BLOCK.
899 That condition may be false only for the last input block -- and then
900 only when it has not been padded to length BYTES_PER_BLOCK. */
903 write_block(off_t current_offset, size_t n_bytes,
904 const char *prev_block, const char *curr_block)
908 if (!(option_mask32 & OPT_v)
910 && n_bytes == G.bytes_per_block
911 && memcmp(prev_block, curr_block, G.bytes_per_block) == 0
913 if (G.prev_pair_equal) {
914 /* The two preceding blocks were equal, and the current
915 block is the same as the last one, so print nothing. */
918 G.prev_pair_equal = 1;
922 G.prev_pair_equal = 0;
923 for (i = 0; i < G.n_specs; i++) {
925 G.format_address(current_offset, '\0');
927 printf("%*s", address_pad_len_char - '0', "");
928 (*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string);
929 if (G.spec[i].hexl_mode_trailer) {
930 /* space-pad out to full line width, then dump the trailer */
931 unsigned datum_width = width_bytes[G.spec[i].size];
932 unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width;
933 unsigned field_width = G.spec[i].field_width + 1;
934 printf("%*s", blank_fields * field_width, "");
935 dump_hexl_mode_trailer(n_bytes, curr_block);
943 read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
945 assert(0 < n && n <= G.bytes_per_block);
947 *n_bytes_in_buffer = 0;
952 while (G.in_stream != NULL) { /* EOF. */
956 n_needed = n - *n_bytes_in_buffer;
957 n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream);
958 *n_bytes_in_buffer += n_read;
959 if (n_read == n_needed)
961 /* error check is done in check_and_close */
967 /* Return the least common multiple of the sizes associated
968 with the format specs. */
976 for (i = 0; i < G.n_specs; i++)
977 l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]);
981 /* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
982 formatted block to standard output, and repeat until the specified
983 maximum number of bytes has been read or until all input has been
984 processed. If the last block read is smaller than BYTES_PER_BLOCK
985 and its size is not a multiple of the size associated with a format
986 spec, extend the input block with zero bytes until its length is a
987 multiple of all format spec sizes. Write the final block. Finally,
988 write on a line by itself the offset of the byte after the last byte
992 dump(off_t current_offset, off_t end_offset)
998 block[0] = xmalloc(2 * G.bytes_per_block);
999 block[1] = block[0] + G.bytes_per_block;
1002 if (option_mask32 & OPT_N) {
1005 if (current_offset >= end_offset) {
1009 n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block);
1010 read_block(n_needed, block[idx], &n_bytes_read);
1011 if (n_bytes_read < G.bytes_per_block)
1013 assert(n_bytes_read == G.bytes_per_block);
1014 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1015 current_offset += n_bytes_read;
1020 read_block(G.bytes_per_block, block[idx], &n_bytes_read);
1021 if (n_bytes_read < G.bytes_per_block)
1023 assert(n_bytes_read == G.bytes_per_block);
1024 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1025 current_offset += n_bytes_read;
1030 if (n_bytes_read > 0) {
1032 size_t bytes_to_write;
1036 /* Make bytes_to_write the smallest multiple of l_c_m that
1037 is at least as large as n_bytes_read. */
1038 bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
1040 memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
1041 write_block(current_offset, bytes_to_write,
1042 block[idx ^ 1], block[idx]);
1043 current_offset += n_bytes_read;
1046 G.format_address(current_offset, '\n');
1048 if ((option_mask32 & OPT_N) && current_offset >= end_offset)
1054 /* Read N bytes into BLOCK from the concatenation of the input files
1055 named in the global array FILE_LIST. On the first call to this
1056 function, the global variable IN_STREAM is expected to be an open
1057 stream associated with the input file INPUT_FILENAME. If all N
1058 bytes cannot be read from IN_STREAM, close IN_STREAM and update
1059 the global variables IN_STREAM and INPUT_FILENAME. Then try to
1060 read the remaining bytes from the newly opened file. Repeat if
1061 necessary until EOF is reached for the last file in FILE_LIST.
1062 On subsequent calls, don't modify BLOCK and return zero. Set
1063 *N_BYTES_IN_BUFFER to the number of bytes read. If an error occurs,
1064 it will be detected through ferror when the stream is about to be
1065 closed. If there is an error, give a message but continue reading
1066 as usual and return nonzero. Otherwise return zero. */
1068 /* STRINGS mode. Find each "string constant" in the input.
1069 A string constant is a run of at least 'string_min' ASCII
1070 graphic (or formatting) characters terminated by a null.
1071 Based on a function written by Richard Stallman for a
1072 traditional version of od. */
1075 dump_strings(off_t address, off_t end_offset)
1077 unsigned bufsize = MAX(100, G.string_min);
1078 unsigned char *buf = xmalloc(bufsize);
1084 /* See if the next 'G.string_min' chars are all printing chars. */
1086 if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address))
1089 while (!(option_mask32 & OPT_N) || address < end_offset) {
1091 bufsize += bufsize/8;
1092 buf = xrealloc(buf, bufsize);
1095 while (G.in_stream) { /* !EOF */
1096 c = fgetc(G.in_stream);
1109 goto tryline; /* It isn't; give up on this string. */
1110 buf[i++] = c; /* String continues; store it all. */
1113 if (i < G.string_min) /* Too short! */
1116 /* If we get here, the string is all printable and NUL-terminated */
1118 G.format_address(address - i - 1, ' ');
1120 for (i = 0; (c = buf[i]); i++) {
1122 case '\007': fputs("\\a", stdout); break;
1123 case '\b': fputs("\\b", stdout); break;
1124 case '\f': fputs("\\f", stdout); break;
1125 case '\n': fputs("\\n", stdout); break;
1126 case '\r': fputs("\\r", stdout); break;
1127 case '\t': fputs("\\t", stdout); break;
1128 case '\v': fputs("\\v", stdout); break;
1129 default: putchar(c);
1135 /* We reach this point only if we search through
1136 (max_bytes_to_format - G.string_min) bytes before reaching EOF. */
1142 #if ENABLE_LONG_OPTS
1143 /* If S is a valid traditional offset specification with an optional
1144 leading '+' return nonzero and set *OFFSET to the offset it denotes. */
1147 parse_old_offset(const char *s, off_t *offset)
1149 static const struct suffix_mult Bb[] = {
1157 /* Skip over any leading '+'. */
1158 if (s[0] == '+') ++s;
1159 if (!isdigit(s[0])) return 0; /* not a number */
1161 /* Determine the radix we'll use to interpret S. If there is a '.',
1162 * it's decimal, otherwise, if the string begins with '0X'or '0x',
1163 * it's hexadecimal, else octal. */
1167 p[0] = '\0'; /* cheating */
1169 } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
1172 *offset = xstrtooff_sfx(s, radix, Bb);
1175 return (*offset >= 0);
1179 int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1180 int od_main(int argc UNUSED_PARAM, char **argv)
1182 #if ENABLE_LONG_OPTS
1183 static const char od_longopts[] ALIGN1 =
1184 "skip-bytes\0" Required_argument "j"
1185 "address-radix\0" Required_argument "A"
1186 "read-bytes\0" Required_argument "N"
1187 "format\0" Required_argument "t"
1188 "output-duplicates\0" No_argument "v"
1189 /* Yes, it's true: -S NUM, but --strings[=NUM]!
1190 * that is, NUM is mandatory for -S but optional for --strings!
1192 "strings\0" Optional_argument "S"
1193 "width\0" Optional_argument "w"
1194 "traditional\0" No_argument "\xff"
1197 const char *str_A, *str_N, *str_j, *str_S = "3";
1198 llist_t *lst_t = NULL;
1201 /* The number of input bytes to skip before formatting and writing. */
1202 off_t n_bytes_to_skip = 0;
1203 /* The offset of the first byte after the last byte to be formatted. */
1204 off_t end_offset = 0;
1205 /* The maximum number of bytes that will be formatted. */
1206 off_t max_bytes_to_format = 0;
1210 /*G.spec = NULL; - already is */
1211 G.format_address = format_address_std;
1212 address_base_char = 'o';
1213 address_pad_len_char = '7';
1215 /* Parse command line */
1216 #if ENABLE_LONG_OPTS
1217 applet_long_options = od_longopts;
1219 opt = OD_GETOPT32();
1222 static const char doxn[] ALIGN1 = "doxn";
1223 static const char doxn_address_base_char[] ALIGN1 = {
1224 'u', 'o', 'x', /* '?' fourth one is not important */
1226 static const uint8_t doxn_address_pad_len_char[] ALIGN1 = {
1227 '7', '7', '6', /* '?' */
1231 p = strchr(doxn, str_A[0]);
1233 bb_error_msg_and_die("bad output address radix "
1234 "'%c' (must be [doxn])", str_A[0]);
1236 if (pos == 3) G.format_address = format_address_none;
1237 address_base_char = doxn_address_base_char[pos];
1238 address_pad_len_char = doxn_address_pad_len_char[pos];
1241 max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm_suffixes);
1243 if (opt & OPT_a) decode_format_string("a");
1244 if (opt & OPT_b) decode_format_string("oC");
1245 if (opt & OPT_c) decode_format_string("c");
1246 if (opt & OPT_d) decode_format_string("u2");
1247 if (opt & OPT_f) decode_format_string("fF");
1248 if (opt & OPT_h) decode_format_string("x2");
1249 if (opt & OPT_i) decode_format_string("d2");
1250 if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm_suffixes);
1251 if (opt & OPT_l) decode_format_string("d4");
1252 if (opt & OPT_o) decode_format_string("o2");
1254 decode_format_string(llist_pop(&lst_t));
1256 if (opt & OPT_x) decode_format_string("x2");
1257 if (opt & OPT_s) decode_format_string("d2");
1259 G.string_min = xstrtou_sfx(str_S, 0, bkm_suffixes);
1263 //if ((option_mask32 & OPT_S) && G.n_specs > 0)
1264 // bb_error_msg_and_die("no type may be specified when dumping strings");
1266 /* If the --traditional option is used, there may be from
1267 * 0 to 3 remaining command line arguments; handle each case
1269 * od [FILE] [[+]OFFSET[.][b] [[+]LABEL[.][b]]]
1270 * The offset and pseudo_start have the same syntax.
1272 * FIXME: POSIX 1003.1-2001 with XSI requires support for the
1273 * traditional syntax even if --traditional is not given. */
1275 #if ENABLE_LONG_OPTS
1276 if (opt & OPT_traditional) {
1278 off_t pseudo_start = -1;
1281 if (!argv[1]) { /* one arg */
1282 if (parse_old_offset(argv[0], &o1)) {
1283 /* od --traditional OFFSET */
1284 n_bytes_to_skip = o1;
1287 /* od --traditional FILE */
1288 } else if (!argv[2]) { /* two args */
1289 if (parse_old_offset(argv[0], &o1)
1290 && parse_old_offset(argv[1], &o2)
1292 /* od --traditional OFFSET LABEL */
1293 n_bytes_to_skip = o1;
1296 } else if (parse_old_offset(argv[1], &o2)) {
1297 /* od --traditional FILE OFFSET */
1298 n_bytes_to_skip = o2;
1301 bb_error_msg_and_die("invalid second argument '%s'", argv[1]);
1303 } else if (!argv[3]) { /* three args */
1304 if (parse_old_offset(argv[1], &o1)
1305 && parse_old_offset(argv[2], &o2)
1307 /* od --traditional FILE OFFSET LABEL */
1308 n_bytes_to_skip = o1;
1312 bb_error_msg_and_die("the last two arguments must be offsets");
1314 } else { /* >3 args */
1315 bb_error_msg_and_die("too many arguments");
1318 if (pseudo_start >= 0) {
1319 if (G.format_address == format_address_none) {
1320 address_base_char = 'o';
1321 address_pad_len_char = '7';
1322 G.format_address = format_address_paren;
1324 G.format_address = format_address_label;
1326 G_pseudo_offset = pseudo_start - n_bytes_to_skip;
1329 /* else: od --traditional (without args) */
1333 if (option_mask32 & OPT_N) {
1334 end_offset = n_bytes_to_skip + max_bytes_to_format;
1335 if (end_offset < n_bytes_to_skip)
1336 bb_error_msg_and_die("SKIP + SIZE is too large");
1339 if (G.n_specs == 0) {
1340 decode_format_string("o2");
1341 /*G.n_specs = 1; - done by decode_format_string */
1344 /* If no files were listed on the command line,
1345 set the global pointer FILE_LIST so that it
1346 references the null-terminated list of one name: "-". */
1347 G.file_list = bb_argv_dash;
1349 /* Set the global pointer FILE_LIST so that it
1350 references the first file-argument on the command-line. */
1351 G.file_list = (char const *const *) argv;
1354 /* Open the first input file */
1356 /* Skip over any unwanted header bytes */
1357 skip(n_bytes_to_skip);
1359 return EXIT_FAILURE;
1361 /* Compute output block length */
1364 if (opt & OPT_w) { /* -w: width */
1365 if (!G.bytes_per_block || G.bytes_per_block % l_c_m != 0) {
1366 bb_error_msg("warning: invalid width %u; using %d instead",
1367 (unsigned)G.bytes_per_block, l_c_m);
1368 G.bytes_per_block = l_c_m;
1371 G.bytes_per_block = l_c_m;
1372 if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
1373 G.bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
1377 for (i = 0; i < G.n_specs; i++) {
1378 printf("%d: fmt=\"%s\" width=%d\n",
1379 i, spec[i].fmt_string, width_bytes[spec[i].size]);
1383 if (option_mask32 & OPT_S)
1384 dump_strings(n_bytes_to_skip, end_offset);
1386 dump(n_bytes_to_skip, end_offset);
1389 bb_perror_msg_and_die(bb_msg_standard_input);