1*4503Sdlw static char *sccsid = "@(#)od.c 5.3 (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]; 2804500Sdlw struct l { long n[2]; }; 2814500Sdlw 2824500Sdlw #if vax 2834500Sdlw if ((((struct l *)f)->n[0] & 0xff00) == 0x8000) /* Vax illegal f.p. */ 2844500Sdlw sprintf(fbuf, " %08x %08x", 2854500Sdlw ((struct l *)f)->n[0], ((struct l *)f)->n[1]); 2864500Sdlw else 2874500Sdlw #endif 2884500Sdlw 2894500Sdlw 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]; 2994500Sdlw 3004500Sdlw #if vax 3014500Sdlw if ((*(long *)f & 0xff00) == 0x8000) /* Vax illegal f.p. form */ 3024500Sdlw sprintf(fbuf, " %08x", *(long *)f); 3034500Sdlw else 3044500Sdlw #endif 3054500Sdlw 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) 361*4503Sdlw printf(d->df_fmt, underline(s)); 3624492Sdlw else 3634492Sdlw printf(d->df_fmt, s); 3644492Sdlw } 3654492Sdlw else 3664492Sdlw { 3674492Sdlw if (c == 0177) 3684492Sdlw c = ' ' + 1; 3694492Sdlw if (pbit == _parity) 370*4503Sdlw printf(d->df_fmt, underline(asc_name[c])); 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 * 391*4503Sdlw underline(s) 3924492Sdlw char *s; 3934492Sdlw { 3944492Sdlw static char ulbuf[16]; 3954492Sdlw register char *u = ulbuf; 3964492Sdlw 397*4503Sdlw while (*s) { 398*4503Sdlw if (*s != ' ') { 3994492Sdlw *u++ = '_'; 4004492Sdlw *u++ = '\b'; 4014492Sdlw } 4024492Sdlw *u++ = *s++; 4034492Sdlw } 4044492Sdlw *u = '\0'; 4054492Sdlw return(ulbuf); 4064492Sdlw } 4074492Sdlw 4084492Sdlw b_put(b, d) 4094492Sdlw char *b; 4104492Sdlw struct dfmt *d; 4114492Sdlw { 4124492Sdlw printf(d->df_fmt, icvt((long)*b & 0377, d->df_radix, d->df_signed, d->df_field)); 4134492Sdlw return(1); 4144492Sdlw } 4154492Sdlw 4164492Sdlw c_put(cc, d) 4174492Sdlw char *cc; 4184492Sdlw struct dfmt *d; 4194492Sdlw { 4204492Sdlw int c = *cc & 0377; 4214492Sdlw register char *s = " "; 4224492Sdlw 4234492Sdlw if(c>037 && c<0177) { 4244492Sdlw s[2] = *cc; 4254492Sdlw printf(d->df_fmt, s); 4264492Sdlw return(1); 4274492Sdlw } 4284492Sdlw 4294492Sdlw switch(c) { 4304492Sdlw case '\0': 4314492Sdlw s = " \\0"; 4324492Sdlw break; 4334492Sdlw case '\b': 4344492Sdlw s = " \\b"; 4354492Sdlw break; 4364492Sdlw case '\f': 4374492Sdlw s = " \\f"; 4384492Sdlw break; 4394492Sdlw case '\n': 4404492Sdlw s = " \\n"; 4414492Sdlw break; 4424492Sdlw case '\r': 4434492Sdlw s = " \\r"; 4444492Sdlw break; 4454492Sdlw case '\t': 4464492Sdlw s = " \\t"; 4474492Sdlw break; 4484492Sdlw default: 4494492Sdlw s = icvt((long)c, d->df_radix, d->df_signed, d->df_field); 4504492Sdlw } 4514492Sdlw printf(d->df_fmt, s); 4524492Sdlw return(1); 4534492Sdlw } 4544492Sdlw 4554492Sdlw /* 4564492Sdlw * integer to ascii conversion 4574492Sdlw * 4584492Sdlw * This code has been rearranged to produce optimized runtime code. 4594492Sdlw */ 4604492Sdlw 4614492Sdlw #define MAXINTLENGTH 32 4624492Sdlw static char _digit[] = "0123456789abcdef"; 4634492Sdlw static char _icv_buf[MAXINTLENGTH+1]; 4644492Sdlw static long _mask = 0x7fffffff; 4654492Sdlw 4664492Sdlw char * 4674492Sdlw icvt (value, radix, signed, ndigits) 4684492Sdlw long value; 4694492Sdlw int radix; 4704492Sdlw int signed; 4714492Sdlw int ndigits; 4724492Sdlw { 4734492Sdlw register long val = value; 4744492Sdlw register long rad = radix; 4754492Sdlw register char *b = &_icv_buf[MAXINTLENGTH]; 4764492Sdlw register char *d = _digit; 4774492Sdlw register long tmp1; 4784492Sdlw register long tmp2; 4794492Sdlw long rem; 4804492Sdlw long kludge; 4814492Sdlw int sign; 4824492Sdlw 4834492Sdlw if (val == 0) 4844492Sdlw { 4854492Sdlw *--b = '0'; 4864492Sdlw sign = 0; 4874492Sdlw goto done; /*return(b);*/ 4884492Sdlw } 4894492Sdlw 4904492Sdlw if (signed && (sign = (val < 0))) /* signed conversion */ 4914492Sdlw { 4924492Sdlw /* 4934492Sdlw * It is necessary to do the first divide 4944492Sdlw * before the absolute value, for the case -2^31 4954492Sdlw * 4964492Sdlw * This is actually what is being done... 4974492Sdlw * tmp1 = (int)(val % rad); 4984492Sdlw * val /= rad; 4994492Sdlw * val = -val 5004492Sdlw * *--b = d[-tmp1]; 5014492Sdlw */ 5024492Sdlw tmp1 = val / rad; 5034492Sdlw *--b = d[(tmp1 * rad) - val]; 5044492Sdlw val = -tmp1; 5054492Sdlw } 5064492Sdlw else /* unsigned conversion */ 5074492Sdlw { 5084492Sdlw sign = 0; 5094492Sdlw if (val < 0) 5104492Sdlw { /* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */ 5114492Sdlw kludge = _mask - (rad - 1); 5124492Sdlw val &= _mask; 5134492Sdlw /* 5144492Sdlw * This is really what's being done... 5154492Sdlw * rem = (kludge % rad) + (val % rad); 5164492Sdlw * val = (kludge / rad) + (val / rad) + (rem / rad) + 1; 5174492Sdlw * *--b = d[rem % rad]; 5184492Sdlw */ 5194492Sdlw tmp1 = kludge / rad; 5204492Sdlw tmp2 = val / rad; 5214492Sdlw rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad)); 5224492Sdlw val = ++tmp1 + tmp2; 5234492Sdlw tmp1 = rem / rad; 5244492Sdlw val += tmp1; 5254492Sdlw *--b = d[rem - (tmp1 * rad)]; 5264492Sdlw } 5274492Sdlw } 5284492Sdlw 5294492Sdlw while (val) 5304492Sdlw { 5314492Sdlw /* 5324492Sdlw * This is really what's being done ... 5334492Sdlw * *--b = d[val % rad]; 5344492Sdlw * val /= rad; 5354492Sdlw */ 5364492Sdlw tmp1 = val / rad; 5374492Sdlw *--b = d[val - (tmp1 * rad)]; 5384492Sdlw val = tmp1; 5394492Sdlw } 5404492Sdlw 5414492Sdlw done: 5424492Sdlw if (sign) 5434492Sdlw *--b = '-'; 5444492Sdlw 5454492Sdlw tmp1 = ndigits - (&_icv_buf[MAXINTLENGTH] - b); 5464492Sdlw tmp2 = signed? ' ':'0'; 5474492Sdlw while (tmp1 > 0) 5484492Sdlw { 5494492Sdlw *--b = tmp2; 5504492Sdlw tmp1--; 5514492Sdlw } 5524492Sdlw 5534492Sdlw return(b); 5544492Sdlw } 5554492Sdlw 5564492Sdlw offset(s) 5574492Sdlw register char *s; 5584492Sdlw { 5594492Sdlw register char *p; 5604492Sdlw long a; 5614492Sdlw register int d; 5624492Sdlw 5634492Sdlw if (*s=='+') 5644492Sdlw s++; 5654492Sdlw if (*s=='x') { 5664492Sdlw s++; 5674492Sdlw addr_base = 16; 5684492Sdlw } else if (*s=='0' && s[1]=='x') { 5694492Sdlw s += 2; 5704492Sdlw addr_base = 16; 5714492Sdlw } else if (*s == '0') 5724492Sdlw addr_base = 8; 5734492Sdlw p = s; 5744492Sdlw while(*p) { 5754492Sdlw if (*p++=='.') 5764492Sdlw addr_base = 10; 5774492Sdlw } 5784492Sdlw for (a=0; *s; s++) { 5794492Sdlw d = *s; 5804492Sdlw if(d>='0' && d<='9') 5814492Sdlw a = a*addr_base + d - '0'; 5824492Sdlw else if (d>='a' && d<='f' && addr_base==16) 5834492Sdlw a = a*addr_base + d + 10 - 'a'; 5844492Sdlw else 5854492Sdlw break; 5864492Sdlw } 5874492Sdlw if (*s == '.') 5884492Sdlw s++; 5894492Sdlw if(*s=='b' || *s=='B') 5904492Sdlw a *= 512; 5914492Sdlw if (canseek(stdin)) 5924492Sdlw fseek(stdin, a, 0); 5934492Sdlw else 5944492Sdlw dumbseek(stdin, a); 5954492Sdlw addr = a; 5964492Sdlw } 5974492Sdlw 5984492Sdlw dumbseek(s, offset) 5994492Sdlw FILE *s; 6004492Sdlw long offset; 6014492Sdlw { 6024492Sdlw char buf[BUFSIZ]; 6034492Sdlw int n; 6044492Sdlw int nr; 6054492Sdlw 6064492Sdlw while (offset > 0) 6074492Sdlw { 6084492Sdlw nr = (offset > BUFSIZ) ? BUFSIZ : (int)offset; 6094492Sdlw if ((n = fread(buf, 1, nr, s)) != nr) 6104492Sdlw { 6114492Sdlw fprintf(stderr, "EOF\n"); 6124492Sdlw exit(1); 6134492Sdlw } 6144492Sdlw offset -= n; 6154492Sdlw } 6164492Sdlw } 6174492Sdlw 6184492Sdlw #include <sys/types.h> 6194492Sdlw #include <sys/stat.h> 6204492Sdlw 6214492Sdlw canseek(f) 6224492Sdlw FILE *f; 6234492Sdlw { 6244492Sdlw struct stat statb; 6254492Sdlw 6264492Sdlw return( (fstat(fileno(f),&statb)==0) && 6274492Sdlw (statb.st_nlink > 0) && /*!pipe*/ 6284492Sdlw (!isatty(fileno(f))) ); 6294492Sdlw } 630