od.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * od implementation for busybox
  4. * Based on code from util-linux v 2.11l
  5. *
  6. * Copyright (c) 1990
  7. * The Regents of the University of California. All rights reserved.
  8. *
  9. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  10. *
  11. * Original copyright notice is retained at the end of this file.
  12. */
  13. #include "libbb.h"
  14. #if ENABLE_DESKTOP
  15. /* This one provides -t (busybox's own build script needs it) */
  16. #include "od_bloaty.c"
  17. #else
  18. #include <getopt.h>
  19. #include "dump.h"
  20. #define isdecdigit(c) isdigit(c)
  21. #define ishexdigit(c) (isxdigit)(c)
  22. static void
  23. odoffset(int argc, char ***argvp)
  24. {
  25. char *num, *p;
  26. int base;
  27. char *end;
  28. /*
  29. * The offset syntax of od(1) was genuinely bizarre. First, if
  30. * it started with a plus it had to be an offset. Otherwise, if
  31. * there were at least two arguments, a number or lower-case 'x'
  32. * followed by a number makes it an offset. By default it was
  33. * octal; if it started with 'x' or '0x' it was hex. If it ended
  34. * in a '.', it was decimal. If a 'b' or 'B' was appended, it
  35. * multiplied the number by 512 or 1024 byte units. There was
  36. * no way to assign a block count to a hex offset.
  37. *
  38. * We assumes it's a file if the offset is bad.
  39. */
  40. p = **argvp;
  41. if (!p) {
  42. /* hey someone is probably piping to us ... */
  43. return;
  44. }
  45. if ((*p != '+')
  46. && (argc < 2
  47. || (!isdecdigit(p[0])
  48. && ((p[0] != 'x') || !ishexdigit(p[1])))))
  49. return;
  50. base = 0;
  51. /*
  52. * bb_dump_skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
  53. * set base.
  54. */
  55. if (p[0] == '+')
  56. ++p;
  57. if (p[0] == 'x' && ishexdigit(p[1])) {
  58. ++p;
  59. base = 16;
  60. } else if (p[0] == '0' && p[1] == 'x') {
  61. p += 2;
  62. base = 16;
  63. }
  64. /* bb_dump_skip over the number */
  65. if (base == 16)
  66. for (num = p; ishexdigit(*p); ++p);
  67. else
  68. for (num = p; isdecdigit(*p); ++p);
  69. /* check for no number */
  70. if (num == p)
  71. return;
  72. /* if terminates with a '.', base is decimal */
  73. if (*p == '.') {
  74. if (base)
  75. return;
  76. base = 10;
  77. }
  78. bb_dump_skip = strtol(num, &end, base ? base : 8);
  79. /* if end isn't the same as p, we got a non-octal digit */
  80. if (end != p)
  81. bb_dump_skip = 0;
  82. else {
  83. if (*p) {
  84. if (*p == 'b') {
  85. bb_dump_skip *= 512;
  86. ++p;
  87. } else if (*p == 'B') {
  88. bb_dump_skip *= 1024;
  89. ++p;
  90. }
  91. }
  92. if (*p)
  93. bb_dump_skip = 0;
  94. else {
  95. ++*argvp;
  96. /*
  97. * If the offset uses a non-octal base, the base of
  98. * the offset is changed as well. This isn't pretty,
  99. * but it's easy.
  100. */
  101. #define TYPE_OFFSET 7
  102. {
  103. char x_or_d;
  104. if (base == 16) {
  105. x_or_d = 'x';
  106. goto DO_X_OR_D;
  107. }
  108. if (base == 10) {
  109. x_or_d = 'd';
  110. DO_X_OR_D:
  111. bb_dump_fshead->nextfu->fmt[TYPE_OFFSET]
  112. = bb_dump_fshead->nextfs->nextfu->fmt[TYPE_OFFSET]
  113. = x_or_d;
  114. }
  115. }
  116. }
  117. }
  118. }
  119. static const char *const add_strings[] = {
  120. "16/1 \"%3_u \" \"\\n\"", /* a */
  121. "8/2 \" %06o \" \"\\n\"", /* B, o */
  122. "16/1 \"%03o \" \"\\n\"", /* b */
  123. "16/1 \"%3_c \" \"\\n\"", /* c */
  124. "8/2 \" %05u \" \"\\n\"", /* d */
  125. "4/4 \" %010u \" \"\\n\"", /* D */
  126. "2/8 \" %21.14e \" \"\\n\"", /* e (undocumented in od), F */
  127. "4/4 \" %14.7e \" \"\\n\"", /* f */
  128. "4/4 \" %08x \" \"\\n\"", /* H, X */
  129. "8/2 \" %04x \" \"\\n\"", /* h, x */
  130. "4/4 \" %11d \" \"\\n\"", /* I, L, l */
  131. "8/2 \" %6d \" \"\\n\"", /* i */
  132. "4/4 \" %011o \" \"\\n\"", /* O */
  133. };
  134. static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxv";
  135. static const char od_o2si[] ALIGN1 = {
  136. 0, 1, 2, 3, 5,
  137. 4, 6, 6, 7, 8,
  138. 9, 0xa, 0xb, 0xa, 0xa,
  139. 0xb, 1, 8, 9,
  140. };
  141. int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  142. int od_main(int argc, char **argv)
  143. {
  144. int ch;
  145. int first = 1;
  146. char *p;
  147. bb_dump_vflag = FIRST;
  148. bb_dump_length = -1;
  149. while ((ch = getopt(argc, argv, od_opts)) > 0) {
  150. if (ch == 'v') {
  151. bb_dump_vflag = ALL;
  152. } else if (((p = strchr(od_opts, ch)) != NULL) && (*p != '\0')) {
  153. if (first) {
  154. first = 0;
  155. bb_dump_add("\"%07.7_Ao\n\"");
  156. bb_dump_add("\"%07.7_ao \"");
  157. } else {
  158. bb_dump_add("\" \"");
  159. }
  160. bb_dump_add(add_strings[(int)od_o2si[(p-od_opts)]]);
  161. } else { /* P, p, s, w, or other unhandled */
  162. bb_show_usage();
  163. }
  164. }
  165. if (!bb_dump_fshead) {
  166. bb_dump_add("\"%07.7_Ao\n\"");
  167. bb_dump_add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\"");
  168. }
  169. argc -= optind;
  170. argv += optind;
  171. odoffset(argc, &argv);
  172. return bb_dump_dump(argv);
  173. }
  174. #endif /* ENABLE_DESKTOP */
  175. /*-
  176. * Copyright (c) 1990 The Regents of the University of California.
  177. * All rights reserved.
  178. *
  179. * Redistribution and use in source and binary forms, with or without
  180. * modification, are permitted provided that the following conditions
  181. * are met:
  182. * 1. Redistributions of source code must retain the above copyright
  183. * notice, this list of conditions and the following disclaimer.
  184. * 2. Redistributions in binary form must reproduce the above copyright
  185. * notice, this list of conditions and the following disclaimer in the
  186. * documentation and/or other materials provided with the distribution.
  187. * 3. Neither the name of the University nor the names of its contributors
  188. * may be used to endorse or promote products derived from this software
  189. * without specific prior written permission.
  190. *
  191. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  192. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  193. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  194. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  195. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  196. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  197. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  198. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  199. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  200. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  201. * SUCH DAMAGE.
  202. */