aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2008-03-26 13:49:14 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2008-03-26 13:49:14 +0000
commit60ca8aa1435fbdd3d070fcc9d4b7019a68186a1a (patch)
treed2e3d4b2131a2fca77a7818af7dd7023240e6b6a /utils
parentc436250848faad51b677a2368ba51d5be18dea08 (diff)
downloadsg3_utils-60ca8aa1435fbdd3d070fcc9d4b7019a68186a1a.tar.gz
add '--progress' option to sg_requests, hxascdmp man page
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@165 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'utils')
-rw-r--r--utils/Makefile14
-rw-r--r--utils/README5
-rw-r--r--utils/hxascdmp.187
-rw-r--r--utils/hxascdmp.c152
4 files changed, 201 insertions, 57 deletions
diff --git a/utils/Makefile b/utils/Makefile
index 2b519bc5..3bf73659 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -1,18 +1,19 @@
SHELL = /bin/sh
-PREFIX=/usr/local
+PREFIX=/usr
INSTDIR=$(DESTDIR)/$(PREFIX)/bin
-MANDIR=$(DESTDIR)/$(PREFIX)/man
+MANDIR=$(DESTDIR)/$(PREFIX)/share/man
CC = gcc
LD = gcc
-EXECS = hxascdmp sg_chk_asc
+EXECS = hxascdmp
+# EXECS = hxascdmp sg_chk_asc
-MAN_PGS =
-MAN_PREF = man8
+MAN_PGS = hxascdmp.1
+MAN_PREF = man1
-CFLAGS = -g -O2 -W
+CFLAGS = -g -O2 -W -Wall
# CFLAGS = -g -O2 -W -pedantic -std=c99
LDFLAGS =
@@ -29,6 +30,7 @@ clean:
hxascdmp: hxascdmp.o
$(LD) -o $@ $(LDFLAGS) $^
+# building sg_chk_asc depends on a prior successful make in ../lib
sg_chk_asc: sg_chk_asc.o ../lib/sg_lib.o ../lib/sg_lib_data.o
$(LD) -o $@ $(LDFLAGS) $^
diff --git a/utils/README b/utils/README
index 19c70a56..3faef309 100644
--- a/utils/README
+++ b/utils/README
@@ -3,7 +3,8 @@ This directory contains these utilities:
which is sent to stdout. The incoming binary stream can either be
from a file or, in the absence of a file name, from stdin. Similar to
the Unix "od" command. By default, it decodes 16 bytes per line with
- an ASCII interpretation to the right of each line.
+ an ASCII interpretation to the right of each line. See its
+ hxascdmp(1) man page.
- sg_chk_asc: utility decodes the SCSI additional sense code table
found at http://www.t10.org/lists/asc-num.txt and checks it
against the table found in sg_lib.c in the lib/ subdirectory.
@@ -21,4 +22,4 @@ the lib/ subdirectory. One way to meet that requirement is to execute
Doug Gilbert
-11th January 2008
+26th March 2008
diff --git a/utils/hxascdmp.1 b/utils/hxascdmp.1
new file mode 100644
index 00000000..6412b4cf
--- /dev/null
+++ b/utils/hxascdmp.1
@@ -0,0 +1,87 @@
+.TH HXASCDMP "1" "March 2008" "sg3_utils\-1.26" SG3_UTILS
+.SH NAME
+hxascdmp \- hexadecimal ASCII dump
+.SH SYNOPSIS
+.B hxascdmp
+[\fI\-b=BPL\fR] [\fI\-h\fR] [\fI\-H\fR] [\fI\-V\fR]
+[\fIFILE+\fR]
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+This utility reads one or more \fIFILE\fR names and dumps them in hexadecimal
+and ASCII to stdout. If no \fIFILE\fR is given then stdin is read instead;
+reading continues (or stalls) until an EOF is received.
+.PP
+The default format is to start each line with the hexadecimal address (offset
+from the start of file) followed by 16 hexadecimal bytes separated by a
+single space (apart from the 8th and 9th bytes which are separated by two
+spaces). If the \fI\-H\fR is not given, there is then a string of 16 ASCII
+characters corresponding to the hexadecimal bytes earlier in the line; only
+bytes in the range 0x20 to 0x7e are printed in ASCII, other bytes values are
+printed as '.' . Each \fIFILE\fR name that appears on the command line is
+printed on a separate line prior to that file's hexadecimal ASCII dump.
+.PP
+This utility is pretty close to the 'hexdump -C' variant of BSD's
+.B hexdump(1)
+command.
+.SH OPTIONS
+.TP
+\fB\-b\fR=\fIBPL\fR
+where \fIBPL\fR specifies the number of bytes per line. The default value is
+16. 16 bytes per line is just enough to allow the address, 16 bytes in
+hexadecimal followed by 16 bytes as ASCII to fit on a standard 80 column
+wide terminal.
+.TP
+\fB\-h\fR
+output the usage message then exit.
+.TP
+\fB\-H\fR
+output hexadecimal only (i.e. don't place an ASCII representation at the
+end of each line).
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+print the version string and then exit.
+.SH EXIT STATUS
+The exit status of hxascdmp is 0 when it is successful. If any of the
+given \fIFILE\fR names cannot be opened then the exit status is 1.
+.SH EXAMPLES
+First we manufacture a short file with a mix of data in it: mostly ASCII with
+some control characters and 0xaa (which the echo command only accepts in
+octal (0252):
+.PP
+ $ echo -e "three blind mice,\t\r\0252" > 3bm.txt
+.PP
+Now we use this utility to see exactly what is in the file. To avoid
+problems with line wrapping, the bytes per line option is set to 8:
+.PP
+ $ hxascdmp -b=8 3bm.txt
+.br
+ASCII hex dump of file: 3bm.txt
+.br
+ 00 74 68 72 65 65 20 62 6c three bl
+.br
+ 08 69 6e 64 20 6d 69 63 65 ind mice
+.br
+ 10 2c 09 0d aa 0a ,....
+.PP
+Using the same file, use this utility to output only hexadecimal formatted
+16 bytes per line.
+.PP
+ $ hxascdmp -H 3bm.txt
+.br
+hex dump of file: 3bm.txt
+.br
+ 00 74 68 72 65 65 20 62 6c 69 6e 64 20 6d 69 63 65
+.br
+ 10 2c 09 0d aa 0a
+.SH AUTHORS
+Written by Douglas Gilbert.
+.SH "REPORTING BUGS"
+Report bugs to <dgilbert at interlog dot com>.
+.SH COPYRIGHT
+Copyright \(co 2004\-2008 Douglas Gilbert
+.br
+This software is distributed under a FreeBSD license. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+.SH "SEE ALSO"
+.B hexdump(1)
diff --git a/utils/hxascdmp.c b/utils/hxascdmp.c
index dedeae80..fb636950 100644
--- a/utils/hxascdmp.c
+++ b/utils/hxascdmp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004 Douglas Gilbert.
+ * Copyright (c) 2004-2008 Douglas Gilbert.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,12 +39,15 @@
static int bytes_per_line = DEF_BYTES_PER_LINE;
+static const char * version_str = "1.10 20080321";
+
#define CHARS_PER_HEX_BYTE 3
#define BINARY_START_COL 6
#define MAX_LINE_LENGTH 257
-static void dStrHex(const char* str, int len, long start)
+static void
+dStrHex(const char* str, int len, long start)
{
const char* p = str;
unsigned char c;
@@ -62,8 +65,7 @@ static void dStrHex(const char* str, int len, long start)
return;
line_length = BINARY_START_COL +
(bytes_per_line * (1 + CHARS_PER_HEX_BYTE)) + 7;
- if (line_length >= MAX_LINE_LENGTH)
- {
+ if (line_length >= MAX_LINE_LENGTH) {
fprintf(stderr, "bytes_per_line causes maximum line length of %d "
"to be exceeded\n", MAX_LINE_LENGTH);
return;
@@ -75,8 +77,7 @@ static void dStrHex(const char* str, int len, long start)
if (bpos >= ((bpstart + (midline_space * CHARS_PER_HEX_BYTE))))
bpos++;
- for(i = 0; i < len; i++)
- {
+ for(i = 0; i < len; i++) {
c = *p++;
bpos += CHARS_PER_HEX_BYTE;
if (bpos == (bpstart + (midline_space * CHARS_PER_HEX_BYTE)))
@@ -86,8 +87,7 @@ static void dStrHex(const char* str, int len, long start)
if ((c < ' ') || (c >= 0x7f))
c='.';
buff[cpos++] = c;
- if (cpos >= (cpstart + bytes_per_line))
- {
+ if (cpos >= (cpstart + bytes_per_line)) {
printf("%s\n", buff);
bpos = bpstart;
cpos = cpstart;
@@ -101,22 +101,76 @@ static void dStrHex(const char* str, int len, long start)
printf("%s\n", buff);
}
+static void
+dStrHexOnly(const char* str, int len, long start)
+{
+ const char* p = str;
+ unsigned char c;
+ char buff[MAX_LINE_LENGTH];
+ long a = start;
+ const int bpstart = BINARY_START_COL;
+ int bpos = bpstart;
+ int midline_space = (bytes_per_line / 2) + 1;
+ int i, k, line_length;
+
+ if (len <= 0)
+ return;
+ line_length = BINARY_START_COL +
+ (bytes_per_line * CHARS_PER_HEX_BYTE) + 4;
+ if (line_length >= MAX_LINE_LENGTH) {
+ fprintf(stderr, "bytes_per_line causes maximum line length of %d "
+ "to be exceeded\n", MAX_LINE_LENGTH);
+ return;
+ }
+ memset(buff, ' ', line_length);
+ buff[line_length] = '\0';
+ k = sprintf(buff + 1, "%.2lx", a);
+ buff[k + 1] = ' ';
+ if (bpos >= ((bpstart + (midline_space * CHARS_PER_HEX_BYTE))))
+ bpos++;
+
+ for(i = 0; i < len; i++) {
+ c = *p++;
+ bpos += CHARS_PER_HEX_BYTE;
+ if (bpos == (bpstart + (midline_space * CHARS_PER_HEX_BYTE)))
+ bpos++;
+ sprintf(&buff[bpos], "%.2x", (int)(unsigned char)c);
+ buff[bpos + 2] = ' ';
+ if (bpos >= (bpstart + (bytes_per_line * CHARS_PER_HEX_BYTE)))
+ {
+ printf("%s\n", buff);
+ bpos = bpstart;
+ a += bytes_per_line;
+ memset(buff,' ', line_length);
+ k = sprintf(buff + 1, "%.2lx", a);
+ buff[k + 1] = ' ';
+ }
+ }
+ if (bpos > bpstart)
+ printf("%s\n", buff);
+}
-static void usage()
+static void
+usage()
{
- fprintf(stderr, "Usage: hxascdmp [-b=<n>] [-h] [-?] [file+] \n");
- fprintf(stderr, " Sends hex ASCII dump of stdin/file to stdout\n");
+ fprintf(stderr, "Usage: hxascdmp [-b=<n>] [-h] [-H] [-V] [-?] "
+ "[<file>+]\n");
fprintf(stderr, " where:\n");
- fprintf(stderr, " -b=<n> bytes per line to display "
+ fprintf(stderr, " -b=<n> bytes per line to display "
"(def: 16)\n");
- fprintf(stderr, " -h print this usage message\n");
- fprintf(stderr, " -? print this usage message\n");
- fprintf(stderr, " file reads file(s) and outputs it "
+ fprintf(stderr, " -h print this usage message\n");
+ fprintf(stderr, " -H print hex only (i.e. no ASCII "
+ "to right)\n");
+ fprintf(stderr, " -V print version string then exits\n");
+ fprintf(stderr, " -? print this usage message\n");
+ fprintf(stderr, " <file>+ reads file(s) and outputs each "
"as hex ASCII\n");
- fprintf(stderr, " if no files reads stdin\n");
+ fprintf(stderr, " if no <file> then reads stdin\n\n");
+ fprintf(stderr, "Sends hex ASCII dump of stdin/file to stdout\n");
}
-int main(int argc, const char ** argv)
+int
+main(int argc, const char ** argv)
{
char buff[8192];
int num = 8192;
@@ -124,15 +178,14 @@ int main(int argc, const char ** argv)
int res, k, u;
int inFile = 0; /* stdin */
int doHelp = 0;
+ int doHex = 0;
int hasFilename = 0;
+ int ret = 0;
- for (k = 1; k < argc; k++)
- {
- if (0 == strncmp("-b=", argv[k], 3))
- {
+ for (k = 1; k < argc; k++) {
+ if (0 == strncmp("-b=", argv[k], 3)) {
res = sscanf(argv[k] + 3, "%d", &u);
- if ((1 != res) || (u < 1))
- {
+ if ((1 != res) || (u < 1)) {
printf("Bad value after '-b' switch\n");
usage();
return 1;
@@ -141,22 +194,23 @@ int main(int argc, const char ** argv)
}
else if (0 == strcmp("-h", argv[k]))
doHelp = 1;
- else if (0 == strcmp("-?", argv[k]))
+ else if (0 == strcmp("-H", argv[k]))
+ doHex = 1;
+ else if (0 == strcmp("-V", argv[k])) {
+ fprintf(stderr, "%s\n", version_str);
+ return 0;
+ } else if (0 == strcmp("-?", argv[k]))
doHelp = 1;
- else if (*argv[k] == '-')
- {
+ else if (*argv[k] == '-') {
fprintf(stderr, "unknown switch: %s\n", argv[k]);
usage();
return 1;
- }
- else
- {
+ } else {
hasFilename = 1;
break;
}
}
- if (doHelp)
- {
+ if (doHelp) {
usage();
return 0;
}
@@ -165,36 +219,36 @@ int main(int argc, const char ** argv)
if (0 != (num % bytes_per_line))
num = (num / bytes_per_line) * bytes_per_line;
- if (hasFilename)
- {
+ if (hasFilename) {
for ( ; k < argc; k++)
{
inFile = open(argv[k], O_RDONLY);
- if (inFile < 0)
- {
+ if (inFile < 0) {
fprintf(stderr, "Couldn't open file: %s\n", argv[k]);
- }
- else
- {
+ ret = 1;
+ } else {
start = 0;
- printf("ASCII hex dump of file: %s\n", argv[k]);
- while ((res = read(inFile, buff, num)) > 0)
- {
- dStrHex(buff, res, start);
+ printf("%shex dump of file: %s\n",
+ (doHex ? "" : "ASCII "), argv[k]);
+ while ((res = read(inFile, buff, num)) > 0) {
+ if (doHex)
+ dStrHexOnly(buff, res, start);
+ else
+ dStrHex(buff, res, start);
start += (long)res;
}
}
close(inFile);
printf("\n");
}
- }
- else
- {
- while ((res = read(inFile, buff, num)) > 0)
- {
- dStrHex(buff, res, start);
+ } else {
+ while ((res = read(inFile, buff, num)) > 0) {
+ if (doHex)
+ dStrHexOnly(buff, res, start);
+ else
+ dStrHex(buff, res, start);
start += (long)res;
}
}
- return 0;
+ return ret;
}