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