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 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
221 G.bytes_per_block = 32; \
225 #define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
226 static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = {
227 [sizeof(char)] = CHAR,
228 #if USHRT_MAX != UCHAR_MAX
229 [sizeof(short)] = SHORT,
231 #if UINT_MAX != USHRT_MAX
234 #if ULONG_MAX != UINT_MAX
235 [sizeof(long)] = LONG,
237 #if ULLONG_MAX != ULONG_MAX
238 [sizeof(ulonglong_t)] = LONG_LONG,
242 #define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
243 static const unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = {
244 /* gcc seems to allow repeated indexes. Last one wins */
245 [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
246 [sizeof(double)] = FLOAT_DOUBLE,
247 [sizeof(float)] = FLOAT_SINGLE
252 gcd(unsigned u, unsigned v)
263 /* Compute the least common multiple of U and V. */
265 lcm(unsigned u, unsigned v) {
266 unsigned t = gcd(u, v);
273 print_s_char(size_t n_bytes, const char *block, const char *fmt_string)
276 int tmp = *(signed char *) block;
277 printf(fmt_string, tmp);
278 block += sizeof(unsigned char);
283 print_char(size_t n_bytes, const char *block, const char *fmt_string)
286 unsigned tmp = *(unsigned char *) block;
287 printf(fmt_string, tmp);
288 block += sizeof(unsigned char);
293 print_s_short(size_t n_bytes, const char *block, const char *fmt_string)
295 n_bytes /= sizeof(signed short);
297 int tmp = *(signed short *) block;
298 printf(fmt_string, tmp);
299 block += sizeof(unsigned short);
304 print_short(size_t n_bytes, const char *block, const char *fmt_string)
306 n_bytes /= sizeof(unsigned short);
308 unsigned tmp = *(unsigned short *) block;
309 printf(fmt_string, tmp);
310 block += sizeof(unsigned short);
315 print_int(size_t n_bytes, const char *block, const char *fmt_string)
317 n_bytes /= sizeof(unsigned);
319 unsigned tmp = *(unsigned *) block;
320 printf(fmt_string, tmp);
321 block += sizeof(unsigned);
325 #if UINT_MAX == ULONG_MAX
326 # define print_long print_int
329 print_long(size_t n_bytes, const char *block, const char *fmt_string)
331 n_bytes /= sizeof(unsigned long);
333 unsigned long tmp = *(unsigned long *) block;
334 printf(fmt_string, tmp);
335 block += sizeof(unsigned long);
340 #if ULONG_MAX == ULLONG_MAX
341 # define print_long_long print_long
344 print_long_long(size_t n_bytes, const char *block, const char *fmt_string)
346 n_bytes /= sizeof(ulonglong_t);
348 ulonglong_t tmp = *(ulonglong_t *) block;
349 printf(fmt_string, tmp);
350 block += sizeof(ulonglong_t);
356 print_float(size_t n_bytes, const char *block, const char *fmt_string)
358 n_bytes /= sizeof(float);
360 float tmp = *(float *) block;
361 printf(fmt_string, tmp);
362 block += sizeof(float);
367 print_double(size_t n_bytes, const char *block, const char *fmt_string)
369 n_bytes /= sizeof(double);
371 double tmp = *(double *) block;
372 printf(fmt_string, tmp);
373 block += sizeof(double);
378 print_long_double(size_t n_bytes, const char *block, const char *fmt_string)
380 n_bytes /= sizeof(longdouble_t);
382 longdouble_t tmp = *(longdouble_t *) block;
383 printf(fmt_string, tmp);
384 block += sizeof(longdouble_t);
388 /* print_[named]_ascii are optimized for speed.
389 * Remember, someday you may want to pump gigabytes through this thing.
390 * Saving a dozen of .text bytes here is counter-productive */
393 print_named_ascii(size_t n_bytes, const char *block,
394 const char *unused_fmt_string UNUSED_PARAM)
396 /* Names for some non-printing characters. */
397 static const char charname[33][3] ALIGN1 = {
398 "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
399 " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
400 "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
401 "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
404 // buf[N] pos: 01234 56789
405 char buf[12] = " x\0 xxx\0";
406 // [12] because we take three 32bit stack slots anyway, and
407 // gcc is too dumb to initialize with constant stores,
408 // it copies initializer from rodata. Oh well.
409 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65410
412 unsigned masked_c = *(unsigned char *) block++;
415 if (masked_c == 0x7f) {
416 fputs(" del", stdout);
419 if (masked_c > ' ') {
424 /* Why? Because printf(" %3.3s") is much slower... */
425 buf[6] = charname[masked_c][0];
426 buf[7] = charname[masked_c][1];
427 buf[8] = charname[masked_c][2];
428 fputs(buf+5, stdout);
433 print_ascii(size_t n_bytes, const char *block,
434 const char *unused_fmt_string UNUSED_PARAM)
436 // buf[N] pos: 01234 56789
437 char buf[12] = " x\0 xxx\0";
441 unsigned c = *(unsigned char *) block++;
474 buf[6] = (c >> 6 & 3) + '0';
475 buf[7] = (c >> 3 & 7) + '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. */
496 G.in_stream = fopen_or_warn_stdin(*G.file_list++);
503 if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N)
504 setbuf(G.in_stream, NULL);
507 /* Test whether there have been errors on in_stream, and close it if
508 it is not standard input. Return nonzero if there has been an error
509 on in_stream or stdout; return zero otherwise. This function will
510 report more than one error only if both a read and a write error
511 have occurred. IN_ERRNO, if nonzero, is the error number
512 corresponding to the most recent action for IN_STREAM. */
515 check_and_close(void)
518 if (ferror(G.in_stream)) {
519 bb_error_msg("%s: read error", (G.in_stream == stdin)
520 ? bb_msg_standard_input
525 fclose_if_not_stdin(G.in_stream);
529 if (ferror(stdout)) {
530 bb_error_msg_and_die(bb_msg_write_error);
534 /* If S points to a single valid modern od format string, put
535 a description of that format in *TSPEC, return pointer to
536 character following the just-decoded format.
537 For example, if S were "d4afL", we will return a rtp to "afL"
540 fmt = SIGNED_DECIMAL;
541 size = INT or LONG; (whichever integral_type_size[4] resolves to)
542 print_function = print_int; (assuming size == INT)
543 fmt_string = "%011d%c";
545 S_ORIG is solely for reporting errors. It should be the full format
548 static NOINLINE const char *
549 decode_one_format(const char *s_orig, const char *s, struct tspec *tspec)
551 enum size_spec size_spec;
553 enum output_format fmt;
556 char *fmt_string = NULL;
557 void (*print_function) (size_t, const char *, const char *);
559 unsigned field_width = 0;
567 static const char CSIL[] ALIGN1 = "CSIL";
570 p = strchr(CSIL, *s);
571 /* if *s == NUL, p != NULL! Testcase: "od -tx" */
572 if (!p || *p == '\0') {
575 size = bb_strtou(s, &end, 0);
577 || MAX_INTEGRAL_TYPE_SIZE < size
578 || integral_type_size[size] == NO_SIZE
580 bb_error_msg_and_die("invalid type string '%s'; "
581 "%u-byte %s type is not supported",
582 s_orig, size, "integral");
587 static const uint8_t CSIL_sizeof[4] = {
593 size = CSIL_sizeof[p - CSIL];
594 s++; /* skip C/S/I/L */
597 #define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format) \
598 ((Spec) == LONG_LONG ? (Max_format) \
599 : ((Spec) == LONG ? (Long_format) : (Min_format)))
601 #define FMT_BYTES_ALLOCATED 9
602 size_spec = integral_type_size[size];
605 static const char doux[] ALIGN1 = "doux";
606 static const char doux_fmt_letter[][4] = {
607 "lld", "llo", "llu", "llx"
609 static const enum output_format doux_fmt[] = {
615 static const uint8_t *const doux_bytes_to_XXX[] = {
616 bytes_to_signed_dec_digits,
618 bytes_to_unsigned_dec_digits,
621 static const char doux_fmtstring[][sizeof(" %%0%u%s")] = {
628 pos = strchr(doux, c) - doux;
630 field_width = doux_bytes_to_XXX[pos][size];
631 p = doux_fmt_letter[pos] + 2;
632 if (size_spec == LONG) p--;
633 if (size_spec == LONG_LONG) p -= 2;
634 fmt_string = xasprintf(doux_fmtstring[pos], field_width, p);
639 print_function = (fmt == SIGNED_DECIMAL
644 print_function = (fmt == SIGNED_DECIMAL
649 print_function = print_int;
652 print_function = print_long;
654 default: /* case LONG_LONG: */
655 print_function = print_long_long;
662 static const char FDL[] ALIGN1 = "FDL";
664 fmt = FLOATING_POINT;
668 size = sizeof(double);
670 size = bb_strtou(s, &end, 0);
671 if (errno == ERANGE || size > MAX_FP_TYPE_SIZE
672 || fp_type_size[size] == NO_SIZE
674 bb_error_msg_and_die("invalid type string '%s'; "
675 "%u-byte %s type is not supported",
676 s_orig, size, "floating point");
681 static const uint8_t FDL_sizeof[] = {
684 sizeof(longdouble_t),
687 size = FDL_sizeof[p - FDL];
690 size_spec = fp_type_size[size];
694 print_function = print_float;
695 field_width = FLT_DIG + 8;
696 /* Don't use %#e; not all systems support it. */
697 fmt_string = xasprintf(" %%%d.%de", field_width, FLT_DIG);
700 print_function = print_double;
701 field_width = DBL_DIG + 8;
702 fmt_string = xasprintf(" %%%d.%de", field_width, DBL_DIG);
704 default: /* case FLOAT_LONG_DOUBLE: */
705 print_function = print_long_double;
706 field_width = LDBL_DIG + 8;
707 fmt_string = xasprintf(" %%%d.%dLe", field_width, LDBL_DIG);
715 fmt = NAMED_CHARACTER;
717 print_function = print_named_ascii;
724 print_function = print_ascii;
728 bb_error_msg_and_die("invalid character '%c' "
729 "in type string '%s'", *s, s_orig);
732 tspec->size = size_spec;
734 tspec->print_function = print_function;
735 tspec->fmt_string = fmt_string;
737 tspec->field_width = field_width;
738 tspec->hexl_mode_trailer = (*s == 'z');
739 if (tspec->hexl_mode_trailer)
745 /* Decode the modern od format string S. Append the decoded
746 representation to the global array SPEC, reallocating SPEC if
750 decode_format_string(const char *s)
752 const char *s_orig = s;
758 next = decode_one_format(s_orig, s, &tspec);
762 G.spec = xrealloc_vector(G.spec, 4, G.n_specs);
763 memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0]));
768 /* Given a list of one or more input filenames FILE_LIST, set the global
769 file pointer IN_STREAM to position N_SKIP in the concatenation of
770 those files. If any file operation fails or if there are fewer than
771 N_SKIP bytes in the combined input, give an error message and return
772 nonzero. When possible, use seek rather than read operations to
773 advance IN_STREAM. */
781 while (G.in_stream) { /* !EOF */
782 struct stat file_stats;
784 /* First try seeking. For large offsets, this extra work is
785 worthwhile. If the offset is below some threshold it may be
786 more efficient to move the pointer by reading. There are two
787 issues when trying to seek:
788 - the file must be seekable.
789 - before seeking to the specified position, make sure
790 that the new position is in the current file.
791 Try to do that by getting file's size using fstat.
792 But that will work only for regular files. */
794 /* The st_size field is valid only for regular files
795 (and for symbolic links, which cannot occur here).
796 If the number of bytes left to skip is at least
797 as large as the size of the current file, we can
798 decrement n_skip and go on to the next file. */
799 if (fstat(fileno(G.in_stream), &file_stats) == 0
800 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0
802 if (file_stats.st_size < n_skip) {
803 n_skip -= file_stats.st_size;
804 /* take "check & close / open_next" route */
806 if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0)
811 /* If it's not a regular file with positive size,
812 position the file pointer by reading. */
814 size_t n_bytes_to_read = 1024;
818 if (n_skip < n_bytes_to_read)
819 n_bytes_to_read = n_skip;
820 n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream);
821 n_skip -= n_bytes_read;
822 if (n_bytes_read != n_bytes_to_read)
823 break; /* EOF on this file or error */
834 bb_error_msg_and_die("can't skip past end of combined input");
838 typedef void FN_format_address(off_t address, char c);
841 format_address_none(off_t address UNUSED_PARAM, char c UNUSED_PARAM)
845 static char address_fmt[] ALIGN1 = "%0n"OFF_FMT"xc";
846 /* Corresponds to 'x' above */
847 #define address_base_char address_fmt[sizeof(address_fmt)-3]
848 /* Corresponds to 'n' above */
849 #define address_pad_len_char address_fmt[2]
852 format_address_std(off_t address, char c)
854 /* Corresponds to 'c' */
855 address_fmt[sizeof(address_fmt)-2] = c;
856 printf(address_fmt, address);
860 /* only used with --traditional */
862 format_address_paren(off_t address, char c)
865 format_address_std(address, ')');
870 format_address_label(off_t address, char c)
872 format_address_std(address, ' ');
873 format_address_paren(address + G_pseudo_offset, c);
878 dump_hexl_mode_trailer(size_t n_bytes, const char *block)
882 unsigned c = *(unsigned char *) block++;
883 c = (ISPRINT(c) ? c : '.');
889 /* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
890 of the N_SPEC format specs. CURRENT_OFFSET is the byte address of
891 CURR_BLOCK in the concatenation of input files, and it is printed
892 (optionally) only before the output line associated with the first
893 format spec. When duplicate blocks are being abbreviated, the output
894 for a sequence of identical input blocks is the output for the first
895 block followed by an asterisk alone on a line. It is valid to compare
896 the blocks PREV_BLOCK and CURR_BLOCK only when N_BYTES == BYTES_PER_BLOCK.
897 That condition may be false only for the last input block -- and then
898 only when it has not been padded to length BYTES_PER_BLOCK. */
901 write_block(off_t current_offset, size_t n_bytes,
902 const char *prev_block, const char *curr_block)
906 if (!(option_mask32 & OPT_v)
908 && n_bytes == G.bytes_per_block
909 && memcmp(prev_block, curr_block, G.bytes_per_block) == 0
911 if (G.prev_pair_equal) {
912 /* The two preceding blocks were equal, and the current
913 block is the same as the last one, so print nothing. */
916 G.prev_pair_equal = 1;
920 G.prev_pair_equal = 0;
921 for (i = 0; i < G.n_specs; i++) {
923 G.format_address(current_offset, '\0');
925 printf("%*s", address_pad_len_char - '0', "");
926 (*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string);
927 if (G.spec[i].hexl_mode_trailer) {
928 /* space-pad out to full line width, then dump the trailer */
929 unsigned datum_width = width_bytes[G.spec[i].size];
930 unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width;
931 unsigned field_width = G.spec[i].field_width + 1;
932 printf("%*s", blank_fields * field_width, "");
933 dump_hexl_mode_trailer(n_bytes, curr_block);
941 read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
943 assert(0 < n && n <= G.bytes_per_block);
945 *n_bytes_in_buffer = 0;
950 while (G.in_stream != NULL) { /* EOF. */
954 n_needed = n - *n_bytes_in_buffer;
955 n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream);
956 *n_bytes_in_buffer += n_read;
957 if (n_read == n_needed)
959 /* error check is done in check_and_close */
965 /* Return the least common multiple of the sizes associated
966 with the format specs. */
974 for (i = 0; i < G.n_specs; i++)
975 l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]);
979 /* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
980 formatted block to standard output, and repeat until the specified
981 maximum number of bytes has been read or until all input has been
982 processed. If the last block read is smaller than BYTES_PER_BLOCK
983 and its size is not a multiple of the size associated with a format
984 spec, extend the input block with zero bytes until its length is a
985 multiple of all format spec sizes. Write the final block. Finally,
986 write on a line by itself the offset of the byte after the last byte
990 dump(off_t current_offset, off_t end_offset)
996 block[0] = xmalloc(2 * G.bytes_per_block);
997 block[1] = block[0] + G.bytes_per_block;
1000 if (option_mask32 & OPT_N) {
1003 if (current_offset >= end_offset) {
1007 n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block);
1008 read_block(n_needed, block[idx], &n_bytes_read);
1009 if (n_bytes_read < G.bytes_per_block)
1011 assert(n_bytes_read == G.bytes_per_block);
1012 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1013 current_offset += n_bytes_read;
1018 read_block(G.bytes_per_block, block[idx], &n_bytes_read);
1019 if (n_bytes_read < G.bytes_per_block)
1021 assert(n_bytes_read == G.bytes_per_block);
1022 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1023 current_offset += n_bytes_read;
1028 if (n_bytes_read > 0) {
1030 size_t bytes_to_write;
1034 /* Make bytes_to_write the smallest multiple of l_c_m that
1035 is at least as large as n_bytes_read. */
1036 bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
1038 memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
1039 write_block(current_offset, bytes_to_write,
1040 block[idx ^ 1], block[idx]);
1041 current_offset += n_bytes_read;
1044 G.format_address(current_offset, '\n');
1046 if ((option_mask32 & OPT_N) && current_offset >= end_offset)
1052 /* Read N bytes into BLOCK from the concatenation of the input files
1053 named in the global array FILE_LIST. On the first call to this
1054 function, the global variable IN_STREAM is expected to be an open
1055 stream associated with the input file INPUT_FILENAME. If all N
1056 bytes cannot be read from IN_STREAM, close IN_STREAM and update
1057 the global variables IN_STREAM and INPUT_FILENAME. Then try to
1058 read the remaining bytes from the newly opened file. Repeat if
1059 necessary until EOF is reached for the last file in FILE_LIST.
1060 On subsequent calls, don't modify BLOCK and return zero. Set
1061 *N_BYTES_IN_BUFFER to the number of bytes read. If an error occurs,
1062 it will be detected through ferror when the stream is about to be
1063 closed. If there is an error, give a message but continue reading
1064 as usual and return nonzero. Otherwise return zero. */
1066 /* STRINGS mode. Find each "string constant" in the input.
1067 A string constant is a run of at least 'string_min' ASCII
1068 graphic (or formatting) characters terminated by a null.
1069 Based on a function written by Richard Stallman for a
1070 traditional version of od. */
1073 dump_strings(off_t address, off_t end_offset)
1075 unsigned bufsize = MAX(100, G.string_min);
1076 unsigned char *buf = xmalloc(bufsize);
1082 /* See if the next 'G.string_min' chars are all printing chars. */
1084 if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address))
1087 while (!(option_mask32 & OPT_N) || address < end_offset) {
1089 bufsize += bufsize/8;
1090 buf = xrealloc(buf, bufsize);
1093 while (G.in_stream) { /* !EOF */
1094 c = fgetc(G.in_stream);
1107 goto tryline; /* It isn't; give up on this string. */
1108 buf[i++] = c; /* String continues; store it all. */
1111 if (i < G.string_min) /* Too short! */
1114 /* If we get here, the string is all printable and NUL-terminated */
1116 G.format_address(address - i - 1, ' ');
1118 for (i = 0; (c = buf[i]); i++) {
1120 case '\007': fputs("\\a", stdout); break;
1121 case '\b': fputs("\\b", stdout); break;
1122 case '\f': fputs("\\f", stdout); break;
1123 case '\n': fputs("\\n", stdout); break;
1124 case '\r': fputs("\\r", stdout); break;
1125 case '\t': fputs("\\t", stdout); break;
1126 case '\v': fputs("\\v", stdout); break;
1127 default: putchar(c);
1133 /* We reach this point only if we search through
1134 (max_bytes_to_format - G.string_min) bytes before reaching EOF. */
1140 #if ENABLE_LONG_OPTS
1141 /* If S is a valid traditional offset specification with an optional
1142 leading '+' return nonzero and set *OFFSET to the offset it denotes. */
1145 parse_old_offset(const char *s, off_t *offset)
1147 static const struct suffix_mult Bb[] = {
1155 /* Skip over any leading '+'. */
1156 if (s[0] == '+') ++s;
1157 if (!isdigit(s[0])) return 0; /* not a number */
1159 /* Determine the radix we'll use to interpret S. If there is a '.',
1160 * it's decimal, otherwise, if the string begins with '0X'or '0x',
1161 * it's hexadecimal, else octal. */
1165 p[0] = '\0'; /* cheating */
1167 } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
1170 *offset = xstrtooff_sfx(s, radix, Bb);
1173 return (*offset >= 0);
1177 int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1178 int od_main(int argc UNUSED_PARAM, char **argv)
1180 #if ENABLE_LONG_OPTS
1181 static const char od_longopts[] ALIGN1 =
1182 "skip-bytes\0" Required_argument "j"
1183 "address-radix\0" Required_argument "A"
1184 "read-bytes\0" Required_argument "N"
1185 "format\0" Required_argument "t"
1186 "output-duplicates\0" No_argument "v"
1187 /* Yes, it's true: -S NUM, but --strings[=NUM]!
1188 * that is, NUM is mandatory for -S but optional for --strings!
1190 "strings\0" Optional_argument "S"
1191 "width\0" Optional_argument "w"
1192 "traditional\0" No_argument "\xff"
1195 const char *str_A, *str_N, *str_j, *str_S = "3";
1196 llist_t *lst_t = NULL;
1199 /* The number of input bytes to skip before formatting and writing. */
1200 off_t n_bytes_to_skip = 0;
1201 /* The offset of the first byte after the last byte to be formatted. */
1202 off_t end_offset = 0;
1203 /* The maximum number of bytes that will be formatted. */
1204 off_t max_bytes_to_format = 0;
1208 /*G.spec = NULL; - already is */
1209 G.format_address = format_address_std;
1210 address_base_char = 'o';
1211 address_pad_len_char = '7';
1213 /* Parse command line */
1214 opt_complementary = "w+:t::"; /* -w N, -t is a list */
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);