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