|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)display.c 5.10 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include <sys/param.h> ! 25: #include <sys/stat.h> ! 26: #include <unistd.h> ! 27: #include <errno.h> ! 28: #include <ctype.h> ! 29: #include <stdio.h> ! 30: #include <string.h> ! 31: #include "hexdump.h" ! 32: ! 33: enum _vflag vflag = FIRST; ! 34: ! 35: static off_t address; /* address/offset in stream */ ! 36: static off_t eaddress; /* end address */ ! 37: static off_t savaddress; /* saved address/offset in stream */ ! 38: ! 39: #define PRINT { \ ! 40: switch(pr->flags) { \ ! 41: case F_ADDRESS: \ ! 42: (void)printf(pr->fmt, address); \ ! 43: break; \ ! 44: case F_BPAD: \ ! 45: (void)printf(pr->fmt, ""); \ ! 46: break; \ ! 47: case F_C: \ ! 48: conv_c(pr, bp); \ ! 49: break; \ ! 50: case F_CHAR: \ ! 51: (void)printf(pr->fmt, *bp); \ ! 52: break; \ ! 53: case F_DBL: { \ ! 54: double dval; \ ! 55: float fval; \ ! 56: switch(pr->bcnt) { \ ! 57: case 4: \ ! 58: bcopy((char *)bp, (char *)&fval, sizeof(fval)); \ ! 59: (void)printf(pr->fmt, fval); \ ! 60: break; \ ! 61: case 8: \ ! 62: bcopy((char *)bp, (char *)&dval, sizeof(dval)); \ ! 63: (void)printf(pr->fmt, dval); \ ! 64: break; \ ! 65: } \ ! 66: break; \ ! 67: } \ ! 68: case F_INT: { \ ! 69: int ival; \ ! 70: short sval; \ ! 71: switch(pr->bcnt) { \ ! 72: case 1: \ ! 73: (void)printf(pr->fmt, (int)*bp); \ ! 74: break; \ ! 75: case 2: \ ! 76: bcopy((char *)bp, (char *)&sval, sizeof(sval)); \ ! 77: (void)printf(pr->fmt, (int)sval); \ ! 78: break; \ ! 79: case 4: \ ! 80: bcopy((char *)bp, (char *)&ival, sizeof(ival)); \ ! 81: (void)printf(pr->fmt, ival); \ ! 82: break; \ ! 83: } \ ! 84: break; \ ! 85: } \ ! 86: case F_P: \ ! 87: (void)printf(pr->fmt, isprint(*bp) ? *bp : '.'); \ ! 88: break; \ ! 89: case F_STR: \ ! 90: (void)printf(pr->fmt, (char *)bp); \ ! 91: break; \ ! 92: case F_TEXT: \ ! 93: (void)printf(pr->fmt); \ ! 94: break; \ ! 95: case F_U: \ ! 96: conv_u(pr, bp); \ ! 97: break; \ ! 98: case F_UINT: { \ ! 99: u_int ival; \ ! 100: u_short sval; \ ! 101: switch(pr->bcnt) { \ ! 102: case 1: \ ! 103: (void)printf(pr->fmt, (u_int)*bp); \ ! 104: break; \ ! 105: case 2: \ ! 106: bcopy((char *)bp, (char *)&sval, sizeof(sval)); \ ! 107: (void)printf(pr->fmt, (u_int)sval); \ ! 108: break; \ ! 109: case 4: \ ! 110: bcopy((char *)bp, (char *)&ival, sizeof(ival)); \ ! 111: (void)printf(pr->fmt, ival); \ ! 112: break; \ ! 113: } \ ! 114: break; \ ! 115: } \ ! 116: } \ ! 117: } ! 118: ! 119: display() ! 120: { ! 121: extern FU *endfu; ! 122: register FS *fs; ! 123: register FU *fu; ! 124: register PR *pr; ! 125: register int cnt; ! 126: register u_char *bp; ! 127: off_t saveaddress; ! 128: u_char savech, *savebp, *get(); ! 129: ! 130: while (bp = get()) ! 131: for (fs = fshead, savebp = bp, saveaddress = address; fs; ! 132: fs = fs->nextfs, bp = savebp, address = saveaddress) ! 133: for (fu = fs->nextfu; fu; fu = fu->nextfu) { ! 134: if (fu->flags&F_IGNORE) ! 135: break; ! 136: for (cnt = fu->reps; cnt; --cnt) ! 137: for (pr = fu->nextpr; pr; address += pr->bcnt, ! 138: bp += pr->bcnt, pr = pr->nextpr) { ! 139: if (eaddress && address >= eaddress && ! 140: !(pr->flags&(F_TEXT|F_BPAD))) ! 141: bpad(pr); ! 142: if (cnt == 1 && pr->nospace) { ! 143: savech = *pr->nospace; ! 144: *pr->nospace = '\0'; ! 145: } ! 146: PRINT; ! 147: if (cnt == 1 && pr->nospace) ! 148: *pr->nospace = savech; ! 149: } ! 150: } ! 151: if (endfu) { ! 152: /* ! 153: * if eaddress not set, error or file size was multiple of ! 154: * blocksize, and no partial block ever found. ! 155: */ ! 156: if (!eaddress) { ! 157: if (!address) ! 158: return; ! 159: eaddress = address; ! 160: } ! 161: for (pr = endfu->nextpr; pr; pr = pr->nextpr) ! 162: switch(pr->flags) { ! 163: case F_ADDRESS: ! 164: (void)printf(pr->fmt, eaddress); ! 165: break; ! 166: case F_TEXT: ! 167: (void)printf(pr->fmt); ! 168: break; ! 169: } ! 170: } ! 171: } ! 172: ! 173: bpad(pr) ! 174: PR *pr; ! 175: { ! 176: static char *spec = " -0+#"; ! 177: register char *p1, *p2; ! 178: ! 179: /* ! 180: * remove all conversion flags; '-' is the only one valid ! 181: * with %s, and it's not useful here. ! 182: */ ! 183: pr->flags = F_BPAD; ! 184: *pr->cchar = 's'; ! 185: for (p1 = pr->fmt; *p1 != '%'; ++p1); ! 186: for (p2 = ++p1; *p1 && index(spec, *p1); ++p1); ! 187: while (*p2++ = *p1++); ! 188: } ! 189: ! 190: static char **_argv; ! 191: ! 192: u_char * ! 193: get() ! 194: { ! 195: extern enum _vflag vflag; ! 196: extern int length; ! 197: static int ateof = 1; ! 198: static u_char *curp, *savp; ! 199: register int n; ! 200: int need, nread; ! 201: u_char *tmpp; ! 202: ! 203: if (!curp) { ! 204: curp = (u_char *)emalloc(blocksize); ! 205: savp = (u_char *)emalloc(blocksize); ! 206: } else { ! 207: tmpp = curp; ! 208: curp = savp; ! 209: savp = tmpp; ! 210: address = savaddress += blocksize; ! 211: } ! 212: for (need = blocksize, nread = 0;;) { ! 213: /* ! 214: * if read the right number of bytes, or at EOF for one file, ! 215: * and no other files are available, zero-pad the rest of the ! 216: * block and set the end flag. ! 217: */ ! 218: if (!length || ateof && !next((char **)NULL)) { ! 219: if (need == blocksize) ! 220: return((u_char *)NULL); ! 221: if (vflag != ALL && !bcmp(curp, savp, nread)) { ! 222: if (vflag != DUP) ! 223: (void)printf("*\n"); ! 224: return((u_char *)NULL); ! 225: } ! 226: bzero((char *)curp + nread, need); ! 227: eaddress = address + nread; ! 228: return(curp); ! 229: } ! 230: n = fread((char *)curp + nread, sizeof(u_char), ! 231: length == -1 ? need : MIN(length, need), stdin); ! 232: if (!n) { ! 233: if (ferror(stdin)) ! 234: (void)fprintf(stderr, "hexdump: %s: %s\n", ! 235: _argv[-1], strerror(errno)); ! 236: ateof = 1; ! 237: continue; ! 238: } ! 239: ateof = 0; ! 240: if (length != -1) ! 241: length -= n; ! 242: if (!(need -= n)) { ! 243: if (vflag == ALL || vflag == FIRST || ! 244: bcmp(curp, savp, blocksize)) { ! 245: if (vflag == DUP || vflag == FIRST) ! 246: vflag = WAIT; ! 247: return(curp); ! 248: } ! 249: if (vflag == WAIT) ! 250: (void)printf("*\n"); ! 251: vflag = DUP; ! 252: address = savaddress += blocksize; ! 253: need = blocksize; ! 254: nread = 0; ! 255: } ! 256: else ! 257: nread += n; ! 258: } ! 259: } ! 260: ! 261: extern off_t skip; /* bytes to skip */ ! 262: ! 263: next(argv) ! 264: char **argv; ! 265: { ! 266: extern int errno, exitval; ! 267: static int done; ! 268: int statok; ! 269: ! 270: if (argv) { ! 271: _argv = argv; ! 272: return(1); ! 273: } ! 274: for (;;) { ! 275: if (*_argv) { ! 276: if (!(freopen(*_argv, "r", stdin))) { ! 277: (void)fprintf(stderr, "hexdump: %s: %s\n", ! 278: *_argv, strerror(errno)); ! 279: exitval = 1; ! 280: ++_argv; ! 281: continue; ! 282: } ! 283: statok = done = 1; ! 284: } else { ! 285: if (done++) ! 286: return(0); ! 287: statok = 0; ! 288: } ! 289: if (skip) ! 290: doskip(statok ? *_argv : "stdin", statok); ! 291: if (*_argv) ! 292: ++_argv; ! 293: if (!skip) ! 294: return(1); ! 295: } ! 296: /* NOTREACHED */ ! 297: } ! 298: ! 299: doskip(fname, statok) ! 300: char *fname; ! 301: int statok; ! 302: { ! 303: extern int errno; ! 304: struct stat sbuf; ! 305: ! 306: if (statok) { ! 307: if (fstat(fileno(stdin), &sbuf)) { ! 308: (void)fprintf(stderr, "hexdump: %s: %s.\n", ! 309: fname, strerror(errno)); ! 310: exit(1); ! 311: } ! 312: if (skip >= sbuf.st_size) { ! 313: skip -= sbuf.st_size; ! 314: address += sbuf.st_size; ! 315: return; ! 316: } ! 317: } ! 318: if (fseek(stdin, skip, SEEK_SET)) { ! 319: (void)fprintf(stderr, "hexdump: %s: %s.\n", ! 320: fname, strerror(errno)); ! 321: exit(1); ! 322: } ! 323: savaddress = address += skip; ! 324: skip = 0; ! 325: } ! 326: ! 327: char * ! 328: emalloc(size) ! 329: int size; ! 330: { ! 331: char *p, *malloc(); ! 332: ! 333: if (!(p = malloc((u_int)size))) ! 334: nomem(); ! 335: bzero(p, size); ! 336: return(p); ! 337: } ! 338: ! 339: nomem() ! 340: { ! 341: extern int errno; ! 342: ! 343: (void)fprintf(stderr, "hexdump: %s.\n", strerror(errno)); ! 344: exit(1); ! 345: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.