version 1.8, 2001/11/19 19:02:14 |
version 1.9, 2001/12/30 08:17:32 |
|
|
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
|
/* $NetBSD: odsyntax.c,v 1.15 2001/12/07 15:14:29 bjh21 Exp $ */ |
|
|
/*- |
/*- |
* Copyright (c) 1990 The Regents of the University of California. |
* Copyright (c) 1990, 1993 |
* All rights reserved. |
* The Regents of the University of California. All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* modification, are permitted provided that the following conditions |
|
|
#endif /* not lint */ |
#endif /* not lint */ |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <stdlib.h> |
|
#include <stdio.h> |
|
#include <ctype.h> |
#include <ctype.h> |
#include <err.h> |
#include <err.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
|
#include "hexdump.h" |
#include "hexdump.h" |
|
|
int deprecated; |
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 |
void |
oldsyntax(argc, argvp) |
oldsyntax(argc, argvp) |
int argc; |
int argc; |
char ***argvp; |
char ***argvp; |
{ |
{ |
extern enum _vflag vflag; |
|
extern FS *fshead; |
|
extern char *optarg; |
|
extern int optind; |
|
int ch; |
int ch; |
char **argv; |
char *p, **argv; |
static void odprecede(); |
|
|
|
deprecated = 1; |
deprecated = 1; |
argv = *argvp; |
argv = *argvp; |
while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != -1) |
while ((ch = getopt(argc, argv, |
|
"aBbcDdeFfHhIij:LlN:OoPpst:wvXx")) != -1) |
switch (ch) { |
switch (ch) { |
case 'a': |
case 'a': |
odprecede(); |
odprecede(); |
|
|
odprecede(); |
odprecede(); |
add("8/2 \" %6d \" \"\\n\""); |
add("8/2 \" %6d \" \"\\n\""); |
break; |
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': |
case 'O': |
odprecede(); |
odprecede(); |
add("4/4 \" %011o \" \"\\n\""); |
add("4/4 \" %011o \" \"\\n\""); |
break; |
break; |
|
case 't': |
|
posixtypes(optarg); |
|
break; |
case 'v': |
case 'v': |
vflag = ALL; |
vflag = ALL; |
break; |
break; |
|
|
case 'w': |
case 'w': |
case '?': |
case '?': |
default: |
default: |
warnx("od(1) has been deprecated for hexdump(1)"); |
warnx("od(1) has been deprecated for hexdump(1)."); |
if (ch != '?') |
if (ch != '?') |
warnx("hexdump(1) compatibility doesn't" |
warnx( |
"support the -%c option%s", |
"hexdump(1) compatibility doesn't support the -%c option%s\n", |
ch, ch == 's' ? "; see strings(1)." : "."); |
ch, ch == 's' ? "; see strings(1)." : "."); |
usage(); |
usage(); |
} |
} |
|
|
argc -= optind; |
argc -= optind; |
*argvp += 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) |
odoffset(argc, argvp) |
int argc; |
int argc; |
char ***argvp; |
char ***argvp; |
{ |
{ |
extern off_t skip; |
|
char *num, *p; |
char *num, *p; |
int base; |
int base; |
char *end; |
char *end; |
|
|
* multiplied the number by 512 or 1024 byte units. There was |
* multiplied the number by 512 or 1024 byte units. There was |
* no way to assign a block count to a hex offset. |
* 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) |
if (!p) |
return; |
return; |
|
|
if (*p != '+' && (argc < 2 || |
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; |
return; |
|
|
base = 0; |
base = 0; |
|
|
*/ |
*/ |
if (p[0] == '+') |
if (p[0] == '+') |
++p; |
++p; |
if (p[0] == 'x' && ishexdigit(p[1])) { |
if (p[0] == 'x' && isxdigit((unsigned char)p[1])) { |
++p; |
++p; |
base = 16; |
base = 16; |
} else if (p[0] == '0' && p[1] == 'x') { |
} else if (p[0] == '0' && p[1] == 'x') { |
|
|
|
|
/* skip over the number */ |
/* skip over the number */ |
if (base == 16) |
if (base == 16) |
for (num = p; ishexdigit(*p); ++p); |
for (num = p; isxdigit((unsigned char)*p); ++p); |
else |
else |
for (num = p; isdigit(*p); ++p); |
for (num = p; isdigit((unsigned char)*p); ++p); |
|
|
/* check for no number */ |
/* check for no number */ |
if (num == p) |
if (num == p) |
|
|
skip = strtol(num, &end, base ? base : 8); |
skip = strtol(num, &end, base ? base : 8); |
|
|
/* if end isn't the same as p, we got a non-octal digit */ |
/* if end isn't the same as p, we got a non-octal digit */ |
if (end != p) |
if (end != p) { |
skip = 0; |
skip = 0; |
else { |
return; |
if (*p) { |
} |
if (*p == 'b') |
|
skip *= 512; |
if (*p) { |
else if (*p == 'B') |
if (*p == 'B') { |
skip *= 1024; |
skip *= 1024; |
++p; |
++p; |
|
} else if (*p == 'b') { |
|
skip *= 512; |
|
++p; |
} |
} |
if (*p) |
} |
skip = 0; |
if (*p) { |
else { |
skip = 0; |
++*argvp; |
return; |
/* |
} |
* If the offset uses a non-octal base, the base of |
/* |
* the offset is changed as well. This isn't pretty, |
* If the offset uses a non-octal base, the base of the offset |
* but it's easy. |
* is changed as well. This isn't pretty, but it's easy. |
*/ |
*/ |
#define TYPE_OFFSET 7 |
#define TYPE_OFFSET 7 |
if (base == 16) { |
if (base == 16) { |
fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; |
fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; |
fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; |
fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; |
} else if (base == 10) { |
} else if (base == 10) { |
fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; |
fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; |
fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; |
fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; |
} |
|
} |
|
} |
} |
|
|
|
/* Terminate file list. */ |
|
(*argvp)[1] = NULL; |
} |
} |
|
|
static void |
static void |