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;
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];
691 size_spec = fp_type_size[size];
695 print_function = print_float;
696 field_width = FLT_DIG + 8;
697 /* Don't use %#e; not all systems support it. */
698 fmt_string = xasprintf(" %%%d.%de", field_width, FLT_DIG);
701 print_function = print_double;
702 field_width = DBL_DIG + 8;
703 fmt_string = xasprintf(" %%%d.%de", field_width, DBL_DIG);
705 default: /* case FLOAT_LONG_DOUBLE: */
706 print_function = print_long_double;
707 field_width = LDBL_DIG + 8;
708 fmt_string = xasprintf(" %%%d.%dLe", field_width, LDBL_DIG);
716 fmt = NAMED_CHARACTER;
718 print_function = print_named_ascii;
725 print_function = print_ascii;
729 bb_error_msg_and_die("invalid character '%c' "
730 "in type string '%s'", *s, s_orig);
733 tspec->size = size_spec;
735 tspec->print_function = print_function;
736 tspec->fmt_string = fmt_string;
738 tspec->field_width = field_width;
739 tspec->hexl_mode_trailer = (*s == 'z');
740 if (tspec->hexl_mode_trailer)
746 /* Decode the modern od format string S. Append the decoded
747 representation to the global array SPEC, reallocating SPEC if
751 decode_format_string(const char *s)
753 const char *s_orig = s;
759 next = decode_one_format(s_orig, s, &tspec);
763 G.spec = xrealloc_vector(G.spec, 4, G.n_specs);
764 memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0]));
769 /* Given a list of one or more input filenames FILE_LIST, set the global
770 file pointer IN_STREAM to position N_SKIP in the concatenation of
771 those files. If any file operation fails or if there are fewer than
772 N_SKIP bytes in the combined input, give an error message and return
773 nonzero. When possible, use seek rather than read operations to
774 advance IN_STREAM. */
782 while (G.in_stream) { /* !EOF */
783 struct stat file_stats;
785 /* First try seeking. For large offsets, this extra work is
786 worthwhile. If the offset is below some threshold it may be
787 more efficient to move the pointer by reading. There are two
788 issues when trying to seek:
789 - the file must be seekable.
790 - before seeking to the specified position, make sure
791 that the new position is in the current file.
792 Try to do that by getting file's size using fstat.
793 But that will work only for regular files. */
795 /* The st_size field is valid only for regular files
796 (and for symbolic links, which cannot occur here).
797 If the number of bytes left to skip is at least
798 as large as the size of the current file, we can
799 decrement n_skip and go on to the next file. */
800 if (fstat(fileno(G.in_stream), &file_stats) == 0
801 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0
803 if (file_stats.st_size < n_skip) {
804 n_skip -= file_stats.st_size;
805 /* take "check & close / open_next" route */
807 if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0)
812 /* If it's not a regular file with positive size,
813 position the file pointer by reading. */
815 size_t n_bytes_to_read = 1024;
819 if (n_skip < n_bytes_to_read)
820 n_bytes_to_read = n_skip;
821 n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream);
822 n_skip -= n_bytes_read;
823 if (n_bytes_read != n_bytes_to_read)
824 break; /* EOF on this file or error */
835 bb_error_msg_and_die("can't skip past end of combined input");
839 typedef void FN_format_address(off_t address, char c);
842 format_address_none(off_t address UNUSED_PARAM, char c UNUSED_PARAM)
846 static char address_fmt[] ALIGN1 = "%0n"OFF_FMT"xc";
847 /* Corresponds to 'x' above */
848 #define address_base_char address_fmt[sizeof(address_fmt)-3]
849 /* Corresponds to 'n' above */
850 #define address_pad_len_char address_fmt[2]
853 format_address_std(off_t address, char c)
855 /* Corresponds to 'c' */
856 address_fmt[sizeof(address_fmt)-2] = c;
857 printf(address_fmt, address);
861 /* only used with --traditional */
863 format_address_paren(off_t address, char c)
866 format_address_std(address, ')');
871 format_address_label(off_t address, char c)
873 format_address_std(address, ' ');
874 format_address_paren(address + G_pseudo_offset, c);
879 dump_hexl_mode_trailer(size_t n_bytes, const char *block)
883 unsigned c = *(unsigned char *) block++;
884 c = (ISPRINT(c) ? c : '.');
890 /* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
891 of the N_SPEC format specs. CURRENT_OFFSET is the byte address of
892 CURR_BLOCK in the concatenation of input files, and it is printed
893 (optionally) only before the output line associated with the first
894 format spec. When duplicate blocks are being abbreviated, the output
895 for a sequence of identical input blocks is the output for the first
896 block followed by an asterisk alone on a line. It is valid to compare
897 the blocks PREV_BLOCK and CURR_BLOCK only when N_BYTES == BYTES_PER_BLOCK.
898 That condition may be false only for the last input block -- and then
899 only when it has not been padded to length BYTES_PER_BLOCK. */
902 write_block(off_t current_offset, size_t n_bytes,
903 const char *prev_block, const char *curr_block)
907 if (!(option_mask32 & OPT_v)
909 && n_bytes == G.bytes_per_block
910 && memcmp(prev_block, curr_block, G.bytes_per_block) == 0
912 if (G.prev_pair_equal) {
913 /* The two preceding blocks were equal, and the current
914 block is the same as the last one, so print nothing. */
917 G.prev_pair_equal = 1;
921 G.prev_pair_equal = 0;
922 for (i = 0; i < G.n_specs; i++) {
924 G.format_address(current_offset, '\0');
926 printf("%*s", address_pad_len_char - '0', "");
927 (*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string);
928 if (G.spec[i].hexl_mode_trailer) {
929 /* space-pad out to full line width, then dump the trailer */
930 unsigned datum_width = width_bytes[G.spec[i].size];
931 unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width;
932 unsigned field_width = G.spec[i].field_width + 1;
933 printf("%*s", blank_fields * field_width, "");
934 dump_hexl_mode_trailer(n_bytes, curr_block);
942 read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
944 assert(0 < n && n <= G.bytes_per_block);
946 *n_bytes_in_buffer = 0;
951 while (G.in_stream != NULL) { /* EOF. */
955 n_needed = n - *n_bytes_in_buffer;
956 n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream);
957 *n_bytes_in_buffer += n_read;
958 if (n_read == n_needed)
960 /* error check is done in check_and_close */
966 /* Return the least common multiple of the sizes associated
967 with the format specs. */
975 for (i = 0; i < G.n_specs; i++)
976 l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]);
980 /* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
981 formatted block to standard output, and repeat until the specified
982 maximum number of bytes has been read or until all input has been
983 processed. If the last block read is smaller than BYTES_PER_BLOCK
984 and its size is not a multiple of the size associated with a format
985 spec, extend the input block with zero bytes until its length is a
986 multiple of all format spec sizes. Write the final block. Finally,
987 write on a line by itself the offset of the byte after the last byte
991 dump(off_t current_offset, off_t end_offset)
997 block[0] = xmalloc(2 * G.bytes_per_block);
998 block[1] = block[0] + G.bytes_per_block;
1001 if (option_mask32 & OPT_N) {
1004 if (current_offset >= end_offset) {
1008 n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block);
1009 read_block(n_needed, block[idx], &n_bytes_read);
1010 if (n_bytes_read < G.bytes_per_block)
1012 assert(n_bytes_read == G.bytes_per_block);
1013 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1014 current_offset += n_bytes_read;
1019 read_block(G.bytes_per_block, block[idx], &n_bytes_read);
1020 if (n_bytes_read < G.bytes_per_block)
1022 assert(n_bytes_read == G.bytes_per_block);
1023 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1024 current_offset += n_bytes_read;
1029 if (n_bytes_read > 0) {
1031 size_t bytes_to_write;
1035 /* Make bytes_to_write the smallest multiple of l_c_m that
1036 is at least as large as n_bytes_read. */
1037 bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
1039 memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
1040 write_block(current_offset, bytes_to_write,
1041 block[idx ^ 1], block[idx]);
1042 current_offset += n_bytes_read;
1045 G.format_address(current_offset, '\n');
1047 if ((option_mask32 & OPT_N) && current_offset >= end_offset)
1053 /* Read N bytes into BLOCK from the concatenation of the input files
1054 named in the global array FILE_LIST. On the first call to this
1055 function, the global variable IN_STREAM is expected to be an open
1056 stream associated with the input file INPUT_FILENAME. If all N
1057 bytes cannot be read from IN_STREAM, close IN_STREAM and update
1058 the global variables IN_STREAM and INPUT_FILENAME. Then try to
1059 read the remaining bytes from the newly opened file. Repeat if
1060 necessary until EOF is reached for the last file in FILE_LIST.
1061 On subsequent calls, don't modify BLOCK and return zero. Set
1062 *N_BYTES_IN_BUFFER to the number of bytes read. If an error occurs,
1063 it will be detected through ferror when the stream is about to be
1064 closed. If there is an error, give a message but continue reading
1065 as usual and return nonzero. Otherwise return zero. */
1067 /* STRINGS mode. Find each "string constant" in the input.
1068 A string constant is a run of at least 'string_min' ASCII
1069 graphic (or formatting) characters terminated by a null.
1070 Based on a function written by Richard Stallman for a
1071 traditional version of od. */
1074 dump_strings(off_t address, off_t end_offset)
1076 unsigned bufsize = MAX(100, G.string_min);
1077 unsigned char *buf = xmalloc(bufsize);
1083 /* See if the next 'G.string_min' chars are all printing chars. */
1085 if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address))
1088 while (!(option_mask32 & OPT_N) || address < end_offset) {
1090 bufsize += bufsize/8;
1091 buf = xrealloc(buf, bufsize);
1094 while (G.in_stream) { /* !EOF */
1095 c = fgetc(G.in_stream);
1108 goto tryline; /* It isn't; give up on this string. */
1109 buf[i++] = c; /* String continues; store it all. */
1112 if (i < G.string_min) /* Too short! */
1115 /* If we get here, the string is all printable and NUL-terminated */
1117 G.format_address(address - i - 1, ' ');
1119 for (i = 0; (c = buf[i]); i++) {
1121 case '\007': fputs("\\a", stdout); break;
1122 case '\b': fputs("\\b", stdout); break;
1123 case '\f': fputs("\\f", stdout); break;
1124 case '\n': fputs("\\n", stdout); break;
1125 case '\r': fputs("\\r", stdout); break;
1126 case '\t': fputs("\\t", stdout); break;
1127 case '\v': fputs("\\v", stdout); break;
1128 default: putchar(c);
1134 /* We reach this point only if we search through
1135 (max_bytes_to_format - G.string_min) bytes before reaching EOF. */
1141 #if ENABLE_LONG_OPTS
1142 /* If S is a valid traditional offset specification with an optional
1143 leading '+' return nonzero and set *OFFSET to the offset it denotes. */
1146 parse_old_offset(const char *s, off_t *offset)
1148 static const struct suffix_mult Bb[] = {
1156 /* Skip over any leading '+'. */
1157 if (s[0] == '+') ++s;
1158 if (!isdigit(s[0])) return 0; /* not a number */
1160 /* Determine the radix we'll use to interpret S. If there is a '.',
1161 * it's decimal, otherwise, if the string begins with '0X'or '0x',
1162 * it's hexadecimal, else octal. */
1166 p[0] = '\0'; /* cheating */
1168 } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
1171 *offset = xstrtooff_sfx(s, radix, Bb);
1174 return (*offset >= 0);
1178 int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1179 int od_main(int argc UNUSED_PARAM, char **argv)
1181 #if ENABLE_LONG_OPTS
1182 static const char od_longopts[] ALIGN1 =
1183 "skip-bytes\0" Required_argument "j"
1184 "address-radix\0" Required_argument "A"
1185 "read-bytes\0" Required_argument "N"
1186 "format\0" Required_argument "t"
1187 "output-duplicates\0" No_argument "v"
1188 /* Yes, it's true: -S NUM, but --strings[=NUM]!
1189 * that is, NUM is mandatory for -S but optional for --strings!
1191 "strings\0" Optional_argument "S"
1192 "width\0" Optional_argument "w"
1193 "traditional\0" No_argument "\xff"
1196 const char *str_A, *str_N, *str_j, *str_S = "3";
1197 llist_t *lst_t = NULL;
1200 /* The number of input bytes to skip before formatting and writing. */
1201 off_t n_bytes_to_skip = 0;
1202 /* The offset of the first byte after the last byte to be formatted. */
1203 off_t end_offset = 0;
1204 /* The maximum number of bytes that will be formatted. */
1205 off_t max_bytes_to_format = 0;
1209 /*G.spec = NULL; - already is */
1210 G.format_address = format_address_std;
1211 address_base_char = 'o';
1212 address_pad_len_char = '7';
1214 /* Parse command line */
1215 #if ENABLE_LONG_OPTS
1216 applet_long_options = od_longopts;
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;
1376 for (i = 0; i < G.n_specs; i++) {
1377 printf("%d: fmt=\"%s\" width=%d\n",
1378 i, spec[i].fmt_string, width_bytes[spec[i].size]);
1382 if (option_mask32 & OPT_S)
1383 dump_strings(n_bytes_to_skip, end_offset);
1385 dump(n_bytes_to_skip, end_offset);
1388 bb_perror_msg_and_die(bb_msg_standard_input);