summaryrefslogtreecommitdiff
path: root/usr.bin/hexdump
diff options
context:
space:
mode:
authorPeter Valchev <pvalchev@cvs.openbsd.org>2001-12-30 08:17:33 +0000
committerPeter Valchev <pvalchev@cvs.openbsd.org>2001-12-30 08:17:33 +0000
commitd5d19f2d773d90fe05e2a93c2878ece3b2a4a7fc (patch)
treeeabe05d107d7761a7d3ce8ea9f04236ef4a93b64 /usr.bin/hexdump
parent80376a6f4b8ec8fa3670cc0fade14a38c69d5a10 (diff)
Changes come from NetBSD, Lite-2 and me. ok deraadt
od(1): - Enable support for printing 8-byte integers. - Added -C option for hexadecimal+ASCII display. - Fix od so it displays short files containing nulls. - POSIXification: The C, S, I and L modifiers now behave correctly, specifying output in units of a char, short, int and long (as defined by the host system) respectively. Support -N, equivalent to hexdump's -n (format only COUNT bytes of input). Add -j option which does the same thing as -s in hexdump (skipping some of the input). hexdump(1): - POSIX.2 doesn't specify hexdump so it can't be compatible with it... - add missing trailing \n in usage() printf
Diffstat (limited to 'usr.bin/hexdump')
-rw-r--r--usr.bin/hexdump/conv.c25
-rw-r--r--usr.bin/hexdump/display.c298
-rw-r--r--usr.bin/hexdump/hexdump.145
-rw-r--r--usr.bin/hexdump/hexdump.c13
-rw-r--r--usr.bin/hexdump/hexdump.h65
-rw-r--r--usr.bin/hexdump/hexsyntax.c35
-rw-r--r--usr.bin/hexdump/od.1293
-rw-r--r--usr.bin/hexdump/odsyntax.c258
-rw-r--r--usr.bin/hexdump/parse.c257
9 files changed, 878 insertions, 411 deletions
diff --git a/usr.bin/hexdump/conv.c b/usr.bin/hexdump/conv.c
index 017695c657b..5c2e0da330d 100644
--- a/usr.bin/hexdump/conv.c
+++ b/usr.bin/hexdump/conv.c
@@ -1,8 +1,9 @@
-/* $OpenBSD: conv.c,v 1.3 2001/07/12 05:17:10 deraadt Exp $ */
+/* $OpenBSD: conv.c,v 1.4 2001/12/30 08:17:32 pvalchev Exp $ */
+/* $NetBSD: conv.c,v 1.7 2001/12/07 15:14:29 bjh21 Exp $ */
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,12 +36,14 @@
#ifndef lint
/*static char sccsid[] = "from: @(#)conv.c 5.4 (Berkeley) 6/1/90";*/
-static char rcsid[] = "$OpenBSD: conv.c,v 1.3 2001/07/12 05:17:10 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: conv.c,v 1.4 2001/12/30 08:17:32 pvalchev Exp $";
#endif /* not lint */
#include <sys/types.h>
-#include <ctype.h>
+
#include <stdio.h>
+#include <ctype.h>
+
#include "hexdump.h"
void
@@ -48,8 +51,8 @@ conv_c(pr, p)
PR *pr;
u_char *p;
{
- extern int deprecated;
- char buf[10], *str;
+ char buf[10];
+ char const *str;
switch(*p) {
case '\0':
@@ -88,7 +91,8 @@ conv_c(pr, p)
*pr->cchar = 'c';
(void)printf(pr->fmt, *p);
} else {
- (void)sprintf(str = buf, "%03o", (int)*p);
+ (void)sprintf(buf, "%03o", (int)*p);
+ str = buf;
strpr: *pr->cchar = 's';
(void)printf(pr->fmt, str);
}
@@ -99,8 +103,7 @@ conv_u(pr, p)
PR *pr;
u_char *p;
{
- extern int deprecated;
- static char *list[] = {
+ static const char *list[] = {
"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
"bs", "ht", "lf", "vt", "ff", "cr", "so", "si",
"dle", "dcl", "dc2", "dc3", "dc4", "nak", "syn", "etb",
@@ -117,7 +120,7 @@ conv_u(pr, p)
} else if (*p == 0x7f) {
*pr->cchar = 's';
(void)printf(pr->fmt, "del");
- } else if (deprecated && *p == 0x20) { /* od replace space with sp */
+ } else if (deprecated && *p == 0x20) { /* od replaced space with sp */
*pr->cchar = 's';
(void)printf(pr->fmt, " sp");
} else if (isprint(*p)) {
diff --git a/usr.bin/hexdump/display.c b/usr.bin/hexdump/display.c
index b7059415c4c..d02234df1fa 100644
--- a/usr.bin/hexdump/display.c
+++ b/usr.bin/hexdump/display.c
@@ -1,8 +1,9 @@
-/* $OpenBSD: display.c,v 1.8 2001/11/19 19:02:14 mpech Exp $ */
+/* $OpenBSD: display.c,v 1.9 2001/12/30 08:17:32 pvalchev Exp $ */
+/* $NetBSD: display.c,v 1.12 2001/12/07 15:14:29 bjh21 Exp $ */
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,119 +36,42 @@
#ifndef lint
/*static char sccsid[] = "from: @(#)display.c 5.11 (Berkeley) 3/9/91";*/
-static char rcsid[] = "$OpenBSD: display.c,v 1.8 2001/11/19 19:02:14 mpech Exp $";
+static char rcsid[] = "$OpenBSD: display.c,v 1.9 2001/12/30 08:17:32 pvalchev Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
+
#include <ctype.h>
+#include <err.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <err.h>
+#include <unistd.h>
+
#include "hexdump.h"
enum _vflag vflag = FIRST;
static off_t address; /* address/offset in stream */
static off_t eaddress; /* end address */
-static off_t savaddress; /* saved address/offset in stream */
-#define PRINT { \
- switch(pr->flags) { \
- case F_ADDRESS: \
- (void)printf(pr->fmt, address); \
- break; \
- case F_BPAD: \
- (void)printf(pr->fmt, ""); \
- break; \
- case F_C: \
- conv_c(pr, bp); \
- break; \
- case F_CHAR: \
- (void)printf(pr->fmt, *bp); \
- break; \
- case F_DBL: { \
- double dval; \
- float fval; \
- switch(pr->bcnt) { \
- case 4: \
- bcopy((char *)bp, (char *)&fval, sizeof(fval)); \
- (void)printf(pr->fmt, fval); \
- break; \
- case 8: \
- bcopy((char *)bp, (char *)&dval, sizeof(dval)); \
- (void)printf(pr->fmt, dval); \
- break; \
- } \
- break; \
- } \
- case F_INT: { \
- int ival; \
- short sval; \
- switch(pr->bcnt) { \
- case 1: \
- (void)printf(pr->fmt, (int)*bp); \
- break; \
- case 2: \
- bcopy((char *)bp, (char *)&sval, sizeof(sval)); \
- (void)printf(pr->fmt, (int)sval); \
- break; \
- case 4: \
- bcopy((char *)bp, (char *)&ival, sizeof(ival)); \
- (void)printf(pr->fmt, ival); \
- break; \
- } \
- break; \
- } \
- case F_P: \
- (void)printf(pr->fmt, isprint(*bp) ? *bp : '.'); \
- break; \
- case F_STR: \
- (void)printf(pr->fmt, (char *)bp); \
- break; \
- case F_TEXT: \
- (void)printf(pr->fmt); \
- break; \
- case F_U: \
- conv_u(pr, bp); \
- break; \
- case F_UINT: { \
- u_int ival; \
- u_short sval; \
- switch(pr->bcnt) { \
- case 1: \
- (void)printf(pr->fmt, (u_int)*bp); \
- break; \
- case 2: \
- bcopy((char *)bp, (char *)&sval, sizeof(sval)); \
- (void)printf(pr->fmt, (u_int)sval); \
- break; \
- case 4: \
- bcopy((char *)bp, (char *)&ival, sizeof(ival)); \
- (void)printf(pr->fmt, ival); \
- break; \
- } \
- break; \
- } \
- } \
-}
+static inline void print __P((PR *, u_char *));
void
display()
{
- extern FU *endfu;
FS *fs;
FU *fu;
PR *pr;
int cnt;
u_char *bp;
off_t saveaddress;
- u_char savech, *savebp, *get();
+ u_char savech, *savebp;
- while ((bp = get()))
+ savech = 0;
+ while ((bp = get()) != NULL)
for (fs = fshead, savebp = bp, saveaddress = address; fs;
fs = fs->nextfs, bp = savebp, address = saveaddress)
for (fu = fs->nextfu; fu; fu = fu->nextfu) {
@@ -157,20 +81,20 @@ display()
for (pr = fu->nextpr; pr; address += pr->bcnt,
bp += pr->bcnt, pr = pr->nextpr) {
if (eaddress && address >= eaddress &&
- !(pr->flags&(F_TEXT|F_BPAD)))
+ !(pr->flags & (F_TEXT|F_BPAD)))
bpad(pr);
if (cnt == 1 && pr->nospace) {
savech = *pr->nospace;
*pr->nospace = '\0';
}
- PRINT;
+ print(pr, bp);
if (cnt == 1 && pr->nospace)
*pr->nospace = savech;
}
}
if (endfu) {
/*
- * if eaddress not set, error or file size was multiple of
+ * If eaddress not set, error or file size was multiple of
* blocksize, and no partial block ever found.
*/
if (!eaddress) {
@@ -181,32 +105,124 @@ display()
for (pr = endfu->nextpr; pr; pr = pr->nextpr)
switch(pr->flags) {
case F_ADDRESS:
- (void)printf(pr->fmt, eaddress);
+ (void)printf(pr->fmt, (quad_t)eaddress);
break;
case F_TEXT:
- (void)printf(pr->fmt);
+ (void)printf("%s", pr->fmt);
break;
}
}
}
+static inline void
+print(pr, bp)
+ PR *pr;
+ u_char *bp;
+{
+ double f8;
+ float f4;
+ int16_t s2;
+ int32_t s4;
+ int64_t s8;
+ u_int16_t u2;
+ u_int32_t u4;
+ u_int64_t u8;
+
+ switch(pr->flags) {
+ case F_ADDRESS:
+ (void)printf(pr->fmt, (quad_t)address);
+ break;
+ case F_BPAD:
+ (void)printf(pr->fmt, "");
+ break;
+ case F_C:
+ conv_c(pr, bp);
+ break;
+ case F_CHAR:
+ (void)printf(pr->fmt, *bp);
+ break;
+ case F_DBL:
+ switch(pr->bcnt) {
+ case 4:
+ memmove(&f4, bp, sizeof(f4));
+ (void)printf(pr->fmt, f4);
+ break;
+ case 8:
+ memmove(&f8, bp, sizeof(f8));
+ (void)printf(pr->fmt, f8);
+ break;
+ }
+ break;
+ case F_INT:
+ switch(pr->bcnt) {
+ case 1:
+ (void)printf(pr->fmt, (quad_t)*bp);
+ break;
+ case 2:
+ memmove(&s2, bp, sizeof(s2));
+ (void)printf(pr->fmt, (quad_t)s2);
+ break;
+ case 4:
+ memmove(&s4, bp, sizeof(s4));
+ (void)printf(pr->fmt, (quad_t)s4);
+ break;
+ case 8:
+ memmove(&s8, bp, sizeof(s8));
+ (void)printf(pr->fmt, s8);
+ break;
+ }
+ break;
+ case F_P:
+ (void)printf(pr->fmt, isprint(*bp) ? *bp : '.');
+ break;
+ case F_STR:
+ (void)printf(pr->fmt, (char *)bp);
+ break;
+ case F_TEXT:
+ (void)printf("%s", pr->fmt);
+ break;
+ case F_U:
+ conv_u(pr, bp);
+ break;
+ case F_UINT:
+ switch(pr->bcnt) {
+ case 1:
+ (void)printf(pr->fmt, (u_quad_t)*bp);
+ break;
+ case 2:
+ memmove(&u2, bp, sizeof(u2));
+ (void)printf(pr->fmt, (u_quad_t)u2);
+ break;
+ case 4:
+ memmove(&u4, bp, sizeof(u4));
+ (void)printf(pr->fmt, (u_quad_t)u4);
+ break;
+ case 8:
+ memmove(&u8, bp, sizeof(u8));
+ (void)printf(pr->fmt, u8);
+ break;
+ }
+ break;
+ }
+}
+
void
bpad(pr)
PR *pr;
{
- static char *spec = " -0+#";
+ static const char *spec = " -0+#";
char *p1, *p2;
/*
- * remove all conversion flags; '-' is the only one valid
+ * Remove all conversion flags; '-' is the only one valid
* with %s, and it's not useful here.
*/
pr->flags = F_BPAD;
- *pr->cchar = 's';
+ pr->cchar[0] = 's';
+ pr->cchar[1] = '\0';
for (p1 = pr->fmt; *p1 != '%'; ++p1);
for (p2 = ++p1; *p1 && strchr(spec, *p1); ++p1);
- while ((*p2++ = *p1++))
- ;
+ while ((*p2++ = *p1++) != '\0');
}
static char **_argv;
@@ -214,24 +230,20 @@ static char **_argv;
u_char *
get()
{
- extern enum _vflag vflag;
- extern int length;
static int ateof = 1;
static u_char *curp, *savp;
int n;
int need, nread;
- int valid_save = 0;
u_char *tmpp;
if (!curp) {
- curp = (u_char *)emalloc(blocksize);
- savp = (u_char *)emalloc(blocksize);
+ curp = emalloc(blocksize);
+ savp = emalloc(blocksize);
} else {
tmpp = curp;
curp = savp;
savp = tmpp;
- address = savaddress += blocksize;
- valid_save = 1;
+ address += blocksize;
}
for (need = blocksize, nread = 0;;) {
/*
@@ -239,16 +251,16 @@ get()
* and no other files are available, zero-pad the rest of the
* block and set the end flag.
*/
- if (!length || ateof && !next((char **)NULL)) {
+ if (!length || (ateof && !next(NULL))) {
if (need == blocksize)
- return((u_char *)NULL);
- if (vflag != ALL && valid_save &&
- !bcmp(curp, savp, nread)) {
+ return(NULL);
+ if (!need && vflag != ALL &&
+ !memcmp(curp, savp, nread)) {
if (vflag != DUP)
(void)printf("*\n");
- return((u_char *)NULL);
+ return(NULL);
}
- bzero((char *)curp + nread, need);
+ memset((char *)curp + nread, 0, need);
eaddress = address + nread;
return(curp);
}
@@ -264,8 +276,8 @@ get()
if (length != -1)
length -= n;
if (!(need -= n)) {
- if (vflag == ALL || vflag == FIRST || !valid_save ||
- bcmp(curp, savp, blocksize)) {
+ if (vflag == ALL || vflag == FIRST ||
+ memcmp(curp, savp, blocksize)) {
if (vflag == DUP || vflag == FIRST)
vflag = WAIT;
return(curp);
@@ -273,7 +285,7 @@ get()
if (vflag == WAIT)
(void)printf("*\n");
vflag = DUP;
- address = savaddress += blocksize;
+ address += blocksize;
need = blocksize;
nread = 0;
}
@@ -282,13 +294,10 @@ get()
}
}
-extern off_t skip; /* bytes to skip */
-
int
next(argv)
char **argv;
{
- extern int exitval;
static int done;
int statok;
@@ -322,34 +331,49 @@ next(argv)
void
doskip(fname, statok)
- char *fname;
+ const char *fname;
int statok;
{
- struct stat sbuf;
+ int cnt;
+ struct stat sb;
if (statok) {
- if (fstat(fileno(stdin), &sbuf))
- err(1, "%s", fname);
- if (skip >= sbuf.st_size) {
- skip -= sbuf.st_size;
- address += sbuf.st_size;
+ if (fstat(fileno(stdin), &sb))
+ err(1, "fstat %s", fname);
+ if (S_ISREG(sb.st_mode) && skip >= sb.st_size) {
+ address += sb.st_size;
+ skip -= sb.st_size;
return;
}
}
- if (fseek(stdin, skip, SEEK_SET))
- err(1, "%s", fname);
- savaddress = address += skip;
- skip = 0;
+ if (S_ISREG(sb.st_mode)) {
+ if (fseek(stdin, skip, SEEK_SET))
+ err(1, "fseek %s", fname);
+ address += skip;
+ skip = 0;
+ } else {
+ for (cnt = 0; cnt < skip; ++cnt)
+ if (getchar() == EOF)
+ break;
+ address += cnt;
+ skip -= cnt;
+ }
}
-char *
-emalloc(size)
- int size;
+void *
+emalloc(allocsize)
+ int allocsize;
{
- char *p;
+ void *p;
- if (!(p = malloc((u_int)size)))
- err(1, "malloc");
- bzero(p, size);
+ if ((p = malloc((u_int)allocsize)) == NULL)
+ nomem();
+ memset(p, 0, allocsize);
return(p);
}
+
+void
+nomem()
+{
+ err(1, NULL);
+}
diff --git a/usr.bin/hexdump/hexdump.1 b/usr.bin/hexdump/hexdump.1
index e1dcb9e4a6e..19b66c794c1 100644
--- a/usr.bin/hexdump/hexdump.1
+++ b/usr.bin/hexdump/hexdump.1
@@ -1,6 +1,8 @@
-.\" $OpenBSD: hexdump.1,v 1.12 2000/11/09 17:52:14 aaron Exp $
-.\" Copyright (c) 1989, 1990 The Regents of the University of California.
-.\" All rights reserved.
+.\" $OpenBSD: hexdump.1,v 1.13 2001/12/30 08:17:32 pvalchev Exp $
+.\" $NetBSD: hexdump.1,v 1.14 2001/12/07 14:46:24 bjh21 Exp $
+.\"
+.\" Copyright (c) 1989, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -30,9 +32,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" from: @(#)hexdump.1 5.12 (Berkeley) 7/27/91
+.\" from: @(#)hexdump.1 8.2 (Berkeley) 4/18/94
.\"
-.Dd July 27, 1991
+.Dd April 18, 1994
.Dt HEXDUMP 1
.Os
.Sh NAME
@@ -40,14 +42,20 @@
.Nd ascii, decimal, hexadecimal, octal dump
.Sh SYNOPSIS
.Nm hexdump
-.Op Fl bcdovx
+.Op Fl bcCdovx
+.Bk -words
.Op Fl e Ar format_string
+.Ek
+.Bk -words
.Op Fl f Ar format_file
+.Ek
+.Bk -words
.Op Fl n Ar length
+.Ek
.Bk -words
-.Op Fl s Ar offset
+.Op Fl s Ar skip
.Ek
-.Ar file Op Ar ...
+.Ar file ...
.Sh DESCRIPTION
The
.Nm
@@ -67,6 +75,11 @@ in octal, per line.
Display the input offset in hexadecimal, followed by sixteen
space-separated, three column, space-filled, characters of input
data per line.
+.It Fl C
+.Em Canonical hex+ASCII display .
+Display the input offset in hexadecimal, followed by sixteen
+space-separated, two column, hexadecimal bytes, followed by the
+same sixteen bytes in %_p format enclosed in ``|'' characters.
.It Fl d
.Em Two-byte decimal display .
Display the input offset in hexadecimal, followed by eight
@@ -167,7 +180,7 @@ Any whitespace before or after the slash is ignored.
The format is required and must be surrounded by double quote
.Pq \&"\& \&"
marks.
-It is interpreted as an fprintf-style format string (see
+It is interpreted as a fprintf-style format string (see
.Xr fprintf 3 ) ,
with the
following exceptions:
@@ -185,9 +198,11 @@ default which prints the entire string if the precision is unspecified).
.It
The conversion characters
.Sq h ,
+.Sq l ,
.Sq n ,
+.Sq p ,
and
-.Sq p
+.Sq q
are not supported.
.It
The single character escape sequences
@@ -258,7 +273,7 @@ One byte counts only.
.Li \&%d , \&%i , \&%o ,
.Li \&%u , \&%X , \&%x
.Xc
-Four byte default, one and two byte counts supported.
+Four byte default, one, two, four and eight byte counts supported.
.It Xo
.Li \&%E , \&%e , \&%f ,
.Li \&%G , \&%g
@@ -320,7 +335,7 @@ to specifying the
option.
.Pp
.Nm
-exits 0 on success or >0 if an error occurred.
+exits 0 on success and >0 if an error occurred.
.Sh EXAMPLES
Display the input in perusal format:
.Bd -literal -offset indent
@@ -336,9 +351,3 @@ Implement the \-x option:
.Ed
.Sh SEE ALSO
.Xr od 1
-.Sh STANDARDS
-The
-.Nm
-utility is expected to be
-.St -p1003.2
-compatible.
diff --git a/usr.bin/hexdump/hexdump.c b/usr.bin/hexdump/hexdump.c
index c1dda5e0762..52b99388364 100644
--- a/usr.bin/hexdump/hexdump.c
+++ b/usr.bin/hexdump/hexdump.c
@@ -1,8 +1,9 @@
-/* $OpenBSD: hexdump.c,v 1.6 2001/11/19 19:02:14 mpech Exp $ */
+/* $OpenBSD: hexdump.c,v 1.7 2001/12/30 08:17:32 pvalchev Exp $ */
+/* $NetBSD: hexdump.c,v 1.7 1997/10/19 02:34:06 lukem Exp $ */
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,7 +42,7 @@ char copyright[] =
#ifndef lint
/*static char sccsid[] = "from: @(#)hexdump.c 5.5 (Berkeley) 6/1/90";*/
-static char rcsid[] = "$OpenBSD: hexdump.c,v 1.6 2001/11/19 19:02:14 mpech Exp $";
+static char rcsid[] = "$OpenBSD: hexdump.c,v 1.7 2001/12/30 08:17:32 pvalchev Exp $";
#endif /* not lint */
#include <sys/types.h>
@@ -54,10 +55,12 @@ int blocksize; /* data block size */
int exitval; /* final exit value */
int length = -1; /* max bytes to read */
+int main __P((int, char **));
+
int
main(argc, argv)
int argc;
- char **argv;
+ char *argv[];
{
FS *tfs;
char *p;
diff --git a/usr.bin/hexdump/hexdump.h b/usr.bin/hexdump/hexdump.h
index f3e6f935029..3f14b233169 100644
--- a/usr.bin/hexdump/hexdump.h
+++ b/usr.bin/hexdump/hexdump.h
@@ -1,7 +1,9 @@
-/* * $OpenBSD: hexdump.h,v 1.3 2001/09/30 07:17:03 pvalchev Exp $*/
+/* $OpenBSD: hexdump.h,v 1.4 2001/12/30 08:17:32 pvalchev Exp $ */
+/* $NetBSD: hexdump.h,v 1.7 2001/12/07 15:14:29 bjh21 Exp $ */
+
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: @(#)hexdump.h 5.4 (Berkeley) 6/1/90
+ * from: @(#)hexdump.h 8.1 (Berkeley) 6/6/93
*/
typedef struct _pr {
@@ -71,29 +73,36 @@ typedef struct _fs { /* format strings */
int bcnt;
} FS;
-extern FS *fshead; /* head of format strings list */
-extern int blocksize; /* data block size */
enum _vflag { ALL, DUP, FIRST, WAIT }; /* -v values */
-char *emalloc();
-void bpad __P((PR *));
-void conv_c __P((PR *, u_char *));
-void conv_u __P((PR *, u_char *));
-int next __P((char **));
-void doskip __P((char *, int));
-void nomem __P((void));
-void odoffset __P((int, char ***));
-void newsyntax __P((int, char ***));
-void oldsyntax __P((int, char ***));
-int size __P((FS *));
-void rewrite __P((FS *));
-void display __P((void));
-void badcnt __P((char *));
-void add __P((char *));
-void addfile __P((char *));
-void badcnt __P((char *));
-void badconv __P((char *));
-void badfmt __P((char *));
-void badsfmt __P((void));
-void escape __P((char *));
-void usage __P((void));
+extern int blocksize; /* data block size */
+extern int deprecated; /* od compatibility */
+extern FU *endfu; /* format at end-of-data */
+extern int exitval; /* final exit value */
+extern FS *fshead; /* head of format strings list */
+extern int length; /* max bytes to read */
+extern off_t skip; /* bytes to skip */
+extern enum _vflag vflag;
+
+void add __P((const char *));
+void addfile __P((char *));
+void badcnt __P((char *));
+void badconv __P((char *));
+void badfmt __P((const char *));
+void badsfmt __P((void));
+void bpad __P((PR *));
+void conv_c __P((PR *, u_char *));
+void conv_u __P((PR *, u_char *));
+void display __P((void));
+void doskip __P((const char *, int));
+/*void err __P((const char *, ...));*/
+void *emalloc __P((int));
+void escape __P((char *));
+u_char *get __P((void));
+void newsyntax __P((int, char ***));
+int next __P((char **));
+void nomem __P((void));
+void oldsyntax __P((int, char ***));
+void rewrite __P((FS *));
+int size __P((FS *));
+void usage __P((void));
diff --git a/usr.bin/hexdump/hexsyntax.c b/usr.bin/hexdump/hexsyntax.c
index c77bf7f8c8a..9b17191d4f3 100644
--- a/usr.bin/hexdump/hexsyntax.c
+++ b/usr.bin/hexdump/hexsyntax.c
@@ -1,8 +1,9 @@
-/* $OpenBSD: hexsyntax.c,v 1.5 2001/11/02 19:41:06 mickey Exp $ */
+/* $OpenBSD: hexsyntax.c,v 1.6 2001/12/30 08:17:32 pvalchev Exp $ */
+/* $NetBSD: hexsyntax.c,v 1.8 1998/04/08 23:48:57 jeremy Exp $ */
/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,15 +36,17 @@
#ifndef lint
/*static char sccsid[] = "from: @(#)hexsyntax.c 5.2 (Berkeley) 5/8/90";*/
-static char rcsid[] = "$OpenBSD: hexsyntax.c,v 1.5 2001/11/02 19:41:06 mickey Exp $";
+static char rcsid[] = "$OpenBSD: hexsyntax.c,v 1.6 2001/12/30 08:17:32 pvalchev Exp $";
#endif /* not lint */
#include <sys/types.h>
+
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
-#include <limits.h>
+#include <string.h>
#include <unistd.h>
-#include <err.h>
+
#include "hexdump.h"
off_t skip; /* bytes to skip */
@@ -53,15 +56,11 @@ newsyntax(argc, argvp)
int argc;
char ***argvp;
{
- extern enum _vflag vflag;
- extern FS *fshead;
- extern char *optarg;
- extern int length, optind;
int ch;
char *p, **argv;
argv = *argvp;
- while ((ch = getopt(argc, argv, "bcde:f:n:os:vx")) != -1)
+ while ((ch = getopt(argc, argv, "bcCde:f:n:os:vx")) != -1)
switch (ch) {
case 'b':
add("\"%07.7_Ax\n\"");
@@ -71,6 +70,11 @@ newsyntax(argc, argvp)
add("\"%07.7_Ax\n\"");
add("\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"");
break;
+ case 'C':
+ add("\"%08.8_Ax\n\"");
+ add("\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" ");
+ add("\" |\" 16/1 \"%_p\" \"|\\n\"");
+ break;
case 'd':
add("\"%07.7_Ax\n\"");
add("\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"");
@@ -83,7 +87,7 @@ newsyntax(argc, argvp)
break;
case 'n':
if ((length = atoi(optarg)) < 0)
- errx(1, "bad length value");
+ errx(1, "%s: bad length value", optarg);
break;
case 'o':
add("\"%07.7_Ax\n\"");
@@ -91,7 +95,7 @@ newsyntax(argc, argvp)
break;
case 's':
if ((skip = strtol(optarg, &p, 0)) < 0)
- errx(1, "bad skip value");
+ errx(1, "%s: bad skip value", optarg);
switch(*p) {
case 'b':
skip *= 512;
@@ -113,7 +117,6 @@ newsyntax(argc, argvp)
break;
case '?':
usage();
- exit(1);
}
if (!fshead) {
@@ -128,7 +131,7 @@ void
usage()
{
extern char *__progname;
- fprintf(stderr, "usage: %s [-bcdovx] [-e fmt] [-f fmt_file] "
- "[-n length] [-s skip] [file ...]", __progname);
+ fprintf(stderr, "usage: %s [-bcCdovx] [-e fmt] [-f fmt_file] "
+ "[-n length] [-s skip] [file ...]\n", __progname);
exit(1);
}
diff --git a/usr.bin/hexdump/od.1 b/usr.bin/hexdump/od.1
index 957905d2b0a..f2d722de1e9 100644
--- a/usr.bin/hexdump/od.1
+++ b/usr.bin/hexdump/od.1
@@ -1,8 +1,12 @@
-.\" $OpenBSD: od.1,v 1.8 2000/03/11 21:40:07 aaron Exp $
+.\" $OpenBSD: od.1,v 1.9 2001/12/30 08:17:32 pvalchev Exp $
+.\" $NetBSD: od.1,v 1.16 2001/12/07 01:23:42 bjh21 Exp $
.\"
-.\" Copyright (c) 1990 The Regents of the University of California.
+.\" Copyright (c) 2001 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Andrew Brown.
+.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
@@ -13,27 +17,25 @@
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" from: @(#)od.1 5.7 (Berkeley) 7/22/91
+.\" This product includes software developed by the NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
.\"
-.Dd July 27, 1991
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"/
+.Dd February 9, 2001
.Dt OD 1
.Os
.Sh NAME
@@ -42,24 +44,33 @@
.Sh SYNOPSIS
.Nm od
.Op Fl aBbcDdeFfHhIiLlOovXx
+.Bk -words
+.Op Fl j Ar skip
+.Ek
+.Bk -words
+.Op Fl N Ar length
+.Ek
+.Bk -words
+.Op Fl t Ar type_string
+.Ek
.Sm off
.Oo
.Op Cm \&+
.Li offset
.Op Cm \&.
.Op Cm Bb
+.Sm on
.Oc
-.Ar file
+.Ar file ...
.Sh DESCRIPTION
.Nm
has been deprecated in favor of
.Xr hexdump 1 .
.Pp
-.Nm hexdump ,
+.Xr hexdump 1 ,
if called as
.Nm od ,
-provides compatibility for the options listed above.
-.Pp
+provides compatibility for the options described below.
It does not provide compatibility for the
.Fl s
option (see
@@ -69,11 +80,231 @@ or the
.Fl p ,
or
.Fl w
-options, nor is compatibility provided for the
-.Dq label
-component of the offset syntax.
+options, nor is compatibility provided for the ``label'' component
+of the offset syntax.
+.Pp
+The options are as follows:
+.Bl -tag -width Fl
+.It Fl a
+.Em One-byte character display .
+Display the input offset in octal, followed by sixteen
+space-separated, three column, space-filled, characters of input data
+per line. Control characters are printed as their names instead of as
+c style escapes.
+.It Fl B
+Same as
+.Fl o .
+.It Fl b
+.Em One-byte octal display .
+Display the input offset in octal, followed by sixteen
+space-separated, three column, zero-filled, bytes of input data, in
+octal, per line. This is the default output style if no other is
+selected.
+.It Fl c
+.Em One-byte character display .
+Display the input offset in octal, followed by sixteen
+space-separated, three column, space-filled, characters of input data
+per line. Control characters are printed at c style escapes, or as
+three octal digits, if no c escape exists for the character.
+.It Fl d
+.Em Two-byte decimal display .
+Display the input offset in octal, followed by eight
+space-separated, five column, zero-filled, two-byte units
+of input data, in unsigned decimal, per line.
+.It Fl e
+.Em Eight-byte floating point display .
+Display the input offset in octal, followed by two space-separated,
+twenty-one column, space filled, eight byte units of input data, in
+floating point, per line.
+.It Fl F
+Same as
+.Fl e .
+.It Fl f
+.Em Four-byte floating point display .
+Display the input offset in octal, followed by four space-separated,
+14 column, space filled, four byte units of input data, in floating
+point, per line.
+.It Fl H
+.Em Four-byte hex display .
+Display the input offset in octal, followed by four space-separated,
+eight column, zero filled, four byte units of input data, in hex,
+per line.
+.It Fl h
+.Em Two-byte hex display .
+Display the input offset in octal, followed by eight space-separated,
+four column, zero filled, two byte units of input data, in hex,
+per line.
+.It Fl I
+.Em Four-byte decimal display .
+Display the input offset in octal, followed by four space-separated,
+eleven column, space filled, four byte units of input data, in
+decimal, per line.
+.It Fl i
+.Em Two-byte decimal display .
+Display the input offset in octal, followed by eight space-separated,
+six column, space filled, two-byte units of input data, in decimal,
+per line.
+.It Fl j Ar offset
+Skip
+.Ar offset
+bytes from the beginning of the input.
+By default,
+.Ar offset
+is interpreted as a decimal number.
+With a leading
+.Cm 0x
+or
+.Cm 0X ,
+.Ar offset
+is interpreted as a hexadecimal number,
+otherwise, with a leading
+.Cm 0 ,
+.Ar offset
+is interpreted as an octal number.
+Appending the character
+.Cm b ,
+.Cm k ,
+or
+.Cm m
+to
+.Ar offset
+causes it to be interpreted as a multiple of
+.Li 512 ,
+.Li 1024 ,
+or
+.Li 1048576 ,
+respectively.
+.It Fl L
+Same as
+.Fl I .
+.It Fl l
+Same as
+.Fl I .
+.It Fl N Ar length
+Interpret only
+.Ar length
+bytes of input.
+.It Fl O
+.Em Four-byte octal display .
+Display the input offset in octal, followed by four
+space-separated, eleven column, zero-filled, four-byte units
+of input data, in octal, per line.
+.It Fl o
+.Em Two-byte octal display .
+Display the input offset in octal, followed by eight
+space-separated, six column, zero-filled, two-byte units
+of input data, in octal, per line.
+.It Fl t Ar type_string
+Specify one or more output types. The
+.Em type_string
+option-argument must be a string specifying the types to be used when
+writing the input data. The string must consist of the type
+specification characters:
+.Pp
+.Cm a
+selects US-ASCII output, with control characters replaced with their
+names instead of as c escape sequences. See also the
+.Cm _u
+conversion provided by hexdump(1).
+.Pp
+.Cm c
+selects a standard character based conversion. See also the
+.Cm _c
+conversion provided by hexdump(1).
+.Pp
+.Cm f
+selects the floating point output format. This type character can be
+optionally followed by the characters
+.Cm 4
+or
+.Cm F
+to specify four byte floating point output, or
+.Cm 8
+or
+.Cm L
+to specify eight byte floating point output. The default output
+format is eight byte floats. See also the
+.Cm e
+conversion provided by hexdump(1).
+.Pp
+.Cm d ,
+.Cm o ,
+.Cm u ,
+or
+.Cm x
+select decimal, octal, unsigned decimal, or hex output respectively.
+These types can optionally be followed by
+.Cm C
+to specify
+.Em char Ns -sized
+output,
+.Cm S
+to specify
+.Em short Ns -sized
+output,
+.Cm I
+to specify
+.Em int Ns -sized
+output,
+.Cm L
+to specify
+.Em long Ns -sized
+output,
+.Cm 1
+to specify one-byte output,
+.Cm 2
+to specify two-byte output,
+.Cm 4
+to specify four-byte output, or
+.Cm 8
+to specify eight-byte output. The default output format is in
+four-byte quantities. See also the
+.Cm d ,
+.Cm o ,
+.Cm u ,
+and
+.Cm x
+conversions provided by hexdump(1).
+.\"(a|c|f[FLD]?|[doux][C1S2I4L8]?)*
+.It Fl v
+The
+.Fl v
+option causes
+.Nm
+to display all input data.
+Without the
+.Fl v
+option, any number of groups of output lines, which would be
+identical to the immediately preceding group of output lines (except
+for the input offsets), are replaced with a line comprised of a
+single asterisk.
+.It Fl X
+Same as
+.Fl H .
+.It Fl x
+Same as
+.Fl h .
+.El
+.Pp
+For each input file,
+.Nm
+sequentially copies the input to standard output, transforming the
+data according to the options given. If no options are specified, the
+default display is equivalent to specifying the
+.Fl o
+option.
+.Pp
+.Nm
+exits 0 on success and >0 if an error occurred.
.Sh SEE ALSO
.Xr hexdump 1 ,
.Xr strings 1
-.Sh BUGS
-Quite a few.
+.Sh HISTORY
+A
+.Nm
+command appears in
+.At v1 .
+.Pp
+This man page was written in February 2001 by Andrew Brown, shortly
+after he augmented the deprecated od syntax to include things he felt
+had been missing for a long time.
diff --git a/usr.bin/hexdump/odsyntax.c b/usr.bin/hexdump/odsyntax.c
index fc1fec435ce..c29ae72cf1c 100644
--- a/usr.bin/hexdump/odsyntax.c
+++ b/usr.bin/hexdump/odsyntax.c
@@ -1,8 +1,9 @@
-/* $OpenBSD: odsyntax.c,v 1.8 2001/11/19 19:02:14 mpech Exp $ */
+/* $OpenBSD: odsyntax.c,v 1.9 2001/12/30 08:17:32 pvalchev Exp $ */
+/* $NetBSD: odsyntax.c,v 1.15 2001/12/07 15:14:29 bjh21 Exp $ */
/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,34 +36,65 @@
#ifndef lint
/*static char sccsid[] = "from: @(#)odsyntax.c 5.4 (Berkeley) 3/8/91";*/
-static char rcsid[] = "$OpenBSD: odsyntax.c,v 1.8 2001/11/19 19:02:14 mpech Exp $";
+static char rcsid[] = "$OpenBSD: odsyntax.c,v 1.9 2001/12/30 08:17:32 pvalchev Exp $";
#endif /* not lint */
#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
+
#include <ctype.h>
#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
#include "hexdump.h"
int deprecated;
+static void odoffset __P((int, char ***));
+static void posixtypes __P((char *));
+static void odprecede __P((void));
+
+
+/*
+ * formats used for -t
+ */
+static const char *fmt[4][4] = {
+ {
+ "16/1 \"%3d \" \"\\n\"",
+ "8/2 \" %05d \" \"\\n\"",
+ "4/4 \" %010d \" \"\\n\"",
+ "2/8 \" %019d \" \"\\n\""
+ }, {
+ "16/1 \"%03o \" \"\\n\"",
+ "8/2 \" %06o \" \"\\n\"",
+ "4/4 \" %011o\" \"\\n\"",
+ "2/8 \" %022o \" \"\\n\""
+ }, {
+ "16/1 \"%03u \" \"\\n\"",
+ "8/2 \" %05u \" \"\\n\"",
+ "4/4 \" %010u \" \"\\n\"",
+ "2/8 \" %020u \" \"\\n\""
+ }, {
+ "16/1 \" %02x \" \"\\n\"",
+ "8/2 \" %04x \" \"\\n\"",
+ "4/4 \" %08x \" \"\\n\"",
+ "2/8 \" %16x \" \"\\n\""
+ }
+};
+
void
oldsyntax(argc, argvp)
int argc;
char ***argvp;
{
- extern enum _vflag vflag;
- extern FS *fshead;
- extern char *optarg;
- extern int optind;
int ch;
- char **argv;
- static void odprecede();
+ char *p, **argv;
deprecated = 1;
argv = *argvp;
- while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != -1)
+ while ((ch = getopt(argc, argv,
+ "aBbcDdeFfHhIij:LlN:OoPpst:wvXx")) != -1)
switch (ch) {
case 'a':
odprecede();
@@ -119,10 +151,32 @@ oldsyntax(argc, argvp)
odprecede();
add("8/2 \" %6d \" \"\\n\"");
break;
+ case 'j':
+ if ((skip = strtol(optarg, &p, 0)) < 0)
+ errx(1, "%s: bad skip value", optarg);
+ switch(*p) {
+ case 'b':
+ skip *= 512;
+ break;
+ case 'k':
+ skip *= 1024;
+ break;
+ case 'm':
+ skip *= 1048576;
+ break;
+ }
+ break;
+ case 'N':
+ if ((length = atoi(optarg)) < 0)
+ errx(1, "%s: bad length value", optarg);
+ break;
case 'O':
odprecede();
add("4/4 \" %011o \" \"\\n\"");
break;
+ case 't':
+ posixtypes(optarg);
+ break;
case 'v':
vflag = ALL;
break;
@@ -132,10 +186,10 @@ oldsyntax(argc, argvp)
case 'w':
case '?':
default:
- warnx("od(1) has been deprecated for hexdump(1)");
+ warnx("od(1) has been deprecated for hexdump(1).");
if (ch != '?')
- warnx("hexdump(1) compatibility doesn't"
- "support the -%c option%s",
+ warnx(
+"hexdump(1) compatibility doesn't support the -%c option%s\n",
ch, ch == 's' ? "; see strings(1)." : ".");
usage();
}
@@ -148,18 +202,114 @@ oldsyntax(argc, argvp)
argc -= optind;
*argvp += optind;
- odoffset(argc, argvp);
+ if (argc)
+ odoffset(argc, argvp);
}
-#define ishexdigit(c) \
- (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F')
+/*
+ * Interpret a POSIX-style -t argument.
+ */
+static void
+posixtypes(type_string)
+ char *type_string;
+{
+ int x, y, nbytes;
-void
+ while (*type_string) {
+ odprecede();
+ switch (*type_string) {
+ case 'a':
+ type_string++;
+ add("16/1 \"%3_u \" \"\\n\"");
+ break;
+ case 'c':
+ type_string++;
+ add("16/1 \"%3_c \" \"\\n\"");
+ break;
+ case 'f':
+ type_string++;
+ if (*type_string == 'F' ||
+ *type_string == '4') {
+ type_string++;
+ add("4/4 \" %14.7e\" \"\\n\"");
+ } else if (*type_string == 'L' ||
+ *type_string == '8') {
+ type_string++;
+ add("2/8 \" %16.14e\" \"\\n\"");
+ } else if (*type_string == 'D')
+ /* long doubles vary in size */
+ usage();
+ else
+ add("2/8 \" %16.14e\" \"\\n\"");
+ break;
+ case 'd':
+ x = 0;
+ goto extensions;
+ case 'o':
+ x = 1;
+ goto extensions;
+ case 'u':
+ x = 2;
+ goto extensions;
+ case 'x':
+ x = 3;
+ extensions:
+ type_string++;
+ y = 2;
+ if (isupper(*type_string)) {
+ switch(*type_string) {
+ case 'C':
+ nbytes = sizeof(char);
+ break;
+ case 'S':
+ nbytes = sizeof(short);
+ break;
+ case 'I':
+ nbytes = sizeof(int);
+ break;
+ case 'L':
+ nbytes = sizeof(long);
+ break;
+ default:
+ warnx("Bad type-size qualifier '%c'",
+ *type_string);
+ usage();
+ }
+ type_string++;
+ } else if (isdigit(*type_string))
+ nbytes = strtol(type_string, &type_string, 10);
+
+ switch (nbytes) {
+ case 1:
+ y = 0;
+ break;
+ case 2:
+ y = 1;
+ break;
+ case 4:
+ y = 2;
+ break;
+ case 8:
+ y = 3;
+ break;
+ default:
+ warnx("%d-byte integer formats are not "
+ "supported", nbytes);
+ usage();
+ }
+ add(fmt[x][y]);
+ break;
+ default:
+ usage();
+ }
+ }
+}
+
+static void
odoffset(argc, argvp)
int argc;
char ***argvp;
{
- extern off_t skip;
char *num, *p;
int base;
char *end;
@@ -174,13 +324,15 @@ odoffset(argc, argvp)
* multiplied the number by 512 or 1024 byte units. There was
* no way to assign a block count to a hex offset.
*
- * We assumes it's a file if the offset is bad.
+ * We assume it's a file if the offset is bad.
*/
- p = **argvp;
+ p = argc == 1 ? (*argvp)[0] : (*argvp)[1];
if (!p)
return;
+
if (*p != '+' && (argc < 2 ||
- (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1])))))
+ (!isdigit((unsigned char)p[0]) &&
+ (p[0] != 'x' || !isxdigit((unsigned char)p[1])))))
return;
base = 0;
@@ -190,7 +342,7 @@ odoffset(argc, argvp)
*/
if (p[0] == '+')
++p;
- if (p[0] == 'x' && ishexdigit(p[1])) {
+ if (p[0] == 'x' && isxdigit((unsigned char)p[1])) {
++p;
base = 16;
} else if (p[0] == '0' && p[1] == 'x') {
@@ -200,9 +352,9 @@ odoffset(argc, argvp)
/* skip over the number */
if (base == 16)
- for (num = p; ishexdigit(*p); ++p);
+ for (num = p; isxdigit((unsigned char)*p); ++p);
else
- for (num = p; isdigit(*p); ++p);
+ for (num = p; isdigit((unsigned char)*p); ++p);
/* check for no number */
if (num == p)
@@ -218,35 +370,39 @@ odoffset(argc, argvp)
skip = strtol(num, &end, base ? base : 8);
/* if end isn't the same as p, we got a non-octal digit */
- if (end != p)
+ if (end != p) {
skip = 0;
- else {
- if (*p) {
- if (*p == 'b')
- skip *= 512;
- else if (*p == 'B')
- skip *= 1024;
+ return;
+ }
+
+ if (*p) {
+ if (*p == 'B') {
+ skip *= 1024;
+ ++p;
+ } else if (*p == 'b') {
+ skip *= 512;
++p;
}
- if (*p)
- skip = 0;
- else {
- ++*argvp;
- /*
- * If the offset uses a non-octal base, the base of
- * the offset is changed as well. This isn't pretty,
- * but it's easy.
- */
+ }
+ if (*p) {
+ skip = 0;
+ return;
+ }
+ /*
+ * If the offset uses a non-octal base, the base of the offset
+ * is changed as well. This isn't pretty, but it's easy.
+ */
#define TYPE_OFFSET 7
- if (base == 16) {
- fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
- fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
- } else if (base == 10) {
- fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
- fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
- }
- }
+ if (base == 16) {
+ fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
+ fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
+ } else if (base == 10) {
+ fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
+ fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
}
+
+ /* Terminate file list. */
+ (*argvp)[1] = NULL;
}
static void
diff --git a/usr.bin/hexdump/parse.c b/usr.bin/hexdump/parse.c
index af4144820a9..e3198ab99bb 100644
--- a/usr.bin/hexdump/parse.c
+++ b/usr.bin/hexdump/parse.c
@@ -1,8 +1,9 @@
-/* $OpenBSD: parse.c,v 1.8 2001/11/19 19:02:14 mpech Exp $ */
+/* $OpenBSD: parse.c,v 1.9 2001/12/30 08:17:32 pvalchev Exp $ */
+/* $NetBSD: parse.c,v 1.12 2001/12/07 13:37:39 bjh21 Exp $ */
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,23 +36,21 @@
#ifndef lint
/*static char sccsid[] = "from: @(#)parse.c 5.6 (Berkeley) 3/9/91";*/
-static char rcsid[] = "$OpenBSD: parse.c,v 1.8 2001/11/19 19:02:14 mpech Exp $";
+static char rcsid[] = "$OpenBSD: parse.c,v 1.9 2001/12/30 08:17:32 pvalchev Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/file.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
-#include <ctype.h>
#include <string.h>
-#include <err.h>
-#include "hexdump.h"
-void addfile __P((char *));
-void add __P((char *));
-int size __P((FS *));
-void rewrite __P((FS *));
-void escape __P((char *));
+#include "hexdump.h"
FU *endfu; /* format at end-of-data */
@@ -61,18 +60,19 @@ addfile(name)
{
char *p;
FILE *fp;
- size_t len;
-
- if (!(fp = fopen(name, "r")))
- err(1, "%s", name);
- while ((p = fgetln(fp, &len))) {
- if (*(p + len - 1) == '\n')
- *(p + len - 1) = '\0';
- else {
- warnx("incomplete line");
+ int ch;
+ char buf[2048 + 1];
+
+ if ((fp = fopen(name, "r")) == NULL)
+ err(1, "fopen %s", name);
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (!(p = strchr(buf, '\n'))) {
+ warnx("line too long.");
+ while ((ch = getchar()) != '\n' && ch != EOF);
continue;
}
- for (; *p && isspace(*p); ++p);
+ *p = '\0';
+ for (p = buf; *p && isspace((unsigned char)*p); ++p);
if (!*p || *p == '#')
continue;
add(p);
@@ -82,17 +82,16 @@ addfile(name)
void
add(fmt)
- char *fmt;
+ const char *fmt;
{
- char *p;
+ const char *p;
static FS **nextfs;
FS *tfs;
FU *tfu, **nextfu;
- char *savep, *emalloc();
+ const char *savep;
/* start new linked list of format units */
- /* NOSTRICT */
- tfs = (FS *)emalloc(sizeof(FS));
+ tfs = emalloc(sizeof(FS));
if (!fshead)
fshead = tfs;
else
@@ -103,62 +102,59 @@ add(fmt)
/* take the format string and break it up into format units */
for (p = fmt;;) {
/* skip leading white space */
- for (; isspace(*p); ++p);
+ for (; isspace((unsigned char)*p); ++p);
if (!*p)
break;
/* allocate a new format unit and link it in */
- /* NOSTRICT */
- tfu = (FU *)emalloc(sizeof(FU));
+ tfu = emalloc(sizeof(FU));
*nextfu = tfu;
nextfu = &tfu->nextfu;
tfu->reps = 1;
/* if leading digit, repetition count */
- if (isdigit(*p)) {
- for (savep = p; isdigit(*p); ++p);
- if (!isspace(*p) && *p != '/')
- errx(1, "bad format {%s}", fmt);
+ if (isdigit((unsigned char)*p)) {
+ for (savep = p; isdigit((unsigned char)*p); ++p);
+ if (!isspace((unsigned char)*p) && *p != '/')
+ badfmt(fmt);
/* may overwrite either white space or slash */
tfu->reps = atoi(savep);
tfu->flags = F_SETREP;
/* skip trailing white space */
- for (++p; isspace(*p); ++p);
+ for (++p; isspace((unsigned char)*p); ++p);
}
/* skip slash and trailing white space */
if (*p == '/')
- while (isspace(*++p));
+ while (isspace((unsigned char)*++p));
/* byte count */
- if (isdigit(*p)) {
- for (savep = p; isdigit(*p); ++p);
- if (!isspace(*p))
- errx(1, "bad format {%s}", fmt);
+ if (isdigit((unsigned char)*p)) {
+ for (savep = p; isdigit((unsigned char)*p); ++p);
+ if (!isspace((unsigned char)*p))
+ badfmt(fmt);
tfu->bcnt = atoi(savep);
/* skip trailing white space */
- for (++p; isspace(*p); ++p);
+ for (++p; isspace((unsigned char)*p); ++p);
}
/* format */
if (*p != '"')
- errx(1, "bad format {%s}", fmt);
+ badfmt(fmt);
for (savep = ++p; *p != '"';)
if (*p++ == 0)
- errx(1, "bad format {%s}", fmt);
+ badfmt(fmt);
if (!(tfu->fmt = malloc(p - savep + 1)))
- err(1, "malloc");
+ nomem();
(void) strncpy(tfu->fmt, savep, p - savep);
tfu->fmt[p - savep] = '\0';
escape(tfu->fmt);
p++;
}
- /* no single fu in fmt */
- if (tfs->nextfu == NULL)
- errx(1, "bad format {%s}", fmt);
}
static const char *spec = ".#-+ 0123456789";
+
int
size(fs)
FS *fs;
@@ -182,9 +178,9 @@ size(fs)
* case it's a %s format.
*/
while (strchr(spec + 1, *++fmt));
- if (*fmt == '.' && isdigit(*++fmt)) {
+ if (*fmt == '.' && isdigit((unsigned char)*++fmt)) {
prec = atoi(fmt);
- while (isdigit(*++fmt));
+ while (isdigit((unsigned char)*++fmt));
}
switch(*fmt) {
case 'c':
@@ -210,7 +206,7 @@ size(fs)
}
cursize += bcnt * fu->reps;
}
- return(cursize);
+ return (cursize);
}
void
@@ -221,26 +217,27 @@ rewrite(fs)
PR *pr, **nextpr;
FU *fu;
char *p1, *p2;
- char savech, *fmtp;
+ char savech, *fmtp, cs[3];
int nconv, prec;
+ nextpr = NULL;
+ prec = 0;
for (fu = fs->nextfu; fu; fu = fu->nextfu) {
/*
- * break each format unit into print units; each
- * conversion character gets its own.
+ * Break each format unit into print units; each conversion
+ * character gets its own.
*/
for (nconv = 0, fmtp = fu->fmt; *fmtp; nextpr = &pr->nextpr) {
- /* NOSTRICT */
- pr = (PR *)emalloc(sizeof(PR));
+ pr = emalloc(sizeof(PR));
if (!fu->nextpr)
fu->nextpr = pr;
else
*nextpr = pr;
- /* skip preceding text and up to the next % sign */
+ /* Skip preceding text and up to the next % sign. */
for (p1 = fmtp; *p1 && *p1 != '%'; ++p1);
- /* only text in the string */
+ /* Only text in the string. */
if (!*p1) {
pr->fmt = fmtp;
pr->flags = F_TEXT;
@@ -248,33 +245,36 @@ rewrite(fs)
}
/*
- * get precision for %s -- if have a byte count, don't
+ * Get precision for %s -- if have a byte count, don't
* need it.
*/
if (fu->bcnt) {
sokay = USEBCNT;
- /* skip to conversion character */
+ /* Skip to conversion character. */
for (++p1; strchr(spec, *p1); ++p1);
} else {
- /* skip any special chars, field width */
+ /* Skip any special chars, field width. */
while (strchr(spec + 1, *++p1));
- if (*p1 == '.' && isdigit(*++p1)) {
+ if (*p1 == '.' &&
+ isdigit((unsigned char)*++p1)) {
sokay = USEPREC;
prec = atoi(p1);
- while (isdigit(*++p1));
- }
- else
+ while (isdigit((unsigned char)*++p1))
+ continue;
+ } else
sokay = NOTOKAY;
}
- p2 = p1 + 1; /* set end pointer */
+ p2 = p1 + 1; /* Set end pointer. */
+ cs[0] = *p1; /* Set conversion string. */
+ cs[1] = '\0';
/*
- * figure out the byte count for each conversion;
+ * Figure out the byte count for each conversion;
* rewrite the format as necessary, set up blank-
* padding for end of data.
*/
- switch(*p1) {
+ switch(cs[0]) {
case 'c':
pr->flags = F_CHAR;
switch(fu->bcnt) {
@@ -282,31 +282,19 @@ rewrite(fs)
pr->bcnt = 1;
break;
default:
- errx(1, "bad byte count for conversion character \'%c\'", *p1);
+ p1[1] = '\0';
+ badcnt(p1);
}
break;
case 'd': case 'i':
pr->flags = F_INT;
- goto sw1;
- case 'l':
- ++p2;
- switch(p1[1]) {
- case 'd': case 'i':
- ++p1;
- pr->flags = F_INT;
- goto sw1;
- case 'o': case 'u': case 'x': case 'X':
- ++p1;
- pr->flags = F_UINT;
- goto sw1;
- default:
- p1[2] = '\0';
- errx(1, "bad conversion character %%%s", p1);
- }
- /* NOTREACHED */
+ goto isint;
case 'o': case 'u': case 'x': case 'X':
pr->flags = F_UINT;
-sw1: switch(fu->bcnt) {
+isint: cs[2] = '\0';
+ cs[1] = cs[0];
+ cs[0] = 'q';
+ switch(fu->bcnt) {
case 0: case 4:
pr->bcnt = 4;
break;
@@ -316,8 +304,12 @@ sw1: switch(fu->bcnt) {
case 2:
pr->bcnt = 2;
break;
+ case 8:
+ pr->bcnt = 8;
+ break;
default:
- errx(1, "bad byte count for conversion character \'%c\'", *p1);
+ p1[1] = '\0';
+ badcnt(p1);
}
break;
case 'e': case 'E': case 'f': case 'g': case 'G':
@@ -330,14 +322,15 @@ sw1: switch(fu->bcnt) {
pr->bcnt = 4;
break;
default:
- errx(1, "bad byte count for conversion character \'%c\'", *p1);
+ p1[1] = '\0';
+ badcnt(p1);
}
break;
case 's':
pr->flags = F_STR;
switch(sokay) {
case NOTOKAY:
- errx(1, "%%s requires a precision or a byte count");
+ badsfmt();
case USEBCNT:
pr->bcnt = fu->bcnt;
break;
@@ -358,62 +351,65 @@ sw1: switch(fu->bcnt) {
++p2;
switch(p1[2]) {
case 'd': case 'o': case'x':
- *p1 = 'q';
- p1[1] = p1[2];
+ cs[0] = 'q';
+ cs[1] = p1[2];
+ cs[2] = '\0';
break;
default:
p1[3] = '\0';
- errx(1, "bad conversion character %%%s", p1);
+ badconv(p1);
}
break;
case 'c':
pr->flags = F_C;
- /* *p1 = 'c'; set in conv_c */
- goto sw2;
+ /* cs[0] = 'c'; set in conv_c */
+ goto isint2;
case 'p':
pr->flags = F_P;
- *p1 = 'c';
- goto sw2;
+ cs[0] = 'c';
+ goto isint2;
case 'u':
pr->flags = F_U;
- /* *p1 = 'c'; set in conv_u */
-sw2: switch(fu->bcnt) {
+ /* cs[0] = 'c'; set in conv_u */
+isint2: switch(fu->bcnt) {
case 0: case 1:
pr->bcnt = 1;
break;
default:
p1[2] = '\0';
- errx(1, "bad byte count for conversion character \'%s\'", p1);
+ badcnt(p1);
}
break;
default:
p1[2] = '\0';
- errx(1, "bad conversion character %%%s", p1);
+ badconv(p1);
}
break;
default:
- errx(1, "bad conversion character %%%c", *p1);
+ p1[1] = '\0';
+ badconv(p1);
}
/*
- * copy to PR format string, set conversion character
+ * Copy to PR format string, set conversion character
* pointer, update original.
*/
savech = *p2;
- p1[(pr->flags&F_ADDRESS)?2:1] = '\0';
- if (!(pr->fmt = strdup(fmtp)))
- err(1, "malloc");
+ p1[0] = '\0';
+ pr->fmt = emalloc(strlen(fmtp) + strlen(cs) + 1);
+ (void)strcpy(pr->fmt, fmtp);
+ (void)strcat(pr->fmt, cs);
*p2 = savech;
pr->cchar = pr->fmt + (p1 - fmtp);
fmtp = p2;
- /* only one conversion character if byte count */
+ /* Only one conversion character if byte count. */
if (!(pr->flags&F_ADDRESS) && fu->bcnt && nconv++)
errx(1,
- "byte count with multiple conversion characters");
+ "byte count with multiple conversion characters");
}
/*
- * if format unit byte count not specified, figure it out
+ * If format unit byte count not specified, figure it out
* so can adjust rep count later.
*/
if (!fu->bcnt)
@@ -421,15 +417,15 @@ sw2: switch(fu->bcnt) {
fu->bcnt += pr->bcnt;
}
/*
- * if the format string interprets any data at all, and it's
+ * If the format string interprets any data at all, and it's
* not the same as the blocksize, and its last format unit
* interprets any data at all, and has no iteration count,
* repeat it as necessary.
*
- * if, rep count is greater than 1, no trailing whitespace
+ * If, rep count is greater than 1, no trailing whitespace
* gets output from the last iteration of the format unit.
*/
- for (fu = fs->nextfu;; fu = fu->nextfu) {
+ for (fu = fs->nextfu; fu; fu = fu->nextfu) {
if (!fu->nextfu && fs->bcnt < blocksize &&
!(fu->flags&F_SETREP) && fu->bcnt)
fu->reps += (blocksize - fs->bcnt) / fu->bcnt;
@@ -438,13 +434,19 @@ sw2: switch(fu->bcnt) {
if (!pr->nextpr)
break;
for (p1 = pr->fmt, p2 = NULL; *p1; ++p1)
- p2 = isspace(*p1) ? p1 : NULL;
+ p2 = isspace((unsigned char)*p1) ? p1 : NULL;
if (p2)
pr->nospace = p2;
}
- if (!fu->nextfu)
- break;
}
+#ifdef DEBUG
+ for (fu = fs->nextfu; fu; fu = fu->nextfu) {
+ (void)printf("fmt:");
+ for (pr = fu->nextpr; pr; pr = pr->nextpr)
+ (void)printf(" {%s}", pr->fmt);
+ (void)printf("\n");
+ }
+#endif
}
void
@@ -489,3 +491,30 @@ escape(p1)
}
}
}
+
+void
+badcnt(s)
+ char *s;
+{
+ errx(1, "%s: bad byte count", s);
+}
+
+void
+badsfmt()
+{
+ errx(1, "%%s: requires a precision or a byte count\n");
+}
+
+void
+badfmt(fmt)
+ const char *fmt;
+{
+ errx(1, "\"%s\": bad format\n", fmt);
+}
+
+void
+badconv(ch)
+ char *ch;
+{
+ errx(1, "%%%s: bad conversion character\n", ch);
+}