File: | build-scan/../src/udev/scsi_id/scsi_id.c |
Warning: | line 418, column 26 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: GPL-2.0+ */ | |||
2 | /* | |||
3 | * Copyright © IBM Corp. 2003 | |||
4 | * Copyright © SUSE Linux Products GmbH, 2006 | |||
5 | * | |||
6 | */ | |||
7 | ||||
8 | #include <ctype.h> | |||
9 | #include <errno(*__errno_location ()).h> | |||
10 | #include <fcntl.h> | |||
11 | #include <getopt.h> | |||
12 | #include <signal.h> | |||
13 | #include <stdarg.h> | |||
14 | #include <stdbool.h> | |||
15 | #include <stdio.h> | |||
16 | #include <stdlib.h> | |||
17 | #include <string.h> | |||
18 | #include <sys/stat.h> | |||
19 | #include <unistd.h> | |||
20 | ||||
21 | #include "libudev.h" | |||
22 | ||||
23 | #include "fd-util.h" | |||
24 | #include "libudev-private.h" | |||
25 | #include "scsi_id.h" | |||
26 | #include "string-util.h" | |||
27 | #include "udev-util.h" | |||
28 | ||||
29 | static const struct option options[] = { | |||
30 | { "device", required_argument1, NULL((void*)0), 'd' }, | |||
31 | { "config", required_argument1, NULL((void*)0), 'f' }, | |||
32 | { "page", required_argument1, NULL((void*)0), 'p' }, | |||
33 | { "blacklisted", no_argument0, NULL((void*)0), 'b' }, | |||
34 | { "whitelisted", no_argument0, NULL((void*)0), 'g' }, | |||
35 | { "replace-whitespace", no_argument0, NULL((void*)0), 'u' }, | |||
36 | { "sg-version", required_argument1, NULL((void*)0), 's' }, | |||
37 | { "verbose", no_argument0, NULL((void*)0), 'v' }, | |||
38 | { "version", no_argument0, NULL((void*)0), 'V' }, /* don't advertise -V */ | |||
39 | { "export", no_argument0, NULL((void*)0), 'x' }, | |||
40 | { "help", no_argument0, NULL((void*)0), 'h' }, | |||
41 | {} | |||
42 | }; | |||
43 | ||||
44 | static bool_Bool all_good = false0; | |||
45 | static bool_Bool dev_specified = false0; | |||
46 | static char config_file[MAX_PATH_LEN512] = "/etc/scsi_id.config"; | |||
47 | static enum page_code default_page_code = PAGE_UNSPECIFIED; | |||
48 | static int sg_version = 4; | |||
49 | static bool_Bool reformat_serial = false0; | |||
50 | static bool_Bool export = false0; | |||
51 | static char vendor_str[64]; | |||
52 | static char model_str[64]; | |||
53 | static char vendor_enc_str[256]; | |||
54 | static char model_enc_str[256]; | |||
55 | static char revision_str[16]; | |||
56 | static char type_str[16]; | |||
57 | ||||
58 | static void set_type(const char *from, char *to, size_t len) | |||
59 | { | |||
60 | int type_num; | |||
61 | char *eptr; | |||
62 | const char *type = "generic"; | |||
63 | ||||
64 | type_num = strtoul(from, &eptr, 0); | |||
65 | if (eptr != from) { | |||
66 | switch (type_num) { | |||
67 | case 0: | |||
68 | type = "disk"; | |||
69 | break; | |||
70 | case 1: | |||
71 | type = "tape"; | |||
72 | break; | |||
73 | case 4: | |||
74 | type = "optical"; | |||
75 | break; | |||
76 | case 5: | |||
77 | type = "cd"; | |||
78 | break; | |||
79 | case 7: | |||
80 | type = "optical"; | |||
81 | break; | |||
82 | case 0xe: | |||
83 | type = "disk"; | |||
84 | break; | |||
85 | case 0xf: | |||
86 | type = "optical"; | |||
87 | break; | |||
88 | default: | |||
89 | break; | |||
90 | } | |||
91 | } | |||
92 | strscpy(to, len, type); | |||
93 | } | |||
94 | ||||
95 | /* | |||
96 | * get_value: | |||
97 | * | |||
98 | * buf points to an '=' followed by a quoted string ("foo") or a string ending | |||
99 | * with a space or ','. | |||
100 | * | |||
101 | * Return a pointer to the NUL terminated string, returns NULL if no | |||
102 | * matches. | |||
103 | */ | |||
104 | static char *get_value(char **buffer) | |||
105 | { | |||
106 | static const char *quote_string = "\"\n"; | |||
107 | static const char *comma_string = ",\n"; | |||
108 | char *val; | |||
109 | const char *end; | |||
110 | ||||
111 | if (**buffer == '"') { | |||
112 | /* | |||
113 | * skip leading quote, terminate when quote seen | |||
114 | */ | |||
115 | (*buffer)++; | |||
116 | end = quote_string; | |||
117 | } else { | |||
118 | end = comma_string; | |||
119 | } | |||
120 | val = strsep(buffer, end); | |||
121 | if (val && end == quote_string) | |||
122 | /* | |||
123 | * skip trailing quote | |||
124 | */ | |||
125 | (*buffer)++; | |||
126 | ||||
127 | while (isspace(**buffer)((*__ctype_b_loc ())[(int) ((**buffer))] & (unsigned short int) _ISspace)) | |||
128 | (*buffer)++; | |||
129 | ||||
130 | return val; | |||
131 | } | |||
132 | ||||
133 | static int argc_count(char *opts) | |||
134 | { | |||
135 | int i = 0; | |||
136 | while (*opts != '\0') | |||
137 | if (*opts++ == ' ') | |||
138 | i++; | |||
139 | return i; | |||
140 | } | |||
141 | ||||
142 | /* | |||
143 | * get_file_options: | |||
144 | * | |||
145 | * If vendor == NULL, find a line in the config file with only "OPTIONS="; | |||
146 | * if vendor and model are set find the first OPTIONS line in the config | |||
147 | * file that matches. Set argc and argv to match the OPTIONS string. | |||
148 | * | |||
149 | * vendor and model can end in '\n'. | |||
150 | */ | |||
151 | static int get_file_options(struct udev *udev, | |||
152 | const char *vendor, const char *model, | |||
153 | int *argc, char ***newargv) | |||
154 | { | |||
155 | _cleanup_free___attribute__((cleanup(freep))) char *buffer = NULL((void*)0); | |||
156 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f; | |||
157 | char *buf; | |||
158 | char *str1; | |||
159 | char *vendor_in, *model_in, *options_in; /* read in from file */ | |||
160 | int lineno; | |||
161 | int c; | |||
162 | int retval = 0; | |||
163 | ||||
164 | f = fopen(config_file, "re"); | |||
165 | if (f == NULL((void*)0)) { | |||
166 | if (errno(*__errno_location ()) == ENOENT2) | |||
167 | return 1; | |||
168 | else { | |||
169 | log_error_errno(errno, "can't open %s: %m", config_file)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= ( (_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/udev/scsi_id/scsi_id.c", 169, __func__ , "can't open %s: %m", config_file) : -abs(_e); }); | |||
170 | return -1; | |||
171 | } | |||
172 | } | |||
173 | ||||
174 | /* | |||
175 | * Allocate a buffer rather than put it on the stack so we can | |||
176 | * keep it around to parse any options (any allocated newargv | |||
177 | * points into this buffer for its strings). | |||
178 | */ | |||
179 | buffer = malloc(MAX_BUFFER_LEN256); | |||
180 | if (!buffer) | |||
181 | return log_oom()log_oom_internal(LOG_REALM_UDEV, "../src/udev/scsi_id/scsi_id.c" , 181, __func__); | |||
182 | ||||
183 | *newargv = NULL((void*)0); | |||
184 | lineno = 0; | |||
185 | for (;;) { | |||
186 | vendor_in = model_in = options_in = NULL((void*)0); | |||
187 | ||||
188 | buf = fgets(buffer, MAX_BUFFER_LEN256, f); | |||
189 | if (buf == NULL((void*)0)) | |||
190 | break; | |||
191 | lineno++; | |||
192 | if (buf[strlen(buffer) - 1] != '\n') { | |||
193 | log_error("Config file line %d too long", lineno)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/scsi_id/scsi_id.c", 193, __func__, "Config file line %d too long" , lineno) : -abs(_e); }); | |||
194 | break; | |||
195 | } | |||
196 | ||||
197 | while (isspace(*buf)((*__ctype_b_loc ())[(int) ((*buf))] & (unsigned short int ) _ISspace)) | |||
198 | buf++; | |||
199 | ||||
200 | /* blank or all whitespace line */ | |||
201 | if (*buf == '\0') | |||
202 | continue; | |||
203 | ||||
204 | /* comment line */ | |||
205 | if (*buf == '#') | |||
206 | continue; | |||
207 | ||||
208 | str1 = strsep(&buf, "="); | |||
209 | if (str1 && strcaseeq(str1, "VENDOR")(strcasecmp((str1),("VENDOR")) == 0)) { | |||
210 | str1 = get_value(&buf); | |||
211 | if (!str1) { | |||
212 | retval = log_oom()log_oom_internal(LOG_REALM_UDEV, "../src/udev/scsi_id/scsi_id.c" , 212, __func__); | |||
213 | break; | |||
214 | } | |||
215 | vendor_in = str1; | |||
216 | ||||
217 | str1 = strsep(&buf, "="); | |||
218 | if (str1 && strcaseeq(str1, "MODEL")(strcasecmp((str1),("MODEL")) == 0)) { | |||
219 | str1 = get_value(&buf); | |||
220 | if (!str1) { | |||
221 | retval = log_oom()log_oom_internal(LOG_REALM_UDEV, "../src/udev/scsi_id/scsi_id.c" , 221, __func__); | |||
222 | break; | |||
223 | } | |||
224 | model_in = str1; | |||
225 | str1 = strsep(&buf, "="); | |||
226 | } | |||
227 | } | |||
228 | ||||
229 | if (str1 && strcaseeq(str1, "OPTIONS")(strcasecmp((str1),("OPTIONS")) == 0)) { | |||
230 | str1 = get_value(&buf); | |||
231 | if (!str1) { | |||
232 | retval = log_oom()log_oom_internal(LOG_REALM_UDEV, "../src/udev/scsi_id/scsi_id.c" , 232, __func__); | |||
233 | break; | |||
234 | } | |||
235 | options_in = str1; | |||
236 | } | |||
237 | ||||
238 | /* | |||
239 | * Only allow: [vendor=foo[,model=bar]]options=stuff | |||
240 | */ | |||
241 | if (!options_in || (!vendor_in && model_in)) { | |||
242 | log_error("Error parsing config file line %d '%s'", lineno, buffer)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/scsi_id/scsi_id.c", 242, __func__, "Error parsing config file line %d '%s'" , lineno, buffer) : -abs(_e); }); | |||
243 | retval = -1; | |||
244 | break; | |||
245 | } | |||
246 | if (vendor == NULL((void*)0)) { | |||
247 | if (vendor_in == NULL((void*)0)) | |||
248 | break; | |||
249 | } else if (vendor_in && | |||
250 | startswith(vendor, vendor_in) && | |||
251 | (!model_in || startswith(model, model_in))) { | |||
252 | /* | |||
253 | * Matched vendor and optionally model. | |||
254 | * | |||
255 | * Note: a short vendor_in or model_in can | |||
256 | * give a partial match (that is FOO | |||
257 | * matches FOOBAR). | |||
258 | */ | |||
259 | break; | |||
260 | } | |||
261 | } | |||
262 | ||||
263 | if (retval == 0) { | |||
264 | if (vendor_in != NULL((void*)0) || model_in != NULL((void*)0) || | |||
265 | options_in != NULL((void*)0)) { | |||
266 | /* | |||
267 | * Something matched. Allocate newargv, and store | |||
268 | * values found in options_in. | |||
269 | */ | |||
270 | strcpy(buffer, options_in); | |||
271 | c = argc_count(buffer) + 2; | |||
272 | *newargv = calloc(c, sizeof(**newargv)); | |||
273 | if (!*newargv) | |||
274 | retval = log_oom()log_oom_internal(LOG_REALM_UDEV, "../src/udev/scsi_id/scsi_id.c" , 274, __func__); | |||
275 | else { | |||
276 | *argc = c; | |||
277 | c = 0; | |||
278 | /* | |||
279 | * argv[0] at 0 is skipped by getopt, but | |||
280 | * store the buffer address there for | |||
281 | * later freeing | |||
282 | */ | |||
283 | (*newargv)[c] = buffer; | |||
284 | for (c = 1; c < *argc; c++) | |||
285 | (*newargv)[c] = strsep(&buffer, " \t"); | |||
286 | buffer = NULL((void*)0); | |||
287 | } | |||
288 | } else { | |||
289 | /* No matches */ | |||
290 | retval = 1; | |||
291 | } | |||
292 | } | |||
293 | return retval; | |||
294 | } | |||
295 | ||||
296 | static void help(void) { | |||
297 | printf("Usage: %s [OPTION...] DEVICE\n\n" | |||
298 | "SCSI device identification.\n\n" | |||
299 | " -h --help Print this message\n" | |||
300 | " --version Print version of the program\n\n" | |||
301 | " -d --device= Device node for SG_IO commands\n" | |||
302 | " -f --config= Location of config file\n" | |||
303 | " -p --page=0x80|0x83|pre-spc3-83 SCSI page (0x80, 0x83, pre-spc3-83)\n" | |||
304 | " -s --sg-version=3|4 Use SGv3 or SGv4\n" | |||
305 | " -b --blacklisted Treat device as blacklisted\n" | |||
306 | " -g --whitelisted Treat device as whitelisted\n" | |||
307 | " -u --replace-whitespace Replace all whitespace by underscores\n" | |||
308 | " -v --verbose Verbose logging\n" | |||
309 | " -x --export Print values as environment keys\n" | |||
310 | , program_invocation_short_name); | |||
311 | ||||
312 | } | |||
313 | ||||
314 | static int set_options(struct udev *udev, | |||
315 | int argc, char **argv, | |||
316 | char *maj_min_dev) | |||
317 | { | |||
318 | int option; | |||
319 | ||||
320 | /* | |||
321 | * optind is a global extern used by getopt. Since we can call | |||
322 | * set_options twice (once for command line, and once for config | |||
323 | * file) we have to reset this back to 1. | |||
324 | */ | |||
325 | optind = 1; | |||
326 | while ((option = getopt_long(argc, argv, "d:f:gp:uvVxhbs:", options, NULL((void*)0))) >= 0) | |||
327 | switch (option) { | |||
328 | case 'b': | |||
329 | all_good = false0; | |||
330 | break; | |||
331 | ||||
332 | case 'd': | |||
333 | dev_specified = true1; | |||
334 | strscpy(maj_min_dev, MAX_PATH_LEN512, optarg); | |||
335 | break; | |||
336 | ||||
337 | case 'f': | |||
338 | strscpy(config_file, MAX_PATH_LEN512, optarg); | |||
339 | break; | |||
340 | ||||
341 | case 'g': | |||
342 | all_good = true1; | |||
343 | break; | |||
344 | ||||
345 | case 'h': | |||
346 | help(); | |||
347 | exit(EXIT_SUCCESS0); | |||
348 | ||||
349 | case 'p': | |||
350 | if (streq(optarg, "0x80")(strcmp((optarg),("0x80")) == 0)) | |||
351 | default_page_code = PAGE_80; | |||
352 | else if (streq(optarg, "0x83")(strcmp((optarg),("0x83")) == 0)) | |||
353 | default_page_code = PAGE_83; | |||
354 | else if (streq(optarg, "pre-spc3-83")(strcmp((optarg),("pre-spc3-83")) == 0)) | |||
355 | default_page_code = PAGE_83_PRE_SPC3; | |||
356 | else { | |||
357 | log_error("Unknown page code '%s'", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/scsi_id/scsi_id.c", 357, __func__, "Unknown page code '%s'" , optarg) : -abs(_e); }); | |||
358 | return -1; | |||
359 | } | |||
360 | break; | |||
361 | ||||
362 | case 's': | |||
363 | sg_version = atoi(optarg); | |||
364 | if (sg_version < 3 || sg_version > 4) { | |||
365 | log_error("Unknown SG version '%s'", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/scsi_id/scsi_id.c", 365, __func__, "Unknown SG version '%s'" , optarg) : -abs(_e); }); | |||
366 | return -1; | |||
367 | } | |||
368 | break; | |||
369 | ||||
370 | case 'u': | |||
371 | reformat_serial = true1; | |||
372 | break; | |||
373 | ||||
374 | case 'v': | |||
375 | log_set_target(LOG_TARGET_CONSOLE); | |||
376 | log_set_max_level(LOG_DEBUG)log_set_max_level_realm(LOG_REALM_UDEV, (7)); | |||
377 | log_open(); | |||
378 | break; | |||
379 | ||||
380 | case 'V': | |||
381 | printf("%s\n", PACKAGE_VERSION"239"); | |||
382 | exit(EXIT_SUCCESS0); | |||
383 | ||||
384 | case 'x': | |||
385 | export = true1; | |||
386 | break; | |||
387 | ||||
388 | case '?': | |||
389 | return -1; | |||
390 | ||||
391 | default: | |||
392 | assert_not_reached("Unknown option")do { log_assert_failed_unreachable_realm(LOG_REALM_UDEV, ("Unknown option" ), "../src/udev/scsi_id/scsi_id.c", 392, __PRETTY_FUNCTION__) ; } while (0); | |||
393 | } | |||
394 | ||||
395 | if (optind < argc && !dev_specified) { | |||
396 | dev_specified = true1; | |||
397 | strscpy(maj_min_dev, MAX_PATH_LEN512, argv[optind]); | |||
398 | } | |||
399 | ||||
400 | return 0; | |||
401 | } | |||
402 | ||||
403 | static int per_dev_options(struct udev *udev, | |||
404 | struct scsi_id_device *dev_scsi, int *good_bad, int *page_code) | |||
405 | { | |||
406 | int retval; | |||
407 | int newargc; | |||
408 | char **newargv = NULL((void*)0); | |||
409 | int option; | |||
410 | ||||
411 | *good_bad = all_good; | |||
412 | *page_code = default_page_code; | |||
413 | ||||
414 | retval = get_file_options(udev, vendor_str, model_str, &newargc, &newargv); | |||
415 | ||||
416 | optind = 1; /* reset this global extern */ | |||
417 | while (retval == 0) { | |||
418 | option = getopt_long(newargc, newargv, "bgp:", options, NULL((void*)0)); | |||
| ||||
419 | if (option == -1) | |||
420 | break; | |||
421 | ||||
422 | switch (option) { | |||
423 | case 'b': | |||
424 | *good_bad = 0; | |||
425 | break; | |||
426 | ||||
427 | case 'g': | |||
428 | *good_bad = 1; | |||
429 | break; | |||
430 | ||||
431 | case 'p': | |||
432 | if (streq(optarg, "0x80")(strcmp((optarg),("0x80")) == 0)) { | |||
433 | *page_code = PAGE_80; | |||
434 | } else if (streq(optarg, "0x83")(strcmp((optarg),("0x83")) == 0)) { | |||
435 | *page_code = PAGE_83; | |||
436 | } else if (streq(optarg, "pre-spc3-83")(strcmp((optarg),("pre-spc3-83")) == 0)) { | |||
437 | *page_code = PAGE_83_PRE_SPC3; | |||
438 | } else { | |||
439 | log_error("Unknown page code '%s'", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/scsi_id/scsi_id.c", 439, __func__, "Unknown page code '%s'" , optarg) : -abs(_e); }); | |||
440 | retval = -1; | |||
441 | } | |||
442 | break; | |||
443 | ||||
444 | default: | |||
445 | log_error("Unknown or bad option '%c' (0x%x)", option, option)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/scsi_id/scsi_id.c", 445, __func__, "Unknown or bad option '%c' (0x%x)" , option, option) : -abs(_e); }); | |||
446 | retval = -1; | |||
447 | break; | |||
448 | } | |||
449 | } | |||
450 | ||||
451 | if (newargv) { | |||
452 | free(newargv[0]); | |||
453 | free(newargv); | |||
454 | } | |||
455 | return retval; | |||
456 | } | |||
457 | ||||
458 | static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, const char *path) | |||
459 | { | |||
460 | int retval; | |||
461 | ||||
462 | dev_scsi->use_sg = sg_version; | |||
463 | ||||
464 | retval = scsi_std_inquiry(udev, dev_scsi, path); | |||
465 | if (retval) | |||
466 | return retval; | |||
467 | ||||
468 | udev_util_encode_string(dev_scsi->vendor, vendor_enc_str, sizeof(vendor_enc_str)); | |||
469 | udev_util_encode_string(dev_scsi->model, model_enc_str, sizeof(model_enc_str)); | |||
470 | ||||
471 | util_replace_whitespace(dev_scsi->vendor, vendor_str, sizeof(vendor_str)); | |||
472 | util_replace_chars(vendor_str, NULL((void*)0)); | |||
473 | util_replace_whitespace(dev_scsi->model, model_str, sizeof(model_str)); | |||
474 | util_replace_chars(model_str, NULL((void*)0)); | |||
475 | set_type(dev_scsi->type, type_str, sizeof(type_str)); | |||
476 | util_replace_whitespace(dev_scsi->revision, revision_str, sizeof(revision_str)); | |||
477 | util_replace_chars(revision_str, NULL((void*)0)); | |||
478 | return 0; | |||
479 | } | |||
480 | ||||
481 | /* | |||
482 | * scsi_id: try to get an id, if one is found, printf it to stdout. | |||
483 | * returns a value passed to exit() - 0 if printed an id, else 1. | |||
484 | */ | |||
485 | static int scsi_id(struct udev *udev, char *maj_min_dev) | |||
486 | { | |||
487 | struct scsi_id_device dev_scsi = {}; | |||
488 | int good_dev; | |||
489 | int page_code; | |||
490 | int retval = 0; | |||
491 | ||||
492 | if (set_inq_values(udev, &dev_scsi, maj_min_dev) < 0) { | |||
493 | retval = 1; | |||
494 | goto out; | |||
495 | } | |||
496 | ||||
497 | /* get per device (vendor + model) options from the config file */ | |||
498 | per_dev_options(udev, &dev_scsi, &good_dev, &page_code); | |||
499 | if (!good_dev) { | |||
500 | retval = 1; | |||
501 | goto out; | |||
502 | } | |||
503 | ||||
504 | /* read serial number from mode pages (no values for optical drives) */ | |||
505 | scsi_get_serial(udev, &dev_scsi, maj_min_dev, page_code, MAX_SERIAL_LEN256); | |||
506 | ||||
507 | if (export) { | |||
508 | char serial_str[MAX_SERIAL_LEN256]; | |||
509 | ||||
510 | printf("ID_SCSI=1\n"); | |||
511 | printf("ID_VENDOR=%s\n", vendor_str); | |||
512 | printf("ID_VENDOR_ENC=%s\n", vendor_enc_str); | |||
513 | printf("ID_MODEL=%s\n", model_str); | |||
514 | printf("ID_MODEL_ENC=%s\n", model_enc_str); | |||
515 | printf("ID_REVISION=%s\n", revision_str); | |||
516 | printf("ID_TYPE=%s\n", type_str); | |||
517 | if (dev_scsi.serial[0] != '\0') { | |||
518 | util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)); | |||
519 | util_replace_chars(serial_str, NULL((void*)0)); | |||
520 | printf("ID_SERIAL=%s\n", serial_str); | |||
521 | util_replace_whitespace(dev_scsi.serial_short, serial_str, sizeof(serial_str)); | |||
522 | util_replace_chars(serial_str, NULL((void*)0)); | |||
523 | printf("ID_SERIAL_SHORT=%s\n", serial_str); | |||
524 | } | |||
525 | if (dev_scsi.wwn[0] != '\0') { | |||
526 | printf("ID_WWN=0x%s\n", dev_scsi.wwn); | |||
527 | if (dev_scsi.wwn_vendor_extension[0] != '\0') { | |||
528 | printf("ID_WWN_VENDOR_EXTENSION=0x%s\n", dev_scsi.wwn_vendor_extension); | |||
529 | printf("ID_WWN_WITH_EXTENSION=0x%s%s\n", dev_scsi.wwn, dev_scsi.wwn_vendor_extension); | |||
530 | } else | |||
531 | printf("ID_WWN_WITH_EXTENSION=0x%s\n", dev_scsi.wwn); | |||
532 | } | |||
533 | if (dev_scsi.tgpt_group[0] != '\0') | |||
534 | printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group); | |||
535 | if (dev_scsi.unit_serial_number[0] != '\0') | |||
536 | printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number); | |||
537 | goto out; | |||
538 | } | |||
539 | ||||
540 | if (dev_scsi.serial[0] == '\0') { | |||
541 | retval = 1; | |||
542 | goto out; | |||
543 | } | |||
544 | ||||
545 | if (reformat_serial) { | |||
546 | char serial_str[MAX_SERIAL_LEN256]; | |||
547 | ||||
548 | util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)); | |||
549 | util_replace_chars(serial_str, NULL((void*)0)); | |||
550 | printf("%s\n", serial_str); | |||
551 | goto out; | |||
552 | } | |||
553 | ||||
554 | printf("%s\n", dev_scsi.serial); | |||
555 | out: | |||
556 | return retval; | |||
557 | } | |||
558 | ||||
559 | int main(int argc, char **argv) { | |||
560 | _cleanup_(udev_unrefp)__attribute__((cleanup(udev_unrefp))) struct udev *udev; | |||
561 | int retval = 0; | |||
562 | char maj_min_dev[MAX_PATH_LEN512]; | |||
563 | int newargc; | |||
564 | char **newargv = NULL((void*)0); | |||
565 | ||||
566 | log_set_target(LOG_TARGET_AUTO); | |||
567 | udev_parse_config(); | |||
568 | log_parse_environment()log_parse_environment_realm(LOG_REALM_UDEV); | |||
569 | log_open(); | |||
570 | ||||
571 | udev = udev_new(); | |||
572 | if (udev == NULL((void*)0)) | |||
| ||||
573 | goto exit; | |||
574 | ||||
575 | /* | |||
576 | * Get config file options. | |||
577 | */ | |||
578 | retval = get_file_options(udev, NULL((void*)0), NULL((void*)0), &newargc, &newargv); | |||
579 | if (retval < 0) { | |||
580 | retval = 1; | |||
581 | goto exit; | |||
582 | } | |||
583 | if (retval == 0) { | |||
584 | assert(newargv)do { if ((__builtin_expect(!!(!(newargv)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("newargv"), "../src/udev/scsi_id/scsi_id.c" , 584, __PRETTY_FUNCTION__); } while (0); | |||
585 | ||||
586 | if (set_options(udev, newargc, newargv, maj_min_dev) < 0) { | |||
587 | retval = 2; | |||
588 | goto exit; | |||
589 | } | |||
590 | } | |||
591 | ||||
592 | /* | |||
593 | * Get command line options (overriding any config file settings). | |||
594 | */ | |||
595 | if (set_options(udev, argc, argv, maj_min_dev) < 0) | |||
596 | exit(EXIT_FAILURE1); | |||
597 | ||||
598 | if (!dev_specified) { | |||
599 | log_error("No device specified.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/scsi_id/scsi_id.c", 599, __func__, "No device specified." ) : -abs(_e); }); | |||
600 | retval = 1; | |||
601 | goto exit; | |||
602 | } | |||
603 | ||||
604 | retval = scsi_id(udev, maj_min_dev); | |||
605 | ||||
606 | exit: | |||
607 | if (newargv) { | |||
608 | free(newargv[0]); | |||
609 | free(newargv); | |||
610 | } | |||
611 | log_close(); | |||
612 | return retval; | |||
613 | } |