1*4530Sdlw static char *sccsid = "@(#)od.c 5.4 (Berkeley) 10/16/81"; 24492Sdlw /* 34492Sdlw * od -- octal, hex, decimal, character dump of data in a file. 44492Sdlw * 5*4530Sdlw * usage: od [-abcdDefFhHiIlLopPvxX] [file] [[+]offset[.][b] [label]] 64492Sdlw * 74492Sdlw * where the option flags have the following meaning: 84492Sdlw * character object radix signed? 94492Sdlw * a byte (10) (n.a.) ASCII named byte stream 104492Sdlw * b byte 8 no byte octal 114492Sdlw * c byte (8) (no) character with octal non-graphic bytes 124492Sdlw * d short 10 no 134492Sdlw * D long 10 no 144492Sdlw * e,F double (10) double precision floating pt. 154492Sdlw * f float (10) single precision floating pt. 164492Sdlw * h,x short 16 no 174492Sdlw * H,X long 16 no 184492Sdlw * i short 10 yes 194492Sdlw * I,l,L long 10 yes 204492Sdlw * o short 8 no (default conversion) 214492Sdlw * O long 8 no 224492Sdlw * 234492Sdlw * p indicate EVEN parity on 'a' conversion 244492Sdlw * P indicate ODD parity on 'a' conversion 254492Sdlw * v show all data - don't skip like lines. 264492Sdlw * 274492Sdlw * More than one format character may be given. 284492Sdlw * If {file} is not specified, standard input is read. 294492Sdlw * If {file} is not specified, then {offset} must start with '+'. 304492Sdlw * {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.); the default 314492Sdlw * is the same as the address radix, which will be the same as the first 324492Sdlw * object radix. 334492Sdlw */ 344492Sdlw 354492Sdlw #include <stdio.h> 364492Sdlw 374492Sdlw #define NO 0 384492Sdlw #define YES 1 394492Sdlw #define EVEN -1 404492Sdlw #define ODD 1 414492Sdlw #define UNSIGNED 0 424492Sdlw #define SIGNED 1 434492Sdlw 444492Sdlw int a_put(); 454492Sdlw int b_put(); 464492Sdlw int c_put(); 474492Sdlw int s_put(); 484492Sdlw int us_put(); 494492Sdlw int l_put(); 504492Sdlw int f_put(); 514492Sdlw int d_put(); 524492Sdlw 534492Sdlw struct dfmt { 544492Sdlw int df_field; /* external field required for object */ 554492Sdlw int df_size; /* size (bytes) of object */ 564492Sdlw int df_radix; /* conversion radix */ 574492Sdlw int df_signed; /* signed? flag */ 584492Sdlw int (*df_put)(); /* function to output object */ 594492Sdlw char *df_fmt; 604492Sdlw } *conv_vec[32]; /* vector of conversions to be done */ 614492Sdlw 624492Sdlw struct dfmt ascii = { 3, sizeof (char), 10, 0, a_put, 0}; 634492Sdlw struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, b_put, 0}; 644492Sdlw struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, c_put, 0}; 654492Sdlw struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, us_put, 0}; 664492Sdlw struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, us_put, 0}; 674492Sdlw struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, us_put, 0}; 684492Sdlw struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, l_put, 0}; 694492Sdlw struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, l_put, 0}; 704492Sdlw struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, l_put, 0}; 714492Sdlw struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, s_put, 0}; 724492Sdlw struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, l_put, 0}; 734492Sdlw struct dfmt flt = {14, sizeof (float), 10, SIGNED, f_put, 0}; 744492Sdlw struct dfmt dble = {21, sizeof (double), 10, SIGNED, d_put, 0}; 754492Sdlw 76*4530Sdlw 77*4530Sdlw char usage[] = "od [-abcdfhilopvx] [file] [[+]offset[.][b] [label]]"; 784492Sdlw char dbuf[16]; 794492Sdlw char lastdbuf[16]; 804492Sdlw int addr_base; 814492Sdlw long addr; 82*4530Sdlw long label = -1L; 834492Sdlw int _parity = NO; 844492Sdlw char fmt[] = " %s"; /* 12 blanks */ 854492Sdlw char *icvt(); 864492Sdlw char *underline(); 87*4530Sdlw long get_addr(); 884492Sdlw 89*4530Sdlw 904492Sdlw main(argc, argv) 914492Sdlw char **argv; 924492Sdlw { 934492Sdlw register char *p; 944492Sdlw register char *l; 954492Sdlw register n, same; 964492Sdlw struct dfmt *d; 974492Sdlw struct dfmt **cv = conv_vec; 984492Sdlw int showall = NO; 994492Sdlw int field, llen, nelm; 1004492Sdlw int max_llen = 0; 1014492Sdlw 1024492Sdlw argv++; 103*4530Sdlw argc--; 1044492Sdlw max_llen = max_nelm = 0; 1054492Sdlw 106*4530Sdlw if(argc > 0) { 1074492Sdlw p = *argv; 1084492Sdlw if(*p == '-') { 1094492Sdlw while(*++p != '\0') { 1104492Sdlw switch(*p) { 1114492Sdlw case 'a': 1124492Sdlw d = &ascii; 1134492Sdlw break; 1144492Sdlw case 'b': 1154492Sdlw d = &byte; 1164492Sdlw break; 1174492Sdlw case 'c': 1184492Sdlw d = &cchar; 1194492Sdlw break; 1204492Sdlw case 'd': 1214492Sdlw d = &u_s_dec; 1224492Sdlw break; 1234492Sdlw case 'D': 1244492Sdlw d = &u_l_dec; 1254492Sdlw break; 1264492Sdlw case 'e': 1274492Sdlw case 'F': 1284492Sdlw d = &dble; 1294492Sdlw break; 1304492Sdlw case 'f': 1314492Sdlw d = &flt; 1324492Sdlw break; 1334492Sdlw case 'h': 1344492Sdlw case 'x': 1354492Sdlw d = &u_s_hex; 1364492Sdlw break; 1374492Sdlw case 'H': 1384492Sdlw case 'X': 1394492Sdlw d = &u_l_hex; 1404492Sdlw break; 1414492Sdlw case 'i': 1424492Sdlw d = &s_s_dec; 1434492Sdlw break; 1444492Sdlw case 'I': 1454492Sdlw case 'l': 1464492Sdlw case 'L': 1474492Sdlw d = &s_l_dec; 1484492Sdlw break; 1494492Sdlw case 'o': 1504492Sdlw d = &u_s_oct; 1514492Sdlw break; 1524492Sdlw case 'O': 1534492Sdlw d = &u_l_oct; 1544492Sdlw break; 1554492Sdlw case 'p': 1564492Sdlw _parity = EVEN; 1574492Sdlw continue; 1584492Sdlw case 'P': 1594492Sdlw _parity = ODD; 1604492Sdlw continue; 1614492Sdlw case 'v': 1624492Sdlw showall = YES; 1634492Sdlw continue; 164*4530Sdlw default: 165*4530Sdlw printf("od: bad flag -%c\n", *p); 166*4530Sdlw puts(usage); 167*4530Sdlw exit(1); 1684492Sdlw } 1694492Sdlw nelm = 16 / d->df_size; 1704492Sdlw llen = (d->df_field + 1) * nelm; 1714492Sdlw if (llen > max_llen) 1724492Sdlw max_llen = llen; 1734492Sdlw if (nelm > max_nelm) 1744492Sdlw max_nelm = nelm; 1754492Sdlw /* 1764492Sdlw * nelm will always be a power of 2. 1774492Sdlw * line length must always be multiple 1784492Sdlw * of max_nelm. 1794492Sdlw */ 1804492Sdlw nelm = max_nelm - 1; 1814492Sdlw max_llen = (max_llen + nelm) & (~nelm); 1824492Sdlw if (addr_base == 0) 1834492Sdlw addr_base = d->df_radix; 1844492Sdlw *(cv++) = d; 1854492Sdlw } 1864492Sdlw argc--; 1874492Sdlw argv++; 1884492Sdlw } 1894492Sdlw } 1904492Sdlw 1914492Sdlw if(cv == conv_vec) { 1924492Sdlw addr_base = 8; 1934492Sdlw *(cv++) = &u_s_oct; 194*4530Sdlw max_nelm = 16 / u_s_oct.df_size; 195*4530Sdlw max_llen = max_nelm * (u_s_oct.df_field + 1); 1964492Sdlw } 1974492Sdlw *cv = (struct dfmt *)0; 1984492Sdlw 1994492Sdlw cv = conv_vec; 2004492Sdlw while (d = *cv++) { 2014492Sdlw nelm = 16 / d->df_size; 2024492Sdlw field = max_llen / nelm; 2034492Sdlw d->df_fmt = fmt + 12 - (field - d->df_field); 2044492Sdlw } 2054492Sdlw 206*4530Sdlw if(argc > 0 && **argv != '+') { 2074492Sdlw if (freopen(*argv, "r", stdin) == NULL) { 2084492Sdlw printf("od: cannot open %s\n", *argv); 2094492Sdlw exit(1); 2104492Sdlw } 2114492Sdlw argv++; 2124492Sdlw argc--; 2134492Sdlw } 2144492Sdlw 215*4530Sdlw if (argc > 0) 216*4530Sdlw { 217*4530Sdlw addr = get_addr(*argv); 218*4530Sdlw offset(addr); 219*4530Sdlw argv++; 220*4530Sdlw argc--; 2214492Sdlw 222*4530Sdlw if (argc > 0) 223*4530Sdlw label = get_addr(*argv); 224*4530Sdlw } 225*4530Sdlw 2264492Sdlw same = -1; 2274492Sdlw while ((n = fread(dbuf, 1, sizeof(dbuf), stdin)) > 0) { 2284492Sdlw if (same>=0 && strncmp(dbuf, lastdbuf, 16) == 0 && !showall) { 2294492Sdlw if (same==0) { 2304492Sdlw printf("*\n"); 2314492Sdlw same = 1; 2324492Sdlw } 2334492Sdlw } 2344492Sdlw else { 2354492Sdlw line(n); 2364492Sdlw same = 0; 2374492Sdlw p = dbuf; 2384492Sdlw l = lastdbuf; 2394492Sdlw for (nelm=0; nelm<16; nelm++) { 2404492Sdlw *l++ = *p; 2414492Sdlw *p++ = '\0'; 2424492Sdlw } 2434492Sdlw } 2444492Sdlw addr += n; 245*4530Sdlw if (label >= 0) 246*4530Sdlw label += n; 2474492Sdlw } 248*4530Sdlw put_addr('\n'); 2494492Sdlw } 2504492Sdlw 251*4530Sdlw put_addr(c) 252*4530Sdlw char c; 253*4530Sdlw { 254*4530Sdlw fputs(icvt(addr, addr_base, UNSIGNED, 7), stdout); 255*4530Sdlw if (label >= 0) 256*4530Sdlw printf(" (%s)", icvt(label, addr_base, UNSIGNED, 7)); 257*4530Sdlw putchar(c); 258*4530Sdlw } 259*4530Sdlw 2604492Sdlw line(n) 2614492Sdlw int n; 2624492Sdlw { 2634492Sdlw register i, first; 2644492Sdlw register struct dfmt *c; 2654492Sdlw register struct dfmt **cv = conv_vec; 2664492Sdlw 2674492Sdlw first = YES; 2684492Sdlw while (c = *cv++) { 2694492Sdlw if (first) { 270*4530Sdlw put_addr(' '); 2714492Sdlw first = NO; 272*4530Sdlw } else { 2734492Sdlw putchar('\t'); 274*4530Sdlw if (label >= 0) 275*4530Sdlw fputs("\t ", stdout); 276*4530Sdlw } 2774492Sdlw i = 0; 2784492Sdlw while (i < n) 2794492Sdlw i += (*(c->df_put))(dbuf+i, c); 2804492Sdlw putchar('\n'); 2814492Sdlw } 2824492Sdlw } 2834492Sdlw 2844492Sdlw s_put(n, d) 2854492Sdlw short *n; 2864492Sdlw struct dfmt *d; 2874492Sdlw { 2884492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 2894492Sdlw return(d->df_size); 2904492Sdlw } 2914492Sdlw 2924492Sdlw us_put(n, d) 2934492Sdlw unsigned short *n; 2944492Sdlw struct dfmt *d; 2954492Sdlw { 2964492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 2974492Sdlw return(d->df_size); 2984492Sdlw } 2994492Sdlw 3004492Sdlw l_put(n, d) 3014492Sdlw long *n; 3024492Sdlw struct dfmt *d; 3034492Sdlw { 3044492Sdlw printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field)); 3054492Sdlw return(d->df_size); 3064492Sdlw } 3074492Sdlw 3084492Sdlw d_put(f, d) 3094492Sdlw double *f; 3104492Sdlw struct dfmt *d; 3114492Sdlw { 3124492Sdlw char fbuf[24]; 3134500Sdlw struct l { long n[2]; }; 3144500Sdlw 3154500Sdlw #if vax 3164500Sdlw if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */ 3174500Sdlw sprintf(fbuf, " %08x %08x", 3184500Sdlw ((struct l *)f)->n[0], ((struct l *)f)->n[1]); 3194500Sdlw else 3204500Sdlw #endif 3214500Sdlw 3224500Sdlw sprintf(fbuf, "%21.14e", *f); 3234492Sdlw printf(d->df_fmt, fbuf); 3244492Sdlw return(d->df_size); 3254492Sdlw } 3264492Sdlw 3274492Sdlw f_put(f, d) 3284492Sdlw float *f; 3294492Sdlw struct dfmt *d; 3304492Sdlw { 3314492Sdlw char fbuf[16]; 3324500Sdlw 3334500Sdlw #if vax 3344500Sdlw if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */ 3354500Sdlw sprintf(fbuf, " %08x", *(long *)f); 3364500Sdlw else 3374500Sdlw #endif 3384500Sdlw sprintf(fbuf, "%14.7e", *f); 3394492Sdlw printf(d->df_fmt, fbuf); 3404492Sdlw return(d->df_size); 3414492Sdlw } 3424492Sdlw 3434492Sdlw 3444492Sdlw char asc_name[34][4] = { 3454492Sdlw "nul", 3464492Sdlw "soh", 3474492Sdlw "stx", 3484492Sdlw "etx", 3494492Sdlw "eot", 3504492Sdlw "enq", 3514492Sdlw "ack", 3524492Sdlw "bel", 3534492Sdlw " bs", 3544492Sdlw " ht", 3554492Sdlw " nl", 3564492Sdlw " vt", 3574492Sdlw " ff", 3584492Sdlw " cr", 3594492Sdlw " so", 3604492Sdlw " si", 3614492Sdlw "dle", 3624492Sdlw "dc1", 3634492Sdlw "dc2", 3644492Sdlw "dc3", 3654492Sdlw "dc4", 3664492Sdlw "nak", 3674492Sdlw "syn", 3684492Sdlw "etb", 3694492Sdlw "can", 3704492Sdlw " em", 3714492Sdlw "sub", 3724492Sdlw "esc", 3734492Sdlw " fs", 3744492Sdlw " gs", 3754492Sdlw " rs", 3764492Sdlw " us", 3774492Sdlw " sp", 3784492Sdlw "del" 3794492Sdlw }; 3804492Sdlw 3814492Sdlw a_put(cc, d) 3824492Sdlw char *cc; 3834492Sdlw struct dfmt *d; 3844492Sdlw { 3854492Sdlw int c = *cc; 3864492Sdlw register char *s = " "; 3874492Sdlw register pbit = parity((int)c & 0377); 3884492Sdlw 3894492Sdlw c &= 0177; 3904492Sdlw if (c > ' ' && c < 0177) 3914492Sdlw { 3924492Sdlw s[2] = *cc; 3934492Sdlw if (pbit == _parity) 3944503Sdlw printf(d->df_fmt, underline(s)); 3954492Sdlw else 3964492Sdlw printf(d->df_fmt, s); 3974492Sdlw } 3984492Sdlw else 3994492Sdlw { 4004492Sdlw if (c == 0177) 4014492Sdlw c = ' ' + 1; 4024492Sdlw if (pbit == _parity) 4034503Sdlw printf(d->df_fmt, underline(asc_name[c])); 4044492Sdlw else 4054492Sdlw printf(d->df_fmt, asc_name[c]); 4064492Sdlw } 4074492Sdlw return(1); 4084492Sdlw } 4094492Sdlw 4104492Sdlw parity(word) 4114492Sdlw int word; 4124492Sdlw { 4134492Sdlw register int p = 0; 4144492Sdlw register int w = word; 4154492Sdlw 4164492Sdlw if (w) 4174492Sdlw do { 4184492Sdlw p ^= 1; 4194492Sdlw } while(w &= (~(-w))); 4204492Sdlw return (p? ODD:EVEN); 4214492Sdlw } 4224492Sdlw 4234492Sdlw char * 4244503Sdlw underline(s) 4254492Sdlw char *s; 4264492Sdlw { 4274492Sdlw static char ulbuf[16]; 4284492Sdlw register char *u = ulbuf; 4294492Sdlw 4304503Sdlw while (*s) { 4314503Sdlw if (*s != ' ') { 4324492Sdlw *u++ = '_'; 4334492Sdlw *u++ = '\b'; 4344492Sdlw } 4354492Sdlw *u++ = *s++; 4364492Sdlw } 4374492Sdlw *u = '\0'; 4384492Sdlw return(ulbuf); 4394492Sdlw } 4404492Sdlw 4414492Sdlw b_put(b, d) 4424492Sdlw char *b; 4434492Sdlw struct dfmt *d; 4444492Sdlw { 4454492Sdlw printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); 4464492Sdlw return(1); 4474492Sdlw } 4484492Sdlw 4494492Sdlw c_put(cc, d) 4504492Sdlw char *cc; 4514492Sdlw struct dfmt *d; 4524492Sdlw { 4534492Sdlw int c = *cc & 0377; 4544492Sdlw register char *s = " "; 4554492Sdlw 4564492Sdlw if(c>037 && c<0177) { 4574492Sdlw s[2] = *cc; 4584492Sdlw printf(d->df_fmt, s); 4594492Sdlw return(1); 4604492Sdlw } 4614492Sdlw 4624492Sdlw switch(c) { 4634492Sdlw case '\0': 4644492Sdlw s = " \\0"; 4654492Sdlw break; 4664492Sdlw case '\b': 4674492Sdlw s = " \\b"; 4684492Sdlw break; 4694492Sdlw case '\f': 4704492Sdlw s = " \\f"; 4714492Sdlw break; 4724492Sdlw case '\n': 4734492Sdlw s = " \\n"; 4744492Sdlw break; 4754492Sdlw case '\r': 4764492Sdlw s = " \\r"; 4774492Sdlw break; 4784492Sdlw case '\t': 4794492Sdlw s = " \\t"; 4804492Sdlw break; 4814492Sdlw default: 4824492Sdlw s = icvt((long)c, d->df_radix, d->df_signed, d->df_field); 4834492Sdlw } 4844492Sdlw printf(d->df_fmt, s); 4854492Sdlw return(1); 4864492Sdlw } 4874492Sdlw 4884492Sdlw /* 4894492Sdlw * integer to ascii conversion 4904492Sdlw * 4914492Sdlw * This code has been rearranged to produce optimized runtime code. 4924492Sdlw */ 4934492Sdlw 4944492Sdlw #define MAXINTLENGTH 32 4954492Sdlw static char _digit[] = "0123456789abcdef"; 4964492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 4974492Sdlw static long _mask = 0x7fffffff; 4984492Sdlw 4994492Sdlw char * 5004492Sdlw icvt (value, radix, signed, ndigits) 5014492Sdlw long value; 5024492Sdlw int radix; 5034492Sdlw int signed; 5044492Sdlw int ndigits; 5054492Sdlw { 5064492Sdlw register long val = value; 5074492Sdlw register long rad = radix; 5084492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 5094492Sdlw register char *d = _digit; 5104492Sdlw register long tmp1; 5114492Sdlw register long tmp2; 5124492Sdlw long rem; 5134492Sdlw long kludge; 5144492Sdlw int sign; 5154492Sdlw 5164492Sdlw if (val == 0) 5174492Sdlw { 5184492Sdlw *--b = '0'; 5194492Sdlw sign = 0; 5204492Sdlw goto done; /*return(b);*/ 5214492Sdlw } 5224492Sdlw 5234492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 5244492Sdlw { 5254492Sdlw /* 5264492Sdlw * It is necessary to do the first divide 5274492Sdlw * before the absolute value, for the case -2^31 5284492Sdlw * 5294492Sdlw * This is actually what is being done... 5304492Sdlw * tmp1 = (int)(val % rad); 5314492Sdlw * val /= rad; 5324492Sdlw * val = -val 5334492Sdlw * *--b = d[-tmp1]; 5344492Sdlw */ 5354492Sdlw tmp1 = val / rad; 5364492Sdlw *--b = d[(tmp1 * rad) - val]; 5374492Sdlw val = -tmp1; 5384492Sdlw } 5394492Sdlw else /* unsigned conversion */ 5404492Sdlw { 5414492Sdlw sign = 0; 5424492Sdlw if (val < 0) 5434492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 5444492Sdlw kludge = _mask - (rad - 1); 5454492Sdlw val &= _mask; 5464492Sdlw /* 5474492Sdlw * This is really what's being done... 5484492Sdlw * rem = (kludge % rad) + (val % rad); 5494492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 5504492Sdlw * *--b = d[rem % rad]; 5514492Sdlw */ 5524492Sdlw tmp1 = kludge / rad; 5534492Sdlw tmp2 = val / rad; 5544492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 5554492Sdlw val = ++tmp1 + tmp2; 5564492Sdlw tmp1 = rem / rad; 5574492Sdlw val += tmp1; 5584492Sdlw *--b = d[rem - (tmp1 * rad)]; 5594492Sdlw } 5604492Sdlw } 5614492Sdlw 5624492Sdlw while (val) 5634492Sdlw { 5644492Sdlw /* 5654492Sdlw * This is really what's being done ... 5664492Sdlw * *--b = d[val % rad]; 5674492Sdlw * val /= rad; 5684492Sdlw */ 5694492Sdlw tmp1 = val / rad; 5704492Sdlw *--b = d[val - (tmp1 * rad)]; 5714492Sdlw val = tmp1; 5724492Sdlw } 5734492Sdlw 5744492Sdlw done: 5754492Sdlw if (sign) 5764492Sdlw *--b = '-'; 5774492Sdlw 5784492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 5794492Sdlw tmp2 = signed? ' ':'0'; 5804492Sdlw while (tmp1 > 0) 5814492Sdlw { 5824492Sdlw *--b = tmp2; 5834492Sdlw tmp1--; 5844492Sdlw } 5854492Sdlw 5864492Sdlw return(b); 5874492Sdlw } 5884492Sdlw 589*4530Sdlw long 590*4530Sdlw get_addr(s) 5914492Sdlw register char *s; 5924492Sdlw { 5934492Sdlw register char *p; 594*4530Sdlw register long a; 5954492Sdlw register int d; 5964492Sdlw 5974492Sdlw if (*s=='+') 5984492Sdlw s++; 5994492Sdlw if (*s=='x') { 6004492Sdlw s++; 6014492Sdlw addr_base = 16; 6024492Sdlw } else if (*s=='0' && s[1]=='x') { 6034492Sdlw s += 2; 6044492Sdlw addr_base = 16; 6054492Sdlw } else if (*s == '0') 6064492Sdlw addr_base = 8; 6074492Sdlw p = s; 6084492Sdlw while(*p) { 6094492Sdlw if (*p++=='.') 6104492Sdlw addr_base = 10; 6114492Sdlw } 6124492Sdlw for (a=0; *s; s++) { 6134492Sdlw d = *s; 6144492Sdlw if(d>='0' && d<='9') 6154492Sdlw a = a*addr_base + d - '0'; 6164492Sdlw else if (d>='a' && d<='f' && addr_base==16) 6174492Sdlw a = a*addr_base + d + 10 - 'a'; 6184492Sdlw else 6194492Sdlw break; 6204492Sdlw } 621*4530Sdlw 6224492Sdlw if (*s == '.') 6234492Sdlw s++; 624*4530Sdlw if(*s=='b') 6254492Sdlw a *= 512; 626*4530Sdlw if(*s=='B') 627*4530Sdlw a *= 1024; 628*4530Sdlw 629*4530Sdlw return(a); 630*4530Sdlw } 631*4530Sdlw 632*4530Sdlw offset(a) 633*4530Sdlw long a; 634*4530Sdlw { 6354492Sdlw if (canseek(stdin)) 6364492Sdlw fseek(stdin, a, 0); 6374492Sdlw else 6384492Sdlw dumbseek(stdin, a); 6394492Sdlw } 6404492Sdlw 6414492Sdlw dumbseek(s, offset) 6424492Sdlw FILE *s; 6434492Sdlw long offset; 6444492Sdlw { 6454492Sdlw char buf[BUFSIZ]; 6464492Sdlw int n; 6474492Sdlw int nr; 6484492Sdlw 6494492Sdlw while (offset > 0) 6504492Sdlw { 6514492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 6524492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 6534492Sdlw { 6544492Sdlw fprintf(stderr, "EOF\n"); 6554492Sdlw exit(1); 6564492Sdlw } 6574492Sdlw offset -= n; 6584492Sdlw } 6594492Sdlw } 6604492Sdlw 6614492Sdlw #include <sys/types.h> 6624492Sdlw #include <sys/stat.h> 6634492Sdlw 6644492Sdlw canseek(f) 6654492Sdlw FILE *f; 6664492Sdlw { 6674492Sdlw struct stat statb; 6684492Sdlw 6694492Sdlw return( (fstat(fileno(f),&statb)==0) && 6704492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 6714492Sdlw (!isatty(fileno(f))) ); 6724492Sdlw } 673