1 |
|
|
/* $OpenBSD: ukcutil.c,v 1.23 2017/09/27 15:14:52 deraadt 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/time.h> |
29 |
|
|
#include <sys/device.h> |
30 |
|
|
|
31 |
|
|
#include <ctype.h> |
32 |
|
|
#include <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 |
|
|
|
44 |
|
|
extern int ukc_mod_kernel; |
45 |
|
|
|
46 |
|
|
struct cfdata * |
47 |
|
|
get_cfdata(int idx) |
48 |
|
|
{ |
49 |
|
|
return((struct cfdata *)(adjust((caddr_t)nl[P_CFDATA].n_value) + |
50 |
|
|
idx * sizeof(struct cfdata))); |
51 |
|
|
} |
52 |
|
|
|
53 |
|
|
short * |
54 |
|
|
get_locnamp(int idx) |
55 |
|
|
{ |
56 |
|
|
return((short *)(adjust((caddr_t)nl[S_LOCNAMP].n_value) + |
57 |
|
|
idx * sizeof(short))); |
58 |
|
|
} |
59 |
|
|
|
60 |
|
|
static caddr_t * |
61 |
|
|
get_locnames(int idx) |
62 |
|
|
{ |
63 |
|
|
return((caddr_t *)(adjust((caddr_t)nl[P_LOCNAMES].n_value) + |
64 |
|
|
idx * sizeof(caddr_t))); |
65 |
|
|
} |
66 |
|
|
|
67 |
|
|
static long * |
68 |
|
|
get_extraloc(int nslots) |
69 |
|
|
{ |
70 |
|
|
long *extralocp, *locp; |
71 |
|
|
int *rextralocp, *textralocp; |
72 |
|
|
|
73 |
|
|
extralocp = (long *)adjust((caddr_t)nl[IA_EXTRALOC].n_value); |
74 |
|
|
rextralocp = (int *)adjust((caddr_t)nl[I_REXTRALOC].n_value); |
75 |
|
|
textralocp = (int *)adjust((caddr_t)nl[I_TEXTRALOC].n_value); |
76 |
|
|
if (*rextralocp < nslots) |
77 |
|
|
return (NULL); |
78 |
|
|
|
79 |
|
|
locp = &extralocp[*textralocp - *rextralocp]; |
80 |
|
|
*rextralocp -= nslots; |
81 |
|
|
return locp; |
82 |
|
|
} |
83 |
|
|
|
84 |
|
|
static char * |
85 |
|
|
get_pdevnames(int idx) |
86 |
|
|
{ |
87 |
|
|
caddr_t *p; |
88 |
|
|
|
89 |
|
|
p = (caddr_t *)adjust((caddr_t)nl[P_PDEVNAMES].n_value + |
90 |
|
|
idx * sizeof(caddr_t)); |
91 |
|
|
return(char *)adjust((caddr_t)*p); |
92 |
|
|
|
93 |
|
|
} |
94 |
|
|
|
95 |
|
|
static struct pdevinit * |
96 |
|
|
get_pdevinit(int idx) |
97 |
|
|
{ |
98 |
|
|
return((struct pdevinit *)(adjust((caddr_t)nl[S_PDEVINIT].n_value) + |
99 |
|
|
idx * sizeof(struct pdevinit))); |
100 |
|
|
} |
101 |
|
|
|
102 |
|
|
int |
103 |
|
|
more(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); |
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 |
|
|
|
122 |
|
|
static void |
123 |
|
|
pnum(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 |
|
|
|
144 |
|
|
static void |
145 |
|
|
pdevnam(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_NOTFOUND: |
157 |
|
|
case FSTATE_DNOTFOUND: |
158 |
|
|
printf("%d", cd->cf_unit); |
159 |
|
|
break; |
160 |
|
|
case FSTATE_FOUND: |
161 |
|
|
printf("*FOUND*"); |
162 |
|
|
break; |
163 |
|
|
case FSTATE_STAR: |
164 |
|
|
case FSTATE_DSTAR: |
165 |
|
|
printf("*"); |
166 |
|
|
break; |
167 |
|
|
default: |
168 |
|
|
printf("*UNKNOWN*"); |
169 |
|
|
break; |
170 |
|
|
} |
171 |
|
|
} |
172 |
|
|
|
173 |
|
|
void |
174 |
|
|
pdev(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_NOTFOUND: |
223 |
|
|
case FSTATE_FOUND: |
224 |
|
|
case FSTATE_STAR: |
225 |
|
|
break; |
226 |
|
|
case FSTATE_DNOTFOUND: |
227 |
|
|
case FSTATE_DSTAR: |
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 |
|
|
|
247 |
|
|
static int |
248 |
|
|
numberl(const char *c, long *val) |
249 |
|
|
{ |
250 |
|
|
char *ep; |
251 |
|
|
|
252 |
|
|
errno = 0; |
253 |
|
|
*val = strtol(c, &ep, 0); |
254 |
|
|
if (*c == '\0' || (!isspace((unsigned char)*ep) && *ep != '\0') || |
255 |
|
|
(errno == ERANGE && (*val == LONG_MAX || *val == LONG_MIN))) |
256 |
|
|
return (-1); |
257 |
|
|
return (0); |
258 |
|
|
} |
259 |
|
|
|
260 |
|
|
int |
261 |
|
|
number(const char *c, int *val) |
262 |
|
|
{ |
263 |
|
|
long v; |
264 |
|
|
int ret = numberl(c, &v); |
265 |
|
|
|
266 |
|
|
if (ret == 0) { |
267 |
|
|
if (v <= INT_MAX && v >= INT_MIN) |
268 |
|
|
*val = (int)v; |
269 |
|
|
else |
270 |
|
|
ret = -1; |
271 |
|
|
} |
272 |
|
|
return (ret); |
273 |
|
|
} |
274 |
|
|
|
275 |
|
|
int |
276 |
|
|
device(char *cmd, int *len, short *unit, short *state) |
277 |
|
|
{ |
278 |
|
|
short u = 0, s = FSTATE_FOUND; |
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_STAR; |
290 |
|
|
c++; |
291 |
|
|
} else { |
292 |
|
|
while (*c >= '0' && *c <= '9') { |
293 |
|
|
s = FSTATE_NOTFOUND; |
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 |
|
|
|
310 |
|
|
int |
311 |
|
|
attr(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 |
|
|
|
340 |
|
|
static int |
341 |
|
|
modifyl(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); |
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 |
|
|
|
369 |
|
|
void |
370 |
|
|
modify(char *item, int *val) |
371 |
|
|
{ |
372 |
|
|
long a = *val; |
373 |
|
|
|
374 |
|
|
while (modifyl(item, &a)) { |
375 |
|
|
if (a <= INT_MAX && a >= INT_MIN) { |
376 |
|
|
*val = (int)a; |
377 |
|
|
break; |
378 |
|
|
} |
379 |
|
|
printf("Out of range argument\n"); |
380 |
|
|
} |
381 |
|
|
} |
382 |
|
|
|
383 |
|
|
void |
384 |
|
|
change(int devno) |
385 |
|
|
{ |
386 |
|
|
int i, share = 0; |
387 |
|
|
long *j = NULL, *l = NULL; |
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; |
429 |
|
|
|
430 |
|
|
j = l = get_extraloc(i); |
431 |
|
|
if (l == NULL) { |
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 |
|
|
|
484 |
|
|
void |
485 |
|
|
change_history(int devno, char *str) |
486 |
|
|
{ |
487 |
|
|
int i, share = 0; |
488 |
|
|
long *j = NULL, *l = NULL; |
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) { |
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 |
|
|
|
604 |
|
|
void |
605 |
|
|
disable(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_NOTFOUND: |
617 |
|
|
cd->cf_fstate = FSTATE_DNOTFOUND; |
618 |
|
|
break; |
619 |
|
|
case FSTATE_STAR: |
620 |
|
|
cd->cf_fstate = FSTATE_DSTAR; |
621 |
|
|
break; |
622 |
|
|
case FSTATE_DNOTFOUND: |
623 |
|
|
case FSTATE_DSTAR: |
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 |
|
|
|
668 |
|
|
void |
669 |
|
|
enable(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_DNOTFOUND: |
680 |
|
|
cd->cf_fstate = FSTATE_NOTFOUND; |
681 |
|
|
break; |
682 |
|
|
case FSTATE_DSTAR: |
683 |
|
|
cd->cf_fstate = FSTATE_STAR; |
684 |
|
|
break; |
685 |
|
|
case FSTATE_NOTFOUND: |
686 |
|
|
case FSTATE_STAR: |
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 |
|
|
|
730 |
|
|
void |
731 |
|
|
show(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 |
|
|
|
751 |
|
|
void |
752 |
|
|
common_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) { |
770 |
|
|
quit = more(); |
771 |
|
|
pdev(i); |
772 |
|
|
} else { |
773 |
|
|
if (*val == *l) { |
774 |
|
|
quit = more(); |
775 |
|
|
switch (routine) { |
776 |
|
|
case UC_ENABLE: |
777 |
|
|
enable(i); |
778 |
|
|
break; |
779 |
|
|
case UC_DISABLE: |
780 |
|
|
disable(i); |
781 |
|
|
break; |
782 |
|
|
case UC_SHOW: |
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 |
|
|
|
807 |
|
|
void |
808 |
|
|
show_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, UC_SHOW); |
842 |
|
|
} else { |
843 |
|
|
if (number(c, &a) == 0) { |
844 |
|
|
common_attr_val(attr, &a, UC_SHOW); |
845 |
|
|
} else { |
846 |
|
|
printf("Unknown argument\n"); |
847 |
|
|
} |
848 |
|
|
} |
849 |
|
|
} |
850 |
|
|
|
851 |
|
|
void |
852 |
|
|
common_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: |
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_FOUND || |
882 |
|
|
(state == FSTATE_STAR && |
883 |
|
|
(cd->cf_fstate == FSTATE_STAR || |
884 |
|
|
cd->cf_fstate == FSTATE_DSTAR)) || |
885 |
|
|
(state == FSTATE_NOTFOUND && |
886 |
|
|
cd->cf_unit == unit && |
887 |
|
|
(cd->cf_fstate == FSTATE_NOTFOUND || |
888 |
|
|
cd->cf_fstate == FSTATE_DNOTFOUND)))) { |
889 |
|
|
if (more()) |
890 |
|
|
break; |
891 |
|
|
switch (routine) { |
892 |
|
|
case UC_CHANGE: |
893 |
|
|
change(i); |
894 |
|
|
break; |
895 |
|
|
case UC_ENABLE: |
896 |
|
|
enable(i); |
897 |
|
|
break; |
898 |
|
|
case UC_DISABLE: |
899 |
|
|
disable(i); |
900 |
|
|
break; |
901 |
|
|
case UC_FIND: |
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_FOUND) { |
919 |
|
|
switch (routine) { |
920 |
|
|
case UC_CHANGE: |
921 |
|
|
change(totdev+1+i); |
922 |
|
|
break; |
923 |
|
|
case UC_ENABLE: |
924 |
|
|
enable(totdev+1+i); |
925 |
|
|
break; |
926 |
|
|
case UC_DISABLE: |
927 |
|
|
disable(totdev+1+i); |
928 |
|
|
break; |
929 |
|
|
case UC_FIND: |
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: |
943 |
|
|
break; |
944 |
|
|
default: |
945 |
|
|
cnt = -1; |
946 |
|
|
break; |
947 |
|
|
} |
948 |
|
|
} |
949 |
|
|
|
950 |
|
|
void |
951 |
|
|
common_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 |
|
|
|
977 |
|
|
void |
978 |
|
|
add_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); |
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_FOUND, UC_FIND); |
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 |
|
|
|
1029 |
|
|
void |
1030 |
|
|
add(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_FOUND) { |
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_SIZE].n_value); |
1092 |
|
|
pv = (short *)adjust((caddr_t)nl[SA_PV].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_SIZE].n_value); |
1101 |
|
|
pv = (short *)adjust((caddr_t)nl[SA_CFROOTS].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_NOTFOUND: |
1125 |
|
|
case FSTATE_DNOTFOUND: |
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_NOTFOUND: |
1152 |
|
|
case FSTATE_DNOTFOUND: |
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_STAR: |
1174 |
|
|
case FSTATE_DSTAR: |
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 |
|
|
|
1193 |
|
|
void |
1194 |
|
|
add_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_SIZE].n_value); |
1228 |
|
|
pv = (short *)adjust((caddr_t)nl[SA_PV].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_SIZE].n_value); |
1237 |
|
|
pv = (short *)adjust((caddr_t)nl[SA_CFROOTS].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_NOTFOUND: |
1258 |
|
|
case FSTATE_DNOTFOUND: |
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_STAR: |
1281 |
|
|
case FSTATE_DSTAR: |
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 |
|
|
|
1297 |
|
|
int |
1298 |
|
|
config(void) |
1299 |
|
|
{ |
1300 |
|
|
cmd_t cmd; |
1301 |
|
|
int i, st; |
1302 |
|
|
|
1303 |
|
|
/* Set up command table pointer */ |
1304 |
|
|
cmd.table = cmd_table; |
1305 |
|
|
|
1306 |
|
|
printf("Enter 'help' for information\n"); |
1307 |
|
|
|
1308 |
|
|
/* Edit cycle */ |
1309 |
|
|
do { |
1310 |
|
|
again: |
1311 |
|
|
printf("ukc> "); |
1312 |
|
|
fflush(stdout); |
1313 |
|
|
ask_cmd(&cmd); |
1314 |
|
|
|
1315 |
|
|
if (cmd.cmd[0] == '\0') |
1316 |
|
|
goto again; |
1317 |
|
|
for (i = 0; cmd_table[i].cmd != NULL; i++) |
1318 |
|
|
if (strstr(cmd_table[i].cmd, cmd.cmd) == |
1319 |
|
|
cmd_table[i].cmd) |
1320 |
|
|
break; |
1321 |
|
|
|
1322 |
|
|
/* Quick hack to put in '?' == 'help' */ |
1323 |
|
|
if (!strcmp(cmd.cmd, "?")) |
1324 |
|
|
i = 0; |
1325 |
|
|
|
1326 |
|
|
/* Check for valid command */ |
1327 |
|
|
if (cmd_table[i].cmd == NULL) { |
1328 |
|
|
printf("Invalid command '%s'. Try 'help'.\n", cmd.cmd); |
1329 |
|
|
continue; |
1330 |
|
|
} else |
1331 |
|
|
strlcpy(cmd.cmd, cmd_table[i].cmd, sizeof cmd.cmd); |
1332 |
|
|
|
1333 |
|
|
/* Call function */ |
1334 |
|
|
st = cmd_table[i].fcn(&cmd); |
1335 |
|
|
|
1336 |
|
|
/* Update status */ |
1337 |
|
|
if (st == CMD_EXIT) |
1338 |
|
|
break; |
1339 |
|
|
if (st == CMD_SAVE) |
1340 |
|
|
break; |
1341 |
|
|
} while (1); |
1342 |
|
|
|
1343 |
|
|
return (st == CMD_SAVE); |
1344 |
|
|
} |
1345 |
|
|
|
1346 |
|
|
void |
1347 |
|
|
process_history(int len, char *buf) |
1348 |
|
|
{ |
1349 |
|
|
char *c; |
1350 |
|
|
int devno, newno; |
1351 |
|
|
short unit, state; |
1352 |
|
|
struct timezone *tz; |
1353 |
|
|
|
1354 |
|
|
if (len == 0) { |
1355 |
|
|
printf("History is empty\n"); |
1356 |
|
|
return; |
1357 |
|
|
} |
1358 |
|
|
|
1359 |
|
|
printf("Processing history...\n"); |
1360 |
|
|
|
1361 |
|
|
buf[len] = 0; |
1362 |
|
|
|
1363 |
|
|
c = buf; |
1364 |
|
|
|
1365 |
|
|
while (*c != '\0') { |
1366 |
|
|
switch (*c) { |
1367 |
|
|
case 'a': |
1368 |
|
|
c++; |
1369 |
|
|
c++; |
1370 |
|
|
devno = atoi(c); |
1371 |
|
|
while (*c >= '0' && *c <= '9') |
1372 |
|
|
c++; |
1373 |
|
|
c++; |
1374 |
|
|
unit = atoi(c); |
1375 |
|
|
if (*c == '-') c++; |
1376 |
|
|
while (*c >= '0' && *c <= '9') |
1377 |
|
|
c++; |
1378 |
|
|
c++; |
1379 |
|
|
state = atoi(c); |
1380 |
|
|
if (*c == '-') |
1381 |
|
|
c++; |
1382 |
|
|
while (*c >= '0' && *c <= '9') |
1383 |
|
|
c++; |
1384 |
|
|
c++; |
1385 |
|
|
newno = atoi(c); |
1386 |
|
|
while (*c >= '0' && *c <= '9') |
1387 |
|
|
c++; |
1388 |
|
|
add_history(devno, unit, state, newno); |
1389 |
|
|
while (*c != '\n') |
1390 |
|
|
c++; |
1391 |
|
|
c++; |
1392 |
|
|
break; |
1393 |
|
|
case 'c': |
1394 |
|
|
c++; |
1395 |
|
|
c++; |
1396 |
|
|
devno = atoi(c); |
1397 |
|
|
while (*c >= '0' && *c <= '9') |
1398 |
|
|
c++; |
1399 |
|
|
if (*c == ' ') |
1400 |
|
|
c++; |
1401 |
|
|
if (*c != '\n') |
1402 |
|
|
change_history(devno, c); |
1403 |
|
|
while (*c != '\n') |
1404 |
|
|
c++; |
1405 |
|
|
c++; |
1406 |
|
|
break; |
1407 |
|
|
case 'd': |
1408 |
|
|
c++; |
1409 |
|
|
devno = atoi(c); |
1410 |
|
|
disable(devno); |
1411 |
|
|
while (*c != '\n') |
1412 |
|
|
c++; |
1413 |
|
|
c++; |
1414 |
|
|
break; |
1415 |
|
|
case 'e': |
1416 |
|
|
c++; |
1417 |
|
|
devno = atoi(c); |
1418 |
|
|
enable(devno); |
1419 |
|
|
while (*c != '\n') |
1420 |
|
|
c++; |
1421 |
|
|
c++; |
1422 |
|
|
break; |
1423 |
|
|
case 't': |
1424 |
|
|
c++; |
1425 |
|
|
c++; |
1426 |
|
|
tz = (struct timezone *)adjust((caddr_t)nl[TZ_TZ]. |
1427 |
|
|
n_value); |
1428 |
|
|
tz->tz_minuteswest = atoi(c); |
1429 |
|
|
while (*c != ' ') |
1430 |
|
|
c++; |
1431 |
|
|
c++; |
1432 |
|
|
tz->tz_dsttime = atoi(c); |
1433 |
|
|
while (*c != '\n') |
1434 |
|
|
c++; |
1435 |
|
|
c++; |
1436 |
|
|
ukc_mod_kernel = 1; |
1437 |
|
|
break; |
1438 |
|
|
case 'q': |
1439 |
|
|
while (*c != '\0') |
1440 |
|
|
c++; |
1441 |
|
|
break; |
1442 |
|
|
default: |
1443 |
|
|
printf("unknown command %c\n", *c); |
1444 |
|
|
while (*c != '\0' && *c != '\n') |
1445 |
|
|
c++; |
1446 |
|
|
break; |
1447 |
|
|
} |
1448 |
|
|
} |
1449 |
|
|
} |