od.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * od implementation for busybox
  3. * Based on code from util-linux v 2.11l
  4. *
  5. * Copyright (c) 1990
  6. * The Regents of the University of California. All rights reserved.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. *
  22. * Original copyright notice is retained at the end of this file.
  23. */
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include <getopt.h>
  27. #include <stdlib.h>
  28. #include "busybox.h"
  29. #include "dump.h"
  30. #define isdecdigit(c) (isdigit)(c)
  31. #define ishexdigit(c) (isxdigit)(c)
  32. static void
  33. odoffset(int argc, char ***argvp)
  34. {
  35. register 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. || (!isdecdigit(p[0])
  58. && ((p[0] != 'x') || !ishexdigit(p[1])))))
  59. return;
  60. base = 0;
  61. /*
  62. * bb_dump_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' && ishexdigit(p[1])) {
  68. ++p;
  69. base = 16;
  70. } else if (p[0] == '0' && p[1] == 'x') {
  71. p += 2;
  72. base = 16;
  73. }
  74. /* bb_dump_skip over the number */
  75. if (base == 16)
  76. for (num = p; ishexdigit(*p); ++p);
  77. else
  78. for (num = p; isdecdigit(*p); ++p);
  79. /* check for no number */
  80. if (num == p)
  81. return;
  82. /* if terminates with a '.', base is decimal */
  83. if (*p == '.') {
  84. if (base)
  85. return;
  86. base = 10;
  87. }
  88. bb_dump_skip = strtol(num, &end, base ? base : 8);
  89. /* if end isn't the same as p, we got a non-octal digit */
  90. if (end != p)
  91. bb_dump_skip = 0;
  92. else {
  93. if (*p) {
  94. if (*p == 'b') {
  95. bb_dump_skip *= 512;
  96. ++p;
  97. } else if (*p == 'B') {
  98. bb_dump_skip *= 1024;
  99. ++p;
  100. }
  101. }
  102. if (*p)
  103. bb_dump_skip = 0;
  104. else {
  105. ++*argvp;
  106. /*
  107. * If the offset uses a non-octal base, the base of
  108. * the offset is changed as well. This isn't pretty,
  109. * but it's easy.
  110. */
  111. #define TYPE_OFFSET 7
  112. {
  113. char x_or_d;
  114. if (base == 16) {
  115. x_or_d = 'x';
  116. goto DO_X_OR_D;
  117. }
  118. if (base == 10) {
  119. x_or_d = 'd';
  120. DO_X_OR_D:
  121. bb_dump_fshead->nextfu->fmt[TYPE_OFFSET]
  122. = bb_dump_fshead->nextfs->nextfu->fmt[TYPE_OFFSET]
  123. = x_or_d;
  124. }
  125. }
  126. }
  127. }
  128. }
  129. static const char * const add_strings[] = {
  130. "16/1 \"%3_u \" \"\\n\"", /* a */
  131. "8/2 \" %06o \" \"\\n\"", /* B, o */
  132. "16/1 \"%03o \" \"\\n\"", /* b */
  133. "16/1 \"%3_c \" \"\\n\"", /* c */
  134. "8/2 \" %05u \" \"\\n\"", /* d */
  135. "4/4 \" %010u \" \"\\n\"", /* D */
  136. "2/8 \" %21.14e \" \"\\n\"", /* e (undocumented in od), F */
  137. "4/4 \" %14.7e \" \"\\n\"", /* f */
  138. "4/4 \" %08x \" \"\\n\"", /* H, X */
  139. "8/2 \" %04x \" \"\\n\"", /* h, x */
  140. "4/4 \" %11d \" \"\\n\"", /* I, L, l */
  141. "8/2 \" %6d \" \"\\n\"", /* i */
  142. "4/4 \" %011o \" \"\\n\"", /* O */
  143. };
  144. static const signed char od_opts[] = "aBbcDdeFfHhIiLlOoXxv";
  145. static const signed char od_o2si[] = {
  146. 0, 1, 2, 3, 5,
  147. 4, 6, 6, 7, 8,
  148. 9, 0xa, 0xb, 0xa, 0xa,
  149. 0xb, 1, 8, 9,
  150. };
  151. int od_main(int argc, char **argv)
  152. {
  153. int ch;
  154. int first = 1;
  155. signed char *p;
  156. bb_dump_vflag = FIRST;
  157. bb_dump_length = -1;
  158. while ((ch = getopt(argc, argv, od_opts)) > 0) {
  159. if (ch == 'v') {
  160. bb_dump_vflag = ALL;
  161. } else if (((p = strchr(od_opts, ch)) != NULL) && (*p >= 0)) {
  162. if (first) {
  163. first = 0;
  164. bb_dump_add("\"%07.7_Ao\n\"");
  165. bb_dump_add("\"%07.7_ao \"");
  166. } else {
  167. bb_dump_add("\" \"");
  168. }
  169. bb_dump_add(add_strings[od_o2si[(int)(p-od_opts)]]);
  170. } else { /* P, p, s, w, or other unhandled */
  171. bb_show_usage();
  172. }
  173. }
  174. if (!bb_dump_fshead) {
  175. bb_dump_add("\"%07.7_Ao\n\"");
  176. bb_dump_add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\"");
  177. }
  178. argc -= optind;
  179. argv += optind;
  180. odoffset(argc, &argv);
  181. return(bb_dump_dump(argv));
  182. }
  183. /*-
  184. * Copyright (c) 1990 The Regents of the University of California.
  185. * All rights reserved.
  186. *
  187. * Redistribution and use in source and binary forms, with or without
  188. * modification, are permitted provided that the following conditions
  189. * are met:
  190. * 1. Redistributions of source code must retain the above copyright
  191. * notice, this list of conditions and the following disclaimer.
  192. * 2. Redistributions in binary form must reproduce the above copyright
  193. * notice, this list of conditions and the following disclaimer in the
  194. * documentation and/or other materials provided with the distribution.
  195. * 3. Neither the name of the University nor the names of its contributors
  196. * may be used to endorse or promote products derived from this software
  197. * without specific prior written permission.
  198. *
  199. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  200. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  201. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  202. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  203. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  204. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  205. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  206. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  207. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  208. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  209. * SUCH DAMAGE.
  210. */