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#define FOR_xxd
35#include "toys.h"
36
37GLOBALS(
38 long s, g, o, l, c;
39)
40
41static void do_xxd(int fd, char *name)
42{
43 long long pos = 0;
44 long long limit = TT.l;
45 int i, len, space;
46
47 if (FLAG(s)) {
48 xlseek(fd, TT.s, SEEK_SET);
49 pos = TT.s;
50 if (limit) limit += TT.s;
51 }
52
53 while (0<(len = readall(fd, toybuf,
54 (limit && limit-pos<TT.c)?limit-pos:TT.c)))
55 {
56 if (!FLAG(p)) printf("%08llx: ", TT.o + pos);
57 pos += len;
58 space = 2*TT.c+(TT.c+TT.g-1)/TT.g+1;
59
60 for (i=0; i<len;) {
61 space -= printf("%02x", toybuf[i]);
62 if (!(++i%TT.g)) {
63 putchar(' ');
64 space--;
65 }
66 }
67
68 if (!FLAG(p)) {
69 printf("%*s", space, "");
70 for (i = 0; i<len; i++)
71 putchar((toybuf[i]>=' ' && toybuf[i]<='~') ? toybuf[i] : '.');
72 }
73 putchar('\n');
74 }
75 if (len<0) perror_exit("read");
76}
77
78static void do_xxd_include(int fd, char *name)
79{
80 int c = 1, i, len;
81
82
83
84 while ((len = read(fd, toybuf, sizeof(toybuf))) > 0) {
85 for (i = 0; i < len; ++i) {
86 printf("%s%#.02x", c > 1 ? ", " : " ", toybuf[i]);
87 if (c++ == TT.c) {
88 xprintf(",\n");
89 c = 1;
90 }
91 }
92 }
93 if (len < 0) perror_msg_raw(name);
94 if (c > 1) xputc('\n');
95}
96
97static int dehex(char ch)
98{
99 if (ch >= '0' && ch <= '9') return ch - '0';
100 if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
101 if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
102 return (ch == '\n') ? -2 : -1;
103}
104
105static void do_xxd_reverse(int fd, char *name)
106{
107 FILE *fp = xfdopen(xdup(fd), "r");
108 long long current_pos = 0;
109 int tmp;
110
111
112 if (FLAG(i)) while (fscanf(fp, " 0x%02x,", &tmp) == 1) xputc(tmp);
113 else while (!feof(fp)) {
114 int col = 0;
115
116
117
118 if (!FLAG(p)) {
119 long long pos;
120
121 if (fscanf(fp, "%llx: ", &pos) == 1) {
122 if (pos != current_pos && fseek(stdout, pos, SEEK_SET) != 0) {
123
124 perror_exit("%s: seek failed", name);
125 }
126 }
127 }
128
129
130
131
132 while (FLAG(p) || col < TT.c) {
133 int n1, n2;
134
135
136 if ((n1 = n2 = dehex(fgetc(fp))) < 0 || (n2 = dehex(fgetc(fp))) < 0) {
137
138 if (n1 == -2 || n2 == -2) continue;
139
140 break;
141 }
142
143 fputc((n1 << 4) | (n2 & 0xf), stdout);
144 col++;
145 current_pos++;
146
147
148 tmp = fgetc(fp);
149 if (tmp != ' ') ungetc(tmp, fp);
150 }
151
152
153 while ((tmp = fgetc(fp)) != EOF && tmp != '\n');
154 }
155
156 if (ferror(fp)) perror_msg_raw(name);
157 fclose(fp);
158}
159
160void xxd_main(void)
161{
162 if (!TT.c) TT.c = FLAG(i) ? 12 : 16;
163
164
165 if (FLAG(p)) TT.c = TT.g = 30;
166
167 loopfiles(toys.optargs,
168 FLAG(r) ? do_xxd_reverse : (FLAG(i) ? do_xxd_include : do_xxd));
169}
170