Bug Summary

File:src/usr.sbin/config/ukcutil.c
Warning:line 428, column 4
Value stored to 'lk' 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 ukcutil.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/usr.sbin/config/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/config -I . -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/config/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/usr.sbin/config/ukcutil.c
1/* $OpenBSD: ukcutil.c,v 1.26 2021/11/20 03:13:37 jcs Exp $ */
2
3/*
4 * Copyright (c) 1999-2001 Mats O Jansson. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/types.h>
28#include <sys/device.h>
29
30#include <ctype.h>
31#include <err.h>
32#include <errno(*__errno()).h>
33#include <limits.h>
34#include <nlist.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38
39#include "cmd.h"
40#include "exec.h"
41#include "ukc.h"
42#include "misc.h"
43
44extern int ukc_mod_kernel;
45
46struct cfdata *
47get_cfdata(int idx)
48{
49 return((struct cfdata *)(adjust((caddr_t)nl[P_CFDATA6].n_value) +
50 idx * sizeof(struct cfdata)));
51}
52
53short *
54get_locnamp(int idx)
55{
56 return((short *)(adjust((caddr_t)nl[S_LOCNAMP1].n_value) +
57 idx * sizeof(short)));
58}
59
60static caddr_t *
61get_locnames(int idx)
62{
63 return((caddr_t *)(adjust((caddr_t)nl[P_LOCNAMES0].n_value) +
64 idx * sizeof(caddr_t)));
65}
66
67static long *
68get_extraloc(int nslots)
69{
70 long *extralocp, *locp;
71 int *rextralocp, *textralocp;
72
73 extralocp = (long *)adjust((caddr_t)nl[IA_EXTRALOC9].n_value);
74 rextralocp = (int *)adjust((caddr_t)nl[I_REXTRALOC10].n_value);
75 textralocp = (int *)adjust((caddr_t)nl[I_TEXTRALOC11].n_value);
76 if (*rextralocp < nslots)
77 return (NULL((void *)0));
78
79 locp = &extralocp[*textralocp - *rextralocp];
80 *rextralocp -= nslots;
81 return locp;
82}
83
84static char *
85get_pdevnames(int idx)
86{
87 caddr_t *p;
88
89 p = (caddr_t *)adjust((caddr_t)nl[P_PDEVNAMES14].n_value +
90 idx * sizeof(caddr_t));
91 return(char *)adjust((caddr_t)*p);
92
93}
94
95static struct pdevinit *
96get_pdevinit(int idx)
97{
98 return((struct pdevinit *)(adjust((caddr_t)nl[S_PDEVINIT16].n_value) +
99 idx * sizeof(struct pdevinit)));
100}
101
102int
103more(void)
104{
105 int quit = 0;
106 cmd_t cmd;
107
108 if (cnt != -1) {
109 if (cnt > 0 && cnt == lines) {
110 printf("--- more ---");
111 fflush(stdout(&__sF[1]));
112 ask_cmd(&cmd);
113 cnt = 0;
114 if (cmd.cmd[0] == 'q' || cmd.cmd[0] == 'Q')
115 quit = 1;
116 }
117 cnt++;
118 }
119 return (quit);
120}
121
122static void
123pnum(long val)
124{
125 if (val > -2 && val < 16) {
126 printf("%ld", val);
127 return;
128 }
129
130 switch (base) {
131 case 8:
132 printf("0%lo", val);
133 break;
134 case 10:
135 printf("%ld", val);
136 break;
137 case 16:
138 default:
139 printf("0x%lx", val);
140 break;
141 }
142}
143
144static void
145pdevnam(short devno)
146{
147 struct cfdata *cd;
148 struct cfdriver *cdrv;
149
150 cd = get_cfdata(devno);
151
152 cdrv = (struct cfdriver *)adjust((caddr_t)cd->cf_driver);
153 printf("%s", adjust((caddr_t)cdrv->cd_name));
154
155 switch (cd->cf_fstate) {
156 case FSTATE_NOTFOUND0:
157 case FSTATE_DNOTFOUND3:
158 printf("%d", cd->cf_unit);
159 break;
160 case FSTATE_FOUND1:
161 printf("*FOUND*");
162 break;
163 case FSTATE_STAR2:
164 case FSTATE_DSTAR4:
165 printf("*");
166 break;
167 default:
168 printf("*UNKNOWN*");
169 break;
170 }
171}
172
173void
174pdev(short devno)
175{
176 struct pdevinit *pi;
177 struct cfdata *cd;
178 short *s, *ln;
179 long *i;
180 caddr_t *p;
181 char c;
182
183 if (nopdev == 0) {
184 if (devno > maxdev && devno <= totdev) {
185 printf("%3d free slot (for add)\n", devno);
186 return;
187 }
188 if (devno > totdev && devno <= totdev + maxpseudo) {
189 pi = get_pdevinit(devno - totdev -1);
190 printf("%3d %s count %d", devno,
191 get_pdevnames(devno - totdev - 1),
192 abs(pi->pdev_count));
193 if (pi->pdev_count < 0)
194 printf(" disable");
195 printf(" (pseudo device)\n");
196 return;
197 }
198 }
199
200 if (devno > maxdev) {
201 printf("Unknown devno (max is %d)\n", maxdev);
202 return;
203 }
204
205 cd = get_cfdata(devno);
206
207 printf("%3d ", devno);
208 pdevnam(devno);
209 printf(" at");
210
211 c = ' ';
212 s = (short *)adjust((caddr_t)cd->cf_parents);
213 if (*s == -1)
214 printf(" root");
215 while (*s != -1) {
216 printf("%c", c);
217 pdevnam(*s);
218 c = '|';
219 s++;
220 }
221 switch (cd->cf_fstate) {
222 case FSTATE_NOTFOUND0:
223 case FSTATE_FOUND1:
224 case FSTATE_STAR2:
225 break;
226 case FSTATE_DNOTFOUND3:
227 case FSTATE_DSTAR4:
228 printf(" disable");
229 break;
230 default:
231 printf(" ???");
232 break;
233 }
234
235 i = (long *)adjust((caddr_t)cd->cf_loc);
236 ln = get_locnamp(cd->cf_locnames);
237 while (*ln != -1) {
238 p = get_locnames(*ln);
239 printf(" %s ", adjust((caddr_t)*p));
240 ln++;
241 pnum(*i);
242 i++;
243 }
244 printf(" flags 0x%x\n", cd->cf_flags);
245}
246
247static int
248numberl(const char *c, long *val)
249{
250 char *ep;
251
252 errno(*__errno()) = 0;
253 *val = strtol(c, &ep, 0);
254 if (*c == '\0' || (!isspace((unsigned char)*ep) && *ep != '\0') ||
255 (errno(*__errno()) == ERANGE34 && (*val == LONG_MAX9223372036854775807L || *val == LONG_MIN(-9223372036854775807L -1L))))
256 return (-1);
257 return (0);
258}
259
260int
261number(const char *c, int *val)
262{
263 long v;
264 int ret = numberl(c, &v);
265
266 if (ret == 0) {
267 if (v <= INT_MAX2147483647 && v >= INT_MIN(-2147483647 -1))
268 *val = (int)v;
269 else
270 ret = -1;
271 }
272 return (ret);
273}
274
275int
276device(char *cmd, int *len, short *unit, short *state)
277{
278 short u = 0, s = FSTATE_FOUND1;
279 int l = 0;
280 char *c;
281
282 c = cmd;
283 while (*c >= 'a' && *c <= 'z') {
284 l++;
285 c++;
286 }
287
288 if (*c == '*') {
289 s = FSTATE_STAR2;
290 c++;
291 } else {
292 while (*c >= '0' && *c <= '9') {
293 s = FSTATE_NOTFOUND0;
294 u = u*10 + *c - '0';
295 c++;
296 }
297 }
298 while (*c == ' ' || *c == '\t' || *c == '\n')
299 c++;
300
301 if (*c == '\0') {
302 *len = l;
303 *unit = u;
304 *state = s;
305 return(0);
306 }
307 return(-1);
308}
309
310int
311attr(char *cmd, int *val)
312{
313 short attr = -1, i = 0, l = 0;
314 caddr_t *p;
315 char *c;
316
317 c = cmd;
318 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
319 c++;
320 l++;
321 }
322
323 p = get_locnames(0);
324
325 while (i <= maxlocnames) {
326 if (strlen((char *)adjust((caddr_t)*p)) == l) {
327 if (strncasecmp(cmd, adjust((caddr_t)*p), l) == 0)
328 attr = i;
329 }
330 p++;
331 i++;
332 }
333 if (attr == -1)
334 return (-1);
335
336 *val = attr;
337 return(0);
338}
339
340static int
341modifyl(char *item, long *val)
342{
343 cmd_t cmd;
344 long a;
345
346 ukc_mod_kernel = 1;
347 while (1) {
348 printf("%s [", item);
349 pnum(*val);
350 printf("] ? ");
351 fflush(stdout(&__sF[1]));
352
353 ask_cmd(&cmd);
354
355 if (strlen(cmd.cmd) != 0) {
356 if (strlen(cmd.args) == 0) {
357 if (numberl(cmd.cmd, &a) == 0) {
358 *val = a;
359 return (1);
360 } else
361 printf("Unknown argument\n");
362 } else
363 printf("Too many arguments\n");
364 } else
365 return (0);
366 }
367}
368
369void
370modify(char *item, int *val)
371{
372 long a = *val;
373
374 while (modifyl(item, &a)) {
375 if (a <= INT_MAX2147483647 && a >= INT_MIN(-2147483647 -1)) {
376 *val = (int)a;
377 break;
378 }
379 printf("Out of range argument\n");
380 }
381}
382
383void
384change(int devno)
385{
386 int i, share = 0;
387 long *j = NULL((void *)0), *l = NULL((void *)0);
388 struct cfdata *cd, *c;
389 struct pdevinit *pi;
390 short *ln, *lk;
391 caddr_t *p;
392
393 ukc_mod_kernel = 1;
394 if (devno <= maxdev) {
395 pdev(devno);
396 if (!ask_yn("change"))
397 return;
398
399 cd = get_cfdata(devno);
400
401 /*
402 * Search for some other driver sharing this
403 * locator table. if one does, we may need to
404 * replace the locators with a new copy.
405 */
406 c = get_cfdata(0);
407 for (i = 0; c->cf_driver; i++) {
408 if (i != devno && c->cf_loc == cd->cf_loc)
409 share = 1;
410 c++;
411 }
412
413 ln = get_locnamp(cd->cf_locnames);
414 l = (long *)adjust((caddr_t)cd->cf_loc);
415
416 if (share) {
417 if (oldkernel) {
418 printf("Can't do that on this kernel\n");
419 return;
420 }
421
422 lk = ln;
423 i = 0;
424 while (*lk != -1) {
425 lk++;
426 i++;
427 }
428 lk = ln;
Value stored to 'lk' is never read
429
430 j = l = get_extraloc(i);
431 if (l == NULL((void *)0)) {
432 printf("Not enough space to change device.\n");
433 return;
434 }
435 if (i)
436 bcopy(adjust((caddr_t)cd->cf_loc), l,
437 sizeof(long) * i);
438 }
439
440 while (*ln != -1) {
441 p = get_locnames(*ln);
442 modifyl((char *)adjust(*p), l);
443 ln++;
444 l++;
445 }
446 modify("flags", &cd->cf_flags);
447
448 if (share) {
449 if (bcmp(adjust((caddr_t)cd->cf_loc),
450 j, sizeof(long) * i)) {
451 cd->cf_loc = (long *)readjust((caddr_t)j);
452 }
453 }
454
455 printf("%3d ", devno);
456 pdevnam(devno);
457 printf(" changed\n");
458 pdev(devno);
459 return;
460 }
461
462 if (nopdev == 0) {
463 if (devno > maxdev && devno <= totdev) {
464 printf("%3d can't change free slot\n", devno);
465 return;
466 }
467
468 if (devno > totdev && devno <= totdev + maxpseudo) {
469 pdev(devno);
470 if (ask_yn("change")) {
471 pi = get_pdevinit(devno-totdev-1);
472 modify("count", &pi->pdev_count);
473 printf("%3d %s changed\n", devno,
474 get_pdevnames(devno - totdev - 1));
475 pdev(devno);
476 }
477 return;
478 }
479 }
480
481 printf("Unknown devno (max is %d)\n", totdev+maxpseudo);
482}
483
484void
485change_history(int devno, char *str)
486{
487 int i, share = 0;
488 long *j = NULL((void *)0), *l = NULL((void *)0);
489 struct cfdata *cd, *c;
490 struct pdevinit *pi;
491 short *ln, *lk;
492
493 ukc_mod_kernel = 1;
494
495 if (devno <= maxdev) {
496
497 pdev(devno);
498 cd = get_cfdata(devno);
499
500 /*
501 * Search for some other driver sharing this
502 * locator table. if one does, we may need to
503 * replace the locators with a new copy.
504 */
505 c = get_cfdata(0);
506 for (i = 0; c->cf_driver; i++) {
507 if (i != devno && c->cf_loc == cd->cf_loc)
508 share = 1;
509 c++;
510 }
511
512 ln = get_locnamp(cd->cf_locnames);
513 l = (long *)adjust((caddr_t)cd->cf_loc);
514
515 if (share) {
516 if (oldkernel) {
517 printf("Can't do that on this kernel\n");
518 return;
519 }
520
521 lk = ln;
522 i = 0;
523 while (*lk != -1) {
524 lk++;
525 i++;
526 }
527 lk = ln;
528
529 j = l = get_extraloc(i);
530 if (l == NULL((void *)0)) {
531 printf("Not enough space to change device.\n");
532 return;
533 }
534 if (i)
535 bcopy(adjust((caddr_t)cd->cf_loc), l,
536 sizeof(long) * i);
537 }
538
539 while (*ln != -1) {
540 *l = atoi(str);
541 if (*str == '-')
542 str++;
543 while (*str >= '0' && *str <= '9')
544 str++;
545 if (*str == ' ')
546 str++;
547 ln++;
548 l++;
549 }
550
551 if (*str) {
552 cd->cf_flags = atoi(str);
553 if (*str == '-')
554 str++;
555 while (*str >= '0' && *str <= '9')
556 str++;
557 if (*str == ' ')
558 str++;
559 }
560
561 if (share) {
562 if (bcmp(adjust((caddr_t)cd->cf_loc),
563 j, sizeof(long) * i)) {
564 cd->cf_loc = (long *)readjust((caddr_t)j);
565 }
566 }
567
568 printf("%3d ", devno);
569 pdevnam(devno);
570 printf(" changed\n");
571 pdev(devno);
572 return;
573 }
574
575 if (nopdev == 0) {
576 if (devno > maxdev && devno <= totdev) {
577 printf("%3d can't change free slot\n", devno);
578 return;
579 }
580 if (devno > totdev && devno <= totdev + maxpseudo) {
581 pdev(devno);
582 pi = get_pdevinit(devno-totdev-1);
583
584 if (*str) {
585 pi->pdev_count = atoi(str);
586 if (*str == '-')
587 str++;
588 while (*str >= '0' && *str <= '9')
589 str++;
590 if (*str == ' ')
591 str++;
592 }
593
594 printf("%3d %s changed\n", devno,
595 get_pdevnames(devno - totdev - 1));
596 pdev(devno);
597 return;
598 }
599 }
600
601 printf("Unknown devno (max is %d)\n", totdev + maxpseudo);
602}
603
604void
605disable(int devno)
606{
607 struct cfdata *cd;
608 struct pdevinit *pi;
609 int done = 0;
610
611 if (devno <= maxdev) {
612
613 cd = get_cfdata(devno);
614
615 switch (cd->cf_fstate) {
616 case FSTATE_NOTFOUND0:
617 cd->cf_fstate = FSTATE_DNOTFOUND3;
618 break;
619 case FSTATE_STAR2:
620 cd->cf_fstate = FSTATE_DSTAR4;
621 break;
622 case FSTATE_DNOTFOUND3:
623 case FSTATE_DSTAR4:
624 done = 1;
625 break;
626 default:
627 printf("Error unknown state\n");
628 break;
629 }
630
631 printf("%3d ", devno);
632 pdevnam(devno);
633 if (done) {
634 printf(" already");
635 } else {
636 ukc_mod_kernel = 1;
637 }
638 printf(" disabled\n");
639
640 return;
641 }
642
643 if (nopdev == 0) {
644 if (devno > maxdev && devno <= totdev) {
645 printf("%3d can't disable free slot\n", devno);
646 return;
647 }
648 if (devno > totdev && devno <= totdev + maxpseudo) {
649 pi = get_pdevinit(devno-totdev-1);
650
651 printf("%3d %s", devno,
652 get_pdevnames(devno - totdev - 1));
653 if (pi->pdev_count < 1) {
654 printf(" already");
655 } else {
656 ukc_mod_kernel = 1;
657 pi->pdev_count*=-1;
658 }
659 printf(" disabled\n");
660 return;
661 }
662 }
663
664 printf("Unknown devno (max is %d)\n", totdev+maxpseudo);
665
666}
667
668void
669enable(int devno)
670{
671 struct cfdata *cd;
672 struct pdevinit *pi;
673 int done = 0;
674
675 if (devno <= maxdev) {
676 cd = get_cfdata(devno);
677
678 switch (cd->cf_fstate) {
679 case FSTATE_DNOTFOUND3:
680 cd->cf_fstate = FSTATE_NOTFOUND0;
681 break;
682 case FSTATE_DSTAR4:
683 cd->cf_fstate = FSTATE_STAR2;
684 break;
685 case FSTATE_NOTFOUND0:
686 case FSTATE_STAR2:
687 done = 1;
688 break;
689 default:
690 printf("Error unknown state\n");
691 break;
692 }
693
694 printf("%3d ", devno);
695 pdevnam(devno);
696 if (done) {
697 printf(" already");
698 } else {
699 ukc_mod_kernel = 1;
700 }
701 printf(" enabled\n");
702
703 return;
704 }
705
706 if (nopdev == 0) {
707 if (devno > maxdev && devno <= totdev) {
708 printf("%3d can't enable free slot\n", devno);
709 return;
710 }
711 if (devno > totdev && devno <= totdev + maxpseudo) {
712 pi = get_pdevinit(devno-totdev-1);
713
714 printf("%3d %s", devno,
715 get_pdevnames(devno - totdev - 1));
716 if (pi->pdev_count > 0) {
717 printf(" already");
718 } else {
719 ukc_mod_kernel = 1;
720 pi->pdev_count*=-1;
721 }
722 printf(" enabled\n");
723 return;
724 }
725 }
726
727 printf("Unknown devno (max is %d)\n", totdev+maxpseudo);
728}
729
730void
731show(void)
732{
733 caddr_t *p;
734 int i = 0;
735
736 cnt = 0;
737
738 p = get_locnames(0);
739
740 while (i <= maxlocnames) {
741 if (more())
742 break;
743 printf("%s\n", (char *)adjust(*p));
744 p++;
745 i++;
746 }
747
748 cnt = -1;
749}
750
751void
752common_attr_val(short attr, int *val, char routine)
753{
754 int i = 0;
755 struct cfdata *cd;
756 long *l;
757 short *ln;
758 int quit = 0;
759
760 cnt = 0;
761
762 cd = get_cfdata(0);
763
764 while (cd->cf_attach != 0) {
765 l = (long *)adjust((caddr_t)cd->cf_loc);
766 ln = get_locnamp(cd->cf_locnames);
767 while (*ln != -1) {
768 if (*ln == attr) {
769 if (val == NULL((void *)0)) {
770 quit = more();
771 pdev(i);
772 } else {
773 if (*val == *l) {
774 quit = more();
775 switch (routine) {
776 case UC_ENABLE'e':
777 enable(i);
778 break;
779 case UC_DISABLE'd':
780 disable(i);
781 break;
782 case UC_SHOW's':
783 pdev(i);
784 break;
785 default:
786 printf("Unknown routine /%c/\n",
787 routine);
788 break;
789 }
790 }
791 }
792 }
793 if (quit)
794 break;
795 ln++;
796 l++;
797 }
798 if (quit)
799 break;
800 i++;
801 cd++;
802 }
803
804 cnt = -1;
805}
806
807void
808show_attr(char *cmd)
809{
810 char *c;
811 caddr_t *p;
812 short attr = -1, i = 0, l = 0;
813 int a;
814
815 c = cmd;
816 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
817 c++;
818 l++;
819 }
820 while (*c == ' ' || *c == '\t' || *c == '\n') {
821 c++;
822 }
823
824 p = get_locnames(0);
825
826 while (i <= maxlocnames) {
827 if (strlen((char *)adjust(*p)) == l) {
828 if (strncasecmp(cmd, adjust(*p), l) == 0)
829 attr = i;
830 }
831 p++;
832 i++;
833 }
834
835 if (attr == -1) {
836 printf("Unknown attribute\n");
837 return;
838 }
839
840 if (*c == '\0') {
841 common_attr_val(attr, NULL((void *)0), UC_SHOW's');
842 } else {
843 if (number(c, &a) == 0) {
844 common_attr_val(attr, &a, UC_SHOW's');
845 } else {
846 printf("Unknown argument\n");
847 }
848 }
849}
850
851void
852common_dev(char *dev, int len, short unit, short state, char routine)
853{
854 struct cfdata *cd;
855 struct cfdriver *cdrv;
856 int i = 0;
857
858 switch (routine) {
859 case UC_CHANGE'c':
860 break;
861 default:
862 cnt = 0;
863 break;
864 }
865
866 cnt = 0;
867
868 cd = get_cfdata(0);
869
870 while (cd->cf_attach != 0) {
871 cdrv = (struct cfdriver *)adjust((caddr_t)cd->cf_driver);
872
873 if (strlen((char *)adjust(cdrv->cd_name)) == len) {
874 /*
875 * Ok, if device name is correct
876 * If state == FSTATE_FOUND, look for "dev"
877 * If state == FSTATE_STAR, look for "dev*"
878 * If state == FSTATE_NOTFOUND, look for "dev0"
879 */
880 if (!strncasecmp(dev,(char *)adjust(cdrv->cd_name), len) &&
881 (state == FSTATE_FOUND1 ||
882 (state == FSTATE_STAR2 &&
883 (cd->cf_fstate == FSTATE_STAR2 ||
884 cd->cf_fstate == FSTATE_DSTAR4)) ||
885 (state == FSTATE_NOTFOUND0 &&
886 cd->cf_unit == unit &&
887 (cd->cf_fstate == FSTATE_NOTFOUND0 ||
888 cd->cf_fstate == FSTATE_DNOTFOUND3)))) {
889 if (more())
890 break;
891 switch (routine) {
892 case UC_CHANGE'c':
893 change(i);
894 break;
895 case UC_ENABLE'e':
896 enable(i);
897 break;
898 case UC_DISABLE'd':
899 disable(i);
900 break;
901 case UC_FIND'f':
902 pdev(i);
903 break;
904 default:
905 printf("Unknown routine /%c/\n",
906 routine);
907 break;
908 }
909 }
910 }
911 i++;
912 cd++;
913 }
914
915 if (nopdev == 0) {
916 for (i = 0; i < maxpseudo; i++) {
917 if (!strncasecmp(dev, (char *)get_pdevnames(i), len) &&
918 state == FSTATE_FOUND1) {
919 switch (routine) {
920 case UC_CHANGE'c':
921 change(totdev+1+i);
922 break;
923 case UC_ENABLE'e':
924 enable(totdev+1+i);
925 break;
926 case UC_DISABLE'd':
927 disable(totdev+1+i);
928 break;
929 case UC_FIND'f':
930 pdev(totdev+1+i);
931 break;
932 default:
933 printf("Unknown pseudo routine /%c/\n",
934 routine);
935 break;
936 }
937 }
938 }
939 }
940
941 switch (routine) {
942 case UC_CHANGE'c':
943 break;
944 default:
945 cnt = -1;
946 break;
947 }
948}
949
950void
951common_attr(char *cmd, int attr, char routine)
952{
953 char *c;
954 short l = 0;
955 int a;
956
957 c = cmd;
958 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
959 c++;
960 l++;
961 }
962 while (*c == ' ' || *c == '\t' || *c == '\n') {
963 c++;
964 }
965 if (*c == '\0') {
966 printf("Value missing for attribute\n");
967 return;
968 }
969
970 if (number(c, &a) == 0) {
971 common_attr_val(attr, &a, routine);
972 } else {
973 printf("Unknown argument\n");
974 }
975}
976
977void
978add_read(char *prompt, char field, char *dev, int len, int *val)
979{
980 int ok = 0;
981 int a;
982 cmd_t cmd;
983 struct cfdata *cd;
984 struct cfdriver *cdrv;
985
986 *val = -1;
987
988 while (!ok) {
989 printf("%s ? ", prompt);
990 fflush(stdout(&__sF[1]));
991
992 ask_cmd(&cmd);
993
994 if (strlen(cmd.cmd) != 0) {
995 if (number(cmd.cmd, &a) == 0) {
996 if (a > maxdev) {
997 printf("Unknown devno (max is %d)\n",
998 maxdev);
999 } else {
1000 cd = get_cfdata(a);
1001 cdrv = (struct cfdriver *)
1002 adjust((caddr_t)cd->cf_driver);
1003 if (strncasecmp(dev,
1004 (char *)adjust(cdrv->cd_name),
1005 len) != 0 &&
1006 field == 'a') {
1007 printf("Not same device type\n");
1008 } else {
1009 *val = a;
1010 ok = 1;
1011 }
1012 }
1013 } else if (cmd.cmd[0] == '?') {
1014 common_dev(dev, len, 0,
1015 FSTATE_FOUND1, UC_FIND'f');
1016 } else if (cmd.cmd[0] == 'q' ||
1017 cmd.cmd[0] == 'Q') {
1018 ok = 1;
1019 } else {
1020 printf("Unknown argument\n");
1021 }
1022 } else {
1023 ok = 1;
1024 }
1025 }
1026
1027}
1028
1029void
1030add(char *dev, int len, short unit, short state)
1031{
1032 int i = 0, found = 0, *p;
1033 short *pv;
1034 struct cfdata new, *cd, *cdp;
1035 struct cfdriver *cdrv;
1036 int val, max_unit, star_unit;
1037
1038 ukc_mod_kernel = 1;
1039
1040 bzero(&new, sizeof(struct cfdata));
1041
1042 if (maxdev == totdev) {
1043 printf("No more space for new devices.\n");
1044 return;
1045 }
1046
1047 if (state == FSTATE_FOUND1) {
1048 printf("Device not complete number or * is missing\n");
1049 return;
1050 }
1051
1052 cd = get_cfdata(0);
1053
1054 while (cd->cf_attach != 0) {
1055 cdrv = (struct cfdriver *)adjust((caddr_t)cd->cf_driver);
1056
1057 if (strlen((char *)adjust(cdrv->cd_name)) == len &&
1058 strncasecmp(dev, (char *)adjust(cdrv->cd_name), len) == 0)
1059 found = 1;
1060 cd++;
1061 }
1062
1063 if (!found) {
1064 printf("No device of this type exists.\n");
1065 return;
1066 }
1067
1068 add_read("Clone Device (DevNo, 'q' or '?')", 'a', dev, len, &val);
1069
1070 if (val != -1) {
1071 cd = get_cfdata(val);
1072 new = *cd;
1073 new.cf_unit = unit;
1074 new.cf_fstate = state;
1075 add_read("Insert before Device (DevNo, 'q' or '?')",
1076 'i', dev, len, &val);
1077 }
1078
1079 if (val != -1) {
1080
1081 /* Insert the new record */
1082 cdp = cd = get_cfdata(maxdev+1);
1083 cdp--;
1084 for (i = maxdev; val <= i; i--) {
1085 *cd-- = *cdp--;
1086 }
1087 cd = get_cfdata(val);
1088 *cd = new;
1089
1090 /* Fix indexs in pv */
1091 p = (int *)adjust((caddr_t)nl[I_PV_SIZE4].n_value);
1092 pv = (short *)adjust((caddr_t)nl[SA_PV5].n_value);
1093 for (i = 0; i < *p; i++) {
1094 if (*pv != 1 && *pv >= val)
1095 *pv = *pv + 1;
1096 pv++;
1097 }
1098
1099 /* Fix indexs in cfroots */
1100 p = (int *)adjust((caddr_t)nl[I_CFROOTS_SIZE3].n_value);
1101 pv = (short *)adjust((caddr_t)nl[SA_CFROOTS2].n_value);
1102 for (i = 0; i < *p; i++) {
1103 if (*pv != 1 && *pv >= val)
1104 *pv = *pv + 1;
1105 pv++;
1106 }
1107
1108 maxdev++;
1109
1110 max_unit = -1;
1111
1112 /* Find max unit number of the device type */
1113
1114 cd = get_cfdata(0);
1115
1116 while (cd->cf_attach != 0) {
1117 cdrv = (struct cfdriver *)
1118 adjust((caddr_t)cd->cf_driver);
1119
1120 if (strlen((char *)adjust(cdrv->cd_name)) == len &&
1121 strncasecmp(dev, (char *)adjust(cdrv->cd_name),
1122 len) == 0) {
1123 switch (cd->cf_fstate) {
1124 case FSTATE_NOTFOUND0:
1125 case FSTATE_DNOTFOUND3:
1126 if (cd->cf_unit > max_unit)
1127 max_unit = cd->cf_unit;
1128 break;
1129 default:
1130 break;
1131 }
1132 }
1133 cd++;
1134 }
1135
1136 /*
1137 * For all * entries set unit number to max+1, and update
1138 * cf_starunit1 if necessary.
1139 */
1140 max_unit++;
1141 star_unit = -1;
1142 cd = get_cfdata(0);
1143 while (cd->cf_attach != 0) {
1144 cdrv = (struct cfdriver *)
1145 adjust((caddr_t)cd->cf_driver);
1146
1147 if (strlen((char *)adjust(cdrv->cd_name)) == len &&
1148 strncasecmp(dev, (char *)adjust(cdrv->cd_name),
1149 len) == 0) {
1150 switch (cd->cf_fstate) {
1151 case FSTATE_NOTFOUND0:
1152 case FSTATE_DNOTFOUND3:
1153 if (cd->cf_unit > star_unit)
1154 star_unit = cd->cf_unit;
1155 break;
1156 default:
1157 break;
1158 }
1159 }
1160 cd++;
1161 }
1162 star_unit++;
1163
1164 cd = get_cfdata(0);
1165 while (cd->cf_attach != 0) {
1166 cdrv = (struct cfdriver *)
1167 adjust((caddr_t)cd->cf_driver);
1168
1169 if (strlen((char *)adjust(cdrv->cd_name)) == len &&
1170 strncasecmp(dev, (char *)adjust(cdrv->cd_name),
1171 len) == 0) {
1172 switch (cd->cf_fstate) {
1173 case FSTATE_STAR2:
1174 case FSTATE_DSTAR4:
1175 cd->cf_unit = max_unit;
1176 if (cd->cf_starunit1 < star_unit)
1177 cd->cf_starunit1 = star_unit;
1178 break;
1179 default:
1180 break;
1181 }
1182 }
1183 cd++;
1184 }
1185
1186 pdev(val);
1187 }
1188
1189 /* cf_attach, cf_driver, cf_unit, cf_fstate, cf_loc, cf_flags,
1190 cf_parents, cf_locnames, cf_locnames and cf_ivstubs */
1191}
1192
1193void
1194add_history(int devno, short unit, short state, int newno)
1195{
1196 int i = 0, *p;
1197 short *pv;
1198 struct cfdata new, *cd, *cdp;
1199 struct cfdriver *cdrv;
1200 int val, max_unit;
1201 int len;
1202 char *dev;
1203
1204 ukc_mod_kernel = 1;
1205
1206 bzero(&new, sizeof(struct cfdata));
1207 cd = get_cfdata(devno);
1208 new = *cd;
1209 new.cf_unit = unit;
1210 new.cf_fstate = state;
1211
1212 val = newno;
1213
1214 cdrv = (struct cfdriver *) adjust((caddr_t)cd->cf_driver);
1215 dev = adjust((caddr_t)cdrv->cd_name);
1216 len = strlen(dev);
1217
1218 /* Insert the new record */
1219 cdp = cd = get_cfdata(maxdev+1);
1220 cdp--;
1221 for (i = maxdev; val <= i; i--)
1222 *cd-- = *cdp--;
1223 cd = get_cfdata(val);
1224 *cd = new;
1225
1226 /* Fix indexs in pv */
1227 p = (int *)adjust((caddr_t)nl[I_PV_SIZE4].n_value);
1228 pv = (short *)adjust((caddr_t)nl[SA_PV5].n_value);
1229 for (i = 0; i < *p; i++) {
1230 if (*pv != 1 && *pv >= val)
1231 *pv = *pv + 1;
1232 pv++;
1233 }
1234
1235 /* Fix indexs in cfroots */
1236 p = (int *)adjust((caddr_t)nl[I_CFROOTS_SIZE3].n_value);
1237 pv = (short *)adjust((caddr_t)nl[SA_CFROOTS2].n_value);
1238 for (i = 0; i < *p; i++) {
1239 if (*pv != 1 && *pv >= val)
1240 *pv = *pv + 1;
1241 pv++;
1242 }
1243
1244 maxdev++;
1245 max_unit = -1;
1246
1247 /* Find max unit number of the device type */
1248 cd = get_cfdata(0);
1249 while (cd->cf_attach != 0) {
1250 cdrv = (struct cfdriver *)
1251 adjust((caddr_t)cd->cf_driver);
1252
1253 if (strlen((char *)adjust(cdrv->cd_name)) == len &&
1254 strncasecmp(dev, (char *)adjust(cdrv->cd_name),
1255 len) == 0) {
1256 switch (cd->cf_fstate) {
1257 case FSTATE_NOTFOUND0:
1258 case FSTATE_DNOTFOUND3:
1259 if (cd->cf_unit > max_unit)
1260 max_unit = cd->cf_unit;
1261 break;
1262 default:
1263 break;
1264 }
1265 }
1266 cd++;
1267 }
1268
1269 /* For all * entries set unit number to max+1 */
1270 max_unit++;
1271 cd = get_cfdata(0);
1272 while (cd->cf_attach != 0) {
1273 cdrv = (struct cfdriver *)
1274 adjust((caddr_t)cd->cf_driver);
1275
1276 if (strlen((char *)adjust(cdrv->cd_name)) == len &&
1277 strncasecmp(dev, (char *)adjust(cdrv->cd_name),
1278 len) == 0) {
1279 switch (cd->cf_fstate) {
1280 case FSTATE_STAR2:
1281 case FSTATE_DSTAR4:
1282 cd->cf_unit = max_unit;
1283 break;
1284 default:
1285 break;
1286 }
1287 }
1288 cd++;
1289 }
1290
1291 printf("%3d ", newno);
1292 pdevnam(newno);
1293 printf(" added\n");
1294 pdev(val);
1295}
1296
1297int
1298config(void)
1299{
1300 extern char *cmdfile;
1301 cmd_t cmd;
1302 int i, st;
1303
1304 /* Set up command table pointer */
1305 cmd.table = cmd_table;
1306
1307 if (cmdfile == NULL((void *)0))
1308 printf("Enter 'help' for information\n");
1309
1310 /* Edit cycle */
1311 do {
1312 char lbuf[100];
1313
1314again:
1315 /* Get input */
1316 if (cmdfile == NULL((void *)0)) {
1317 printf("ukc> ");
1318 fflush(stdout(&__sF[1]));
1319 }
1320 ask_cmd(&cmd);
1321
1322 if (cmd.cmd[0] == '\0') {
1323 if (cmdfile != NULL((void *)0))
1324 return 1;
1325 goto again;
1326 }
1327 for (i = 0; cmd_table[i].cmd != NULL((void *)0); i++)
1328 if (strstr(cmd_table[i].cmd, cmd.cmd) ==
1329 cmd_table[i].cmd)
1330 break;
1331
1332 /* Quick hack to put in '?' == 'help' */
1333 if (!strcmp(cmd.cmd, "?"))
1334 i = 0;
1335
1336 /* Check for valid command */
1337 if (cmd_table[i].cmd == NULL((void *)0)) {
1338 if (cmdfile == NULL((void *)0)) {
1339 printf("Invalid command '%s'\n", cmd.cmd);
1340 exit(1);
1341 }
1342 printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd);
1343 continue;
1344 } else
1345 strlcpy(cmd.cmd, cmd_table[i].cmd, sizeof cmd.cmd);
1346
1347 /* Call function */
1348 st = cmd_table[i].fcn(&cmd);
1349
1350 /* Update status */
1351 if (st == CMD_EXIT0x0000)
1352 break;
1353 if (st == CMD_SAVE0x0001)
1354 break;
1355 } while (1);
1356
1357 return (st == CMD_SAVE0x0001);
1358}
1359
1360void
1361process_history(int len, char *buf)
1362{
1363 char *c;
1364 int devno, newno;
1365 short unit, state;
1366
1367 if (len == 0) {
1368 printf("History is empty\n");
1369 return;
1370 }
1371
1372 printf("Processing history...\n");
1373
1374 buf[len] = 0;
1375
1376 c = buf;
1377
1378 while (*c != '\0') {
1379 switch (*c) {
1380 case 'a':
1381 c++;
1382 c++;
1383 devno = atoi(c);
1384 while (*c >= '0' && *c <= '9')
1385 c++;
1386 c++;
1387 unit = atoi(c);
1388 if (*c == '-') c++;
1389 while (*c >= '0' && *c <= '9')
1390 c++;
1391 c++;
1392 state = atoi(c);
1393 if (*c == '-')
1394 c++;
1395 while (*c >= '0' && *c <= '9')
1396 c++;
1397 c++;
1398 newno = atoi(c);
1399 while (*c >= '0' && *c <= '9')
1400 c++;
1401 add_history(devno, unit, state, newno);
1402 while (*c != '\n')
1403 c++;
1404 c++;
1405 break;
1406 case 'c':
1407 c++;
1408 c++;
1409 devno = atoi(c);
1410 while (*c >= '0' && *c <= '9')
1411 c++;
1412 if (*c == ' ')
1413 c++;
1414 if (*c != '\n')
1415 change_history(devno, c);
1416 while (*c != '\n')
1417 c++;
1418 c++;
1419 break;
1420 case 'd':
1421 c++;
1422 devno = atoi(c);
1423 disable(devno);
1424 while (*c != '\n')
1425 c++;
1426 c++;
1427 break;
1428 case 'e':
1429 c++;
1430 devno = atoi(c);
1431 enable(devno);
1432 while (*c != '\n')
1433 c++;
1434 c++;
1435 break;
1436 case 'q':
1437 while (*c != '\0')
1438 c++;
1439 break;
1440 default:
1441 printf("unknown command %c\n", *c);
1442 while (*c != '\0' && *c != '\n')
1443 c++;
1444 break;
1445 }
1446 }
1447}