aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2013-01-24 00:59:41 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2013-01-24 00:59:41 +0000
commitcbbf0d86b9bbcfb5bbe362ea16c765a665c666ef (patch)
tree391470fd11709ac86dcbaedab18241874e0fcf74 /utils
parent9e391d682247b69fb0cb631dd22cb481b378c2ee (diff)
downloadsg3_utils-cbbf0d86b9bbcfb5bbe362ea16c765a665c666ef.tar.gz
sg_vpd: persistent connection page 0x91, fix my_snprintf
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@478 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'utils')
-rw-r--r--utils/Makefile5
-rw-r--r--utils/tst_sg_lib.c226
2 files changed, 230 insertions, 1 deletions
diff --git a/utils/Makefile b/utils/Makefile
index a1416467..fb9b6ea1 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -8,7 +8,7 @@ CC = gcc
LD = gcc
EXECS = hxascdmp
-EXTRA_EXECS = hxascdmp sg_chk_asc
+EXTRA_EXECS = hxascdmp sg_chk_asc tst_sg_lib
MAN_PGS = hxascdmp.1
MAN_PREF = man1
@@ -34,6 +34,9 @@ hxascdmp: hxascdmp.o
sg_chk_asc: sg_chk_asc.o ../lib/sg_lib.o ../lib/sg_lib_data.o
$(LD) -o $@ $(LDFLAGS) $^
+tst_sg_lib: tst_sg_lib.o ../lib/sg_lib.o ../lib/sg_lib_data.o
+ $(LD) -o $@ $(LDFLAGS) $^
+
install: $(EXECS)
install -d $(INSTDIR)
diff --git a/utils/tst_sg_lib.c b/utils/tst_sg_lib.c
new file mode 100644
index 00000000..504530d5
--- /dev/null
+++ b/utils/tst_sg_lib.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2013 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.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "sg_lib.h"
+
+/* A utility program to test sg_libs string handling, specifically
+ * related to snprintf().
+ *
+ */
+
+static char * version_str = "1.00 20130122";
+
+
+#define MAX_LINE_LEN 1024
+
+
+static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"verbose", 0, 0, 'v'},
+ {"version", 0, 0, 'V'},
+ {0, 0, 0, 0},
+};
+
+const unsigned char desc_sense_data[] = {
+ /* unrec_err, excessive_writes, sdat_ovfl, additional_len=? */
+ 0x72, 0x1, 0x3, 0x2, 0x80, 0x0, 0x0, 32+4+8+4+28,
+ /* Information: 0x11223344556677bb */
+ 0x0, 0xa, 0x80, 0x0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xbb,
+ /* command specific: 0x3344556677bbccff */
+ 0x1, 0xa, 0x0, 0x0, 0x33, 0x44, 0x55, 0x66, 0x77, 0xbb, 0xcc, 0xff,
+ /* sense key specific: SKSV=1, actual_count=257 (hex: 0x101) */
+ 0x2, 0x6, 0x0, 0x0, 0x80, 0x1, 0x1, 0x0,
+ /* field replaceable code=0x45 */
+ 0x3, 0x2, 0x0, 0x45,
+ /* another progress report indicator */
+ 0xa, 0x6, 0x2, 0x1, 0x2, 0x0, 0x32, 0x01,
+ /* incorrect length indicator (ILI) */
+ 0x5, 0x2, 0x0, 0x20,
+ /* user data degment referral */
+ 0xb, 26, 0x1, 0x0,
+ 0,0,0,1, 0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,
+ 0x1,0x2,0x3,0x4,0x55,0x6,0x7,0x8,
+ 2,0,0x12,0x34,
+ };
+
+
+static void usage()
+{
+ fprintf(stderr, "Usage: "
+ "tst_sg_lib [--help] [--verbose] [--version]\n"
+ " where: --help|-h print out usage message\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-V print version string and exit\n\n"
+ "xxxxxxxxxxxxxxxxxxxxxxxx\n"
+ );
+
+}
+
+/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
+ * then assume cp is pointing to a null char and do nothing. Returns number
+ * number of chars placed in cp excluding the trailing null char. So for
+ * cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
+ * <= 0 the return value is 0 (and no chars are written to cp). */
+static int
+my_snprintf(char * cp, int cp_max_len, const char * fmt, ...)
+{
+ va_list args;
+ int n;
+
+ if (cp_max_len < 2)
+ return 0;
+ va_start(args, fmt);
+ n = vsnprintf(cp, cp_max_len, fmt, args);
+ va_end(args);
+ return (n < cp_max_len) ? n : (cp_max_len - 1);
+}
+
+int main(int argc, char * argv[])
+{
+ int c, n, len;
+ int verbose = 0;
+ int ret = 1;
+ char b[2048];
+
+ while (1) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "hvV", long_options,
+ &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'h':
+ case '?':
+ usage();
+ return 0;
+ case 'v':
+ ++verbose;
+ break;
+ case 'V':
+ fprintf(stderr, "version: %s\n", version_str);
+ return 0;
+ default:
+ fprintf(stderr, "unrecognised switch code 0x%x ??\n", c);
+ usage();
+ return 1;
+ }
+ }
+ if (optind < argc) {
+ if (optind < argc) {
+ for (; optind < argc; ++optind)
+ fprintf(stderr, "Unexpected extra argument: %s\n",
+ argv[optind]);
+ usage();
+ return 1;
+ }
+ }
+
+ printf("Testing my_snprintf():\n");
+ sg_print_sense("desc_sense_data test", desc_sense_data, (int)sizeof(desc_sense_data), 1);
+ printf("\n");
+
+#if 1
+ sg_get_sense_str("sg_get_sense_str", desc_sense_data, sizeof(desc_sense_data), 1, sizeof(b), b);
+ printf("sg_get_sense_str: strlen(b)->%zd\n", strlen(b));
+ printf("%s", b);
+ printf("\n");
+#endif
+
+ b[0] = '\0';
+ len = sizeof(b);
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = -1;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = 0;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = 1;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = 2;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = 3;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = 4;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = 5;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = 6;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ b[0] = '\0';
+ len = 7;
+ n = my_snprintf(b, len, "%s", "test");
+ printf("my_snprintf(,%d,,\"test\") -> %d; strlen(b) -> %zd\n",
+ len, n, strlen(b));
+ if (strlen(b) > 0)
+ printf("Resulting string: %s\n", b);
+
+ return ret;
+}