xref: /aosp_15_r20/external/sg3_utils/testing/sg_chk_asc.c (revision 44704f698541f6367e81f991ef8bb54ccbf3fc18)
1*44704f69SBart Van Assche /*
2*44704f69SBart Van Assche  * Copyright (c) 2006-2021 Douglas Gilbert.
3*44704f69SBart Van Assche  * All rights reserved.
4*44704f69SBart Van Assche  * Use of this source code is governed by a BSD-style
5*44704f69SBart Van Assche  * license that can be found in the BSD_LICENSE file.
6*44704f69SBart Van Assche  *
7*44704f69SBart Van Assche  * SPDX-License-Identifier: BSD-2-Clause
8*44704f69SBart Van Assche  */
9*44704f69SBart Van Assche 
10*44704f69SBart Van Assche #include <unistd.h>
11*44704f69SBart Van Assche #include <fcntl.h>
12*44704f69SBart Van Assche #include <stdio.h>
13*44704f69SBart Van Assche #include <stdlib.h>
14*44704f69SBart Van Assche #include <string.h>
15*44704f69SBart Van Assche #include <getopt.h>
16*44704f69SBart Van Assche #include <ctype.h>
17*44704f69SBart Van Assche #include <errno.h>
18*44704f69SBart Van Assche 
19*44704f69SBart Van Assche #include "sg_lib.h"
20*44704f69SBart Van Assche 
21*44704f69SBart Van Assche /* A utility program for the Linux OS SCSI subsystem.
22*44704f69SBart Van Assche  *
23*44704f69SBart Van Assche  * This program takes a asc_ascq.txt file from www.t10.org and
24*44704f69SBart Van Assche  * checks it against the additional sense codes held in the
25*44704f69SBart Van Assche  * sg_lib.c file.
26*44704f69SBart Van Assche  * The online version of the asc_ascq codes can be found at:
27*44704f69SBart Van Assche  * https://www.t10.org/lists/asc-num.txt
28*44704f69SBart Van Assche  */
29*44704f69SBart Van Assche 
30*44704f69SBart Van Assche static const char * version_str = "1.09 20210226";
31*44704f69SBart Van Assche 
32*44704f69SBart Van Assche 
33*44704f69SBart Van Assche #define MAX_LINE_LEN 1024
34*44704f69SBart Van Assche 
35*44704f69SBart Van Assche 
36*44704f69SBart Van Assche static struct option long_options[] = {
37*44704f69SBart Van Assche         {"help", 0, 0, 'h'},
38*44704f69SBart Van Assche         {"verbose", 0, 0, 'v'},
39*44704f69SBart Van Assche         {"version", 0, 0, 'V'},
40*44704f69SBart Van Assche         {0, 0, 0, 0},
41*44704f69SBart Van Assche };
42*44704f69SBart Van Assche 
usage()43*44704f69SBart Van Assche static void usage()
44*44704f69SBart Van Assche {
45*44704f69SBart Van Assche     fprintf(stderr, "Usage: "
46*44704f69SBart Van Assche             "sg_chk_asc [--help] [--offset=POS] [--verbose] [--version]\n"
47*44704f69SBart Van Assche             "                  <asc_ascq_file>\n"
48*44704f69SBart Van Assche             "  where:\n"
49*44704f69SBart Van Assche             "    --help|-h          print out usage message\n"
50*44704f69SBart Van Assche             "    --offset=POS|-o POS    line position in file where "
51*44704f69SBart Van Assche             "text starts\n"
52*44704f69SBart Van Assche             "                           origin 0 (def: 24 (was 25))\n"
53*44704f69SBart Van Assche             "    --verbose|-v       increase verbosity\n"
54*44704f69SBart Van Assche             "    --version|-V       print version string and exit\n\n"
55*44704f69SBart Van Assche             "Checks asc/ascq codes in <asc_ascq_file> against the sg3_utils "
56*44704f69SBart Van Assche             "library.\nThe additional sense codes (asc_ascq) can be found "
57*44704f69SBart Van Assche             "at\nwww.t10.org/lists/asc-num.txt .\n"
58*44704f69SBart Van Assche            );
59*44704f69SBart Van Assche 
60*44704f69SBart Van Assche }
61*44704f69SBart Van Assche 
main(int argc,char * argv[])62*44704f69SBart Van Assche int main(int argc, char * argv[])
63*44704f69SBart Van Assche {
64*44704f69SBart Van Assche     int k, j, res, c, num, len;
65*44704f69SBart Van Assche     unsigned int asc, ascq;
66*44704f69SBart Van Assche     FILE * fp;
67*44704f69SBart Van Assche     int offset = 24;
68*44704f69SBart Van Assche     int verbose = 0;
69*44704f69SBart Van Assche     char file_name[256];
70*44704f69SBart Van Assche     char line[MAX_LINE_LEN];
71*44704f69SBart Van Assche     char b[MAX_LINE_LEN];
72*44704f69SBart Van Assche     char bb[MAX_LINE_LEN];
73*44704f69SBart Van Assche     char * cp;
74*44704f69SBart Van Assche     int ret = 1;
75*44704f69SBart Van Assche 
76*44704f69SBart Van Assche     memset(file_name, 0, sizeof file_name);
77*44704f69SBart Van Assche     memset(line, 0, sizeof file_name);
78*44704f69SBart Van Assche     while (1) {
79*44704f69SBart Van Assche         int option_index = 0;
80*44704f69SBart Van Assche 
81*44704f69SBart Van Assche         c = getopt_long(argc, argv, "ho:vV", long_options,
82*44704f69SBart Van Assche                         &option_index);
83*44704f69SBart Van Assche         if (c == -1)
84*44704f69SBart Van Assche             break;
85*44704f69SBart Van Assche 
86*44704f69SBart Van Assche         switch (c) {
87*44704f69SBart Van Assche         case 'h':
88*44704f69SBart Van Assche         case '?':
89*44704f69SBart Van Assche             usage();
90*44704f69SBart Van Assche             return 0;
91*44704f69SBart Van Assche         case 'o':
92*44704f69SBart Van Assche             offset = sg_get_num(optarg);
93*44704f69SBart Van Assche             if (offset < 0) {
94*44704f69SBart Van Assche                 fprintf(stderr, "bad argument to --offset\n");
95*44704f69SBart Van Assche                 return 1;
96*44704f69SBart Van Assche             }
97*44704f69SBart Van Assche             break;
98*44704f69SBart Van Assche         case 'v':
99*44704f69SBart Van Assche             ++verbose;
100*44704f69SBart Van Assche             break;
101*44704f69SBart Van Assche         case 'V':
102*44704f69SBart Van Assche             fprintf(stderr, "version: %s\n", version_str);
103*44704f69SBart Van Assche             return 0;
104*44704f69SBart Van Assche         default:
105*44704f69SBart Van Assche             fprintf(stderr, "unrecognised switch code 0x%x ??\n", c);
106*44704f69SBart Van Assche             usage();
107*44704f69SBart Van Assche             return 1;
108*44704f69SBart Van Assche         }
109*44704f69SBart Van Assche     }
110*44704f69SBart Van Assche     if (optind < argc) {
111*44704f69SBart Van Assche         if ('\0' == file_name[0]) {
112*44704f69SBart Van Assche             strncpy(file_name, argv[optind], sizeof(file_name) - 1);
113*44704f69SBart Van Assche             file_name[sizeof(file_name) - 1] = '\0';
114*44704f69SBart Van Assche             ++optind;
115*44704f69SBart Van Assche         }
116*44704f69SBart Van Assche         if (optind < argc) {
117*44704f69SBart Van Assche             for (; optind < argc; ++optind)
118*44704f69SBart Van Assche                 fprintf(stderr, "Unexpected extra argument: %s\n",
119*44704f69SBart Van Assche                         argv[optind]);
120*44704f69SBart Van Assche             usage();
121*44704f69SBart Van Assche             return 1;
122*44704f69SBart Van Assche         }
123*44704f69SBart Van Assche     }
124*44704f69SBart Van Assche 
125*44704f69SBart Van Assche     if (0 == file_name[0]) {
126*44704f69SBart Van Assche         fprintf(stderr, "missing file name!\n");
127*44704f69SBart Van Assche         usage();
128*44704f69SBart Van Assche         return 1;
129*44704f69SBart Van Assche     }
130*44704f69SBart Van Assche     fp = fopen(file_name, "r");
131*44704f69SBart Van Assche     if (NULL == fp) {
132*44704f69SBart Van Assche         fprintf(stderr, "open error: %s: %s\n", file_name,
133*44704f69SBart Van Assche                 safe_strerror(errno));
134*44704f69SBart Van Assche         return 1;
135*44704f69SBart Van Assche     }
136*44704f69SBart Van Assche     for (k = 0; (cp = fgets(line, sizeof(line) - 1, fp)); ++k) {
137*44704f69SBart Van Assche         len = strlen(line);
138*44704f69SBart Van Assche         if (len < 1)
139*44704f69SBart Van Assche             continue;
140*44704f69SBart Van Assche         if (! isdigit(line[0]))
141*44704f69SBart Van Assche             continue;
142*44704f69SBart Van Assche         num = sscanf(line, "%xh/%xh", &asc, &ascq);
143*44704f69SBart Van Assche         if (1 == num)
144*44704f69SBart Van Assche             ascq = 999;
145*44704f69SBart Van Assche         if (num < 1) {
146*44704f69SBart Van Assche             if (verbose)
147*44704f69SBart Van Assche                 fprintf(stderr, "Badly formed line number %d (num=%d)\n",
148*44704f69SBart Van Assche                         k + 1, num);
149*44704f69SBart Van Assche             continue;
150*44704f69SBart Van Assche         }
151*44704f69SBart Van Assche         if (len < 26)
152*44704f69SBart Van Assche             continue;
153*44704f69SBart Van Assche #if 0
154*44704f69SBart Van Assche strncpy(b , line, sizeof(b) - 1);
155*44704f69SBart Van Assche b[sizeof(b) - 1] = '\0';
156*44704f69SBart Van Assche num = strlen(b);
157*44704f69SBart Van Assche if (0xd == b[num - 2]) {
158*44704f69SBart Van Assche     b[num - 2] = '\0';
159*44704f69SBart Van Assche     b[num - 1] = '\0';
160*44704f69SBart Van Assche }
161*44704f69SBart Van Assche printf("\"%s\",\n", b);
162*44704f69SBart Van Assche #endif
163*44704f69SBart Van Assche         strncpy(b , line + offset, sizeof(b) - 1);
164*44704f69SBart Van Assche         b[sizeof(b) - 1] = '\0';
165*44704f69SBart Van Assche         num = strlen(b);
166*44704f69SBart Van Assche         if (0xd == b[num - 2])
167*44704f69SBart Van Assche             b[num - 2] = '\0';
168*44704f69SBart Van Assche         b[num - 1] = '\0';
169*44704f69SBart Van Assche         num = strlen(b);
170*44704f69SBart Van Assche         for (j = 0; j < num; ++j)
171*44704f69SBart Van Assche             b[j] = toupper(b[j]);
172*44704f69SBart Van Assche 
173*44704f69SBart Van Assche         bb[0] = '\0';
174*44704f69SBart Van Assche         if (ascq < 999) {
175*44704f69SBart Van Assche             cp = sg_get_asc_ascq_str(asc, ascq, sizeof(bb) - 1, bb);
176*44704f69SBart Van Assche             if (NULL == cp) {
177*44704f69SBart Van Assche                 fprintf(stderr, "no entry for %x,%x : %s\n", asc, ascq, b);
178*44704f69SBart Van Assche                 continue;
179*44704f69SBart Van Assche             }
180*44704f69SBart Van Assche             num = strlen(cp);
181*44704f69SBart Van Assche // fprintf(stderr, "file: asc=%x  acsq=%x  strlen=%d %s\n", asc, ascq, num,
182*44704f69SBart Van Assche //         cp);
183*44704f69SBart Van Assche //            if (num < 20)
184*44704f69SBart Van Assche //                continue;
185*44704f69SBart Van Assche             if ((num > 6) &&
186*44704f69SBart Van Assche                 ((0 == memcmp("ASC", cp, 3)) ||
187*44704f69SBart Van Assche                  (0 == memcmp("vendor", cp, 6)))) {
188*44704f69SBart Van Assche                 fprintf(stderr, "%x,%x differ, ref: %s, sg_lib_data: "
189*44704f69SBart Van Assche                         "<missing>\n", asc, ascq, b);
190*44704f69SBart Van Assche                 continue;
191*44704f69SBart Van Assche             }
192*44704f69SBart Van Assche             if (num > 20) {
193*44704f69SBart Van Assche                 cp += 18;
194*44704f69SBart Van Assche                 num -= 18;
195*44704f69SBart Van Assche                 for (j = 0; j < num; ++j)
196*44704f69SBart Van Assche                     cp[j] = toupper(cp[j]);
197*44704f69SBart Van Assche             }
198*44704f69SBart Van Assche             if (0 != strcmp(b, cp))
199*44704f69SBart Van Assche                 fprintf(stderr, "%x,%x differ, ref: %s, sg_lib_data: "
200*44704f69SBart Van Assche                         "%s\n", asc, ascq, b, cp);
201*44704f69SBart Van Assche         }
202*44704f69SBart Van Assche     }
203*44704f69SBart Van Assche     if (NULL == cp) {
204*44704f69SBart Van Assche         if (feof(fp)) {
205*44704f69SBart Van Assche             if (verbose > 2)
206*44704f69SBart Van Assche                 fprintf(stderr, "EOF detected\n");
207*44704f69SBart Van Assche         } else
208*44704f69SBart Van Assche             fprintf(stderr, "fgets: %s\n", safe_strerror(errno));
209*44704f69SBart Van Assche     } else
210*44704f69SBart Van Assche         fprintf(stderr, "%s\n", line);
211*44704f69SBart Van Assche 
212*44704f69SBart Van Assche     res = fclose(fp);
213*44704f69SBart Van Assche     if (EOF == res) {
214*44704f69SBart Van Assche         fprintf(stderr, "close error: %s\n", safe_strerror(errno));
215*44704f69SBart Van Assche         return 1;
216*44704f69SBart Van Assche     }
217*44704f69SBart Van Assche     return ret;
218*44704f69SBart Van Assche }
219