od.c 6.5 KB

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