Annotation of 43BSDReno/usr.bin/hexdump/display.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.