date and time created 83/08/05 13:35:06 by sam
[unix-history] / usr / src / old / od / od.c
CommitLineData
78d90aa3 1static char *sccsid = "@(#)od.c 5.11 (Berkeley) %G%";
3718e103
DW
2/*
3 * od -- octal, hex, decimal, character dump of data in a file.
4 *
bca5f88e 5 * usage: od [-abBcdDefFhHiIlLopPs[n]vw[n]xX] [file] [[+]offset[.][b] [label]]
3718e103
DW
6 *
7 * where the option flags have the following meaning:
8 * character object radix signed?
9 * a byte (10) (n.a.) ASCII named byte stream
10 * b byte 8 no byte octal
11 * c byte (8) (no) character with octal non-graphic bytes
12 * d short 10 no
13 * D long 10 no
14 * e,F double (10) double precision floating pt.
15 * f float (10) single precision floating pt.
16 * h,x short 16 no
17 * H,X long 16 no
18 * i short 10 yes
19 * I,l,L long 10 yes
0e88daf2 20 * o,B short 8 no (default conversion)
3718e103 21 * O long 8 no
bca5f88e 22 * s[n] string (8) ASCII graphic strings
3718e103
DW
23 *
24 * p indicate EVEN parity on 'a' conversion
25 * P indicate ODD parity on 'a' conversion
26 * v show all data - don't skip like lines.
bca5f88e 27 * w[n] bytes per display line
3718e103
DW
28 *
29 * More than one format character may be given.
30 * If {file} is not specified, standard input is read.
31 * If {file} is not specified, then {offset} must start with '+'.
bca5f88e
DW
32 * {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.).
33 * The default is octal. The same radix will be used to display the address.
3718e103
DW
34 */
35
36#include <stdio.h>
37
bca5f88e
DW
38#define DBUF_SIZE BUFSIZ
39#define BIG_DBUF 32
0e88daf2
DW
40#define NO 0
41#define YES 1
42#define EVEN -1
43#define ODD 1
44#define UNSIGNED 0
45#define SIGNED 1
46#define PADDR 1
47#define MIN_SLEN 3
3718e103
DW
48
49int a_put();
50int b_put();
51int c_put();
52int s_put();
53int us_put();
54int l_put();
55int f_put();
56int d_put();
0e88daf2 57int st_put();
3718e103
DW
58
59struct dfmt {
60 int df_field; /* external field required for object */
61 int df_size; /* size (bytes) of object */
62 int df_radix; /* conversion radix */
63 int df_signed; /* signed? flag */
0e88daf2 64 int df_paddr; /* "put address on each line?" flag */
3718e103 65 int (*df_put)(); /* function to output object */
0e88daf2 66 char *df_fmt; /* output string format */
3718e103
DW
67} *conv_vec[32]; /* vector of conversions to be done */
68
0e88daf2
DW
69struct dfmt ascii = { 3, sizeof (char), 10, 0, PADDR, a_put, 0};
70struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, PADDR, b_put, 0};
71struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, PADDR, c_put, 0};
72struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, PADDR, us_put, 0};
73struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, PADDR, us_put, 0};
74struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, PADDR, us_put, 0};
75struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, PADDR, l_put, 0};
76struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, PADDR, l_put, 0};
77struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, PADDR, l_put, 0};
78struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, PADDR, s_put, 0};
79struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, PADDR, l_put, 0};
80struct dfmt flt = {14, sizeof (float), 10, SIGNED, PADDR, f_put, 0};
81struct dfmt dble = {21, sizeof (double), 10, SIGNED, PADDR, d_put, 0};
82struct dfmt string = { 0, 0, 8, 0, NO, st_put, 0};
83
84
bca5f88e 85char usage[] ="usage: od [-abcdfhilopswvx] [file] [[+]offset[.][b] [label]]";
0e88daf2
DW
86char dbuf[DBUF_SIZE];
87char lastdbuf[DBUF_SIZE];
bca5f88e
DW
88int addr_base = 8; /* default address base is OCTAL */
89long addr = 0L; /* current file offset */
90long label = -1L; /* current label; -1 is "off" */
91int dbuf_size = 16; /* file bytes / display line */
92int _parity = NO; /* show parity on ascii bytes */
3718e103
DW
93char fmt[] = " %s"; /* 12 blanks */
94char *icvt();
0e88daf2 95char *scvt();
3718e103 96char *underline();
1fd5a2d4
DW
97long get_addr();
98
3718e103 99
0e88daf2
DW
100/*
101 * special form of _ctype
102 */
103
104#define A 01
105#define G 02
106#define D 04
107#define P 010
108#define X 020
109#define isdigit(c) (_ctype[c] & D)
110#define isascii(c) (_ctype[c] & A)
111#define isgraphic(c) (_ctype[c] & G)
112#define isprint(c) (_ctype[c] & P)
113#define ishex(c) (_ctype[c] & (X|D))
114
115char _ctype[256] = {
116/* 000 */ 0, 0, 0, 0, 0, 0, 0, 0,
117/* 010 */ A, A, A, 0, A, A, 0, 0,
118/* 020 */ 0, 0, 0, 0, 0, 0, 0, 0,
119/* 030 */ 0, 0, 0, 0, 0, 0, 0, 0,
120/* 040 */ P|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
121/* 050 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
122/* 060 */ P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,P|G|D|A,
123/* 070 */ P|G|D|A,P|G|D|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
124/* 100 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
125/* 110 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
126/* 120 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
127/* 130 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
128/* 140 */ P|G|A,X|P|G|A,X|P|G|A,X|P|G|A,X|P|G|A,X|P|G|A,X|P|G|A, P|G|A,
129/* 150 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
130/* 160 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A,
131/* 170 */ P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, P|G|A, 0,
132/* 200 */ 0, 0, 0, 0, 0, 0, 0, 0,
133/* 210 */ 0, 0, 0, 0, 0, 0, 0, 0,
134/* 220 */ 0, 0, 0, 0, 0, 0, 0, 0,
135/* 230 */ 0, 0, 0, 0, 0, 0, 0, 0,
136/* 240 */ 0, 0, 0, 0, 0, 0, 0, 0,
137/* 250 */ 0, 0, 0, 0, 0, 0, 0, 0,
138/* 260 */ 0, 0, 0, 0, 0, 0, 0, 0,
139/* 270 */ 0, 0, 0, 0, 0, 0, 0, 0,
140/* 300 */ 0, 0, 0, 0, 0, 0, 0, 0,
141/* 310 */ 0, 0, 0, 0, 0, 0, 0, 0,
142/* 320 */ 0, 0, 0, 0, 0, 0, 0, 0,
143/* 330 */ 0, 0, 0, 0, 0, 0, 0, 0,
144/* 340 */ 0, 0, 0, 0, 0, 0, 0, 0,
145/* 350 */ 0, 0, 0, 0, 0, 0, 0, 0,
146/* 360 */ 0, 0, 0, 0, 0, 0, 0, 0,
147/* 370 */ 0, 0, 0, 0, 0, 0, 0, 0,
148};
149
150
3718e103 151main(argc, argv)
0e88daf2
DW
152int argc;
153char **argv;
3718e103
DW
154{
155 register char *p;
156 register char *l;
157 register n, same;
158 struct dfmt *d;
159 struct dfmt **cv = conv_vec;
160 int showall = NO;
161 int field, llen, nelm;
162 int max_llen = 0;
163
164 argv++;
1fd5a2d4 165 argc--;
3718e103 166
0e88daf2
DW
167 if(argc > 0)
168 {
3718e103 169 p = *argv;
0e88daf2
DW
170 if(*p == '-')
171 {
172 while(*++p != '\0')
173 {
174 switch(*p)
175 {
3718e103
DW
176 case 'a':
177 d = &ascii;
178 break;
179 case 'b':
180 d = &byte;
181 break;
182 case 'c':
183 d = &cchar;
184 break;
185 case 'd':
186 d = &u_s_dec;
187 break;
188 case 'D':
189 d = &u_l_dec;
190 break;
191 case 'e':
192 case 'F':
193 d = &dble;
194 break;
195 case 'f':
196 d = &flt;
197 break;
198 case 'h':
199 case 'x':
200 d = &u_s_hex;
201 break;
202 case 'H':
203 case 'X':
204 d = &u_l_hex;
205 break;
206 case 'i':
207 d = &s_s_dec;
208 break;
209 case 'I':
210 case 'l':
211 case 'L':
212 d = &s_l_dec;
213 break;
214 case 'o':
0e88daf2 215 case 'B':
3718e103
DW
216 d = &u_s_oct;
217 break;
218 case 'O':
219 d = &u_l_oct;
220 break;
221 case 'p':
222 _parity = EVEN;
223 continue;
224 case 'P':
225 _parity = ODD;
226 continue;
0e88daf2
DW
227 case 's':
228 d = &string;
229 *(cv++) = d;
0e88daf2
DW
230 while (isdigit(p[1]))
231 d->df_size = (10 * d->df_size) + (*++p - '0');
232 if (d->df_size <= 0)
233 d->df_size = MIN_SLEN;
234 showall = YES;
235 continue;
bca5f88e
DW
236 case 'w':
237 dbuf_size = 0;
238 while (isdigit(p[1]))
239 dbuf_size = (10 * dbuf_size) + (*++p - '0');
240 if (dbuf_size == 0)
241 dbuf_size = BIG_DBUF;
242 continue;
3718e103
DW
243 case 'v':
244 showall = YES;
245 continue;
1fd5a2d4
DW
246 default:
247 printf("od: bad flag -%c\n", *p);
248 puts(usage);
249 exit(1);
3718e103 250 }
3718e103
DW
251 *(cv++) = d;
252 }
253 argc--;
254 argv++;
255 }
256 }
257
0e88daf2
DW
258 /*
259 * if nothing spec'd, setup default conversion.
260 */
261 if(cv == conv_vec)
3718e103 262 *(cv++) = &u_s_oct;
bca5f88e 263
3718e103
DW
264 *cv = (struct dfmt *)0;
265
bca5f88e
DW
266 /*
267 * calculate display parameters
268 */
269 for (cv = conv_vec; d = *cv; cv++)
270 {
271 nelm = (dbuf_size + d->df_size - 1) / d->df_size;
272 llen = nelm * (d->df_field + 1);
273 if (llen > max_llen)
274 max_llen = llen;
275 }
276
0e88daf2
DW
277 /*
278 * setup df_fmt to point to uniform output fields.
279 */
bca5f88e 280 for (cv = conv_vec; d = *cv; cv++)
0e88daf2
DW
281 {
282 if (d->df_field) /* only if external field is known */
283 {
bca5f88e 284 nelm = (dbuf_size + d->df_size - 1) / d->df_size;
0e88daf2
DW
285 field = max_llen / nelm;
286 d->df_fmt = fmt + 12 - (field - d->df_field);
287 }
3718e103
DW
288 }
289
0e88daf2
DW
290 /*
291 * input file specified ?
292 */
293 if(argc > 0 && **argv != '+')
294 {
295 if (freopen(*argv, "r", stdin) == NULL)
296 {
78d90aa3 297 perror(*argv);
3718e103
DW
298 exit(1);
299 }
300 argv++;
301 argc--;
302 }
303
0e88daf2
DW
304 /*
305 * check for possible offset [label]
306 */
1fd5a2d4
DW
307 if (argc > 0)
308 {
309 addr = get_addr(*argv);
310 offset(addr);
311 argv++;
312 argc--;
313
314 if (argc > 0)
315 label = get_addr(*argv);
316 }
3718e103 317
0e88daf2
DW
318 /*
319 * main dump loop
320 */
3718e103 321 same = -1;
bca5f88e 322 while ((n = fread(dbuf, 1, dbuf_size, stdin)) > 0)
0e88daf2 323 {
bca5f88e 324 if (same>=0 && bufncmp(dbuf, lastdbuf, dbuf_size) == 0 && !showall)
0e88daf2
DW
325 {
326 if (same==0)
327 {
3718e103
DW
328 printf("*\n");
329 same = 1;
330 }
331 }
0e88daf2
DW
332 else
333 {
3718e103
DW
334 line(n);
335 same = 0;
336 p = dbuf;
337 l = lastdbuf;
bca5f88e 338 for (nelm = 0; nelm < dbuf_size; nelm++)
0e88daf2 339 {
3718e103
DW
340 *l++ = *p;
341 *p++ = '\0';
342 }
343 }
344 addr += n;
1fd5a2d4
DW
345 if (label >= 0)
346 label += n;
3718e103 347 }
0e88daf2
DW
348
349 /*
350 * Some conversions require "flushing".
351 */
352 n = 0;
353 for (cv = conv_vec; *cv; cv++)
354 {
355 if ((*cv)->df_paddr)
356 {
357 if (n++ == 0)
358 put_addr(addr, label, '\n');
359 }
360 else
361 (*((*cv)->df_put))(0, *cv);
362 }
1fd5a2d4
DW
363}
364
0e88daf2
DW
365put_addr(a, l, c)
366long a;
367long l;
1fd5a2d4
DW
368char c;
369{
0e88daf2
DW
370 fputs(icvt(a, addr_base, UNSIGNED, 7), stdout);
371 if (l >= 0)
372 printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7));
1fd5a2d4 373 putchar(c);
3718e103
DW
374}
375
376line(n)
377int n;
378{
379 register i, first;
380 register struct dfmt *c;
381 register struct dfmt **cv = conv_vec;
382
383 first = YES;
0e88daf2
DW
384 while (c = *cv++)
385 {
386 if (c->df_paddr)
387 {
388 if (first)
389 {
390 put_addr(addr, label, ' ');
391 first = NO;
392 }
393 else
394 {
395 putchar('\t');
396 if (label >= 0)
397 fputs("\t ", stdout);
398 }
1fd5a2d4 399 }
3718e103
DW
400 i = 0;
401 while (i < n)
402 i += (*(c->df_put))(dbuf+i, c);
0e88daf2
DW
403 if (c->df_paddr)
404 putchar('\n');
3718e103
DW
405 }
406}
407
408s_put(n, d)
409short *n;
410struct dfmt *d;
411{
412 printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
413 return(d->df_size);
414}
415
416us_put(n, d)
417unsigned short *n;
418struct dfmt *d;
419{
420 printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
421 return(d->df_size);
422}
423
424l_put(n, d)
425long *n;
426struct dfmt *d;
427{
428 printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field));
429 return(d->df_size);
430}
431
432d_put(f, d)
433double *f;
434struct dfmt *d;
435{
436 char fbuf[24];
d13b8628
DW
437 struct l { long n[2]; };
438
439#if vax
440 if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */
441 sprintf(fbuf, " %08x %08x",
442 ((struct l *)f)->n[0], ((struct l *)f)->n[1]);
443 else
444#endif
445
446 sprintf(fbuf, "%21.14e", *f);
3718e103
DW
447 printf(d->df_fmt, fbuf);
448 return(d->df_size);
449}
450
451f_put(f, d)
452float *f;
453struct dfmt *d;
454{
455 char fbuf[16];
d13b8628
DW
456
457#if vax
458 if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */
459 sprintf(fbuf, " %08x", *(long *)f);
460 else
461#endif
462 sprintf(fbuf, "%14.7e", *f);
3718e103
DW
463 printf(d->df_fmt, fbuf);
464 return(d->df_size);
465}
466
467
468char asc_name[34][4] = {
0e88daf2
DW
469/* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
470/* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
471/* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
472/* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
473/* 040 */ " sp", "del"
3718e103
DW
474};
475
476a_put(cc, d)
477char *cc;
478struct dfmt *d;
479{
480 int c = *cc;
481 register char *s = " ";
482 register pbit = parity((int)c & 0377);
483
484 c &= 0177;
0e88daf2 485 if (isgraphic(c))
3718e103 486 {
0e88daf2 487 s[2] = c;
3718e103 488 if (pbit == _parity)
d2b19b28 489 printf(d->df_fmt, underline(s));
3718e103
DW
490 else
491 printf(d->df_fmt, s);
492 }
493 else
494 {
495 if (c == 0177)
496 c = ' ' + 1;
497 if (pbit == _parity)
d2b19b28 498 printf(d->df_fmt, underline(asc_name[c]));
3718e103
DW
499 else
500 printf(d->df_fmt, asc_name[c]);
501 }
502 return(1);
503}
504
505parity(word)
506int word;
507{
508 register int p = 0;
509 register int w = word;
510
511 if (w)
0e88daf2
DW
512 do
513 {
3718e103
DW
514 p ^= 1;
515 } while(w &= (~(-w)));
516 return (p? ODD:EVEN);
517}
518
519char *
d2b19b28 520underline(s)
3718e103 521char *s;
3718e103
DW
522{
523 static char ulbuf[16];
524 register char *u = ulbuf;
525
0e88daf2
DW
526 while (*s)
527 {
528 if (*s != ' ')
529 {
3718e103
DW
530 *u++ = '_';
531 *u++ = '\b';
532 }
533 *u++ = *s++;
534 }
535 *u = '\0';
536 return(ulbuf);
537}
538
539b_put(b, d)
540char *b;
541struct dfmt *d;
542{
543 printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field));
544 return(1);
545}
546
547c_put(cc, d)
548char *cc;
549struct dfmt *d;
550{
0e88daf2
DW
551 register char *s;
552 register int n;
553 register int c = *cc & 0377;
554
555 s = scvt(c, d);
556 for (n = d->df_field - strlen(s); n > 0; n--)
557 putchar(' ');
558 printf(d->df_fmt, s);
559 return(1);
560}
561
562char *scvt(c, d)
563int c;
564struct dfmt *d;
565{
566 static char s[2];
567
568 switch(c)
569 {
570 case '\0':
571 return("\\0");
572
573 case '\b':
574 return("\\b");
3718e103 575
0e88daf2
DW
576 case '\f':
577 return("\\f");
578
579 case '\n':
580 return("\\n");
581
582 case '\r':
583 return("\\r");
584
585 case '\t':
586 return("\\t");
587
588 default:
589 if (isprint(c))
590 {
591 s[0] = c;
592 return(s);
593 }
594 return(icvt((long)c, d->df_radix, d->df_signed, d->df_field));
3718e103 595 }
0e88daf2 596}
3718e103 597
0e88daf2
DW
598/*
599 * Look for strings.
600 * A string contains bytes > 037 && < 177, and ends with a null.
601 * The minimum length is given in the dfmt structure.
602 */
603
604#define CNULL '\0'
605#define S_EMPTY 0
606#define S_FILL 1
607#define S_CONT 2
608#define SBUFSIZE 1024
609
610static char str_buf[SBUFSIZE];
611static int str_mode = S_EMPTY;
612static char *str_ptr;
613static long str_addr;
614static long str_label;
615
67e162d0
DW
616st_put(cc, d)
617char *cc;
0e88daf2
DW
618struct dfmt *d;
619{
67e162d0
DW
620 register int c;
621
622 if (cc == 0)
0e88daf2
DW
623 {
624 pr_sbuf(d, YES);
67e162d0 625 return(1);
3718e103 626 }
67e162d0
DW
627
628 c = (*cc & 0377);
629
630 if (str_mode & S_FILL)
0e88daf2 631 {
67e162d0
DW
632 if (isascii(c))
633 put_sbuf(c, d);
0e88daf2
DW
634 else
635 {
636 *str_ptr = CNULL;
67e162d0 637 if (c == NULL)
0e88daf2
DW
638 pr_sbuf(d, YES);
639 str_mode = S_EMPTY;
640 }
641 }
67e162d0 642 else if (isascii(c))
0e88daf2
DW
643 {
644 str_mode = S_FILL;
67e162d0 645 str_addr = addr + (cc - dbuf); /* ugly */
0e88daf2 646 if ((str_label = label) >= 0)
67e162d0 647 str_label += (cc - dbuf); /* '' */
0e88daf2 648 str_ptr = str_buf;
67e162d0 649 put_sbuf(c, d);
0e88daf2
DW
650 }
651
3718e103
DW
652 return(1);
653}
654
0e88daf2 655put_sbuf(c, d)
67e162d0 656int c;
0e88daf2
DW
657struct dfmt *d;
658{
659 *str_ptr++ = c;
660 if (str_ptr >= (str_buf + SBUFSIZE))
661 {
662 pr_sbuf(d, NO);
663 str_ptr = str_buf;
664 str_mode |= S_CONT;
665 }
666}
667
668pr_sbuf(d, end)
669struct dfmt *d;
670int end;
671{
672 register char *p = str_buf;
673
674 if (str_mode == S_EMPTY
675 || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size))
676 return;
677
678 if (!(str_mode & S_CONT))
679 put_addr(str_addr, str_label, ' ');
680
681 while (p < str_ptr)
682 fputs(scvt(*p++, d), stdout);
683
684 if (end)
685 putchar('\n');
686}
687
3718e103
DW
688/*
689 * integer to ascii conversion
690 *
691 * This code has been rearranged to produce optimized runtime code.
692 */
693
694#define MAXINTLENGTH 32
695static char _digit[] = "0123456789abcdef";
696static char _icv_buf[MAXINTLENGTH+1];
697static long _mask = 0x7fffffff;
698
699char *
700icvt (value, radix, signed, ndigits)
701long value;
702int radix;
703int signed;
704int ndigits;
705{
706 register long val = value;
707 register long rad = radix;
708 register char *b = &_icv_buf[MAXINTLENGTH];
709 register char *d = _digit;
710 register long tmp1;
711 register long tmp2;
712 long rem;
713 long kludge;
714 int sign;
715
716 if (val == 0)
717 {
718 *--b = '0';
719 sign = 0;
720 goto done; /*return(b);*/
721 }
722
723 if (signed && (sign = (val < 0))) /* signed conversion */
724 {
725 /*
726 * It is necessary to do the first divide
727 * before the absolute value, for the case -2^31
728 *
729 * This is actually what is being done...
730 * tmp1 = (int)(val % rad);
731 * val /= rad;
732 * val = -val
733 * *--b = d[-tmp1];
734 */
735 tmp1 = val / rad;
736 *--b = d[(tmp1 * rad) - val];
737 val = -tmp1;
738 }
739 else /* unsigned conversion */
740 {
741 sign = 0;
742 if (val < 0)
743 { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
744 kludge = _mask - (rad - 1);
745 val &= _mask;
746 /*
747 * This is really what's being done...
748 * rem = (kludge % rad) + (val % rad);
749 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
750 * *--b = d[rem % rad];
751 */
752 tmp1 = kludge / rad;
753 tmp2 = val / rad;
754 rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
755 val = ++tmp1 + tmp2;
756 tmp1 = rem / rad;
757 val += tmp1;
758 *--b = d[rem - (tmp1 * rad)];
759 }
760 }
761
762 while (val)
763 {
764 /*
765 * This is really what's being done ...
766 * *--b = d[val % rad];
767 * val /= rad;
768 */
769 tmp1 = val / rad;
770 *--b = d[val - (tmp1 * rad)];
771 val = tmp1;
772 }
773
774done:
775 if (sign)
776 *--b = '-';
777
778 tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b);
779 tmp2 = signed? ' ':'0';
780 while (tmp1 > 0)
781 {
782 *--b = tmp2;
783 tmp1--;
784 }
785
786 return(b);
787}
788
0e88daf2 789long get_addr(s)
3718e103
DW
790register char *s;
791{
792 register char *p;
1fd5a2d4 793 register long a;
3718e103
DW
794 register int d;
795
796 if (*s=='+')
797 s++;
0e88daf2
DW
798 if (*s=='x')
799 {
3718e103
DW
800 s++;
801 addr_base = 16;
0e88daf2
DW
802 }
803 else if (*s=='0' && s[1]=='x')
804 {
3718e103
DW
805 s += 2;
806 addr_base = 16;
0e88daf2
DW
807 }
808 else if (*s == '0')
3718e103
DW
809 addr_base = 8;
810 p = s;
0e88daf2
DW
811 while(*p)
812 {
3718e103
DW
813 if (*p++=='.')
814 addr_base = 10;
815 }
0e88daf2
DW
816 for (a=0; *s; s++)
817 {
3718e103 818 d = *s;
0e88daf2 819 if(isdigit(d))
3718e103 820 a = a*addr_base + d - '0';
0e88daf2 821 else if (ishex(d) && addr_base==16)
3718e103
DW
822 a = a*addr_base + d + 10 - 'a';
823 else
824 break;
825 }
1fd5a2d4 826
3718e103
DW
827 if (*s == '.')
828 s++;
1fd5a2d4 829 if(*s=='b')
3718e103 830 a *= 512;
1fd5a2d4
DW
831 if(*s=='B')
832 a *= 1024;
833
834 return(a);
835}
836
7f1bc61f
DW
837bufncmp(a, b, n)
838char *a;
839char *b;
840int n;
841{
842 while (n--)
843 if (*a++ != *b++)
844 return(1);
845}
846
1fd5a2d4
DW
847offset(a)
848long a;
849{
3718e103 850 if (canseek(stdin))
1c2b767a
DW
851 {
852 /*
853 * in case we're accessing a raw disk,
854 * we have to seek in multiples of a physical block.
855 */
856 fseek(stdin, a & 0xfffffe00L, 0);
857 a &= 0x1ffL;
858 }
859 dumbseek(stdin, a);
3718e103
DW
860}
861
862dumbseek(s, offset)
863FILE *s;
864long offset;
865{
866 char buf[BUFSIZ];
867 int n;
868 int nr;
869
870 while (offset > 0)
871 {
872 nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset;
873 if ((n = fread(buf, 1, nr, s)) != nr)
874 {
875 fprintf(stderr, "EOF\n");
876 exit(1);
877 }
878 offset -= n;
879 }
880}
881
882#include <sys/types.h>
883#include <sys/stat.h>
884
885canseek(f)
886FILE *f;
887{
888 struct stat statb;
889
890 return( (fstat(fileno(f),&statb)==0) &&
891 (statb.st_nlink > 0) && /*!pipe*/
892 (!isatty(fileno(f))) );
893}