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. */
20 /* Busyboxed by Denis Vlasenko
22 Based on od.c from coreutils-5.2.1
25 00000073 t parse_old_offset
27 00000090 r long_options
28 00000092 t print_named_ascii
29 000000bf t print_ascii
30 00000168 t write_block
31 00000366 t decode_format_string
34 Tested for compat with coreutils 6.3
35 using this script. Minor differences fixed.
39 time /path/to/coreutils/od \
48 diff -u -a std bbox >bbox.diff || { echo Different!; sleep 1; }
56 #define assert(a) ((void)0)
58 /* Check for 0x7f is a coreutils 6.3 addition */
59 #define ISPRINT(c) (((c)>=' ') && (c) != 0x7f)
61 typedef long double longdouble_t;
62 typedef unsigned long long ulonglong_t;
63 typedef long long llong;
66 # define xstrtooff_sfx xstrtoull_sfx
68 # define xstrtooff_sfx xstrtoul_sfx
71 /* The default number of input bytes per output line. */
72 #define DEFAULT_BYTES_PER_BLOCK 16
74 /* The number of decimal digits of precision in a float. */
79 /* The number of decimal digits of precision in a double. */
84 /* The number of decimal digits of precision in a long double. */
86 # define LDBL_DIG DBL_DIG
112 /* Each output format specification (from '-t spec' or from
113 old-style options) is represented by one of these structures. */
115 enum output_format fmt;
117 void (*print_function) (size_t, const char *, const char *);
119 int hexl_mode_trailer;
123 /* Convert the number of 8-bit bytes of a binary representation to
124 the number of characters (digits + sign if the type is signed)
125 required to represent the same quantity in the specified base/type.
126 For example, a 32-bit (4-byte) quantity may require a field width
127 as wide as the following for these types:
131 8 unsigned hexadecimal */
133 static const uint8_t bytes_to_oct_digits[] =
134 {0, 3, 6, 8, 11, 14, 16, 19, 22, 25, 27, 30, 32, 35, 38, 41, 43};
136 static const uint8_t bytes_to_signed_dec_digits[] =
137 {1, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 28, 30, 33, 35, 37, 40};
139 static const uint8_t bytes_to_unsigned_dec_digits[] =
140 {0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39};
142 static const uint8_t bytes_to_hex_digits[] =
143 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32};
145 /* Convert enum size_spec to the size of the named type. */
146 static const signed char width_bytes[] = {
158 /* Ensure that for each member of 'enum size_spec' there is an
159 initializer in the width_bytes array. */
161 int assert_width_bytes_matches_size_spec_decl
162 [sizeof width_bytes / sizeof width_bytes[0] == N_SIZE_SPECS ? 1 : -1];
165 static size_t string_min;
166 static int flag_dump_strings;
168 /* Non-zero if an old-style 'pseudo-address' was specified. */
169 static int flag_pseudo_start;
171 /* The difference between the old-style pseudo starting address and
172 the number of bytes to skip. */
173 static off_t pseudo_offset;
175 /* Function that accepts an address and an optional following char,
176 and prints the address and char to stdout. */
177 static void (*format_address) (off_t, char);
179 /* The number of input bytes to skip before formatting and writing. */
180 static off_t n_bytes_to_skip; // = 0;
182 /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
183 input is formatted. */
184 static int limit_bytes_to_format; // = 0;
186 /* The maximum number of bytes that will be formatted. */
187 static off_t max_bytes_to_format;
189 /* The offset of the first byte after the last byte to be formatted. */
190 static off_t end_offset;
192 /* When nonzero and two or more consecutive blocks are equal, format
193 only the first block and output an asterisk alone on the following
194 line to indicate that identical blocks have been elided. */
195 static int abbreviate_duplicate_blocks = 1;
197 /* An array of specs describing how to format each input block. */
198 static size_t n_specs;
199 static struct tspec *spec;
201 /* The number of input bytes formatted per output line. It must be
202 a multiple of the least common multiple of the sizes associated with
203 the specified output types. It should be as large as possible, but
204 no larger than 16 -- unless specified with the -w option. */
205 static size_t bytes_per_block;
207 /* Human-readable representation of *file_list (for error messages).
208 It differs from *file_list only when *file_list is "-". */
209 static char const *input_filename;
211 /* A NULL-terminated list of the file-arguments from the command line. */
212 static char const *const *file_list;
214 /* Initializer for file_list if no file-arguments
215 were specified on the command line. */
216 static char const *const default_file_list[] = { "-", NULL };
218 /* The input stream associated with the current file. */
219 static FILE *in_stream;
223 #define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
224 static unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] = {
225 [sizeof(char)] = CHAR,
226 #if USHRT_MAX != UCHAR_MAX
227 [sizeof(short)] = SHORT,
229 #if UINT_MAX != USHRT_MAX
232 #if ULONG_MAX != UINT_MAX
233 [sizeof(long)] = LONG,
235 #if ULLONG_MAX != ULONG_MAX
236 [sizeof(ulonglong_t)] = LONG_LONG,
240 #define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
241 static unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] = {
242 /* gcc seems to allow repeated indexes. Last one stays */
243 [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
244 [sizeof(double)] = FLOAT_DOUBLE,
245 [sizeof(float)] = FLOAT_SINGLE,
250 gcd(unsigned u, unsigned v)
261 /* Compute the least common multiple of U and V. */
263 lcm(unsigned u, unsigned v) {
264 unsigned t = gcd(u, v);
271 print_s_char(size_t n_bytes, const char *block, const char *fmt_string)
274 int tmp = *(signed char *) block;
275 printf(fmt_string, tmp);
276 block += sizeof(unsigned char);
281 print_char(size_t n_bytes, const char *block, const char *fmt_string)
284 unsigned tmp = *(unsigned char *) block;
285 printf(fmt_string, tmp);
286 block += sizeof(unsigned char);
291 print_s_short(size_t n_bytes, const char *block, const char *fmt_string)
293 n_bytes /= sizeof(signed short);
295 int tmp = *(signed short *) block;
296 printf(fmt_string, tmp);
297 block += sizeof(unsigned short);
302 print_short(size_t n_bytes, const char *block, const char *fmt_string)
304 n_bytes /= sizeof(unsigned short);
306 unsigned tmp = *(unsigned short *) block;
307 printf(fmt_string, tmp);
308 block += sizeof(unsigned short);
313 print_int(size_t n_bytes, const char *block, const char *fmt_string)
315 n_bytes /= sizeof(unsigned);
317 unsigned tmp = *(unsigned *) block;
318 printf(fmt_string, tmp);
319 block += sizeof(unsigned);
323 #if UINT_MAX == ULONG_MAX
324 # define print_long print_int
327 print_long(size_t n_bytes, const char *block, const char *fmt_string)
329 n_bytes /= sizeof(unsigned long);
331 unsigned long tmp = *(unsigned long *) block;
332 printf(fmt_string, tmp);
333 block += sizeof(unsigned long);
338 #if ULONG_MAX == ULLONG_MAX
339 # define print_long_long print_long
342 print_long_long(size_t n_bytes, const char *block, const char *fmt_string)
344 n_bytes /= sizeof(ulonglong_t);
346 ulonglong_t tmp = *(ulonglong_t *) block;
347 printf(fmt_string, tmp);
348 block += sizeof(ulonglong_t);
354 print_float(size_t n_bytes, const char *block, const char *fmt_string)
356 n_bytes /= sizeof(float);
358 float tmp = *(float *) block;
359 printf(fmt_string, tmp);
360 block += sizeof(float);
365 print_double(size_t n_bytes, const char *block, const char *fmt_string)
367 n_bytes /= sizeof(double);
369 double tmp = *(double *) block;
370 printf(fmt_string, tmp);
371 block += sizeof(double);
376 print_long_double(size_t n_bytes, const char *block, const char *fmt_string)
378 n_bytes /= sizeof(longdouble_t);
380 longdouble_t tmp = *(longdouble_t *) block;
381 printf(fmt_string, tmp);
382 block += sizeof(longdouble_t);
386 /* print_[named]_ascii are optimized for speed.
387 * Remember, someday you may want to pump gigabytes thru this thing.
388 * Saving a dozen of .text bytes here is counter-productive */
391 print_named_ascii(size_t n_bytes, const char *block,
392 const char *unused_fmt_string ATTRIBUTE_UNUSED)
394 /* Names for some non-printing characters. */
395 static const char charname[33][3] = {
396 "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
397 " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
398 "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
399 "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
402 // buf[N] pos: 01234 56789
403 char buf[12] = " x\0 0xx\0";
404 // actually " x\0 xxx\0", but I want to share the string with below.
405 // [12] because we take three 32bit stack slots anyway, and
406 // gcc is too dumb to initialize with constant stores,
407 // it copies initializer from rodata. Oh well.
410 unsigned masked_c = *(unsigned char *) block++;
413 if (masked_c == 0x7f) {
414 fputs(" del", stdout);
417 if (masked_c > ' ') {
422 /* Why? Because printf(" %3.3s") is much slower... */
423 buf[6] = charname[masked_c][0];
424 buf[7] = charname[masked_c][1];
425 buf[8] = charname[masked_c][2];
426 fputs(buf+5, stdout);
431 print_ascii(size_t n_bytes, const char *block,
432 const char *unused_fmt_string ATTRIBUTE_UNUSED)
434 // buf[N] pos: 01234 56789
435 char buf[12] = " x\0 0xx\0";
439 unsigned c = *(unsigned char *) block++;
474 default: /* c is never larger than 040 */
475 buf[7] = (c >> 3) + '0';
476 buf[8] = (c & 7) + '0';
483 /* Given a list of one or more input filenames FILE_LIST, set the global
484 file pointer IN_STREAM and the global string INPUT_FILENAME to the
485 first one that can be successfully opened. Modify FILE_LIST to
486 reference the next filename in the list. A file name of "-" is
487 interpreted as standard input. If any file open fails, give an error
488 message and return nonzero. */
494 input_filename = *file_list;
498 in_stream = fopen_or_warn_stdin(input_filename);
500 if (in_stream == stdin)
501 input_filename = bb_msg_standard_input;
507 if (limit_bytes_to_format && !flag_dump_strings)
508 setbuf(in_stream, NULL);
511 /* Test whether there have been errors on in_stream, and close it if
512 it is not standard input. Return nonzero if there has been an error
513 on in_stream or stdout; return zero otherwise. This function will
514 report more than one error only if both a read and a write error
515 have occurred. IN_ERRNO, if nonzero, is the error number
516 corresponding to the most recent action for IN_STREAM. */
519 check_and_close(void)
522 if (ferror(in_stream)) {
523 bb_error_msg("%s: read error", input_filename);
526 fclose_if_not_stdin(in_stream);
530 if (ferror(stdout)) {
531 bb_error_msg("write error");
536 /* If S points to a single valid modern od format string, put
537 a description of that format in *TSPEC, make *NEXT point at the
538 character following the just-decoded format (if *NEXT is non-NULL),
539 and return zero. For example, if S were "d4afL"
540 *NEXT would be set to "afL" and *TSPEC would be
542 fmt = SIGNED_DECIMAL;
543 size = INT or LONG; (whichever integral_type_size[4] resolves to)
544 print_function = print_int; (assuming size == INT)
545 fmt_string = "%011d%c";
547 S_ORIG is solely for reporting errors. It should be the full format
551 decode_one_format(const char *s_orig, const char *s, const char **next,
554 enum size_spec size_spec;
556 enum output_format fmt;
559 char *fmt_string = NULL;
560 void (*print_function) (size_t, const char *, const char *);
562 unsigned field_width = 0;
565 assert(tspec != NULL);
572 static const char CSIL[] = "CSIL";
575 p = strchr(CSIL, *s);
579 size = bb_strtou(s, &end, 0);
581 || MAX_INTEGRAL_TYPE_SIZE < size
582 || integral_type_size[size] == NO_SIZE
584 bb_error_msg_and_die("invalid type string '%s'; "
585 "%u-byte %s type is not supported",
586 s_orig, size, "integral");
591 static const uint8_t CSIL_sizeof[] = {
597 size = CSIL_sizeof[p - CSIL];
600 #define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format) \
601 ((Spec) == LONG_LONG ? (Max_format) \
602 : ((Spec) == LONG ? (Long_format) : (Min_format)))
604 #define FMT_BYTES_ALLOCATED 9
605 size_spec = integral_type_size[size];
608 static const char doux[] = "doux";
609 static const char doux_fmt_letter[][4] = {
610 "lld", "llo", "llu", "llx"
612 static const enum output_format doux_fmt[] = {
618 static const uint8_t *const doux_bytes_to_XXX[] = {
619 bytes_to_signed_dec_digits,
621 bytes_to_unsigned_dec_digits,
624 static const char doux_fmtstring[][sizeof(" %%0%u%s")] = {
631 pos = strchr(doux, c) - doux;
633 field_width = doux_bytes_to_XXX[pos][size];
634 p = doux_fmt_letter[pos] + 2;
635 if (size_spec == LONG) p--;
636 if (size_spec == LONG_LONG) p -= 2;
637 fmt_string = xasprintf(doux_fmtstring[pos], field_width, p);
642 print_function = (fmt == SIGNED_DECIMAL
647 print_function = (fmt == SIGNED_DECIMAL
652 print_function = print_int;
655 print_function = print_long;
657 default: /* case LONG_LONG: */
658 print_function = print_long_long;
665 static const char FDL[] = "FDL";
667 fmt = FLOATING_POINT;
671 size = sizeof(double);
673 size = bb_strtou(s, &end, 0);
674 if (errno == ERANGE || size > MAX_FP_TYPE_SIZE
675 || fp_type_size[size] == NO_SIZE
677 bb_error_msg_and_die("invalid type string '%s'; "
678 "%u-byte %s type is not supported",
679 s_orig, size, "floating point");
684 static const uint8_t FDL_sizeof[] = {
687 sizeof(longdouble_t),
690 size = FDL_sizeof[p - FDL];
693 size_spec = fp_type_size[size];
697 print_function = print_float;
698 field_width = FLT_DIG + 8;
699 /* Don't use %#e; not all systems support it. */
700 fmt_string = xasprintf(" %%%d.%de", field_width, FLT_DIG);
703 print_function = print_double;
704 field_width = DBL_DIG + 8;
705 fmt_string = xasprintf(" %%%d.%de", field_width, DBL_DIG);
707 default: /* case FLOAT_LONG_DOUBLE: */
708 print_function = print_long_double;
709 field_width = LDBL_DIG + 8;
710 fmt_string = xasprintf(" %%%d.%dLe", field_width, LDBL_DIG);
718 fmt = NAMED_CHARACTER;
720 print_function = print_named_ascii;
727 print_function = print_ascii;
731 bb_error_msg_and_die("invalid character '%c' "
732 "in type string '%s'", *s, s_orig);
735 tspec->size = size_spec;
737 tspec->print_function = print_function;
738 tspec->fmt_string = fmt_string;
740 tspec->field_width = field_width;
741 tspec->hexl_mode_trailer = (*s == 'z');
742 if (tspec->hexl_mode_trailer)
749 /* Decode the modern od format string S. Append the decoded
750 representation to the global array SPEC, reallocating SPEC if
751 necessary. Return zero if S is valid, nonzero otherwise. */
754 decode_format_string(const char *s)
756 const char *s_orig = s;
762 decode_one_format(s_orig, s, &next, &tspec);
767 spec = xrealloc(spec, n_specs * sizeof(*spec));
768 memcpy(&spec[n_specs-1], &tspec, sizeof *spec);
772 /* Given a list of one or more input filenames FILE_LIST, set the global
773 file pointer IN_STREAM to position N_SKIP in the concatenation of
774 those files. If any file operation fails or if there are fewer than
775 N_SKIP bytes in the combined input, give an error message and return
776 nonzero. When possible, use seek rather than read operations to
777 advance IN_STREAM. */
785 while (in_stream) { /* !EOF */
786 struct stat file_stats;
788 /* First try seeking. For large offsets, this extra work is
789 worthwhile. If the offset is below some threshold it may be
790 more efficient to move the pointer by reading. There are two
791 issues when trying to seek:
792 - the file must be seekable.
793 - before seeking to the specified position, make sure
794 that the new position is in the current file.
795 Try to do that by getting file's size using fstat.
796 But that will work only for regular files. */
798 /* The st_size field is valid only for regular files
799 (and for symbolic links, which cannot occur here).
800 If the number of bytes left to skip is at least
801 as large as the size of the current file, we can
802 decrement n_skip and go on to the next file. */
803 if (fstat(fileno(in_stream), &file_stats) == 0
804 && S_ISREG(file_stats.st_mode) && file_stats.st_size >= 0
806 if (file_stats.st_size < n_skip) {
807 n_skip -= file_stats.st_size;
808 /* take check&close / open_next route */
810 if (fseeko(in_stream, n_skip, SEEK_CUR) != 0)
815 /* If it's not a regular file with nonnegative size,
816 position the file pointer by reading. */
818 size_t n_bytes_read, n_bytes_to_read = BUFSIZ;
821 if (n_skip < n_bytes_to_read)
822 n_bytes_to_read = n_skip;
823 n_bytes_read = fread(buf, 1, n_bytes_to_read, in_stream);
824 n_skip -= n_bytes_read;
825 if (n_bytes_read != n_bytes_to_read)
826 break; /* EOF on this file or error */
837 bb_error_msg_and_die("cannot skip past end of combined input");
841 typedef void FN_format_address(off_t address, char c);
844 format_address_none(off_t address ATTRIBUTE_UNUSED, char c ATTRIBUTE_UNUSED)
848 static char address_fmt[] = "%0n"OFF_FMT"xc";
849 /* Corresponds to 'x' above */
850 #define address_base_char address_fmt[sizeof(address_fmt)-3]
851 /* Corresponds to 'n' above */
852 #define address_pad_len_char address_fmt[2]
855 format_address_std(off_t address, char c)
857 /* Corresponds to 'c' */
858 address_fmt[sizeof(address_fmt)-2] = c;
859 printf(address_fmt, address);
862 #if ENABLE_GETOPT_LONG
863 /* only used with --traditional */
865 format_address_paren(off_t address, char c)
868 format_address_std(address, ')');
869 /* BUG in coreutils 5.2.1! must be "if (c) putchar(c);" */
874 format_address_label(off_t address, char c)
876 format_address_std(address, ' ');
877 format_address_paren(address + 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)
908 static char first = 1;
909 static char prev_pair_equal = 0;
912 if (abbreviate_duplicate_blocks
914 && n_bytes == bytes_per_block
915 && memcmp(prev_block, curr_block, bytes_per_block) == 0
917 if (prev_pair_equal) {
918 /* The two preceding blocks were equal, and the current
919 block is the same as the last one, so print nothing. */
927 for (i = 0; i < n_specs; i++) {
929 format_address(current_offset, '\0');
931 printf("%*s", address_pad_len_char - '0', "");
932 (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
933 if (spec[i].hexl_mode_trailer) {
934 /* space-pad out to full line width, then dump the trailer */
935 int datum_width = width_bytes[spec[i].size];
936 int blank_fields = (bytes_per_block - n_bytes) / datum_width;
937 int field_width = spec[i].field_width + 1;
938 printf("%*s", blank_fields * field_width, "");
939 dump_hexl_mode_trailer(n_bytes, curr_block);
947 read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
949 assert(0 < n && n <= bytes_per_block);
951 *n_bytes_in_buffer = 0;
956 while (in_stream != NULL) { /* EOF. */
960 n_needed = n - *n_bytes_in_buffer;
961 n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, in_stream);
962 *n_bytes_in_buffer += n_read;
963 if (n_read == n_needed)
965 /* error check is done in check_and_close */
971 /* Return the least common multiple of the sizes associated
972 with the format specs. */
980 for (i = 0; i < n_specs; i++)
981 l_c_m = lcm(l_c_m, width_bytes[(int) spec[i].size]);
985 #if ENABLE_GETOPT_LONG
986 /* If S is a valid traditional offset specification with an optional
987 leading '+' return nonzero and set *OFFSET to the offset it denotes. */
990 parse_old_offset(const char *s, off_t *offset)
992 static const struct suffix_mult Bb[] = {
1000 /* Skip over any leading '+'. */
1001 if (s[0] == '+') ++s;
1003 /* Determine the radix we'll use to interpret S. If there is a '.',
1004 * it's decimal, otherwise, if the string begins with '0X'or '0x',
1005 * it's hexadecimal, else octal. */
1009 p[0] = '\0'; /* cheating */
1011 } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
1014 *offset = xstrtooff_sfx(s, radix, Bb);
1017 return (*offset >= 0);
1021 /* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
1022 formatted block to standard output, and repeat until the specified
1023 maximum number of bytes has been read or until all input has been
1024 processed. If the last block read is smaller than BYTES_PER_BLOCK
1025 and its size is not a multiple of the size associated with a format
1026 spec, extend the input block with zero bytes until its length is a
1027 multiple of all format spec sizes. Write the final block. Finally,
1028 write on a line by itself the offset of the byte after the last byte
1029 read. Accumulate return values from calls to read_block and
1030 check_and_close, and if any was nonzero, return nonzero.
1031 Otherwise, return zero. */
1037 off_t current_offset;
1039 size_t n_bytes_read;
1041 block[0] = xmalloc(2*bytes_per_block);
1042 block[1] = block[0] + bytes_per_block;
1044 current_offset = n_bytes_to_skip;
1047 if (limit_bytes_to_format) {
1050 if (current_offset >= end_offset) {
1054 n_needed = MIN(end_offset - current_offset,
1055 (off_t) bytes_per_block);
1056 read_block(n_needed, block[idx], &n_bytes_read);
1057 if (n_bytes_read < bytes_per_block)
1059 assert(n_bytes_read == bytes_per_block);
1060 write_block(current_offset, n_bytes_read,
1061 block[!idx], block[idx]);
1062 current_offset += n_bytes_read;
1067 read_block(bytes_per_block, block[idx], &n_bytes_read);
1068 if (n_bytes_read < bytes_per_block)
1070 assert(n_bytes_read == bytes_per_block);
1071 write_block(current_offset, n_bytes_read,
1072 block[!idx], block[idx]);
1073 current_offset += n_bytes_read;
1078 if (n_bytes_read > 0) {
1080 size_t bytes_to_write;
1084 /* Make bytes_to_write the smallest multiple of l_c_m that
1085 is at least as large as n_bytes_read. */
1086 bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
1088 memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
1089 write_block(current_offset, bytes_to_write,
1090 block[!idx], block[idx]);
1091 current_offset += n_bytes_read;
1094 format_address(current_offset, '\n');
1096 if (limit_bytes_to_format && current_offset >= end_offset)
1102 /* Read a single byte into *C from the concatenation of the input files
1103 named in the global array FILE_LIST. On the first call to this
1104 function, the global variable IN_STREAM is expected to be an open
1105 stream associated with the input file INPUT_FILENAME. If IN_STREAM
1106 is at end-of-file, close it and update the global variables IN_STREAM
1107 and INPUT_FILENAME so they correspond to the next file in the list.
1108 Then try to read a byte from the newly opened file. Repeat if
1109 necessary until EOF is reached for the last file in FILE_LIST, then
1110 set *C to EOF and return. Subsequent calls do likewise. The return
1111 value is nonzero if any errors occured, zero otherwise. */
1116 while (in_stream) { /* !EOF */
1117 *c = fgetc(in_stream);
1126 /* Read N bytes into BLOCK from the concatenation of the input files
1127 named in the global array FILE_LIST. On the first call to this
1128 function, the global variable IN_STREAM is expected to be an open
1129 stream associated with the input file INPUT_FILENAME. If all N
1130 bytes cannot be read from IN_STREAM, close IN_STREAM and update
1131 the global variables IN_STREAM and INPUT_FILENAME. Then try to
1132 read the remaining bytes from the newly opened file. Repeat if
1133 necessary until EOF is reached for the last file in FILE_LIST.
1134 On subsequent calls, don't modify BLOCK and return zero. Set
1135 *N_BYTES_IN_BUFFER to the number of bytes read. If an error occurs,
1136 it will be detected through ferror when the stream is about to be
1137 closed. If there is an error, give a message but continue reading
1138 as usual and return nonzero. Otherwise return zero. */
1140 /* STRINGS mode. Find each "string constant" in the input.
1141 A string constant is a run of at least 'string_min' ASCII
1142 graphic (or formatting) characters terminated by a null.
1143 Based on a function written by Richard Stallman for a
1144 traditional version of od. Return nonzero if an error
1145 occurs. Otherwise, return zero. */
1150 size_t bufsize = MAX(100, string_min);
1151 char *buf = xmalloc(bufsize);
1152 off_t address = n_bytes_to_skip;
1158 /* See if the next 'string_min' chars are all printing chars. */
1160 if (limit_bytes_to_format && (end_offset - string_min <= address))
1163 while (!limit_bytes_to_format || address < end_offset) {
1165 bufsize += bufsize/8;
1166 buf = xrealloc(buf, bufsize);
1169 if (c < 0) { /* EOF */
1177 goto tryline; /* It isn't; give up on this string. */
1178 buf[i++] = c; /* String continues; store it all. */
1181 if (i < string_min) /* Too short! */
1184 /* If we get here, the string is all printable and null-terminated,
1185 * so print it. It is all in 'buf' and 'i' is its length. */
1187 format_address(address - i - 1, ' ');
1189 for (i = 0; (c = buf[i]); i++) {
1191 case '\007': fputs("\\a", stdout); break;
1192 case '\b': fputs("\\b", stdout); break;
1193 case '\f': fputs("\\f", stdout); break;
1194 case '\n': fputs("\\n", stdout); break;
1195 case '\r': fputs("\\r", stdout); break;
1196 case '\t': fputs("\\t", stdout); break;
1197 case '\v': fputs("\\v", stdout); break;
1198 default: putc(c, stdout);
1204 /* We reach this point only if we search through
1205 (max_bytes_to_format - string_min) bytes before reaching EOF. */
1212 od_main(int argc, char **argv)
1214 static const struct suffix_mult bkm[] = {
1222 /* The old-style 'pseudo starting address' to be printed in parentheses
1223 after any true address. */
1224 off_t pseudo_start = 0; // only for gcc
1244 OPT_traditional = (1 << 18) * ENABLE_GETOPT_LONG,
1246 #if ENABLE_GETOPT_LONG
1247 static const struct option long_options[] = {
1248 { "skip-bytes", required_argument, NULL, 'j' },
1249 { "address-radix", required_argument, NULL, 'A' },
1250 { "read-bytes", required_argument, NULL, 'N' },
1251 { "format", required_argument, NULL, 't' },
1252 { "output-duplicates", no_argument, NULL, 'v' },
1253 { "strings", optional_argument, NULL, 'S' },
1254 { "width", optional_argument, NULL, 'w' },
1255 { "traditional", no_argument, NULL, 0xff },
1256 { NULL, 0, NULL, 0 }
1259 char *str_A, *str_N, *str_j, *str_S;
1261 llist_t *lst_t = NULL;
1264 format_address = format_address_std;
1265 address_base_char = 'o';
1266 address_pad_len_char = '7';
1267 flag_dump_strings = 0;
1269 /* Parse command line */
1270 opt_complementary = "t::"; // list
1271 #if ENABLE_GETOPT_LONG
1272 applet_long_options = long_options;
1274 opt = getopt32(argc, argv, "A:N:abcdfhij:lot:vxsS:"
1275 "w::", // -w with optional param
1276 // -S was -s and also had optional parameter
1277 // but in coreutils 6.3 it was renamed and now has
1278 // _mandatory_ parameter
1279 &str_A, &str_N, &str_j, &lst_t, &str_S, &str_w);
1283 static const char doxn[] = "doxn";
1284 static const char doxn_address_base_char[] = {
1285 'u', 'o', 'x', /* '?' fourth one is not important */
1287 static const uint8_t doxn_address_pad_len_char[] = {
1288 '7', '7', '6', /* '?' */
1292 p = strchr(doxn, str_A[0]);
1294 bb_error_msg_and_die("bad output address radix "
1295 "'%c' (must be [doxn])", str_A[0]);
1297 if (pos == 3) format_address = format_address_none;
1298 address_base_char = doxn_address_base_char[pos];
1299 address_pad_len_char = doxn_address_pad_len_char[pos];
1302 limit_bytes_to_format = 1;
1303 max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm);
1305 if (opt & OPT_a) decode_format_string("a");
1306 if (opt & OPT_b) decode_format_string("oC");
1307 if (opt & OPT_c) decode_format_string("c");
1308 if (opt & OPT_d) decode_format_string("u2");
1309 if (opt & OPT_f) decode_format_string("fF");
1310 if (opt & OPT_h) decode_format_string("x2");
1311 if (opt & OPT_i) decode_format_string("d2");
1312 if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm);
1313 if (opt & OPT_l) decode_format_string("d4");
1314 if (opt & OPT_o) decode_format_string("o2");
1315 //if (opt & OPT_t)...
1316 lst_t = rev_llist(lst_t);
1318 decode_format_string(lst_t->data);
1319 lst_t = lst_t->link;
1321 if (opt & OPT_v) abbreviate_duplicate_blocks = 0;
1322 if (opt & OPT_x) decode_format_string("x2");
1323 if (opt & OPT_s) decode_format_string("d2");
1326 string_min = xstrtou_sfx(str_S, 0, bkm);
1327 flag_dump_strings = 1;
1329 //if (opt & OPT_w)...
1330 //if (opt & OPT_traditional)...
1332 if (flag_dump_strings && n_specs > 0)
1333 bb_error_msg_and_die("no type may be specified when dumping strings");
1335 /* If the --traditional option is used, there may be from
1336 * 0 to 3 remaining command line arguments; handle each case
1338 * od [file] [[+]offset[.][b] [[+]label[.][b]]]
1339 * The offset and pseudo_start have the same syntax.
1341 * FIXME: POSIX 1003.1-2001 with XSI requires support for the
1342 * traditional syntax even if --traditional is not given. */
1344 #if ENABLE_GETOPT_LONG
1345 if (opt & OPT_traditional) {
1349 if (parse_old_offset(argv[0], &o1)) {
1350 n_bytes_to_skip = o1;
1354 } else if (argc == 2) {
1355 if (parse_old_offset(argv[0], &o1)
1356 && parse_old_offset(argv[1], &o2)
1358 n_bytes_to_skip = o1;
1359 flag_pseudo_start = 1;
1363 } else if (parse_old_offset(argv[1], &o2)) {
1364 n_bytes_to_skip = o2;
1369 bb_error_msg_and_die("invalid second operand "
1370 "in compatibility mode '%s'", argv[1]);
1372 } else if (argc == 3) {
1373 if (parse_old_offset(argv[1], &o1)
1374 && parse_old_offset(argv[2], &o2)
1376 n_bytes_to_skip = o1;
1377 flag_pseudo_start = 1;
1383 bb_error_msg_and_die("in compatibility mode "
1384 "the last two arguments must be offsets");
1386 } else if (argc > 3) {
1387 bb_error_msg_and_die("compatibility mode supports "
1388 "at most three arguments");
1391 if (flag_pseudo_start) {
1392 if (format_address == format_address_none) {
1393 address_base_char = 'o';
1394 address_pad_len_char = '7';
1395 format_address = format_address_paren;
1397 format_address = format_address_label;
1402 if (limit_bytes_to_format) {
1403 end_offset = n_bytes_to_skip + max_bytes_to_format;
1404 if (end_offset < n_bytes_to_skip)
1405 bb_error_msg_and_die("skip-bytes + read-bytes is too large");
1409 decode_format_string("o2");
1413 /* If no files were listed on the command line,
1414 set the global pointer FILE_LIST so that it
1415 references the null-terminated list of one name: "-". */
1416 file_list = default_file_list;
1418 /* Set the global pointer FILE_LIST so that it
1419 references the first file-argument on the command-line. */
1420 file_list = (char const *const *) argv;
1423 /* open the first input file */
1425 /* skip over any unwanted header bytes */
1426 skip(n_bytes_to_skip);
1430 pseudo_offset = (flag_pseudo_start ? pseudo_start - n_bytes_to_skip : 0);
1432 /* Compute output block length. */
1435 if (opt & OPT_w) { /* -w: width */
1436 bytes_per_block = 32;
1438 bytes_per_block = xatou(str_w);
1439 if (!bytes_per_block || bytes_per_block % l_c_m != 0) {
1440 bb_error_msg("warning: invalid width %u; using %d instead",
1441 bytes_per_block, l_c_m);
1442 bytes_per_block = l_c_m;
1445 bytes_per_block = l_c_m;
1446 if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
1447 bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
1451 for (i = 0; i < n_specs; i++) {
1452 printf("%d: fmt=\"%s\" width=%d\n",
1453 i, spec[i].fmt_string, width_bytes[spec[i].size]);
1457 if (flag_dump_strings)
1462 if (fclose(stdin) == EOF)
1463 bb_perror_msg_and_die(bb_msg_standard_input);
1465 return (ioerror != 0); /* err != 0 - return 1 (failure) */