|
|
1.1 root 1: static char *sccsid = "@(#)od.c 5.15 (Berkeley) 12/21/87";
2: /*
3: * od -- octal, hex, decimal, character dump of data in a file.
4: *
5: * usage: od [-abBcdDefFhHiIlLopPs[n]vw[n]xX] [file] [[+]offset[.][b] [label]]
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
20: * o,B short 8 no (default conversion)
21: * O long 8 no
22: * s[n] string (8) ASCII graphic strings
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.
27: * w[n] bytes per display line
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 '+'.
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.
34: */
35:
36: #include <stdio.h>
37:
38: #define DBUF_SIZE BUFSIZ
39: #define BIG_DBUF 32
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
48:
49: int a_put();
50: int b_put();
51: int c_put();
52: int s_put();
53: int us_put();
54: int l_put();
55: int f_put();
56: int d_put();
57: int st_put();
58:
59: struct 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 */
64: int df_paddr; /* "put address on each line?" flag */
65: int (*df_put)(); /* function to output object */
66: char *df_fmt; /* output string format */
67: } *conv_vec[32]; /* vector of conversions to be done */
68:
69: struct dfmt ascii = { 3, sizeof (char), 10, 0, PADDR, a_put, 0};
70: struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, PADDR, b_put, 0};
71: struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, PADDR, c_put, 0};
72: struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, PADDR, us_put, 0};
73: struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, PADDR, us_put, 0};
74: struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, PADDR, us_put, 0};
75: struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, PADDR, l_put, 0};
76: struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, PADDR, l_put, 0};
77: struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, PADDR, l_put, 0};
78: struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, PADDR, s_put, 0};
79: struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, PADDR, l_put, 0};
80: struct dfmt flt = {14, sizeof (float), 10, SIGNED, PADDR, f_put, 0};
81: struct dfmt dble = {21, sizeof (double), 10, SIGNED, PADDR, d_put, 0};
82: struct dfmt string = { 0, 0, 8, 0, NO, st_put, 0};
83:
84:
85: char usage[] ="usage: od [-abcdfhilopswvx] [file] [[+]offset[.][b] [label]]";
86: char dbuf[DBUF_SIZE];
87: char lastdbuf[DBUF_SIZE];
88: int addr_base = 8; /* default address base is OCTAL */
89: long addr = 0L; /* current file offset */
90: long label = -1L; /* current label; -1 is "off" */
91: int dbuf_size = 16; /* file bytes / display line */
92: int _parity = NO; /* show parity on ascii bytes */
93: char fmt[] = " %s"; /* 12 blanks */
94: char *icvt();
95: char *scvt();
96: char *underline();
97: long get_addr();
98:
99:
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:
115: char _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:
151: main(argc, argv)
152: int argc;
153: char **argv;
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++;
165: argc--;
166:
167: if(argc > 0)
168: {
169: p = *argv;
170: if(*p == '-')
171: {
172: while(*++p != '\0')
173: {
174: switch(*p)
175: {
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':
215: case 'B':
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;
227: case 's':
228: d = &string;
229: *(cv++) = d;
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;
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;
243: case 'v':
244: showall = YES;
245: continue;
246: default:
247: printf("od: bad flag -%c\n", *p);
248: puts(usage);
249: exit(1);
250: }
251: *(cv++) = d;
252: }
253: argc--;
254: argv++;
255: }
256: }
257:
258: /*
259: * if nothing spec'd, setup default conversion.
260: */
261: if(cv == conv_vec)
262: *(cv++) = &u_s_oct;
263:
264: *cv = (struct dfmt *)0;
265:
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:
277: /*
278: * setup df_fmt to point to uniform output fields.
279: */
280: for (cv = conv_vec; d = *cv; cv++)
281: {
282: if (d->df_field) /* only if external field is known */
283: {
284: nelm = (dbuf_size + d->df_size - 1) / d->df_size;
285: field = max_llen / nelm;
286: d->df_fmt = fmt + 12 - (field - d->df_field);
287: }
288: }
289:
290: /*
291: * input file specified ?
292: */
293: if(argc > 0 && **argv != '+')
294: {
295: if (freopen(*argv, "r", stdin) == NULL)
296: {
297: perror(*argv);
298: exit(1);
299: }
300: argv++;
301: argc--;
302: }
303:
304: /*
305: * check for possible offset [label]
306: */
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: }
317:
318: /*
319: * main dump loop
320: */
321: same = -1;
322: while ((n = fread(dbuf, 1, dbuf_size, stdin)) > 0)
323: {
324: if (same>=0 && bcmp(dbuf, lastdbuf, dbuf_size) == 0 && !showall)
325: {
326: if (same==0)
327: {
328: printf("*\n");
329: same = 1;
330: }
331: }
332: else
333: {
334: line(n);
335: same = 0;
336: p = dbuf;
337: l = lastdbuf;
338: for (nelm = 0; nelm < dbuf_size; nelm++)
339: {
340: *l++ = *p;
341: *p++ = '\0';
342: }
343: }
344: addr += n;
345: if (label >= 0)
346: label += n;
347: }
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: }
363: exit(0);
364: }
365:
366: put_addr(a, l, c)
367: long a;
368: long l;
369: char c;
370: {
371: fputs(icvt(a, addr_base, UNSIGNED, 7), stdout);
372: if (l >= 0)
373: printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7));
374: putchar(c);
375: }
376:
377: line(n)
378: int n;
379: {
380: register i, first;
381: register struct dfmt *c;
382: register struct dfmt **cv = conv_vec;
383:
384: first = YES;
385: while (c = *cv++)
386: {
387: if (c->df_paddr)
388: {
389: if (first)
390: {
391: put_addr(addr, label, ' ');
392: first = NO;
393: }
394: else
395: {
396: putchar('\t');
397: if (label >= 0)
398: fputs("\t ", stdout);
399: }
400: }
401: i = 0;
402: while (i < n)
403: i += (*(c->df_put))(dbuf+i, c);
404: if (c->df_paddr)
405: putchar('\n');
406: }
407: }
408:
409: s_put(n, d)
410: short *n;
411: struct dfmt *d;
412: {
413: printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
414: return(d->df_size);
415: }
416:
417: us_put(n, d)
418: unsigned short *n;
419: struct dfmt *d;
420: {
421: printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field));
422: return(d->df_size);
423: }
424:
425: l_put(n, d)
426: long *n;
427: struct dfmt *d;
428: {
429: printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field));
430: return(d->df_size);
431: }
432:
433: d_put(f, d)
434: double *f;
435: struct dfmt *d;
436: {
437: char fbuf[24];
438: struct l { long n[2]; };
439:
440: #if vax
441: if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */
442: (void)sprintf(fbuf, " %08x %08x",
443: ((struct l *)f)->n[0], ((struct l *)f)->n[1]);
444: else
445: #endif
446:
447: (void)sprintf(fbuf, "%21.14e", *f);
448: printf(d->df_fmt, fbuf);
449: return(d->df_size);
450: }
451:
452: f_put(f, d)
453: float *f;
454: struct dfmt *d;
455: {
456: char fbuf[16];
457:
458: #if vax
459: if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */
460: (void)sprintf(fbuf, " %08x", *(long *)f);
461: else
462: #endif
463: (void)sprintf(fbuf, "%14.7e", *f);
464: printf(d->df_fmt, fbuf);
465: return(d->df_size);
466: }
467:
468:
469: char asc_name[34][4] = {
470: /* 000 */ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
471: /* 010 */ " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
472: /* 020 */ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
473: /* 030 */ "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
474: /* 040 */ " sp", "del"
475: };
476:
477: a_put(cc, d)
478: char *cc;
479: struct dfmt *d;
480: {
481: int c = *cc;
482: register char *s = " ";
483: register pbit = parity((int)c & 0377);
484:
485: c &= 0177;
486: if (isgraphic(c))
487: {
488: s[2] = c;
489: if (pbit == _parity)
490: printf(d->df_fmt, underline(s));
491: else
492: printf(d->df_fmt, s);
493: }
494: else
495: {
496: if (c == 0177)
497: c = ' ' + 1;
498: if (pbit == _parity)
499: printf(d->df_fmt, underline(asc_name[c]));
500: else
501: printf(d->df_fmt, asc_name[c]);
502: }
503: return(1);
504: }
505:
506: parity(word)
507: int word;
508: {
509: register int p = 0;
510: register int w = word;
511:
512: if (w)
513: do
514: {
515: p ^= 1;
516: } while(w &= (~(-w)));
517: return (p? ODD:EVEN);
518: }
519:
520: char *
521: underline(s)
522: char *s;
523: {
524: static char ulbuf[16];
525: register char *u = ulbuf;
526:
527: while (*s)
528: {
529: if (*s != ' ')
530: {
531: *u++ = '_';
532: *u++ = '\b';
533: }
534: *u++ = *s++;
535: }
536: *u = '\0';
537: return(ulbuf);
538: }
539:
540: b_put(b, d)
541: char *b;
542: struct dfmt *d;
543: {
544: printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field));
545: return(1);
546: }
547:
548: c_put(cc, d)
549: char *cc;
550: struct dfmt *d;
551: {
552: register char *s;
553: register int n;
554: register int c = *cc & 0377;
555:
556: s = scvt(c, d);
557: for (n = d->df_field - strlen(s); n > 0; n--)
558: putchar(' ');
559: printf(d->df_fmt, s);
560: return(1);
561: }
562:
563: char *scvt(c, d)
564: int c;
565: struct dfmt *d;
566: {
567: static char s[2];
568:
569: switch(c)
570: {
571: case '\0':
572: return("\\0");
573:
574: case '\b':
575: return("\\b");
576:
577: case '\f':
578: return("\\f");
579:
580: case '\n':
581: return("\\n");
582:
583: case '\r':
584: return("\\r");
585:
586: case '\t':
587: return("\\t");
588:
589: default:
590: if (isprint(c))
591: {
592: s[0] = c;
593: return(s);
594: }
595: return(icvt((long)c, d->df_radix, d->df_signed, d->df_field));
596: }
597: }
598:
599: /*
600: * Look for strings.
601: * A string contains bytes > 037 && < 177, and ends with a null.
602: * The minimum length is given in the dfmt structure.
603: */
604:
605: #define CNULL '\0'
606: #define S_EMPTY 0
607: #define S_FILL 1
608: #define S_CONT 2
609: #define SBUFSIZE 1024
610:
611: static char str_buf[SBUFSIZE];
612: static int str_mode = S_EMPTY;
613: static char *str_ptr;
614: static long str_addr;
615: static long str_label;
616:
617: st_put(cc, d)
618: char *cc;
619: struct dfmt *d;
620: {
621: register int c;
622:
623: if (cc == 0)
624: {
625: pr_sbuf(d, YES);
626: return(1);
627: }
628:
629: c = (*cc & 0377);
630:
631: if (str_mode & S_FILL)
632: {
633: if (isascii(c))
634: put_sbuf(c, d);
635: else
636: {
637: *str_ptr = CNULL;
638: if (c == NULL)
639: pr_sbuf(d, YES);
640: str_mode = S_EMPTY;
641: }
642: }
643: else if (isascii(c))
644: {
645: str_mode = S_FILL;
646: str_addr = addr + (cc - dbuf); /* ugly */
647: if ((str_label = label) >= 0)
648: str_label += (cc - dbuf); /* '' */
649: str_ptr = str_buf;
650: put_sbuf(c, d);
651: }
652:
653: return(1);
654: }
655:
656: put_sbuf(c, d)
657: int c;
658: struct dfmt *d;
659: {
660: *str_ptr++ = c;
661: if (str_ptr >= (str_buf + SBUFSIZE))
662: {
663: pr_sbuf(d, NO);
664: str_ptr = str_buf;
665: str_mode |= S_CONT;
666: }
667: }
668:
669: pr_sbuf(d, end)
670: struct dfmt *d;
671: int end;
672: {
673: register char *p = str_buf;
674:
675: if (str_mode == S_EMPTY
676: || (!(str_mode & S_CONT) && (str_ptr - str_buf) < d->df_size))
677: return;
678:
679: if (!(str_mode & S_CONT))
680: put_addr(str_addr, str_label, ' ');
681:
682: while (p < str_ptr)
683: fputs(scvt(*p++, d), stdout);
684:
685: if (end)
686: putchar('\n');
687: }
688:
689: /*
690: * integer to ascii conversion
691: *
692: * This code has been rearranged to produce optimized runtime code.
693: */
694:
695: #define MAXINTLENGTH 32
696: static char _digit[] = "0123456789abcdef";
697: static char _icv_buf[MAXINTLENGTH+1];
698: static long _mask = 0x7fffffff;
699:
700: char *
701: icvt (value, radix, hassign, ndigits)
702: long value;
703: int radix;
704: int hassign;
705: int ndigits;
706: {
707: register long val = value;
708: register long rad = radix;
709: register char *b = &_icv_buf[MAXINTLENGTH];
710: register char *d = _digit;
711: register long tmp1;
712: register long tmp2;
713: long rem;
714: long kludge;
715: int sign;
716:
717: if (val == 0)
718: {
719: *--b = '0';
720: sign = 0;
721: goto done; /*return(b);*/
722: }
723:
724: if (hassign && (sign = (val < 0))) /* signed conversion */
725: {
726: /*
727: * It is necessary to do the first divide
728: * before the absolute value, for the case -2^31
729: *
730: * This is actually what is being done...
731: * tmp1 = (int)(val % rad);
732: * val /= rad;
733: * val = -val
734: * *--b = d[-tmp1];
735: */
736: tmp1 = val / rad;
737: *--b = d[(tmp1 * rad) - val];
738: val = -tmp1;
739: }
740: else /* unsigned conversion */
741: {
742: sign = 0;
743: if (val < 0)
744: { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
745: kludge = _mask - (rad - 1);
746: val &= _mask;
747: /*
748: * This is really what's being done...
749: * rem = (kludge % rad) + (val % rad);
750: * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
751: * *--b = d[rem % rad];
752: */
753: tmp1 = kludge / rad;
754: tmp2 = val / rad;
755: rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
756: val = ++tmp1 + tmp2;
757: tmp1 = rem / rad;
758: val += tmp1;
759: *--b = d[rem - (tmp1 * rad)];
760: }
761: }
762:
763: while (val)
764: {
765: /*
766: * This is really what's being done ...
767: * *--b = d[val % rad];
768: * val /= rad;
769: */
770: tmp1 = val / rad;
771: *--b = d[val - (tmp1 * rad)];
772: val = tmp1;
773: }
774:
775: done:
776: if (sign)
777: *--b = '-';
778:
779: tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b);
780: tmp2 = hassign? ' ':'0';
781: while (tmp1 > 0)
782: {
783: *--b = tmp2;
784: tmp1--;
785: }
786:
787: return(b);
788: }
789:
790: long get_addr(s)
791: register char *s;
792: {
793: register char *p;
794: register long a;
795: register int d;
796:
797: if (*s=='+')
798: s++;
799: if (*s=='x')
800: {
801: s++;
802: addr_base = 16;
803: }
804: else if (*s=='0' && s[1]=='x')
805: {
806: s += 2;
807: addr_base = 16;
808: }
809: else if (*s == '0')
810: addr_base = 8;
811: p = s;
812: while(*p)
813: {
814: if (*p++=='.')
815: addr_base = 10;
816: }
817: for (a=0; *s; s++)
818: {
819: d = *s;
820: if(isdigit(d))
821: a = a*addr_base + d - '0';
822: else if (ishex(d) && addr_base==16)
823: a = a*addr_base + d + 10 - 'a';
824: else
825: break;
826: }
827:
828: if (*s == '.')
829: s++;
830: if(*s=='b')
831: a *= 512;
832: if(*s=='B')
833: a *= 1024;
834:
835: return(a);
836: }
837:
838: offset(a)
839: long a;
840: {
841: if (canseek(stdin))
842: {
843: /*
844: * in case we're accessing a raw disk,
845: * we have to seek in multiples of a physical block.
846: */
847: fseek(stdin, a & 0xfffffe00L, 0);
848: a &= 0x1ffL;
849: }
850: dumbseek(stdin, a);
851: }
852:
853: dumbseek(s, offset)
854: FILE *s;
855: long offset;
856: {
857: char buf[BUFSIZ];
858: int n;
859: int nr;
860:
861: while (offset > 0)
862: {
863: nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset;
864: if ((n = fread(buf, 1, nr, s)) != nr)
865: {
866: fprintf(stderr, "EOF\n");
867: exit(1);
868: }
869: offset -= n;
870: }
871: }
872:
873: #include <sys/types.h>
874: #include <sys/stat.h>
875:
876: canseek(f)
877: FILE *f;
878: {
879: struct stat statb;
880:
881: return( (fstat(fileno(f),&statb)==0) &&
882: (statb.st_nlink > 0) && /*!pipe*/
883: (!isatty(fileno(f))) );
884: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.