[comp.sources.misc] v13i020: hd - hexadecimal dump V1.6

pjr@pyra.co.uk (Peter Ruczynski) (06/03/90)

Posting-number: Volume 13, Issue 20
Submitted-by: pjr@pyra.co.uk (Peter Ruczynski)
Archive-name: hd1.6/part01

[Warning to Xenix users:  rename this before installing]

Well, here is the next release of hd (od++ ;-)

There are lots of new goodies in this release but the most significant
change is that output can now be obtained in Octal, Decimal and Hex
(with or without leading zeros). Full details are given in the README
file.  All flags used for the previous release have been preserved.

Use and Enjoy.

Pete.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile Makefile.ztc README hd.1 hd.c hexprint.c
#   hexprint.h
# Wrapped by pjr@pyrrot on Thu May 31 23:15:06 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(389 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XHOME=/b2/pjr
XCC=cc
XSRC=.
XCFLAGS=-c -DH_OFFSETS -DH_COMPRESS
XCFILES=hd.c hexprint.c
XOBJ=hd.o hexprint.o
X
Xhd:	$(OBJ)
X	$(CC) $(OBJ) -o hd
X
Xinst:	hd
X	cp hd $(HOME)/bin
X
Xhd.o:		hd.c /usr/include/stdio.h /usr/include/sys/types.h\
X		/usr/include/sys/file.h /usr/include/sys/fcntl.h\
X		/usr/include/fcntl.h /usr/include/string.h hexprint.h
X
Xhexprint.o:	hexprint.c /usr/include/stdio.h hexprint.h
X
END_OF_FILE
if test 389 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'Makefile.ztc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile.ztc'\"
else
echo shar: Extracting \"'Makefile.ztc'\" \(457 characters\)
sed "s/^X//" >'Makefile.ztc' <<'END_OF_FILE'
XCC=ztc
XCFLAGS=-c -g -DATT -DH_OFFSETS -DH_COMPRESS
XCFILES=hd.c hexprint.c
XOBJ=hd.obj hexprint.obj
X
Xhd.exe:	$(OBJ)
X	$(CC) $(OBJ) cppts.lib
X
Xinst:	hd.exe
X	cp hd.exe c:\bin
X
Xdepend:
X	makedep $(I) $(CFILES)
X
Xhd.obj : c:\zortech\include\stdio.h c:\zortech\include\sys\types.h c:\zortech\include\string.h c:\zortech\include\fcntl.h hexprint.h hd.c
X	$(CC) $(CFLAGS) hd.c
Xhexprint.obj : c:\zortech\include\stdio.h hexprint.h hexprint.c
X	$(CC) $(CFLAGS) hexprint.c
X
END_OF_FILE
if test 457 -ne `wc -c <'Makefile.ztc'`; then
    echo shar: \"'Makefile.ztc'\" unpacked with wrong size!
fi
# end of 'Makefile.ztc'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(5079 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X			===========================
X			HD Hexadecimal Dump Program
X			===========================
X
XThis program came about because I was not satisfied with the output from
Xthe standard UNIX od utility. It is basically a case of personal preference
Xbut I hope that some people will find this useful and perhaps preferable
Xto od. It is not quite as flexible as od in that it can only output in hex
Xand ascii but it is more flexible than od in format and control of output.
X
XOne of the the main considerations when writing the hexprint routine was speed,
Xhence the offset printing and compression can be compiled out if the
Xappropriate flags are not defined, giving a faster but simpler dump routine.
XUnfortunately as a result the code is not pretty!
X
XPorting of the code to a MS_DOS environment took about 15 minutes (most of
Xwhich was spent looking for the correct compiler flags and include files) and
Xso can easily be used on considerably inferior systems without any problems.
XSee the changes section below for more details.
X
X
X - hd.c
X
XThis contains main, file open and close, argument processor and main block
Xformatting routine.
X
X - hexprint.c
X
XThe file hexprint.c contains a routine which can be used independantly
Xfrom the main hd program in the debugging of your own programs for outputing
Xareas of memory in a hexadecimal form.
X
XIt uses bcopy and bcmp or memcpy and memcmp routines depending on
Xwhether the ATT compilation flag is set or not. Specifying ATT causes bcopy
Xand bcmp to be used. Hence if compilation is being done on a machine running
Xan AT&T version of unix use the ATT flag.
X
XThe H_OFFSETS and H_COMPRESS compilation flags switch on offset
Xprinting and compression respectively, these need to be used in
Xconjunction with the hex_compression and offset_print flags which must
Xbe set to true in the main program or enclosing scope of the called
Xhexprint routine. The offset variable must be set each time the
Xhexprint routine is entered otherwise the offset numbering will always
Xstart at 0, so if you want to print out a number of buffers in
Xsuccession with continuous offset numbering you need to update the
Xoffset after each call of hexprint, with the size of the buffer last
Xpassed to hexprint.
X
XOmission of H_OFFSETS and H_COMPRESS means you can forget everything I just
Xsaid and just call the hexprint routine straight.
X
X - Changes since version 1.4 for version 1.6:
X
XA "-r" flag has been added which will print out a "ruler" line just
Xabove each block that is printed.  Note that blocking (-b n) must
Xbe enabled for this to happen, otherwise a single ruler will be printed
Xout at the start of the output.
X
XOutput may now be formatted in octal, decimal or hexadecimal for both
Xthe offset and the actual dump.  This is done by using the format
Xflag.  The flag takes the format of -f[f] where "ff" may be any
Xcombination of 't' (number zero),  'd', 'x' and '-'.
X
XThe single letter versions of the flag imply that offset and dump come
Xout in the same format.  The "-d" flag specifies dump output in
Xdecimal, "-t" flag specifies output in octal.  The default is of course
Xhexadecimal, this can be forced by "-x".
X
XPlacing a trailing '-' eg: "-d-" means that you wish the offsets to be
Xprinted in decimal and the dump in default format.  And "--d" says that
Xyou wish the offsets in default format and dump in decimal.
X
XCombining letters eg: "-td" means that you want the offset in octal and the
Xdump in decimal.
X
XSo, to be pedantic, "---" means use all defaults, which will be
Xequivalent to -x.
X
XThe flags may also be in upper case, this then means that each output
Xfield will have leading zeros printed.
X
XThe above formatting is controlled by the "fmt_" variables defined in
Xhexprint.c, the default values of which may be found in hexprint.h.
XThey are simply printf format strings for the offset, field and padding
Xstrings which were hard coded before.  You can of course tweak these if
Xyou want different output formats from the ones given.  The ruler also uses
Xthe field format to get its spacing correct.
X
XThere is also a way to override the fixed number of fields that are printed
Xon the screen (16 for hex, 10 for dec, 8 for oct). This is via the -l flag
Xand a suitable numeric value.  There is no checking for screen size so the
Xformatting is pretty much up to you.  The change is achieved by changing the
Xh_slen varaiable defined in hexprint.c
X
XThere is an extra makefile "Makefile.ztc" in this release.  This is a
Xmakefile for the MS DOS zortech c++ 2.0 compiler (I would imagine that
Xit will work with other versions of zortech c also).  There are NO
Xchanges which need to be made to any of the source files for hd to
Xcompile on dos under the zortech compiler.  Hence you can now have a
Xuniform dump program between dos and unix.
X
XAdded the -V flag to explicitly envoke verbose mode.  This has to be
Xenabled first (ie first on the cmd line) to get all the info about all
Xthe size type options selected.
X
XAlso added the r_len variable, this tells the print_rule routine which base
Xit is working in so that it can get the best format output for itself.
X
END_OF_FILE
if test 5079 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'hd.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hd.1'\"
else
echo shar: Extracting \"'hd.1'\" \(4309 characters\)
sed "s/^X//" >'hd.1' <<'END_OF_FILE'
X.TH HD 1 "FEB 16, 1990"
X.UC 4
X.SH NAME
Xhd \- hexadecimal dump
X.SH SYNOPSIS
X.B hd
X[
X.B \-cnorvV
X] [
X[
X.B \-fmt
X] [
X.B \-l n
X] [
X.B \-b n
X] [
X.B \-sp
X|
X.B \-sn n
X] [
X.B \-sb n
X] [
X.B \-eb n
X]
X.B filename
X.SH DESCRIPTION
X.PP
X.I hd
Xproduces a hex dump of the specified file or the data that is piped into it
Xfrom the standard input.
X.PP
XThe format of the dump is basically hex values on the left, in groups of 16
Xand corresponding ascii values on the right. Only printable ascii values are
Xprinted as themselves, all other ascii values are output as fullstops.
X.PP
XThere are various options to
X.I hd
Xwhich allow further formatting of the output, and control over the start and
Xend of the output.
X.PP
XNote that byte counting starts from 0; record (block) counting starts from
X1, after the start position which has been given (if any).
X.PP
XOptions:
X.TP
X.I \-c
X(compress): compresses similar lines to a single char, "*". The complete line
Xjust before the first char is the one which is repeated. This does not cross
Xblock boundaries.
X.TP
X.I \-n
X(numbering):
Xenables block numbering, each block will be labelled giving its number from
Xthe start of the file or the start block. The final block printed has its size
Xprinted also, if it is less than the specified or default block size.
XUsed without the \-b option causes 1024 byte blocks to be output.
X.TP
X.I \-o
X(offset): prints the offset within the file on the very left hand
Xside of the output.
X.TP
X.I \-r
X(ruler): prints a ruler across the top of each new block or at the start of the
Xoutput if blocking is not enabled.
X.TP
X.I \-v
X(version):
Xprint the version number of
X.I hd.
X.TP
X.I \-V
X(verbose): explicitly envoke verbose mode.  This has to be enabled
Xfirst (ie first on the cmd line) to get all the info about all the size
Xtype options selected.
X.TP
X.I \-fmt
X(format): this governs the output format of hd.  Output may be
Xformatted in octal, decimal or hexadecimal for both the offset and the
Xactual dump.  The flag takes the format of
X.B \-f[f]
Xwhere "ff" may be any combination of 't' 'd' 'x' and '\-'.
X
XThe single letter versions of the flag imply that offset and dump come
Xout in the same format.  The "\-d" flag specifies dump output in
Xdecimal, "\-t" flag specifies output in octal.  The default is
Xhexadecimal, this can also be forced by "\-x".
X
XPlacing a trailing'\-' eg: "\-d\-" means that the offsets are to be
Xprinted in decimal and the dump in default format.  "\-\-d" says that
Xthe offsets are to be printed in default format and dump in decimal.
XCombining letters eg: "\-td" means that the offset is to be printed in
Xoctal and the dump in decimal.
X
XSo, to be pedantic, "\-\-\-" means use all defaults, which is  equivalent
Xto \-x.
X
XThe flags may also be in upper case, this then means that each output
Xfield will have leading zeros printed.
X.TP
X.I \-l n
X(line size):
Xsets the number of fields on a line to
X.I n
X(where
X.I n
Xmay be
Xa decimal or C standard hexadecimal or octal number).
XNote that this overrides the fixed values for the various formats (8 for octal
X10 for decimal and 16 for hex) if it is specified after the \-fmt flag.
XUse of the flag without \-fmt results in a different number of fields in the
Xdefault output format.
X.TP
X.I \-b n
X(block size):
Xsets the block size to
X.I n
X(where
X.I n
Xmay be
Xa decimal or C standard hexadecimal or octal number).
XOmmision of this option will cause a continuous stream of output with no
Xbreaks unless the \-n option is used.
X.TP
X.I \-sp n
X(start posn, print):
Xthis causes any blocking options that have been specified to start after the
X.I n'th
Xbyte in the file, the first
X.I n
Xbytes are printed in one continuous block. This option takes precedence over
X.I \-sn.
X.TP
X.I \-sn n
X(start posn, no print):
Xoutput will commence starting after the
X.I n'th
Xbyte, the first
X.I n
Xbytes not being printed.
X.I n
Xmay be a decimal or C standard hexadecimal or octal number, and
Xis held as a long to allow starting deep in a file.
X.TP
X.I \-sb n
X(start block)
Xoutput will commence starting after the
X.I n'th
Xblock in the file.
X.TP
X.I \-eb n
X(end block)
Xoutput will cease after the 
X.I n'th
Xblock in the file.
X.SH SEE ALSO
Xfm by Tony Field.         tony@ajfcal
X.SH "AUTHOR"
XPeter Ruczynski		pjr@pyra.co.uk
X.br
X.SH "FUTURE ENHANCEMENTS"
X.PP
XStartup definitions file ".hdrc" and user defined formatting of output.
X
END_OF_FILE
if test 4309 -ne `wc -c <'hd.1'`; then
    echo shar: \"'hd.1'\" unpacked with wrong size!
fi
# end of 'hd.1'
fi
if test -f 'hd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hd.c'\"
else
echo shar: Extracting \"'hd.c'\" \(12336 characters\)
sed "s/^X//" >'hd.c' <<'END_OF_FILE'
X/******************************************************************************
X*
X*   Copyright P.J.Ruczynski 1990
X*   This software is free for redistribution and re-use as long as this
X*   copyright is included in all source files. This software is supplied
X*   as is and no responsibilty is taken by the author for any problems
X*   arising from this code.
X*
X* File name		-  hd.c
X*
X* Module name		-  HD
X*
X* Author		-  P.J.Ruczynski	<pjr@pyra.co.uk>
X*
X* Second Release	-  31 May 1990 (V1.6)
X* First Release		-  16 Feb 1990 (V1.4)
X*
X* Version number	-  1.6
X*
X* Description		-  A hexdump formatting tool, this can take input from
X*			   stdin or a file and print it to stdout in a neat
X*			   hexdump format.
X*			   Basically, a better/different(*) version of od.
X*
X*				(*) delete as you think appropriate :-)
X*
X*			Revision List
X*
X* pjr   08.05.89        Added offset numbering. 
X*
X* pjr   11.05.89        Added compressed output format. 
X*
X* pjr	30.05.89	Changed to allow any block size to be used, default
X*			is still 1024 though.
X*
X* pjr	31.05.89	Added version printing option.
X*
X* pjr	02.06.89	Added start and end block specification.
X*
X* pjr	30.03.90	Added ruler across top of blocks option
X*
X* pjr	15.05.90	Added octal and decimal output formatting.
X*					Also added variable line length output, ie can change
X*			h_slen from the command line.
X*
X* pjr	24.05.90	Added the -V flag to explicitly envoke verbose mode.
X*			This has to be enabled first (ie first on the cmd line) to get
X*			all the info about all the size type options selected.
X*
X******************************************************************************/
X
X#define VERSION		"1.6 (15.05.89)"
X#define PRINTUSAGE	fprintf(stderr,"Usage: %s [-cnorvV] [-fmt] [-l n] [-b n] [-sp|-sn n] [-sb n] [-eb n] [fname]\n", progname);
X
X/*
X * This file contains the following routines:
X *
X * get_options()
X * openfile()
X * closefile()
X * printfile
X * parse_fmt()
X * print_rule()
X * main()
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <string.h>
X#include <fcntl.h>
X#include "hexprint.h"
X
X#define	MAXLINE		256		/* Length of character strings. */
X#define	MAX_BUFSIZ	1024	/* default read bufer size */
X
X/*
X * these are control vars for the hexprint routine
X */
Xextern int offset_print;	/* only print offsets on request */
Xextern long offset;			/* default start offset for printing */
Xextern int hex_compression;	/* compress identical lines */
Xextern char *fmt_offset;	/* printf format for offsets */
Xextern char *fmt_dump;		/* printf format for the dump */
Xextern char *fmt_pad;		/* printf format for padding up to ascii */
Xextern int h_slen;			/* no of chars per line */
X
X
X/*
X * option variables
X */
Xchar progname[MAXLINE];			/* Name of this program. */
Xint b_start = 1;				/* start block no to be printed */
Xint b_end = 0;					/* end block no to be printed */
Xint b_size = MAX_BUFSIZ;		/* block size */
Xint blocking_on = FALSE;		/* only block up on request */
Xchar fname[MAXLINE];			/* name of input file (if any) */
Xint block_numbering = FALSE;	/* output number of each block ? */
Xint print_start_block = FALSE;	/* print the very first diff size block ? */
Xint print_ruler = FALSE;		/* print ruler across top of block */
Xint r_len=16;					/* info for ruler printing */
Xint sb_size = 0;				/* staring block size */
Xlong n_blocks = 0;				/* no blocks to print, 0 => all */
Xint verbose = FALSE;			/* print all the details ie block size etc */
X
X/*
X * get_options
X *
X * Read and process command line options.
X */
X/*****************************************************************************/
Xvoid get_options(argc,argv)
X/*****************************************************************************/
Xint argc;
Xchar *argv[];
X{
Xint i, leading_zero = FALSE;
X
X    fname[0] = 0;	/* indicate no filename input */
X    argc-- ; argv++ ;	/* skip the program name */
X
X    while (argc > 0)	/* now get the rest */
X    {
X      if (argv[0][0] == '-')
X	switch (argv[0][1])
X	{
X	case 'l' :	/* h_slen size, no of fields/chars per line */
X		argv++;
X		h_slen = (int)strtol(&argv[0][0], (char **)NULL, 0);
X		if (verbose)
X			printf("line length = %d (0x%x) fields\n",
X					h_slen,(unsigned)h_slen);
X		blocking_on = TRUE;
X		argc--;
X		break;
X	case '-' :				/* default, do nothing */
X		if (argv[0][2])
X			parse_fmt(argv[0][2]);
X		break;
X	case 'T' :				/* octal */
X		leading_zero = TRUE;
X	case 't' :				/* octal */
X		if (leading_zero)
X			fmt_offset = ZOCTALO;
X		else
X			fmt_offset = OCTALO;
X
X		if (argv[0][2])
X			parse_fmt(argv[0][2]);
X		else
X		{
X			if (leading_zero)
X				fmt_dump = ZOCTALD;
X			else
X				fmt_dump = OCTALD;
X
X			fmt_pad = OCTALP;
X			r_len = h_slen = 8;		/* no of dump fields */
X		}
X
X		break;
X	case 'D' :				/* decimal */
X		leading_zero = TRUE;
X	case 'd' :				/* decimal */
X		if (leading_zero)
X			fmt_offset = ZDECIMALO;
X		else
X			fmt_offset = DECIMALO;
X
X		if (argv[0][2])
X			parse_fmt(argv[0][2]);
X		else
X		{
X			if (leading_zero)
X				fmt_dump = ZDECIMALD;
X			else
X				fmt_dump = DECIMALD;
X
X			fmt_pad = DECIMALP;
X			r_len = h_slen = 10;
X		}
X
X		break;
X	case 'X' :				/* hexadecimal */
X		leading_zero = TRUE;
X	case 'x' :				/* hexadecimal */
X		if (leading_zero)
X			fmt_offset = ZHEXO;
X		else
X			fmt_offset = HEXO;
X
X		if (argv[0][2])
X			parse_fmt(argv[0][2]);
X		else
X		{
X			if (leading_zero)
X				fmt_dump = ZHEXD;
X			else
X				fmt_dump = HEXD;
X
X			fmt_pad = HEXP;
X			r_len = h_slen = H_SLEN;
X		}
X
X		break;
X	case 'b' :	/* block size to output */
X		argv++;
X		b_size = (int)strtol(&argv[0][0], (char **)NULL, 0);
X		if (verbose)
X			printf("block size = %d (0x%x) bytes\n",
X					b_size,(unsigned)b_size);
X		blocking_on = TRUE;
X		argc--;
X		break;
X	case 'c' :
X	case 'n' :
X	case 'o' :
X	case 'r' :
X	case 'v' :
X	case 'V' :
X		i = 1;
X		while (argv[0][i])
X		{
X			switch (argv[0][i])
X			{
X			case 'c' :	/* compress identical lines */
X				hex_compression = TRUE;
X				break;
X			case 'n' :	/* switch on block numbering */
X				block_numbering = TRUE;
X				blocking_on = TRUE;
X				break;
X			case 'o' :	/* switch on offset printing */
X				offset_print = TRUE;
X				break;
X			case 'r' :	/* switch on ruler */
X				print_ruler = TRUE;
X				break;
X			case 'v' :	/* print the version of this hd */
X				printf("%s version %s Author P.Ruczynski\n",
X						progname,VERSION);
X				break;
X			case 'V' :	/* verbose mode, ie print the block size etc.. */
X				verbose = TRUE;
X				break;
X			default : PRINTUSAGE
X				exit(1);
X			} /* end of switch */
X			i++;
X		} /* end of while */
X		break;
X	case 'e' :	/* end block options */
X		switch (argv[0][2])
X		{
X		case 'b' :	/* do not print starting block */
X			argv++;
X			b_end = strtol(&argv[0][0], (char **)NULL, 0);
X			if (verbose)
X				printf("last block printed = %d (0x%x) bytes\n",
X						b_end,(unsigned)b_end);
X			argc--;
X			break;
X		default: PRINTUSAGE
X			exit(1);
X		}
X		break;
X	case 's' :	/* starting block options */
X		switch (argv[0][2])
X		{
X		case 'p' :	/* print the starting block */
X			print_start_block = TRUE;
X			/* FALLTHROUGH */
X		case 'n' :	/* do not print starting block */
X			argv++;
X			sb_size = strtol(&argv[0][0], (char **)NULL, 0);
X			if (verbose)
X				printf("starting block size = %d (0x%x) bytes\n",
X						sb_size,(unsigned)sb_size);
X			argc--;
X			break;
X		case 'b' :	/* get the starting block number */
X			argv++;
X			b_start = strtol(&argv[0][0], (char **)NULL, 0);
X			if (verbose)
X				printf("first block printed = %d (0x%x)\n",
X						b_start,(unsigned)b_start);
X			argc--;
X			break;
X		default: PRINTUSAGE
X			exit(1);
X		}
X		break;
X	case '?' : /* FALLTHROUGH */
X	default  : PRINTUSAGE
X		exit(1);
X	} /* end of case */
X	else	/* not an option so must be file name */
X	{
X		strcpy(&fname[0], &argv[0][0]);
X		if (verbose)
X			printf("input file = %s\n",fname);
X	}
X
X	argc-- ;
X	argv++ ;
X
X    } /* end of while loop */
X
X} /* end of get_options */
X 
X
X/*
X * openfile
X *
X * open the requested file or assign stdin for reading
X */
X/*****************************************************************************/
Xint openfile(fname)
X/*****************************************************************************/
Xchar *fname;
X{
Xint fd;	/* file descriptor to read from */
X
X	if (fname[0] != 0)
X		if ((fd = open(fname, O_RDONLY)) < 0)
X		{
X			perror(progname);
X			exit(1);
X		}
X		else
X			return(fd);
X	else
X		return(0);	/* if no file then stdin */
X} /* end of openfile */
X
X
X/*
X * closefile
X *
X * close the given file descriptor
X */
X/*****************************************************************************/
Xvoid closefile(fd)
X/*****************************************************************************/
Xint fd;
X{
X	if (fd != 0)
X		close(fd);
X} /* end of closefile */
X
X
X/*
X * printfile
X *
X * print the given file descriptor
X */
X/*****************************************************************************/
Xvoid printfile(fd)
X/*****************************************************************************/
Xint fd;
X{
Xchar *buf;	/*[MAX_BUFSIZ]; */
Xint n, x=0, y=0, i;
Xlong bn = 1;
X
X	if ((buf = (char *)malloc(b_size)) == (char *)NULL)
X	{
X		printf("%s: error in block size memory allocation\n",progname);
X		exit(1);
X	}
X
X	/*
X	 * this first 'if' handles the start block case (if there is one)
X	 */
X	if (sb_size != 0)
X	{
X		x = sb_size % MAX_BUFSIZ;	/* the very last bit */
X		y = sb_size / MAX_BUFSIZ;	/* the no of full bufs */
X		sb_size = MAX_BUFSIZ;		/* optimum read size. 1K */
X
X		if ((block_numbering) && (print_start_block))
X			printf("start block\n");
X
X		for (i=0; i<=y; i++)
X		{
X			if (i==y)
X				sb_size = x;
X
X			if (((n=read(fd, &buf[0], sb_size)) > 0) &&
X					(print_start_block))
X				hexprint(&buf[0], n);
X		
X			offset += n;
X		}
X
X		if (((blocking_on) || (hex_compression))
X		    && (print_start_block))
X			printf("\n");
X	}
X
X	if (print_ruler && !blocking_on)
X		print_rule();
X
X	while ((n = read(fd, &buf[0], b_size)) > 0)
X	{
X
X		if ((block_numbering) && (bn >= b_start) &&
X		    ((bn <= b_end) || (b_end == 0)))
X		{
X			printf("block number %d (0x%x) ", bn, bn);
X			if (n < b_size)
X				printf("size = %d",n);
X			printf("\n");
X		}
X
X		if ((print_ruler) && (blocking_on) && (bn >= b_start) &&
X			((bn <= b_end) || (b_end == 0)))
X			print_rule();
X
X		if (blocking_on)
X		{
X			if ((bn >= b_start) && ((b_end == 0) || (bn <= b_end)))
X			{
X				hexprint(&buf[0], n);
X				offset += n;
X			}
X			bn++;
X		}
X		else
X		{
X			hexprint(&buf[0], n);
X			offset += n;
X		}
X
X		if ((blocking_on) && (bn >= b_start) &&
X			((bn <= b_end) || (b_end == 0)))
X			printf("\n");
X	}
X
X	free(buf);
X
X} /* end of printfile */
X
X
X/*
X * parse_fmt()
X *
X * This routine parses the second char in the format routine, ie the dump
X * format.
X */
X/*****************************************************************************/
Xparse_fmt(c)
X/*****************************************************************************/
Xchar c;
X{
Xint leading_zero = FALSE;
X
X	switch (c)
X	{
X	case '-' :		/* default */
X		break;
X	case 'T' :		/* octal */
X		leading_zero = TRUE;
X	case 't' :		/* octal */
X		if (leading_zero)
X			fmt_dump = ZOCTALD;
X		else
X			fmt_dump = OCTALD;
X
X		r_len = h_slen = 8;
X
X		fmt_pad = OCTALP;
X		break;
X	case 'D' :		/* decimal */
X		leading_zero = TRUE;
X	case 'd' :		/* decimal */
X		if (leading_zero)
X			fmt_dump = ZDECIMALD;
X		else
X			fmt_dump = DECIMALD;
X
X		r_len = h_slen = 10;
X
X		fmt_pad = DECIMALP;
X		break;
X	case 'X' :		/* hexadecimal */
X		leading_zero = TRUE;
X	case 'x' :		/* hexadecimal */
X		if (leading_zero)
X			fmt_dump = ZHEXD;
X		else
X			fmt_dump = HEXD;
X
X		r_len = h_slen = H_SLEN;
X
X		fmt_pad = HEXP;
X		break;
X	}
X} /* end of parse_fmt */
X
X
Xchar fmt_map[]="0123456789abcdef";
X
X/*
X * print_rule()
X */
X/*****************************************************************************/
Xprint_rule()
X/*****************************************************************************/
X{
Xint i;
X
X	if (offset_print)
X		printf("       ");
X
X	for (i=0; i<h_slen; i++)
X		printf(fmt_dump, i);
X
X	for (i=0; i<h_slen; i++)
X		printf("%c", fmt_map[i%r_len]);
X
X	printf("\n-------\n");
X
X} /* end of print_rule */
X
X
X/*
X * main
X */
X/*****************************************************************************/
Xmain(argc,argv)
X/*****************************************************************************/
Xint argc;
Xchar **argv;
X{
Xint fd;	/* file descriptor to read from */
X
X	strcpy(progname, argv[0]);  /* Save this program name. */
X	get_options(argc,argv);     /* Read and process command line options. */
X
X	fd = openfile(fname);	    /* do this cos input maybe stdin */
X	printfile(fd);
X	closefile(fd);
X
X	exit(0);
X
X} /* end of main */
X
X
END_OF_FILE
if test 12336 -ne `wc -c <'hd.c'`; then
    echo shar: \"'hd.c'\" unpacked with wrong size!
fi
# end of 'hd.c'
fi
if test -f 'hexprint.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hexprint.c'\"
else
echo shar: Extracting \"'hexprint.c'\" \(5180 characters\)
sed "s/^X//" >'hexprint.c' <<'END_OF_FILE'
X/******************************************************************************
X*
X*   Copyright P.J.Ruczynski 1990
X*   This software is free for redistribution and re-use as long as this
X*   copyright is included in all source files. This software is supplied
X*   as is and no responsibilty is taken by the author for any problems
X*   arising from this code.
X*
X* File name		-  hexprint.c
X*
X* Module name		-  HEXPRINT
X*
X* Author		-  P.J.Ruczynski	<pjr@pyra.co.uk>
X*
X* Second Release	-  31 May 1990 (V1.6)
X* First Release		-  16 Feb 1990 (V1.4)
X*
X* Version number	-  1.6
X*
X* Description		-  A hexadecimal printing routine, will print the given
X*			   buffer with the hex on the left and the ascii on the
X*			   right.
X*
X*			Revision List
X*
X* pjr	08.05.89	Added offset numbering. This can be compiled out for
X*			optimum performance.
X*
X* pjr	11.05.89	Added compressed output format. This can be compiled
X*			out for optimum performance.
X*
X* pjr	02.08.89	Changed the bcopy and bcmp routines to use defines defined
X*			in hexprint.h and controlled by compilation flag 'ATT'. With this
X*			defined att routines are used, default means bsd routines are used.
X*			Note that the compression stuff uses BCMP and BCOPY.
X*
X* pjr	04.08.89	Added output to file capability. This can be compiled in
X*			by defining the H_FILEIO flag. Note that you also have to have
X*			a file open with an fd of lfp, although this can be changed by
X*			changing the decn below.
X*
X* pjr	15.05.90	Added octal and decimal output formatting.  This is
X*			controlled by the fmt_ strings and the h_slen variabale which
X*			governs the no of chars output on a line, the default for this
X*			is equivalent to the base we are viewing in, eg octal is 8 etc.
X*			Some preset values of can be found in hexprint.h.
X*			The default is of course hex!
X*
X******************************************************************************/
X#include <stdio.h>
X#include "hexprint.h"
X
X#ifdef H_FILEIO
Xextern FILE *lfp;
X#else
X#define lfp stdout
X#endif /* H_FILEIO */
X
X#ifdef H_COMPRESS
Xint hex_compression = FALSE;	/* compression is off as a default */
X#endif /* H_COMPRESS */
X
X#ifdef H_OFFSETS
Xint offset_print = FALSE;	/* only print offsets on request */
Xlong offset = 0L;		/* default start offset for printing */
X#endif /* H_OFFSET */
X
Xchar *fmt_offset = HEXO;		/* printf format for offsets */
Xchar *fmt_dump = HEXD;		/* printf format for the dump */
Xchar *fmt_pad = HEXP;		/* printf format for the dump */
Xint h_slen = H_SLEN;
X
X/*
X * hexprint
X *
X * routine to print a buffer out in hex form with ascii form on
X * the right hand side
X */
X/*****************************************************************************/
Xvoid hexprint(buf, buflen)
X/*****************************************************************************/
Xchar *buf;	/* ptr to data part of msg req, protocol format, to print     */
Xint buflen;
X{
Xint i,j;
Xchar string[H_SLEN];	/* H_SLEN is 16 and max so ok with this */
X
X#ifdef H_COMPRESS
Xint done_compression = FALSE;	/* have we done any compression ? */
Xchar o_string[H_SLEN];			/* string prior to the current one */
X#endif /* H_COMPRESS */
X
X#ifdef H_OFFSETS
Xlong o;
X	if (offset_print)
X	{
X		o = offset;
X		fprintf(lfp, fmt_offset, o);
X	}
X#endif /* H_OFFSETS */
X
X	for (i=0; i<buflen; i++) {
X		string[i%h_slen] = *buf++;
X		if (i%h_slen == (h_slen-1)) {
X#ifdef H_OFFSETS
X			o += h_slen;
X#endif /* H_OFFSETS */
X#ifdef H_COMPRESS
X			if (hex_compression)
X				if (i == (h_slen-1))  /* first time around ? */
X					BCOPY(string, o_string, h_slen);
X				else
X				{
X
X				if (BCMP(o_string, string, h_slen) == 0)
X					{
X						fprintf(lfp,"* ");
X						done_compression = TRUE;
X						BCOPY(string, o_string, h_slen);
X						continue;
X					}
X					else if (done_compression)
X					{
X						fprintf(lfp,"\n");
X#ifdef H_OFFSETS
X						if (offset_print)
X						    fprintf(lfp, fmt_offset, o - h_slen);
X#endif /* H_OFFSETS */
X						done_compression = FALSE;
X					}
X					BCOPY(string, o_string, h_slen);
X				}
X#endif /* H_COMPRESS */
X			for (j=0; j<h_slen; j++)
X				fprintf(lfp, fmt_dump, (unsigned char)string[j]);
X
X			for (j=0; j<h_slen; j++)
X				if (string[j] >= 0x20 && string[j] <= 0x7e)
X					fprintf(lfp, "%c",string[j]);
X				else
X					fprintf(lfp, ".");
X			fprintf(lfp, "\n");
X#ifdef H_OFFSETS
X			if ((i != (buflen -1)) && offset_print)
X				fprintf(lfp, fmt_offset, o);
X#endif /* H_OFFSETS */
X		} else
X			if ((i%h_slen < (h_slen-1)) && (i == buflen-1)) {
X#ifdef H_COMPRESS
X				if (done_compression)
X				{
X					fprintf(lfp, "\n");
X#ifdef H_OFFSETS
X					if (offset_print)
X						fprintf(lfp, fmt_offset, o);
X#endif /* H_OFFSETS */
X					done_compression = FALSE;
X				}
X				BCOPY(string, o_string, h_slen);
X#endif /* H_COMPRESS */
X				for (j=0; j<=(i%h_slen); j++)
X					fprintf(lfp, fmt_dump, (unsigned char)string[j]);
X
X				for (j=0; j<((h_slen-1)-(i%h_slen)); j++)
X					fprintf(lfp, fmt_pad);	/* PAD STRING */
X
X				for (j=0; j<=(i%h_slen); j++)
X					if (string[j] >= 0x20 &&
X					    string[j] <= 0x7e)
X						fprintf(lfp, "%c",string[j]);
X					else
X						fprintf(lfp, ".");
X
X				fprintf(lfp, "\n");
X			}
X	} /* end of for */
X
X#ifdef H_COMPRESS
X	if (done_compression)
X		fprintf(lfp, "\n");
X#endif /* H_COMPRESS */
X
X} /* end of hexprint */
X
END_OF_FILE
if test 5180 -ne `wc -c <'hexprint.c'`; then
    echo shar: \"'hexprint.c'\" unpacked with wrong size!
fi
# end of 'hexprint.c'
fi
if test -f 'hexprint.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hexprint.h'\"
else
echo shar: Extracting \"'hexprint.h'\" \(2288 characters\)
sed "s/^X//" >'hexprint.h' <<'END_OF_FILE'
X/******************************************************************************
X*
X*   Copyright P.J.Ruczynski 1990
X*   This software is free for redistribution and re-use as long as this
X*   copyright is included in all source files. This software is supplied
X*   as is and no responsibilty is taken by the author for any problems
X*   arising from this code.
X*
X* File name		-  hexprint.h
X*
X* Module name		-  HEXPRINT
X*
X* Author		-  P.J.Ruczynski	<pjr@pyra.co.uk>
X*
X* Second Release	-  31 May 1990 (V1.6)
X* First Release		-  16 Feb 1990 (V1.4)
X*
X* Version number	-  1.6
X*
X* Description		-  This file contains definitions required by the 
X*			   hexprint routine.
X*
X*			Revision List
X*
X* pjr	02.08.89	Changed the bcopy and bcmp routines to use defines defined
X*			in hexprint.h and controlled by compilation flag 'ATT'. With this
X*			defined att routines are used, default means bsd routines are used.
X*			Note that the compression stuff uses BCMP and BCOPY.
X*
X* pjr	15.05.90	Added octal and decimal output formatting. See hexprint.c
X*			for a fuller explanation.
X*
X******************************************************************************/
X
X#define	TRUE		1
X#define	FALSE		0
X#define	H_SLEN		16
X
X#ifdef ATT
X#define BCMP memcmp
X#define BCOPY(a,b,c) memcpy(b,a,c)
X#else /* ucb */
X#define BCMP bcmp
X#define BCOPY bcopy
X#endif
X
X#define ZOCTALO		"%05o  "	/* leading zero printf format for offsets */
X#define ZOCTALD		"%03o "		/* leading zero printf format for the dump */
X#define OCTALO		"%5o  "		/* printf format for offsets */
X#define OCTALD		"%3o "		/* printf format for the dump */
X#define OCTALP		"    "		/* printf format for padding to ascii */
X
X#define ZDECIMALO	"%05d  "	/* leading zero printf format for offsets */
X#define ZDECIMALD	"%03d "		/* leading zero printf format for the dump */
X#define DECIMALO	"%5d  "		/* printf format for offsets */
X#define DECIMALD	"%3d "		/* printf format for the dump */
X#define DECIMALP	"    "		/* printf format for padding to ascii */
X
X#define ZHEXO		"%05x  "	/* leading zero printf format for offsets */
X#define ZHEXD		"%02x "		/* leading zero printf format for the dump */
X#define HEXO		"%5x  "		/* printf format for offsets */
X#define HEXD		"%2x "		/* printf format for the dump */
X#define HEXP		"   "		/* printf format for padding to ascii */
END_OF_FILE
if test 2288 -ne `wc -c <'hexprint.h'`; then
    echo shar: \"'hexprint.h'\" unpacked with wrong size!
fi
# end of 'hexprint.h'
fi
echo shar: End of shell archive.
exit 0
-- 
      -w---------    Pyramid Technology U.K.       Peter Ruczynski    
    ---www-------    Pyramid House                 #include <std/disclaimer.h>
  -----wwwww-----    Farnborough                   pjr@pyra.co.uk
-------wwwwwww---    Hants GU14 7PL     England.   Wot no funny comment :-)

-- 
      -w---------    Pyramid Technology U.K.       Peter Ruczynski    
    ---www-------    Pyramid House                 #include <std/disclaimer.h>
  -----wwwww-----    Farnborough                   pjr@pyra.co.uk
-------wwwwwww---    Hants GU14 7PL     England.   Wot no funny comment :-)