1*4492Sdlw static char *sccsid = "@(#)od.c 5.1 (Berkeley) 10/13/81"; 2*4492Sdlw /* 3*4492Sdlw * od -- octal, hex, decimal, character dump of data in a file. 4*4492Sdlw * 5*4492Sdlw * usage: od [-abcdDefFhHiIlLopPvxX] [file] [[+]offset[.][b]] 6*4492Sdlw * 7*4492Sdlw * where the option flags have the following meaning: 8*4492Sdlw * character object radix signed? 9*4492Sdlw * a byte (10) (n.a.) ASCII named byte stream 10*4492Sdlw * b byte 8 no byte octal 11*4492Sdlw * c byte (8) (no) character with octal non-graphic bytes 12*4492Sdlw * d short 10 no 13*4492Sdlw * D long 10 no 14*4492Sdlw * e,F double (10) double precision floating pt. 15*4492Sdlw * f float (10) single precision floating pt. 16*4492Sdlw * h,x short 16 no 17*4492Sdlw * H,X long 16 no 18*4492Sdlw * i short 10 yes 19*4492Sdlw * I,l,L long 10 yes 20*4492Sdlw * o short 8 no (default conversion) 21*4492Sdlw * O long 8 no 22*4492Sdlw * 23*4492Sdlw * p indicate EVEN parity on 'a' conversion 24*4492Sdlw * P indicate ODD parity on 'a' conversion 25*4492Sdlw * v show all data - don't skip like lines. 26*4492Sdlw * 27*4492Sdlw * More than one format character may be given. 28*4492Sdlw * If {file} is not specified, standard input is read. 29*4492Sdlw * If {file} is not specified, then {offset} must start with '+'. 30*4492Sdlw * {Offset} may be HEX (0xnnn), OCTAL (0nn), or decimal (nnn.); the default 31*4492Sdlw * is the same as the address radix, which will be the same as the first 32*4492Sdlw * object radix. 33*4492Sdlw */ 34*4492Sdlw 35*4492Sdlw #include <stdio.h> 36*4492Sdlw 37*4492Sdlw #define NO 0 38*4492Sdlw #define YES 1 39*4492Sdlw #define EVEN -1 40*4492Sdlw #define ODD 1 41*4492Sdlw #define UNSIGNED 0 42*4492Sdlw #define SIGNED 1 43*4492Sdlw 44*4492Sdlw int a_put(); 45*4492Sdlw int b_put(); 46*4492Sdlw int c_put(); 47*4492Sdlw int s_put(); 48*4492Sdlw int us_put(); 49*4492Sdlw int l_put(); 50*4492Sdlw int f_put(); 51*4492Sdlw int d_put(); 52*4492Sdlw 53*4492Sdlw struct dfmt { 54*4492Sdlw int df_field; /* external field required for object */ 55*4492Sdlw int df_size; /* size (bytes) of object */ 56*4492Sdlw int df_radix; /* conversion radix */ 57*4492Sdlw int df_signed; /* signed? flag */ 58*4492Sdlw int (*df_put)(); /* function to output object */ 59*4492Sdlw char *df_fmt; 60*4492Sdlw } *conv_vec[32]; /* vector of conversions to be done */ 61*4492Sdlw 62*4492Sdlw struct dfmt ascii = { 3, sizeof (char), 10, 0, a_put, 0}; 63*4492Sdlw struct dfmt byte = { 3, sizeof (char), 8, UNSIGNED, b_put, 0}; 64*4492Sdlw struct dfmt cchar = { 3, sizeof (char), 8, UNSIGNED, c_put, 0}; 65*4492Sdlw struct dfmt u_s_oct = { 6, sizeof (short), 8, UNSIGNED, us_put, 0}; 66*4492Sdlw struct dfmt u_s_dec = { 5, sizeof (short), 10, UNSIGNED, us_put, 0}; 67*4492Sdlw struct dfmt u_s_hex = { 4, sizeof (short), 16, UNSIGNED, us_put, 0}; 68*4492Sdlw struct dfmt u_l_oct = {11, sizeof (long), 8, UNSIGNED, l_put, 0}; 69*4492Sdlw struct dfmt u_l_dec = {10, sizeof (long), 10, UNSIGNED, l_put, 0}; 70*4492Sdlw struct dfmt u_l_hex = { 8, sizeof (long), 16, UNSIGNED, l_put, 0}; 71*4492Sdlw struct dfmt s_s_dec = { 6, sizeof (short), 10, SIGNED, s_put, 0}; 72*4492Sdlw struct dfmt s_l_dec = {11, sizeof (long), 10, SIGNED, l_put, 0}; 73*4492Sdlw struct dfmt flt = {14, sizeof (float), 10, SIGNED, f_put, 0}; 74*4492Sdlw struct dfmt dble = {21, sizeof (double), 10, SIGNED, d_put, 0}; 75*4492Sdlw 76*4492Sdlw char dbuf[16]; 77*4492Sdlw char lastdbuf[16]; 78*4492Sdlw int addr_base; 79*4492Sdlw long addr; 80*4492Sdlw int _parity = NO; 81*4492Sdlw char fmt[] = " %s"; /* 12 blanks */ 82*4492Sdlw char *icvt(); 83*4492Sdlw char *underline(); 84*4492Sdlw 85*4492Sdlw main(argc, argv) 86*4492Sdlw char **argv; 87*4492Sdlw { 88*4492Sdlw register char *p; 89*4492Sdlw register char *l; 90*4492Sdlw register n, same; 91*4492Sdlw struct dfmt *d; 92*4492Sdlw struct dfmt **cv = conv_vec; 93*4492Sdlw int showall = NO; 94*4492Sdlw int field, llen, nelm; 95*4492Sdlw int max_llen = 0; 96*4492Sdlw 97*4492Sdlw argv++; 98*4492Sdlw max_llen = max_nelm = 0; 99*4492Sdlw 100*4492Sdlw if(argc > 1) { 101*4492Sdlw p = *argv; 102*4492Sdlw if(*p == '-') { 103*4492Sdlw while(*++p != '\0') { 104*4492Sdlw switch(*p) { 105*4492Sdlw case 'a': 106*4492Sdlw d = &ascii; 107*4492Sdlw break; 108*4492Sdlw case 'b': 109*4492Sdlw d = &byte; 110*4492Sdlw break; 111*4492Sdlw case 'c': 112*4492Sdlw d = &cchar; 113*4492Sdlw break; 114*4492Sdlw case 'd': 115*4492Sdlw d = &u_s_dec; 116*4492Sdlw break; 117*4492Sdlw case 'D': 118*4492Sdlw d = &u_l_dec; 119*4492Sdlw break; 120*4492Sdlw case 'e': 121*4492Sdlw case 'F': 122*4492Sdlw d = &dble; 123*4492Sdlw break; 124*4492Sdlw case 'f': 125*4492Sdlw d = &flt; 126*4492Sdlw break; 127*4492Sdlw case 'h': 128*4492Sdlw case 'x': 129*4492Sdlw d = &u_s_hex; 130*4492Sdlw break; 131*4492Sdlw case 'H': 132*4492Sdlw case 'X': 133*4492Sdlw d = &u_l_hex; 134*4492Sdlw break; 135*4492Sdlw case 'i': 136*4492Sdlw d = &s_s_dec; 137*4492Sdlw break; 138*4492Sdlw case 'I': 139*4492Sdlw case 'l': 140*4492Sdlw case 'L': 141*4492Sdlw d = &s_l_dec; 142*4492Sdlw break; 143*4492Sdlw case 'o': 144*4492Sdlw d = &u_s_oct; 145*4492Sdlw break; 146*4492Sdlw case 'O': 147*4492Sdlw d = &u_l_oct; 148*4492Sdlw break; 149*4492Sdlw case 'p': 150*4492Sdlw _parity = EVEN; 151*4492Sdlw continue; 152*4492Sdlw case 'P': 153*4492Sdlw _parity = ODD; 154*4492Sdlw continue; 155*4492Sdlw case 'v': 156*4492Sdlw showall = YES; 157*4492Sdlw continue; 158*4492Sdlw } 159*4492Sdlw nelm = 16 / d->df_size; 160*4492Sdlw llen = (d->df_field + 1) * nelm; 161*4492Sdlw if (llen > max_llen) 162*4492Sdlw max_llen = llen; 163*4492Sdlw if (nelm > max_nelm) 164*4492Sdlw max_nelm = nelm; 165*4492Sdlw /* 166*4492Sdlw * nelm will always be a power of 2. 167*4492Sdlw * line length must always be multiple 168*4492Sdlw * of max_nelm. 169*4492Sdlw */ 170*4492Sdlw nelm = max_nelm - 1; 171*4492Sdlw max_llen = (max_llen + nelm) & (~nelm); 172*4492Sdlw if (addr_base == 0) 173*4492Sdlw addr_base = d->df_radix; 174*4492Sdlw *(cv++) = d; 175*4492Sdlw } 176*4492Sdlw argc--; 177*4492Sdlw argv++; 178*4492Sdlw } 179*4492Sdlw } 180*4492Sdlw 181*4492Sdlw if(cv == conv_vec) { 182*4492Sdlw addr_base = 8; 183*4492Sdlw *(cv++) = &u_s_oct; 184*4492Sdlw max_llen = (16 / u_s_oct.df_size) * (u_s_oct.df_field + 1); 185*4492Sdlw } 186*4492Sdlw *cv = (struct dfmt *)0; 187*4492Sdlw 188*4492Sdlw cv = conv_vec; 189*4492Sdlw while (d = *cv++) { 190*4492Sdlw nelm = 16 / d->df_size; 191*4492Sdlw field = max_llen / nelm; 192*4492Sdlw d->df_fmt = fmt + 12 - (field - d->df_field); 193*4492Sdlw } 194*4492Sdlw 195*4492Sdlw if(argc > 1 && **argv != '+') { 196*4492Sdlw if (freopen(*argv, "r", stdin) == NULL) { 197*4492Sdlw printf("od: cannot open %s\n", *argv); 198*4492Sdlw exit(1); 199*4492Sdlw } 200*4492Sdlw argv++; 201*4492Sdlw argc--; 202*4492Sdlw } 203*4492Sdlw 204*4492Sdlw if (argc > 1) 205*4492Sdlw offset(*argv); 206*4492Sdlw 207*4492Sdlw same = -1; 208*4492Sdlw while ((n = fread(dbuf, 1, sizeof(dbuf), stdin)) > 0) { 209*4492Sdlw if (same>=0 && strncmp(dbuf, lastdbuf, 16) == 0 && !showall) { 210*4492Sdlw if (same==0) { 211*4492Sdlw printf("*\n"); 212*4492Sdlw same = 1; 213*4492Sdlw } 214*4492Sdlw } 215*4492Sdlw else { 216*4492Sdlw line(n); 217*4492Sdlw same = 0; 218*4492Sdlw p = dbuf; 219*4492Sdlw l = lastdbuf; 220*4492Sdlw for (nelm=0; nelm<16; nelm++) { 221*4492Sdlw *l++ = *p; 222*4492Sdlw *p++ = '\0'; 223*4492Sdlw } 224*4492Sdlw } 225*4492Sdlw addr += n; 226*4492Sdlw } 227*4492Sdlw puts(icvt(addr, addr_base, UNSIGNED, 7)); 228*4492Sdlw } 229*4492Sdlw 230*4492Sdlw line(n) 231*4492Sdlw int n; 232*4492Sdlw { 233*4492Sdlw register i, first; 234*4492Sdlw register struct dfmt *c; 235*4492Sdlw register struct dfmt **cv = conv_vec; 236*4492Sdlw 237*4492Sdlw first = YES; 238*4492Sdlw while (c = *cv++) { 239*4492Sdlw if (first) { 240*4492Sdlw printf("%s ", icvt(addr, addr_base, UNSIGNED, 7)); 241*4492Sdlw first = NO; 242*4492Sdlw } else 243*4492Sdlw putchar('\t'); 244*4492Sdlw i = 0; 245*4492Sdlw while (i < n) 246*4492Sdlw i += (*(c->df_put))(dbuf+i, c); 247*4492Sdlw putchar('\n'); 248*4492Sdlw } 249*4492Sdlw } 250*4492Sdlw 251*4492Sdlw s_put(n, d) 252*4492Sdlw short *n; 253*4492Sdlw struct dfmt *d; 254*4492Sdlw { 255*4492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 256*4492Sdlw return(d->df_size); 257*4492Sdlw } 258*4492Sdlw 259*4492Sdlw us_put(n, d) 260*4492Sdlw unsigned short *n; 261*4492Sdlw struct dfmt *d; 262*4492Sdlw { 263*4492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 264*4492Sdlw return(d->df_size); 265*4492Sdlw } 266*4492Sdlw 267*4492Sdlw l_put(n, d) 268*4492Sdlw long *n; 269*4492Sdlw struct dfmt *d; 270*4492Sdlw { 271*4492Sdlw printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field)); 272*4492Sdlw return(d->df_size); 273*4492Sdlw } 274*4492Sdlw 275*4492Sdlw d_put(f, d) 276*4492Sdlw double *f; 277*4492Sdlw struct dfmt *d; 278*4492Sdlw { 279*4492Sdlw char fbuf[24]; 280*4492Sdlw sprintf(fbuf, "%21.14e", *f); 281*4492Sdlw printf(d->df_fmt, fbuf); 282*4492Sdlw return(d->df_size); 283*4492Sdlw } 284*4492Sdlw 285*4492Sdlw f_put(f, d) 286*4492Sdlw float *f; 287*4492Sdlw struct dfmt *d; 288*4492Sdlw { 289*4492Sdlw char fbuf[16]; 290*4492Sdlw sprintf(fbuf, "%14.7e", *f); 291*4492Sdlw printf(d->df_fmt, fbuf); 292*4492Sdlw return(d->df_size); 293*4492Sdlw } 294*4492Sdlw 295*4492Sdlw 296*4492Sdlw char asc_name[34][4] = { 297*4492Sdlw "nul", 298*4492Sdlw "soh", 299*4492Sdlw "stx", 300*4492Sdlw "etx", 301*4492Sdlw "eot", 302*4492Sdlw "enq", 303*4492Sdlw "ack", 304*4492Sdlw "bel", 305*4492Sdlw " bs", 306*4492Sdlw " ht", 307*4492Sdlw " nl", 308*4492Sdlw " vt", 309*4492Sdlw " ff", 310*4492Sdlw " cr", 311*4492Sdlw " so", 312*4492Sdlw " si", 313*4492Sdlw "dle", 314*4492Sdlw "dc1", 315*4492Sdlw "dc2", 316*4492Sdlw "dc3", 317*4492Sdlw "dc4", 318*4492Sdlw "nak", 319*4492Sdlw "syn", 320*4492Sdlw "etb", 321*4492Sdlw "can", 322*4492Sdlw " em", 323*4492Sdlw "sub", 324*4492Sdlw "esc", 325*4492Sdlw " fs", 326*4492Sdlw " gs", 327*4492Sdlw " rs", 328*4492Sdlw " us", 329*4492Sdlw " sp", 330*4492Sdlw "del" 331*4492Sdlw }; 332*4492Sdlw 333*4492Sdlw a_put(cc, d) 334*4492Sdlw char *cc; 335*4492Sdlw struct dfmt *d; 336*4492Sdlw { 337*4492Sdlw int c = *cc; 338*4492Sdlw register char *s = " "; 339*4492Sdlw register pbit = parity((int)c & 0377); 340*4492Sdlw 341*4492Sdlw c &= 0177; 342*4492Sdlw if (c > ' ' && c < 0177) 343*4492Sdlw { 344*4492Sdlw s[2] = *cc; 345*4492Sdlw if (pbit == _parity) 346*4492Sdlw printf(d->df_fmt, underline(s, 1)); 347*4492Sdlw else 348*4492Sdlw printf(d->df_fmt, s); 349*4492Sdlw } 350*4492Sdlw else 351*4492Sdlw { 352*4492Sdlw if (c == 0177) 353*4492Sdlw c = ' ' + 1; 354*4492Sdlw if (pbit == _parity) 355*4492Sdlw printf(d->df_fmt, underline(asc_name[c], 3)); 356*4492Sdlw else 357*4492Sdlw printf(d->df_fmt, asc_name[c]); 358*4492Sdlw } 359*4492Sdlw return(1); 360*4492Sdlw } 361*4492Sdlw 362*4492Sdlw parity(word) 363*4492Sdlw int word; 364*4492Sdlw { 365*4492Sdlw register int p = 0; 366*4492Sdlw register int w = word; 367*4492Sdlw 368*4492Sdlw if (w) 369*4492Sdlw do { 370*4492Sdlw p ^= 1; 371*4492Sdlw } while(w &= (~(-w))); 372*4492Sdlw return (p? ODD:EVEN); 373*4492Sdlw } 374*4492Sdlw 375*4492Sdlw char * 376*4492Sdlw underline(s, n) 377*4492Sdlw char *s; 378*4492Sdlw int n; 379*4492Sdlw { 380*4492Sdlw static char ulbuf[16]; 381*4492Sdlw register char *u = ulbuf; 382*4492Sdlw 383*4492Sdlw while (n--) { 384*4492Sdlw if (*s && *s != ' ') { 385*4492Sdlw *u++ = '_'; 386*4492Sdlw *u++ = '\b'; 387*4492Sdlw } 388*4492Sdlw *u++ = *s++; 389*4492Sdlw } 390*4492Sdlw *u = '\0'; 391*4492Sdlw return(ulbuf); 392*4492Sdlw } 393*4492Sdlw 394*4492Sdlw b_put(b, d) 395*4492Sdlw char *b; 396*4492Sdlw struct dfmt *d; 397*4492Sdlw { 398*4492Sdlw printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); 399*4492Sdlw return(1); 400*4492Sdlw } 401*4492Sdlw 402*4492Sdlw c_put(cc, d) 403*4492Sdlw char *cc; 404*4492Sdlw struct dfmt *d; 405*4492Sdlw { 406*4492Sdlw int c = *cc & 0377; 407*4492Sdlw register char *s = " "; 408*4492Sdlw 409*4492Sdlw if(c>037 && c<0177) { 410*4492Sdlw s[2] = *cc; 411*4492Sdlw printf(d->df_fmt, s); 412*4492Sdlw return(1); 413*4492Sdlw } 414*4492Sdlw 415*4492Sdlw switch(c) { 416*4492Sdlw case '\0': 417*4492Sdlw s = " \\0"; 418*4492Sdlw break; 419*4492Sdlw case '\b': 420*4492Sdlw s = " \\b"; 421*4492Sdlw break; 422*4492Sdlw case '\f': 423*4492Sdlw s = " \\f"; 424*4492Sdlw break; 425*4492Sdlw case '\n': 426*4492Sdlw s = " \\n"; 427*4492Sdlw break; 428*4492Sdlw case '\r': 429*4492Sdlw s = " \\r"; 430*4492Sdlw break; 431*4492Sdlw case '\t': 432*4492Sdlw s = " \\t"; 433*4492Sdlw break; 434*4492Sdlw default: 435*4492Sdlw s = icvt((long)c, d->df_radix, d->df_signed, d->df_field); 436*4492Sdlw } 437*4492Sdlw printf(d->df_fmt, s); 438*4492Sdlw return(1); 439*4492Sdlw } 440*4492Sdlw 441*4492Sdlw /* 442*4492Sdlw * integer to ascii conversion 443*4492Sdlw * 444*4492Sdlw * This code has been rearranged to produce optimized runtime code. 445*4492Sdlw */ 446*4492Sdlw 447*4492Sdlw #define MAXINTLENGTH 32 448*4492Sdlw static char _digit[] = "0123456789abcdef"; 449*4492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 450*4492Sdlw static long _mask = 0x7fffffff; 451*4492Sdlw 452*4492Sdlw char * 453*4492Sdlw icvt (value, radix, signed, ndigits) 454*4492Sdlw long value; 455*4492Sdlw int radix; 456*4492Sdlw int signed; 457*4492Sdlw int ndigits; 458*4492Sdlw { 459*4492Sdlw register long val = value; 460*4492Sdlw register long rad = radix; 461*4492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 462*4492Sdlw register char *d = _digit; 463*4492Sdlw register long tmp1; 464*4492Sdlw register long tmp2; 465*4492Sdlw long rem; 466*4492Sdlw long kludge; 467*4492Sdlw int sign; 468*4492Sdlw 469*4492Sdlw if (val == 0) 470*4492Sdlw { 471*4492Sdlw *--b = '0'; 472*4492Sdlw sign = 0; 473*4492Sdlw goto done; /*return(b);*/ 474*4492Sdlw } 475*4492Sdlw 476*4492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 477*4492Sdlw { 478*4492Sdlw /* 479*4492Sdlw * It is necessary to do the first divide 480*4492Sdlw * before the absolute value, for the case -2^31 481*4492Sdlw * 482*4492Sdlw * This is actually what is being done... 483*4492Sdlw * tmp1 = (int)(val % rad); 484*4492Sdlw * val /= rad; 485*4492Sdlw * val = -val 486*4492Sdlw * *--b = d[-tmp1]; 487*4492Sdlw */ 488*4492Sdlw tmp1 = val / rad; 489*4492Sdlw *--b = d[(tmp1 * rad) - val]; 490*4492Sdlw val = -tmp1; 491*4492Sdlw } 492*4492Sdlw else /* unsigned conversion */ 493*4492Sdlw { 494*4492Sdlw sign = 0; 495*4492Sdlw if (val < 0) 496*4492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 497*4492Sdlw kludge = _mask - (rad - 1); 498*4492Sdlw val &= _mask; 499*4492Sdlw /* 500*4492Sdlw * This is really what's being done... 501*4492Sdlw * rem = (kludge % rad) + (val % rad); 502*4492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 503*4492Sdlw * *--b = d[rem % rad]; 504*4492Sdlw */ 505*4492Sdlw tmp1 = kludge / rad; 506*4492Sdlw tmp2 = val / rad; 507*4492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 508*4492Sdlw val = ++tmp1 + tmp2; 509*4492Sdlw tmp1 = rem / rad; 510*4492Sdlw val += tmp1; 511*4492Sdlw *--b = d[rem - (tmp1 * rad)]; 512*4492Sdlw } 513*4492Sdlw } 514*4492Sdlw 515*4492Sdlw while (val) 516*4492Sdlw { 517*4492Sdlw /* 518*4492Sdlw * This is really what's being done ... 519*4492Sdlw * *--b = d[val % rad]; 520*4492Sdlw * val /= rad; 521*4492Sdlw */ 522*4492Sdlw tmp1 = val / rad; 523*4492Sdlw *--b = d[val - (tmp1 * rad)]; 524*4492Sdlw val = tmp1; 525*4492Sdlw } 526*4492Sdlw 527*4492Sdlw done: 528*4492Sdlw if (sign) 529*4492Sdlw *--b = '-'; 530*4492Sdlw 531*4492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 532*4492Sdlw tmp2 = signed? ' ':'0'; 533*4492Sdlw while (tmp1 > 0) 534*4492Sdlw { 535*4492Sdlw *--b = tmp2; 536*4492Sdlw tmp1--; 537*4492Sdlw } 538*4492Sdlw 539*4492Sdlw return(b); 540*4492Sdlw } 541*4492Sdlw 542*4492Sdlw offset(s) 543*4492Sdlw register char *s; 544*4492Sdlw { 545*4492Sdlw register char *p; 546*4492Sdlw long a; 547*4492Sdlw register int d; 548*4492Sdlw 549*4492Sdlw if (*s=='+') 550*4492Sdlw s++; 551*4492Sdlw if (*s=='x') { 552*4492Sdlw s++; 553*4492Sdlw addr_base = 16; 554*4492Sdlw } else if (*s=='0' && s[1]=='x') { 555*4492Sdlw s += 2; 556*4492Sdlw addr_base = 16; 557*4492Sdlw } else if (*s == '0') 558*4492Sdlw addr_base = 8; 559*4492Sdlw p = s; 560*4492Sdlw while(*p) { 561*4492Sdlw if (*p++=='.') 562*4492Sdlw addr_base = 10; 563*4492Sdlw } 564*4492Sdlw for (a=0; *s; s++) { 565*4492Sdlw d = *s; 566*4492Sdlw if(d>='0' && d<='9') 567*4492Sdlw a = a*addr_base + d - '0'; 568*4492Sdlw else if (d>='a' && d<='f' && addr_base==16) 569*4492Sdlw a = a*addr_base + d + 10 - 'a'; 570*4492Sdlw else 571*4492Sdlw break; 572*4492Sdlw } 573*4492Sdlw if (*s == '.') 574*4492Sdlw s++; 575*4492Sdlw if(*s=='b' || *s=='B') 576*4492Sdlw a *= 512; 577*4492Sdlw if (canseek(stdin)) 578*4492Sdlw fseek(stdin, a, 0); 579*4492Sdlw else 580*4492Sdlw dumbseek(stdin, a); 581*4492Sdlw addr = a; 582*4492Sdlw } 583*4492Sdlw 584*4492Sdlw dumbseek(s, offset) 585*4492Sdlw FILE *s; 586*4492Sdlw long offset; 587*4492Sdlw { 588*4492Sdlw char buf[BUFSIZ]; 589*4492Sdlw int n; 590*4492Sdlw int nr; 591*4492Sdlw 592*4492Sdlw while (offset > 0) 593*4492Sdlw { 594*4492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 595*4492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 596*4492Sdlw { 597*4492Sdlw fprintf(stderr, "EOF\n"); 598*4492Sdlw exit(1); 599*4492Sdlw } 600*4492Sdlw offset -= n; 601*4492Sdlw } 602*4492Sdlw } 603*4492Sdlw 604*4492Sdlw #include <sys/types.h> 605*4492Sdlw #include <sys/stat.h> 606*4492Sdlw 607*4492Sdlw canseek(f) 608*4492Sdlw FILE *f; 609*4492Sdlw { 610*4492Sdlw struct stat statb; 611*4492Sdlw 612*4492Sdlw return( (fstat(fileno(f),&statb)==0) && 613*4492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 614*4492Sdlw (!isatty(fileno(f))) ); 615*4492Sdlw } 616