aboutsummaryrefslogtreecommitdiff
path: root/testing/sg_chk_asc.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2017-11-04 21:01:08 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2017-11-04 21:01:08 +0000
commitb77f4de57f4048774e8a78fac9934b58d33b6a68 (patch)
tree917e55edd4852e89c071f01f4c375efcf6f82116 /testing/sg_chk_asc.c
parent3d464ff0b558af456cd4baa79b609a0940489487 (diff)
downloadsg3_utils-b77f4de57f4048774e8a78fac9934b58d33b6a68.tar.gz
move some testing utilities out of the 'examples' and 'utils' directory into the new 'testing' directory; sg_vpd: add enclosure services device characteristics vpage
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@729 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing/sg_chk_asc.c')
-rw-r--r--testing/sg_chk_asc.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/testing/sg_chk_asc.c b/testing/sg_chk_asc.c
new file mode 100644
index 00000000..cb30075d
--- /dev/null
+++ b/testing/sg_chk_asc.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2006-2015 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 <string.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "sg_lib.h"
+
+/* A utility program for the Linux OS SCSI subsystem.
+ *
+ * This program takes a asc_ascq.txt file from www.t10.org and
+ * checks it against the additional sense codes held in the
+ * sg_lib.c file.
+ * The online version of the asc_ascq codes can be found at:
+ * http://www.t10.org/lists/asc-num.txt
+ */
+
+static char * version_str = "1.05 20150105";
+
+
+#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},
+};
+
+static void usage()
+{
+ fprintf(stderr, "Usage: "
+ "sg_chk_asc [--help] [--offset=POS] [--verbose] [--version]\n"
+ " <asc_ascq_file>\n"
+ " where:\n"
+ " --help|-h print out usage message\n"
+ " --offset=POS|-o POS line position in file where "
+ "text starts\n"
+ " origin 0 (def: 24 (was 25))\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-V print version string and exit\n\n"
+ "Checks asc/ascq codes in <asc_ascq_file> against the sg3_utils "
+ "library.\nThe additional sense code (asc_ascq) can be found at\n"
+ "www.t10.org/lists/asc-num.txt .\n"
+ );
+
+}
+
+int main(int argc, char * argv[])
+{
+ int k, j, res, c, num, len, asc, ascq;
+ FILE * fp;
+ int offset = 24;
+ int verbose = 0;
+ char file_name[256];
+ char line[MAX_LINE_LEN];
+ char b[MAX_LINE_LEN];
+ char bb[MAX_LINE_LEN];
+ char * cp;
+ int ret = 1;
+
+ memset(file_name, 0, sizeof file_name);
+ memset(line, 0, sizeof file_name);
+ while (1) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "ho:vV", long_options,
+ &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'h':
+ case '?':
+ usage();
+ return 0;
+ case 'o':
+ offset = sg_get_num(optarg);
+ if (offset < 0) {
+ fprintf(stderr, "bad argument to --offset\n");
+ return 1;
+ }
+ break;
+ 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 ('\0' == file_name[0]) {
+ strncpy(file_name, argv[optind], sizeof(file_name) - 1);
+ file_name[sizeof(file_name) - 1] = '\0';
+ ++optind;
+ }
+ if (optind < argc) {
+ for (; optind < argc; ++optind)
+ fprintf(stderr, "Unexpected extra argument: %s\n",
+ argv[optind]);
+ usage();
+ return 1;
+ }
+ }
+
+ if (0 == file_name[0]) {
+ fprintf(stderr, "missing file name!\n");
+ usage();
+ return 1;
+ }
+ fp = fopen(file_name, "r");
+ if (NULL == fp) {
+ fprintf(stderr, "open error: %s: %s\n", file_name,
+ safe_strerror(errno));
+ return 1;
+ }
+ for (k = 0; (cp = fgets(line, sizeof(line) - 1, fp)); ++k) {
+ len = strlen(line);
+ if (len < 1)
+ continue;
+ if (! isdigit(line[0]))
+ continue;
+ num = sscanf(line, "%xh/%xh", &asc, &ascq);
+ if (1 == num)
+ ascq = -1;
+ if (num < 1) {
+ if (verbose)
+ fprintf(stderr, "Badly formed line number %d (num=%d)\n",
+ k + 1, num);
+ continue;
+ }
+ if (len < 26)
+ continue;
+#if 0
+strncpy(b , line, sizeof(b) - 1);
+b[sizeof(b) - 1] = '\0';
+num = strlen(b);
+if (0xd == b[num - 2]) {
+ b[num - 2] = '\0';
+ b[num - 1] = '\0';
+}
+printf("\"%s\",\n", b);
+#endif
+ strncpy(b , line + offset, sizeof(b) - 1);
+ b[sizeof(b) - 1] = '\0';
+ num = strlen(b);
+ if (0xd == b[num - 2]) {
+ b[num - 2] = '\0';
+ b[num - 1] = '\0';
+ }
+ num = strlen(b);
+ for (j = 0; j < num; ++j)
+ b[j] = toupper(b[j]);
+
+ bb[0] = '\0';
+ if (ascq >= 0) {
+ cp = sg_get_asc_ascq_str(asc, ascq, sizeof(bb) - 1, bb);
+ if (NULL == cp) {
+ fprintf(stderr, "no entry for %x,%x : %s\n", asc, ascq, b);
+ continue;
+ }
+ num = strlen(cp);
+// fprintf(stderr, "file: asc=%x acsq=%x strlen=%d %s\n", asc, ascq, num,
+// cp);
+// if (num < 20)
+// continue;
+ if ((num > 6) &&
+ ((0 == memcmp("ASC", cp, 3)) ||
+ (0 == memcmp("vendor", cp, 6)))) {
+ fprintf(stderr, "%x,%x differ, ref: %s, sg_lib_data: "
+ "<missing>\n", asc, ascq, b);
+ continue;
+ }
+ if (num > 20) {
+ cp += 18;
+ num -= 18;
+ for (j = 0; j < num; ++j)
+ cp[j] = toupper(cp[j]);
+ }
+ if (0 != strcmp(b, cp))
+ fprintf(stderr, "%x,%x differ, ref: %s, sg_lib_data: "
+ "%s\n", asc, ascq, b, cp);
+ }
+ }
+ if (NULL == cp) {
+ if (feof(fp)) {
+ if (verbose > 2)
+ fprintf(stderr, "EOF detected\n");
+ } else
+ fprintf(stderr, "fgets: %s\n", safe_strerror(errno));
+ } else
+ fprintf(stderr, "%s\n", line);
+
+ res = fclose(fp);
+ if (EOF == res) {
+ fprintf(stderr, "close error: %s\n", safe_strerror(errno));
+ return 1;
+ }
+ return ret;
+}