aboutsummaryrefslogtreecommitdiff
path: root/src/sg_decode_sense.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sg_decode_sense.c')
-rw-r--r--src/sg_decode_sense.c111
1 files changed, 69 insertions, 42 deletions
diff --git a/src/sg_decode_sense.c b/src/sg_decode_sense.c
index a21ceb47..76e5f6f9 100644
--- a/src/sg_decode_sense.c
+++ b/src/sg_decode_sense.c
@@ -30,9 +30,9 @@
#include "sg_unaligned.h"
-static const char * version_str = "1.24 20211104";
+static const char * version_str = "1.25 20211119";
-#define MAX_SENSE_LEN 1024 /* max descriptor format actually: 255+8 */
+#define MAX_SENSE_LEN 4096 /* max descriptor format actually: 255+8 */
static struct option long_options[] = {
{"binary", required_argument, 0, 'b'},
@@ -45,6 +45,7 @@ static struct option long_options[] = {
{"hex", no_argument, 0, 'H'},
{"in", required_argument, 0, 'i'}, /* don't advertise */
{"inhex", required_argument, 0, 'i'}, /* same as --file */
+ {"nodecode", no_argument, 0, 'N'},
{"nospace", no_argument, 0, 'n'},
{"status", required_argument, 0, 's'},
{"verbose", no_argument, 0, 'v'},
@@ -57,7 +58,7 @@ struct opts_t {
bool do_binary;
bool do_cdb;
bool do_help;
- bool do_hex;
+ bool no_decode;
bool no_space;
bool do_status;
bool verbose_given;
@@ -66,6 +67,7 @@ struct opts_t {
bool file_given;
const char * fname;
int es_val;
+ int hex_count;
int sense_len;
int sstatus;
int verbose;
@@ -82,10 +84,11 @@ usage()
{
pr2serr("Usage: sg_decode_sense [--binary=BFN] [--cdb] [--err=ES] "
"[--file=HFN]\n"
- " [--help] [--hex] [--inhex=HFN] [--nospace] "
- "[--status=SS]\n"
- " [--verbose] [--version] [--write=WFN] H1 "
- "H2 H3 ...\n"
+ " [--help] [--hex] [--inhex=HFN] "
+ "[--nodecode]\n"
+ " [--nospace] [--status=SS] [--verbose] "
+ "[--version]\n"
+ " [--write=WFN] H1 H2 H3 ...\n"
" where:\n"
" --binary=BFN|-b BFN BFN is a file name to read sense "
"data in\n"
@@ -105,6 +108,8 @@ usage()
" C language style ASCII hex (instead "
"of binary)\n"
" --inhex=HFN|-i HFN same as action as --file=HFN\n"
+ " --nodecode|-N do not decode, may be neither sense "
+ "nor cdb\n"
" --nospace|-n no spaces or other separators between "
"pairs of\n"
" hex digits (e.g. '3132330A')\n"
@@ -133,7 +138,8 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[])
char *endptr;
while (1) {
- c = getopt_long(argc, argv, "b:ce:f:hHi:ns:vVw:", long_options, NULL);
+ c = getopt_long(argc, argv, "b:ce:f:hHi:nNs:vVw:", long_options,
+ NULL);
if (c == -1)
break;
@@ -182,11 +188,14 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[])
op->fname = optarg;
break;
case 'H':
- op->do_hex = true;
+ op->hex_count++;
break;
case 'n':
op->no_space = true;
break;
+ case 'N':
+ op->no_decode = true;
+ break;
case 's':
if (1 != sscanf(optarg, "%x", &ui)) {
pr2serr("'--status=SS' expects a byte value\n");
@@ -257,6 +266,7 @@ the_end:
return 0;
}
+/* Keep this format (e.g. 0xff,0x12,...) for backward compatibility */
static void
write2wfn(FILE * fp, struct opts_t * op)
{
@@ -264,30 +274,23 @@ write2wfn(FILE * fp, struct opts_t * op)
size_t s;
char b[128];
- if (op->do_hex) {
- for (k = 0, n = 0; k < op->sense_len; ++k) {
- n += sprintf(b + n, "0x%02x,", op->sense[k]);
- if (15 == (k % 16)) {
- b[n] = '\n';
- s = fwrite(b, 1, n + 1, fp);
- if ((int)s != (n + 1))
- pr2serr("only able to write %d of %d bytes to %s\n",
- (int)s, n + 1, op->wfname);
- n = 0;
- }
- }
- if (n > 0) {
+ for (k = 0, n = 0; k < op->sense_len; ++k) {
+ n += sprintf(b + n, "0x%02x,", op->sense[k]);
+ if (15 == (k % 16)) {
b[n] = '\n';
s = fwrite(b, 1, n + 1, fp);
if ((int)s != (n + 1))
- pr2serr("only able to write %d of %d bytes to %s\n", (int)s,
- n + 1, op->wfname);
+ pr2serr("only able to write %d of %d bytes to %s\n",
+ (int)s, n + 1, op->wfname);
+ n = 0;
}
- } else {
- s = fwrite(op->sense, 1, op->sense_len, fp);
- if ((int)s != op->sense_len)
+ }
+ if (n > 0) {
+ b[n] = '\n';
+ s = fwrite(b, 1, n + 1, fp);
+ if ((int)s != (n + 1))
pr2serr("only able to write %d of %d bytes to %s\n", (int)s,
- op->sense_len, op->wfname);
+ n + 1, op->wfname);
}
}
@@ -374,7 +377,8 @@ main(int argc, char *argv[])
if ((0 == op->sense_len) && (! op->do_binary) && (! op->file_given)) {
if (op->do_status)
return 0;
- pr2serr(">> Need sense data on the command line or in a file\n\n");
+ pr2serr(">> Need sense/cdb/arbitrary data on the command line or "
+ "in a file\n\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
@@ -413,19 +417,40 @@ main(int argc, char *argv[])
}
}
- if (op->sense_len) {
- if (op->wfname) {
- if ((fp = fopen(op->wfname, "w"))) {
+ if (op->sense_len > 0) {
+ if (op->wfname || op->hex_count) {
+ if (op->wfname) {
+ if (NULL == ((fp = fopen(op->wfname, "w")))) {
+ err =errno;
+ perror("open");
+ pr2serr("trying to write to %s\n", op->wfname);
+ ret = sg_convert_errno(err);
+ goto fini;
+ }
+ } else
+ fp = stdout;
+
+ if (op->wfname && (1 == op->hex_count))
write2wfn(fp, op);
- fclose(fp);
- } else {
- err =errno;
- perror("open");
- pr2serr("trying to write to %s\n", op->wfname);
- ret = sg_convert_errno(err);
+ else if (op->hex_count && (2 != op->hex_count))
+ dStrHexFp((const char *)op->sense, op->sense_len,
+ ((1 == op->hex_count) ? 1 : -1), fp);
+ else if (op->hex_count)
+ dStrHexFp((const char *)op->sense, op->sense_len, 0, fp);
+ else {
+ size_t s = fwrite(op->sense, 1, op->sense_len, fp);
+
+ if ((int)s != op->sense_len)
+ pr2serr("only able to write %d of %d bytes to %s\n",
+ (int)s, op->sense_len, op->wfname);
}
- }
- if (op->do_cdb) {
+ if (op->wfname)
+ fclose(fp);
+ } else if (op->no_decode) {
+ if (op->verbose > 1)
+ pr2serr("Not decoding as %s because --nodecode given\n",
+ (op->do_cdb ? "cdb" : "sense"));
+ } else if (op->do_cdb) {
int sa, opcode;
opcode = op->sense[0];
@@ -436,10 +461,12 @@ main(int argc, char *argv[])
else
sa = 0;
sg_get_opcode_sa_name(opcode, sa, 0, blen, b);
- } else
+ printf("%s\n", b);
+ } else {
sg_get_sense_str(NULL, op->sense, op->sense_len,
op->verbose, blen, b);
- printf("%s\n", b);
+ printf("%s\n", b);
+ }
}
fini:
return ret;