diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2019-05-18 15:37:19 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2019-05-18 15:37:19 +0000 |
commit | 3e030c2951bee369b5593243bf317bb5a482a35b (patch) | |
tree | 0fc4dff2af1d3ff6f635877879b2c8ec8e6eb1f1 /src | |
parent | c80acc95be9d1463830259db821ac248e7dc7e46 (diff) | |
download | sg3_utils-3e030c2951bee369b5593243bf317bb5a482a35b.tar.gz |
sg_lib: add sg_f2hex_arr()
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@824 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r-- | src/sg_decode_sense.c | 156 | ||||
-rw-r--r-- | src/sg_inq.c | 190 | ||||
-rw-r--r-- | src/sg_logs.c | 193 | ||||
-rw-r--r-- | src/sg_raw.c | 201 | ||||
-rw-r--r-- | src/sg_read_attr.c | 188 | ||||
-rw-r--r-- | src/sg_read_buffer.c | 205 | ||||
-rw-r--r-- | src/sg_vpd.c | 207 |
7 files changed, 23 insertions, 1317 deletions
diff --git a/src/sg_decode_sense.c b/src/sg_decode_sense.c index 8dd682db..e4727593 100644 --- a/src/sg_decode_sense.c +++ b/src/sg_decode_sense.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2018 Douglas Gilbert. + * Copyright (c) 2010-2019 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. @@ -30,7 +30,7 @@ #include "sg_unaligned.h" -static const char * version_str = "1.19 20180714"; +static const char * version_str = "1.20 20190516"; #define MAX_SENSE_LEN 1024 /* max descriptor format actually: 255+8 */ @@ -244,154 +244,6 @@ the_end: return 0; } -/* Read ASCII hex bytes from fname (a file named '-' taken as stdin). - * There should be either one entry per line or a comma, space or tab - * separated list of bytes. If no_space is set then a string of ACSII hex - * digits is expected, 2 per byte. Everything from and including a '#' - * on a line is ignored. Returns 0 if ok, sg3_utils code value. */ -static int -f2hex_arr(const char * fname, bool no_space, uint8_t * mp_arr, - int * mp_arr_len, int max_arr_len) -{ - bool split_line; - int fn_len, in_len, k, j, m, err; - int off = 0; - unsigned int h; - const char * lcp; - FILE * fp; - char line[512]; - char carry_over[4]; - - if ((NULL == fname) || (NULL == mp_arr) || (NULL == mp_arr_len)) - return SG_LIB_LOGIC_ERROR; - fn_len = strlen(fname); - if (0 == fn_len) - return SG_LIB_SYNTAX_ERROR; - if ((1 == fn_len) && ('-' == fname[0])) /* read from stdin */ - fp = stdin; - else { - fp = fopen(fname, "r"); - if (NULL == fp) { - err = errno; - pr2serr("Unable to open %s for reading: %s\n", fname, - safe_strerror(err)); - return sg_convert_errno(err); - } - } - - carry_over[0] = 0; - for (j = 0; j < 512; ++j) { - if (NULL == fgets(line, sizeof(line), fp)) - break; - in_len = strlen(line); - if (in_len > 0) { - if ('\n' == line[in_len - 1]) { - --in_len; - line[in_len] = '\0'; - split_line = false; - } else - split_line = true; - } - if (in_len < 1) { - carry_over[0] = 0; - continue; - } - if (carry_over[0]) { - if (isxdigit(line[0])) { - carry_over[1] = line[0]; - carry_over[2] = '\0'; - if (1 == sscanf(carry_over, "%x", &h)) - mp_arr[off - 1] = h; /* back up and overwrite */ - else { - pr2serr("%s: carry_over error ['%s'] around line %d\n", - __func__, carry_over, j + 1); - goto bad; - } - lcp = line + 1; - --in_len; - } else - lcp = line; - carry_over[0] = 0; - } else - lcp = line; - - m = strspn(lcp, " \t"); - if (m == in_len) - continue; - lcp += m; - in_len -= m; - if ('#' == *lcp) - continue; - k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t"); - if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) { - pr2serr("%s: syntax error at line %d, pos %d\n", __func__, j + 1, - m + k + 1); - goto bad; - } - if (no_space) { - for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1)); - ++k, lcp += 2) { - if (1 != sscanf(lcp, "%2x", &h)) { - pr2serr("%s: bad hex number in line %d, pos %d\n", - __func__, j + 1, (int)(lcp - line + 1)); - goto bad; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - } - if (isxdigit(*lcp) && (! isxdigit(*(lcp + 1)))) - carry_over[0] = *lcp; - off += k; - } else { - for (k = 0; k < 1024; ++k) { - if (1 == sscanf(lcp, "%x", &h)) { - if (h > 0xff) { - pr2serr("%s: hex number larger than 0xff in line %d, " - "pos %d\n", __func__, j + 1, - (int)(lcp - line + 1)); - goto bad; - } - if (split_line && (1 == strlen(lcp))) { - /* single trailing hex digit might be a split pair */ - carry_over[0] = *lcp; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - lcp = strpbrk(lcp, " ,\t"); - if (NULL == lcp) - break; - lcp += strspn(lcp, " ,\t"); - if ('\0' == *lcp) - break; - } else { - if (('#' == *lcp) || ('\r' == *lcp)) { - --k; - break; - } - pr2serr("%s: error in line %d, at pos %d\n", __func__, - j + 1, (int)(lcp - line + 1)); - goto bad; - } - } - off += (k + 1); - } - } - *mp_arr_len = off; - if (stdin != fp) - fclose(fp); - return 0; -bad: - if (stdin != fp) - fclose(fp); - return SG_LIB_SYNTAX_ERROR; -} - static void write2wfn(FILE * fp, struct opts_t * op) { @@ -538,8 +390,8 @@ main(int argc, char *argv[]) } op->sense_len = s; } else if (op->file_given) { - ret = f2hex_arr(op->fname, op->no_space, op->sense, &op->sense_len, - MAX_SENSE_LEN); + ret = sg_f2hex_arr(op->fname, false, op->no_space, op->sense, + &op->sense_len, MAX_SENSE_LEN); if (ret) { pr2serr("unable to decode ASCII hex from file: %s\n", op->fname); return ret; diff --git a/src/sg_inq.c b/src/sg_inq.c index d3534cb8..2319c9ed 100644 --- a/src/sg_inq.c +++ b/src/sg_inq.c @@ -51,7 +51,7 @@ #include "sg_pt_nvme.h" #endif -static const char * version_str = "2.00 20190313"; /* SPC-5 rev 21 */ +static const char * version_str = "2.01 20190520"; /* SPC-5 rev 22 */ /* INQUIRY notes: * It is recommended that the initial allocation length given to a @@ -820,190 +820,6 @@ parse_cmd_line(struct opts_t * op, int argc, char * argv[]) #endif /* SG_SCSI_STRINGS */ -/* Read ASCII hex bytes or binary from fname (a file named '-' taken as - * stdin). If reading ASCII hex then there should be either one entry per - * line or a comma, space or tab separated list of bytes. If no_space is - * set then a string of ACSII hex digits is expected, 2 per byte. Everything - * from and including a '#' on a line is ignored. Returns 0 if ok, or a - * negated errno or SG_LIB_SYNTAX_ERROR or SG_LIB_FILE_ERROR . */ -static int -f2hex_arr(const char * fname, int as_binary, int no_space, - uint8_t * mp_arr, int * mp_arr_len, int max_arr_len) -{ - bool has_stdin; - bool split_line; - int fn_len, in_len, k, j, m, fd, err; - int off = 0; - unsigned int h; - const char * lcp; - FILE * fp; - char line[512]; - char carry_over[4]; - - if ((NULL == fname) || (NULL == mp_arr) || (NULL == mp_arr_len)) - return SG_LIB_LOGIC_ERROR; - fn_len = strlen(fname); - if (0 == fn_len) - return SG_LIB_SYNTAX_ERROR; - has_stdin = ((1 == fn_len) && ('-' == fname[0])); /* read from stdin */ - if (as_binary) { - if (has_stdin) { - fd = STDIN_FILENO; - if (sg_set_binary_mode(STDIN_FILENO) < 0) - perror("sg_set_binary_mode"); - } else { - fd = open(fname, O_RDONLY); - if (fd < 0) { - err = errno; - pr2serr("unable to open binary file %s: %s\n", fname, - safe_strerror(err)); - return -err; - } else if (sg_set_binary_mode(fd) < 0) - perror("sg_set_binary_mode"); - } - k = read(fd, mp_arr, max_arr_len); - if (k <= 0) { - if (0 == k) - pr2serr("read 0 bytes from binary file %s\n", fname); - else - pr2serr("read from binary file %s: %s\n", fname, - safe_strerror(errno)); - if (! has_stdin) - close(fd); - return SG_LIB_SYNTAX_ERROR; - } - *mp_arr_len = k; - if (! has_stdin) - close(fd); - return 0; - } else { /* So read the file as ASCII hex */ - if (has_stdin) - fp = stdin; - else { - fp = fopen(fname, "r"); - if (NULL == fp) { - err = errno; - pr2serr("Unable to open %s for reading\n", fname); - return -err; - } - } - } - - carry_over[0] = 0; - for (j = 0; j < 512; ++j) { - if (NULL == fgets(line, sizeof(line), fp)) - break; - in_len = strlen(line); - if (in_len > 0) { - if ('\n' == line[in_len - 1]) { - --in_len; - line[in_len] = '\0'; - split_line = false; - } else - split_line = true; - } - if (in_len < 1) { - carry_over[0] = 0; - continue; - } - if (carry_over[0]) { - if (isxdigit(line[0])) { - carry_over[1] = line[0]; - carry_over[2] = '\0'; - if (1 == sscanf(carry_over, "%x", &h)) - mp_arr[off - 1] = h; /* back up and overwrite */ - else { - pr2serr("%s: carry_over error ['%s'] around line %d\n", - __func__, carry_over, j + 1); - goto bad; - } - lcp = line + 1; - --in_len; - } else - lcp = line; - carry_over[0] = 0; - } else - lcp = line; - - m = strspn(lcp, " \t"); - if (m == in_len) - continue; - lcp += m; - in_len -= m; - if ('#' == *lcp) - continue; - k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t"); - if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) { - pr2serr("%s: syntax error at line %d, pos %d\n", __func__, - j + 1, m + k + 1); - goto bad; - } - if (no_space) { - for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1)); - ++k, lcp += 2) { - if (1 != sscanf(lcp, "%2x", &h)) { - pr2serr("%s: bad hex number in line %d, pos %d\n", - __func__, j + 1, (int)(lcp - line + 1)); - goto bad; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - } - if (isxdigit(*lcp) && (! isxdigit(*(lcp + 1)))) - carry_over[0] = *lcp; - off += k; - } else { - for (k = 0; k < 1024; ++k) { - if (1 == sscanf(lcp, "%x", &h)) { - if (h > 0xff) { - pr2serr("%s: hex number larger than 0xff in line %d, " - "pos %d\n", __func__, j + 1, - (int)(lcp - line + 1)); - goto bad; - } - if (split_line && (1 == strlen(lcp))) { - /* single trailing hex digit might be a split pair */ - carry_over[0] = *lcp; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - lcp = strpbrk(lcp, " ,\t"); - if (NULL == lcp) - break; - lcp += strspn(lcp, " ,\t"); - if ('\0' == *lcp) - break; - } else { - if (('#' == *lcp) || ('\r' == *lcp)) { - --k; - break; - } - pr2serr("%s: error in line %d, at pos %d\n", __func__, - j + 1, (int)(lcp - line + 1)); - goto bad; - } - } - off += (k + 1); - } - } - *mp_arr_len = off; - err = ferror(fp) ? SG_LIB_FILE_ERROR : 0; - if (stdin != fp) - fclose(fp); - return err; -bad: - err = SG_LIB_SYNTAX_ERROR; - if (stdin != fp) - fclose(fp); - return err; -} - static const struct svpd_values_name_t * sdp_find_vpd_by_acron(const char * ap) { @@ -4363,8 +4179,8 @@ main(int argc, char * argv[]) ret = SG_LIB_CONTRADICT; goto err_out; } - err = f2hex_arr(op->inhex_fn, op->do_raw, 0, rsp_buff, &inhex_len, - rsp_buff_sz); + err = sg_f2hex_arr(op->inhex_fn, !!op->do_raw, false, rsp_buff, + &inhex_len, rsp_buff_sz); if (err) { if (err < 0) err = sg_convert_errno(-err); diff --git a/src/sg_logs.c b/src/sg_logs.c index a869f0c9..c60b50a1 100644 --- a/src/sg_logs.c +++ b/src/sg_logs.c @@ -36,7 +36,7 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "1.74 20190502"; /* spc5r21 + sbc4r17 */ +static const char * version_str = "1.75 20190516"; /* spc5r22 + sbc4r17 */ #define MX_ALLOC_LEN (0xfffc) #define SHORT_RESP_LEN 128 @@ -1356,189 +1356,6 @@ num_or_unknown(const uint8_t * xp, int num_bytes /* max is 8 */, bool in_hex, return b; } -/* Read ASCII hex bytes or binary from fname (a file named '-' taken as - * stdin). If reading ASCII hex then there should be either one entry per - * line or a comma, space or tab separated list of bytes. If no_space is - * set then a string of ACSII hex digits is expected, 2 per byte. Everything - * from and including a '#' on a line is ignored. Returns 0 if ok, error - * code. */ -static int -f2hex_arr(const char * fname, bool as_binary, bool no_space, - uint8_t * mp_arr, int * mp_arr_len, int max_arr_len) -{ - bool split_line, has_stdin; - int fn_len, in_len, k, j, m, fd, err; - int off = 0; - unsigned int h; - const char * lcp; - FILE * fp; - char line[512]; - char carry_over[4]; - - if ((NULL == fname) || (NULL == mp_arr) || (NULL == mp_arr_len)) - return SG_LIB_LOGIC_ERROR; - fn_len = strlen(fname); - if (0 == fn_len) - return SG_LIB_SYNTAX_ERROR; - has_stdin = ((1 == fn_len) && ('-' == fname[0])); /* read from stdin */ - if (as_binary) { - if (has_stdin) { - fd = STDIN_FILENO; - if (sg_set_binary_mode(STDIN_FILENO) < 0) - perror("sg_set_binary_mode"); - } else { - fd = open(fname, O_RDONLY); - if (fd < 0) { - err = errno; - pr2serr("unable to open binary file %s: %s\n", fname, - safe_strerror(err)); - return sg_convert_errno(err); - } else if (sg_set_binary_mode(fd) < 0) - perror("sg_set_binary_mode"); - } - k = read(fd, mp_arr, max_arr_len); - if (k <= 0) { - if (0 == k) - pr2serr("read 0 bytes from binary file %s\n", fname); - else - pr2serr("read from binary file %s: %s\n", fname, - safe_strerror(errno)); - if (! has_stdin) - close(fd); - return SG_LIB_SYNTAX_ERROR; - } - *mp_arr_len = k; - if (! has_stdin) - close(fd); - return 0; - } else { /* So read the file as ASCII hex */ - if (has_stdin) - fp = stdin; - else { - fp = fopen(fname, "r"); - if (NULL == fp) { - err = errno; - pr2serr("Unable to open %s for reading: %s\n", fname, - safe_strerror(err)); - return sg_convert_errno(err); - } - } - } - - carry_over[0] = 0; - for (j = 0; j < 512; ++j) { - if (NULL == fgets(line, sizeof(line), fp)) - break; - in_len = strlen(line); - if (in_len > 0) { - if ('\n' == line[in_len - 1]) { - --in_len; - line[in_len] = '\0'; - split_line = false; - } else - split_line = true; - } - if (in_len < 1) { - carry_over[0] = 0; - continue; - } - if (carry_over[0]) { - if (isxdigit(line[0])) { - carry_over[1] = line[0]; - carry_over[2] = '\0'; - if (1 == sscanf(carry_over, "%4x", &h)) - mp_arr[off - 1] = h; /* back up and overwrite */ - else { - pr2serr("%s: carry_over error ['%s'] around line %d\n", - __func__, carry_over, j + 1); - goto bad; - } - lcp = line + 1; - --in_len; - } else - lcp = line; - carry_over[0] = 0; - } else - lcp = line; - - m = strspn(lcp, " \t"); - if (m == in_len) - continue; - lcp += m; - in_len -= m; - if ('#' == *lcp) - continue; - k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t"); - if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) { - pr2serr("%s: syntax error at line %d, pos %d\n", __func__, - j + 1, m + k + 1); - goto bad; - } - if (no_space) { - for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1)); - ++k, lcp += 2) { - if (1 != sscanf(lcp, "%2x", &h)) { - pr2serr("%s: bad hex number in line %d, pos %d\n", - __func__, j + 1, (int)(lcp - line + 1)); - goto bad; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - } - if (isxdigit(*lcp) && (! isxdigit(*(lcp + 1)))) - carry_over[0] = *lcp; - off += k; - } else { - for (k = 0; k < 1024; ++k) { - if (1 == sscanf(lcp, "%4x", &h)) { - if (h > 0xff) { - pr2serr("%s: hex number larger than 0xff in line %d, " - "pos %d\n", __func__, j + 1, - (int)(lcp - line + 1)); - goto bad; - } - if (split_line && (1 == strlen(lcp))) { - /* single trailing hex digit might be a split pair */ - carry_over[0] = *lcp; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - lcp = strpbrk(lcp, " ,\t"); - if (NULL == lcp) - break; - lcp += strspn(lcp, " ,\t"); - if ('\0' == *lcp) - break; - } else { - if (('#' == *lcp) || ('\r' == *lcp)) { - --k; - break; - } - pr2serr("%s: error in line %d, at pos %d\n", __func__, - j + 1, (int)(lcp - line + 1)); - goto bad; - } - } - off += (k + 1); - } - } - *mp_arr_len = off; - if (stdin != fp) - fclose(fp); - return 0; -bad: - if (stdin != fp) - fclose(fp); - return SG_LIB_SYNTAX_ERROR; -} - - /* Call LOG SENSE twice: the first time ask for 4 byte response to determine actual length of response; then a second time requesting the min(actual_len, mx_resp_len) bytes. If the calculated length for the @@ -6982,8 +6799,8 @@ main(int argc, char * argv[]) int pg_code, subpg_code, pdt, n; uint16_t u; - if ((ret = f2hex_arr(op->in_fn, op->do_raw, false, rsp_buff, - &in_len, rsp_buff_sz))) + if ((ret = sg_f2hex_arr(op->in_fn, op->do_raw, false, rsp_buff, + &in_len, rsp_buff_sz))) goto err_out; if (vb > 2) pr2serr("Read %d [0x%x] bytes of user supplied data\n", @@ -7079,8 +6896,8 @@ main(int argc, char * argv[]) ret = SG_LIB_CONTRADICT; goto err_out; } - if ((ret = f2hex_arr(op->in_fn, op->do_raw, false, rsp_buff, &in_len, - rsp_buff_sz))) + if ((ret = sg_f2hex_arr(op->in_fn, op->do_raw, false, rsp_buff, + &in_len, rsp_buff_sz))) goto err_out; if (vb > 2) pr2serr("Read %d [0x%x] bytes of user supplied data\n", in_len, diff --git a/src/sg_raw.c b/src/sg_raw.c index 00a58e0f..f9deaa9f 100644 --- a/src/sg_raw.c +++ b/src/sg_raw.c @@ -39,7 +39,7 @@ #include "sg_pr2serr.h" #include "sg_unaligned.h" -#define SG_RAW_VERSION "0.4.29 (2019-01-24)" +#define SG_RAW_VERSION "0.4.30 (2019-05-16)" #define DEFAULT_TIMEOUT 20 #define MIN_SCSI_CDBSZ 6 @@ -152,199 +152,6 @@ usage() " sg_raw -r 1k /dev/sg0 12 00 00 00 60 00\n"); } -/* Read ASCII hex bytes or binary from fname (a file named '-' taken as - * stdin). If reading ASCII hex then there should be either one entry per - * line or a comma, space or tab separated list of bytes. If no_space is - * true then a string of ACSII hex digits is expected, 2 per byte. Everything - * from and including a '#' on a line is ignored. Returns true if ok, or - * false if error. */ -static bool -f2hex_arr(const char * fname, bool as_binary, bool no_space, - uint8_t * mp_arr, int * mp_arr_len, int max_arr_len) -{ - int fn_len, in_len, k, j, m, fd; - bool has_stdin, split_line; - unsigned int h; - const char * lcp; - FILE * fp; - char line[512]; - char carry_over[4]; - int off = 0; - struct stat a_stat; - - if ((NULL == fname) || (NULL == mp_arr) || (NULL == mp_arr_len)) - return false; - fn_len = strlen(fname); - if (0 == fn_len) - return false; - has_stdin = ((1 == fn_len) && ('-' == fname[0])); /* read from stdin */ - if (as_binary) { - if (has_stdin) - fd = STDIN_FILENO; - else { - fd = open(fname, O_RDONLY); - if (fd < 0) { - pr2serr("unable to open binary file %s: %s\n", fname, - safe_strerror(errno)); - return false; - } - } - k = read(fd, mp_arr, max_arr_len); - if (k <= 0) { - if (0 == k) - pr2serr("read 0 bytes from binary file %s\n", fname); - else - pr2serr("read from binary file %s: %s\n", fname, - safe_strerror(errno)); - if (! has_stdin) - close(fd); - return false; - } - if ((0 == fstat(fd, &a_stat)) && S_ISFIFO(a_stat.st_mode)) { - /* pipe; keep reading till error or 0 read */ - while (k < max_arr_len) { - m = read(fd, mp_arr + k, max_arr_len - k); - if (0 == m) - break; - if (m < 0) { - pr2serr("read from binary pipe %s: %s\n", fname, - safe_strerror(errno)); - if (! has_stdin) - close(fd); - return false; - } - k += m; - } - } - *mp_arr_len = k; - if (! has_stdin) - close(fd); - return true; - } else { /* So read the file as ASCII hex */ - if (has_stdin) - fp = stdin; - else { - fp = fopen(fname, "r"); - if (NULL == fp) { - pr2serr("Unable to open %s for reading\n", fname); - return false; - } - } - } - - carry_over[0] = 0; - for (j = 0; j < 512; ++j) { - if (NULL == fgets(line, sizeof(line), fp)) - break; - in_len = strlen(line); - if (in_len > 0) { - if ('\n' == line[in_len - 1]) { - --in_len; - line[in_len] = '\0'; - split_line = false; - } else - split_line = true; - } - if (in_len < 1) { - carry_over[0] = 0; - continue; - } - if (carry_over[0]) { - if (isxdigit(line[0])) { - carry_over[1] = line[0]; - carry_over[2] = '\0'; - if (1 == sscanf(carry_over, "%4x", &h)) - mp_arr[off - 1] = h; /* back up and overwrite */ - else { - pr2serr("%s: carry_over error ['%s'] around line %d\n", - __func__, carry_over, j + 1); - goto bad; - } - lcp = line + 1; - --in_len; - } else - lcp = line; - carry_over[0] = 0; - } else - lcp = line; - - m = strspn(lcp, " \t"); - if (m == in_len) - continue; - lcp += m; - in_len -= m; - if ('#' == *lcp) - continue; - k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t"); - if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) { - pr2serr("%s: syntax error at line %d, pos %d\n", __func__, - j + 1, m + k + 1); - goto bad; - } - if (no_space) { - for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1)); - ++k, lcp += 2) { - if (1 != sscanf(lcp, "%2x", &h)) { - pr2serr("%s: bad hex number in line %d, pos %d\n", - __func__, j + 1, (int)(lcp - line + 1)); - goto bad; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - } - if (isxdigit(*lcp) && (! isxdigit(*(lcp + 1)))) - carry_over[0] = *lcp; - off += k; - } else { - for (k = 0; k < 1024; ++k) { - if (1 == sscanf(lcp, "%10x", &h)) { - if (h > 0xff) { - pr2serr("%s: hex number larger than 0xff in line " - "%d, pos %d\n", __func__, j + 1, - (int)(lcp - line + 1)); - goto bad; - } - if (split_line && (1 == strlen(lcp))) { - /* single trailing hex digit might be a split pair */ - carry_over[0] = *lcp; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - lcp = strpbrk(lcp, " ,\t"); - if (NULL == lcp) - break; - lcp += strspn(lcp, " ,\t"); - if ('\0' == *lcp) - break; - } else { - if (('#' == *lcp) || ('\r' == *lcp)) { - --k; - break; - } - pr2serr("%s: error in line %d, at pos %d\n", __func__, - j + 1, (int)(lcp - line + 1)); - goto bad; - } - } - off += (k + 1); - } - } - *mp_arr_len = off; - if (stdin != fp) - fclose(fp); - return true; -bad: - if (stdin != fp) - fclose(fp); - return false; -} - static int parse_cmd_line(struct opts_t * op, int argc, char *argv[]) { @@ -467,9 +274,9 @@ parse_cmd_line(struct opts_t * op, int argc, char *argv[]) if (op->cmdfile_given) { bool ok; - ok = f2hex_arr(op->cmd_file, (op->raw > 0) /* as_binary */, - false /* no_space */, op->cdb, &op->cdb_length, - MAX_SCSI_CDBSZ); + ok = sg_f2hex_arr(op->cmd_file, (op->raw > 0) /* as_binary */, + false /* no_space */, op->cdb, &op->cdb_length, + MAX_SCSI_CDBSZ); if (! ok) return SG_LIB_SYNTAX_ERROR; if (op->verbose > 2) { diff --git a/src/sg_read_attr.c b/src/sg_read_attr.c index 33aa54ed..0b664596 100644 --- a/src/sg_read_attr.c +++ b/src/sg_read_attr.c @@ -373,190 +373,6 @@ enum_sa_acrons(void) printf(" %d:\t\t%s\t%s\n", anvp->val, anvp->acron, anvp->name); } -/* Read ASCII hex bytes or binary from fname (a file named '-' taken as - * stdin). If reading ASCII hex then there should be either one entry per - * line or a comma, space or tab separated list of bytes. If no_space is - * set then a string of ACSII hex digits is expected, 2 per byte. Everything - * from and including a '#' on a line is ignored. Returns 0 if ok, or error - * code. */ -static int -f2hex_arr(const char * fname, bool as_binary, bool no_space, - uint8_t * mp_arr, int * mp_arr_len, int max_arr_len) -{ - bool split_line, has_stdin; - int fn_len, in_len, k, j, m, fd, err; - int off = 0; - int ret = SG_LIB_SYNTAX_ERROR; - unsigned int h; - const char * lcp; - FILE * fp; - char line[512]; - char carry_over[4]; - - if ((NULL == fname) || (NULL == mp_arr) || (NULL == mp_arr_len)) - return SG_LIB_LOGIC_ERROR; - fn_len = strlen(fname); - if (0 == fn_len) - return SG_LIB_SYNTAX_ERROR; - has_stdin = ((1 == fn_len) && ('-' == fname[0])); /* read from stdin */ - if (as_binary) { - if (has_stdin) { - fd = STDIN_FILENO; - if (sg_set_binary_mode(STDIN_FILENO) < 0) - perror("sg_set_binary_mode"); - } else { - fd = open(fname, O_RDONLY); - if (fd < 0) { - err = errno; - pr2serr("unable to open binary file %s: %s\n", fname, - safe_strerror(err)); - return sg_convert_errno(err); - } else if (sg_set_binary_mode(fd) < 0) - perror("sg_set_binary_mode"); - } - k = read(fd, mp_arr, max_arr_len); - if (k <= 0) { - if (0 == k) - pr2serr("read 0 bytes from binary file %s\n", fname); - else { - err = errno; - pr2serr("read from binary file %s: %s\n", fname, - safe_strerror(err)); - ret = sg_convert_errno(err); - } - if (! has_stdin) - close(fd); - return ret; - } - *mp_arr_len = k; - if (! has_stdin) - close(fd); - return 0; - } else { /* So read the file as ASCII hex */ - if (has_stdin) - fp = stdin; - else { - fp = fopen(fname, "r"); - if (NULL == fp) { - pr2serr("Unable to open %s for reading\n", fname); - return 1; - } - } - } - - carry_over[0] = 0; - for (j = 0; j < 512; ++j) { - if (NULL == fgets(line, sizeof(line), fp)) - break; - in_len = strlen(line); - if (in_len > 0) { - if ('\n' == line[in_len - 1]) { - --in_len; - line[in_len] = '\0'; - split_line = false; - } else - split_line = true; - } - if (in_len < 1) { - carry_over[0] = 0; - continue; - } - if (carry_over[0]) { - if (isxdigit(line[0])) { - carry_over[1] = line[0]; - carry_over[2] = '\0'; - if (1 == sscanf(carry_over, "%4x", &h)) - mp_arr[off - 1] = h; /* back up and overwrite */ - else { - pr2serr("%s: carry_over error ['%s'] around line %d\n", - __func__, carry_over, j + 1); - goto bad; - } - lcp = line + 1; - --in_len; - } else - lcp = line; - carry_over[0] = 0; - } else - lcp = line; - - m = strspn(lcp, " \t"); - if (m == in_len) - continue; - lcp += m; - in_len -= m; - if ('#' == *lcp) - continue; - k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t"); - if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) { - pr2serr("%s: syntax error at line %d, pos %d\n", __func__, - j + 1, m + k + 1); - goto bad; - } - if (no_space) { - for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1)); - ++k, lcp += 2) { - if (1 != sscanf(lcp, "%2x", &h)) { - pr2serr("%s: bad hex number in line %d, pos %d\n", - __func__, j + 1, (int)(lcp - line + 1)); - goto bad; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - } - if (isxdigit(*lcp) && (! isxdigit(*(lcp + 1)))) - carry_over[0] = *lcp; - off += k; - } else { - for (k = 0; k < 1024; ++k) { - if (1 == sscanf(lcp, "%4x", &h)) { - if (h > 0xff) { - pr2serr("%s: hex number larger than 0xff in line %d, " - "pos %d\n", __func__, j + 1, - (int)(lcp - line + 1)); - goto bad; - } - if (split_line && (1 == strlen(lcp))) { - /* single trailing hex digit might be a split pair */ - carry_over[0] = *lcp; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - lcp = strpbrk(lcp, " ,\t"); - if (NULL == lcp) - break; - lcp += strspn(lcp, " ,\t"); - if ('\0' == *lcp) - break; - } else { - if (('#' == *lcp) || ('\r' == *lcp)) { - --k; - break; - } - pr2serr("%s: error in line %d, at pos %d\n", __func__, - j + 1, (int)(lcp - line + 1)); - goto bad; - } - } - off += (k + 1); - } - } - *mp_arr_len = off; - if (stdin != fp) - fclose(fp); - return 0; -bad: - if (stdin != fp) - fclose(fp); - return 1; -} - /* Returns 1 if 'bp' all 0xff bytes, returns 2 is all 0xff bytes apart * from last being 0xfe; otherwise returns 0. */ static int @@ -1093,8 +909,8 @@ main(int argc, char * argv[]) if (NULL == device_name) { if (fname) { - if ((ret = f2hex_arr(fname, op->do_raw, 0 /* no space */, rabp, - &in_len, op->maxlen))) + if ((ret = sg_f2hex_arr(fname, op->do_raw, false /* no space */, + rabp, &in_len, op->maxlen))) goto clean_up; if (op->do_raw) op->do_raw = false; /* can interfere on decode */ diff --git a/src/sg_read_buffer.c b/src/sg_read_buffer.c index 82682f30..2dabefb2 100644 --- a/src/sg_read_buffer.c +++ b/src/sg_read_buffer.c @@ -39,7 +39,7 @@ * device. */ -static const char * version_str = "1.29 20190515"; /* spc5r22 */ +static const char * version_str = "1.29 20190516"; /* spc5r22 */ #ifndef SG_READ_BUFFER_10_CMD @@ -391,207 +391,6 @@ decode_microcode_status(uint8_t * resp, int rb_len) } } -/* Read ASCII hex bytes or binary from fname (a file named '-' taken as - * stdin). If reading ASCII hex then there should be either one entry per - * line or a comma, space or tab separated list of bytes. If no_space is - * set then a string of ACSII hex digits is expected, 2 per byte. Everything - * from and including a '#' on a line is ignored. Returns 0 if ok, or an - * error code. */ -static int -f2hex_arr(const char * fname, int as_binary, int no_space, - uint8_t * mp_arr, int * mp_arr_len, int max_arr_len) -{ - int fn_len, in_len, k, j, m, fd, err; - bool has_stdin, split_line; - unsigned int h; - const char * lcp; - FILE * fp; - char line[512]; - char carry_over[4]; - int off = 0; - struct stat a_stat; - - if ((NULL == fname) || (NULL == mp_arr) || (NULL == mp_arr_len)) - return SG_LIB_LOGIC_ERROR; - fn_len = strlen(fname); - if (0 == fn_len) - return SG_LIB_SYNTAX_ERROR; - has_stdin = ((1 == fn_len) && ('-' == fname[0])); /* read from stdin */ - if (as_binary) { - if (has_stdin) - fd = STDIN_FILENO; - else { - fd = open(fname, O_RDONLY); - if (fd < 0) { - err = errno; - pr2serr("unable to open binary file %s: %s\n", fname, - safe_strerror(err)); - return sg_convert_errno(err); - } - } - k = read(fd, mp_arr, max_arr_len); - if (k <= 0) { - int ret = SG_LIB_SYNTAX_ERROR; - - if (0 == k) - pr2serr("read 0 bytes from binary file %s\n", fname); - else { - ret = sg_convert_errno(errno); - pr2serr("read from binary file %s: %s\n", fname, - safe_strerror(errno)); - } - if (! has_stdin) - close(fd); - return ret; - } - if ((0 == fstat(fd, &a_stat)) && S_ISFIFO(a_stat.st_mode)) { - /* pipe; keep reading till error or 0 read */ - while (k < max_arr_len) { - m = read(fd, mp_arr + k, max_arr_len - k); - if (0 == m) - break; - if (m < 0) { - err = errno; - pr2serr("read from binary pipe %s: %s\n", fname, - safe_strerror(err)); - if (! has_stdin) - close(fd); - return sg_convert_errno(err); - } - k += m; - } - } - *mp_arr_len = k; - if (! has_stdin) - close(fd); - return 0; - } else { /* So read the file as ASCII hex */ - if (has_stdin) - fp = stdin; - else { - fp = fopen(fname, "r"); - if (NULL == fp) { - err = errno; - pr2serr("Unable to open %s for reading: %s\n", fname, - safe_strerror(err)); - return sg_convert_errno(err); - } - } - } - - carry_over[0] = 0; - for (j = 0; j < 512; ++j) { - if (NULL == fgets(line, sizeof(line), fp)) - break; - in_len = strlen(line); - if (in_len > 0) { - if ('\n' == line[in_len - 1]) { - --in_len; - line[in_len] = '\0'; - split_line = false; - } else - split_line = true; - } - if (in_len < 1) { - carry_over[0] = 0; - continue; - } - if (carry_over[0]) { - if (isxdigit(line[0])) { - carry_over[1] = line[0]; - carry_over[2] = '\0'; - if (1 == sscanf(carry_over, "%4x", &h)) - mp_arr[off - 1] = h; /* back up and overwrite */ - else { - pr2serr("%s: carry_over error ['%s'] around line %d\n", - __func__, carry_over, j + 1); - goto bad; - } - lcp = line + 1; - --in_len; - } else - lcp = line; - carry_over[0] = 0; - } else - lcp = line; - - m = strspn(lcp, " \t"); - if (m == in_len) - continue; - lcp += m; - in_len -= m; - if ('#' == *lcp) - continue; - k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t"); - if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) { - pr2serr("%s: syntax error at line %d, pos %d\n", __func__, - j + 1, m + k + 1); - goto bad; - } - if (no_space) { - for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1)); - ++k, lcp += 2) { - if (1 != sscanf(lcp, "%2x", &h)) { - pr2serr("%s: bad hex number in line %d, pos %d\n", - __func__, j + 1, (int)(lcp - line + 1)); - goto bad; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - } - if (isxdigit(*lcp) && (! isxdigit(*(lcp + 1)))) - carry_over[0] = *lcp; - off += k; - } else { - for (k = 0; k < 1024; ++k) { - if (1 == sscanf(lcp, "%10x", &h)) { - if (h > 0xff) { - pr2serr("%s: hex number larger than 0xff in line " - "%d, pos %d\n", __func__, j + 1, - (int)(lcp - line + 1)); - goto bad; - } - if (split_line && (1 == strlen(lcp))) { - /* single trailing hex digit might be a split pair */ - carry_over[0] = *lcp; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - lcp = strpbrk(lcp, " ,\t"); - if (NULL == lcp) - break; - lcp += strspn(lcp, " ,\t"); - if ('\0' == *lcp) - break; - } else { - if (('#' == *lcp) || ('\r' == *lcp)) { - --k; - break; - } - pr2serr("%s: error in line %d, at pos %d\n", __func__, - j + 1, (int)(lcp - line + 1)); - goto bad; - } - } - off += (k + 1); - } - } - *mp_arr_len = off; - if (stdin != fp) - fclose(fp); - return 0; -bad: - if (stdin != fp) - fclose(fp); - return 1; -} - static void dStrRaw(const uint8_t * str, int len) { @@ -782,7 +581,7 @@ main(int argc, char * argv[]) } else if (fname) { rb_len = (rb_len > MAX_DEF_INHEX_LEN) ? rb_len : MAX_DEF_INHEX_LEN; resp = (uint8_t *)sg_memalign(rb_len, 0, &free_resp, false); - ret = f2hex_arr(fname, do_raw, 0, resp, &inhex_len, rb_len); + ret = sg_f2hex_arr(fname, do_raw, false, resp, &inhex_len, rb_len); if (ret) goto fini; if (do_raw) diff --git a/src/sg_vpd.c b/src/sg_vpd.c index bf5c448f..6e4b21e8 100644 --- a/src/sg_vpd.c +++ b/src/sg_vpd.c @@ -40,7 +40,7 @@ */ -static const char * version_str = "1.53 20190429"; /* spc5r20 + sbc4r15 */ +static const char * version_str = "1.54 20190516"; /* spc5r22 + sbc4r17 */ /* standard VPD pages, in ascending page number order */ #define VPD_SUPPORTED_VPDS 0x0 @@ -300,207 +300,6 @@ usage() "INQUIRY response.\n"); } -/* Read ASCII hex bytes or binary from fname (a file named '-' taken as - * stdin). If reading ASCII hex then there should be either one entry per - * line or a comma, space or tab separated list of bytes. If no_space is - * set then a string of ACSII hex digits is expected, 2 per byte. Everything - * from and including a '#' on a line is ignored. Returns 0 if ok, or an - * error code. */ -static int -f2hex_arr(const char * fname, int as_binary, int no_space, - uint8_t * mp_arr, int * mp_arr_len, int max_arr_len) -{ - int fn_len, in_len, k, j, m, fd, err; - bool has_stdin, split_line; - unsigned int h; - const char * lcp; - FILE * fp; - char line[512]; - char carry_over[4]; - int off = 0; - struct stat a_stat; - - if ((NULL == fname) || (NULL == mp_arr) || (NULL == mp_arr_len)) - return SG_LIB_LOGIC_ERROR; - fn_len = strlen(fname); - if (0 == fn_len) - return SG_LIB_SYNTAX_ERROR; - has_stdin = ((1 == fn_len) && ('-' == fname[0])); /* read from stdin */ - if (as_binary) { - if (has_stdin) - fd = STDIN_FILENO; - else { - fd = open(fname, O_RDONLY); - if (fd < 0) { - err = errno; - pr2serr("unable to open binary file %s: %s\n", fname, - safe_strerror(err)); - return sg_convert_errno(err); - } - } - k = read(fd, mp_arr, max_arr_len); - if (k <= 0) { - int ret = SG_LIB_SYNTAX_ERROR; - - if (0 == k) - pr2serr("read 0 bytes from binary file %s\n", fname); - else { - ret = sg_convert_errno(errno); - pr2serr("read from binary file %s: %s\n", fname, - safe_strerror(errno)); - } - if (! has_stdin) - close(fd); - return ret; - } - if ((0 == fstat(fd, &a_stat)) && S_ISFIFO(a_stat.st_mode)) { - /* pipe; keep reading till error or 0 read */ - while (k < max_arr_len) { - m = read(fd, mp_arr + k, max_arr_len - k); - if (0 == m) - break; - if (m < 0) { - err = errno; - pr2serr("read from binary pipe %s: %s\n", fname, - safe_strerror(err)); - if (! has_stdin) - close(fd); - return sg_convert_errno(err); - } - k += m; - } - } - *mp_arr_len = k; - if (! has_stdin) - close(fd); - return 0; - } else { /* So read the file as ASCII hex */ - if (has_stdin) - fp = stdin; - else { - fp = fopen(fname, "r"); - if (NULL == fp) { - err = errno; - pr2serr("Unable to open %s for reading: %s\n", fname, - safe_strerror(err)); - return sg_convert_errno(err); - } - } - } - - carry_over[0] = 0; - for (j = 0; j < 512; ++j) { - if (NULL == fgets(line, sizeof(line), fp)) - break; - in_len = strlen(line); - if (in_len > 0) { - if ('\n' == line[in_len - 1]) { - --in_len; - line[in_len] = '\0'; - split_line = false; - } else - split_line = true; - } - if (in_len < 1) { - carry_over[0] = 0; - continue; - } - if (carry_over[0]) { - if (isxdigit(line[0])) { - carry_over[1] = line[0]; - carry_over[2] = '\0'; - if (1 == sscanf(carry_over, "%4x", &h)) - mp_arr[off - 1] = h; /* back up and overwrite */ - else { - pr2serr("%s: carry_over error ['%s'] around line %d\n", - __func__, carry_over, j + 1); - goto bad; - } - lcp = line + 1; - --in_len; - } else - lcp = line; - carry_over[0] = 0; - } else - lcp = line; - - m = strspn(lcp, " \t"); - if (m == in_len) - continue; - lcp += m; - in_len -= m; - if ('#' == *lcp) - continue; - k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t"); - if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) { - pr2serr("%s: syntax error at line %d, pos %d\n", __func__, - j + 1, m + k + 1); - goto bad; - } - if (no_space) { - for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1)); - ++k, lcp += 2) { - if (1 != sscanf(lcp, "%2x", &h)) { - pr2serr("%s: bad hex number in line %d, pos %d\n", - __func__, j + 1, (int)(lcp - line + 1)); - goto bad; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - } - if (isxdigit(*lcp) && (! isxdigit(*(lcp + 1)))) - carry_over[0] = *lcp; - off += k; - } else { - for (k = 0; k < 1024; ++k) { - if (1 == sscanf(lcp, "%10x", &h)) { - if (h > 0xff) { - pr2serr("%s: hex number larger than 0xff in line " - "%d, pos %d\n", __func__, j + 1, - (int)(lcp - line + 1)); - goto bad; - } - if (split_line && (1 == strlen(lcp))) { - /* single trailing hex digit might be a split pair */ - carry_over[0] = *lcp; - } - if ((off + k) >= max_arr_len) { - pr2serr("%s: array length exceeded\n", __func__); - goto bad; - } - mp_arr[off + k] = h; - lcp = strpbrk(lcp, " ,\t"); - if (NULL == lcp) - break; - lcp += strspn(lcp, " ,\t"); - if ('\0' == *lcp) - break; - } else { - if (('#' == *lcp) || ('\r' == *lcp)) { - --k; - break; - } - pr2serr("%s: error in line %d, at pos %d\n", __func__, - j + 1, (int)(lcp - line + 1)); - goto bad; - } - } - off += (k + 1); - } - } - *mp_arr_len = off; - if (stdin != fp) - fclose(fp); - return 0; -bad: - if (stdin != fp) - fclose(fp); - return 1; -} - /* mxlen is command line --maxlen=LEN option (def: 0) or -1 for a VPD page * with a short length (1 byte). Returns 0 for success. */ int /* global: use by sg_vpd_vendor.c */ @@ -4036,8 +3835,8 @@ main(int argc, char * argv[]) ret = SG_LIB_SYNTAX_ERROR; goto err_out; } - if ((ret = f2hex_arr(op->inhex_fn, op->do_raw, 0, rsp_buff, - &inhex_len, rsp_buff_sz))) { + if ((ret = sg_f2hex_arr(op->inhex_fn, !!op->do_raw, false, rsp_buff, + &inhex_len, rsp_buff_sz))) { goto err_out; } if (op->verbose > 2) |