diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2016-05-03 17:23:00 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2016-05-03 17:23:00 +0000 |
commit | 20da50bd5b4b881d1640ced19b3385223de121e7 (patch) | |
tree | f5d5014cb170586b5dd318e9ae2efb185d58dc3c | |
parent | 8e843eeb5a054dd8fe14c0f4a18c45dbea695dde (diff) | |
download | sg3_utils-20da50bd5b4b881d1640ced19b3385223de121e7.tar.gz |
sg_lib: implement 'format' argument in dStrHexStr(); sg_vpd: 3 party copy VPD page improvements
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@699 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Makefile.in | 8 | ||||
-rwxr-xr-x | configure | 1 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | doc/Makefile.in | 4 | ||||
-rw-r--r-- | include/Makefile.in | 4 | ||||
-rw-r--r-- | include/sg_lib.h | 13 | ||||
-rw-r--r-- | lib/Makefile.in | 4 | ||||
-rw-r--r-- | lib/sg_lib.c | 129 | ||||
-rw-r--r-- | lib/sg_lib_data.c | 2 | ||||
-rw-r--r-- | scripts/Makefile.in | 4 | ||||
-rw-r--r-- | src/Makefile.in | 4 | ||||
-rw-r--r-- | src/sg_ses.c | 30 | ||||
-rw-r--r-- | src/sg_vpd.c | 46 | ||||
-rw-r--r-- | utils/tst_sg_lib.c | 10 |
15 files changed, 161 insertions, 106 deletions
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and some description at the top of its ".c" file. All utilities in the main directory have their own "man" pages. There is also a sg3_utils man page. -Changelog for sg3_utils-1.43 [20160429] [svn: r698] +Changelog for sg3_utils-1.43 [20160503] [svn: r699] - sg_senddiag: add --timeout=SEC option - sg_sanitize: add --timeout=SEC option - sg_format: add --timeout=SEC option @@ -21,6 +21,7 @@ Changelog for sg3_utils-1.43 [20160429] [svn: r698] page (spc5r09) - add --force option to bypass checking supported vpd pages page and fetch requested page directly + - sg_vpd: 3 party copy VPD page improvements - sg_reassign+sg_write_same: fix ULONG_MAX problem - sg_rdac: add sanity checks for -f=lun value - sg_turs+sg_requests: make both accept '--num=NUM' @@ -31,6 +32,7 @@ Changelog for sg3_utils-1.43 [20160429] [svn: r698] - sg_lib: add SSC maintenance in/out sa names - add read buffer(16) command mode names - add sg_decode_transportid_str() + - implement 'format' argument in dStrHexStr() - sg_lib_data: sync asc/ascq codes with T10 20160425 - rescan-scsi-bus.sh: harden code - clang --analyze static checker clean ups diff --git a/Makefile.in b/Makefile.in index b242c417..07ba3990 100644 --- a/Makefile.in +++ b/Makefile.in @@ -339,15 +339,15 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile + $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -2769,7 +2769,6 @@ END fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. diff --git a/configure.ac b/configure.ac index fdd311db..6c35d1af 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_INIT(sg3_utils, 1.43, dgilbert@interlog.com) -AM_INIT_AUTOMAKE -AM_MAINTAINER_MODE([-Wall -Werror foreign]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +AM_MAINTAINER_MODE AM_CONFIG_HEADER(config.h) AC_PROG_CC diff --git a/doc/Makefile.in b/doc/Makefile.in index 5d131988..f7dc9eaa 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -309,9 +309,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu doc/Makefile + $(AUTOMAKE) --foreign doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ diff --git a/include/Makefile.in b/include/Makefile.in index 9b45d1d9..08495eb2 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -340,9 +340,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu include/Makefile + $(AUTOMAKE) --foreign include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ diff --git a/include/sg_lib.h b/include/sg_lib.h index 71e73c5e..9a81f9e7 100644 --- a/include/sg_lib.h +++ b/include/sg_lib.h @@ -383,20 +383,21 @@ char * safe_strerror(int errnum); * = 0 in addition, the bytes are listed in ASCII to the right * < 0 only the ASCII-hex bytes are listed (i.e. without address) */ -void dStrHex(const char* str, int len, int no_ascii); +void dStrHex(const char * str, int len, int no_ascii); /* Print (to sg_warnings_strm (stderr)) 'str' of bytes in hex, 16 bytes per * line optionally followed at right by its ASCII interpretation. Same * logic as dStrHex() with different output stream (i.e. stderr). */ -void dStrHexErr(const char* str, int len, int no_ascii); +void dStrHexErr(const char * str, int len, int no_ascii); /* Read 'len' bytes from 'str' and output as ASCII-Hex bytes (space * separated) to 'b' not to exceed 'b_len' characters. Each line * starts with 'leadin' (NULL for no leadin) and there are 16 bytes * per line with an extra space between the 8th and 9th bytes. 'format' - * is unused, set to 0 . Returns number of bytes written to 'b' excluding - * the trailing '\0'.*/ -int dStrHexStr(const char* str, int len, const char * leadin, int format, + * is 0 for repeat in printable ASCII ('.' for non printable chars) to + * right of each line; 1 don't (so just output ASCII hex). Returns + * number of bytes written to 'b' excluding the trailing '\0'. */ +int dStrHexStr(const char * str, int len, const char * leadin, int format, int b_len, char * b); /* Returns 1 when executed on big endian machine; else returns 0. @@ -425,7 +426,7 @@ int sg_ata_get_chars(const unsigned short * word_arr, int start_word, * If 'swapb' non-zero then bytes in each word swapped. Needs to be set * for ATA IDENTIFY DEVICE response on big-endian machines. */ -void dWordHex(const unsigned short* words, int num, int no_ascii, int swapb); +void dWordHex(const unsigned short * words, int num, int no_ascii, int swapb); /* If the number in 'buf' can not be decoded or the multiplier is unknown * then -1 is returned. Accepts a hex prefix (0x or 0X) or a 'h' (or 'H') diff --git a/lib/Makefile.in b/lib/Makefile.in index 26c2cddc..fa695ceb 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -373,9 +373,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu lib/Makefile + $(AUTOMAKE) --foreign lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ diff --git a/lib/sg_lib.c b/lib/sg_lib.c index 675b99e0..f2565576 100644 --- a/lib/sg_lib.c +++ b/lib/sg_lib.c @@ -98,6 +98,13 @@ scnpr(char * cp, int cp_max_len, const char * fmt, ...) return (n < cp_max_len) ? n : (cp_max_len - 1); } +/* Simple ASCII printable (does not use locale), includes space and excludes + * DEL (0x7f). */ +static inline int my_isprint(int ch) +{ + return ((ch >= ' ') && (ch < 0x7f)); +} + /* Searches 'arr' for match on 'value' then 'peri_type'. If matches 'value' but not 'peri_type' then yields first 'value' match entry. Last element of 'arr' has NULL 'name'. If no match returns NULL. */ @@ -508,7 +515,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, if (0 != tpid_format) n += scnpr(b + n, blen - n, "%s [Unexpected TPID format: " "%d]\n", lip, tpid_format); - n += dStrHexStr((const char *)bp +8, 8, lip, -1, blen - n, + n += dStrHexStr((const char *)bp +8, 8, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -528,7 +535,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, "defined):\n", lip); n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip, tpid_format); - n += dStrHexStr((const char *)bp, normal_len, lip, 0, blen - n, + n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -537,7 +544,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, if (0 != tpid_format) n += scnpr(b + n, blen - n, "%s [Unexpected TPID format: " "%d]\n", lip, tpid_format); - n += dStrHexStr((const char *)&bp[8], 8, lip, -1, blen - n, + n += dStrHexStr((const char *)&bp[8], 8, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -547,7 +554,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, if (0 != tpid_format) n += scnpr(b + n, blen - n, "%s [Unexpected TPID format: " "%d]\n", lip, tpid_format); - n += dStrHexStr((const char *)&bp[8], 16, lip, -1, blen - n, + n += dStrHexStr((const char *)&bp[8], 16, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -581,7 +588,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, n += scnpr(b + n, blen - n, "%s ADT:\n", lip); n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip, tpid_format); - n += dStrHexStr((const char *)bp, normal_len, lip, 0, blen - n, + n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -589,7 +596,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, n += scnpr(b + n, blen - n, "%s ATAPI:\n", lip); n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip, tpid_format); - n += dStrHexStr((const char *)bp, normal_len, lip, 0, blen - n, + n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -597,7 +604,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, n += scnpr(b + n, blen - n, "%s UAS:\n", lip); n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip, tpid_format); - n += dStrHexStr((const char *)bp, normal_len, lip, 0, blen - n, + n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -609,7 +616,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, else { n += scnpr(b + n, blen - n, " [Unexpected TPID format: " "%d]\n", tpid_format); - n += dStrHexStr((const char *)bp, normal_len, lip, 0, + n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n, b + n); } bump = TRANSPORT_ID_MIN_LEN; @@ -618,7 +625,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, n += scnpr(b + n, blen - n, "%s PCIE:\n", lip); n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip, tpid_format); - n += dStrHexStr((const char *)bp, normal_len, lip, 0, blen - n, + n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -631,7 +638,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen, default: n += scnpr(b + n, blen - n, "%s unknown protocol id=0x%x " "TPID format=%d\n", lip, proto_id, tpid_format); - n += dStrHexStr((const char *)bp, normal_len, lip, 0, blen - n, + n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n, b + n); bump = TRANSPORT_ID_MIN_LEN; break; @@ -756,7 +763,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, case 0: /* vendor specific */ k = 0; if ((1 == c_set) || (2 == c_set)) { /* ASCII or UTF-8 */ - for (k = 0; (k < dlen) && isprint(ip[k]); ++k) + for (k = 0; (k < dlen) && my_isprint(ip[k]); ++k) ; if (k >= dlen) k = 1; @@ -789,7 +796,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, if ((8 != dlen) && (12 != dlen) && (16 != dlen)) { n += scnpr(b + n, blen - n, "%s << expect 8, 12 and 16 " "byte EUI, got %d >>\n", lip, dlen); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } @@ -804,7 +811,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, if (1 != c_set) { n += scnpr(b + n, blen - n, "%s << expected binary code_set " "(1) >>\n", lip); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } ci_off = 0; @@ -816,7 +823,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, } else if ((8 != dlen) && (12 != dlen)) { n += scnpr(b + n, blen - n, "%s << can only decode 8, 12 " "and 16 byte ids >>\n", lip); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } c_id = sg_get_unaligned_be24(ip + ci_off); @@ -840,7 +847,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, if (1 != c_set) { n += scnpr(b + n, blen - n, "%s << unexpected code set %d " "for NAA >>\n", lip, c_set); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } naa = (ip[0] >> 4) & 0xff; @@ -849,7 +856,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, if (8 != dlen) { n += scnpr(b + n, blen - n, "%s << unexpected NAA 2 " "identifier length: 0x%x >>\n", lip, dlen); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } @@ -877,7 +884,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, if (8 != dlen) { n += scnpr(b + n, blen - n, "%s << unexpected NAA 3 " "identifier length: 0x%x >>\n", lip, dlen); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } @@ -893,7 +900,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, if (8 != dlen) { n += scnpr(b + n, blen - n, "%s << unexpected NAA 5 " "identifier length: 0x%x >>\n", lip, dlen); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } @@ -924,7 +931,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, if (16 != dlen) { n += scnpr(b + n, blen - n, "%s << unexpected NAA 6 " "identifier length: 0x%x >>\n", lip, dlen); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } @@ -958,7 +965,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, default: n += scnpr(b + n, blen - n, "%s << unexpected NAA [0x%x] " ">>\n", lip, naa); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } break; @@ -967,7 +974,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, n += scnpr(b + n, blen - n, "%s << expected binary " "code_set, target port association, length 4 >>\n", lip); - n += dStrHexStr((const char *)ip, dlen, "", 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, "", 1, blen - n, b + n); break; } d_id = sg_get_unaligned_be16(ip + 2); @@ -979,7 +986,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, n += scnpr(b + n, blen - n, "%s << expected binary " "code_set, target port association, length 4 >>\n", lip); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } d_id = sg_get_unaligned_be16(ip + 2); @@ -991,7 +998,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, n += scnpr(b + n, blen - n, "%s << expected binary " "code_set, logical unit association, length 4 >>\n", lip); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } d_id = sg_get_unaligned_be16(ip + 2); @@ -1002,12 +1009,12 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, if ((1 != c_set) || (0 != assoc)) { n += scnpr(b + n, blen - n, "%s << expected binary " "code_set, logical unit association >>\n", lip); - n += dStrHexStr((const char *)ip, dlen, "", 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, "", 1, blen - n, b + n); break; } n += scnpr(b + n, blen - n, "%s MD5 logical unit identifier:\n", lip); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; case 8: /* SCSI name string */ if (3 != c_set) { /* accept ASCII as subset of UTF-8 */ @@ -1088,7 +1095,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp, default: /* reserved */ n += scnpr(b + n, blen - n, "%s reserved designator=0x%x\n", lip, desig_type); - n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n); + n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n); break; } return n; @@ -1765,8 +1772,8 @@ sg_get_sense_str(const char * lip, const unsigned char * sbp, int sb_len, if (n >= (buff_len - 1)) return n; scnpr(z, sizeof(z), "%.50s ", lip); - n += dStrHexStr((const char *)sbp, len, z, 0, - buff_len - n, buff + n); + n += dStrHexStr((const char *)sbp, len, z, 1, buff_len - n, + buff + n); } return n; } @@ -2332,7 +2339,7 @@ dStrHexFp(const char* str, int len, int no_ascii, FILE * fp) if (no_ascii) buff[cpos++] = ' '; else { - if ((c < ' ') || (c >= 0x7f)) + if (! my_isprint(c)) c = '.'; buff[cpos++] = c; } @@ -2369,56 +2376,74 @@ dStrHexErr(const char* str, int len, int no_ascii) (sg_warnings_strm ? sg_warnings_strm : stderr)); } +#define DSHS_LINE_BLEN 160 +#define DSHS_BPL 16 + /* Read 'len' bytes from 'str' and output as ASCII-Hex bytes (space * separated) to 'b' not to exceed 'b_len' characters. Each line * starts with 'leadin' (NULL for no leadin) and there are 16 bytes * per line with an extra space between the 8th and 9th bytes. 'format' - * is unused (currently), set to 0 . Returns number of bytes written - * to 'b' excluding the trailing '\0'. */ + * is 0 for repeat in printable ASCII ('.' for non printable) to + * right of each line; 1 don't (so just output ASCII hex). Returns + * number of bytes written to 'b' excluding the trailing '\0'. */ int -dStrHexStr(const char* str, int len, const char * leadin, int format, +dStrHexStr(const char * str, int len, const char * leadin, int format, int b_len, char * b) { - const char * p = str; unsigned char c; - char buff[122]; - int bpstart, bpos, k, n; + int bpstart, bpos, k, n, prior_ascii_len; + bool want_ascii; + char buff[DSHS_LINE_BLEN + 2]; + char a[DSHS_BPL + 1]; + const char * p = str; if (len <= 0) { if (b_len > 0) b[0] = '\0'; return 0; } - if (0 != format) { - ; /* do nothing different for now */ + if (b_len <= 0) + return 0; + want_ascii = !format; + if (want_ascii) { + memset(a, ' ', DSHS_BPL); + a[DSHS_BPL] = '\0'; } if (leadin) { bpstart = strlen(leadin); - /* Cap leadin at 60 characters */ - if (bpstart > 60) - bpstart = 60; + /* Cap leadin at (DSHS_LINE_BLEN - 70) characters */ + if (bpstart > (DSHS_LINE_BLEN - 70)) + bpstart = DSHS_LINE_BLEN - 70; } else bpstart = 0; bpos = bpstart; + prior_ascii_len = bpstart + (DSHS_BPL * 3) + 1; n = 0; - memset(buff, ' ', 120); - buff[120] = '\0'; + memset(buff, ' ', DSHS_LINE_BLEN); + buff[DSHS_LINE_BLEN] = '\0'; if (bpstart > 0) memcpy(buff, leadin, bpstart); for (k = 0; k < len; k++) { c = *p++; - if (bpos == (bpstart + (8 * 3))) - bpos++; + if (bpos == (bpstart + ((DSHS_BPL / 2) * 3))) + bpos++; /* for extra space in middle of each line's hex */ scnpr(buff + bpos, (int)sizeof(buff) - bpos, "%.2x", (int)(unsigned char)c); buff[bpos + 2] = ' '; - if ((k > 0) && (0 == ((k + 1) % 16))) { + if (want_ascii) + a[k % DSHS_BPL] = my_isprint(c) ? c : '.'; + if ((k > 0) && (0 == ((k + 1) % DSHS_BPL))) { trimTrailingSpaces(buff); - n += scnpr(b + n, b_len - n, "%s\n", buff); + if (want_ascii) { + n += scnpr(b + n, b_len - n, "%-*s %s\n", prior_ascii_len, + buff, a); + memset(a, ' ', DSHS_BPL); + } else + n += scnpr(b + n, b_len - n, "%s\n", buff); if (n >= (b_len - 1)) return n; + memset(buff, ' ', DSHS_LINE_BLEN); bpos = bpstart; - memset(buff, ' ', 120); if (bpstart > 0) memcpy(buff, leadin, bpstart); } else @@ -2426,7 +2451,11 @@ dStrHexStr(const char* str, int len, const char * leadin, int format, } if (bpos > bpstart) { trimTrailingSpaces(buff); - n += scnpr(b + n, b_len - n, "%s\n", buff); + if (want_ascii) + n += scnpr(b + n, b_len - n, "%-*s %s\n", prior_ascii_len, + buff, a); + else + n += scnpr(b + n, b_len - n, "%s\n", buff); } return n; } @@ -2529,10 +2558,10 @@ dWordHex(const unsigned short* words, int num, int no_ascii, int swapb) } else { upp = (c >> 8) & 0xff; low = c & 0xff; - if ((upp < 0x20) || (upp >= 0x7f)) + if (! my_isprint(upp)) upp = '.'; buff[cpos++] = upp; - if ((low < 0x20) || (low >= 0x7f)) + if (! my_isprint(low)) low = '.'; buff[cpos++] = low; buff[cpos++] = ' '; diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c index 5c7c7355..5c468629 100644 --- a/lib/sg_lib_data.c +++ b/lib/sg_lib_data.c @@ -17,7 +17,7 @@ #endif -const char * sg_lib_version_str = "2.22 20160428"; /* spc5r09, sbc4r10 */ +const char * sg_lib_version_str = "2.23 20160503"; /* spc5r09, sbc4r10 */ /* indexed by pdt; those that map to own index do not decay */ diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 58108179..e0ad947a 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -284,9 +284,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign scripts/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu scripts/Makefile + $(AUTOMAKE) --foreign scripts/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ diff --git a/src/Makefile.in b/src/Makefile.in index 7cde80ce..8907375e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -645,9 +645,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/Makefile + $(AUTOMAKE) --foreign src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ diff --git a/src/sg_ses.c b/src/sg_ses.c index f4c81986..41c63d0a 100644 --- a/src/sg_ses.c +++ b/src/sg_ses.c @@ -31,7 +31,7 @@ * commands tailored for SES (enclosure) devices. */ -static const char * version_str = "2.12 20160413"; /* ses3r13 */ +static const char * version_str = "2.13 20160502"; /* ses3r13 */ #define MX_ALLOC_LEN ((64 * 1024) - 4) /* max allowable for big enclosures */ #define MX_ELEM_HDR 1024 @@ -1725,15 +1725,12 @@ configuration_sdg(const uint8_t * resp, int resp_len) printf("\n enclosure vendor: %.8s product: %.16s rev: %.4s\n", bp + 12, bp + 20, bp + 36); if (el > 40) { + char bb[1024]; + printf(" vendor-specific data:\n"); - /* dStrHex((const char *)(bp + 40), el - 40, 0); */ - printf(" "); - for (j = 0; j < (el - 40); ++j) { - if ((j > 0) && (0 == (j % 16))) - printf("\n "); - printf("%02x ", *(bp + 40 + j)); - } - printf("\n"); + dStrHexStr((const char *)(bp + 40), el - 40, " ", 0, + sizeof(bb), bb); + printf("%s\n", bb); } } /* printf("\n"); */ @@ -3216,7 +3213,7 @@ truncated: static void subenc_string_sdg(const uint8_t * resp, int resp_len) { - int k, j, el, num_subs; + int k, el, num_subs; uint32_t gen_code; const uint8_t * bp; const uint8_t * last_bp; @@ -3236,14 +3233,11 @@ subenc_string_sdg(const uint8_t * resp, int resp_len) el = sg_get_unaligned_be16(bp + 2) + 4; printf(" subenclosure identifier: %d\n", bp[1]); if (el > 4) { - /* dStrHex((const char *)(bp + 4), el - 4, 0); */ - printf(" "); - for (j = 0; j < (el - 4); ++j) { - if ((j > 0) && (0 == (j % 16))) - printf("\n "); - printf("%02x ", *(bp + 4 + j)); - } - printf("\n"); + char bb[1024]; + + dStrHexStr((const char *)(bp + 40), el - 40, " ", 0, + sizeof(bb), bb); + printf("%s\n", bb); } else printf(" <empty>\n"); } diff --git a/src/sg_vpd.c b/src/sg_vpd.c index d735d224..57b74458 100644 --- a/src/sg_vpd.c +++ b/src/sg_vpd.c @@ -37,7 +37,7 @@ */ -static const char * version_str = "1.20 20160428"; /* spc5r09 + sbc4r10 */ +static const char * version_str = "1.21 20160503"; /* spc5r09 + sbc4r10 */ /* These structures are duplicates of those of the same name in @@ -2046,7 +2046,8 @@ get_cscd_desc_id_name(uint16_t cscd_desc_id) /* VPD_3PARTY_COPY [3PC, third party copy] */ static void -decode_3party_copy_vpd(unsigned char * buff, int len, int do_hex, int verbose) +decode_3party_copy_vpd(unsigned char * buff, int len, int do_hex, int pdt, + int verbose) { int j, k, m, bump, desc_type, desc_len, sa_len; unsigned int u; @@ -2084,6 +2085,8 @@ decode_3party_copy_vpd(unsigned char * buff, int len, int do_hex, int verbose) else if (do_hex > 2) dStrHex((const char *)bp, bump, 1); else { + int csll; + switch (desc_type) { case 0x0000: /* Required if POPULATE TOKEN (or friend) used */ printf(" Block Device ROD Token Limits:\n"); @@ -2101,14 +2104,27 @@ decode_3party_copy_vpd(unsigned char * buff, int len, int do_hex, int verbose) case 0x0001: /* Mandatory (SPC-4) */ printf(" Supported Commands:\n"); j = 0; - while (j < bp[4]) { + csll = bp[4]; + if (csll >= desc_len) { + pr2serr("Command supported list length (%d) >= " + "descriptor length (%d), wrong so trim\n", + csll, desc_len); + csll = desc_len - 1; + } + while (j < csll) { sa_len = bp[6 + j]; - for (m = 0; m < sa_len; ++m) { + for (m = 0; (m < sa_len) && ((j + m) < csll); ++m) { sg_get_opcode_sa_name(bp[5 + j], bp[7 + j + m], - 0, sizeof(b), b); + pdt, sizeof(b), b); printf(" %s\n", b); } - j += sa_len + 2; + if (0 == sa_len) { + sg_get_opcode_name(bp[5 + j], pdt, sizeof(b), b); + printf(" %s\n", b); + } else if (m < sa_len) + pr2serr("Supported service actions list length (%d) " + "is too large\n", sa_len); + j += m + 2; } break; case 0x0004: @@ -2483,16 +2499,28 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt) } } +static const char * prov_type_arr[8] = { + "not known or fully provisioned", + "resource provisioned", + "thin provisioned", + "reserved [0x3]", + "reserved [0x4]", + "reserved [0x5]", + "reserved [0x6]", + "reserved [0x7]", +}; + /* VPD_LB_PROVISIONING 0xb2 */ static int decode_block_lb_prov_vpd(unsigned char * b, int len, const struct opts_t * op) { - int dp; + int dp, pt; if (len < 4) { pr2serr("Logical block provisioning page too short=%d\n", len); return SG_LIB_CAT_MALFORMED; } + pt = b[6] & 0x7; printf(" Unmap command supported (LBPU): %d\n", !!(0x80 & b[5])); printf(" Write same (16) with unmap bit supported (LBWS): %d\n", !!(0x40 & b[5])); @@ -2505,7 +2533,7 @@ decode_block_lb_prov_vpd(unsigned char * b, int len, const struct opts_t * op) printf(" Threshold exponent: %d\n", b[4]); printf(" Descriptor present (DP): %d\n", dp); printf(" Minimum percentage: %d\n", 0x1f & (b[6] >> 3)); - printf(" Provisioning type: %d\n", b[6] & 0x7); + printf(" Provisioning type: %d (%s)\n", pt, prov_type_arr[pt]); printf(" Threshold percentage: %d\n", b[7]); if (dp) { const unsigned char * bp; @@ -3251,7 +3279,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off) printf(" [PQual=%d Peripheral device type: %s]\n", (rp[0] & 0xe0) >> 5, sg_get_pdt_str(pdt, sizeof(b), b)); - decode_3party_copy_vpd(rp, len, op->do_hex, vb); + decode_3party_copy_vpd(rp, len, op->do_hex, pdt, vb); } return 0; } diff --git a/utils/tst_sg_lib.c b/utils/tst_sg_lib.c index 569f1765..13be7ff8 100644 --- a/utils/tst_sg_lib.c +++ b/utils/tst_sg_lib.c @@ -25,7 +25,7 @@ * */ -static char * version_str = "1.03 20160128"; +static char * version_str = "1.04 20160503"; #define MAX_LINE_LEN 1024 @@ -188,7 +188,7 @@ main(int argc, char * argv[]) int verbose = 0; int ret = 0; char b[2048]; - char bb[128]; + char bb[256]; while (1) { int option_index = 0; @@ -369,10 +369,12 @@ main(int argc, char * argv[]) for (k = 0; k < 18; ++k) { printf("k=%d:\n", k); dStrHex(b, k, 0); + dStrHexStr(b, k, "dSHS_0: ", 0, sizeof(bb), bb); + printf("%s", bb); dStrHex(b, k, 1); - dStrHex(b, k, -1); - dStrHexStr(b, k, "dStrHexStr:^", 0, sizeof(bb), bb); + dStrHexStr(b, k, "dSHS_1: ", 1, sizeof(bb), bb); printf("%s", bb); + dStrHex(b, k, -1); printf("\n"); } } |