1 /* od - octal dump Author: Andy Tanenbaum */
10 int bflag
, cflag
, dflag
, oflag
, xflag
, hflag
, vflag
;
11 int linenr
, width
, state
, ever
;
14 char buf
[512], buffer
[BUFSIZ
];
18 int main(int argc
, char **argv
);
19 long offset(int argc
, char *argv
[], int k
);
21 void wdump(short *words
, int k
, int radix
);
22 void bdump(char bytes
[16 ], int k
, int c
);
23 void byte(int val
, int c
);
24 int getwords(short **words
);
25 int same(short *w1
, int *w2
);
26 void outword(int val
, int radix
);
27 void outnum(int num
, int radix
);
40 setbuf(stdout
, buffer
);
43 if (argc
> 1 && *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;
63 if ((bflag
| cflag
| dflag
| oflag
| xflag
) == 0) oflag
= 1;
75 /* Process file name, if any. */
77 if (k
< argc
&& *p
!= '+') {
78 /* Explicit file name given. */
80 if (open(argv
[k
], O_RDONLY
) != 0) {
81 fprintf(stderr
, "od: cannot open %s\n", argv
[k
]);
87 /* Process offset, if any. */
90 off
= offset(argc
, argv
, k
);
91 off
= (off
/ 16L) * 16L;
92 lseek(0, off
, SEEK_SET
);
101 long offset(argc
, argv
, k
)
110 /* See if the offset is decimal. */
114 if (*p
++ == '.') dot
= 1;
116 /* Convert offset to binary. */
117 radix
= (dot
? 10 : 8);
121 while (*p
!= 0 && *p
!= '.') {
123 if (c
< '0' || c
> '9') {
124 printf("Bad character in offset: %c\n", c
);
127 val
= radix
* val
+ c
- '0';
131 if (k
+ 1 == argc
- 1 && *p
== 'b') val
= 512L * val
;
141 while ((k
= getwords(&words
))) { /* 'k' is # bytes read */
142 if (!vflag
) { /* ensure 'lazy' evaluation */
143 if (k
== 16 && ever
== 1 && same(words
, prevwds
)) {
149 } else if (state
== 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;
171 void wdump(words
, k
, radix
)
177 if (linenr
++ != 1) printf(" ");
178 for (i
= 0; i
< (k
+ 1) / 2; i
++) outword(words
[i
] & 0xFFFF, radix
);
183 void bdump(bytes
, k
, c
)
190 if (linenr
++ != 1) printf(" ");
191 for (i
= 0; i
< k
; i
++) byte(bytes
[i
] & 0377, c
);
206 else if (val
== '\b')
208 else if (val
== '\f')
210 else if (val
== '\n')
212 else if (val
== '\r')
214 else if (val
== '\t')
216 else if (val
>= ' ' && val
< 0177)
230 if (next
>= bytespresent
) {
231 bytespresent
= read(0, buf
, 512);
234 if (next
>= bytespresent
) return(0);
235 *words
= (short *) &buf
[next
];
236 if (next
+ 16 <= bytespresent
)
239 count
= bytespresent
- next
;
252 if (*w1
++ != *w2
++) return(0);
256 void outword(val
, radix
)
259 /* Output 'val' in 'radix' in a field of total size 'width'. */
263 if (radix
== 16) i
= width
- 4;
264 if (radix
== 10) i
= width
- 5;
265 if (radix
== 8) i
= width
- 6;
278 void outnum(num
, radix
)
281 /* Output a number with all leading 0s present. Octal is 6 places,
282 * decimal is 5 places, hex is 4 places.
286 val
= (unsigned) num
;
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) {
295 printf ("%03o", val
);
313 fprintf(stderr
, "Usage: od [-bcdhovx] [file] [ [+] offset [.] [b] ]\n");