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:
rocky
2004-05-26 00:52:53 +00:00
parent 484637b207
commit 95546002d5

View File

@@ -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);