od.c 6.0 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 "dump.h"
  19. #define isdecdigit(c) isdigit(c)
  20. #define ishexdigit(c) (isxdigit)(c)
  21. static void
  22. odoffset(dumper_t *dumper, int argc, char ***argvp)
  23. {
  24. char *num, *p;
  25. int base;
  26. char *end;
  27. /*
  28. * The offset syntax of od(1) was genuinely bizarre. First, if
  29. * it started with a plus it had to be an offset. Otherwise, if
  30. * there were at least two arguments, a number or lower-case 'x'
  31. * followed by a number makes it an offset. By default it was
  32. * octal; if it started with 'x' or '0x' it was hex. If it ended
  33. * in a '.', it was decimal. If a 'b' or 'B' was appended, it
  34. * multiplied the number by 512 or 1024 byte units. There was
  35. * no way to assign a block count to a hex offset.
  36. *
  37. * We assumes it's a file if the offset is bad.
  38. */
  39. p = **argvp;
  40. if (!p) {
  41. /* hey someone is probably piping to us ... */
  42. return;
  43. }
  44. if ((*p != '+')
  45. && (argc < 2
  46. || (!isdecdigit(p[0])
  47. && ((p[0] != 'x') || !ishexdigit(p[1])))))
  48. return;
  49. base = 0;
  50. /*
  51. * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
  52. * set base.
  53. */
  54. if (p[0] == '+')
  55. ++p;
  56. if (p[0] == 'x' && ishexdigit(p[1])) {
  57. ++p;
  58. base = 16;
  59. } else if (p[0] == '0' && p[1] == 'x') {
  60. p += 2;
  61. base = 16;
  62. }
  63. /* skip over the number */
  64. if (base == 16)
  65. for (num = p; ishexdigit(*p); ++p)
  66. continue;
  67. else
  68. for (num = p; isdecdigit(*p); ++p)
  69. continue;
  70. /* check for no number */
  71. if (num == p)
  72. return;
  73. /* if terminates with a '.', base is decimal */
  74. if (*p == '.') {
  75. if (base)
  76. return;
  77. base = 10;
  78. }
  79. dumper->dump_skip = strtol(num, &end, base ? base : 8);
  80. /* if end isn't the same as p, we got a non-octal digit */
  81. if (end != p)
  82. dumper->dump_skip = 0;
  83. else {
  84. if (*p) {
  85. if (*p == 'b') {
  86. dumper->dump_skip *= 512;
  87. ++p;
  88. } else if (*p == 'B') {
  89. dumper->dump_skip *= 1024;
  90. ++p;
  91. }
  92. }
  93. if (*p)
  94. dumper->dump_skip = 0;
  95. else {
  96. ++*argvp;
  97. /*
  98. * If the offset uses a non-octal base, the base of
  99. * the offset is changed as well. This isn't pretty,
  100. * but it's easy.
  101. */
  102. #define TYPE_OFFSET 7
  103. {
  104. char x_or_d;
  105. if (base == 16) {
  106. x_or_d = 'x';
  107. goto DO_X_OR_D;
  108. }
  109. if (base == 10) {
  110. x_or_d = 'd';
  111. DO_X_OR_D:
  112. dumper->fshead->nextfu->fmt[TYPE_OFFSET]
  113. = dumper->fshead->nextfs->nextfu->fmt[TYPE_OFFSET]
  114. = x_or_d;
  115. }
  116. }
  117. }
  118. }
  119. }
  120. static const char *const add_strings[] = {
  121. "16/1 \"%3_u \" \"\\n\"", /* a */
  122. "8/2 \" %06o \" \"\\n\"", /* B, o */
  123. "16/1 \"%03o \" \"\\n\"", /* b */
  124. "16/1 \"%3_c \" \"\\n\"", /* c */
  125. "8/2 \" %05u \" \"\\n\"", /* d */
  126. "4/4 \" %010u \" \"\\n\"", /* D */
  127. "2/8 \" %21.14e \" \"\\n\"", /* e (undocumented in od), F */
  128. "4/4 \" %14.7e \" \"\\n\"", /* f */
  129. "4/4 \" %08x \" \"\\n\"", /* H, X */
  130. "8/2 \" %04x \" \"\\n\"", /* h, x */
  131. "4/4 \" %11d \" \"\\n\"", /* I, L, l */
  132. "8/2 \" %6d \" \"\\n\"", /* i */
  133. "4/4 \" %011o \" \"\\n\"", /* O */
  134. };
  135. static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxv";
  136. static const char od_o2si[] ALIGN1 = {
  137. 0, 1, 2, 3, 5,
  138. 4, 6, 6, 7, 8,
  139. 9, 0xa, 0xb, 0xa, 0xa,
  140. 0xb, 1, 8, 9,
  141. };
  142. int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  143. int od_main(int argc, char **argv)
  144. {
  145. int ch;
  146. int first = 1;
  147. char *p;
  148. dumper_t *dumper = alloc_dumper();
  149. while ((ch = getopt(argc, argv, od_opts)) > 0) {
  150. if (ch == 'v') {
  151. dumper->dump_vflag = ALL;
  152. } else if (((p = strchr(od_opts, ch)) != NULL) && (*p != '\0')) {
  153. if (first) {
  154. first = 0;
  155. bb_dump_add(dumper, "\"%07.7_Ao\n\"");
  156. bb_dump_add(dumper, "\"%07.7_ao \"");
  157. } else {
  158. bb_dump_add(dumper, "\" \"");
  159. }
  160. bb_dump_add(dumper, 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 (!dumper->fshead) {
  166. bb_dump_add(dumper, "\"%07.7_Ao\n\"");
  167. bb_dump_add(dumper, "\"%07.7_ao \" 8/2 \"%06o \" \"\\n\"");
  168. }
  169. argc -= optind;
  170. argv += optind;
  171. odoffset(dumper, argc, &argv);
  172. return bb_dump_dump(dumper, 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. */