|
|
1.1 root 1: static char *sccsid = "@(#)od.c 5.11 (Berkeley) 4/29/83";
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 && bufncmp(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: }
364:
365: put_addr(a, l, c)
366: long a;
367: long l;
368: char c;
369: {
370: fputs(icvt(a, addr_base, UNSIGNED, 7), stdout);
371: if (l >= 0)
372: printf(" (%s)", icvt(l, addr_base, UNSIGNED, 7));
373: putchar(c);
374: }
375:
376: line(n)
377: int n;
378: {
379: register i, first;
380: register struct dfmt *c;
381: register struct dfmt **cv = conv_vec;
382:
383: first = YES;
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: }
399: }
400: i = 0;
401: while (i < n)
402: i += (*(c->df_put))(dbuf+i, c);
403: if (c->df_paddr)
404: putchar('\n');
405: }
406: }
407:
408: s_put(n, d)
409: short *n;
410: struct 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:
416: us_put(n, d)
417: unsigned short *n;
418: struct 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:
424: l_put(n, d)
425: long *n;
426: struct 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:
432: d_put(f, d)
433: double *f;
434: struct dfmt *d;
435: {
436: char fbuf[24];
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);
447: printf(d->df_fmt, fbuf);
448: return(d->df_size);
449: }
450:
451: f_put(f, d)
452: float *f;
453: struct dfmt *d;
454: {
455: char fbuf[16];
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);
463: printf(d->df_fmt, fbuf);
464: return(d->df_size);
465: }
466:
467:
468: char asc_name[34][4] = {
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"
474: };
475:
476: a_put(cc, d)
477: char *cc;
478: struct dfmt *d;
479: {
480: int c = *cc;
481: register char *s = " ";
482: register pbit = parity((int)c & 0377);
483:
484: c &= 0177;
485: if (isgraphic(c))
486: {
487: s[2] = c;
488: if (pbit == _parity)
489: printf(d->df_fmt, underline(s));
490: else
491: printf(d->df_fmt, s);
492: }
493: else
494: {
495: if (c == 0177)
496: c = ' ' + 1;
497: if (pbit == _parity)
498: printf(d->df_fmt, underline(asc_name[c]));
499: else
500: printf(d->df_fmt, asc_name[c]);
501: }
502: return(1);
503: }
504:
505: parity(word)
506: int word;
507: {
508: register int p = 0;
509: register int w = word;
510:
511: if (w)
512: do
513: {
514: p ^= 1;
515: } while(w &= (~(-w)));
516: return (p? ODD:EVEN);
517: }
518:
519: char *
520: underline(s)
521: char *s;
522: {
523: static char ulbuf[16];
524: register char *u = ulbuf;
525:
526: while (*s)
527: {
528: if (*s != ' ')
529: {
530: *u++ = '_';
531: *u++ = '\b';
532: }
533: *u++ = *s++;
534: }
535: *u = '\0';
536: return(ulbuf);
537: }
538:
539: b_put(b, d)
540: char *b;
541: struct 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:
547: c_put(cc, d)
548: char *cc;
549: struct dfmt *d;
550: {
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:
562: char *scvt(c, d)
563: int c;
564: struct 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");
575:
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));
595: }
596: }
597:
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:
610: static char str_buf[SBUFSIZE];
611: static int str_mode = S_EMPTY;
612: static char *str_ptr;
613: static long str_addr;
614: static long str_label;
615:
616: st_put(cc, d)
617: char *cc;
618: struct dfmt *d;
619: {
620: register int c;
621:
622: if (cc == 0)
623: {
624: pr_sbuf(d, YES);
625: return(1);
626: }
627:
628: c = (*cc & 0377);
629:
630: if (str_mode & S_FILL)
631: {
632: if (isascii(c))
633: put_sbuf(c, d);
634: else
635: {
636: *str_ptr = CNULL;
637: if (c == NULL)
638: pr_sbuf(d, YES);
639: str_mode = S_EMPTY;
640: }
641: }
642: else if (isascii(c))
643: {
644: str_mode = S_FILL;
645: str_addr = addr + (cc - dbuf); /* ugly */
646: if ((str_label = label) >= 0)
647: str_label += (cc - dbuf); /* '' */
648: str_ptr = str_buf;
649: put_sbuf(c, d);
650: }
651:
652: return(1);
653: }
654:
655: put_sbuf(c, d)
656: int c;
657: struct 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:
668: pr_sbuf(d, end)
669: struct dfmt *d;
670: int 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:
688: /*
689: * integer to ascii conversion
690: *
691: * This code has been rearranged to produce optimized runtime code.
692: */
693:
694: #define MAXINTLENGTH 32
695: static char _digit[] = "0123456789abcdef";
696: static char _icv_buf[MAXINTLENGTH+1];
697: static long _mask = 0x7fffffff;
698:
699: char *
700: icvt (value, radix, signed, ndigits)
701: long value;
702: int radix;
703: int signed;
704: int 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:
774: done:
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:
789: long get_addr(s)
790: register char *s;
791: {
792: register char *p;
793: register long a;
794: register int d;
795:
796: if (*s=='+')
797: s++;
798: if (*s=='x')
799: {
800: s++;
801: addr_base = 16;
802: }
803: else if (*s=='0' && s[1]=='x')
804: {
805: s += 2;
806: addr_base = 16;
807: }
808: else if (*s == '0')
809: addr_base = 8;
810: p = s;
811: while(*p)
812: {
813: if (*p++=='.')
814: addr_base = 10;
815: }
816: for (a=0; *s; s++)
817: {
818: d = *s;
819: if(isdigit(d))
820: a = a*addr_base + d - '0';
821: else if (ishex(d) && addr_base==16)
822: a = a*addr_base + d + 10 - 'a';
823: else
824: break;
825: }
826:
827: if (*s == '.')
828: s++;
829: if(*s=='b')
830: a *= 512;
831: if(*s=='B')
832: a *= 1024;
833:
834: return(a);
835: }
836:
837: bufncmp(a, b, n)
838: char *a;
839: char *b;
840: int n;
841: {
842: while (n--)
843: if (*a++ != *b++)
844: return(1);
845: }
846:
847: offset(a)
848: long a;
849: {
850: if (canseek(stdin))
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);
860: }
861:
862: dumbseek(s, offset)
863: FILE *s;
864: long 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:
885: canseek(f)
886: FILE *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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.