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