Annotation of src/usr.bin/hexdump/display.c, Revision 1.9
1.9 ! pvalchev 1: /* $OpenBSD: display.c,v 1.8 2001/11/19 19:02:14 mpech Exp $ */
! 2: /* $NetBSD: display.c,v 1.12 2001/12/07 15:14:29 bjh21 Exp $ */
1.3 deraadt 3:
1.1 deraadt 4: /*
1.9 ! pvalchev 5: * Copyright (c) 1989, 1993
! 6: * The Regents of the University of California. All rights reserved.
1.1 deraadt 7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: /*static char sccsid[] = "from: @(#)display.c 5.11 (Berkeley) 3/9/91";*/
1.9 ! pvalchev 39: static char rcsid[] = "$OpenBSD: display.c,v 1.8 2001/11/19 19:02:14 mpech Exp $";
1.1 deraadt 40: #endif /* not lint */
41:
42: #include <sys/param.h>
43: #include <sys/stat.h>
1.9 ! pvalchev 44:
! 45: #include <ctype.h>
! 46: #include <err.h>
1.1 deraadt 47: #include <errno.h>
48: #include <stdio.h>
49: #include <stdlib.h>
50: #include <string.h>
1.9 ! pvalchev 51: #include <unistd.h>
! 52:
1.1 deraadt 53: #include "hexdump.h"
54:
55: enum _vflag vflag = FIRST;
56:
57: static off_t address; /* address/offset in stream */
58: static off_t eaddress; /* end address */
59:
1.9 ! pvalchev 60: static inline void print __P((PR *, u_char *));
1.1 deraadt 61:
1.6 deraadt 62: void
1.1 deraadt 63: display()
64: {
1.8 mpech 65: FS *fs;
66: FU *fu;
67: PR *pr;
68: int cnt;
69: u_char *bp;
1.1 deraadt 70: off_t saveaddress;
1.9 ! pvalchev 71: u_char savech, *savebp;
1.1 deraadt 72:
1.9 ! pvalchev 73: savech = 0;
! 74: while ((bp = get()) != NULL)
1.1 deraadt 75: for (fs = fshead, savebp = bp, saveaddress = address; fs;
76: fs = fs->nextfs, bp = savebp, address = saveaddress)
77: for (fu = fs->nextfu; fu; fu = fu->nextfu) {
78: if (fu->flags&F_IGNORE)
79: break;
80: for (cnt = fu->reps; cnt; --cnt)
81: for (pr = fu->nextpr; pr; address += pr->bcnt,
82: bp += pr->bcnt, pr = pr->nextpr) {
83: if (eaddress && address >= eaddress &&
1.9 ! pvalchev 84: !(pr->flags & (F_TEXT|F_BPAD)))
1.1 deraadt 85: bpad(pr);
86: if (cnt == 1 && pr->nospace) {
87: savech = *pr->nospace;
88: *pr->nospace = '\0';
89: }
1.9 ! pvalchev 90: print(pr, bp);
1.1 deraadt 91: if (cnt == 1 && pr->nospace)
92: *pr->nospace = savech;
93: }
94: }
95: if (endfu) {
96: /*
1.9 ! pvalchev 97: * If eaddress not set, error or file size was multiple of
1.1 deraadt 98: * blocksize, and no partial block ever found.
99: */
100: if (!eaddress) {
101: if (!address)
102: return;
103: eaddress = address;
104: }
105: for (pr = endfu->nextpr; pr; pr = pr->nextpr)
106: switch(pr->flags) {
107: case F_ADDRESS:
1.9 ! pvalchev 108: (void)printf(pr->fmt, (quad_t)eaddress);
1.1 deraadt 109: break;
110: case F_TEXT:
1.9 ! pvalchev 111: (void)printf("%s", pr->fmt);
1.1 deraadt 112: break;
113: }
114: }
115: }
116:
1.9 ! pvalchev 117: static inline void
! 118: print(pr, bp)
! 119: PR *pr;
! 120: u_char *bp;
! 121: {
! 122: double f8;
! 123: float f4;
! 124: int16_t s2;
! 125: int32_t s4;
! 126: int64_t s8;
! 127: u_int16_t u2;
! 128: u_int32_t u4;
! 129: u_int64_t u8;
! 130:
! 131: switch(pr->flags) {
! 132: case F_ADDRESS:
! 133: (void)printf(pr->fmt, (quad_t)address);
! 134: break;
! 135: case F_BPAD:
! 136: (void)printf(pr->fmt, "");
! 137: break;
! 138: case F_C:
! 139: conv_c(pr, bp);
! 140: break;
! 141: case F_CHAR:
! 142: (void)printf(pr->fmt, *bp);
! 143: break;
! 144: case F_DBL:
! 145: switch(pr->bcnt) {
! 146: case 4:
! 147: memmove(&f4, bp, sizeof(f4));
! 148: (void)printf(pr->fmt, f4);
! 149: break;
! 150: case 8:
! 151: memmove(&f8, bp, sizeof(f8));
! 152: (void)printf(pr->fmt, f8);
! 153: break;
! 154: }
! 155: break;
! 156: case F_INT:
! 157: switch(pr->bcnt) {
! 158: case 1:
! 159: (void)printf(pr->fmt, (quad_t)*bp);
! 160: break;
! 161: case 2:
! 162: memmove(&s2, bp, sizeof(s2));
! 163: (void)printf(pr->fmt, (quad_t)s2);
! 164: break;
! 165: case 4:
! 166: memmove(&s4, bp, sizeof(s4));
! 167: (void)printf(pr->fmt, (quad_t)s4);
! 168: break;
! 169: case 8:
! 170: memmove(&s8, bp, sizeof(s8));
! 171: (void)printf(pr->fmt, s8);
! 172: break;
! 173: }
! 174: break;
! 175: case F_P:
! 176: (void)printf(pr->fmt, isprint(*bp) ? *bp : '.');
! 177: break;
! 178: case F_STR:
! 179: (void)printf(pr->fmt, (char *)bp);
! 180: break;
! 181: case F_TEXT:
! 182: (void)printf("%s", pr->fmt);
! 183: break;
! 184: case F_U:
! 185: conv_u(pr, bp);
! 186: break;
! 187: case F_UINT:
! 188: switch(pr->bcnt) {
! 189: case 1:
! 190: (void)printf(pr->fmt, (u_quad_t)*bp);
! 191: break;
! 192: case 2:
! 193: memmove(&u2, bp, sizeof(u2));
! 194: (void)printf(pr->fmt, (u_quad_t)u2);
! 195: break;
! 196: case 4:
! 197: memmove(&u4, bp, sizeof(u4));
! 198: (void)printf(pr->fmt, (u_quad_t)u4);
! 199: break;
! 200: case 8:
! 201: memmove(&u8, bp, sizeof(u8));
! 202: (void)printf(pr->fmt, u8);
! 203: break;
! 204: }
! 205: break;
! 206: }
! 207: }
! 208:
1.6 deraadt 209: void
1.1 deraadt 210: bpad(pr)
211: PR *pr;
212: {
1.9 ! pvalchev 213: static const char *spec = " -0+#";
1.8 mpech 214: char *p1, *p2;
1.1 deraadt 215:
216: /*
1.9 ! pvalchev 217: * Remove all conversion flags; '-' is the only one valid
1.1 deraadt 218: * with %s, and it's not useful here.
219: */
220: pr->flags = F_BPAD;
1.9 ! pvalchev 221: pr->cchar[0] = 's';
! 222: pr->cchar[1] = '\0';
1.1 deraadt 223: for (p1 = pr->fmt; *p1 != '%'; ++p1);
1.4 millert 224: for (p2 = ++p1; *p1 && strchr(spec, *p1); ++p1);
1.9 ! pvalchev 225: while ((*p2++ = *p1++) != '\0');
1.1 deraadt 226: }
227:
228: static char **_argv;
229:
230: u_char *
231: get()
232: {
233: static int ateof = 1;
234: static u_char *curp, *savp;
1.8 mpech 235: int n;
1.1 deraadt 236: int need, nread;
237: u_char *tmpp;
238:
239: if (!curp) {
1.9 ! pvalchev 240: curp = emalloc(blocksize);
! 241: savp = emalloc(blocksize);
1.1 deraadt 242: } else {
243: tmpp = curp;
244: curp = savp;
245: savp = tmpp;
1.9 ! pvalchev 246: address += blocksize;
1.1 deraadt 247: }
248: for (need = blocksize, nread = 0;;) {
249: /*
250: * if read the right number of bytes, or at EOF for one file,
251: * and no other files are available, zero-pad the rest of the
252: * block and set the end flag.
253: */
1.9 ! pvalchev 254: if (!length || (ateof && !next(NULL))) {
1.1 deraadt 255: if (need == blocksize)
1.9 ! pvalchev 256: return(NULL);
! 257: if (!need && vflag != ALL &&
! 258: !memcmp(curp, savp, nread)) {
1.1 deraadt 259: if (vflag != DUP)
260: (void)printf("*\n");
1.9 ! pvalchev 261: return(NULL);
1.1 deraadt 262: }
1.9 ! pvalchev 263: memset((char *)curp + nread, 0, need);
1.1 deraadt 264: eaddress = address + nread;
265: return(curp);
266: }
267: n = fread((char *)curp + nread, sizeof(u_char),
268: length == -1 ? need : MIN(length, need), stdin);
269: if (!n) {
270: if (ferror(stdin))
1.7 mickey 271: warn("%s", _argv[-1]);
1.1 deraadt 272: ateof = 1;
273: continue;
274: }
275: ateof = 0;
276: if (length != -1)
277: length -= n;
278: if (!(need -= n)) {
1.9 ! pvalchev 279: if (vflag == ALL || vflag == FIRST ||
! 280: memcmp(curp, savp, blocksize)) {
1.1 deraadt 281: if (vflag == DUP || vflag == FIRST)
282: vflag = WAIT;
283: return(curp);
284: }
285: if (vflag == WAIT)
286: (void)printf("*\n");
287: vflag = DUP;
1.9 ! pvalchev 288: address += blocksize;
1.1 deraadt 289: need = blocksize;
290: nread = 0;
291: }
292: else
293: nread += n;
294: }
295: }
296:
1.6 deraadt 297: int
1.1 deraadt 298: next(argv)
299: char **argv;
300: {
301: static int done;
302: int statok;
303:
304: if (argv) {
305: _argv = argv;
306: return(1);
307: }
308: for (;;) {
309: if (*_argv) {
310: if (!(freopen(*_argv, "r", stdin))) {
1.7 mickey 311: warn("%s", *_argv);
1.1 deraadt 312: exitval = 1;
313: ++_argv;
314: continue;
315: }
316: statok = done = 1;
317: } else {
318: if (done++)
319: return(0);
320: statok = 0;
321: }
322: if (skip)
323: doskip(statok ? *_argv : "stdin", statok);
324: if (*_argv)
325: ++_argv;
326: if (!skip)
327: return(1);
328: }
329: /* NOTREACHED */
330: }
331:
1.6 deraadt 332: void
1.1 deraadt 333: doskip(fname, statok)
1.9 ! pvalchev 334: const char *fname;
1.1 deraadt 335: int statok;
336: {
1.9 ! pvalchev 337: int cnt;
! 338: struct stat sb;
1.1 deraadt 339:
340: if (statok) {
1.9 ! pvalchev 341: if (fstat(fileno(stdin), &sb))
! 342: err(1, "fstat %s", fname);
! 343: if (S_ISREG(sb.st_mode) && skip >= sb.st_size) {
! 344: address += sb.st_size;
! 345: skip -= sb.st_size;
1.1 deraadt 346: return;
347: }
348: }
1.9 ! pvalchev 349: if (S_ISREG(sb.st_mode)) {
! 350: if (fseek(stdin, skip, SEEK_SET))
! 351: err(1, "fseek %s", fname);
! 352: address += skip;
! 353: skip = 0;
! 354: } else {
! 355: for (cnt = 0; cnt < skip; ++cnt)
! 356: if (getchar() == EOF)
! 357: break;
! 358: address += cnt;
! 359: skip -= cnt;
! 360: }
1.1 deraadt 361: }
362:
1.9 ! pvalchev 363: void *
! 364: emalloc(allocsize)
! 365: int allocsize;
1.1 deraadt 366: {
1.9 ! pvalchev 367: void *p;
1.1 deraadt 368:
1.9 ! pvalchev 369: if ((p = malloc((u_int)allocsize)) == NULL)
! 370: nomem();
! 371: memset(p, 0, allocsize);
1.1 deraadt 372: return(p);
1.9 ! pvalchev 373: }
! 374:
! 375: void
! 376: nomem()
! 377: {
! 378: err(1, NULL);
1.1 deraadt 379: }