diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2017-11-04 21:01:08 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2017-11-04 21:01:08 +0000 |
commit | b77f4de57f4048774e8a78fac9934b58d33b6a68 (patch) | |
tree | 917e55edd4852e89c071f01f4c375efcf6f82116 /testing/sg_chk_asc.c | |
parent | 3d464ff0b558af456cd4baa79b609a0940489487 (diff) | |
download | sg3_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.c | 216 |
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; +} |