forked from Imagelibrary/rtems
2009-06-12 Chris Johns <chrisj@rtems.org>
* libmisc/shell/dd-args.c, libmisc/shell/dd-conv.c,
libmisc/shell/dd-conv_tab.c, libmisc/shell/dd-misc.c,
libmisc/shell/dd-position.c, libmisc/shell/dd.h,
libmisc/shell/extern-dd.h, libmisc/shell/hexdump-conv.c,
libmisc/shell/hexdump-display.c, libmisc/shell/hexdump-odsyntax.c,
libmisc/shell/hexdump-parse.c, libmisc/shell/hexdump.h,
libmisc/shell/hexsyntax.c, libmisc/shell/main_dd.c,
libmisc/shell/main_hexdump.c: New.
* libmisc/Makefile.am, libmisc/shell/shellconfig.h: Add dd and
hexdump commands.
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
2009-06-12 Chris Johns <chrisj@rtems.org>
|
||||
|
||||
* libmisc/shell/dd-args.c, libmisc/shell/dd-conv.c,
|
||||
libmisc/shell/dd-conv_tab.c, libmisc/shell/dd-misc.c,
|
||||
libmisc/shell/dd-position.c, libmisc/shell/dd.h,
|
||||
libmisc/shell/extern-dd.h, libmisc/shell/hexdump-conv.c,
|
||||
libmisc/shell/hexdump-display.c, libmisc/shell/hexdump-odsyntax.c,
|
||||
libmisc/shell/hexdump-parse.c, libmisc/shell/hexdump.h,
|
||||
libmisc/shell/hexsyntax.c, libmisc/shell/main_dd.c,
|
||||
libmisc/shell/main_hexdump.c: New.
|
||||
* libmisc/Makefile.am, libmisc/shell/shellconfig.h: Add dd and
|
||||
hexdump commands.
|
||||
|
||||
2009-06-12 Chris Johns <chrisj@rtems.org>
|
||||
|
||||
* libblock/include/rtems/flashdisk.h,
|
||||
|
||||
@@ -86,7 +86,12 @@ libshell_a_SOURCES = shell/cat_file.c shell/cmds.c shell/internal.h \
|
||||
shell/verrx.c shell/vwarn.c shell/vwarnx.c shell/warn.c shell/warnx.c \
|
||||
shell/fts.c shell/print_heapinfo.c shell/main_wkspaceinfo.c \
|
||||
shell/shell_script.c shell/login_prompt.c shell/login_check.c \
|
||||
shell/fdisk.c shell/main_rtc.c
|
||||
shell/fdisk.c shell/main_rtc.c \
|
||||
shell/dd-args.c shell/main_dd.c shell/dd-conv.c shell/dd-conv_tab.c shell/dd-misc.c \
|
||||
shell/dd-position.c \
|
||||
shell/main_hexdump.c shell/hexdump-conv.c shell/hexdump-display.c \
|
||||
shell/hexdump-odsyntax.c shell/hexdump-parse.c shell/hexsyntax.c
|
||||
|
||||
if LIBNETWORKING
|
||||
libshell_a_SOURCES += shell/main_mount_ftp.c shell/main_mount_tftp.c \
|
||||
shell/main_ifconfig.c shell/main_route.c shell/main_netstats.c \
|
||||
|
||||
503
cpukit/libmisc/shell/dd-args.c
Normal file
503
cpukit/libmisc/shell/dd-args.c
Normal file
@@ -0,0 +1,503 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/bin/dd/args.c,v 1.40 2004/08/15 19:10:05 rwatson Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dd.h"
|
||||
#include "extern-dd.h"
|
||||
|
||||
#define strtouq strtoul
|
||||
#define strtoq strtol
|
||||
|
||||
static int c_arg(const void *, const void *);
|
||||
static int c_conv(const void *, const void *);
|
||||
static void f_bs(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_cbs(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_conv(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_count(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_files(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_fillchar(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_ibs(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_if(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_obs(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_of(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_seek(rtems_shell_dd_globals* globals, char *);
|
||||
static void f_skip(rtems_shell_dd_globals* globals, char *);
|
||||
static uintmax_t get_num(rtems_shell_dd_globals* globals, const char *);
|
||||
static off_t get_off_t(rtems_shell_dd_globals* globals, const char *);
|
||||
|
||||
static const struct arg {
|
||||
const char *name;
|
||||
void (*f)(rtems_shell_dd_globals* globals, char *);
|
||||
u_int set, noset;
|
||||
} args[] = {
|
||||
{ "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC },
|
||||
{ "cbs", f_cbs, C_CBS, C_CBS },
|
||||
{ "conv", f_conv, 0, 0 },
|
||||
{ "count", f_count, C_COUNT, C_COUNT },
|
||||
{ "files", f_files, C_FILES, C_FILES },
|
||||
{ "fillchar", f_fillchar, C_FILL, C_FILL },
|
||||
{ "ibs", f_ibs, C_IBS, C_BS|C_IBS },
|
||||
{ "if", f_if, C_IF, C_IF },
|
||||
{ "iseek", f_skip, C_SKIP, C_SKIP },
|
||||
{ "obs", f_obs, C_OBS, C_BS|C_OBS },
|
||||
{ "of", f_of, C_OF, C_OF },
|
||||
{ "oseek", f_seek, C_SEEK, C_SEEK },
|
||||
{ "seek", f_seek, C_SEEK, C_SEEK },
|
||||
{ "skip", f_skip, C_SKIP, C_SKIP },
|
||||
};
|
||||
|
||||
static char *oper;
|
||||
|
||||
/*
|
||||
* args -- parse JCL syntax of dd.
|
||||
*/
|
||||
void
|
||||
jcl(rtems_shell_dd_globals* globals, char **argv)
|
||||
{
|
||||
struct arg *ap, tmp;
|
||||
char *arg;
|
||||
|
||||
oper = NULL;
|
||||
|
||||
in.dbsz = out.dbsz = 512;
|
||||
|
||||
while ((oper = *++argv) != NULL) {
|
||||
// if ((oper = strdup(oper)) == NULL)
|
||||
// errx(exit_jump, 1, "unable to allocate space for the argument \"%s\"", *argv);
|
||||
if ((arg = strchr(oper, '=')) == NULL)
|
||||
errx(exit_jump, 1, "unknown operand %s", oper);
|
||||
*arg++ = '\0';
|
||||
if (!*arg)
|
||||
errx(exit_jump, 1, "no value specified for %s", oper);
|
||||
tmp.name = oper;
|
||||
if (!(ap = (struct arg *)bsearch(&tmp, args,
|
||||
sizeof(args)/sizeof(struct arg), sizeof(struct arg),
|
||||
c_arg)))
|
||||
errx(exit_jump, 1, "unknown operand %s", tmp.name);
|
||||
if (ddflags & ap->noset)
|
||||
errx(exit_jump, 1, "%s: illegal argument combination or already set",
|
||||
tmp.name);
|
||||
ddflags |= ap->set;
|
||||
ap->f(globals, arg);
|
||||
}
|
||||
|
||||
/* Final sanity checks. */
|
||||
|
||||
if (ddflags & C_BS) {
|
||||
/*
|
||||
* Bs is turned off by any conversion -- we assume the user
|
||||
* just wanted to set both the input and output block sizes
|
||||
* and didn't want the bs semantics, so we don't warn.
|
||||
*/
|
||||
if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |
|
||||
C_UNBLOCK))
|
||||
ddflags &= ~C_BS;
|
||||
|
||||
/* Bs supersedes ibs and obs. */
|
||||
if (ddflags & C_BS && ddflags & (C_IBS | C_OBS))
|
||||
warnx("bs supersedes ibs and obs");
|
||||
}
|
||||
|
||||
/*
|
||||
* Ascii/ebcdic and cbs implies block/unblock.
|
||||
* Block/unblock requires cbs and vice-versa.
|
||||
*/
|
||||
if (ddflags & (C_BLOCK | C_UNBLOCK)) {
|
||||
if (!(ddflags & C_CBS))
|
||||
errx(exit_jump, 1, "record operations require cbs");
|
||||
if (cbsz == 0)
|
||||
errx(exit_jump, 1, "cbs cannot be zero");
|
||||
cfunc = ddflags & C_BLOCK ? block : unblock;
|
||||
} else if (ddflags & C_CBS) {
|
||||
if (ddflags & (C_ASCII | C_EBCDIC)) {
|
||||
if (ddflags & C_ASCII) {
|
||||
ddflags |= C_UNBLOCK;
|
||||
cfunc = unblock;
|
||||
} else {
|
||||
ddflags |= C_BLOCK;
|
||||
cfunc = block;
|
||||
}
|
||||
} else
|
||||
errx(exit_jump, 1, "cbs meaningless if not doing record operations");
|
||||
} else
|
||||
cfunc = def;
|
||||
|
||||
/*
|
||||
* Bail out if the calculation of a file offset would overflow.
|
||||
*/
|
||||
if (in.offset > OFF_MAX / (ssize_t)in.dbsz ||
|
||||
out.offset > OFF_MAX / (ssize_t)out.dbsz)
|
||||
errx(exit_jump, 1, "seek offsets cannot be larger than %jd",
|
||||
(intmax_t)OFF_MAX);
|
||||
}
|
||||
|
||||
static int
|
||||
c_arg(const void *a, const void *b)
|
||||
{
|
||||
|
||||
return (strcmp(((const struct arg *)a)->name,
|
||||
((const struct arg *)b)->name));
|
||||
}
|
||||
|
||||
static void
|
||||
f_bs(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
uintmax_t res;
|
||||
|
||||
res = get_num(globals, arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(exit_jump, 1, "bs must be between 1 and %jd", (intmax_t)SSIZE_MAX);
|
||||
in.dbsz = out.dbsz = (size_t)res;
|
||||
}
|
||||
|
||||
static void
|
||||
f_cbs(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
uintmax_t res;
|
||||
|
||||
res = get_num(globals, arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(exit_jump, 1, "cbs must be between 1 and %jd", (intmax_t)SSIZE_MAX);
|
||||
cbsz = (size_t)res;
|
||||
}
|
||||
|
||||
static void
|
||||
f_count(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
intmax_t res;
|
||||
|
||||
res = (intmax_t)get_num(globals, arg);
|
||||
if (res < 0)
|
||||
errx(exit_jump, 1, "count cannot be negative");
|
||||
if (res == 0)
|
||||
cpy_cnt = (uintmax_t)-1;
|
||||
else
|
||||
cpy_cnt = (uintmax_t)res;
|
||||
}
|
||||
|
||||
static void
|
||||
f_files(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
|
||||
files_cnt = get_num(globals, arg);
|
||||
if (files_cnt < 1)
|
||||
errx(exit_jump, 1, "files must be between 1 and %jd", (uintmax_t)-1);
|
||||
}
|
||||
|
||||
static void
|
||||
f_fillchar(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
|
||||
if (strlen(arg) != 1)
|
||||
errx(exit_jump, 1, "need exactly one fill char");
|
||||
|
||||
fill_char = arg[0];
|
||||
}
|
||||
|
||||
static void
|
||||
f_ibs(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
uintmax_t res;
|
||||
|
||||
if (!(ddflags & C_BS)) {
|
||||
res = get_num(globals, arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(exit_jump, 1, "ibs must be between 1 and %jd",
|
||||
(intmax_t)SSIZE_MAX);
|
||||
in.dbsz = (size_t)res;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
f_if(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
|
||||
in.name = strdup(arg);
|
||||
}
|
||||
|
||||
static void
|
||||
f_obs(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
uintmax_t res;
|
||||
|
||||
if (!(ddflags & C_BS)) {
|
||||
res = get_num(globals, arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(exit_jump, 1, "obs must be between 1 and %jd",
|
||||
(intmax_t)SSIZE_MAX);
|
||||
out.dbsz = (size_t)res;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
f_of(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
|
||||
out.name = strdup(arg);
|
||||
}
|
||||
|
||||
static void
|
||||
f_seek(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
|
||||
out.offset = get_off_t(globals, arg);
|
||||
}
|
||||
|
||||
static void
|
||||
f_skip(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
|
||||
in.offset = get_off_t(globals, arg);
|
||||
}
|
||||
|
||||
static const struct conv {
|
||||
const char *name;
|
||||
u_int set, noset;
|
||||
const u_char *ctab_;
|
||||
} clist[] = {
|
||||
{ "ascii", C_ASCII, C_EBCDIC, e2a_POSIX },
|
||||
{ "block", C_BLOCK, C_UNBLOCK, NULL },
|
||||
{ "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX },
|
||||
{ "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX },
|
||||
{ "lcase", C_LCASE, C_UCASE, NULL },
|
||||
{ "noerror", C_NOERROR, 0, NULL },
|
||||
{ "notrunc", C_NOTRUNC, 0, NULL },
|
||||
{ "oldascii", C_ASCII, C_EBCDIC, e2a_32V },
|
||||
{ "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V },
|
||||
{ "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V },
|
||||
{ "osync", C_OSYNC, C_BS, NULL },
|
||||
{ "pareven", C_PAREVEN, C_PARODD|C_PARSET|C_PARNONE, NULL},
|
||||
{ "parnone", C_PARNONE, C_PARODD|C_PARSET|C_PAREVEN, NULL},
|
||||
{ "parodd", C_PARODD, C_PAREVEN|C_PARSET|C_PARNONE, NULL},
|
||||
{ "parset", C_PARSET, C_PARODD|C_PAREVEN|C_PARNONE, NULL},
|
||||
{ "sparse", C_SPARSE, 0, NULL },
|
||||
{ "swab", C_SWAB, 0, NULL },
|
||||
{ "sync", C_SYNC, 0, NULL },
|
||||
{ "ucase", C_UCASE, C_LCASE, NULL },
|
||||
{ "unblock", C_UNBLOCK, C_BLOCK, NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
f_conv(rtems_shell_dd_globals* globals, char *arg)
|
||||
{
|
||||
struct conv *cp, tmp;
|
||||
|
||||
while (arg != NULL) {
|
||||
tmp.name = strsep(&arg, ",");
|
||||
cp = bsearch(&tmp, clist, sizeof(clist) / sizeof(struct conv),
|
||||
sizeof(struct conv), c_conv);
|
||||
if (cp == NULL)
|
||||
errx(exit_jump, 1, "unknown conversion %s", tmp.name);
|
||||
if (ddflags & cp->noset)
|
||||
errx(exit_jump, 1, "%s: illegal conversion combination", tmp.name);
|
||||
ddflags |= cp->set;
|
||||
if (cp->ctab_)
|
||||
ctab = cp->ctab_;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
c_conv(const void *a, const void *b)
|
||||
{
|
||||
|
||||
return (strcmp(((const struct conv *)a)->name,
|
||||
((const struct conv *)b)->name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an expression of the following forms to a uintmax_t.
|
||||
* 1) A positive decimal number.
|
||||
* 2) A positive decimal number followed by a 'b' or 'B' (mult by 512).
|
||||
* 3) A positive decimal number followed by a 'k' or 'K' (mult by 1 << 10).
|
||||
* 4) A positive decimal number followed by a 'm' or 'M' (mult by 1 << 20).
|
||||
* 5) A positive decimal number followed by a 'g' or 'G' (mult by 1 << 30).
|
||||
* 5) A positive decimal number followed by a 'w' or 'W' (mult by sizeof int).
|
||||
* 6) Two or more positive decimal numbers (with/without [BbKkMmGgWw])
|
||||
* separated by 'x' or 'X' (also '*' for backwards compatibility),
|
||||
* specifying the product of the indicated values.
|
||||
*/
|
||||
static uintmax_t
|
||||
get_num(rtems_shell_dd_globals* globals, const char *val)
|
||||
{
|
||||
uintmax_t num, mult, prevnum;
|
||||
char *expr;
|
||||
|
||||
errno = 0;
|
||||
num = strtouq(val, &expr, 0);
|
||||
if (errno != 0) /* Overflow or underflow. */
|
||||
err(exit_jump, 1, "%s", oper);
|
||||
|
||||
if (expr == val) /* No valid digits. */
|
||||
errx(exit_jump, 1, "%s: illegal numeric value", oper);
|
||||
|
||||
mult = 0;
|
||||
switch (*expr) {
|
||||
case 'B':
|
||||
case 'b':
|
||||
mult = 512;
|
||||
break;
|
||||
case 'K':
|
||||
case 'k':
|
||||
mult = 1 << 10;
|
||||
break;
|
||||
case 'M':
|
||||
case 'm':
|
||||
mult = 1 << 20;
|
||||
break;
|
||||
case 'G':
|
||||
case 'g':
|
||||
mult = 1 << 30;
|
||||
break;
|
||||
case 'W':
|
||||
case 'w':
|
||||
mult = sizeof(int);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if (mult != 0) {
|
||||
prevnum = num;
|
||||
num *= mult;
|
||||
/* Check for overflow. */
|
||||
if (num / mult != prevnum)
|
||||
goto erange;
|
||||
expr++;
|
||||
}
|
||||
|
||||
switch (*expr) {
|
||||
case '\0':
|
||||
break;
|
||||
case '*': /* Backward compatible. */
|
||||
case 'X':
|
||||
case 'x':
|
||||
mult = get_num(globals, expr + 1);
|
||||
prevnum = num;
|
||||
num *= mult;
|
||||
if (num / mult == prevnum)
|
||||
break;
|
||||
erange:
|
||||
errx(exit_jump, 1, "%s: %s", oper, strerror(ERANGE));
|
||||
default:
|
||||
errx(exit_jump, 1, "%s: illegal numeric value", oper);
|
||||
}
|
||||
return (num);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an expression of the following forms to an off_t. This is the
|
||||
* same as get_num(), but it uses signed numbers.
|
||||
*
|
||||
* The major problem here is that an off_t may not necessarily be a intmax_t.
|
||||
*/
|
||||
static off_t
|
||||
get_off_t(rtems_shell_dd_globals* globals, const char *val)
|
||||
{
|
||||
intmax_t num, mult, prevnum;
|
||||
char *expr;
|
||||
|
||||
errno = 0;
|
||||
num = strtoq(val, &expr, 0);
|
||||
if (errno != 0) /* Overflow or underflow. */
|
||||
err(exit_jump, 1, "%s", oper);
|
||||
|
||||
if (expr == val) /* No valid digits. */
|
||||
errx(exit_jump, 1, "%s: illegal numeric value", oper);
|
||||
|
||||
mult = 0;
|
||||
switch (*expr) {
|
||||
case 'B':
|
||||
case 'b':
|
||||
mult = 512;
|
||||
break;
|
||||
case 'K':
|
||||
case 'k':
|
||||
mult = 1 << 10;
|
||||
break;
|
||||
case 'M':
|
||||
case 'm':
|
||||
mult = 1 << 20;
|
||||
break;
|
||||
case 'G':
|
||||
case 'g':
|
||||
mult = 1 << 30;
|
||||
break;
|
||||
case 'W':
|
||||
case 'w':
|
||||
mult = sizeof(int);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mult != 0) {
|
||||
prevnum = num;
|
||||
num *= mult;
|
||||
/* Check for overflow. */
|
||||
if ((prevnum > 0) != (num > 0) || num / mult != prevnum)
|
||||
goto erange;
|
||||
expr++;
|
||||
}
|
||||
|
||||
switch (*expr) {
|
||||
case '\0':
|
||||
break;
|
||||
case '*': /* Backward compatible. */
|
||||
case 'X':
|
||||
case 'x':
|
||||
mult = (intmax_t)get_off_t(globals, expr + 1);
|
||||
prevnum = num;
|
||||
num *= mult;
|
||||
if ((prevnum > 0) == (num > 0) && num / mult == prevnum)
|
||||
break;
|
||||
erange:
|
||||
errx(exit_jump, 1, "%s: %s", oper, strerror(ERANGE));
|
||||
default:
|
||||
errx(exit_jump, 1, "%s: illegal numeric value", oper);
|
||||
}
|
||||
return (num);
|
||||
}
|
||||
268
cpukit/libmisc/shell/dd-conv.c
Normal file
268
cpukit/libmisc/shell/dd-conv.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)conv.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/bin/dd/conv.c,v 1.19 2004/04/06 20:06:45 markm Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dd.h"
|
||||
#include "extern-dd.h"
|
||||
|
||||
/*
|
||||
* def --
|
||||
* Copy input to output. Input is buffered until reaches obs, and then
|
||||
* output until less than obs remains. Only a single buffer is used.
|
||||
* Worst case buffer calculation is (ibs + obs - 1).
|
||||
*/
|
||||
void
|
||||
def(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
u_char *inp;
|
||||
const u_char *t;
|
||||
size_t cnt;
|
||||
|
||||
if ((t = ctab) != NULL)
|
||||
for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
|
||||
*inp = t[*inp];
|
||||
|
||||
/* Make the output buffer look right. */
|
||||
out.dbp = in.dbp;
|
||||
out.dbcnt = in.dbcnt;
|
||||
|
||||
if (in.dbcnt >= out.dbsz) {
|
||||
/* If the output buffer is full, write it. */
|
||||
dd_out(globals, 0);
|
||||
|
||||
/*
|
||||
* Ddout copies the leftover output to the beginning of
|
||||
* the buffer and resets the output buffer. Reset the
|
||||
* input buffer to match it.
|
||||
*/
|
||||
in.dbp = out.dbp;
|
||||
in.dbcnt = out.dbcnt;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
def_close(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
/* Just update the count, everything is already in the buffer. */
|
||||
if (in.dbcnt)
|
||||
out.dbcnt = in.dbcnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy variable length newline terminated records with a max size cbsz
|
||||
* bytes to output. Records less than cbs are padded with spaces.
|
||||
*
|
||||
* max in buffer: MAX(ibs, cbsz)
|
||||
* max out buffer: obs + cbsz
|
||||
*/
|
||||
void
|
||||
block(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
u_char *inp, *outp;
|
||||
const u_char *t;
|
||||
size_t cnt, maxlen;
|
||||
static int intrunc;
|
||||
int ch;
|
||||
|
||||
/*
|
||||
* Record truncation can cross block boundaries. If currently in a
|
||||
* truncation state, keep tossing characters until reach a newline.
|
||||
* Start at the beginning of the buffer, as the input buffer is always
|
||||
* left empty.
|
||||
*/
|
||||
if (intrunc) {
|
||||
for (inp = in.db, cnt = in.dbrcnt; cnt && *inp++ != '\n'; --cnt)
|
||||
;
|
||||
if (!cnt) {
|
||||
in.dbcnt = 0;
|
||||
in.dbp = in.db;
|
||||
return;
|
||||
}
|
||||
intrunc = 0;
|
||||
/* Adjust the input buffer numbers. */
|
||||
in.dbcnt = cnt - 1;
|
||||
in.dbp = inp + cnt - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy records (max cbsz size chunks) into the output buffer. The
|
||||
* translation is done as we copy into the output buffer.
|
||||
*/
|
||||
ch = 0;
|
||||
for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
|
||||
maxlen = MIN(cbsz, in.dbcnt);
|
||||
if ((t = ctab) != NULL)
|
||||
for (cnt = 0; cnt < maxlen && (ch = *inp++) != '\n';
|
||||
++cnt)
|
||||
*outp++ = t[ch];
|
||||
else
|
||||
for (cnt = 0; cnt < maxlen && (ch = *inp++) != '\n';
|
||||
++cnt)
|
||||
*outp++ = ch;
|
||||
/*
|
||||
* Check for short record without a newline. Reassemble the
|
||||
* input block.
|
||||
*/
|
||||
if (ch != '\n' && in.dbcnt < cbsz) {
|
||||
(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Adjust the input buffer numbers. */
|
||||
in.dbcnt -= cnt;
|
||||
if (ch == '\n')
|
||||
--in.dbcnt;
|
||||
|
||||
/* Pad short records with spaces. */
|
||||
if (cnt < cbsz)
|
||||
(void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt);
|
||||
else {
|
||||
/*
|
||||
* If the next character wouldn't have ended the
|
||||
* block, it's a truncation.
|
||||
*/
|
||||
if (!in.dbcnt || *inp != '\n')
|
||||
++st.trunc;
|
||||
|
||||
/* Toss characters to a newline. */
|
||||
for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt)
|
||||
;
|
||||
if (!in.dbcnt)
|
||||
intrunc = 1;
|
||||
else
|
||||
--in.dbcnt;
|
||||
}
|
||||
|
||||
/* Adjust output buffer numbers. */
|
||||
out.dbp += cbsz;
|
||||
if ((out.dbcnt += cbsz) >= out.dbsz)
|
||||
dd_out(globals, 0);
|
||||
outp = out.dbp;
|
||||
}
|
||||
in.dbp = in.db + in.dbcnt;
|
||||
}
|
||||
|
||||
void
|
||||
block_close(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
/*
|
||||
* Copy any remaining data into the output buffer and pad to a record.
|
||||
* Don't worry about truncation or translation, the input buffer is
|
||||
* always empty when truncating, and no characters have been added for
|
||||
* translation. The bottom line is that anything left in the input
|
||||
* buffer is a truncated record. Anything left in the output buffer
|
||||
* just wasn't big enough.
|
||||
*/
|
||||
if (in.dbcnt) {
|
||||
++st.trunc;
|
||||
(void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
|
||||
(void)memset(out.dbp + in.dbcnt, ctab ? ctab[' '] : ' ',
|
||||
cbsz - in.dbcnt);
|
||||
out.dbcnt += cbsz;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert fixed length (cbsz) records to variable length. Deletes any
|
||||
* trailing blanks and appends a newline.
|
||||
*
|
||||
* max in buffer: MAX(ibs, cbsz) + cbsz
|
||||
* max out buffer: obs + cbsz
|
||||
*/
|
||||
void
|
||||
unblock(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
u_char *inp;
|
||||
const u_char *t;
|
||||
size_t cnt;
|
||||
|
||||
/* Translation and case conversion. */
|
||||
if ((t = ctab) != NULL)
|
||||
for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
|
||||
*inp = t[*inp];
|
||||
/*
|
||||
* Copy records (max cbsz size chunks) into the output buffer. The
|
||||
* translation has to already be done or we might not recognize the
|
||||
* spaces.
|
||||
*/
|
||||
for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
|
||||
for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t)
|
||||
;
|
||||
if (t >= inp) {
|
||||
cnt = t - inp + 1;
|
||||
(void)memmove(out.dbp, inp, cnt);
|
||||
out.dbp += cnt;
|
||||
out.dbcnt += cnt;
|
||||
}
|
||||
*out.dbp++ = '\n';
|
||||
if (++out.dbcnt >= out.dbsz)
|
||||
dd_out(globals, 0);
|
||||
}
|
||||
if (in.dbcnt)
|
||||
(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
|
||||
in.dbp = in.db + in.dbcnt;
|
||||
}
|
||||
|
||||
void
|
||||
unblock_close(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
u_char *t;
|
||||
size_t cnt;
|
||||
|
||||
if (in.dbcnt) {
|
||||
warnx("%s: short input record", in.name);
|
||||
for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t)
|
||||
;
|
||||
if (t >= in.db) {
|
||||
cnt = t - in.db + 1;
|
||||
(void)memmove(out.dbp, in.db, cnt);
|
||||
out.dbp += cnt;
|
||||
out.dbcnt += cnt;
|
||||
}
|
||||
++out.dbcnt;
|
||||
*out.dbp++ = '\n';
|
||||
}
|
||||
}
|
||||
284
cpukit/libmisc/shell/dd-conv_tab.c
Normal file
284
cpukit/libmisc/shell/dd-conv_tab.c
Normal file
@@ -0,0 +1,284 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)conv_tab.c 8.1 (Berkeley) 5/31/93";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/bin/dd/conv_tab.c,v 1.12 2004/04/06 20:06:45 markm Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* There are currently six tables:
|
||||
*
|
||||
* ebcdic -> ascii 32V conv=oldascii
|
||||
* ascii -> ebcdic 32V conv=oldebcdic
|
||||
* ascii -> ibm ebcdic 32V conv=oldibm
|
||||
*
|
||||
* ebcdic -> ascii POSIX/S5 conv=ascii
|
||||
* ascii -> ebcdic POSIX/S5 conv=ebcdic
|
||||
* ascii -> ibm ebcdic POSIX/S5 conv=ibm
|
||||
*
|
||||
* Other tables are built from these if multiple conversions are being
|
||||
* done.
|
||||
*
|
||||
* Tables used for conversions to/from IBM and EBCDIC to support an extension
|
||||
* to POSIX P1003.2/D11. The tables referencing POSIX contain data extracted
|
||||
* from tables 4-3 and 4-4 in P1003.2/Draft 11. The historic tables were
|
||||
* constructed by running against a file with all possible byte values.
|
||||
*
|
||||
* More information can be obtained in "Correspondences of 8-Bit and Hollerith
|
||||
* Codes for Computer Environments-A USASI Tutorial", Communications of the
|
||||
* ACM, Volume 11, Number 11, November 1968, pp. 783-789.
|
||||
*/
|
||||
|
||||
u_char casetab[256];
|
||||
|
||||
/* EBCDIC to ASCII -- 32V compatible. */
|
||||
const u_char e2a_32V[] = {
|
||||
0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177, /* 0000 */
|
||||
0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017, /* 0010 */
|
||||
0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207, /* 0020 */
|
||||
0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037, /* 0030 */
|
||||
0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033, /* 0040 */
|
||||
0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007, /* 0050 */
|
||||
0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004, /* 0060 */
|
||||
0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032, /* 0070 */
|
||||
0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246, /* 0100 */
|
||||
0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041, /* 0110 */
|
||||
0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257, /* 0120 */
|
||||
0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136, /* 0130 */
|
||||
0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267, /* 0140 */
|
||||
0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077, /* 0150 */
|
||||
0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301, /* 0160 */
|
||||
0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042, /* 0170 */
|
||||
0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147, /* 0200 */
|
||||
0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311, /* 0210 */
|
||||
0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160, /* 0220 */
|
||||
0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320, /* 0230 */
|
||||
0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170, /* 0240 */
|
||||
0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327, /* 0250 */
|
||||
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, /* 0260 */
|
||||
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347, /* 0270 */
|
||||
0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107, /* 0300 */
|
||||
0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355, /* 0310 */
|
||||
0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120, /* 0320 */
|
||||
0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363, /* 0330 */
|
||||
0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130, /* 0340 */
|
||||
0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371, /* 0350 */
|
||||
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, /* 0360 */
|
||||
0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||
};
|
||||
|
||||
/* ASCII to EBCDIC -- 32V compatible. */
|
||||
const u_char a2e_32V[] = {
|
||||
0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */
|
||||
0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */
|
||||
0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */
|
||||
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
|
||||
0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
|
||||
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
|
||||
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
|
||||
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
|
||||
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
|
||||
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
|
||||
0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155, /* 0130 */
|
||||
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
|
||||
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
|
||||
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
|
||||
0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007, /* 0170 */
|
||||
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
|
||||
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
|
||||
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
|
||||
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
|
||||
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
|
||||
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
|
||||
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
|
||||
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
|
||||
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
|
||||
0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, /* 0310 */
|
||||
0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, /* 0320 */
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
|
||||
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, /* 0340 */
|
||||
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
|
||||
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
|
||||
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||
};
|
||||
|
||||
/* ASCII to IBM EBCDIC -- 32V compatible. */
|
||||
const u_char a2ibm_32V[] = {
|
||||
0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */
|
||||
0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */
|
||||
0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */
|
||||
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
|
||||
0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
|
||||
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
|
||||
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
|
||||
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
|
||||
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
|
||||
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
|
||||
0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155, /* 0130 */
|
||||
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
|
||||
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
|
||||
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
|
||||
0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007, /* 0170 */
|
||||
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
|
||||
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
|
||||
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
|
||||
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
|
||||
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
|
||||
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
|
||||
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
|
||||
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
|
||||
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
|
||||
0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, /* 0310 */
|
||||
0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, /* 0320 */
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
|
||||
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, /* 0340 */
|
||||
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
|
||||
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
|
||||
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||
};
|
||||
|
||||
/* EBCDIC to ASCII -- POSIX and System V compatible. */
|
||||
const u_char e2a_POSIX[] = {
|
||||
0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177, /* 0000 */
|
||||
0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017, /* 0010 */
|
||||
0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207, /* 0020 */
|
||||
0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037, /* 0030 */
|
||||
0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033, /* 0040 */
|
||||
0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007, /* 0050 */
|
||||
0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004, /* 0060 */
|
||||
0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032, /* 0070 */
|
||||
0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246, /* 0100 */
|
||||
0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174, /* 0110 */
|
||||
0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257, /* 0120 */
|
||||
0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176, /* 0130 */
|
||||
0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267, /* 0140 */
|
||||
0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077, /* 0150 */
|
||||
0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301, /* 0160 */
|
||||
0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042, /* 0170 */
|
||||
0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147, /* 0200 */
|
||||
0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311, /* 0210 */
|
||||
0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160, /* 0220 */
|
||||
0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320, /* 0230 */
|
||||
0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170, /* 0240 */
|
||||
0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327, /* 0250 */
|
||||
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, /* 0260 */
|
||||
0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347, /* 0270 */
|
||||
0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107, /* 0300 */
|
||||
0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355, /* 0310 */
|
||||
0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120, /* 0320 */
|
||||
0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363, /* 0330 */
|
||||
0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130, /* 0340 */
|
||||
0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371, /* 0350 */
|
||||
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, /* 0360 */
|
||||
0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||
};
|
||||
|
||||
/* ASCII to EBCDIC -- POSIX and System V compatible. */
|
||||
const u_char a2e_POSIX[] = {
|
||||
0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */
|
||||
0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */
|
||||
0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */
|
||||
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
|
||||
0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
|
||||
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
|
||||
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
|
||||
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
|
||||
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
|
||||
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
|
||||
0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155, /* 0130 */
|
||||
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
|
||||
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
|
||||
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
|
||||
0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007, /* 0170 */
|
||||
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
|
||||
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
|
||||
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
|
||||
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
|
||||
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
|
||||
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
|
||||
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
|
||||
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
|
||||
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
|
||||
0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236, /* 0310 */
|
||||
0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257, /* 0320 */
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
|
||||
0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277, /* 0340 */
|
||||
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
|
||||
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
|
||||
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||
};
|
||||
|
||||
/* ASCII to IBM EBCDIC -- POSIX and System V compatible. */
|
||||
const u_char a2ibm_POSIX[] = {
|
||||
0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */
|
||||
0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */
|
||||
0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */
|
||||
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
|
||||
0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
|
||||
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
|
||||
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
|
||||
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
|
||||
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
|
||||
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
|
||||
0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155, /* 0130 */
|
||||
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
|
||||
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
|
||||
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
|
||||
0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007, /* 0170 */
|
||||
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
|
||||
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
|
||||
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
|
||||
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
|
||||
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
|
||||
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
|
||||
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
|
||||
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
|
||||
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
|
||||
0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, /* 0310 */
|
||||
0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, /* 0320 */
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
|
||||
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, /* 0340 */
|
||||
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
|
||||
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
|
||||
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||
};
|
||||
108
cpukit/libmisc/shell/dd-misc.c
Normal file
108
cpukit/libmisc/shell/dd-misc.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#if 0
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/bin/dd/misc.c,v 1.27 2004/04/06 20:06:46 markm Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dd.h"
|
||||
#include "extern-dd.h"
|
||||
|
||||
void
|
||||
summary(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
struct timeval tv;
|
||||
double secs;
|
||||
char buf[100];
|
||||
|
||||
(void)gettimeofday(&tv, (struct timezone *)NULL);
|
||||
secs = tv.tv_sec + tv.tv_usec * 1e-6 - st.start;
|
||||
if (secs < 1e-6)
|
||||
secs = 1e-6;
|
||||
/* Use snprintf(3) so that we don't reenter stdio(3). */
|
||||
(void)snprintf(buf, sizeof(buf),
|
||||
"%ju+%ju records in\n%ju+%ju records out\n",
|
||||
st.in_full, st.in_part, st.out_full, st.out_part);
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
if (st.swab) {
|
||||
(void)snprintf(buf, sizeof(buf), "%ju odd length swab %s\n",
|
||||
st.swab, (st.swab == 1) ? "block" : "blocks");
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
if (st.trunc) {
|
||||
(void)snprintf(buf, sizeof(buf), "%ju truncated %s\n",
|
||||
st.trunc, (st.trunc == 1) ? "block" : "blocks");
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
(void)snprintf(buf, sizeof(buf),
|
||||
"%ju bytes transferred in %.6f secs (%.0f bytes/sec)\n",
|
||||
st.bytes, secs, st.bytes / secs);
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
summaryx(rtems_shell_dd_globals* globals, int __unused)
|
||||
{
|
||||
int save_errno = errno;
|
||||
|
||||
summary(globals);
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
/* ARGSUSED */
|
||||
void
|
||||
terminate(int sig)
|
||||
{
|
||||
|
||||
summary();
|
||||
_exit(sig == 0 ? 0 : 1);
|
||||
}
|
||||
#endif
|
||||
189
cpukit/libmisc/shell/dd-position.c
Normal file
189
cpukit/libmisc/shell/dd-position.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/bin/dd/position.c,v 1.23 2004/04/06 20:06:46 markm Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#if RTEMS_REMOVED
|
||||
#include <sys/mtio.h>
|
||||
#endif
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dd.h"
|
||||
#include "extern-dd.h"
|
||||
|
||||
/*
|
||||
* Position input/output data streams before starting the copy. Device type
|
||||
* dependent. Seekable devices use lseek, and the rest position by reading.
|
||||
* Seeking past the end of file can cause null blocks to be written to the
|
||||
* output.
|
||||
*/
|
||||
void
|
||||
pos_in(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
off_t cnt;
|
||||
int warned;
|
||||
ssize_t nr;
|
||||
size_t bcnt;
|
||||
|
||||
/* If known to be seekable, try to seek on it. */
|
||||
if (in.flags & ISSEEK) {
|
||||
errno = 0;
|
||||
if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1 &&
|
||||
errno != 0)
|
||||
err(exit_jump, 1, "%s", in.name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't try to read a really weird amount (like negative). */
|
||||
if (in.offset < 0)
|
||||
errx(exit_jump, 1, "%s: illegal offset", "iseek/skip");
|
||||
|
||||
/*
|
||||
* Read the data. If a pipe, read until satisfy the number of bytes
|
||||
* being skipped. No differentiation for reading complete and partial
|
||||
* blocks for other devices.
|
||||
*/
|
||||
for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
|
||||
if ((nr = read(in.fd, in.db, bcnt)) > 0) {
|
||||
if (in.flags & ISPIPE) {
|
||||
if (!(bcnt -= nr)) {
|
||||
bcnt = in.dbsz;
|
||||
--cnt;
|
||||
}
|
||||
} else
|
||||
--cnt;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nr == 0) {
|
||||
if (files_cnt > 1) {
|
||||
--files_cnt;
|
||||
continue;
|
||||
}
|
||||
errx(exit_jump, 1, "skip reached end of input");
|
||||
}
|
||||
|
||||
/*
|
||||
* Input error -- either EOF with no more files, or I/O error.
|
||||
* If noerror not set die. POSIX requires that the warning
|
||||
* message be followed by an I/O display.
|
||||
*/
|
||||
if (ddflags & C_NOERROR) {
|
||||
if (!warned) {
|
||||
warn("%s", in.name);
|
||||
warned = 1;
|
||||
summary(globals);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
err(exit_jump, 1, "%s", in.name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pos_out(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
#if RTEMS_REMOVED
|
||||
struct mtop t_op;
|
||||
off_t cnt;
|
||||
ssize_t n;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If not a tape, try seeking on the file. Seeking on a pipe is
|
||||
* going to fail, but don't protect the user -- they shouldn't
|
||||
* have specified the seek operand.
|
||||
*/
|
||||
if (out.flags & (ISSEEK | ISPIPE)) {
|
||||
errno = 0;
|
||||
if (lseek(out.fd, out.offset * out.dbsz, SEEK_CUR) == -1 &&
|
||||
errno != 0)
|
||||
err(exit_jump, 1, "%s", out.name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't try to read a really weird amount (like negative). */
|
||||
if (out.offset < 0)
|
||||
errx(exit_jump, 1, "%s: illegal offset", "oseek/seek");
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
/* If no read access, try using mtio. */
|
||||
if (out.flags & NOREAD) {
|
||||
t_op.mt_op = MTFSR;
|
||||
t_op.mt_count = out.offset;
|
||||
|
||||
if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
|
||||
err(1, "%s", out.name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read it. */
|
||||
for (cnt = 0; cnt < out.offset; ++cnt) {
|
||||
if ((n = read(out.fd, out.db, out.dbsz)) > 0)
|
||||
continue;
|
||||
|
||||
if (n == -1)
|
||||
err(1, "%s", out.name);
|
||||
|
||||
/*
|
||||
* If reach EOF, fill with NUL characters; first, back up over
|
||||
* the EOF mark. Note, cnt has not yet been incremented, so
|
||||
* the EOF read does not count as a seek'd block.
|
||||
*/
|
||||
t_op.mt_op = MTBSR;
|
||||
t_op.mt_count = 1;
|
||||
if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
|
||||
err(1, "%s", out.name);
|
||||
|
||||
while (cnt++ < out.offset) {
|
||||
n = write(out.fd, out.db, out.dbsz);
|
||||
if (n == -1)
|
||||
err(1, "%s", out.name);
|
||||
if ((size_t)n != out.dbsz)
|
||||
errx(1, "%s: write failure", out.name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
108
cpukit/libmisc/shell/dd.h
Normal file
108
cpukit/libmisc/shell/dd.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*
|
||||
* @(#)dd.h 8.3 (Berkeley) 4/2/94
|
||||
* $FreeBSD: src/bin/dd/dd.h,v 1.22 2004/08/15 19:10:05 rwatson Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DD_H_
|
||||
#define _DD_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define OFF_MAX LONG_MAX
|
||||
|
||||
/* Input/output stream state. */
|
||||
typedef struct {
|
||||
u_char *db; /* buffer address */
|
||||
u_char *dbp; /* current buffer I/O address */
|
||||
/* XXX ssize_t? */
|
||||
size_t dbcnt; /* current buffer byte count */
|
||||
size_t dbrcnt; /* last read byte count */
|
||||
size_t dbsz; /* buffer size */
|
||||
|
||||
#define ISCHR 0x01 /* character device (warn on short) */
|
||||
#define ISPIPE 0x02 /* pipe-like (see position.c) */
|
||||
#define ISTAPE 0x04 /* tape */
|
||||
#define ISSEEK 0x08 /* valid to seek on */
|
||||
#define NOREAD 0x10 /* not readable */
|
||||
#define ISTRUNC 0x20 /* valid to ftruncate() */
|
||||
u_int flags;
|
||||
|
||||
const char *name; /* name */
|
||||
int fd; /* file descriptor */
|
||||
off_t offset; /* # of blocks to skip */
|
||||
} IO;
|
||||
|
||||
typedef struct {
|
||||
uintmax_t in_full; /* # of full input blocks */
|
||||
uintmax_t in_part; /* # of partial input blocks */
|
||||
uintmax_t out_full; /* # of full output blocks */
|
||||
uintmax_t out_part; /* # of partial output blocks */
|
||||
uintmax_t trunc; /* # of truncated records */
|
||||
uintmax_t swab; /* # of odd-length swab blocks */
|
||||
uintmax_t bytes; /* # of bytes written */
|
||||
double start; /* start time of dd */
|
||||
} STAT;
|
||||
|
||||
/* Flags (in ddflags). */
|
||||
#define C_ASCII 0x00001
|
||||
#define C_BLOCK 0x00002
|
||||
#define C_BS 0x00004
|
||||
#define C_CBS 0x00008
|
||||
#define C_COUNT 0x00010
|
||||
#define C_EBCDIC 0x00020
|
||||
#define C_FILES 0x00040
|
||||
#define C_IBS 0x00080
|
||||
#define C_IF 0x00100
|
||||
#define C_LCASE 0x00200
|
||||
#define C_NOERROR 0x00400
|
||||
#define C_NOTRUNC 0x00800
|
||||
#define C_OBS 0x01000
|
||||
#define C_OF 0x02000
|
||||
#define C_OSYNC 0x04000
|
||||
#define C_PAREVEN 0x08000
|
||||
#define C_PARNONE 0x100000
|
||||
#define C_PARODD 0x200000
|
||||
#define C_PARSET 0x400000
|
||||
#define C_SEEK 0x800000
|
||||
#define C_SKIP 0x1000000
|
||||
#define C_SPARSE 0x2000000
|
||||
#define C_SWAB 0x4000000
|
||||
#define C_SYNC 0x8000000
|
||||
#define C_UCASE 0x10000000
|
||||
#define C_UNBLOCK 0x20000000
|
||||
#define C_FILL 0x40000000
|
||||
|
||||
#define C_PARITY (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)
|
||||
|
||||
#endif
|
||||
106
cpukit/libmisc/shell/extern-dd.h
Normal file
106
cpukit/libmisc/shell/extern-dd.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*
|
||||
* @(#)extern.h 8.3 (Berkeley) 4/2/94
|
||||
* $FreeBSD: src/bin/dd/extern.h,v 1.15 2004/08/15 19:10:05 rwatson Exp $
|
||||
*/
|
||||
|
||||
#ifndef _EXTERN_DD_H_
|
||||
#define _EXTERN_DD_H_
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
typedef struct rtems_shell_dd_globals_t {
|
||||
IO in, out; /* input/output state */
|
||||
STAT st; /* statistics */
|
||||
void (*cfunc)(struct rtems_shell_dd_globals_t* globals); /* conversion function */
|
||||
uintmax_t cpy_cnt; /* # of blocks to copy */
|
||||
u_int ddflags; /* conversion options */
|
||||
size_t cbsz; /* conversion block size */
|
||||
uintmax_t files_cnt; /* # of files to copy */
|
||||
const u_char *ctab; /* conversion table */
|
||||
char fill_char; /* Character to fill with if defined */
|
||||
u_char casetab[256];
|
||||
int exit_code;
|
||||
jmp_buf exit_jmp;
|
||||
} rtems_shell_dd_globals;
|
||||
|
||||
#define in globals->in
|
||||
#define out globals->out
|
||||
#define st globals->st
|
||||
#define cfunc globals->cfunc
|
||||
#define cpy_cnt globals->cpy_cnt
|
||||
#define ddflags globals->ddflags
|
||||
#define cbsz globals->cbsz
|
||||
#define files_cnt globals->files_cnt
|
||||
#define casetab globals->casetab
|
||||
#define ctab globals->ctab
|
||||
#define fill_char globals->fill_char
|
||||
#define exit_jump &(globals->exit_jmp)
|
||||
|
||||
#define block rtems_shell_dd_block
|
||||
#define block_close rtems_shell_dd_block_close
|
||||
#define dd_out rtems_shell_dd_dd_out
|
||||
#define def rtems_shell_dd_def
|
||||
#define def_close rtems_shell_dd_def_close
|
||||
#define jcl rtems_shell_dd_jcl
|
||||
#define pos_in rtems_shell_dd_pos_in
|
||||
#define pos_out rtems_shell_dd_pos_out
|
||||
#define summary rtems_shell_dd_summary
|
||||
#define summaryx rtems_shell_dd_summaryx
|
||||
#define terminate rtems_shell_dd_terminate
|
||||
#define unblock rtems_shell_dd_unblock
|
||||
#define unblock_close rtems_shell_dd_unblock_close
|
||||
|
||||
void block(rtems_shell_dd_globals* );
|
||||
void block_close(rtems_shell_dd_globals* );
|
||||
void dd_out(rtems_shell_dd_globals* , int);
|
||||
void def(rtems_shell_dd_globals* globals);
|
||||
void def_close(rtems_shell_dd_globals* );
|
||||
void jcl(rtems_shell_dd_globals* , char **);
|
||||
void pos_in(rtems_shell_dd_globals* );
|
||||
void pos_out(rtems_shell_dd_globals* );
|
||||
void summary(rtems_shell_dd_globals* );
|
||||
void summaryx(rtems_shell_dd_globals* , int);
|
||||
void terminate(int);
|
||||
void unblock(rtems_shell_dd_globals* globals);
|
||||
void unblock_close(rtems_shell_dd_globals* globals);
|
||||
|
||||
const u_char a2e_32V[256], a2e_POSIX[256];
|
||||
const u_char e2a_32V[256], e2a_POSIX[256];
|
||||
const u_char a2ibm_32V[256], a2ibm_POSIX[256];
|
||||
|
||||
void rtems_shell_dd_exit(rtems_shell_dd_globals* globals, int code);
|
||||
|
||||
#define exit(ec) rtems_shell_dd_exit(globals, ec)
|
||||
|
||||
#endif /* !_EXTERN_H_ */
|
||||
184
cpukit/libmisc/shell/hexdump-conv.c
Normal file
184
cpukit/libmisc/shell/hexdump-conv.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)conv.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif /* not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/usr.bin/hexdump/conv.c,v 1.9 2006/07/31 14:17:04 jkoshy Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include "hexdump.h"
|
||||
|
||||
void
|
||||
conv_c(rtems_shell_hexdump_globals* globals, PR *pr, u_char *p, size_t bufsize)
|
||||
{
|
||||
char buf[10];
|
||||
char const *str;
|
||||
wchar_t wc;
|
||||
size_t clen, oclen;
|
||||
int converr, pad, width;
|
||||
char peekbuf[MB_LEN_MAX];
|
||||
|
||||
printf("MB_LEN_MAX=%i\n", MB_LEN_MAX);
|
||||
return;
|
||||
if (pr->mbleft > 0) {
|
||||
str = "**";
|
||||
pr->mbleft--;
|
||||
goto strpr;
|
||||
}
|
||||
|
||||
switch(*p) {
|
||||
case '\0':
|
||||
str = "\\0";
|
||||
goto strpr;
|
||||
/* case '\a': */
|
||||
case '\007':
|
||||
str = "\\a";
|
||||
goto strpr;
|
||||
case '\b':
|
||||
str = "\\b";
|
||||
goto strpr;
|
||||
case '\f':
|
||||
str = "\\f";
|
||||
goto strpr;
|
||||
case '\n':
|
||||
str = "\\n";
|
||||
goto strpr;
|
||||
case '\r':
|
||||
str = "\\r";
|
||||
goto strpr;
|
||||
case '\t':
|
||||
str = "\\t";
|
||||
goto strpr;
|
||||
case '\v':
|
||||
str = "\\v";
|
||||
goto strpr;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Multibyte characters are disabled for hexdump(1) for backwards
|
||||
* compatibility and consistency (none of its other output formats
|
||||
* recognize them correctly).
|
||||
*/
|
||||
converr = 0;
|
||||
if (odmode && MB_CUR_MAX > 1) {
|
||||
oclen = 0;
|
||||
retry:
|
||||
clen = mbrtowc(&wc, (char*)p, bufsize, &pr->mbstate);
|
||||
if (clen == 0)
|
||||
clen = 1;
|
||||
else if (clen == (size_t)-1 || (clen == (size_t)-2 &&
|
||||
buf == peekbuf)) {
|
||||
memset(&pr->mbstate, 0, sizeof(pr->mbstate));
|
||||
wc = *p;
|
||||
clen = 1;
|
||||
converr = 1;
|
||||
} else if (clen == (size_t)-2) {
|
||||
/*
|
||||
* Incomplete character; peek ahead and see if we
|
||||
* can complete it.
|
||||
*/
|
||||
oclen = bufsize;
|
||||
bufsize = peek(globals, p = (u_char*)peekbuf, MB_CUR_MAX);
|
||||
goto retry;
|
||||
}
|
||||
clen += oclen;
|
||||
} else {
|
||||
wc = *p;
|
||||
clen = 1;
|
||||
}
|
||||
if (!converr && iswprint(wc)) {
|
||||
if (!odmode) {
|
||||
*pr->cchar = 'c';
|
||||
(void)printf(pr->fmt, (int)wc);
|
||||
} else {
|
||||
*pr->cchar = 'C';
|
||||
assert(strcmp(pr->fmt, "%3C") == 0);
|
||||
width = wcwidth(wc);
|
||||
assert(width >= 0);
|
||||
pad = 3 - width;
|
||||
if (pad < 0)
|
||||
pad = 0;
|
||||
(void)printf("%*s%C", pad, "", wc);
|
||||
pr->mbleft = clen - 1;
|
||||
}
|
||||
} else {
|
||||
(void)sprintf(buf, "%03o", (int)*p);
|
||||
str = buf;
|
||||
strpr: *pr->cchar = 's';
|
||||
(void)printf(pr->fmt, str);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
conv_u(rtems_shell_hexdump_globals* globals, PR *pr, u_char *p)
|
||||
{
|
||||
static char const * 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",
|
||||
"can", "em", "sub", "esc", "fs", "gs", "rs", "us",
|
||||
};
|
||||
|
||||
/* od used nl, not lf */
|
||||
if (*p <= 0x1f) {
|
||||
*pr->cchar = 's';
|
||||
if (odmode && *p == 0x0a)
|
||||
(void)printf(pr->fmt, "nl");
|
||||
else
|
||||
(void)printf(pr->fmt, list[*p]);
|
||||
} else if (*p == 0x7f) {
|
||||
*pr->cchar = 's';
|
||||
(void)printf(pr->fmt, "del");
|
||||
} else if (odmode && *p == 0x20) { /* od replaced space with sp */
|
||||
*pr->cchar = 's';
|
||||
(void)printf(pr->fmt, " sp");
|
||||
} else if (isprint(*p)) {
|
||||
*pr->cchar = 'c';
|
||||
(void)printf(pr->fmt, *p);
|
||||
} else {
|
||||
*pr->cchar = 'x';
|
||||
(void)printf(pr->fmt, (int)*p);
|
||||
}
|
||||
}
|
||||
420
cpukit/libmisc/shell/hexdump-display.c
Normal file
420
cpukit/libmisc/shell/hexdump-display.c
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* 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
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)display.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#if 0
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/usr.bin/hexdump/display.c,v 1.22 2004/08/04 02:47:32 tjr Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "hexdump.h"
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
enum _vflag vflag = FIRST;
|
||||
|
||||
static off_t address; /* address/offset in stream */
|
||||
static off_t eaddress; /* end address */
|
||||
#endif
|
||||
|
||||
static void print(rtems_shell_hexdump_globals*, PR *, u_char *);
|
||||
|
||||
void
|
||||
display(rtems_shell_hexdump_globals* globals)
|
||||
{
|
||||
FS *fs;
|
||||
FU *fu;
|
||||
PR *pr;
|
||||
int cnt;
|
||||
u_char *bp;
|
||||
off_t saveaddress;
|
||||
u_char savech, *savebp;
|
||||
|
||||
savech = 0;
|
||||
while ((bp = get(globals)))
|
||||
for (fs = fshead, savebp = bp, saveaddress = address; fs;
|
||||
fs = fs->nextfs, bp = savebp, address = saveaddress)
|
||||
for (fu = fs->nextfu; fu; fu = fu->nextfu) {
|
||||
if (fu->flags&F_IGNORE)
|
||||
break;
|
||||
for (cnt = fu->reps; cnt; --cnt)
|
||||
for (pr = fu->nextpr; pr; address += pr->bcnt,
|
||||
bp += pr->bcnt, pr = pr->nextpr) {
|
||||
if (eaddress && address >= eaddress &&
|
||||
!(pr->flags & (F_TEXT|F_BPAD)))
|
||||
bpad(pr);
|
||||
if (cnt == 1 && pr->nospace) {
|
||||
savech = *pr->nospace;
|
||||
*pr->nospace = '\0';
|
||||
}
|
||||
print(globals, pr, bp);
|
||||
if (cnt == 1 && pr->nospace)
|
||||
*pr->nospace = savech;
|
||||
}
|
||||
}
|
||||
if (endfu) {
|
||||
/*
|
||||
* If eaddress not set, error or file size was multiple of
|
||||
* blocksize, and no partial block ever found.
|
||||
*/
|
||||
if (!eaddress) {
|
||||
if (!address)
|
||||
return;
|
||||
eaddress = address;
|
||||
}
|
||||
for (pr = endfu->nextpr; pr; pr = pr->nextpr)
|
||||
switch(pr->flags) {
|
||||
case F_ADDRESS:
|
||||
(void)printf(pr->fmt, (quad_t)eaddress);
|
||||
break;
|
||||
case F_TEXT:
|
||||
(void)printf("%s", pr->fmt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print(rtems_shell_hexdump_globals* globals, PR *pr, u_char *bp)
|
||||
{
|
||||
long double ldbl;
|
||||
double f8;
|
||||
float f4;
|
||||
int16_t s2;
|
||||
int8_t s8;
|
||||
int32_t s4;
|
||||
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(globals, pr, bp, eaddress ? eaddress - address :
|
||||
blocksize - address % blocksize);
|
||||
break;
|
||||
case F_CHAR:
|
||||
(void)printf(pr->fmt, *bp);
|
||||
break;
|
||||
case F_DBL:
|
||||
switch(pr->bcnt) {
|
||||
case 4:
|
||||
bcopy(bp, &f4, sizeof(f4));
|
||||
(void)printf(pr->fmt, f4);
|
||||
break;
|
||||
case 8:
|
||||
bcopy(bp, &f8, sizeof(f8));
|
||||
(void)printf(pr->fmt, f8);
|
||||
break;
|
||||
default:
|
||||
if (pr->bcnt == sizeof(long double)) {
|
||||
bcopy(bp, &ldbl, sizeof(ldbl));
|
||||
(void)printf(pr->fmt, ldbl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case F_INT:
|
||||
switch(pr->bcnt) {
|
||||
case 1:
|
||||
(void)printf(pr->fmt, (quad_t)(signed char)*bp);
|
||||
break;
|
||||
case 2:
|
||||
bcopy(bp, &s2, sizeof(s2));
|
||||
(void)printf(pr->fmt, (quad_t)s2);
|
||||
break;
|
||||
case 4:
|
||||
bcopy(bp, &s4, sizeof(s4));
|
||||
(void)printf(pr->fmt, (quad_t)s4);
|
||||
break;
|
||||
case 8:
|
||||
bcopy(bp, &s8, 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(globals, pr, bp);
|
||||
break;
|
||||
case F_UINT:
|
||||
switch(pr->bcnt) {
|
||||
case 1:
|
||||
(void)printf(pr->fmt, (u_quad_t)*bp);
|
||||
break;
|
||||
case 2:
|
||||
bcopy(bp, &u2, sizeof(u2));
|
||||
(void)printf(pr->fmt, (u_quad_t)u2);
|
||||
break;
|
||||
case 4:
|
||||
bcopy(bp, &u4, sizeof(u4));
|
||||
(void)printf(pr->fmt, (u_quad_t)u4);
|
||||
break;
|
||||
case 8:
|
||||
bcopy(bp, &u8, sizeof(u8));
|
||||
(void)printf(pr->fmt, u8);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bpad(PR *pr)
|
||||
{
|
||||
static char const *spec = " -0+#";
|
||||
char *p1, *p2;
|
||||
|
||||
/*
|
||||
* Remove all conversion flags; '-' is the only one valid
|
||||
* with %s, and it's not useful here.
|
||||
*/
|
||||
pr->flags = F_BPAD;
|
||||
pr->cchar[0] = 's';
|
||||
pr->cchar[1] = '\0';
|
||||
for (p1 = pr->fmt; *p1 != '%'; ++p1);
|
||||
for (p2 = ++p1; *p1 && index(spec, *p1); ++p1);
|
||||
while ((*p2++ = *p1++));
|
||||
}
|
||||
|
||||
static char **_argv;
|
||||
|
||||
u_char *
|
||||
get(rtems_shell_hexdump_globals* globals)
|
||||
{
|
||||
#if RTEMS_REMOVED
|
||||
static int ateof = 1;
|
||||
static u_char *curp, *savp;
|
||||
#endif
|
||||
int n;
|
||||
int need, nread;
|
||||
int valid_save = 0;
|
||||
u_char *tmpp;
|
||||
|
||||
if (!curp) {
|
||||
if ((curp = calloc(1, blocksize)) == NULL)
|
||||
err(exit_jump, 1, NULL);
|
||||
if ((savp = calloc(1, blocksize)) == NULL)
|
||||
err(exit_jump, 1, NULL);
|
||||
} else {
|
||||
tmpp = curp;
|
||||
curp = savp;
|
||||
savp = tmpp;
|
||||
address += blocksize;
|
||||
valid_save = 1;
|
||||
}
|
||||
for (need = blocksize, nread = 0;;) {
|
||||
/*
|
||||
* if read the right number of bytes, or at EOF for one file,
|
||||
* and no other files are available, zero-pad the rest of the
|
||||
* block and set the end flag.
|
||||
*/
|
||||
if (!length || (ateof && !next(globals, (char **)NULL))) {
|
||||
if (odmode && address < skip)
|
||||
errx(exit_jump, 1, "cannot skip past end of input");
|
||||
if (need == blocksize)
|
||||
return((u_char *)NULL);
|
||||
/*
|
||||
* XXX bcmp() is not quite right in the presence
|
||||
* of multibyte characters.
|
||||
*/
|
||||
if (vflag != ALL &&
|
||||
valid_save &&
|
||||
bcmp(curp, savp, nread) == 0) {
|
||||
if (vflag != DUP)
|
||||
(void)printf("*\n");
|
||||
return((u_char *)NULL);
|
||||
}
|
||||
bzero((char *)curp + nread, need);
|
||||
eaddress = address + nread;
|
||||
return(curp);
|
||||
}
|
||||
n = fread((char *)curp + nread, sizeof(u_char),
|
||||
length == -1 ? need : MIN(length, need), hdstdin);
|
||||
if (!n) {
|
||||
if (ferror(hdstdin))
|
||||
warn("%s", _argv[-1]);
|
||||
ateof = 1;
|
||||
continue;
|
||||
}
|
||||
ateof = 0;
|
||||
if (length != -1)
|
||||
length -= n;
|
||||
if (!(need -= n)) {
|
||||
/*
|
||||
* XXX bcmp() is not quite right in the presence
|
||||
* of multibyte characters.
|
||||
*/
|
||||
if (vflag == ALL || vflag == FIRST ||
|
||||
valid_save == 0 ||
|
||||
bcmp(curp, savp, blocksize) != 0) {
|
||||
if (vflag == DUP || vflag == FIRST)
|
||||
vflag = WAIT;
|
||||
return(curp);
|
||||
}
|
||||
if (vflag == WAIT)
|
||||
(void)printf("*\n");
|
||||
vflag = DUP;
|
||||
address += blocksize;
|
||||
need = blocksize;
|
||||
nread = 0;
|
||||
}
|
||||
else
|
||||
nread += n;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
peek(rtems_shell_hexdump_globals* globals, u_char *buf, size_t nbytes)
|
||||
{
|
||||
size_t n, nread;
|
||||
int c;
|
||||
|
||||
if (length != -1 && nbytes > (unsigned int)length)
|
||||
nbytes = length;
|
||||
nread = 0;
|
||||
while (nread < nbytes && (c = getchar()) != EOF) {
|
||||
*buf++ = c;
|
||||
nread++;
|
||||
}
|
||||
n = nread;
|
||||
while (n-- > 0) {
|
||||
c = *--buf;
|
||||
ungetc(c, hdstdin);
|
||||
}
|
||||
return (nread);
|
||||
}
|
||||
|
||||
int
|
||||
next(rtems_shell_hexdump_globals* globals, char **argv)
|
||||
{
|
||||
#if RTEMS_REMOVED
|
||||
static int done;
|
||||
#endif
|
||||
int statok;
|
||||
|
||||
if (argv) {
|
||||
_argv = argv;
|
||||
return(1);
|
||||
}
|
||||
for (;;) {
|
||||
if (*_argv) {
|
||||
done = 1;
|
||||
if (!hdstdin) {
|
||||
hdstdin = malloc(sizeof(FILE));
|
||||
if (!hdstdin)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
err(exit_jump, 1, "file name allocation");
|
||||
}
|
||||
}
|
||||
if (!(hdstdin = fopen(*_argv, "r"))) {
|
||||
warn("%s", *_argv);
|
||||
exitval = 1;
|
||||
++_argv;
|
||||
continue;
|
||||
}
|
||||
statok = 1;
|
||||
} else {
|
||||
errno = ECANCELED;
|
||||
err(exit_jump, 1, "no file (stdin no supported)");
|
||||
if (done++)
|
||||
return(0);
|
||||
statok = 0;
|
||||
}
|
||||
if (skip)
|
||||
doskip(globals, statok ? *_argv : "stdin", statok);
|
||||
if (*_argv)
|
||||
++_argv;
|
||||
if (!skip)
|
||||
return(1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
doskip(rtems_shell_hexdump_globals* globals, const char *fname, int statok)
|
||||
{
|
||||
int cnt;
|
||||
struct stat sb;
|
||||
|
||||
if (statok) {
|
||||
if (fstat(fileno(hdstdin), &sb))
|
||||
err(exit_jump, 1, "%s", fname);
|
||||
if (S_ISREG(sb.st_mode) && skip >= sb.st_size) {
|
||||
address += sb.st_size;
|
||||
skip -= sb.st_size;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (S_ISREG(sb.st_mode)) {
|
||||
if (fseeko(hdstdin, skip, SEEK_SET))
|
||||
err(exit_jump, 1, "%s", fname);
|
||||
address += skip;
|
||||
skip = 0;
|
||||
} else {
|
||||
for (cnt = 0; cnt < skip; ++cnt)
|
||||
if (getchar() == EOF)
|
||||
break;
|
||||
address += cnt;
|
||||
skip -= cnt;
|
||||
}
|
||||
}
|
||||
451
cpukit/libmisc/shell/hexdump-odsyntax.c
Normal file
451
cpukit/libmisc/shell/hexdump-odsyntax.c
Normal file
@@ -0,0 +1,451 @@
|
||||
/*-
|
||||
* 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
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)odsyntax.c 8.2 (Berkeley) 5/4/95";
|
||||
#endif /* not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/usr.bin/hexdump/odsyntax.c,v 1.17 2004/07/22 13:14:42 johan Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "hexdump.h"
|
||||
|
||||
#define __need_getopt_newlib
|
||||
#include <getopt.h>
|
||||
|
||||
#define PADDING " "
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
int odmode;
|
||||
#endif
|
||||
|
||||
static void odadd(rtems_shell_hexdump_globals*, const char *);
|
||||
static void odformat(rtems_shell_hexdump_globals*, const char *);
|
||||
static const char *odformatfp(rtems_shell_hexdump_globals*, char, const char *);
|
||||
static const char *odformatint(rtems_shell_hexdump_globals*, char, const char *);
|
||||
static void odoffset(rtems_shell_hexdump_globals*, int, char ***);
|
||||
static void odusage(rtems_shell_hexdump_globals*);
|
||||
|
||||
void
|
||||
oldsyntax(rtems_shell_hexdump_globals* globals, int argc, char ***argvp)
|
||||
{
|
||||
static char empty[] = "", padding[] = PADDING;
|
||||
int ch;
|
||||
char **argv, *end;
|
||||
|
||||
struct getopt_data getopt_reent;
|
||||
memset(&getopt_reent, 0, sizeof(getopt_data));
|
||||
|
||||
/* Add initial (default) address format. -A may change it later. */
|
||||
#define TYPE_OFFSET 7
|
||||
add(globals, "\"%07.7_Ao\n\"");
|
||||
add(globals, "\"%07.7_ao \"");
|
||||
|
||||
odmode = 1;
|
||||
argv = *argvp;
|
||||
while ((ch = getopt_r(argc, argv, "A:aBbcDdeFfHhIij:LlN:Oost:vXx", &getopt_reent)) != -1)
|
||||
switch (ch) {
|
||||
case 'A':
|
||||
switch (*optarg) {
|
||||
case 'd': case 'o': case 'x':
|
||||
fshead->nextfu->fmt[TYPE_OFFSET] = *optarg;
|
||||
fshead->nextfs->nextfu->fmt[TYPE_OFFSET] =
|
||||
*optarg;
|
||||
break;
|
||||
case 'n':
|
||||
fshead->nextfu->fmt = empty;
|
||||
fshead->nextfs->nextfu->fmt = padding;
|
||||
break;
|
||||
default:
|
||||
errx(exit_jump, 1, "%s: invalid address base", optarg);
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
odformat(globals, "a");
|
||||
break;
|
||||
case 'B':
|
||||
case 'o':
|
||||
odformat(globals, "o2");
|
||||
break;
|
||||
case 'b':
|
||||
odformat(globals, "o1");
|
||||
break;
|
||||
case 'c':
|
||||
odformat(globals, "c");
|
||||
break;
|
||||
case 'd':
|
||||
odformat(globals, "u2");
|
||||
break;
|
||||
case 'D':
|
||||
odformat(globals, "u4");
|
||||
break;
|
||||
case 'e': /* undocumented in od */
|
||||
case 'F':
|
||||
odformat(globals, "fD");
|
||||
break;
|
||||
case 'f':
|
||||
odformat(globals, "fF");
|
||||
break;
|
||||
case 'H':
|
||||
case 'X':
|
||||
odformat(globals, "x4");
|
||||
break;
|
||||
case 'h':
|
||||
case 'x':
|
||||
odformat(globals, "x2");
|
||||
break;
|
||||
case 'I':
|
||||
case 'L':
|
||||
case 'l':
|
||||
odformat(globals, "dL");
|
||||
break;
|
||||
case 'i':
|
||||
odformat(globals, "dI");
|
||||
break;
|
||||
case 'j':
|
||||
errno = 0;
|
||||
skip = strtoll(optarg, &end, 0);
|
||||
if (*end == 'b')
|
||||
skip *= 512;
|
||||
else if (*end == 'k')
|
||||
skip *= 1024;
|
||||
else if (*end == 'm')
|
||||
skip *= 1048576L;
|
||||
if (errno != 0 || skip < 0 || strlen(end) > 1)
|
||||
errx(exit_jump, 1, "%s: invalid skip amount", optarg);
|
||||
break;
|
||||
case 'N':
|
||||
if ((length = atoi(optarg)) <= 0)
|
||||
errx(exit_jump, 1, "%s: invalid length", optarg);
|
||||
break;
|
||||
case 'O':
|
||||
odformat(globals, "o4");
|
||||
break;
|
||||
case 's':
|
||||
odformat(globals, "d2");
|
||||
break;
|
||||
case 't':
|
||||
odformat(globals, optarg);
|
||||
break;
|
||||
case 'v':
|
||||
vflag = ALL;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
odusage(globals);
|
||||
}
|
||||
|
||||
if (fshead->nextfs->nextfs == NULL)
|
||||
odformat(globals, "oS");
|
||||
|
||||
argc -= getopt_reent.optind;
|
||||
*argvp += getopt_reent.optind;
|
||||
|
||||
if (argc)
|
||||
odoffset(globals, argc, argvp);
|
||||
}
|
||||
|
||||
static void
|
||||
odusage(rtems_shell_hexdump_globals* globals)
|
||||
{
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: od [-aBbcDdeFfHhIiLlOosvXx] [-A base] [-j skip] [-N length] [-t type]\n");
|
||||
fprintf(stderr,
|
||||
" [[+]offset[.][Bb]] [file ...]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
odoffset(rtems_shell_hexdump_globals* globals, int argc, char ***argvp)
|
||||
{
|
||||
char *p, *num, *end;
|
||||
int base;
|
||||
|
||||
/*
|
||||
* The offset syntax of od(1) was genuinely bizarre. First, if
|
||||
* it started with a plus it had to be an offset. Otherwise, if
|
||||
* there were at least two arguments, a number or lower-case 'x'
|
||||
* followed by a number makes it an offset. By default it was
|
||||
* octal; if it started with 'x' or '0x' it was hex. If it ended
|
||||
* in a '.', it was decimal. If a 'b' or 'B' was appended, it
|
||||
* multiplied the number by 512 or 1024 byte units. There was
|
||||
* no way to assign a block count to a hex offset.
|
||||
*
|
||||
* We assume it's a file if the offset is bad.
|
||||
*/
|
||||
p = argc == 1 ? (*argvp)[0] : (*argvp)[1];
|
||||
|
||||
if (*p != '+' && (argc < 2 ||
|
||||
(!isdigit(p[0]) && (p[0] != 'x' || !isxdigit(p[1])))))
|
||||
return;
|
||||
|
||||
base = 0;
|
||||
/*
|
||||
* skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
|
||||
* set base.
|
||||
*/
|
||||
if (p[0] == '+')
|
||||
++p;
|
||||
if (p[0] == 'x' && isxdigit(p[1])) {
|
||||
++p;
|
||||
base = 16;
|
||||
} else if (p[0] == '0' && p[1] == 'x') {
|
||||
p += 2;
|
||||
base = 16;
|
||||
}
|
||||
|
||||
/* skip over the number */
|
||||
if (base == 16)
|
||||
for (num = p; isxdigit(*p); ++p);
|
||||
else
|
||||
for (num = p; isdigit(*p); ++p);
|
||||
|
||||
/* check for no number */
|
||||
if (num == p)
|
||||
return;
|
||||
|
||||
/* if terminates with a '.', base is decimal */
|
||||
if (*p == '.') {
|
||||
if (base)
|
||||
return;
|
||||
base = 10;
|
||||
}
|
||||
|
||||
skip = strtoll(num, &end, base ? base : 8);
|
||||
|
||||
/* if end isn't the same as p, we got a non-octal digit */
|
||||
if (end != p) {
|
||||
skip = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*p) {
|
||||
if (*p == 'B') {
|
||||
skip *= 1024;
|
||||
++p;
|
||||
} else if (*p == 'b') {
|
||||
skip *= 512;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
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
|
||||
odformat(rtems_shell_hexdump_globals* globals, const char *fmt)
|
||||
{
|
||||
char fchar;
|
||||
|
||||
while (*fmt != '\0') {
|
||||
switch ((fchar = *fmt++)) {
|
||||
case 'a':
|
||||
odadd(globals, "16/1 \"%3_u \" \"\\n\"");
|
||||
break;
|
||||
case 'c':
|
||||
odadd(globals, "16/1 \"%3_c \" \"\\n\"");
|
||||
break;
|
||||
case 'o': case 'u': case 'd': case 'x':
|
||||
fmt = odformatint(globals, fchar, fmt);
|
||||
break;
|
||||
case 'f':
|
||||
fmt = odformatfp(globals, fchar, fmt);
|
||||
break;
|
||||
default:
|
||||
errx(exit_jump, 1, "%c: unrecognised format character", fchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
#define __unused
|
||||
|
||||
static const char *
|
||||
odformatfp(rtems_shell_hexdump_globals* globals, char fchar __unused, const char *fmt)
|
||||
{
|
||||
size_t isize;
|
||||
int digits;
|
||||
char *end, *hdfmt;
|
||||
|
||||
isize = sizeof(double);
|
||||
switch (*fmt) {
|
||||
case 'F':
|
||||
isize = sizeof(float);
|
||||
fmt++;
|
||||
break;
|
||||
case 'D':
|
||||
isize = sizeof(double);
|
||||
fmt++;
|
||||
break;
|
||||
case 'L':
|
||||
isize = sizeof(long double);
|
||||
fmt++;
|
||||
break;
|
||||
default:
|
||||
if (isdigit((unsigned char)*fmt)) {
|
||||
errno = 0;
|
||||
isize = (size_t)strtoul(fmt, &end, 10);
|
||||
if (errno != 0 || isize == 0)
|
||||
errx(exit_jump, 1, "%s: invalid size", fmt);
|
||||
fmt = (const char *)end;
|
||||
}
|
||||
}
|
||||
switch (isize) {
|
||||
case sizeof(float):
|
||||
digits = FLT_DIG;
|
||||
break;
|
||||
case sizeof(double):
|
||||
digits = DBL_DIG;
|
||||
break;
|
||||
default:
|
||||
if (isize == sizeof(long double))
|
||||
digits = LDBL_DIG;
|
||||
else
|
||||
errx(exit_jump, 1, "unsupported floating point size %lu",
|
||||
(u_long)isize);
|
||||
}
|
||||
|
||||
asprintf(&hdfmt, "%lu/%lu \" %%%d.%de \" \"\\n\"",
|
||||
16UL / (u_long)isize, (u_long)isize, digits + 8, digits);
|
||||
if (hdfmt == NULL)
|
||||
err(exit_jump, 1, NULL);
|
||||
odadd(globals, hdfmt);
|
||||
free(hdfmt);
|
||||
|
||||
return (fmt);
|
||||
}
|
||||
|
||||
static const char *
|
||||
odformatint(rtems_shell_hexdump_globals* globals, char fchar, const char *fmt)
|
||||
{
|
||||
unsigned long long n;
|
||||
size_t isize;
|
||||
int digits;
|
||||
char *end, *hdfmt;
|
||||
|
||||
isize = sizeof(int);
|
||||
switch (*fmt) {
|
||||
case 'C':
|
||||
isize = sizeof(char);
|
||||
fmt++;
|
||||
break;
|
||||
case 'I':
|
||||
isize = sizeof(int);
|
||||
fmt++;
|
||||
break;
|
||||
case 'L':
|
||||
isize = sizeof(long);
|
||||
fmt++;
|
||||
break;
|
||||
case 'S':
|
||||
isize = sizeof(short);
|
||||
fmt++;
|
||||
break;
|
||||
default:
|
||||
if (isdigit((unsigned char)*fmt)) {
|
||||
errno = 0;
|
||||
isize = (size_t)strtoul(fmt, &end, 10);
|
||||
if (errno != 0 || isize == 0)
|
||||
errx(exit_jump, 1, "%s: invalid size", fmt);
|
||||
if (isize != sizeof(char) && isize != sizeof(short) &&
|
||||
isize != sizeof(int) && isize != sizeof(long))
|
||||
errx(exit_jump, 1, "unsupported int size %lu",
|
||||
(u_long)isize);
|
||||
fmt = (const char *)end;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the maximum number of digits we need to
|
||||
* fit the number. Overestimate for decimal with log
|
||||
* base 8. We need one extra space for signed numbers
|
||||
* to store the sign.
|
||||
*/
|
||||
n = (1ULL << (8 * isize)) - 1;
|
||||
digits = 0;
|
||||
while (n != 0) {
|
||||
digits++;
|
||||
n >>= (fchar == 'x') ? 4 : 3;
|
||||
}
|
||||
if (fchar == 'd')
|
||||
digits++;
|
||||
asprintf(&hdfmt, "%lu/%lu \"%*s%%%s%d%c\" \"\\n\"",
|
||||
16UL / (u_long)isize, (u_long)isize, (int)(4 * isize - digits),
|
||||
"", (fchar == 'd' || fchar == 'u') ? "" : "0", digits, fchar);
|
||||
if (hdfmt == NULL)
|
||||
err(exit_jump, 1, NULL);
|
||||
odadd(globals, hdfmt);
|
||||
free(hdfmt);
|
||||
|
||||
return (fmt);
|
||||
}
|
||||
|
||||
static void
|
||||
odadd(rtems_shell_hexdump_globals* globals, const char *fmt)
|
||||
{
|
||||
static int needpad;
|
||||
|
||||
if (needpad)
|
||||
add(globals, "\""PADDING"\"");
|
||||
add(globals, fmt);
|
||||
needpad = 1;
|
||||
}
|
||||
517
cpukit/libmisc/shell/hexdump-parse.c
Normal file
517
cpukit/libmisc/shell/hexdump-parse.c
Normal file
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* 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
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/usr.bin/hexdump/parse.c,v 1.14 2006/08/09 19:12:10 maxim Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "hexdump.h"
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
FU *endfu; /* format at end-of-data */
|
||||
#endif
|
||||
|
||||
void
|
||||
addfile(rtems_shell_hexdump_globals* globals, char *name)
|
||||
{
|
||||
unsigned char *p;
|
||||
FILE *fp;
|
||||
int ch;
|
||||
char buf[2048 + 1];
|
||||
|
||||
if ((fp = fopen(name, "r")) == NULL)
|
||||
err(exit_jump, 1, "%s", name);
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
if (!(p = (unsigned char*)index(buf, '\n'))) {
|
||||
warnx("line too long");
|
||||
while ((ch = getchar()) != '\n' && ch != EOF);
|
||||
continue;
|
||||
}
|
||||
*p = '\0';
|
||||
for (p = (unsigned char*) buf; *p && isspace(*p); ++p);
|
||||
if (!*p || *p == '#')
|
||||
continue;
|
||||
add(globals, (char*)p);
|
||||
}
|
||||
(void)fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
add(rtems_shell_hexdump_globals* globals, const char *fmt)
|
||||
{
|
||||
unsigned const char *p, *savep;
|
||||
static FS **nextfs;
|
||||
FS *tfs;
|
||||
FU *tfu, **nextfu;
|
||||
|
||||
/* start new linked list of format units */
|
||||
if ((tfs = calloc(1, sizeof(FS))) == NULL)
|
||||
err(exit_jump, 1, NULL);
|
||||
if (!fshead)
|
||||
fshead = tfs;
|
||||
else
|
||||
*nextfs = tfs;
|
||||
nextfs = &tfs->nextfs;
|
||||
nextfu = &tfs->nextfu;
|
||||
|
||||
/* take the format string and break it up into format units */
|
||||
for (p = (unsigned const char*)fmt;;) {
|
||||
/* skip leading white space */
|
||||
for (; isspace(*p); ++p);
|
||||
if (!*p)
|
||||
break;
|
||||
|
||||
/* allocate a new format unit and link it in */
|
||||
if ((tfu = calloc(1, sizeof(FU))) == NULL)
|
||||
err(exit_jump, 1, NULL);
|
||||
*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 != '/')
|
||||
badfmt(globals, fmt);
|
||||
/* may overwrite either white space or slash */
|
||||
tfu->reps = atoi((char*)savep);
|
||||
tfu->flags = F_SETREP;
|
||||
/* skip trailing white space */
|
||||
for (++p; isspace(*p); ++p);
|
||||
}
|
||||
|
||||
/* skip slash and trailing white space */
|
||||
if (*p == '/')
|
||||
while (isspace(*++p));
|
||||
|
||||
/* byte count */
|
||||
if (isdigit(*p)) {
|
||||
for (savep = p; isdigit(*p); ++p);
|
||||
if (!isspace(*p))
|
||||
badfmt(globals, fmt);
|
||||
tfu->bcnt = atoi((char*)savep);
|
||||
/* skip trailing white space */
|
||||
for (++p; isspace(*p); ++p);
|
||||
}
|
||||
|
||||
/* format */
|
||||
if (*p != '"')
|
||||
badfmt(globals, fmt);
|
||||
for (savep = ++p; *p != '"';)
|
||||
if (*p++ == 0)
|
||||
badfmt(globals, fmt);
|
||||
if (!(tfu->fmt = malloc(p - savep + 1)))
|
||||
err(exit_jump, 1, NULL);
|
||||
(void) strncpy(tfu->fmt, (char*)savep, p - savep);
|
||||
tfu->fmt[p - savep] = '\0';
|
||||
escape(tfu->fmt);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *spec = ".#-+ 0123456789";
|
||||
|
||||
int
|
||||
size(rtems_shell_hexdump_globals* globals, FS *fs)
|
||||
{
|
||||
FU *fu;
|
||||
int bcnt, cursize;
|
||||
unsigned char *fmt;
|
||||
int prec;
|
||||
|
||||
/* figure out the data block size needed for each format unit */
|
||||
for (cursize = 0, fu = fs->nextfu; fu; fu = fu->nextfu) {
|
||||
if (fu->bcnt) {
|
||||
cursize += fu->bcnt * fu->reps;
|
||||
continue;
|
||||
}
|
||||
for (bcnt = prec = 0, fmt = (unsigned char*) fu->fmt; *fmt; ++fmt) {
|
||||
if (*fmt != '%')
|
||||
continue;
|
||||
/*
|
||||
* skip any special chars -- save precision in
|
||||
* case it's a %s format.
|
||||
*/
|
||||
while (index(spec + 1, *++fmt));
|
||||
if (*fmt == '.' && isdigit(*++fmt)) {
|
||||
prec = atoi((char*)fmt);
|
||||
while (isdigit(*++fmt));
|
||||
}
|
||||
switch(*fmt) {
|
||||
case 'c':
|
||||
bcnt += 1;
|
||||
break;
|
||||
case 'd': case 'i': case 'o': case 'u':
|
||||
case 'x': case 'X':
|
||||
bcnt += 4;
|
||||
break;
|
||||
case 'e': case 'E': case 'f': case 'g': case 'G':
|
||||
bcnt += 8;
|
||||
break;
|
||||
case 's':
|
||||
bcnt += prec;
|
||||
break;
|
||||
case '_':
|
||||
switch(*++fmt) {
|
||||
case 'c': case 'p': case 'u':
|
||||
bcnt += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cursize += bcnt * fu->reps;
|
||||
}
|
||||
return (cursize);
|
||||
}
|
||||
|
||||
void
|
||||
rewrite(rtems_shell_hexdump_globals* globals, FS *fs)
|
||||
{
|
||||
enum { NOTOKAY, USEBCNT, USEPREC } sokay;
|
||||
PR *pr, **nextpr;
|
||||
FU *fu;
|
||||
unsigned char *p1, *p2, *fmtp;
|
||||
char savech, cs[3];
|
||||
int nconv, prec;
|
||||
size_t len;
|
||||
|
||||
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.
|
||||
*/
|
||||
for (nconv = 0, fmtp = (unsigned char*)fu->fmt; *fmtp; nextpr = &pr->nextpr) {
|
||||
if ((pr = calloc(1, sizeof(PR))) == NULL)
|
||||
err(exit_jump, 1, NULL);
|
||||
if (!fu->nextpr)
|
||||
fu->nextpr = pr;
|
||||
else
|
||||
*nextpr = pr;
|
||||
|
||||
/* Skip preceding text and up to the next % sign. */
|
||||
for (p1 = fmtp; *p1 && *p1 != '%'; ++p1);
|
||||
|
||||
/* Only text in the string. */
|
||||
if (!*p1) {
|
||||
pr->fmt = (char*)fmtp;
|
||||
pr->flags = F_TEXT;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get precision for %s -- if have a byte count, don't
|
||||
* need it.
|
||||
*/
|
||||
if (fu->bcnt) {
|
||||
sokay = USEBCNT;
|
||||
/* Skip to conversion character. */
|
||||
for (++p1; index(spec, *p1); ++p1);
|
||||
} else {
|
||||
/* Skip any special chars, field width. */
|
||||
while (index(spec + 1, *++p1));
|
||||
if (*p1 == '.' && isdigit(*++p1)) {
|
||||
sokay = USEPREC;
|
||||
prec = atoi((char*)p1);
|
||||
while (isdigit(*++p1));
|
||||
} else
|
||||
sokay = NOTOKAY;
|
||||
}
|
||||
|
||||
p2 = p1 + 1; /* Set end pointer. */
|
||||
cs[0] = *p1; /* Set conversion string. */
|
||||
cs[1] = '\0';
|
||||
|
||||
/*
|
||||
* Figure out the byte count for each conversion;
|
||||
* rewrite the format as necessary, set up blank-
|
||||
* padding for end of data.
|
||||
*/
|
||||
switch(cs[0]) {
|
||||
case 'c':
|
||||
pr->flags = F_CHAR;
|
||||
switch(fu->bcnt) {
|
||||
case 0: case 1:
|
||||
pr->bcnt = 1;
|
||||
break;
|
||||
default:
|
||||
p1[1] = '\0';
|
||||
badcnt(globals, (char*)p1);
|
||||
}
|
||||
break;
|
||||
case 'd': case 'i':
|
||||
pr->flags = F_INT;
|
||||
goto isint;
|
||||
case 'o': case 'u': case 'x': case 'X':
|
||||
pr->flags = F_UINT;
|
||||
isint: cs[2] = '\0';
|
||||
cs[1] = cs[0];
|
||||
cs[0] = 'q';
|
||||
switch(fu->bcnt) {
|
||||
case 0: case 4:
|
||||
pr->bcnt = 4;
|
||||
break;
|
||||
case 1:
|
||||
pr->bcnt = 1;
|
||||
break;
|
||||
case 2:
|
||||
pr->bcnt = 2;
|
||||
break;
|
||||
default:
|
||||
p1[1] = '\0';
|
||||
badcnt(globals, (char*)p1);
|
||||
}
|
||||
break;
|
||||
case 'e': case 'E': case 'f': case 'g': case 'G':
|
||||
pr->flags = F_DBL;
|
||||
switch(fu->bcnt) {
|
||||
case 0: case 8:
|
||||
pr->bcnt = 8;
|
||||
break;
|
||||
case 4:
|
||||
pr->bcnt = 4;
|
||||
break;
|
||||
default:
|
||||
if (fu->bcnt == sizeof(long double)) {
|
||||
cs[2] = '\0';
|
||||
cs[1] = cs[0];
|
||||
cs[0] = 'L';
|
||||
pr->bcnt = sizeof(long double);
|
||||
} else {
|
||||
p1[1] = '\0';
|
||||
badcnt(globals, (char*)p1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
pr->flags = F_STR;
|
||||
switch(sokay) {
|
||||
case NOTOKAY:
|
||||
badsfmt(globals);
|
||||
case USEBCNT:
|
||||
pr->bcnt = fu->bcnt;
|
||||
break;
|
||||
case USEPREC:
|
||||
pr->bcnt = prec;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '_':
|
||||
++p2;
|
||||
switch(p1[1]) {
|
||||
case 'A':
|
||||
endfu = fu;
|
||||
fu->flags |= F_IGNORE;
|
||||
/* FALLTHROUGH */
|
||||
case 'a':
|
||||
pr->flags = F_ADDRESS;
|
||||
++p2;
|
||||
switch(p1[2]) {
|
||||
case 'd': case 'o': case'x':
|
||||
cs[0] = 'q';
|
||||
cs[1] = p1[2];
|
||||
cs[2] = '\0';
|
||||
break;
|
||||
default:
|
||||
p1[3] = '\0';
|
||||
badconv(globals, (char*)p1);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
pr->flags = F_C;
|
||||
/* cs[0] = 'c'; set in conv_c */
|
||||
goto isint2;
|
||||
case 'p':
|
||||
pr->flags = F_P;
|
||||
cs[0] = 'c';
|
||||
goto isint2;
|
||||
case 'u':
|
||||
pr->flags = F_U;
|
||||
/* cs[0] = 'c'; set in conv_u */
|
||||
isint2: switch(fu->bcnt) {
|
||||
case 0: case 1:
|
||||
pr->bcnt = 1;
|
||||
break;
|
||||
default:
|
||||
p1[2] = '\0';
|
||||
badcnt(globals, (char*)p1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
p1[2] = '\0';
|
||||
badconv(globals, (char*)p1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
p1[1] = '\0';
|
||||
badconv(globals, (char*)p1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy to PR format string, set conversion character
|
||||
* pointer, update original.
|
||||
*/
|
||||
savech = *p2;
|
||||
p1[0] = '\0';
|
||||
len = strlen((char*)fmtp) + strlen(cs) + 1;
|
||||
if ((pr->fmt = calloc(1, len)) == NULL)
|
||||
err(exit_jump, 1, NULL);
|
||||
snprintf(pr->fmt, len, "%s%s", fmtp, cs);
|
||||
*p2 = savech;
|
||||
pr->cchar = pr->fmt + (p1 - fmtp);
|
||||
fmtp = p2;
|
||||
|
||||
/* Only one conversion character if byte count. */
|
||||
if (!(pr->flags&F_ADDRESS) && fu->bcnt && nconv++)
|
||||
errx(exit_jump, 1, "byte count with multiple conversion characters");
|
||||
}
|
||||
/*
|
||||
* If format unit byte count not specified, figure it out
|
||||
* so can adjust rep count later.
|
||||
*/
|
||||
if (!fu->bcnt)
|
||||
for (pr = fu->nextpr; pr; pr = pr->nextpr)
|
||||
fu->bcnt += pr->bcnt;
|
||||
}
|
||||
/*
|
||||
* 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
|
||||
* gets output from the last iteration of the format unit.
|
||||
*/
|
||||
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;
|
||||
if (fu->reps > 1) {
|
||||
for (pr = fu->nextpr;; pr = pr->nextpr)
|
||||
if (!pr->nextpr)
|
||||
break;
|
||||
for (p1 = (unsigned char*)pr->fmt, p2 = NULL; *p1; ++p1)
|
||||
p2 = isspace(*p1) ? p1 : NULL;
|
||||
if (p2)
|
||||
pr->nospace = (char*)p2;
|
||||
}
|
||||
}
|
||||
#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
|
||||
escape(char *p1)
|
||||
{
|
||||
char *p2;
|
||||
|
||||
/* alphabetic escape sequences have to be done in place */
|
||||
for (p2 = p1;; ++p1, ++p2) {
|
||||
if (!*p1) {
|
||||
*p2 = *p1;
|
||||
break;
|
||||
}
|
||||
if (*p1 == '\\')
|
||||
switch(*++p1) {
|
||||
case 'a':
|
||||
/* *p2 = '\a'; */
|
||||
*p2 = '\007';
|
||||
break;
|
||||
case 'b':
|
||||
*p2 = '\b';
|
||||
break;
|
||||
case 'f':
|
||||
*p2 = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
*p2 = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
*p2 = '\r';
|
||||
break;
|
||||
case 't':
|
||||
*p2 = '\t';
|
||||
break;
|
||||
case 'v':
|
||||
*p2 = '\v';
|
||||
break;
|
||||
default:
|
||||
*p2 = *p1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
badcnt(rtems_shell_hexdump_globals* globals, char *s)
|
||||
{
|
||||
errx(exit_jump, 1, "%s: bad byte count", s);
|
||||
}
|
||||
|
||||
void
|
||||
badsfmt(rtems_shell_hexdump_globals* globals)
|
||||
{
|
||||
errx(exit_jump, 1, "%%s: requires a precision or a byte count");
|
||||
}
|
||||
|
||||
void
|
||||
badfmt(rtems_shell_hexdump_globals* globals, const char *fmt)
|
||||
{
|
||||
errx(exit_jump, 1, "\"%s\": bad format", fmt);
|
||||
}
|
||||
|
||||
void
|
||||
badconv(rtems_shell_hexdump_globals* globals, char *ch)
|
||||
{
|
||||
errx(exit_jump, 1, "%%%s: bad conversion character", ch);
|
||||
}
|
||||
183
cpukit/libmisc/shell/hexdump.h
Normal file
183
cpukit/libmisc/shell/hexdump.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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.
|
||||
*
|
||||
* @(#)hexdump.h 8.1 (Berkeley) 6/6/93
|
||||
* $FreeBSD: src/usr.bin/hexdump/hexdump.h,v 1.9 2004/07/11 01:11:12 tjr Exp $
|
||||
*/
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
typedef struct _pr {
|
||||
struct _pr *nextpr; /* next print unit */
|
||||
#define F_ADDRESS 0x001 /* print offset */
|
||||
#define F_BPAD 0x002 /* blank pad */
|
||||
#define F_C 0x004 /* %_c */
|
||||
#define F_CHAR 0x008 /* %c */
|
||||
#define F_DBL 0x010 /* %[EefGf] */
|
||||
#define F_INT 0x020 /* %[di] */
|
||||
#define F_P 0x040 /* %_p */
|
||||
#define F_STR 0x080 /* %s */
|
||||
#define F_U 0x100 /* %_u */
|
||||
#define F_UINT 0x200 /* %[ouXx] */
|
||||
#define F_TEXT 0x400 /* no conversions */
|
||||
u_int flags; /* flag values */
|
||||
int bcnt; /* byte count */
|
||||
char *cchar; /* conversion character */
|
||||
char *fmt; /* printf format */
|
||||
char *nospace; /* no whitespace version */
|
||||
int mbleft; /* bytes left of multibyte char. */
|
||||
mbstate_t mbstate; /* conversion state */
|
||||
} PR;
|
||||
|
||||
typedef struct _fu {
|
||||
struct _fu *nextfu; /* next format unit */
|
||||
struct _pr *nextpr; /* next print unit */
|
||||
#define F_IGNORE 0x01 /* %_A */
|
||||
#define F_SETREP 0x02 /* rep count set, not default */
|
||||
u_int flags; /* flag values */
|
||||
int reps; /* repetition count */
|
||||
int bcnt; /* byte count */
|
||||
char *fmt; /* format string */
|
||||
} FU;
|
||||
|
||||
typedef struct _fs { /* format strings */
|
||||
struct _fs *nextfs; /* linked list of format strings */
|
||||
struct _fu *nextfu; /* linked list of format units */
|
||||
int bcnt;
|
||||
} FS;
|
||||
|
||||
#if 0
|
||||
extern FS *fshead; /* head of format strings list */
|
||||
extern FU *endfu; /* format at end-of-data */
|
||||
extern int blocksize; /* data block size */
|
||||
extern int exitval; /* final exit value */
|
||||
extern int odmode; /* are we acting as od(1)? */
|
||||
extern int length; /* amount of data to read */
|
||||
extern off_t skip; /* amount of data to skip at start */
|
||||
enum _vflag { ALL, DUP, FIRST, WAIT }; /* -v values */
|
||||
extern enum _vflag vflag;
|
||||
#endif
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
enum _vflag { ALL, DUP, FIRST, WAIT }; /* -v values */
|
||||
typedef struct rtems_shell_hexdump_globals_t {
|
||||
FS *fshead; /* head of format strings list */
|
||||
FU *endfu; /* format at end-of-data */
|
||||
int blocksize; /* data block size */
|
||||
int exitval; /* final exit value */
|
||||
int odmode; /* are we acting as od(1)? */
|
||||
int length; /* amount of data to read */
|
||||
off_t skip; /* amount of data to skip at start */
|
||||
enum _vflag vflag;
|
||||
|
||||
off_t address;
|
||||
off_t eaddress;
|
||||
int ateof;
|
||||
u_char *curp;
|
||||
u_char *savp;
|
||||
int done;
|
||||
|
||||
FILE* hdstdin;
|
||||
|
||||
int exit_code;
|
||||
jmp_buf exit_jmp;
|
||||
} rtems_shell_hexdump_globals;
|
||||
|
||||
#define fshead globals->fshead
|
||||
#define endfu globals->endfu
|
||||
#define blocksize globals->blocksize
|
||||
#define exitval globals->exitval
|
||||
#define odmode globals->odmode
|
||||
#define length globals->length
|
||||
#define skip globals->skip
|
||||
#define vflag globals->vflag
|
||||
|
||||
#define address globals->address
|
||||
#define eaddress globals->eaddress
|
||||
#define ateof globals->ateof
|
||||
#define curp globals->curp
|
||||
#define savp globals->savp
|
||||
#define done globals->done
|
||||
|
||||
#define hdstdin globals->hdstdin
|
||||
|
||||
#define exit_jump &(globals->exit_jmp)
|
||||
|
||||
#define add rtems_shell_hexdump_add
|
||||
#define addfile rtems_shell_hexdump_addfile
|
||||
#define badcnt rtems_shell_hexdump_badcnt
|
||||
#define badconv rtems_shell_hexdump_badconv
|
||||
#define badfmt rtems_shell_hexdump_badfmt
|
||||
#define badsfmt rtems_shell_hexdump_badsfmt
|
||||
#define bpad rtems_shell_hexdump_bpad
|
||||
#define conv_c rtems_shell_hexdump_conv_c
|
||||
#define conv_u rtems_shell_hexdump_conv_u
|
||||
#define display rtems_shell_hexdump_display
|
||||
#define doskip rtems_shell_hexdump_doskip
|
||||
#define escape rtems_shell_hexdump_escape
|
||||
#define get rtems_shell_hexdump_get
|
||||
#define newsyntax rtems_shell_hexdump_newsyntax
|
||||
#define next rtems_shell_hexdump_next
|
||||
#define nomem rtems_shell_hexdump_nomem
|
||||
#define oldsyntax rtems_shell_hexdump_oldsyntax
|
||||
#define peek rtems_shell_hexdump_peek
|
||||
#define rewrite rtems_shell_hexdump_rewrite
|
||||
#define size rtems_shell_hexdump_size
|
||||
#define usage rtems_shell_hexdump_usage
|
||||
|
||||
void add(rtems_shell_hexdump_globals*, const char *);
|
||||
void addfile(rtems_shell_hexdump_globals*, char *);
|
||||
void badcnt(rtems_shell_hexdump_globals*, char *);
|
||||
void badconv(rtems_shell_hexdump_globals*, char *);
|
||||
void badfmt(rtems_shell_hexdump_globals*, const char *);
|
||||
void badsfmt(rtems_shell_hexdump_globals*);
|
||||
void bpad(PR *);
|
||||
void conv_c(rtems_shell_hexdump_globals*, PR *, u_char *, size_t);
|
||||
void conv_u(rtems_shell_hexdump_globals*, PR *, u_char *);
|
||||
void display(rtems_shell_hexdump_globals*);
|
||||
void doskip(rtems_shell_hexdump_globals*, const char *, int);
|
||||
void escape(char *);
|
||||
u_char *get(rtems_shell_hexdump_globals*);
|
||||
void newsyntax(rtems_shell_hexdump_globals*, int, char ***);
|
||||
int next(rtems_shell_hexdump_globals*, char **);
|
||||
void nomem(void);
|
||||
void oldsyntax(rtems_shell_hexdump_globals*, int, char ***);
|
||||
size_t peek(rtems_shell_hexdump_globals*, u_char *, size_t);
|
||||
void rewrite(rtems_shell_hexdump_globals*, FS *);
|
||||
int size(rtems_shell_hexdump_globals*, FS *);
|
||||
void usage(rtems_shell_hexdump_globals*);
|
||||
|
||||
#define exit(ec) rtems_shell_hexdump_exit(globals, ec)
|
||||
|
||||
void rtems_shell_hexdump_exit(rtems_shell_hexdump_globals* globals, int code);
|
||||
152
cpukit/libmisc/shell/hexsyntax.c
Normal file
152
cpukit/libmisc/shell/hexsyntax.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*-
|
||||
* 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
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)hexsyntax.c 8.2 (Berkeley) 5/4/95";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/usr.bin/hexdump/hexsyntax.c,v 1.12 2002/09/04 23:29:01 dwmalone Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "hexdump.h"
|
||||
|
||||
#define __need_getopt_newlib
|
||||
#include <getopt.h>
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
off_t skip; /* bytes to skip */
|
||||
#endif
|
||||
|
||||
void
|
||||
newsyntax(rtems_shell_hexdump_globals* globals, int argc, char ***argvp)
|
||||
{
|
||||
int ch;
|
||||
char *p, **argv;
|
||||
|
||||
struct getopt_data getopt_reent;
|
||||
memset(&getopt_reent, 0, sizeof(getopt_data));
|
||||
|
||||
argv = *argvp;
|
||||
if ((p = rindex(argv[0], 'h')) != NULL &&
|
||||
strcmp(p, "hd") == 0) {
|
||||
/* "Canonical" format, implies -C. */
|
||||
add(globals, "\"%08.8_Ax\n\"");
|
||||
add(globals, "\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" ");
|
||||
add(globals, "\" |\" 16/1 \"%_p\" \"|\\n\"");
|
||||
}
|
||||
while ((ch = getopt_r(argc, argv, "bcCde:f:n:os:vx", &getopt_reent)) != -1)
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
add(globals, "\"%07.7_Ax\n\"");
|
||||
add(globals, "\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"");
|
||||
break;
|
||||
case 'c':
|
||||
add(globals, "\"%07.7_Ax\n\"");
|
||||
add(globals, "\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"");
|
||||
break;
|
||||
case 'C':
|
||||
add(globals, "\"%08.8_Ax\n\"");
|
||||
add(globals, "\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" ");
|
||||
add(globals, "\" |\" 16/1 \"%_p\" \"|\\n\"");
|
||||
break;
|
||||
case 'd':
|
||||
add(globals, "\"%07.7_Ax\n\"");
|
||||
add(globals, "\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"");
|
||||
break;
|
||||
case 'e':
|
||||
add(globals, getopt_reent.optarg);
|
||||
break;
|
||||
case 'f':
|
||||
addfile(globals, getopt_reent.optarg);
|
||||
break;
|
||||
case 'n':
|
||||
if ((length = atoi(getopt_reent.optarg)) < 0)
|
||||
errx(exit_jump, 1, "%s: bad length value", getopt_reent.optarg);
|
||||
break;
|
||||
case 'o':
|
||||
add(globals, "\"%07.7_Ax\n\"");
|
||||
add(globals, "\"%07.7_ax \" 8/2 \" %06o \" \"\\n\"");
|
||||
break;
|
||||
case 's':
|
||||
if ((skip = strtoll(getopt_reent.optarg, &p, 0)) < 0)
|
||||
errx(exit_jump, 1, "%s: bad skip value", getopt_reent.optarg);
|
||||
switch(*p) {
|
||||
case 'b':
|
||||
skip *= 512;
|
||||
break;
|
||||
case 'k':
|
||||
skip *= 1024;
|
||||
break;
|
||||
case 'm':
|
||||
skip *= 1048576;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
vflag = ALL;
|
||||
break;
|
||||
case 'x':
|
||||
add(globals, "\"%07.7_Ax\n\"");
|
||||
add(globals, "\"%07.7_ax \" 8/2 \" %04x \" \"\\n\"");
|
||||
break;
|
||||
case '?':
|
||||
usage(globals);
|
||||
}
|
||||
|
||||
if (!fshead) {
|
||||
add(globals, "\"%07.7_Ax\n\"");
|
||||
add(globals, "\"%07.7_ax \" 8/2 \"%04x \" \"\\n\"");
|
||||
}
|
||||
|
||||
*argvp += getopt_reent.optind;
|
||||
}
|
||||
|
||||
void
|
||||
usage(rtems_shell_hexdump_globals* globals)
|
||||
{
|
||||
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
|
||||
"usage: hexdump [-bcCdovx] [-e fmt] [-f fmt_file] [-n length]",
|
||||
" [-s skip] [file ...]",
|
||||
" hd [-bcdovx] [-e fmt] [-f fmt_file] [-n length]",
|
||||
" [-s skip] [file ...]");
|
||||
exit(1);
|
||||
}
|
||||
561
cpukit/libmisc/shell/main_dd.c
Normal file
561
cpukit/libmisc/shell/main_dd.c
Normal file
@@ -0,0 +1,561 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char const copyright[] =
|
||||
"@(#) Copyright (c) 1991, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/bin/dd/dd.c,v 1.43 2004/08/15 19:10:05 rwatson Exp $");
|
||||
#endif
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/shell.h>
|
||||
#include <rtems/shellconfig.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/conf.h>
|
||||
#if RTEMS_REMOVED
|
||||
#include <sys/disklabel.h>
|
||||
#endif
|
||||
#include <sys/filio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dd.h"
|
||||
#include "extern-dd.h"
|
||||
|
||||
#define DEFFILEMODE 0
|
||||
|
||||
static void dd_close(rtems_shell_dd_globals* globals);
|
||||
static void dd_in(rtems_shell_dd_globals* globals);
|
||||
static void getfdtype(rtems_shell_dd_globals* globals, IO *);
|
||||
static void setup(rtems_shell_dd_globals* globals);
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
IO in, out; /* input/output state */
|
||||
STAT st; /* statistics */
|
||||
void (*cfunc)(void); /* conversion function */
|
||||
uintmax_t cpy_cnt; /* # of blocks to copy */
|
||||
static off_t pending = 0; /* pending seek if sparse */
|
||||
u_int ddflags = 0; /* conversion options */
|
||||
size_t cbsz; /* conversion block size */
|
||||
uintmax_t files_cnt = 1; /* # of files to copy */
|
||||
const u_char *ctab; /* conversion table */
|
||||
char fill_char; /* Character to fill with if defined */
|
||||
#endif
|
||||
|
||||
static off_t pending = 0; /* pending seek if sparse */
|
||||
|
||||
void
|
||||
rtems_shell_dd_exit (rtems_shell_dd_globals* globals, int code)
|
||||
{
|
||||
globals->exit_code = code;
|
||||
longjmp (globals->exit_jmp, 1);
|
||||
}
|
||||
|
||||
static int main_dd(rtems_shell_dd_globals* globals, int argc, char *argv[]);
|
||||
|
||||
int
|
||||
rtems_shell_main_dd(int argc, char *argv[])
|
||||
{
|
||||
rtems_shell_dd_globals dd_globals;
|
||||
rtems_shell_dd_globals* globals = &dd_globals;
|
||||
memset (globals, 0, sizeof (dd_globals));
|
||||
pending = 0;
|
||||
ddflags = 0;
|
||||
files_cnt = 1;
|
||||
dd_globals.exit_code = 1;
|
||||
if (setjmp (dd_globals.exit_jmp) == 0)
|
||||
dd_globals.exit_code = main_dd (globals, argc, argv);
|
||||
if (in.fd)
|
||||
close(in.fd);
|
||||
if (out.fd)
|
||||
close(out.fd);
|
||||
if (in.name)
|
||||
free((void*)in.name);
|
||||
if (out.name)
|
||||
free((void*)out.name);
|
||||
if (in.db)
|
||||
free(in.db);
|
||||
if (out.db && (in.db != out.db))
|
||||
free(out.db);
|
||||
return dd_globals.exit_code;
|
||||
}
|
||||
|
||||
int
|
||||
main_dd(rtems_shell_dd_globals* globals, int argc __unused, char *argv[])
|
||||
{
|
||||
(void)setlocale(LC_CTYPE, "");
|
||||
jcl(globals, argv);
|
||||
setup(globals);
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
(void)signal(SIGINFO, summaryx);
|
||||
(void)signal(SIGINT, terminate);
|
||||
|
||||
atexit(summary);
|
||||
#endif
|
||||
|
||||
while (files_cnt--)
|
||||
dd_in(globals);
|
||||
|
||||
dd_close(globals);
|
||||
exit(0);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parity(u_char c)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = c ^ (c >> 1) ^ (c >> 2) ^ (c >> 3) ^
|
||||
(c >> 4) ^ (c >> 5) ^ (c >> 6) ^ (c >> 7);
|
||||
return (i & 1);
|
||||
}
|
||||
|
||||
static void
|
||||
setup(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
u_int cnt;
|
||||
struct timeval tv;
|
||||
|
||||
if (in.name == NULL) {
|
||||
in.name = "stdin";
|
||||
in.fd = STDIN_FILENO;
|
||||
} else {
|
||||
in.fd = open(in.name, O_RDONLY, 0);
|
||||
if (in.fd == -1)
|
||||
err(exit_jump, 1, "%s", in.name);
|
||||
}
|
||||
|
||||
getfdtype(globals, &in);
|
||||
|
||||
if (files_cnt > 1 && !(in.flags & ISTAPE))
|
||||
errx(exit_jump, 1, "files is not supported for non-tape devices");
|
||||
|
||||
if (out.name == NULL) {
|
||||
/* No way to check for read access here. */
|
||||
out.fd = STDOUT_FILENO;
|
||||
out.name = "stdout";
|
||||
} else {
|
||||
#define OFLAGS \
|
||||
(O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
|
||||
out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE);
|
||||
/*
|
||||
* May not have read access, so try again with write only.
|
||||
* Without read we may have a problem if output also does
|
||||
* not support seeks.
|
||||
*/
|
||||
if (out.fd == -1) {
|
||||
out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE);
|
||||
out.flags |= NOREAD;
|
||||
}
|
||||
if (out.fd == -1)
|
||||
err(exit_jump, 1, "%s", out.name);
|
||||
}
|
||||
|
||||
getfdtype(globals, &out);
|
||||
|
||||
/*
|
||||
* Allocate space for the input and output buffers. If not doing
|
||||
* record oriented I/O, only need a single buffer.
|
||||
*/
|
||||
if (!(ddflags & (C_BLOCK | C_UNBLOCK))) {
|
||||
if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL)
|
||||
err(exit_jump, 1, "input buffer");
|
||||
out.db = in.db;
|
||||
} else if ((in.db = malloc(MAX(in.dbsz, cbsz) + cbsz)) == NULL ||
|
||||
(out.db = malloc(out.dbsz + cbsz)) == NULL)
|
||||
err(exit_jump, 1, "output buffer");
|
||||
in.dbp = in.db;
|
||||
out.dbp = out.db;
|
||||
|
||||
/* Position the input/output streams. */
|
||||
if (in.offset)
|
||||
pos_in(globals);
|
||||
if (out.offset)
|
||||
pos_out(globals);
|
||||
|
||||
/*
|
||||
* Truncate the output file. If it fails on a type of output file
|
||||
* that it should _not_ fail on, error out.
|
||||
*/
|
||||
if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK) &&
|
||||
out.flags & ISTRUNC)
|
||||
if (ftruncate(out.fd, out.offset * out.dbsz) == -1)
|
||||
err(exit_jump, 1, "truncating %s", out.name);
|
||||
|
||||
if (ddflags & (C_LCASE | C_UCASE | C_ASCII | C_EBCDIC | C_PARITY)) {
|
||||
if (ctab != NULL) {
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
casetab[cnt] = ctab[cnt];
|
||||
} else {
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
casetab[cnt] = cnt;
|
||||
}
|
||||
if ((ddflags & C_PARITY) && !(ddflags & C_ASCII)) {
|
||||
/*
|
||||
* If the input is not EBCDIC, and we do parity
|
||||
* processing, strip input parity.
|
||||
*/
|
||||
for (cnt = 200; cnt <= 0377; ++cnt)
|
||||
casetab[cnt] = casetab[cnt & 0x7f];
|
||||
}
|
||||
if (ddflags & C_LCASE) {
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
casetab[cnt] = tolower(casetab[cnt]);
|
||||
} else if (ddflags & C_UCASE) {
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
casetab[cnt] = toupper(casetab[cnt]);
|
||||
}
|
||||
if ((ddflags & C_PARITY)) {
|
||||
/*
|
||||
* This should strictly speaking be a no-op, but I
|
||||
* wonder what funny LANG settings could get us.
|
||||
*/
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
casetab[cnt] = casetab[cnt] & 0x7f;
|
||||
}
|
||||
if ((ddflags & C_PARSET)) {
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
casetab[cnt] = casetab[cnt] | 0x80;
|
||||
}
|
||||
if ((ddflags & C_PAREVEN)) {
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
if (parity(casetab[cnt]))
|
||||
casetab[cnt] = casetab[cnt] | 0x80;
|
||||
}
|
||||
if ((ddflags & C_PARODD)) {
|
||||
for (cnt = 0; cnt <= 0377; ++cnt)
|
||||
if (!parity(casetab[cnt]))
|
||||
casetab[cnt] = casetab[cnt] | 0x80;
|
||||
}
|
||||
|
||||
ctab = casetab;
|
||||
}
|
||||
|
||||
(void)gettimeofday(&tv, (struct timezone *)NULL);
|
||||
st.start = tv.tv_sec + tv.tv_usec * 1e-6;
|
||||
}
|
||||
|
||||
static void
|
||||
getfdtype(rtems_shell_dd_globals* globals, IO *io)
|
||||
{
|
||||
struct stat sb;
|
||||
#if RTEMS_REMOVED
|
||||
int type;
|
||||
#endif
|
||||
|
||||
if (fstat(io->fd, &sb) == -1)
|
||||
err(exit_jump, 1, "%s", io->name);
|
||||
if (S_ISREG(sb.st_mode))
|
||||
io->flags |= ISTRUNC;
|
||||
#if RTEMS_REMOVED
|
||||
if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) {
|
||||
if (ioctl(io->fd, FIODTYPE, &type) == -1) {
|
||||
err(exit_jump, 1, "%s", io->name);
|
||||
} else {
|
||||
if (type & D_TAPE)
|
||||
io->flags |= ISTAPE;
|
||||
else if (type & (D_DISK | D_MEM))
|
||||
io->flags |= ISSEEK;
|
||||
if (S_ISCHR(sb.st_mode) && (type & D_TAPE) == 0)
|
||||
io->flags |= ISCHR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#else
|
||||
io->flags |= ISSEEK;
|
||||
#endif
|
||||
errno = 0;
|
||||
if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
|
||||
io->flags |= ISPIPE;
|
||||
else
|
||||
io->flags |= ISSEEK;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_in(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
for (;;) {
|
||||
switch (cpy_cnt) {
|
||||
case -1: /* count=0 was specified */
|
||||
return;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
if (st.in_full + st.in_part >= (uintmax_t)cpy_cnt)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zero the buffer first if sync; if doing block operations,
|
||||
* use spaces.
|
||||
*/
|
||||
if (ddflags & C_SYNC) {
|
||||
if (ddflags & C_FILL)
|
||||
memset(in.dbp, fill_char, in.dbsz);
|
||||
else if (ddflags & (C_BLOCK | C_UNBLOCK))
|
||||
memset(in.dbp, ' ', in.dbsz);
|
||||
else
|
||||
memset(in.dbp, 0, in.dbsz);
|
||||
}
|
||||
|
||||
n = read(in.fd, in.dbp, in.dbsz);
|
||||
if (n == 0) {
|
||||
in.dbrcnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read error. */
|
||||
if (n == -1) {
|
||||
/*
|
||||
* If noerror not specified, die. POSIX requires that
|
||||
* the warning message be followed by an I/O display.
|
||||
*/
|
||||
if (!(ddflags & C_NOERROR))
|
||||
err(exit_jump, 1, "%s", in.name);
|
||||
warn("%s", in.name);
|
||||
summary(globals);
|
||||
|
||||
/*
|
||||
* If it's a seekable file descriptor, seek past the
|
||||
* error. If your OS doesn't do the right thing for
|
||||
* raw disks this section should be modified to re-read
|
||||
* in sector size chunks.
|
||||
*/
|
||||
if (in.flags & ISSEEK &&
|
||||
lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
|
||||
warn("%s", in.name);
|
||||
|
||||
/* If sync not specified, omit block and continue. */
|
||||
if (!(ddflags & C_SYNC))
|
||||
continue;
|
||||
|
||||
/* Read errors count as full blocks. */
|
||||
in.dbcnt += in.dbrcnt = in.dbsz;
|
||||
++st.in_full;
|
||||
|
||||
/* Handle full input blocks. */
|
||||
} else if ((size_t)n == in.dbsz) {
|
||||
in.dbcnt += in.dbrcnt = n;
|
||||
++st.in_full;
|
||||
|
||||
/* Handle partial input blocks. */
|
||||
} else {
|
||||
/* If sync, use the entire block. */
|
||||
if (ddflags & C_SYNC)
|
||||
in.dbcnt += in.dbrcnt = in.dbsz;
|
||||
else
|
||||
in.dbcnt += in.dbrcnt = n;
|
||||
++st.in_part;
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX states that if bs is set and no other conversions
|
||||
* than noerror, notrunc or sync are specified, the block
|
||||
* is output without buffering as it is read.
|
||||
*/
|
||||
if (ddflags & C_BS) {
|
||||
out.dbcnt = in.dbcnt;
|
||||
dd_out(globals, 1);
|
||||
in.dbcnt = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ddflags & C_SWAB) {
|
||||
if ((n = in.dbrcnt) & 1) {
|
||||
++st.swab;
|
||||
--n;
|
||||
}
|
||||
swab(in.dbp, in.dbp, (size_t)n);
|
||||
}
|
||||
|
||||
in.dbp += in.dbrcnt;
|
||||
(*cfunc)(globals);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up any remaining I/O and flush output. If necessary, the output file
|
||||
* is truncated.
|
||||
*/
|
||||
static void
|
||||
dd_close(rtems_shell_dd_globals* globals)
|
||||
{
|
||||
if (cfunc == def)
|
||||
def_close(globals);
|
||||
else if (cfunc == block)
|
||||
block_close(globals);
|
||||
else if (cfunc == unblock)
|
||||
unblock_close(globals);
|
||||
if (ddflags & C_OSYNC && out.dbcnt && out.dbcnt < out.dbsz) {
|
||||
if (ddflags & C_FILL)
|
||||
memset(out.dbp, fill_char, out.dbsz - out.dbcnt);
|
||||
else if (ddflags & (C_BLOCK | C_UNBLOCK))
|
||||
memset(out.dbp, ' ', out.dbsz - out.dbcnt);
|
||||
else
|
||||
memset(out.dbp, 0, out.dbsz - out.dbcnt);
|
||||
out.dbcnt = out.dbsz;
|
||||
}
|
||||
if (out.dbcnt || pending)
|
||||
dd_out(globals, 1);
|
||||
}
|
||||
|
||||
void
|
||||
dd_out(rtems_shell_dd_globals* globals, int force)
|
||||
{
|
||||
u_char *outp;
|
||||
size_t cnt, i, n;
|
||||
ssize_t nw;
|
||||
static int warned;
|
||||
int sparse;
|
||||
|
||||
/*
|
||||
* Write one or more blocks out. The common case is writing a full
|
||||
* output block in a single write; increment the full block stats.
|
||||
* Otherwise, we're into partial block writes. If a partial write,
|
||||
* and it's a character device, just warn. If a tape device, quit.
|
||||
*
|
||||
* The partial writes represent two cases. 1: Where the input block
|
||||
* was less than expected so the output block was less than expected.
|
||||
* 2: Where the input block was the right size but we were forced to
|
||||
* write the block in multiple chunks. The original versions of dd(1)
|
||||
* never wrote a block in more than a single write, so the latter case
|
||||
* never happened.
|
||||
*
|
||||
* One special case is if we're forced to do the write -- in that case
|
||||
* we play games with the buffer size, and it's usually a partial write.
|
||||
*/
|
||||
outp = out.db;
|
||||
for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
|
||||
for (cnt = n;; cnt -= nw) {
|
||||
sparse = 0;
|
||||
if (ddflags & C_SPARSE) {
|
||||
sparse = 1; /* Is buffer sparse? */
|
||||
for (i = 0; i < cnt; i++)
|
||||
if (outp[i] != 0) {
|
||||
sparse = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sparse && !force) {
|
||||
pending += cnt;
|
||||
nw = cnt;
|
||||
} else {
|
||||
if (pending != 0) {
|
||||
if (force)
|
||||
pending--;
|
||||
if (lseek(out.fd, pending, SEEK_CUR) ==
|
||||
-1)
|
||||
err(exit_jump, 2, "%s: seek error creating sparse file",
|
||||
out.name);
|
||||
if (force)
|
||||
write(out.fd, outp, 1);
|
||||
pending = 0;
|
||||
}
|
||||
if (cnt)
|
||||
nw = write(out.fd, outp, cnt);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (nw <= 0) {
|
||||
if (nw == 0)
|
||||
errx(exit_jump, 1, "%s: end of device", out.name);
|
||||
if (errno != EINTR)
|
||||
err(exit_jump, 1, "%s", out.name);
|
||||
nw = 0;
|
||||
}
|
||||
outp += nw;
|
||||
st.bytes += nw;
|
||||
if ((size_t)nw == n) {
|
||||
if (n != out.dbsz)
|
||||
++st.out_part;
|
||||
else
|
||||
++st.out_full;
|
||||
break;
|
||||
}
|
||||
++st.out_part;
|
||||
if ((size_t)nw == cnt)
|
||||
break;
|
||||
if (out.flags & ISTAPE)
|
||||
errx(exit_jump, 1, "%s: short write on tape device",
|
||||
out.name);
|
||||
if (out.flags & ISCHR && !warned) {
|
||||
warned = 1;
|
||||
warnx("%s: short write on character device",
|
||||
out.name);
|
||||
}
|
||||
}
|
||||
if ((out.dbcnt -= n) < out.dbsz)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reassemble the output block. */
|
||||
if (out.dbcnt)
|
||||
(void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt);
|
||||
out.dbp = out.db + out.dbcnt;
|
||||
}
|
||||
|
||||
rtems_shell_cmd_t rtems_shell_DD_Command = {
|
||||
"dd", /* name */
|
||||
"dd [OPERAND]...", /* usage */
|
||||
"files", /* topic */
|
||||
rtems_shell_main_dd, /* command */
|
||||
NULL, /* alias */
|
||||
NULL /* next */
|
||||
};
|
||||
161
cpukit/libmisc/shell/main_hexdump.c
Normal file
161
cpukit/libmisc/shell/main_hexdump.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1989, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)hexdump.c 8.1 (Berkeley) 6/6/93";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/usr.bin/hexdump/hexdump.c,v 1.7 2002/09/04 23:29:01 dwmalone Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/shell.h>
|
||||
#include <rtems/shellconfig.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "hexdump.h"
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
FS *fshead; /* head of format strings */
|
||||
int blocksize; /* data block size */
|
||||
int exitval; /* final exit value */
|
||||
int length = -1; /* max bytes to read */
|
||||
#endif
|
||||
|
||||
void
|
||||
rtems_shell_hexdump_exit (rtems_shell_hexdump_globals* globals, int code)
|
||||
{
|
||||
globals->exit_code = code;
|
||||
longjmp (globals->exit_jmp, 1);
|
||||
}
|
||||
|
||||
static int main_hexdump(rtems_shell_hexdump_globals* globals, int argc, char *argv[]);
|
||||
|
||||
int
|
||||
rtems_shell_main_hexdump(int argc, char *argv[])
|
||||
{
|
||||
rtems_shell_hexdump_globals hexdump_globals;
|
||||
rtems_shell_hexdump_globals* globals = &hexdump_globals;
|
||||
memset (globals, 0, sizeof (hexdump_globals));
|
||||
vflag = FIRST;
|
||||
ateof = 1;
|
||||
hexdump_globals.exit_code = 1;
|
||||
if (setjmp (hexdump_globals.exit_jmp) == 0)
|
||||
hexdump_globals.exit_code = main_hexdump (globals, argc, argv);
|
||||
if (curp)
|
||||
free (curp);
|
||||
if (savp)
|
||||
free (savp);
|
||||
while (fshead)
|
||||
{
|
||||
FS* nextfs = fshead->nextfs;
|
||||
while (fshead->nextfu)
|
||||
{
|
||||
FU* nextfu = fshead->nextfu->nextfu;
|
||||
if (fshead->nextfu->fmt)
|
||||
free(fshead->nextfu->fmt);
|
||||
while (fshead->nextfu->nextpr)
|
||||
{
|
||||
PR* nextpr = fshead->nextfu->nextpr->nextpr;
|
||||
if (((fshead->nextfu->nextpr->flags & F_TEXT) == 0) &&
|
||||
fshead->nextfu->nextpr->fmt)
|
||||
free(fshead->nextfu->nextpr->fmt);
|
||||
free(fshead->nextfu->nextpr);
|
||||
fshead->nextfu->nextpr = nextpr;
|
||||
}
|
||||
free(fshead->nextfu);
|
||||
fshead->nextfu = nextfu;
|
||||
}
|
||||
free(fshead);
|
||||
fshead = nextfs;
|
||||
}
|
||||
if (hdstdin)
|
||||
{
|
||||
fclose (hdstdin);
|
||||
free (hdstdin);
|
||||
}
|
||||
return hexdump_globals.exit_code;
|
||||
}
|
||||
|
||||
int
|
||||
main_hexdump(rtems_shell_hexdump_globals* globals, int argc, char *argv[])
|
||||
{
|
||||
FS *tfs;
|
||||
char *p;
|
||||
|
||||
#if RTEMS_REMOVED
|
||||
(void)setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
if (!(p = rindex(argv[0], 'o')) || strcmp(p, "od"))
|
||||
newsyntax(globals, argc, &argv);
|
||||
else
|
||||
oldsyntax(globals, argc, &argv);
|
||||
|
||||
/* figure out the data block size */
|
||||
for (blocksize = 0, tfs = fshead; tfs; tfs = tfs->nextfs) {
|
||||
tfs->bcnt = size(globals, tfs);
|
||||
if (blocksize < tfs->bcnt)
|
||||
blocksize = tfs->bcnt;
|
||||
}
|
||||
/* rewrite the rules, do syntax checking */
|
||||
for (tfs = fshead; tfs; tfs = tfs->nextfs)
|
||||
rewrite(globals, tfs);
|
||||
|
||||
(void)next(globals, argv);
|
||||
display(globals);
|
||||
exit(exitval);
|
||||
return exitval;
|
||||
}
|
||||
|
||||
rtems_shell_cmd_t rtems_shell_HEXDUMP_Command = {
|
||||
"hexdump", /* name */
|
||||
"hexdump [-bcCdovx] [-e fmt] [-f fmt_file] [-n length]\n" /* usage */
|
||||
" [-s skip] [file ...]",
|
||||
"files", /* topic */
|
||||
rtems_shell_main_hexdump, /* command */
|
||||
NULL, /* alias */
|
||||
NULL /* next */
|
||||
};
|
||||
|
||||
@@ -54,6 +54,8 @@ extern rtems_shell_cmd_t rtems_shell_MOUNT_Command;
|
||||
extern rtems_shell_cmd_t rtems_shell_UNMOUNT_Command;
|
||||
extern rtems_shell_cmd_t rtems_shell_BLKSYNC_Command;
|
||||
extern rtems_shell_cmd_t rtems_shell_FDISK_Command;
|
||||
extern rtems_shell_cmd_t rtems_shell_DD_Command;
|
||||
extern rtems_shell_cmd_t rtems_shell_HEXDUMP_Command;
|
||||
|
||||
extern rtems_shell_cmd_t rtems_shell_RTC_Command;
|
||||
|
||||
@@ -307,6 +309,16 @@ extern rtems_shell_filesystems_t *rtems_shell_Mount_filesystems[];
|
||||
defined(CONFIGURE_SHELL_COMMAND_FDISK)
|
||||
&rtems_shell_FDISK_Command,
|
||||
#endif
|
||||
#if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
|
||||
!defined(CONFIGURE_SHELL_NO_COMMAND_DD)) || \
|
||||
defined(CONFIGURE_SHELL_COMMAND_DD)
|
||||
&rtems_shell_DD_Command,
|
||||
#endif
|
||||
#if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
|
||||
!defined(CONFIGURE_SHELL_NO_COMMAND_HEXDUMP)) || \
|
||||
defined(CONFIGURE_SHELL_COMMAND_HEXDUMP)
|
||||
&rtems_shell_HEXDUMP_Command,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RTEMS Related commands
|
||||
|
||||
Reference in New Issue
Block a user