aboutsummaryrefslogtreecommitdiff
path: root/src/sg_read_attr.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2019-05-18 15:37:19 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2019-05-18 15:37:19 +0000
commit3e030c2951bee369b5593243bf317bb5a482a35b (patch)
tree0fc4dff2af1d3ff6f635877879b2c8ec8e6eb1f1 /src/sg_read_attr.c
parentc80acc95be9d1463830259db821ac248e7dc7e46 (diff)
downloadsg3_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/sg_read_attr.c')
-rw-r--r--src/sg_read_attr.c188
1 files changed, 2 insertions, 186 deletions
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 */