Bug Summary

File:src/sbin/scsi/scsi.c
Warning:line 776, column 3
Value stored to 'mode_pars' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name scsi.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/scsi/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/scsi/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/scsi/scsi.c
1/* $OpenBSD: scsi.c,v 1.31 2021/06/22 14:51:29 jmc Exp $ */
2/* $FreeBSD: scsi.c,v 1.11 1996/04/06 11:00:28 joerg Exp $ */
3
4/*
5 * Written By Julian ELischer
6 * Copyright julian Elischer 1993.
7 * Permission is granted to use or redistribute this file in any way as long
8 * as this notice remains. Julian Elischer does not guarantee that this file
9 * is totally correct for any given task and users of this file must
10 * accept responsibility for any damage that occurs from the application of this
11 * file.
12 *
13 * (julian@tfs.com julian@dialix.oz.au)
14 *
15 * User SCSI hooks added by Peter Dufault:
16 *
17 * Copyright (c) 1994 HD Associates
18 * (contact: dufault@hda.com)
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. The name of HD Associates
30 * may not be used to endorse or promote products derived from this software
31 * without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 */
45
46#include <sys/types.h>
47#include <sys/wait.h>
48
49#include <fcntl.h>
50#include <stdio.h>
51#include <string.h>
52#include <stdlib.h>
53#include <unistd.h>
54#include <errno(*__errno()).h>
55#include <sys/scsiio.h>
56#include <ctype.h>
57#include <signal.h>
58#include <err.h>
59#include <paths.h>
60
61#include "libscsi.h"
62
63int fd;
64int debuglevel;
65int debugflag;
66int commandflag;
67int verbose = 0;
68
69int modeflag;
70int editflag;
71int modepage = 0; /* Read this mode page */
72int pagectl = 0; /* Mode sense page control */
73int seconds = 2;
74
75void procargs(int *argc_p, char ***argv_p);
76int iget(void *hook, char *name);
77char *cget(void *hook, char *name);
78void arg_put(void *hook, int letter, void *arg, int count, char *name);
79void mode_sense(int fd, u_char *data, int len, int pc, int page);
80void mode_select(int fd, u_char *data, int len, int perm);
81int editit(const char *pathname);
82
83static void
84usage(void)
85{
86 fprintf(stderr(&__sF[2]),
87"usage: scsi -f device -d debug_level\n"
88" scsi -f device -m page [-e] [-P pc]\n"
89" scsi -f device [-v] [-s seconds] -c cmd_fmt [arg ...]"
90" -o count out_fmt\n"
91" [arg ...] -i count in_fmt [arg ...]\n");
92
93 exit (1);
94}
95
96void
97procargs(int *argc_p, char ***argv_p)
98{
99 int argc = *argc_p;
100 char **argv = *argv_p;
101 int fflag, ch;
102
103 fflag = 0;
104 commandflag = 0;
105 debugflag = 0;
106 while ((ch = getopt(argc, argv, "cef:d:m:P:s:v")) != -1) {
107 switch (ch) {
108 case 'c':
109 commandflag = 1;
110 break;
111 case 'e':
112 editflag = 1;
113 break;
114 case 'f':
115 if ((fd = scsi_open(optarg, O_RDWR0x0002)) < 0)
116 err(1, "unable to open device %s", optarg);
117 fflag = 1;
118 break;
119 case 'd':
120 debuglevel = strtol(optarg, 0, 0);
121 debugflag = 1;
122 break;
123 case 'm':
124 modeflag = 1;
125 modepage = strtol(optarg, 0, 0);
126 break;
127 case 'P':
128 pagectl = strtol(optarg, 0, 0);
129 break;
130 case 's':
131 seconds = strtol(optarg, 0, 0);
132 break;
133 case 'v':
134 verbose = 1;
135 break;
136 case '?':
137 default:
138 usage();
139 }
140 }
141 *argc_p = argc - optind;
142 *argv_p = argv + optind;
143
144 if (!fflag) usage();
145}
146
147/* get_hook: Structure for evaluating args in a callback.
148 */
149struct get_hook
150{
151 int argc;
152 char **argv;
153 int got;
154};
155
156/* iget: Integer argument callback
157 */
158int
159iget(void *hook, char *name)
160{
161 struct get_hook *h = (struct get_hook *)hook;
162 int arg;
163
164 if (h->got >= h->argc)
165 {
166 fprintf(stderr(&__sF[2]), "Expecting an integer argument.\n");
167 usage();
168 }
169 arg = strtol(h->argv[h->got], 0, 0);
170 h->got++;
171
172 if (verbose && name && *name)
173 printf("%s: %d\n", name, arg);
174
175 return arg;
176}
177
178/* cget: char * argument callback
179 */
180char *
181cget(void *hook, char *name)
182{
183 struct get_hook *h = (struct get_hook *)hook;
184 char *arg;
185
186 if (h->got >= h->argc)
187 {
188 fprintf(stderr(&__sF[2]), "Expecting a character pointer argument.\n");
189 usage();
190 }
191 arg = h->argv[h->got];
192 h->got++;
193
194 if (verbose && name)
195 printf("cget: %s: %s", name, arg);
196
197 return arg;
198}
199
200/* arg_put: "put argument" callback
201 */
202void arg_put(void *hook, int letter, void *arg, int count, char *name)
203{
204 if (verbose && name && *name)
205 printf("%s: ", name);
206
207 switch(letter)
208 {
209 case 'i':
210 case 'b':
211 printf("%ld ", (long)arg);
212 break;
213
214 case 'c':
215 case 'z':
216 {
217 char *p = malloc(count + 1);
218 if (p == NULL((void *)0))
219 err(1, NULL((void *)0));
220
221 p[count] = 0;
222 strncpy(p, (char *)arg, count);
223 if (letter == 'z')
224 {
225 int i;
226 for (i = count - 1; i >= 0; i--)
227 if (p[i] == ' ')
228 p[i] = 0;
229 else
230 break;
231 }
232 printf("%s ", p);
233 free(p);
234 }
235
236 break;
237
238 default:
239 printf("Unknown format letter: '%c'\n", letter);
240 }
241 if (verbose)
242 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
243}
244
245/* data_phase: SCSI bus data phase: DATA IN, DATA OUT, or no data transfer.
246 */
247enum data_phase {none = 0, in, out};
248
249/* do_cmd: Send a command to a SCSI device
250 */
251static void
252do_cmd(int fd, char *fmt, int argc, char **argv)
253{
254 struct get_hook h;
255 scsireq_t *scsireq = scsireq_new();
256 enum data_phase data_phase;
257 int count, amount;
258 char *data_fmt, *bp;
259
260 h.argc = argc;
261 h.argv = argv;
262 h.got = 0;
263
264 scsireq_reset(scsireq);
265
266 scsireq_build_visit(scsireq, 0, 0, 0, fmt, iget, (void *)&h);
267
268 /* Three choices here:
269 * 1. We've used up all the args and have no data phase.
270 * 2. We have input data ("-i")
271 * 3. We have output data ("-o")
272 */
273
274 if (h.got >= h.argc)
275 {
276 data_phase = none;
277 count = scsireq->datalen = 0;
278 }
279 else
280 {
281 char *flag = cget(&h, 0);
282
283 if (strcmp(flag, "-o") == 0)
284 {
285 data_phase = out;
286 scsireq->flags = SCCMD_WRITE0x00000002;
287 }
288 else if (strcmp(flag, "-i") == 0)
289 {
290 data_phase = in;
291 scsireq->flags = SCCMD_READ0x00000001;
292 }
293 else
294 {
295 fprintf(stderr(&__sF[2]),
296 "Need either \"-i\" or \"-o\" for data phase; not \"%s\".\n", flag);
297 usage();
298 }
299
300 count = scsireq->datalen = iget(&h, 0);
301 if (count) {
302 data_fmt = cget(&h, 0);
303
304 scsireq->databuf = malloc(count);
305 if (scsireq->databuf == NULL((void *)0))
306 err(1, NULL((void *)0));
307
308 if (data_phase == out) {
309 if (strcmp(data_fmt, "-") == 0) {
310 bp = (char *)scsireq->databuf;
311 while (count > 0 &&
312 (amount = read(STDIN_FILENO0,
313 bp, count)) > 0) {
314 count -= amount;
315 bp += amount;
316 }
317 if (amount == -1)
318 err(1, "read");
319 else if (amount == 0) {
320 /* early EOF */
321 fprintf(stderr(&__sF[2]),
322 "Warning: only read %lu bytes out of %lu.\n",
323 scsireq->datalen - (u_long)count,
324 scsireq->datalen);
325 scsireq->datalen -= (u_long)count;
326 }
327 }
328 else
329 {
330 bzero(scsireq->databuf, count);
331 scsireq_encode_visit(scsireq, data_fmt, iget, (void *)&h);
332 }
333 }
334 }
335 }
336
337
338 scsireq->timeout = seconds * 1000;
339
340 if (scsireq_enter(fd, scsireq) == -1)
341 {
342 scsi_debug(stderr(&__sF[2]), -1, scsireq);
343 exit(1);
344 }
345
346 if (SCSIREQ_ERROR(scsireq)(scsireq->senselen_used || scsireq->status || scsireq->
retsts || scsireq->error)
)
347 scsi_debug(stderr(&__sF[2]), 0, scsireq);
348
349 if (count && data_phase == in)
350 {
351 if (strcmp(data_fmt, "-") == 0) /* stdout */
352 {
353 bp = (char *)scsireq->databuf;
354 while (count > 0 && (amount = write(STDOUT_FILENO1, bp, count)) > 0)
355 {
356 count -= amount;
357 bp += amount;
358 }
359 if (amount < 0)
360 err(1, "write");
361 else if (amount == 0)
362 fprintf(stderr(&__sF[2]), "Warning: wrote only %lu bytes out of %lu.\n",
363 scsireq->datalen - count,
364 scsireq->datalen);
365
366 }
367 else
368 {
369 scsireq_decode_visit(scsireq, data_fmt, arg_put, 0);
370 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
371 }
372 }
373}
374
375void mode_sense(int fd, u_char *data, int len, int pc, int page)
376{
377 scsireq_t *scsireq;
378
379 bzero(data, len);
380
381 scsireq = scsireq_new();
382
383 if (scsireq_enter(fd, scsireq_build(scsireq,
384 len, data, SCCMD_READ0x00000001,
385 "1A 0 v:2 {Page Control} v:6 {Page Code} 0 v:i1 {Allocation Length} 0",
386 pc, page, len)) == -1) /* Mode sense */
387 {
388 scsi_debug(stderr(&__sF[2]), -1, scsireq);
389 exit(1);
390 }
391
392 if (SCSIREQ_ERROR(scsireq)(scsireq->senselen_used || scsireq->status || scsireq->
retsts || scsireq->error)
)
393 {
394 scsi_debug(stderr(&__sF[2]), 0, scsireq);
395 exit(1);
396 }
397
398 free(scsireq);
399}
400
401void mode_select(int fd, u_char *data, int len, int perm)
402{
403 scsireq_t *scsireq;
404
405 scsireq = scsireq_new();
406
407 if (scsireq_enter(fd, scsireq_build(scsireq,
408 len, data, SCCMD_WRITE0x00000002,
409 "15 0:7 v:1 {SP} 0 0 v:i1 {Allocation Length} 0", perm, len)) == -1) /* Mode select */
410 {
411 scsi_debug(stderr(&__sF[2]), -1, scsireq);
412 exit(1);
413 }
414
415 if (SCSIREQ_ERROR(scsireq)(scsireq->senselen_used || scsireq->status || scsireq->
retsts || scsireq->error)
)
416 {
417 scsi_debug(stderr(&__sF[2]), 0, scsireq);
418 exit(1);
419 }
420
421 free(scsireq);
422}
423
424
425#define START_ENTRY'{' '{'
426#define END_ENTRY'}' '}'
427
428static void
429skipwhite(FILE *f)
430{
431 int c;
432
433skip_again:
434
435 while (isspace(c = getc(f)(!__isthreaded ? (--(f)->_r < 0 ? __srget(f) : (int)(*(
f)->_p++)) : (getc)(f))
))
436 continue;
437
438 if (c == '#') {
439 while ((c = getc(f)(!__isthreaded ? (--(f)->_r < 0 ? __srget(f) : (int)(*(
f)->_p++)) : (getc)(f))
) != '\n' && c != EOF(-1))
440 continue;
441 goto skip_again;
442 }
443
444 ungetc(c, f);
445}
446
447/* mode_lookup: Lookup a format description for a given page.
448 */
449char *mode_db = "/usr/share/misc/scsi_modes";
450static char *mode_lookup(int page)
451{
452 char *new_db;
453 FILE *modes;
454 int match, next, found, c;
455 static char fmt[1024]; /* XXX This should be with strealloc */
456 int page_desc;
457 new_db = getenv("SCSI_MODES");
458
459 if (new_db)
460 mode_db = new_db;
461
462 modes = fopen(mode_db, "r");
463 if (modes == NULL((void *)0))
464 return 0;
465
466 next = 0;
467 found = 0;
468
469 while (!found) {
470
471 skipwhite(modes);
472
473 if (fscanf(modes, "%i", &page_desc) != 1)
474 break;
475
476 if (page_desc == page)
477 found = 1;
478
479 skipwhite(modes);
480 if (getc(modes)(!__isthreaded ? (--(modes)->_r < 0 ? __srget(modes) : (
int)(*(modes)->_p++)) : (getc)(modes))
!= START_ENTRY'{') {
481 errx(1, "Expected %c", START_ENTRY'{');
482 }
483
484 match = 1;
485 while (match != 0) {
486 c = getc(modes)(!__isthreaded ? (--(modes)->_r < 0 ? __srget(modes) : (
int)(*(modes)->_p++)) : (getc)(modes))
;
487 if (c == EOF(-1))
488 fprintf(stderr(&__sF[2]), "Expected %c.\n", END_ENTRY'}');
489
490 if (c == START_ENTRY'{') {
491 match++;
492 }
493 if (c == END_ENTRY'}') {
494 match--;
495 if (match == 0)
496 break;
497 }
498 if (found && c != '\n') {
499 if (next >= sizeof(fmt)) {
500 errx(1, "Stupid program: Buffer overflow.\n");
501 }
502
503 fmt[next++] = (u_char)c;
504 }
505 }
506 }
507 fclose(modes);
508 fmt[next] = 0;
509
510 return (found) ? fmt : 0;
511}
512
513/* -------- edit: Mode Select Editor ---------
514 */
515struct editinfo
516{
517 long can_edit;
518 long default_value;
519} editinfo[64]; /* XXX Bogus fixed size */
520
521static int editind;
522volatile int edit_opened;
523static FILE *edit_file;
524static char edit_name[L_tmpnam1024];
525
526static void
527edit_rewind(void)
528{
529 editind = 0;
530}
531
532static void
533edit_done(void)
534{
535 int opened;
536
537 sigset_t all, prev;
538 sigfillset(&all);
539
540 (void)sigprocmask(SIG_SETMASK3, &all, &prev);
541
542 opened = (int)edit_opened;
543 edit_opened = 0;
544
545 (void)sigprocmask(SIG_SETMASK3, &prev, 0);
546
547 if (opened)
548 {
549 if (fclose(edit_file))
550 perror(edit_name);
551 if (unlink(edit_name))
552 perror(edit_name);
553 }
554}
555
556static void
557edit_init(void)
558{
559 int fd;
560
561 edit_rewind();
562 strlcpy(edit_name, "/var/tmp/scXXXXXXXX", sizeof edit_name);
563 if ((fd = mkstemp(edit_name)) == -1)
564 err(1, "mkstemp");
565 if ( (edit_file = fdopen(fd, "w+")) == 0)
566 err(1, "fdopen");
567 edit_opened = 1;
568
569 atexit(edit_done);
570}
571
572static void
573edit_check(void *hook, int letter, void *arg, int count, char *name)
574{
575 if (letter != 'i' && letter != 'b') {
576 errx(1, "Can't edit format %c.\n", letter);
577 }
578
579 if (editind >= sizeof(editinfo) / sizeof(editinfo[0])) {
580 errx(1, "edit table overflow");
581 }
582 editinfo[editind].can_edit = ((long)arg != 0);
583 editind++;
584}
585
586static void
587edit_defaults(void *hook, int letter, void *arg, int count, char *name)
588{
589 if (letter != 'i' && letter != 'b') {
590 errx(1, "Can't edit format %c.\n", letter);
591 }
592
593 editinfo[editind].default_value = ((long)arg);
594 editind++;
595}
596
597static void
598edit_report(void *hook, int letter, void *arg, int count, char *name)
599{
600 if (editinfo[editind].can_edit) {
601 if (letter != 'i' && letter != 'b') {
602 errx(1, "Can't report format %c.\n", letter);
603 }
604
605 fprintf(edit_file, "%s: %ld\n", name, (long)arg);
606 }
607
608 editind++;
609}
610
611static int
612edit_get(void *hook, char *name)
613{
614 int arg = editinfo[editind].default_value;
615
616 if (editinfo[editind].can_edit) {
617 char line[80];
618 size_t len;
619 if (fgets(line, sizeof(line), edit_file) == NULL((void *)0))
620 err(1, "fgets");
621
622 len = strlen(line);
623 if (len && line[len - 1] == '\n')
624 line[len - 1] = '\0';
625
626 if (strncmp(name, line, strlen(name)) != 0) {
627 errx(1, "Expected \"%s\" and read \"%s\"\n",
628 name, line);
629 }
630
631 arg = strtoul(line + strlen(name) + 2, 0, 0);
632 }
633
634 editind++;
635 return arg;
636}
637
638int
639editit(const char *pathname)
640{
641 char *argp[] = {"sh", "-c", NULL((void *)0), NULL((void *)0)}, *ed, *p;
642 sig_t sighup, sigint, sigquit;
643 pid_t pid;
644 int st;
645
646 ed = getenv("VISUAL");
647 if (ed == NULL((void *)0) || ed[0] == '\0')
648 ed = getenv("EDITOR");
649 if (ed == NULL((void *)0) || ed[0] == '\0')
650 ed = _PATH_VI"/usr/bin/vi";
651 if (asprintf(&p, "%s %s", ed, pathname) == -1)
652 return (-1);
653 argp[2] = p;
654
655 top:
656 sighup = signal(SIGHUP1, SIG_IGN(void (*)(int))1);
657 sigint = signal(SIGINT2, SIG_IGN(void (*)(int))1);
658 sigquit = signal(SIGQUIT3, SIG_IGN(void (*)(int))1);
659 if ((pid = fork()) == -1) {
660 int saved_errno = errno(*__errno());
661
662 (void)signal(SIGHUP1, sighup);
663 (void)signal(SIGINT2, sigint);
664 (void)signal(SIGQUIT3, sigquit);
665 if (saved_errno == EAGAIN35) {
666 sleep(1);
667 goto top;
668 }
669 free(p);
670 errno(*__errno()) = saved_errno;
671 return (-1);
672 }
673 if (pid == 0) {
674 execv(_PATH_BSHELL"/bin/sh", argp);
675 _exit(127);
676 }
677 free(p);
678 for (;;) {
679 if (waitpid(pid, &st, 0) == -1) {
680 if (errno(*__errno()) != EINTR4)
681 return (-1);
682 } else
683 break;
684 }
685 (void)signal(SIGHUP1, sighup);
686 (void)signal(SIGINT2, sigint);
687 (void)signal(SIGQUIT3, sigquit);
688 if (!WIFEXITED(st)(((st) & 0177) == 0) || WEXITSTATUS(st)(int)(((unsigned)(st) >> 8) & 0xff) != 0) {
689 errno(*__errno()) = ECHILD10;
690 return (-1);
691 }
692 return (0);
693}
694
695static void
696mode_edit(int fd, int page, int edit, int argc, char *argv[])
697{
698 int i;
699 u_char data[255];
700 u_char *mode_pars;
701 struct mode_header
702 {
703 u_char mdl; /* Mode data length */
704 u_char medium_type;
705 u_char dev_spec_par;
706 u_char bdl; /* Block descriptor length */
707 };
708
709 struct mode_page_header
710 {
711 u_char page_code;
712 u_char page_length;
713 };
714
715 struct mode_header *mh;
716 struct mode_page_header *mph;
717
718 char *fmt = mode_lookup(page);
719 if (!fmt && verbose) {
720 fprintf(stderr(&__sF[2]),
721 "No mode data base entry in \"%s\" for page %d; binary %s only.\n",
722 mode_db, page, (edit ? "edit" : "display"));
723 }
724
725 if (edit) {
726 if (!fmt) {
727 errx(1, "Sorry: can't edit without a format.\n");
728 }
729
730 if (pagectl != 0 && pagectl != 3) {
731 errx(1,
732"It only makes sense to edit page 0 (current) or page 3 (saved values)\n");
733 }
734
735 verbose = 1;
736
737 mode_sense(fd, data, sizeof(data), 1, page);
738
739 mh = (struct mode_header *)data;
740 mph = (struct mode_page_header *)
741 (((char *)mh) + sizeof(*mh) + mh->bdl);
742
743 mode_pars = (char *)mph + sizeof(*mph);
744
745 edit_init();
746 scsireq_buff_decode_visit(mode_pars, mh->mdl,
747 fmt, edit_check, 0);
748
749 mode_sense(fd, data, sizeof(data), 0, page);
750
751 edit_rewind();
752 scsireq_buff_decode_visit(mode_pars, mh->mdl,
753 fmt, edit_defaults, 0);
754
755 edit_rewind();
756 scsireq_buff_decode_visit(mode_pars, mh->mdl,
757 fmt, edit_report, 0);
758
759 fclose(edit_file);
760 if (editit(edit_name) == -1 && errno(*__errno()) != ECHILD10)
761 err(1, "edit %s", edit_name);
762 if ((edit_file = fopen(edit_name, "r")) == NULL((void *)0))
763 err(1, "open %s", edit_name);
764
765 edit_rewind();
766 scsireq_buff_encode_visit(mode_pars, mh->mdl,
767 fmt, edit_get, 0);
768
769 /* Eliminate block descriptors:
770 */
771 bcopy((char *)mph, ((char *)mh) + sizeof(*mh),
772 sizeof(*mph) + mph->page_length);
773
774 mh->bdl = 0;
775 mph = (struct mode_page_header *) (((char *)mh) + sizeof(*mh));
776 mode_pars = ((char *)mph) + 2;
Value stored to 'mode_pars' is never read
777
778#if 0
779 /* Turn this on to see what you're sending to the
780 * device:
781 */
782 edit_rewind();
783 scsireq_buff_decode_visit(mode_pars,
784 mh->mdl, fmt, arg_put, 0);
785#endif
786
787 edit_done();
788
789 /* Make it permanent if pageselect is three.
790 */
791
792 mph->page_code &= ~0xC0; /* Clear PS and RESERVED */
793 mh->mdl = 0; /* Reserved for mode select */
794
795 mode_select(fd, (char *)mh,
796 sizeof(*mh) + mh->bdl + sizeof(*mph) + mph->page_length,
797 (pagectl == 3));
798
799 exit(0);
800 }
801
802 mode_sense(fd, data, sizeof(data), pagectl, page);
803
804 /* Skip over the block descriptors.
805 */
806 mh = (struct mode_header *)data;
807 mph = (struct mode_page_header *)(((char *)mh) + sizeof(*mh) + mh->bdl);
808 mode_pars = (char *)mph + sizeof(*mph);
809
810 if (!fmt) {
811 for (i = 0; i < mh->mdl; i++) {
812 printf("%02x%c",mode_pars[i],
813 (((i + 1) % 8) == 0) ? '\n' : ' ');
814 }
815 putc('\n', stdout)(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
816 } else {
817 verbose = 1;
818 scsireq_buff_decode_visit(mode_pars,
819 mh->mdl, fmt, arg_put, 0);
820 }
821}
822
823int
824main(int argc, char **argv)
825{
826 procargs(&argc,&argv);
827
828 /* XXX This has grown to the point that it should be cleaned up.
829 */
830 if (debugflag) {
831 if (ioctl(fd,SCIOCDEBUG((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('Q')) << 8) | ((2)))
,&debuglevel) == -1)
832 err(1, "SCIOCDEBUG");
833 } else if (commandflag) {
834 char *fmt;
835
836 if (argc < 1) {
837 fprintf(stderr(&__sF[2]), "Need the command format string.\n");
838 usage();
839 }
840
841
842 fmt = argv[0];
843
844 argc -= 1;
845 argv += 1;
846
847 do_cmd(fd, fmt, argc, argv);
848 } else if (modeflag)
849 mode_edit(fd, modepage, editflag, argc, argv);
850
851 exit(0);
852}