File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #ifdef HAVE_CONFIG_H
0035 #include "config.h"
0036 #endif
0037
0038 #ifndef lint
0039 #if 0
0040 static char sccsid[] = "@(#)display.c 8.1 (Berkeley) 6/6/93";
0041 #endif
0042 #endif
0043 #if 0
0044 #include <sys/cdefs.h>
0045 __FBSDID("$FreeBSD: src/usr.bin/hexdump/display.c,v 1.22 2004/08/04 02:47:32 tjr Exp $");
0046 #endif
0047
0048 #include <sys/param.h>
0049 #include <sys/stat.h>
0050
0051 #include <stdint.h>
0052
0053 #include <ctype.h>
0054 #include "err.h"
0055 #include <errno.h>
0056 #include <stdio.h>
0057 #include <stdlib.h>
0058 #include <string.h>
0059 #include <unistd.h>
0060 #include "hexdump.h"
0061
0062 #define bcmp(s1,s2,sz) memcmp(s1,s2,sz)
0063 #define bcopy(s,d,sz) memcpy(d,s,sz)
0064 #define bzero(s,sz) memset(s,0,sz)
0065 #define index(s,c) strchr(s,c)
0066
0067 #if RTEMS_REMOVED
0068 enum _vflag vflag = FIRST;
0069
0070 static off_t address;
0071 static off_t eaddress;
0072 #endif
0073
0074 static void print(rtems_shell_hexdump_globals*, PR *, u_char *);
0075
0076 void
0077 display(rtems_shell_hexdump_globals* globals)
0078 {
0079 FS *fs;
0080 FU *fu;
0081 PR *pr;
0082 int cnt;
0083 u_char *bp;
0084 off_t saveaddress;
0085 u_char savech, *savebp;
0086
0087 savech = 0;
0088 while ((bp = get(globals)))
0089 for (fs = fshead, savebp = bp, saveaddress = address; fs;
0090 fs = fs->nextfs, bp = savebp, address = saveaddress)
0091 for (fu = fs->nextfu; fu; fu = fu->nextfu) {
0092 if (fu->flags&F_IGNORE)
0093 break;
0094 for (cnt = fu->reps; cnt; --cnt)
0095 for (pr = fu->nextpr; pr; address += pr->bcnt,
0096 bp += pr->bcnt, pr = pr->nextpr) {
0097 if (eaddress && address >= eaddress &&
0098 !(pr->flags & (F_TEXT|F_BPAD)))
0099 bpad(pr);
0100 if (cnt == 1 && pr->nospace) {
0101 savech = *pr->nospace;
0102 *pr->nospace = '\0';
0103 }
0104 print(globals, pr, bp);
0105 if (cnt == 1 && pr->nospace)
0106 *pr->nospace = savech;
0107 }
0108 }
0109 if (endfu) {
0110
0111
0112
0113
0114 if (!eaddress) {
0115 if (!address)
0116 return;
0117 eaddress = address;
0118 }
0119 for (pr = endfu->nextpr; pr; pr = pr->nextpr)
0120 switch(pr->flags) {
0121 case F_ADDRESS:
0122 (void)printf(pr->fmt, (quad_t)eaddress);
0123 break;
0124 case F_TEXT:
0125 (void)printf("%s", pr->fmt);
0126 break;
0127 }
0128 }
0129 }
0130
0131 static void
0132 print(rtems_shell_hexdump_globals* globals, PR *pr, u_char *bp)
0133 {
0134 long double ldbl;
0135 double f8;
0136 float f4;
0137 int16_t s2;
0138 int8_t s8;
0139 int32_t s4;
0140 u_int16_t u2;
0141 u_int32_t u4;
0142 u_int64_t u8;
0143
0144 switch(pr->flags) {
0145 case F_ADDRESS:
0146 (void)printf(pr->fmt, (quad_t)address);
0147 break;
0148 case F_BPAD:
0149 (void)printf(pr->fmt, "");
0150 break;
0151 case F_C:
0152 conv_c(globals, pr, bp, eaddress ? eaddress - address :
0153 blocksize - address % blocksize);
0154 break;
0155 case F_CHAR:
0156 (void)printf(pr->fmt, *bp);
0157 break;
0158 case F_DBL:
0159 switch(pr->bcnt) {
0160 case 4:
0161 bcopy(bp, &f4, sizeof(f4));
0162 (void)printf(pr->fmt, f4);
0163 break;
0164 case 8:
0165 bcopy(bp, &f8, sizeof(f8));
0166 (void)printf(pr->fmt, f8);
0167 break;
0168 default:
0169 if (pr->bcnt == sizeof(long double)) {
0170 bcopy(bp, &ldbl, sizeof(ldbl));
0171 (void)printf(pr->fmt, ldbl);
0172 }
0173 break;
0174 }
0175 break;
0176 case F_INT:
0177 switch(pr->bcnt) {
0178 case 1:
0179 (void)printf(pr->fmt, (quad_t)(signed char)*bp);
0180 break;
0181 case 2:
0182 bcopy(bp, &s2, sizeof(s2));
0183 (void)printf(pr->fmt, (quad_t)s2);
0184 break;
0185 case 4:
0186 bcopy(bp, &s4, sizeof(s4));
0187 (void)printf(pr->fmt, (quad_t)s4);
0188 break;
0189 case 8:
0190 bcopy(bp, &s8, sizeof(s8));
0191 (void)printf(pr->fmt, s8);
0192 break;
0193 }
0194 break;
0195 case F_P:
0196 (void)printf(pr->fmt, isprint(*bp) ? *bp : '.');
0197 break;
0198 case F_STR:
0199 (void)printf(pr->fmt, (char *)bp);
0200 break;
0201 case F_TEXT:
0202 (void)printf("%s", pr->fmt);
0203 break;
0204 case F_U:
0205 conv_u(globals, pr, bp);
0206 break;
0207 case F_UINT:
0208 switch(pr->bcnt) {
0209 case 1:
0210 (void)printf(pr->fmt, (u_quad_t)*bp);
0211 break;
0212 case 2:
0213 bcopy(bp, &u2, sizeof(u2));
0214 (void)printf(pr->fmt, (u_quad_t)u2);
0215 break;
0216 case 4:
0217 bcopy(bp, &u4, sizeof(u4));
0218 (void)printf(pr->fmt, (u_quad_t)u4);
0219 break;
0220 case 8:
0221 bcopy(bp, &u8, sizeof(u8));
0222 (void)printf(pr->fmt, u8);
0223 break;
0224 }
0225 break;
0226 }
0227 }
0228
0229 void
0230 bpad(PR *pr)
0231 {
0232 static char const *spec = " -0+#";
0233 char *p1, *p2;
0234
0235
0236
0237
0238
0239 pr->flags = F_BPAD;
0240 pr->cchar[0] = 's';
0241 pr->cchar[1] = '\0';
0242 for (p1 = pr->fmt; *p1 != '%'; ++p1);
0243 for (p2 = ++p1; *p1 && index(spec, *p1); ++p1);
0244 while ((*p2++ = *p1++));
0245 }
0246
0247 static char **_argv;
0248
0249 u_char *
0250 get(rtems_shell_hexdump_globals* globals)
0251 {
0252 #if RTEMS_REMOVED
0253 static int ateof = 1;
0254 static u_char *curp, *savp;
0255 #endif
0256 int n;
0257 int need, nread;
0258 int valid_save = 0;
0259 u_char *tmpp;
0260
0261 if (!curp) {
0262 if ((curp = calloc(1, blocksize)) == NULL)
0263 err(exit_jump, 1, NULL);
0264 if ((savp = calloc(1, blocksize)) == NULL)
0265 err(exit_jump, 1, NULL);
0266 } else {
0267 tmpp = curp;
0268 curp = savp;
0269 savp = tmpp;
0270 address += blocksize;
0271 valid_save = 1;
0272 }
0273 for (need = blocksize, nread = 0;;) {
0274
0275
0276
0277
0278
0279 if (!length || (ateof && !next(globals, (char **)NULL))) {
0280 if (odmode && address < skip)
0281 errx(exit_jump, 1, "cannot skip past end of input");
0282 if (need == blocksize)
0283 return((u_char *)NULL);
0284
0285
0286
0287
0288 if (vflag != ALL &&
0289 valid_save &&
0290 bcmp(curp, savp, nread) == 0) {
0291 if (vflag != DUP)
0292 (void)printf("*\n");
0293 return((u_char *)NULL);
0294 }
0295 bzero((char *)curp + nread, need);
0296 eaddress = address + nread;
0297 return(curp);
0298 }
0299 n = fread((char *)curp + nread, sizeof(u_char),
0300 length == -1 ? need : MIN(length, need), hdstdin);
0301 if (!n) {
0302 if (ferror(hdstdin))
0303 warn("%s", _argv[-1]);
0304 ateof = 1;
0305 continue;
0306 }
0307 ateof = 0;
0308 if (length != -1)
0309 length -= n;
0310 if (!(need -= n)) {
0311
0312
0313
0314
0315 if (vflag == ALL || vflag == FIRST ||
0316 valid_save == 0 ||
0317 bcmp(curp, savp, blocksize) != 0) {
0318 if (vflag == DUP || vflag == FIRST)
0319 vflag = WAIT;
0320 return(curp);
0321 }
0322 if (vflag == WAIT)
0323 (void)printf("*\n");
0324 vflag = DUP;
0325 address += blocksize;
0326 need = blocksize;
0327 nread = 0;
0328 }
0329 else
0330 nread += n;
0331 }
0332 }
0333
0334 size_t
0335 peek(rtems_shell_hexdump_globals* globals, u_char *buf, size_t nbytes)
0336 {
0337 size_t n, nread;
0338 int c;
0339
0340 if (length != -1 && nbytes > (unsigned int)length)
0341 nbytes = length;
0342 nread = 0;
0343 while (nread < nbytes && (c = getchar()) != EOF) {
0344 *buf++ = c;
0345 nread++;
0346 }
0347 n = nread;
0348 while (n-- > 0) {
0349 c = *--buf;
0350 ungetc(c, hdstdin);
0351 }
0352 return (nread);
0353 }
0354
0355 int
0356 next(rtems_shell_hexdump_globals* globals, char **argv)
0357 {
0358 #if RTEMS_REMOVED
0359 static int done;
0360 #endif
0361 int statok;
0362
0363 if (argv) {
0364 _argv = argv;
0365 return(1);
0366 }
0367 for (;;) {
0368 if (*_argv) {
0369 done = 1;
0370 if (!hdstdin) {
0371 hdstdin = malloc(sizeof(FILE));
0372 if (!hdstdin)
0373 {
0374 errno = ENOMEM;
0375 err(exit_jump, 1, "file name allocation");
0376 }
0377 memset (hdstdin, 0, sizeof(FILE));
0378 }
0379 if (!(hdstdin = freopen(*_argv, "r", hdstdin))) {
0380 warn("%s", *_argv);
0381 exitval = 1;
0382 ++_argv;
0383 continue;
0384 }
0385 statok = 1;
0386 } else {
0387 errno = ECANCELED;
0388 err(exit_jump, 1, "no file (stdin no supported)");
0389 if (done++)
0390 return(0);
0391 statok = 0;
0392 }
0393 if (skip)
0394 doskip(globals, statok ? *_argv : "stdin", statok);
0395 if (*_argv)
0396 ++_argv;
0397 if (!skip)
0398 return(1);
0399 }
0400
0401 }
0402
0403 void
0404 doskip(rtems_shell_hexdump_globals* globals, const char *fname, int statok)
0405 {
0406 int cnt;
0407 struct stat sb;
0408
0409 if (statok) {
0410 if (fstat(fileno(hdstdin), &sb))
0411 err(exit_jump, 1, "%s", fname);
0412
0413 if (0 && S_ISREG(sb.st_mode) && skip >= sb.st_size) {
0414 address += sb.st_size;
0415 skip -= sb.st_size;
0416 return;
0417 }
0418 if (1 || S_ISREG(sb.st_mode)) {
0419 if (fseeko(hdstdin, skip, SEEK_SET))
0420 err(exit_jump, 1, "%s", fname);
0421 address += skip;
0422 skip = 0;
0423 } else {
0424 for (cnt = 0; cnt < skip; ++cnt)
0425 if (getchar() == EOF)
0426 break;
0427 address += cnt;
0428 skip -= cnt;
0429 }
0430 }
0431 }