aboutsummaryrefslogtreecommitdiff
path: root/src/sg_unmap.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2014-01-28 16:27:16 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2014-01-28 16:27:16 +0000
commit7a21fa031cd5f471ffbfbf1e2c8b2a27a6149657 (patch)
treede95ab2764b89f8bd4314a0f5e228fdb630821ce /src/sg_unmap.c
parent4ac0d027631c7d48114d36257fde211c32d20137 (diff)
downloadsg3_utils-7a21fa031cd5f471ffbfbf1e2c8b2a27a6149657.tar.gz
sg_unmap cleanup; manpages: add rescan-scsi-bus.sh.8 and other cleanups
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@548 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_unmap.c')
-rw-r--r--src/sg_unmap.c130
1 files changed, 78 insertions, 52 deletions
diff --git a/src/sg_unmap.c b/src/sg_unmap.c
index 314ca7a5..aaafc2b0 100644
--- a/src/sg_unmap.c
+++ b/src/sg_unmap.c
@@ -9,6 +9,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h>
@@ -29,7 +30,7 @@
* logical blocks.
*/
-static const char * version_str = "1.04 20140110";
+static const char * version_str = "1.05 20140126";
#define DEF_TIMEOUT_SECS 60
@@ -49,10 +50,30 @@ static struct option long_options[] = {
{0, 0, 0, 0},
};
+
+#ifdef __GNUC__
+static int pr2serr(const char * fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+#else
+static int pr2serr(const char * fmt, ...);
+#endif
+
+static int
+pr2serr(const char * fmt, ...)
+{
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vfprintf(stderr, fmt, args);
+ va_end(args);
+ return n;
+}
+
static void
usage()
{
- fprintf(stderr, "Usage: "
+ pr2serr("Usage: "
"sg_unmap [--anchor] [--grpnum=GN] [--help] [--in=FILE]\n"
" [--lba=LBA,LBA...] [--num=NUM,NUM...] "
"[--timeout=TO]\n"
@@ -85,7 +106,7 @@ usage()
/* Trying to decode multipliers as sg_get_llnum() [in sg_libs] does would
* only confuse things here, so use this local trimmed version */
-int64_t
+static int64_t
get_llnum(const char * buf)
{
int res, len;
@@ -133,12 +154,12 @@ build_lba_arr(const char * inp, uint64_t * lba_arr,
if (0 == in_len)
*lba_arr_len = 0;
if ('-' == inp[0]) { /* read from stdin */
- fprintf(stderr, "'--lba' cannot be read from stdin\n");
+ pr2serr("'--lba' cannot be read from stdin\n");
return 1;
} else { /* list of numbers (default decimal) on command line */
k = strspn(inp, "0123456789aAbBcCdDeEfFhHxX, ");
if (in_len != k) {
- fprintf(stderr, "build_lba_arr: error at pos %d\n", k + 1);
+ pr2serr("build_lba_arr: error at pos %d\n", k + 1);
return 1;
}
for (k = 0; k < max_arr_len; ++k) {
@@ -155,14 +176,14 @@ build_lba_arr(const char * inp, uint64_t * lba_arr,
cp = c2p;
lcp = cp + 1;
} else {
- fprintf(stderr, "build_lba_arr: error at pos %d\n",
+ pr2serr("build_lba_arr: error at pos %d\n",
(int)(lcp - inp + 1));
return 1;
}
}
*lba_arr_len = k + 1;
if (k == max_arr_len) {
- fprintf(stderr, "build_lba_arr: array length exceeded\n");
+ pr2serr("build_lba_arr: array length exceeded\n");
return 1;
}
}
@@ -191,18 +212,23 @@ build_num_arr(const char * inp, uint32_t * num_arr,
if (0 == in_len)
*num_arr_len = 0;
if ('-' == inp[0]) { /* read from stdin */
- fprintf(stderr, "'--len' cannot be read from stdin\n");
+ pr2serr("'--len' cannot be read from stdin\n");
return 1;
} else { /* list of numbers (default decimal) on command line */
k = strspn(inp, "0123456789aAbBcCdDeEfFhHxX, ");
if (in_len != k) {
- fprintf(stderr, "build_num_arr: error at pos %d\n", k + 1);
+ pr2serr("build_num_arr: error at pos %d\n", k + 1);
return 1;
}
for (k = 0; k < max_arr_len; ++k) {
ll = get_llnum(lcp);
if (-1 != ll) {
- num_arr[k] = (uint32_t)ll; // could truncate
+ if (ll > UINT32_MAX) {
+ pr2serr("build_num_arr: number exceeds 32 bits at pos "
+ "%d\n", (int)(lcp - inp + 1));
+ return 1;
+ }
+ num_arr[k] = (uint32_t)ll;
cp = (char *)strchr(lcp, ',');
c2p = (char *)strchr(lcp, ' ');
if (NULL == cp)
@@ -213,14 +239,14 @@ build_num_arr(const char * inp, uint32_t * num_arr,
cp = c2p;
lcp = cp + 1;
} else {
- fprintf(stderr, "build_num_arr: error at pos %d\n",
+ pr2serr("build_num_arr: error at pos %d\n",
(int)(lcp - inp + 1));
return 1;
}
}
*num_arr_len = k + 1;
if (k == max_arr_len) {
- fprintf(stderr, "build_num_arr: array length exceeded\n");
+ pr2serr("build_num_arr: array length exceeded\n");
return 1;
}
}
@@ -249,8 +275,7 @@ build_joint_arr(const char * file_name, uint64_t * lba_arr, uint32_t * num_arr,
else {
fp = fopen(file_name, "r");
if (NULL == fp) {
- fprintf(stderr, "build_joint_arr: unable to open %s\n",
- file_name);
+ pr2serr("build_joint_arr: unable to open %s\n", file_name);
return 1;
}
}
@@ -278,8 +303,8 @@ build_joint_arr(const char * file_name, uint64_t * lba_arr, uint32_t * num_arr,
continue;
k = strspn(lcp, "0123456789aAbBcCdDeEfFhHxX ,\t");
if ((k < in_len) && ('#' != lcp[k])) {
- fprintf(stderr, "build_joint_arr: syntax error at "
- "line %d, pos %d\n", j + 1, m + k + 1);
+ pr2serr("build_joint_arr: syntax error at line %d, pos %d\n",
+ j + 1, m + k + 1);
return 1;
}
for (k = 0; k < 1024; ++k) {
@@ -288,13 +313,18 @@ build_joint_arr(const char * file_name, uint64_t * lba_arr, uint32_t * num_arr,
ind = ((off + k) >> 1);
bit0 = 0x1 & (off + k);
if (ind >= max_arr_len) {
- fprintf(stderr, "build_joint_arr: array length "
- "exceeded\n");
+ pr2serr("build_joint_arr: array length exceeded\n");
return 1;
}
- if (bit0)
- num_arr[ind] = (uint32_t)ll;
- else
+ if (bit0) {
+ if (ll > UINT32_MAX) {
+ pr2serr("build_joint_arr: number exceeds 32 bits in "
+ "line %d, at pos %d\n", j + 1,
+ (int)(lcp - line + 1));
+ return 1;
+ }
+ num_arr[ind] = (uint32_t)ll;
+ } else
lba_arr[ind] = (uint64_t)ll;
lcp = strpbrk(lcp, " ,\t");
if (NULL == lcp)
@@ -307,17 +337,16 @@ build_joint_arr(const char * file_name, uint64_t * lba_arr, uint32_t * num_arr,
--k;
break;
}
- fprintf(stderr, "build_joint_arr: error in "
- "line %d, at pos %d\n", j + 1,
- (int)(lcp - line + 1));
+ pr2serr("build_joint_arr: error on line %d, at pos %d\n",
+ j + 1, (int)(lcp - line + 1));
return 1;
}
}
off += (k + 1);
}
if (0x1 & off) {
- fprintf(stderr, "build_joint_arr: expect LBA,NUM pairs but decoded "
- "odd number\n from %s\n", have_stdin ? "stdin" : file_name);
+ pr2serr("build_joint_arr: expect LBA,NUM pairs but decoded odd "
+ "number\n from %s\n", have_stdin ? "stdin" : file_name);
return 1;
}
*arr_len = off >> 1;
@@ -362,7 +391,7 @@ main(int argc, char * argv[])
if ((1 == num) && ((res < 0) || (res > 31)))
grpnum = res;
else {
- fprintf(stderr, "value for '--grpnum=' must be 0 to 31\n");
+ pr2serr("value for '--grpnum=' must be 0 to 31\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
@@ -382,7 +411,7 @@ main(int argc, char * argv[])
case 't':
timeout = sg_get_num(optarg);
if (timeout < 0) {
- fprintf(stderr, "bad argument to '--timeout'\n");
+ pr2serr("bad argument to '--timeout'\n");
return SG_LIB_SYNTAX_ERROR;
} else if (0 == timeout)
timeout = DEF_TIMEOUT_SECS;
@@ -391,10 +420,10 @@ main(int argc, char * argv[])
++verbose;
break;
case 'V':
- fprintf(stderr, "version: %s\n", version_str);
+ pr2serr("version: %s\n", version_str);
return 0;
default:
- fprintf(stderr, "unrecognised option code 0x%x ??\n", c);
+ pr2serr("unrecognised option code 0x%x ??\n", c);
usage();
return SG_LIB_SYNTAX_ERROR;
}
@@ -406,30 +435,28 @@ main(int argc, char * argv[])
}
if (optind < argc) {
for (; optind < argc; ++optind)
- fprintf(stderr, "Unexpected extra argument: %s\n",
- argv[optind]);
+ pr2serr("Unexpected extra argument: %s\n", argv[optind]);
usage();
return SG_LIB_SYNTAX_ERROR;
}
}
if (NULL == device_name) {
- fprintf(stderr, "missing device name!\n");
+ pr2serr("missing device name!\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
if (in_op && (lba_op || num_op)) {
- fprintf(stderr, "expect '--in=' by itself, or both '--lba=' and "
- "'--num='\n");
+ pr2serr("expect '--in=' by itself, or both '--lba=' and '--num='\n");
usage();
return SG_LIB_SYNTAX_ERROR;
} else if (in_op || (lba_op && num_op))
;
else {
if (lba_op)
- fprintf(stderr, "since '--lba=' is given, also need '--num='\n");
+ pr2serr("since '--lba=' is given, also need '--num='\n");
else
- fprintf(stderr, "expect either both '--lba=' and '--num=', or "
+ pr2serr("expect either both '--lba=' and '--num=', or "
"'--in=' by itself\n");
usage();
return SG_LIB_SYNTAX_ERROR;
@@ -441,16 +468,16 @@ main(int argc, char * argv[])
if (lba_op && num_op) {
if (0 != build_lba_arr(lba_op, addr_arr, &addr_arr_len,
MAX_NUM_ADDR)) {
- fprintf(stderr, "bad argument to '--lba'\n");
+ pr2serr("bad argument to '--lba'\n");
return SG_LIB_SYNTAX_ERROR;
}
if (0 != build_num_arr(num_op, num_arr, &num_arr_len,
MAX_NUM_ADDR)) {
- fprintf(stderr, "bad argument to '--num'\n");
+ pr2serr("bad argument to '--num'\n");
return SG_LIB_SYNTAX_ERROR;
}
if ((addr_arr_len != num_arr_len) || (num_arr_len <= 0)) {
- fprintf(stderr, "need same number of arguments to '--lba=' "
+ pr2serr("need same number of arguments to '--lba=' "
"and '--num=' options\n");
return SG_LIB_SYNTAX_ERROR;
}
@@ -458,12 +485,12 @@ main(int argc, char * argv[])
if (in_op) {
if (0 != build_joint_arr(in_op, addr_arr, num_arr, &addr_arr_len,
MAX_NUM_ADDR)) {
- fprintf(stderr, "bad argument to '--in'\n");
+ pr2serr("bad argument to '--in'\n");
return SG_LIB_SYNTAX_ERROR;
}
if (addr_arr_len <= 0) {
- fprintf(stderr, "no addresses found in '--in=' argument, file: "
- "%s\n", in_op);
+ pr2serr("no addresses found in '--in=' argument, file: %s\n",
+ in_op);
return SG_LIB_SYNTAX_ERROR;
}
}
@@ -496,8 +523,7 @@ main(int argc, char * argv[])
sg_fd = sg_cmds_open_device(device_name, 0 /* rw */, verbose);
if (sg_fd < 0) {
- fprintf(stderr, "open error: %s: %s\n", device_name,
- safe_strerror(-sg_fd));
+ pr2serr("open error: %s: %s\n", device_name, safe_strerror(-sg_fd));
return SG_LIB_FILE_ERROR;
}
@@ -505,29 +531,29 @@ main(int argc, char * argv[])
1, verbose);
ret = res;
if (SG_LIB_CAT_NOT_READY == res) {
- fprintf(stderr, "UNMAP failed, device not ready\n");
+ pr2serr("UNMAP failed, device not ready\n");
goto err_out;
} else if (SG_LIB_CAT_UNIT_ATTENTION == res) {
- fprintf(stderr, "UNMAP, unit attention\n");
+ pr2serr("UNMAP, unit attention\n");
goto err_out;
} else if (SG_LIB_CAT_ABORTED_COMMAND == res) {
- fprintf(stderr, "UNMAP, aborted command\n");
+ pr2serr("UNMAP, aborted command\n");
goto err_out;
} else if (SG_LIB_CAT_INVALID_OP == res) {
- fprintf(stderr, "UNMAP not supported\n");
+ pr2serr("UNMAP not supported\n");
goto err_out;
} else if (SG_LIB_CAT_ILLEGAL_REQ == res) {
- fprintf(stderr, "bad field in UNMAP cdb\n");
+ pr2serr("bad field in UNMAP cdb\n");
goto err_out;
} else if (0 != res) {
- fprintf(stderr, "UNMAP failed (use '-v' to get more information)\n");
+ pr2serr("UNMAP failed (use '-v' to get more information)\n");
goto err_out;
}
err_out:
res = sg_cmds_close_device(sg_fd);
if (res < 0) {
- fprintf(stderr, "close error: %s\n", safe_strerror(-res));
+ pr2serr("close error: %s\n", safe_strerror(-res));
if (0 == ret)
return SG_LIB_FILE_ERROR;
}