source: trunk/minix/commands/simple/od.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 5.5 KB
Line 
1/* od - octal dump Author: Andy Tanenbaum */
2
3#include <sys/types.h>
4#include <fcntl.h>
5#include <unistd.h>
6#include <stdlib.h>
7#include <stdio.h>
8
9
10int bflag, cflag, dflag, oflag, xflag, hflag, vflag;
11int linenr, width, state, ever;
12int prevwds[8];
13long off;
14char buf[512], buffer[BUFSIZ];
15int next;
16int bytespresent;
17
18_PROTOTYPE(int main, (int argc, char **argv));
19_PROTOTYPE(long offset, (int argc, char *argv [], int k));
20_PROTOTYPE(void dumpfile, (void));
21_PROTOTYPE(void wdump, (short *words, int k, int radix));
22_PROTOTYPE(void bdump, (char bytes [16 ], int k, int c));
23_PROTOTYPE(void byte, (int val, int c));
24_PROTOTYPE(int getwords, (short **words));
25_PROTOTYPE(int same, (short *w1, int *w2));
26_PROTOTYPE(void outword, (int val, int radix));
27_PROTOTYPE(void outnum, (int num, int radix));
28_PROTOTYPE(void addrout, (long l));
29_PROTOTYPE(char hexit, (int k));
30_PROTOTYPE(void usage, (void));
31
32int main(argc, argv)
33int argc;
34char *argv[];
35{
36 int k, flags;
37 char *p;
38
39 /* Process flags */
40 setbuf(stdout, buffer);
41 flags = 0;
42 p = argv[1];
43 if (argc > 1 && *p == '-') {
44 /* Flags present. */
45 flags++;
46 p++;
47 while (*p) {
48 switch (*p) {
49 case 'b': bflag++; break;
50 case 'c': cflag++; break;
51 case 'd': dflag++; break;
52 case 'h': hflag++; break;
53 case 'o': oflag++; break;
54 case 'v': vflag++; break;
55 case 'x': xflag++; break;
56 default: usage();
57 }
58 p++;
59 }
60 } else {
61 oflag = 1;
62 }
63 if ((bflag | cflag | dflag | oflag | xflag) == 0) oflag = 1;
64 k = (flags ? 2 : 1);
65 if (bflag | cflag) {
66 width = 8;
67 } else if (oflag) {
68 width = 7;
69 } else if (dflag) {
70 width = 6;
71 } else {
72 width = 5;
73 }
74
75 /* Process file name, if any. */
76 p = argv[k];
77 if (k < argc && *p != '+') {
78 /* Explicit file name given. */
79 close(0);
80 if (open(argv[k], O_RDONLY) != 0) {
81 fprintf(stderr, "od: cannot open %s\n", argv[k]);
82 exit(1);
83 }
84 k++;
85 }
86
87 /* Process offset, if any. */
88 if (k < argc) {
89 /* Offset present. */
90 off = offset(argc, argv, k);
91 off = (off / 16L) * 16L;
92 lseek(0, off, SEEK_SET);
93 }
94 dumpfile();
95 addrout(off);
96 printf("\n");
97 return(0);
98}
99
100
101long offset(argc, argv, k)
102int argc;
103char *argv[];
104int k;
105{
106 int dot, radix;
107 char *p, c;
108 long val;
109
110 /* See if the offset is decimal. */
111 dot = 0;
112 p = argv[k];
113 while (*p)
114 if (*p++ == '.') dot = 1;
115
116 /* Convert offset to binary. */
117 radix = (dot ? 10 : 8);
118 val = 0;
119 p = argv[k];
120 if (*p == '+') p++;
121 while (*p != 0 && *p != '.') {
122 c = *p++;
123 if (c < '0' || c > '9') {
124 printf("Bad character in offset: %c\n", c);
125 exit(1);
126 }
127 val = radix * val + c - '0';
128 }
129
130 p = argv[k + 1];
131 if (k + 1 == argc - 1 && *p == 'b') val = 512L * val;
132 return(val);
133}
134
135
136void dumpfile()
137{
138 int k;
139 short *words;
140
141 while ((k = getwords(&words))) { /* 'k' is # bytes read */
142 if (!vflag) { /* ensure 'lazy' evaluation */
143 if (k == 16 && ever == 1 && same(words, prevwds)) {
144 if (state == 0) {
145 printf("*\n");
146 state = 1;
147 off += 16;
148 continue;
149 } else if (state == 1) {
150 off += 16;
151 continue;
152 }
153 }
154 }
155 addrout(off);
156 off += k;
157 state = 0;
158 ever = 1;
159 linenr = 1;
160 if (oflag) wdump(words, k, 8);
161 if (dflag) wdump(words, k, 10);
162 if (xflag) wdump(words, k, 16);
163 if (cflag) bdump((char *)words, k, (int)'c');
164 if (bflag) bdump((char *)words, k, (int)'b');
165 for (k = 0; k < 8; k++) prevwds[k] = words[k];
166 for (k = 0; k < 8; k++) words[k] = 0;
167 }
168}
169
170
171void wdump(words, k, radix)
172short *words;
173int k, radix;
174{
175 int i;
176
177 if (linenr++ != 1) printf(" ");
178 for (i = 0; i < (k + 1) / 2; i++) outword(words[i] & 0xFFFF, radix);
179 printf("\n");
180}
181
182
183void bdump(bytes, k, c)
184char bytes[16];
185int k;
186char c;
187{
188 int i;
189
190 if (linenr++ != 1) printf(" ");
191 for (i = 0; i < k; i++) byte(bytes[i] & 0377, c);
192 printf("\n");
193}
194
195void byte(val, c)
196int val;
197char c;
198{
199 if (c == 'b') {
200 printf(" ");
201 outnum(val, 7);
202 return;
203 }
204 if (val == 0)
205 printf(" \\0");
206 else if (val == '\b')
207 printf(" \\b");
208 else if (val == '\f')
209 printf(" \\f");
210 else if (val == '\n')
211 printf(" \\n");
212 else if (val == '\r')
213 printf(" \\r");
214 else if (val == '\t')
215 printf(" \\t");
216 else if (val >= ' ' && val < 0177)
217 printf(" %c", val);
218 else {
219 printf(" ");
220 outnum(val, 7);
221 }
222}
223
224
225int getwords(words)
226short **words;
227{
228 int count;
229
230 if (next >= bytespresent) {
231 bytespresent = read(0, buf, 512);
232 next = 0;
233 }
234 if (next >= bytespresent) return(0);
235 *words = (short *) &buf[next];
236 if (next + 16 <= bytespresent)
237 count = 16;
238 else
239 count = bytespresent - next;
240
241 next += count;
242 return(count);
243}
244
245int same(w1, w2)
246short *w1;
247int *w2;
248{
249 int i;
250 i = 8;
251 while (i--)
252 if (*w1++ != *w2++) return(0);
253 return(1);
254}
255
256void outword(val, radix)
257int val, radix;
258{
259/* Output 'val' in 'radix' in a field of total size 'width'. */
260
261 int i;
262
263 if (radix == 16) i = width - 4;
264 if (radix == 10) i = width - 5;
265 if (radix == 8) i = width - 6;
266 if (i == 1)
267 printf(" ");
268 else if (i == 2)
269 printf(" ");
270 else if (i == 3)
271 printf(" ");
272 else if (i == 4)
273 printf(" ");
274 outnum(val, radix);
275}
276
277
278void outnum(num, radix)
279int num, radix;
280{
281/* Output a number with all leading 0s present. Octal is 6 places,
282 * decimal is 5 places, hex is 4 places.
283 */
284 unsigned val;
285
286 val = (unsigned) num;
287 if (radix == 8)
288 printf ("%06o", val);
289 else if (radix == 10)
290 printf ("%05u", val);
291 else if (radix == 16)
292 printf ("%04x", val);
293 else if (radix == 7) {
294 /* special case */
295 printf ("%03o", val);
296 }
297}
298
299
300void addrout(l)
301long l;
302{
303 if (hflag == 0) {
304 printf("%07lo", l);
305 } else {
306 printf("%07lx", l);
307 }
308}
309
310
311void usage()
312{
313 fprintf(stderr, "Usage: od [-bcdhovx] [file] [ [+] offset [.] [b] ]\n");
314}
Note: See TracBrowser for help on using the repository browser.