1*4500Sdlw static char *sccsid = "@(#)od.c 5.2 (Berkeley) 10/14/81"; 24492Sdlw /* 34492Sdlw * od -- octal, hex, decimal, character dump of data in a file. 44492Sdlw * 54492Sdlw * usage: od [-abcdDefFhHiIlLopPvxX] [file] [[+]offset[.][b]] 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 764492Sdlw char dbuf[16]; 774492Sdlw char lastdbuf[16]; 784492Sdlw int addr_base; 794492Sdlw long addr; 804492Sdlw int _parity = NO; 814492Sdlw char fmt[] = " %s"; /* 12 blanks */ 824492Sdlw char *icvt(); 834492Sdlw char *underline(); 844492Sdlw 854492Sdlw main(argc, argv) 864492Sdlw char **argv; 874492Sdlw { 884492Sdlw register char *p; 894492Sdlw register char *l; 904492Sdlw register n, same; 914492Sdlw struct dfmt *d; 924492Sdlw struct dfmt **cv = conv_vec; 934492Sdlw int showall = NO; 944492Sdlw int field, llen, nelm; 954492Sdlw int max_llen = 0; 964492Sdlw 974492Sdlw argv++; 984492Sdlw max_llen = max_nelm = 0; 994492Sdlw 1004492Sdlw if(argc > 1) { 1014492Sdlw p = *argv; 1024492Sdlw if(*p == '-') { 1034492Sdlw while(*++p != '\0') { 1044492Sdlw switch(*p) { 1054492Sdlw case 'a': 1064492Sdlw d = &ascii; 1074492Sdlw break; 1084492Sdlw case 'b': 1094492Sdlw d = &byte; 1104492Sdlw break; 1114492Sdlw case 'c': 1124492Sdlw d = &cchar; 1134492Sdlw break; 1144492Sdlw case 'd': 1154492Sdlw d = &u_s_dec; 1164492Sdlw break; 1174492Sdlw case 'D': 1184492Sdlw d = &u_l_dec; 1194492Sdlw break; 1204492Sdlw case 'e': 1214492Sdlw case 'F': 1224492Sdlw d = &dble; 1234492Sdlw break; 1244492Sdlw case 'f': 1254492Sdlw d = &flt; 1264492Sdlw break; 1274492Sdlw case 'h': 1284492Sdlw case 'x': 1294492Sdlw d = &u_s_hex; 1304492Sdlw break; 1314492Sdlw case 'H': 1324492Sdlw case 'X': 1334492Sdlw d = &u_l_hex; 1344492Sdlw break; 1354492Sdlw case 'i': 1364492Sdlw d = &s_s_dec; 1374492Sdlw break; 1384492Sdlw case 'I': 1394492Sdlw case 'l': 1404492Sdlw case 'L': 1414492Sdlw d = &s_l_dec; 1424492Sdlw break; 1434492Sdlw case 'o': 1444492Sdlw d = &u_s_oct; 1454492Sdlw break; 1464492Sdlw case 'O': 1474492Sdlw d = &u_l_oct; 1484492Sdlw break; 1494492Sdlw case 'p': 1504492Sdlw _parity = EVEN; 1514492Sdlw continue; 1524492Sdlw case 'P': 1534492Sdlw _parity = ODD; 1544492Sdlw continue; 1554492Sdlw case 'v': 1564492Sdlw showall = YES; 1574492Sdlw continue; 1584492Sdlw } 1594492Sdlw nelm = 16 / d->df_size; 1604492Sdlw llen = (d->df_field + 1) * nelm; 1614492Sdlw if (llen > max_llen) 1624492Sdlw max_llen = llen; 1634492Sdlw if (nelm > max_nelm) 1644492Sdlw max_nelm = nelm; 1654492Sdlw /* 1664492Sdlw * nelm will always be a power of 2. 1674492Sdlw * line length must always be multiple 1684492Sdlw * of max_nelm. 1694492Sdlw */ 1704492Sdlw nelm = max_nelm - 1; 1714492Sdlw max_llen = (max_llen + nelm) & (~nelm); 1724492Sdlw if (addr_base == 0) 1734492Sdlw addr_base = d->df_radix; 1744492Sdlw *(cv++) = d; 1754492Sdlw } 1764492Sdlw argc--; 1774492Sdlw argv++; 1784492Sdlw } 1794492Sdlw } 1804492Sdlw 1814492Sdlw if(cv == conv_vec) { 1824492Sdlw addr_base = 8; 1834492Sdlw *(cv++) = &u_s_oct; 1844492Sdlw max_llen = (16 / u_s_oct.df_size) * (u_s_oct.df_field + 1); 1854492Sdlw } 1864492Sdlw *cv = (struct dfmt *)0; 1874492Sdlw 1884492Sdlw cv = conv_vec; 1894492Sdlw while (d = *cv++) { 1904492Sdlw nelm = 16 / d->df_size; 1914492Sdlw field = max_llen / nelm; 1924492Sdlw d->df_fmt = fmt + 12 - (field - d->df_field); 1934492Sdlw } 1944492Sdlw 1954492Sdlw if(argc > 1 && **argv != '+') { 1964492Sdlw if (freopen(*argv, "r", stdin) == NULL) { 1974492Sdlw printf("od: cannot open %s\n", *argv); 1984492Sdlw exit(1); 1994492Sdlw } 2004492Sdlw argv++; 2014492Sdlw argc--; 2024492Sdlw } 2034492Sdlw 2044492Sdlw if (argc > 1) 2054492Sdlw offset(*argv); 2064492Sdlw 2074492Sdlw same = -1; 2084492Sdlw while ((n = fread(dbuf, 1, sizeof(dbuf), stdin)) > 0) { 2094492Sdlw if (same>=0 && strncmp(dbuf, lastdbuf, 16) == 0 && !showall) { 2104492Sdlw if (same==0) { 2114492Sdlw printf("*\n"); 2124492Sdlw same = 1; 2134492Sdlw } 2144492Sdlw } 2154492Sdlw else { 2164492Sdlw line(n); 2174492Sdlw same = 0; 2184492Sdlw p = dbuf; 2194492Sdlw l = lastdbuf; 2204492Sdlw for (nelm=0; nelm<16; nelm++) { 2214492Sdlw *l++ = *p; 2224492Sdlw *p++ = '\0'; 2234492Sdlw } 2244492Sdlw } 2254492Sdlw addr += n; 2264492Sdlw } 2274492Sdlw puts(icvt(addr, addr_base, UNSIGNED, 7)); 2284492Sdlw } 2294492Sdlw 2304492Sdlw line(n) 2314492Sdlw int n; 2324492Sdlw { 2334492Sdlw register i, first; 2344492Sdlw register struct dfmt *c; 2354492Sdlw register struct dfmt **cv = conv_vec; 2364492Sdlw 2374492Sdlw first = YES; 2384492Sdlw while (c = *cv++) { 2394492Sdlw if (first) { 2404492Sdlw printf("%s ", icvt(addr, addr_base, UNSIGNED, 7)); 2414492Sdlw first = NO; 2424492Sdlw } else 2434492Sdlw putchar('\t'); 2444492Sdlw i = 0; 2454492Sdlw while (i < n) 2464492Sdlw i += (*(c->df_put))(dbuf+i, c); 2474492Sdlw putchar('\n'); 2484492Sdlw } 2494492Sdlw } 2504492Sdlw 2514492Sdlw s_put(n, d) 2524492Sdlw short *n; 2534492Sdlw struct dfmt *d; 2544492Sdlw { 2554492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 2564492Sdlw return(d->df_size); 2574492Sdlw } 2584492Sdlw 2594492Sdlw us_put(n, d) 2604492Sdlw unsigned short *n; 2614492Sdlw struct dfmt *d; 2624492Sdlw { 2634492Sdlw printf(d->df_fmt, icvt((long)*n, d->df_radix, d->df_signed, d->df_field)); 2644492Sdlw return(d->df_size); 2654492Sdlw } 2664492Sdlw 2674492Sdlw l_put(n, d) 2684492Sdlw long *n; 2694492Sdlw struct dfmt *d; 2704492Sdlw { 2714492Sdlw printf(d->df_fmt, icvt(*n, d->df_radix, d->df_signed, d->df_field)); 2724492Sdlw return(d->df_size); 2734492Sdlw } 2744492Sdlw 2754492Sdlw d_put(f, d) 2764492Sdlw double *f; 2774492Sdlw struct dfmt *d; 2784492Sdlw { 2794492Sdlw char fbuf[24]; 280*4500Sdlw struct l { long n[2]; }; 281*4500Sdlw 282*4500Sdlw #if vax 283*4500Sdlw if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */ 284*4500Sdlw sprintf(fbuf, " %08x %08x", 285*4500Sdlw ((struct l *)f)->n[0], ((struct l *)f)->n[1]); 286*4500Sdlw else 287*4500Sdlw #endif 288*4500Sdlw 289*4500Sdlw sprintf(fbuf, "%21.14e", *f); 2904492Sdlw printf(d->df_fmt, fbuf); 2914492Sdlw return(d->df_size); 2924492Sdlw } 2934492Sdlw 2944492Sdlw f_put(f, d) 2954492Sdlw float *f; 2964492Sdlw struct dfmt *d; 2974492Sdlw { 2984492Sdlw char fbuf[16]; 299*4500Sdlw 300*4500Sdlw #if vax 301*4500Sdlw if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */ 302*4500Sdlw sprintf(fbuf, " %08x", *(long *)f); 303*4500Sdlw else 304*4500Sdlw #endif 305*4500Sdlw sprintf(fbuf, "%14.7e", *f); 3064492Sdlw printf(d->df_fmt, fbuf); 3074492Sdlw return(d->df_size); 3084492Sdlw } 3094492Sdlw 3104492Sdlw 3114492Sdlw char asc_name[34][4] = { 3124492Sdlw "nul", 3134492Sdlw "soh", 3144492Sdlw "stx", 3154492Sdlw "etx", 3164492Sdlw "eot", 3174492Sdlw "enq", 3184492Sdlw "ack", 3194492Sdlw "bel", 3204492Sdlw " bs", 3214492Sdlw " ht", 3224492Sdlw " nl", 3234492Sdlw " vt", 3244492Sdlw " ff", 3254492Sdlw " cr", 3264492Sdlw " so", 3274492Sdlw " si", 3284492Sdlw "dle", 3294492Sdlw "dc1", 3304492Sdlw "dc2", 3314492Sdlw "dc3", 3324492Sdlw "dc4", 3334492Sdlw "nak", 3344492Sdlw "syn", 3354492Sdlw "etb", 3364492Sdlw "can", 3374492Sdlw " em", 3384492Sdlw "sub", 3394492Sdlw "esc", 3404492Sdlw " fs", 3414492Sdlw " gs", 3424492Sdlw " rs", 3434492Sdlw " us", 3444492Sdlw " sp", 3454492Sdlw "del" 3464492Sdlw }; 3474492Sdlw 3484492Sdlw a_put(cc, d) 3494492Sdlw char *cc; 3504492Sdlw struct dfmt *d; 3514492Sdlw { 3524492Sdlw int c = *cc; 3534492Sdlw register char *s = " "; 3544492Sdlw register pbit = parity((int)c & 0377); 3554492Sdlw 3564492Sdlw c &= 0177; 3574492Sdlw if (c > ' ' && c < 0177) 3584492Sdlw { 3594492Sdlw s[2] = *cc; 3604492Sdlw if (pbit == _parity) 3614492Sdlw printf(d->df_fmt, underline(s, 1)); 3624492Sdlw else 3634492Sdlw printf(d->df_fmt, s); 3644492Sdlw } 3654492Sdlw else 3664492Sdlw { 3674492Sdlw if (c == 0177) 3684492Sdlw c = ' ' + 1; 3694492Sdlw if (pbit == _parity) 3704492Sdlw printf(d->df_fmt, underline(asc_name[c], 3)); 3714492Sdlw else 3724492Sdlw printf(d->df_fmt, asc_name[c]); 3734492Sdlw } 3744492Sdlw return(1); 3754492Sdlw } 3764492Sdlw 3774492Sdlw parity(word) 3784492Sdlw int word; 3794492Sdlw { 3804492Sdlw register int p = 0; 3814492Sdlw register int w = word; 3824492Sdlw 3834492Sdlw if (w) 3844492Sdlw do { 3854492Sdlw p ^= 1; 3864492Sdlw } while(w &= (~(-w))); 3874492Sdlw return (p? ODD:EVEN); 3884492Sdlw } 3894492Sdlw 3904492Sdlw char * 3914492Sdlw underline(s, n) 3924492Sdlw char *s; 3934492Sdlw int n; 3944492Sdlw { 3954492Sdlw static char ulbuf[16]; 3964492Sdlw register char *u = ulbuf; 3974492Sdlw 3984492Sdlw while (n--) { 3994492Sdlw if (*s && *s != ' ') { 4004492Sdlw *u++ = '_'; 4014492Sdlw *u++ = '\b'; 4024492Sdlw } 4034492Sdlw *u++ = *s++; 4044492Sdlw } 4054492Sdlw *u = '\0'; 4064492Sdlw return(ulbuf); 4074492Sdlw } 4084492Sdlw 4094492Sdlw b_put(b, d) 4104492Sdlw char *b; 4114492Sdlw struct dfmt *d; 4124492Sdlw { 4134492Sdlw printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); 4144492Sdlw return(1); 4154492Sdlw } 4164492Sdlw 4174492Sdlw c_put(cc, d) 4184492Sdlw char *cc; 4194492Sdlw struct dfmt *d; 4204492Sdlw { 4214492Sdlw int c = *cc & 0377; 4224492Sdlw register char *s = " "; 4234492Sdlw 4244492Sdlw if(c>037 && c<0177) { 4254492Sdlw s[2] = *cc; 4264492Sdlw printf(d->df_fmt, s); 4274492Sdlw return(1); 4284492Sdlw } 4294492Sdlw 4304492Sdlw switch(c) { 4314492Sdlw case '\0': 4324492Sdlw s = " \\0"; 4334492Sdlw break; 4344492Sdlw case '\b': 4354492Sdlw s = " \\b"; 4364492Sdlw break; 4374492Sdlw case '\f': 4384492Sdlw s = " \\f"; 4394492Sdlw break; 4404492Sdlw case '\n': 4414492Sdlw s = " \\n"; 4424492Sdlw break; 4434492Sdlw case '\r': 4444492Sdlw s = " \\r"; 4454492Sdlw break; 4464492Sdlw case '\t': 4474492Sdlw s = " \\t"; 4484492Sdlw break; 4494492Sdlw default: 4504492Sdlw s = icvt((long)c, d->df_radix, d->df_signed, d->df_field); 4514492Sdlw } 4524492Sdlw printf(d->df_fmt, s); 4534492Sdlw return(1); 4544492Sdlw } 4554492Sdlw 4564492Sdlw /* 4574492Sdlw * integer to ascii conversion 4584492Sdlw * 4594492Sdlw * This code has been rearranged to produce optimized runtime code. 4604492Sdlw */ 4614492Sdlw 4624492Sdlw #define MAXINTLENGTH 32 4634492Sdlw static char _digit[] = "0123456789abcdef"; 4644492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 4654492Sdlw static long _mask = 0x7fffffff; 4664492Sdlw 4674492Sdlw char * 4684492Sdlw icvt (value, radix, signed, ndigits) 4694492Sdlw long value; 4704492Sdlw int radix; 4714492Sdlw int signed; 4724492Sdlw int ndigits; 4734492Sdlw { 4744492Sdlw register long val = value; 4754492Sdlw register long rad = radix; 4764492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 4774492Sdlw register char *d = _digit; 4784492Sdlw register long tmp1; 4794492Sdlw register long tmp2; 4804492Sdlw long rem; 4814492Sdlw long kludge; 4824492Sdlw int sign; 4834492Sdlw 4844492Sdlw if (val == 0) 4854492Sdlw { 4864492Sdlw *--b = '0'; 4874492Sdlw sign = 0; 4884492Sdlw goto done; /*return(b);*/ 4894492Sdlw } 4904492Sdlw 4914492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 4924492Sdlw { 4934492Sdlw /* 4944492Sdlw * It is necessary to do the first divide 4954492Sdlw * before the absolute value, for the case -2^31 4964492Sdlw * 4974492Sdlw * This is actually what is being done... 4984492Sdlw * tmp1 = (int)(val % rad); 4994492Sdlw * val /= rad; 5004492Sdlw * val = -val 5014492Sdlw * *--b = d[-tmp1]; 5024492Sdlw */ 5034492Sdlw tmp1 = val / rad; 5044492Sdlw *--b = d[(tmp1 * rad) - val]; 5054492Sdlw val = -tmp1; 5064492Sdlw } 5074492Sdlw else /* unsigned conversion */ 5084492Sdlw { 5094492Sdlw sign = 0; 5104492Sdlw if (val < 0) 5114492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 5124492Sdlw kludge = _mask - (rad - 1); 5134492Sdlw val &= _mask; 5144492Sdlw /* 5154492Sdlw * This is really what's being done... 5164492Sdlw * rem = (kludge % rad) + (val % rad); 5174492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 5184492Sdlw * *--b = d[rem % rad]; 5194492Sdlw */ 5204492Sdlw tmp1 = kludge / rad; 5214492Sdlw tmp2 = val / rad; 5224492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 5234492Sdlw val = ++tmp1 + tmp2; 5244492Sdlw tmp1 = rem / rad; 5254492Sdlw val += tmp1; 5264492Sdlw *--b = d[rem - (tmp1 * rad)]; 5274492Sdlw } 5284492Sdlw } 5294492Sdlw 5304492Sdlw while (val) 5314492Sdlw { 5324492Sdlw /* 5334492Sdlw * This is really what's being done ... 5344492Sdlw * *--b = d[val % rad]; 5354492Sdlw * val /= rad; 5364492Sdlw */ 5374492Sdlw tmp1 = val / rad; 5384492Sdlw *--b = d[val - (tmp1 * rad)]; 5394492Sdlw val = tmp1; 5404492Sdlw } 5414492Sdlw 5424492Sdlw done: 5434492Sdlw if (sign) 5444492Sdlw *--b = '-'; 5454492Sdlw 5464492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 5474492Sdlw tmp2 = signed? ' ':'0'; 5484492Sdlw while (tmp1 > 0) 5494492Sdlw { 5504492Sdlw *--b = tmp2; 5514492Sdlw tmp1--; 5524492Sdlw } 5534492Sdlw 5544492Sdlw return(b); 5554492Sdlw } 5564492Sdlw 5574492Sdlw offset(s) 5584492Sdlw register char *s; 5594492Sdlw { 5604492Sdlw register char *p; 5614492Sdlw long a; 5624492Sdlw register int d; 5634492Sdlw 5644492Sdlw if (*s=='+') 5654492Sdlw s++; 5664492Sdlw if (*s=='x') { 5674492Sdlw s++; 5684492Sdlw addr_base = 16; 5694492Sdlw } else if (*s=='0' && s[1]=='x') { 5704492Sdlw s += 2; 5714492Sdlw addr_base = 16; 5724492Sdlw } else if (*s == '0') 5734492Sdlw addr_base = 8; 5744492Sdlw p = s; 5754492Sdlw while(*p) { 5764492Sdlw if (*p++=='.') 5774492Sdlw addr_base = 10; 5784492Sdlw } 5794492Sdlw for (a=0; *s; s++) { 5804492Sdlw d = *s; 5814492Sdlw if(d>='0' && d<='9') 5824492Sdlw a = a*addr_base + d - '0'; 5834492Sdlw else if (d>='a' && d<='f' && addr_base==16) 5844492Sdlw a = a*addr_base + d + 10 - 'a'; 5854492Sdlw else 5864492Sdlw break; 5874492Sdlw } 5884492Sdlw if (*s == '.') 5894492Sdlw s++; 5904492Sdlw if(*s=='b' || *s=='B') 5914492Sdlw a *= 512; 5924492Sdlw if (canseek(stdin)) 5934492Sdlw fseek(stdin, a, 0); 5944492Sdlw else 5954492Sdlw dumbseek(stdin, a); 5964492Sdlw addr = a; 5974492Sdlw } 5984492Sdlw 5994492Sdlw dumbseek(s, offset) 6004492Sdlw FILE *s; 6014492Sdlw long offset; 6024492Sdlw { 6034492Sdlw char buf[BUFSIZ]; 6044492Sdlw int n; 6054492Sdlw int nr; 6064492Sdlw 6074492Sdlw while (offset > 0) 6084492Sdlw { 6094492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 6104492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 6114492Sdlw { 6124492Sdlw fprintf(stderr, "EOF\n"); 6134492Sdlw exit(1); 6144492Sdlw } 6154492Sdlw offset -= n; 6164492Sdlw } 6174492Sdlw } 6184492Sdlw 6194492Sdlw #include <sys/types.h> 6204492Sdlw #include <sys/stat.h> 6214492Sdlw 6224492Sdlw canseek(f) 6234492Sdlw FILE *f; 6244492Sdlw { 6254492Sdlw struct stat statb; 6264492Sdlw 6274492Sdlw return( (fstat(fileno(f),&statb)==0) && 6284492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 6294492Sdlw (!isatty(fileno(f))) ); 6304492Sdlw } 631