Annotation of src/usr.bin/hexdump/display.c, Revision 1.10
1.10 ! millert 1: /* $OpenBSD: display.c,v 1.9 2001/12/30 08:17:32 pvalchev 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.
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.10 ! millert 39: static char rcsid[] = "$OpenBSD: display.c,v 1.9 2001/12/30 08:17:32 pvalchev 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.10 ! millert 60: static inline void print(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: }