1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#define FOR_hexdump
39#include "toys.h"
40
41GLOBALS(
42 long s, n;
43
44 long long len, pos, ppos;
45 const char *fmt;
46 unsigned int fn, bc;
47 char linebuf[16];
48
49
50)
51
52const char *make_printable(unsigned char byte) {
53 switch (byte) {
54 case '\0': return "\\0";
55 case '\a': return "\\a";
56 case '\b': return "\\b";
57 case '\t': return "\\t";
58 case '\n': return "\\n";
59 case '\v': return "\\v";
60 case '\f': return "\\f";
61 default: return "??";
62 }
63}
64
65void do_hexdump(int fd, char *name)
66{
67 unsigned short block, adv, i;
68 int sl, fs;
69
70 TT.fn++;
71
72 if (FLAG(s) && (TT.s-TT.pos>0)) {
73 fs = xlseek(fd, 0L, SEEK_END);
74
75 if (fs < TT.s) {
76 TT.pos += fs;
77 TT.ppos += fs;
78 } else {
79 xlseek(fd, TT.s-TT.pos, SEEK_SET);
80 TT.ppos = TT.s;
81 TT.pos = TT.s;
82 }
83 }
84
85 for (sl = 0;
86 0 < (TT.len = readall(fd, toybuf,
87 (TT.n && TT.s+TT.n-TT.pos<16-(TT.bc%16))
88 ? TT.s+TT.n-TT.pos : 16-(TT.bc%16)));
89 TT.pos += TT.len) {
90
91
92
93
94 for (i = 0; i < 16 && i < TT.len; i++){
95 if (FLAG(v) || TT.len < 16 || toybuf[i] != TT.linebuf[i]) goto newline;
96 }
97 if (sl == 0) {
98 printf("*\n");
99 sl = 1;
100 }
101 TT.ppos += TT.len;
102 continue;
103
104newline:
105 strncpy(TT.linebuf+(TT.bc%16), toybuf, TT.len);
106 TT.bc = TT.bc % 16 + TT.len;
107 sl = 0;
108 if (TT.pos + TT.bc == TT.s+TT.n || TT.fn == toys.optc || TT.bc == 16) {
109 if (!FLAG(C) && !FLAG(c)) {
110 printf("%07llx", TT.ppos);
111 adv = FLAG(b) ? 1 : 2;
112 for (i = 0; i < TT.bc; i += adv) {
113 block = (FLAG(b) || i == TT.bc-1)
114 ? TT.linebuf[i] : (TT.linebuf[i] | TT.linebuf[i+1] << 8);
115 printf(TT.fmt, block);
116 }
117 } else if (FLAG(C)) {
118 printf("%08llx", TT.ppos);
119 for (i = 0; i < 16; i++) {
120 if (!(i % 8)) putchar(' ');
121 if (i < TT.bc) printf(" %02x", TT.linebuf[i]);
122 else printf(" ");
123 }
124 printf(" |");
125 for (i = 0; i < TT.bc; i++) {
126 if (TT.linebuf[i] < ' ' || TT.linebuf[i] > '~') putchar('.');
127 else putchar(TT.linebuf[i]);
128 }
129 putchar('|');
130 } else {
131 printf("%07llx", TT.ppos);
132 for (i = 0; i < TT.bc; i++) {
133 if (TT.linebuf[i] >= ' ' && TT.linebuf[i] <= '~')
134 printf("%4c", TT.linebuf[i]);
135 else printf("%4s", make_printable(TT.linebuf[i]));
136 }
137 }
138 putchar('\n');
139 TT.ppos += TT.bc;
140 }
141 }
142
143 if (TT.len < 0) perror_exit("read");
144}
145
146void hexdump_main(void)
147{
148 if FLAG(b) TT.fmt = " %03o";
149 else if FLAG(d) TT.fmt = " %05d";
150 else if FLAG(o) TT.fmt = " %06o";
151 else TT.fmt = " %04x";
152
153 loopfiles(toys.optargs, do_hexdump);
154 FLAG(C) ? printf("%08llx\n", TT.pos) : printf("%07llx\n", TT.pos);
155}
156