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: }

Defined functions

bpad defined in line 173; used 1 times
display defined in line 119; used 1 times
doskip defined in line 299; used 1 times
emalloc defined in line 327; used 7 times
get defined in line 192; used 2 times
next defined in line 263; used 2 times
nomem defined in line 339; used 3 times

Defined variables

_argv defined in line 190; used 9 times
address defined in line 35; used 12 times
eaddress defined in line 36; used 6 times
savaddress defined in line 37; used 3 times
sccsid defined in line 21; never used
vflag defined in line 33; used 10 times

Defined macros

PRINT defined in line 39; used 1 times
Last modified: 1990-06-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4085
Valid CSS Valid XHTML 1.0 Strict