[net.sources] xod - alternative to od

rlk@chinet.UUCP (Richard Klappal) (08/06/86)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	xod.1
#	xod.c
# This archive created: Sun Aug  3 21:35:45 1986
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'xod.1'
then
	echo shar: "will not over-write existing file 'xod.1'"
else
cat << \SHAR_EOF > 'xod.1'

.TH XOD 1
.\" 8/3/86
.ad
.fi
.UC 4
.SH NAME
xod \- hex/octal/decimal dump
.SH SYNOPSIS
.B xod
[
.B \-xod
] [\fIfile ...\fR]
.SH DESCRIPTION
.I Xod
dumps the specified
.I file(s)
in the base selected by the first argument.
If the first argument is missing,
.B \-x
is default.
.PP
The
.I file
argument specifies which file is to be dumped.
If no file argument is specified, the standard input is used.
.PP
Each output line consists of:
.sp 1
.ce
offset: ... numeric dump ... | ASCII dump |
.sp 1
where the offset and numeric dump portions are in the specified base.
Each output line dumps the same number of bytes as specified by the
base.
Non-printable characters are replaced with \`.\' in the ASCII portion
of the dump.
.PP
Where sequential records are duplicates of the preceeding record, all
such records are replaced by a single asterisk.
.PP
Dumping continues until end-of-file.
.SH OPTIONS
The meanings of the base argument characters
are:
.TP 3
.B  d
Interpret bytes (8 bit words) in decimal.
.TP 3
.B  o
Interpret bytes (8 bit words) in octal.
.TP 3
.B  x
Interpret bytes (8 bit words) in hex.
.PP
If more than one option is specified, the last one is used.
.SH BUGS
There is no provision for beginning at a specified offset into the
input file.
.PP
There is no provision for merging multibyte words into single values
in the numeric dump portion.
.SH SEE ALSO
adb(1), od(1).
.SH AUTHOR
Richard Klappal
.br
uucp:       !ihnp4!chinet!uklpl!rlk
.br
            !ihnp4!ihu1h!rlk    (IH 4H-326 x4770)
.br
CompuServe: 74106,1021
.br
MCIMail:    rklappal
SHAR_EOF
fi
if test -f 'xod.c'
then
	echo shar: "will not over-write existing file 'xod.c'"
else
cat << \SHAR_EOF > 'xod.c'
static char *SCCS_id = "@(#) xod.c (1.2) 8/3/86 21:35:14";
/*
 * xod.c - hex/octal/decimal dump utility
 *
 * xod [-xodwv] file ...
 *	x	selects hex base
 *	o	selects octal base
 *	d	selects decimal base
 *
 * Displays file(s) in the following format
 *
 * offset: ......numeric...... |...ascii...|
 *
 * where the offset and numeric sections are in the specified base
 * 'record' length is the same as the chose base (e.i., hex prints
 *	16 bytes per line, octal prints 8 bytes per line, decimal
 *	prints 10 bytes per line.
 */
#include <stdio.h>
#include <memory.h>

#define	TRUE	1
#define	FALSE	0

FILE	*infile;
unsigned char	inrec[16];
unsigned char	savrec[16];
unsigned	recno;
int	duplicate;

int	base = 16;	/* default to hexadecimal */

main(argc, argv)
int argc;
char *argv[];
{
	extern int optind;
	extern char *optarg;
	int	c;

	while ((c = getopt(argc,argv,"xod")) != EOF) {
		switch (c) {
		case 'x':
			base = 16;
			break;
		case 'o':
			base = 8;
			break;
		case 'd':
			base = 10;
			break;
		default:
			fprintf(stderr,"%s: unknown option (%c)\n",
			    argv[0], c);
			exit(1);
		}
	}
	if (optind == argc) {
		infile = stdin;
		printf("\n\nDump: standard input\n\n");
		dump(stdin);
	} 
	else {
		for ( ; optind < argc; optind++) {
			if ((infile = fopen(argv[optind], "r")) == NULL) {
				fprintf(stderr,
				    "Unable to open %s\n\n", argv[optind]);
				continue;
			}
			printf("\n\nDump: %s\n\n", argv[optind]);
			dump(infile);
			if (duplicate) {
				printrec(savrec);
				duplicate = FALSE;
			}
			fclose(infile);
		}
	}
}



printrec(rec)
unsigned char *rec;
{
	unsigned char *i;

	switch (base) {
	case 16:
		printf("%08x: ", recno);
		break;
	case 8:
		printf("%012o: ", recno);
		break;
	case 10:
		printf("%10d: ", recno);
		break;
	}
	for (i=rec; i<&rec[base]; i++) {
		switch (base) {
		case 16:
			printf("%02x ", *i);
			break;
		case 8:
			printf(" %03o ", *i);
			break;
		case 10:
			printf("%3d ", *i);
			break;
		}
	}
	printf("| ");
	for(i=rec; i<&rec[base]; i++) {
		if (*i > 0x1f && *i < 0x7f)
			printf("%c", *i);
		else
			printf(".");
	}
	printf(" |\n");
}

dump(src)
FILE	*src;
{
	recno = 0;
	switch (base) {
	case 16:
		printf(
"Offset:    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f   0123456789abcdef\n\n");
		break;
	case 8:
		printf(
"Offset:          0    1    2    3    4    5    6    7   01234567\n\n");
		break;
	case 10:
		printf(
"Offset:       0   1   2   3   4   5   6   7   8   9   0123456789\n\n");
		break;
	}

	while (fread(inrec, 1, base, src) != 0) {
		if (memcmp(inrec,savrec,base) == 0) {
			duplicate = TRUE;
			recno += base;
			continue;
		}
		if (duplicate) {
			printf("*\n");
			duplicate = FALSE;
		}
		printrec(inrec);
		recno += base;
		memcpy(savrec,inrec,base);
		memset(inrec,'\0',base);
	}
}



SHAR_EOF
fi
exit 0
#	End of shell archive


-- 
---
UUCP: ..!ihnp4!chinet!uklpl!rlk || MCIMail: rklappal || Compuserve: 74106,1021
      ..!ihnp4!ihu1h!rlk
---