home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.2 / util-lin / util-linux-2.2 / text-utils / display.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  8.2 KB  |  365 lines

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