1 /*
2 * Copyright (C) 2004-2018 D. Gilbert
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 /* This is a simple program that tests the sense data descriptor format
12 * printout function in sg_lib.c . */
13
14 #include <unistd.h>
15 #include <fcntl.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdint.h>
19 #include <string.h>
20 #include <getopt.h>
21
22 #include "sg_lib.h"
23
24
25 #define EBUFF_SZ 256
26
27 #define ME "sg_sense_test: "
28
29 static const char * version_str = "2.04 20181207";
30
31 static struct option long_options[] = {
32 {"help", no_argument, 0, 'h'},
33 {"leadin", required_argument, 0, 'l'},
34 {"stdout", no_argument, 0, 's'},
35 {"verbose", no_argument, 0, 'v'},
36 {"version", no_argument, 0, 'V'},
37 {0, 0, 0, 0}, /* sentinel */
38 };
39
40
41 static void
usage()42 usage()
43 {
44 fprintf(stderr,
45 "Usage: %s [--help] [--leadin=STR] [--stdout] [--verbose] "
46 "[--version]\n"
47 " where: --help|-h print out usage message\n"
48 " --leadin=STR|-l STR every line output by --sense "
49 "should\n"
50 " be prefixed by STR\n"
51 " --stdout|-s send output to stdout (def: "
52 "stderr)\n"
53 " --verbose|-v increase verbosity\n"
54 " --version|-V print version string and exit\n\n"
55 "Test sense data handling of sg_lib. Overlaps somewhat with "
56 "tst_sg_lib\n", ME
57 );
58
59 }
60
61 int
main(int argc,char * argv[])62 main(int argc, char * argv[])
63 {
64 bool to_stdout = false;
65 int c, k, prev_len;
66 int verbose = 0;
67 const char * leadin = NULL;
68 FILE * outfp = stderr;
69 uint8_t err1[] = {0x72, 0x5, 0x24, 0x0, 0, 0, 0, 32,
70 0x2, 0x6, 0, 0, 0xc8, 0x0, 0x3, 0,
71 0, 0xa, 0x80, 0, 1, 2, 3, 4,
72 0xaa, 0xbb, 0xcc, 0xdd,
73 1, 0xa, 0, 0, 1, 2, 3, 4,
74 0xaa, 0xbb, 0xee, 0xff};
75 uint8_t err2[] = {0x72, SPC_SK_MEDIUM_ERROR, 0x11, 0xb, 0x80, 0, 0,
76 32,
77 0x2, 0x6, 0, 0, 0xc8, 0x0, 0x3, 0,
78 0, 0xa, 0x80, 0, 1, 2, 3, 4,
79 0xaa, 0xbb, 0xcc, 0xdd,
80 1, 0xa, 0, 0, 1, 2, 3, 4,
81 0xaa, 0xbb, 0xee, 0xff};
82 /* Set SDAT_OVFL */
83 uint8_t err3[] = {0x72, SPC_SK_NO_SENSE, 0x4, 0x4, 0, 0, 0, 8,
84 0x2, 0x6, 0, 0, 0xc8, 0x12, 0x34, 0};
85 uint8_t err4[] = {0x73, SPC_SK_COPY_ABORTED, 0x8, 0x4, 0, 0, 0, 22,
86 0x2, 0x6, 0, 0, 0xc8, 0x0, 0x3, 0,
87 0x3, 0x2, 0, 0x55,
88 0x5, 0x2, 0, 0x20,
89 0x85, 0x4, 0, 0x20, 0x33, 0x44};
90 /* Set Filemark, EOM, ILI and SDAT_OVFL */
91 uint8_t err5[] = {0xf1, 0, (0xf0 | SPC_SK_ILLEGAL_REQUEST), 0x11,
92 0x22, 0x33, 0x44, 0xa,
93 0x0, 0x0, 0, 0, 0x4, 0x1, 0, 0xcf, 0, 5,};
94 uint8_t err6[] = {0x72, SPC_SK_NO_SENSE, 0x4, 0x1, 0, 0, 0, 14,
95 0x9, 0xc, 1, 0, 0x11, 0x22, 0x66, 0x33,
96 0x77, 0x44, 0x88, 0x55, 0x1, 0x2};
97 uint8_t err7[] = {0xf1, 0, 0xe5, 0x11, 0x22, 0x33, 0x44, 0xa,
98 0x0, 0x0, 0x0, 0x0, 0x24, 0x1, 0xbb,
99 0xc9, 0x0, 0x2};
100 /* Vendor specific, with "valid" bit set */
101 uint8_t err8[] = {0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc,
102 0xd, 0xe, 0xf, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99,
103 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0};
104 char b[2048];
105
106 while (1) {
107 int option_index = 0;
108
109 c = getopt_long(argc, argv, "hl:svV", long_options,
110 &option_index);
111 if (c == -1)
112 break;
113
114 switch (c) {
115 case 'h':
116 case '?':
117 usage();
118 return 0;
119 case 'l':
120 leadin = optarg;
121 break;
122 case 's':
123 to_stdout = true;
124 break;
125 case 'v':
126 ++verbose;
127 break;
128 case 'V':
129 fprintf(stderr, "version: %s\n", version_str);
130 return 0;
131 default:
132 fprintf(stderr, "unrecognised switch code 0x%x ??\n", c);
133 usage();
134 return 1;
135 }
136 }
137 if (optind < argc) {
138 if (optind < argc) {
139 for (; optind < argc; ++optind)
140 fprintf(stderr, "Unexpected extra argument: %s\n",
141 argv[optind]);
142 usage();
143 return 1;
144 }
145 }
146 if (to_stdout) {
147 outfp = stdout;
148 sg_set_warnings_strm(outfp);
149 }
150
151 fprintf(outfp, "err1 test:\n");
152 sg_print_sense(leadin, err1, sizeof(err1), verbose /* raw_info */);
153 fprintf(outfp, "\n");
154 fprintf(outfp, "err2 test:\n");
155 sg_print_sense(leadin, err2, sizeof(err2), verbose);
156 fprintf(outfp, "\n");
157 fprintf(outfp, "err3 test:\n");
158 sg_print_sense(leadin, err3, sizeof(err3), verbose);
159 fprintf(outfp, "\n");
160 fprintf(outfp, "err4 test:\n");
161 sg_print_sense(leadin, err4, sizeof(err4), verbose);
162 fprintf(outfp, "\n");
163 fprintf(outfp, "err5 test: Set Filemark, EOM, ILI and SDAT_OVFL\n");
164 sg_print_sense(leadin, err5, sizeof(err5), verbose);
165 fprintf(outfp, "\n");
166 fprintf(outfp, "err6 test:\n");
167 sg_print_sense(leadin, err6, sizeof(err6), verbose);
168 fprintf(outfp, "\n");
169 fprintf(outfp, "err7 test:\n");
170 sg_print_sense(leadin, err7, sizeof(err7), verbose);
171 fprintf(outfp, "\n");
172 fprintf(outfp, "err8 test (vendor specific):\n");
173 sg_print_sense(leadin, err8, sizeof(err8), verbose);
174 fprintf(outfp, "\n");
175
176 if (verbose > 1) {
177 fprintf(outfp, "\n\nTry different output string sizes with "
178 "sg_get_sense_str(err2):\n");
179 for (k = 1, prev_len = -1; k < 512; ++k) {
180 /* snprintf(leadin, sizeof(leadin), "blen=%d", k); */
181 sg_get_sense_str(NULL, err2, sizeof(err2), 0, k, b);
182 fprintf(outfp, "%s\n", b);
183 if (prev_len == (int)strlen(b))
184 break;
185 else
186 prev_len = strlen(b);
187 }
188 }
189
190 if (verbose > 2) {
191 fprintf(outfp, "\n\nTry different output string sizes with "
192 "sg_get_sense_str(err4):\n");
193 for (k = 1, prev_len = -1; k < 512; ++k) {
194 /* snprintf(leadin, sizeof(leadin), "blen=%d", k); */
195 sg_get_sense_str(NULL, err4, sizeof(err4), 0, k, b);
196 fprintf(outfp, "%s\n", b);
197 if (prev_len == (int)strlen(b))
198 break;
199 else
200 prev_len = strlen(b);
201 }
202 }
203 return 0;
204 }
205