home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- From: kelvin@autodesk.com (John Walker)
- Subject: v37i056: xd - Hexadecimal dump/load/edit filter, Part01/01
- Message-ID: <1993May16.010225.16229@sparky.imd.sterling.com>
- X-Md4-Signature: 87362a932d771d68189158665f1dcdf0
- Date: Sun, 16 May 1993 01:02:25 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: kelvin@autodesk.com (John Walker)
- Posting-number: Volume 37, Issue 56
- Archive-name: xd/part01
- Environment: UNIX, Sun, SGI
-
- XD dumps files as hex bytes, optionally showing the same bytes as ISO
- characters, with non-printing characters (defined according to ISO
- 8859/1 Latin-1) rendered as periods. File addresses are shown as hex
- numbers without leading zeroes.
-
- If you specify the "-l" option, XD will *read* a dump file in the same
- format it writes and create a binary file from the hex data. This
- allows you to dump a binary file with XD, edit it with your favourite
- text editor, then make a new binary file containing whatever changes
- you made. When creating a binary file, XD normally assumes you've
- only changed data in place (neither expanding nor contracting the
- file) and verifies file addresses to guarantee this. However, if you
- set the "-s" (stream) option, file addresses are ignored and you're
- free to insert or delete bytes at will. These options effectively
- turn your existing text editor into a binary file editor without
- requiring you to learn any new commands.
-
- Finally, the "-d" option reads a binary file and emits a C language
- data declaration which contains the data from the file. This is handy
- when you wish to embed binary data within programs.
-
- ------------------------------ Cut here -----------------------------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: README Makefile xd.1 xd.c
- # Wrapped by kent@sparky on Sat May 15 19:59:25 1993
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 1 (of 1)."'
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2665 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X XD
- X Hexadecimal dump and load
- X
- X by John Walker
- X Revision 1 -- December 30th, 1991
- X
- XThis program was created out of exasperation with the Unix "od"
- Xprogram which, notwithstanding its acronym of "octal dump" will
- Xhappily make hexadecimal dumps of files but, in tribute to the past,
- Xrefuses to display file addresses as anything other than octal.
- X
- XXD is a hexadecimal file dump program without pretensions of grandeur.
- XIt dumps files as hex bytes, optionally showing the same bytes as ISO
- Xcharacters, with non-printing characters (defined according to ISO
- X8859/1 Latin-1) rendered as periods. File addresses are shown as hex
- Xnumbers without leading zeroes.
- X
- XXD has a few more little tricks up its sleeve. If you specify the
- X"-l" option, XD will *read* a dump file in the same format it writes
- Xand create a binary file from the hex data. This allows you to dump a
- Xbinary file with XD, edit it with your favourite text editor, then
- Xmake a new binary file containing whatever changes you made. When
- Xcreating a binary file, XD normally assumes you've only changed data
- Xin place (neither expanding nor contracting the file) and verifies
- Xfile addresses to guarantee this. However, if you set the "-s"
- X(stream) option, file addresses are ignored and you're free to insert
- Xor delete bytes at will. These options effectively turn your existing
- Xtext editor into a binary file editor without requiring you to learn
- Xany new commands.
- X
- XFinally, the "-d" option reads a binary file and emits a C language
- Xdata declaration which contains the data from the file. This is handy
- Xwhen you wish to embed binary data within programs.
- X
- XXD is written to be as portable as possible. It does assume that file
- XI/O is not subjected to end of line translation; if you're porting it
- Xto a system such as MS-DOS which requires binary files to be
- Xexplicitly declared, you'll have to add code appropriate to your
- Xcompiler.
- X
- XAUTHOR
- X John Walker
- X Autodesk Neuchatel
- X Avenue des Champs-Montants 14b
- X CH-2074 MARIN
- X Switzerland
- X Usenet: kelvin@autodesk.com
- X Fax: 038/33 88 15
- X Voice: 038/33 76 33
- X
- XThis program is in the public domain: "Do what thou wilt shall be the
- Xwhole of the law". I'd appreciate receiving any bug fixes and/or
- Xenhancements, which I'll incorporate in future versions of the
- Xprogram. Please leave the original attribution information intact so
- Xthat credit and blame may be properly apportioned.
- END_OF_FILE
- if test 2665 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1058 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X
- XCFLAGS = -O
- X
- Xxd: xd.o
- X cc $(CFLAGS) xd.o -o xd
- X strip xd
- X
- Xclean:
- X rm -f xd *.bak core *.out *.o *.shar
- X
- Xshar:
- X shar -b -v README Makefile xd.1 xd.c >xd.shar
- X
- Xlint:
- X lint -h xd.c
- X
- Xmanpage:
- X nroff -man xd.1 | more
- X
- Xprintman:
- X ptroff -man xd.1
- X
- X# The following test should produce no error messages from XD or CMP
- X
- Xtest: xd
- X xd xd /tmp/xd1.bak
- X xd -l /tmp/xd1.bak /tmp/xd2.bak
- X cmp /tmp/xd2.bak xd
- X xd -c xd /tmp/xd3.bak
- X xd -l /tmp/xd3.bak /tmp/xd4.bak
- X cmp /tmp/xd4.bak xd
- X xd -l -s /tmp/xd3.bak /tmp/xd4.bak
- X cmp /tmp/xd4.bak xd
- X sed 's/........//' /tmp/xd3.bak >/tmp/xd5.bak
- X xd -l -s /tmp/xd5.bak /tmp/xd6.bak
- X cmp /tmp/xd6.bak xd
- X echo Hello there >/tmp/xd10.bak
- X xd /tmp/xd10.bak >/tmp/xd7.bak
- X sed '1d' /tmp/xd3.bak >>/tmp/xd7.bak
- X xd -l -s /tmp/xd7.bak /tmp/xd8.bak
- X cp /tmp/xd10.bak /tmp/xd9.bak
- X tail +17c xd >>/tmp/xd9.bak
- X cmp /tmp/xd8.bak /tmp/xd9.bak
- X cat xd | xd -dDeFile >/tmp/xd10.c
- X echo "main() {write(1,DeFile,sizeof DeFile); return 0;}" >>/tmp/xd10.c
- X cc /tmp/xd10.c -o /tmp/xd10.bak
- X /tmp/xd10.bak >/tmp/xd11.bak
- X cmp /tmp/xd11.bak xd
- END_OF_FILE
- if test 1058 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'xd.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xd.1'\"
- else
- echo shar: Extracting \"'xd.1'\" \(4623 characters\)
- sed "s/^X//" >'xd.1' <<'END_OF_FILE'
- X'\" t
- X.TH XD 1 "30 DEC 1991"
- X.UC 4
- X.SH NAME
- Xxd \- binary to hexadecimal filter
- X.SH SYNOPSIS
- X.B xd
- X[
- X.B \-c
- X.BI \-d label
- X.B \-l
- X.B \-s
- X] [
- X.I infile
- X[
- X.I outfile
- X] ]
- X.SH DESCRIPTION
- X.B xd
- Xdumps files in hexadecimal, optionally with ISO characters side by
- Xside. Unlike
- X.BR od ,
- Xfile addresses are given in hex, not octal.
- X.PP
- X.B xd
- Xcan
- X.I read
- Xdump files in the same format it writes and create binary files from
- Xthe hex data therein. This allows you to dump a binary file with
- X.BR xd ,
- Xedit it with your favourite text editor, then
- Xmake a new binary file containing whatever changes you've made. When
- Xcreating a binary file,
- X.B xd
- Xnormally assumes you've only modified data in place (neither expanding
- Xnor contracting the file) and verifies file addresses to guarantee
- Xthis. However, a ``stream'' option is available which ignores file
- Xaddresses so you're free to insert and delete bytes at
- Xwill.
- X.B xd
- Xthus turns your existing text editor into a binary file editor without
- Xrequiring you to learn any new commands.
- X.PP
- XFinally,
- X.B xd
- Xcan read a binary file and emit a C language data declaration which
- Xcontains the data from the file. This is handy when you wish to embed
- Xbinary data within C programs.
- X.SH OPTIONS
- X.TP 10
- X.B \-c
- XDisplay ISO characters alongside the hexadecimal dump. Non-printing
- Xcharacters (according to ISO 8859/1) are shown as periods. The ISO
- Xcharacters are separated from the hexadecimal dump by vertical bar
- Xcharacters, which
- X.B xd
- Xtreats as comment delimiters when loading a hex file.
- X.TP
- X.BI \-d label
- XDumps the file as a C language declaration of an array of
- X.B unsigned char
- Xwhich, when compiled, will contain the same data as the binary input file.
- XThe C array declaration is given the variable name
- X.IR label ,
- Xor
- X.B xd_data
- Xif no
- X.I label
- Xspecification is given. Data are declared as individual bytes to
- Xguarantee portability across architectures with different byte ordering
- Xconventions, and are expressed as decimal numbers in lines of less than
- X80 characters for maximum portability among compilers. The
- XC operator
- X.B sizeof
- Xmay be applied to the array
- X.I label
- Xto obtain its length in bytes.
- X.TP
- X.B \-l
- XLoad file from hexadecimal dump.
- X.B xd
- Xreads a file in the same format it writes, creating a binary output
- Xfile. Each line is assumed to begin with a file address terminated by
- Xa colon. Each data byte must be two hexadecimal characters (letters
- Xmay be upper or lower case), and any characters after a vertical bar
- Xare ignored (thus discarding any ISO characters included in the
- Xdump with the
- X.B \-c
- Xoption). If the
- X.B \-s
- Xoption is not specified, each file address is checked against the
- Xnumber of bytes written so far to guarantee that no bytes have been
- Xadded or deleted.
- X.TP
- X.B \-s
- XStream input when loading file. If this option is specified in conjunction
- Xwith the
- X.B \-l
- Xoption, file addresses are not verified when loading a file and, in fact,
- Xneed not be specified at all. This option treats the input file as stream
- Xof bytes, each specified by two hexadecimal digits. This option allows
- Xyou to create a dump with
- X.BR xd ,
- Xedit it as you wish with any text editor, inserting and deleting bytes
- Xin the file wherever you like, then create a binary file from the
- Xmodified dump with the command
- X.B xd \-l \-s
- X.IR "dumpfile outfile" .
- X.TP
- X.B \-u
- XPrint how-to-call information.
- X.SH FILES
- XIf no
- X.I infile
- Xis specified,
- X.B xd
- Xobtains its input from standard input; if no
- X.I outfile
- Xis given, output is sent to standard output. The input and
- Xoutput are processed in a strictly serial manner regardless
- Xof options; consequently
- X.B xd
- Xmay be used in pipelines without restrictions.
- X.SH BUGS
- X.PP
- XInput error checking in load mode might be improved. Note that each
- Xbyte in load mode must be specified as exactly two adjacent
- Xhexadecimal digits and bytes must be separated by white space. While these
- Xrestrictions could be easily relaxed in the scanner, doing so would
- Xmake
- X.B xd
- Xmore vulnerable to typos in its input file, potentially leading to
- Xvery difficult to find errors in the binary files it creates.
- X.SH "SEE ALSO"
- X.PD
- X.BR cc (1),
- X.BR od (1),
- X.BR iso_8859_1 (7)
- X.ne 10
- X.SH AUTHOR
- X.RS 5
- X.nf
- XJohn Walker
- XAutodesk Neuch\o'^a'tel
- XAvenue des Champs-Montants 14b
- XCH-2074 MARIN
- XSuisse/Schweiz/Svizzera/Switzerland
- X.PD 0
- X.TP 9
- XUsenet:
- Xkelvin@autodesk.com
- X.TP
- XFax:
- X038/33 88 15
- X.TP
- XVoice:
- X038/33 76 33
- X.fi
- X.RE
- X.PD
- X.PP
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted,
- Xwithout any conditions or restrictions. This software is provided ``as
- Xis'' without express or implied warranty.
- END_OF_FILE
- if test 4623 -ne `wc -c <'xd.1'`; then
- echo shar: \"'xd.1'\" unpacked with wrong size!
- fi
- # end of 'xd.1'
- fi
- if test -f 'xd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xd.c'\"
- else
- echo shar: Extracting \"'xd.c'\" \(6491 characters\)
- sed "s/^X//" >'xd.c' <<'END_OF_FILE'
- X/*
- X
- X Hex dump and load utility
- X
- X John Walker
- X Autodesk Neuchatel
- X Avenue des Champs-Montants 14b
- X CH-2074 MARIN
- X Switzerland
- X Usenet: kelvin@autodesk.com
- X Fax: 038/33 88 15
- X Voice: 038/33 76 33
- X
- X*/
- X
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#define FALSE 0
- X#define TRUE 1
- X
- X#define EOS '\0'
- X
- Xstatic char addrformat[80] = "%6X";
- Xstatic char dataformat1[80] = "%02X";
- Xstatic int bytesperline = 16, doublechar = FALSE,
- X dflen = 2, loading = FALSE, streaming = FALSE;
- Xstatic unsigned long fileaddr;
- Xstatic unsigned char lineecho[32];
- X
- X/* OUTLINE -- Edit a line of binary data into the selected output
- X format. */
- X
- Xstatic void outline(out, dat, len)
- X FILE *out;
- X unsigned char *dat;
- X int len;
- X{
- X char oline[132];
- X int i;
- X
- X sprintf(oline, addrformat, fileaddr);
- X strcat(oline, ":");
- X for (i = 0; i < len; i++) {
- X char outedit[80];
- X
- X sprintf(outedit, dataformat1, dat[i]);
- X strcat(oline, (i == (bytesperline / 2)) ? " " : " ");
- X strcat(oline, outedit);
- X }
- X
- X if (doublechar) {
- X char oc[2];
- X int shortfall = ((bytesperline - len) * (dflen + 1)) +
- X (len <= (bytesperline / 2) ? 1 : 0);
- X
- X while (shortfall-- > 0) {
- X strcat(oline, " ");
- X }
- X oc[1] = EOS;
- X strcat(oline, " | ");
- X for (i = 0; i < len; i++) {
- X int b = dat[i];
- X
- X /* Map non-printing characters to "." according to the
- X definitions for ISO 8859/1 Latin-1. */
- X
- X if (b < ' ' || (b > '~' && b < 145)
- X || (b > 146 && b < 160)) {
- X b = '.';
- X }
- X oc[0] = b;
- X strcat(oline, oc);
- X }
- X }
- X strcat(oline, "\n");
- X fputs(oline, out);
- X}
- X
- X/* INTERPLINE -- Interpret a line of input. */
- X
- Xstatic int interpline(line, lineno, out)
- X char *line;
- X int lineno;
- X FILE *out;
- X{
- X char *cp = line;
- X char c;
- X long lfaddr;
- X int gfaddr = FALSE;
- X
- X /* Scan the line for a possible alternative format information
- X following a vertical bar and delete it. */
- X
- X while ((c = *cp++) != EOS) {
- X if (c == '|') {
- X cp[-1] = EOS;
- X break;
- X }
- X }
- X
- X /* Scan the line for a file address terminated by a colon. Save
- X the file address. */
- X
- X cp = line;
- X
- X while ((c = *cp++) != EOS) {
- X if (c == ':') {
- X int sa;
- X char tchar;
- X
- X cp[-1] = EOS;
- X sa = sscanf(line, "%lx%c", &lfaddr, &tchar);
- X if (sa == 0 || (sa > 1 && tchar != EOS)) {
- X fprintf(stderr,
- X "Bad hexadecimal file address \"%s\" on line %d:\n",
- X line, lineno);
- X return FALSE;
- X }
- X gfaddr = TRUE;
- X cp[-1] = ':';
- X break;
- X }
- X }
- X if (!gfaddr) {
- X cp = line;
- X }
- X if (!streaming) {
- X if (!gfaddr) {
- X fprintf(stderr, "File address missing on line %d:\n", lineno);
- X fprintf(stderr, "%s\n", line);
- X return FALSE;
- X }
- X if (lfaddr != fileaddr) {
- X fprintf(stderr, "File address sequence error on line %d.\n",
- X lineno);
- X fprintf(stderr, " Expected 0%X, received 0%X.\n", fileaddr,
- X lfaddr);
- X fprintf(stderr, "%s\n", line);
- X return FALSE;
- X }
- X }
- X
- X while ((c = *cp++) != EOS) {
- X if (!isspace(c)) {
- X if (isxdigit(c) &&
- X isxdigit(*cp) &&
- X (cp[1] == EOS || isspace(cp[1]))) {
- X int b;
- X
- X sscanf(cp - 1, "%2x", &b);
- X putc(b, out);
- X fileaddr++;
- X cp += 2;
- X } else {
- X fprintf(stderr, "Improper hex value, \"%c%c%c\" on line %d:\n",
- X c, *cp, cp[1], lineno);
- X fprintf(stderr, "%s\n", line);
- X fprintf(stderr,
- X "Bytes must be specified as two hexadecimal\n");
- X fprintf(stderr, "digits separated by white space.\n");
- X return FALSE;
- X }
- X }
- X }
- X return TRUE;
- X}
- X
- X/* Main program */
- X
- Xint main(argc, argv)
- X int argc; char *argv[];
- X{
- X int i, b, bp, cdata = FALSE, f = 0;
- X char *cp, *clabel, opt;
- X FILE *in = stdin, *out = stdout;
- X
- X for (i = 1; i < argc; i++) {
- X cp = argv[i];
- X if (*cp == '-') {
- X opt = *(++cp);
- X if (islower(opt))
- X opt = toupper(opt);
- X switch (opt) {
- X
- X case 'C':
- X doublechar = TRUE;
- X break;
- X
- X case 'D':
- X cdata = TRUE;
- X clabel = cp + 1;
- X break;
- X
- X case 'L':
- X loading = TRUE;
- X break;
- X
- X case 'S':
- X streaming = TRUE;
- X break;
- X
- X case '?':
- X case 'U':
- X fprintf(stderr,"\nXD -- Hex dump. Call");
- X fprintf(stderr,
- X "\n with xd [input [output]]");
- X fprintf(stderr,"\n");
- X fprintf(stderr,"\n Options:");
- X fprintf(stderr,"\n -C Dump as ISO characters");
- X fprintf(stderr,"\n -Dlabel Dump as a C data declaration");
- X fprintf(stderr,"\n -L Load file from hex dump");
- X fprintf(stderr,"\n -S Stream load (don't check file addresses)");
- X fprintf(stderr,"\n");
- X return 0;
- X }
- X } else {
- X switch (f) {
- X case 0:
- X if ((in = fopen(cp, "r")) == NULL) {
- X fprintf(stderr, "Cannot open input file %s\n", cp);
- X return 2;
- X }
- X f++;
- X break;
- X
- X case 1:
- X if ((out = fopen(cp, "w")) == NULL) {
- X fprintf(stderr, "Cannot open output file %s\n", cp);
- X return 2;
- X }
- X f++;
- X break;
- X
- X default:
- X fprintf(stderr, "Too many file names specified.\n");
- X }
- X }
- X }
- X
- X bp = 0;
- X fileaddr = 0;
- X
- X if (loading) {
- X char inline[256];
- X int lineno = 0;
- X
- X while (fgets(inline, (sizeof inline) - 2, in)) {
- X lineno++;
- X if (!interpline(inline, lineno, out)) {
- X fclose(out);
- X return 2;
- X }
- X }
- X } else {
- X if (cdata) {
- X char cout[80];
- X
- X fprintf(out, "unsigned char %s[] = {\n",
- X clabel[0] == EOS ? "xd_data" : clabel);
- X strcpy(cout, " ");
- X
- X while ((b = getc(in)) != EOF) {
- X if (strlen(cout) > 72) {
- X fprintf(out, "%s\n", cout);
- X strcpy(cout, " ");
- X }
- X sprintf(cout + strlen(cout), "%d,", b);
- X }
- X if (strlen(cout) > 4) {
- X cout[strlen(cout) - 1] = EOS; /* Strip trailing comma */
- X fprintf(out, "%s\n", cout);
- X }
- X fprintf(out, "};\n");
- X } else {
- X while ((b = getc(in)) != EOF) {
- X if (bp >= bytesperline) {
- X outline(out, lineecho, bp);
- X bp = 0;
- X fileaddr += bytesperline;
- X }
- X lineecho[bp++] = b;
- X }
- X
- X if (bp > 0) {
- X outline(out, lineecho, bp);
- X }
- X }
- X }
- X return 0;
- X}
- END_OF_FILE
- if test 6491 -ne `wc -c <'xd.c'`; then
- echo shar: \"'xd.c'\" unpacked with wrong size!
- fi
- # end of 'xd.c'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-