Add --hexdump and --no-hexdump options. We now can hexdump to a file and
dump bytes stdout (which may be useful in a pipe).
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: cd-read.c,v 1.17 2004/05/04 02:06:48 rocky Exp $
|
$Id: cd-read.c,v 1.18 2004/05/26 00:52:53 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||||
|
|
||||||
@@ -92,6 +92,11 @@ struct arguments
|
|||||||
char *access_mode; /* Access method driver should use for control */
|
char *access_mode; /* Access method driver should use for control */
|
||||||
char *output_file; /* file to output blocks if not NULL. */
|
char *output_file; /* file to output blocks if not NULL. */
|
||||||
int debug_level;
|
int debug_level;
|
||||||
|
int hexdump; /* Show output as a hexdump */
|
||||||
|
int nohexdump; /* Don't output as a hexdump. I don't know
|
||||||
|
how to get popt to combine these as
|
||||||
|
one variable.
|
||||||
|
*/
|
||||||
read_mode_t read_mode;
|
read_mode_t read_mode;
|
||||||
int version_only;
|
int version_only;
|
||||||
int no_header;
|
int no_header;
|
||||||
@@ -103,26 +108,27 @@ struct arguments
|
|||||||
} opts;
|
} opts;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hexdump (uint8_t * buffer, unsigned int len)
|
hexdump (FILE *stream, uint8_t * buffer, unsigned int len)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < len; i++, buffer++)
|
for (i = 0; i < len; i++, buffer++)
|
||||||
{
|
{
|
||||||
if (i % 16 == 0)
|
if (i % 16 == 0)
|
||||||
printf ("0x%04x: ", i);
|
fprintf (stream, "0x%04x: ", i);
|
||||||
printf ("%02x", *buffer);
|
fprintf (stream, "%02x", *buffer);
|
||||||
if (i % 2 == 1)
|
if (i % 2 == 1)
|
||||||
printf (" ");
|
fprintf (stream, " ");
|
||||||
if (i % 16 == 15) {
|
if (i % 16 == 15) {
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
printf (" ");
|
fprintf (stream, " ");
|
||||||
for (p=buffer-15; p <= buffer; p++) {
|
for (p=buffer-15; p <= buffer; p++) {
|
||||||
printf("%c", isprint(*p) ? *p : '.');
|
fprintf(stream, "%c", isprint(*p) ? *p : '.');
|
||||||
}
|
}
|
||||||
printf ("\n");
|
fprintf (stream, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf ("\n");
|
fprintf (stream, "\n");
|
||||||
|
fflush (stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Comparison function called by bearch() to find sub-option record. */
|
/* Comparison function called by bearch() to find sub-option record. */
|
||||||
@@ -191,6 +197,13 @@ parse_options (int argc, const char *argv[])
|
|||||||
POPT_ARG_INT, &opts.debug_level, 0,
|
POPT_ARG_INT, &opts.debug_level, 0,
|
||||||
"Set debugging to LEVEL"},
|
"Set debugging to LEVEL"},
|
||||||
|
|
||||||
|
{"hexdump", 'x', POPT_ARG_NONE, &opts.hexdump, 0,
|
||||||
|
"Show output as a hex dump. The default is a hex dump when "
|
||||||
|
"output goes to stdout and no hex dump when output is to a file."},
|
||||||
|
|
||||||
|
{"no-hexdump", '\0', POPT_ARG_NONE, &opts.nohexdump, 0,
|
||||||
|
"Don't show output as a hex dump."},
|
||||||
|
|
||||||
{"start", 's',
|
{"start", 's',
|
||||||
POPT_ARG_INT, &opts.start_lsn, 0,
|
POPT_ARG_INT, &opts.start_lsn, 0,
|
||||||
"Set LBA to start reading from"},
|
"Set LBA to start reading from"},
|
||||||
@@ -224,7 +237,7 @@ parse_options (int argc, const char *argv[])
|
|||||||
OP_SOURCE_CDRDAO, "set \"TOC\" CD-ROM disk image file as source", "FILE"},
|
OP_SOURCE_CDRDAO, "set \"TOC\" CD-ROM disk image file as source", "FILE"},
|
||||||
|
|
||||||
{"output-file", 'o', POPT_ARG_STRING, &opts.output_file, 0,
|
{"output-file", 'o', POPT_ARG_STRING, &opts.output_file, 0,
|
||||||
"Output blocks to file rather than give a hexdump."},
|
"Output blocks to file rather than give a hexdump.", "FILE"},
|
||||||
|
|
||||||
{"version", 'V', POPT_ARG_NONE, NULL, OP_VERSION,
|
{"version", 'V', POPT_ARG_NONE, NULL, OP_VERSION,
|
||||||
"display version and copyright information and exit"},
|
"display version and copyright information and exit"},
|
||||||
@@ -339,6 +352,15 @@ parse_options (int argc, const char *argv[])
|
|||||||
|
|
||||||
/* Check consistency between start_lsn, end_lsn and num_sectors. */
|
/* Check consistency between start_lsn, end_lsn and num_sectors. */
|
||||||
|
|
||||||
|
if (opts.nohexdump && opts.hexdump != 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: don't give both --hexdump and --no-hexdump together\n",
|
||||||
|
program_name);
|
||||||
|
exit(13);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.nohexdump) opts.hexdump = 0;
|
||||||
|
|
||||||
if (opts.start_lsn == CDIO_INVALID_LSN) {
|
if (opts.start_lsn == CDIO_INVALID_LSN) {
|
||||||
/* Maybe we derive the start from the end and num sectors. */
|
/* Maybe we derive the start from the end and num sectors. */
|
||||||
if (opts.end_lsn == CDIO_INVALID_LSN) {
|
if (opts.end_lsn == CDIO_INVALID_LSN) {
|
||||||
@@ -418,6 +440,7 @@ init(void)
|
|||||||
opts.num_sectors = 0;
|
opts.num_sectors = 0;
|
||||||
opts.read_mode = READ_MODE_UNINIT;
|
opts.read_mode = READ_MODE_UNINIT;
|
||||||
opts.source_image = IMAGE_UNKNOWN;
|
opts.source_image = IMAGE_UNKNOWN;
|
||||||
|
opts.hexdump = 2; /* Not set. */
|
||||||
|
|
||||||
gl_default_cdio_log_handler = cdio_log_set_handler (log_handler);
|
gl_default_cdio_log_handler = cdio_log_set_handler (log_handler);
|
||||||
}
|
}
|
||||||
@@ -429,6 +452,7 @@ main(int argc, const char *argv[])
|
|||||||
unsigned int blocklen=CDIO_CD_FRAMESIZE_RAW;
|
unsigned int blocklen=CDIO_CD_FRAMESIZE_RAW;
|
||||||
CdIo *cdio=NULL;
|
CdIo *cdio=NULL;
|
||||||
int output_fd=-1;
|
int output_fd=-1;
|
||||||
|
FILE *output_stream;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
@@ -491,13 +515,23 @@ main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opts.output_file!=NULL) {
|
if (opts.output_file!=NULL) {
|
||||||
|
|
||||||
|
/* If hexdump not explicitly set, then don't produce hexdump
|
||||||
|
when writing to a file.
|
||||||
|
*/
|
||||||
|
if (opts.hexdump == 2) opts.hexdump = 0;
|
||||||
|
|
||||||
output_fd = open(opts.output_file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
output_fd = open(opts.output_file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
||||||
if (-1 == output_fd) {
|
if (-1 == output_fd) {
|
||||||
err_exit("Error opening output file %s: %s\n",
|
err_exit("Error opening output file %s: %s\n",
|
||||||
opts.output_file, strerror(errno));
|
opts.output_file, strerror(errno));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
/* If we are writing to stdout, then the default is to produce
|
||||||
|
a hexdump.
|
||||||
|
*/
|
||||||
|
if (opts.hexdump == 2) opts.hexdump = 1;
|
||||||
|
|
||||||
|
|
||||||
for ( ; opts.start_lsn <= opts.end_lsn; opts.start_lsn++ ) {
|
for ( ; opts.start_lsn <= opts.end_lsn; opts.start_lsn++ ) {
|
||||||
@@ -555,11 +589,21 @@ main(int argc, const char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.output_file) {
|
if (!opts.output_file) {
|
||||||
write(output_fd, buffer, blocklen);
|
output_stream = stdout;
|
||||||
} else {
|
} else {
|
||||||
hexdump(buffer, blocklen);
|
output_stream = fdopen(output_fd, "w");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.hexdump)
|
||||||
|
hexdump(output_stream, buffer, blocklen);
|
||||||
|
else if (opts.output_file)
|
||||||
|
write(output_fd, buffer, blocklen);
|
||||||
|
else {
|
||||||
|
unsigned int i;
|
||||||
|
for (i=0; i<blocklen; i++) printf("%c", buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.output_file) close(output_fd);
|
if (opts.output_file) close(output_fd);
|
||||||
|
|||||||
Reference in New Issue
Block a user