]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/hwinfo/hwscan.c
Kleiner netter neuer Versuch.
[people/pmueller/ipfire-2.x.git] / src / hwinfo / hwscan.c
CommitLineData
a6316ce4
MT
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <getopt.h>
6
7#include "hd.h"
8#include "hd_int.h"
9
10struct option options[] = {
11 { "help", 0, NULL, 'h' },
12 { "verbose", 0, NULL, 'v' },
13 { "version", 0, NULL, 400 },
14 { "show", 1, NULL, 500 },
15 { "list", 0, NULL, 501 },
16 { "cfg", 1, NULL, 502 },
17 { "avail", 1, NULL, 503 },
18 { "need", 1, NULL, 504 },
19 { "new", 0, NULL, 505 },
20 { "fast", 0, NULL, 506 },
21 { "silent", 0, NULL, 507 },
22 { "boot", 0, NULL, 508 },
23 { "active", 1, NULL, 509 },
24 { "only", 1, NULL, 510 },
25 { "sys", 0, NULL, 1000 + hw_sys },
26 { "cpu", 0, NULL, 1000 + hw_cpu },
27 { "keyboard", 0, NULL, 1000 + hw_keyboard },
28 { "braille", 0, NULL, 1000 + hw_braille },
29 { "mouse", 0, NULL, 1000 + hw_mouse },
30 { "joystick", 0, NULL, 1000 + hw_joystick },
31 { "printer", 0, NULL, 1000 + hw_printer },
32 { "scanner", 0, NULL, 1000 + hw_scanner },
33 { "chipcard", 0, NULL, 1000 + hw_chipcard },
34 { "monitor", 0, NULL, 1000 + hw_monitor },
35 { "tv", 0, NULL, 1000 + hw_tv },
36 { "gfxcard", 0, NULL, 1000 + hw_display },
37 { "framebuffer", 0, NULL, 1000 + hw_framebuffer },
38 { "camera", 0, NULL, 1000 + hw_camera },
39 { "sound", 0, NULL, 1000 + hw_sound },
40 { "storage-ctrl", 0, NULL, 1000 + hw_storage_ctrl },
41 { "storage_ctrl", 0, NULL, 1000 + hw_storage_ctrl },
42 { "netcard", 0, NULL, 1000 + hw_network_ctrl },
43 { "network-ctrl", 0, NULL, 1000 + hw_network_ctrl },
44 { "network_ctrl", 0, NULL, 1000 + hw_network_ctrl },
45 { "isdn", 0, NULL, 1000 + hw_isdn },
46 { "modem", 0, NULL, 1000 + hw_modem },
47 { "network", 0, NULL, 1000 + hw_network },
48 { "disk", 0, NULL, 1000 + hw_disk },
49 { "partition", 0, NULL, 1000 + hw_partition },
50 { "cdrom", 0, NULL, 1000 + hw_cdrom },
51 { "floppy", 0, NULL, 1000 + hw_floppy },
52 { "update", 0, NULL, 1000 + hw_manual },
53 { "usb-ctrl", 0, NULL, 1000 + hw_usb_ctrl },
54 { "usb_ctrl", 0, NULL, 1000 + hw_usb_ctrl },
55 { "usb", 0, NULL, 1000 + hw_usb },
56 { "bios", 0, NULL, 1000 + hw_bios },
57 { "pci", 0, NULL, 1000 + hw_pci },
58 { "isapnp", 0, NULL, 1000 + hw_isapnp },
59 { "bridge", 0, NULL, 1000 + hw_bridge },
60 { "hub", 0, NULL, 1000 + hw_hub },
61 { "scsi", 0, NULL, 1000 + hw_scsi },
62 { "ide", 0, NULL, 1000 + hw_ide },
63 { "memory", 0, NULL, 1000 + hw_memory },
64 { "dvb", 0, NULL, 1000 + hw_dvb },
65 { "pcmcia", 0, NULL, 1000 + hw_pcmcia },
66 { "pcmcia_ctrl", 0, NULL, 1000 + hw_pcmcia_ctrl },
67 { "ieee1394", 0, NULL, 1000 + hw_ieee1394 },
68 { "firewire", 0, NULL, 1000 + hw_ieee1394 },
69 { "ieee1394_ctrl", 0, NULL, 1000 + hw_ieee1394_ctrl },
70 { "firewire_ctrl", 0, NULL, 1000 + hw_ieee1394_ctrl },
71 { "hotplug", 0, NULL, 1000 + hw_hotplug },
72 { "hotplug_ctrl", 0, NULL, 1000 + hw_hotplug_ctrl },
73 { "zip", 0, NULL, 1000 + hw_zip },
74 { "pppoe", 0, NULL, 1000 + hw_pppoe },
75 { "dsl", 0, NULL, 1000 + hw_dsl },
76 { "wlan", 0, NULL, 1000 + hw_wlan },
77 { "block", 0, NULL, 1000 + hw_block },
78 { "tape", 0, NULL, 1000 + hw_tape },
79 { "vbe", 0, NULL, 1000 + hw_vbe },
80 { "bluetooth", 0, NULL, 1000 + hw_bluetooth },
81 { "all", 0, NULL, 1000 + hw_all },
82 { }
83};
84
85int verbose = 0;
86hd_hw_item_t scan_item[100] = { };
87unsigned scan_items = 0;
88int found_items = 0;
89
90struct {
91 unsigned show:1;
92 unsigned scan:1;
93 unsigned list:1;
94 unsigned config_cfg:1;
95 unsigned config_avail:1;
96 unsigned config_need:1;
97 unsigned config_active:1;
98 unsigned new:1;
99 unsigned fast:1;
100 unsigned silent:1;
101 unsigned boot:1;
102 str_list_t *only;
103} opt;
104
105void help(void);
106int do_scan(hd_hw_item_t *items);
107int do_show(char *id);
108int do_list(hd_hw_item_t *items);
109int do_config(int type, char *val, char *id);
110int fast_ok(hd_hw_item_t *items);
111int has_item(hd_hw_item_t *items, hd_hw_item_t item);
112int has_hw_class(hd_t *hd, hd_hw_item_t *items);
113
114
115int main(int argc, char **argv)
116{
117 int rc = 0;
118
119#ifndef LIBHD_TINY
120
121 char *id = NULL;
122 char *config_cfg = NULL;
123 char *config_avail = NULL;
124 char *config_need = NULL;
125 char *config_active = NULL;
126 int i;
127 int ok = 0;
128 FILE *f;
129
130 opterr = 0;
131
132 while((i = getopt_long(argc, argv, "hv", options, NULL)) != -1) {
133 switch(i) {
134 case 'v':
135 verbose++;
136 break;
137
138 case 400:
139 printf("%s\n", hd_version());
140 ok = 1;
141 break;
142
143 case 500:
144 opt.show = 1;
145 id = optarg;
146 break;
147
148 case 501:
149 opt.list = 1;
150 break;
151
152 case 502:
153 opt.config_cfg = 1;
154 config_cfg = optarg;
155 break;
156
157 case 503:
158 opt.config_avail = 1;
159 config_avail = optarg;
160 break;
161
162 case 504:
163 opt.config_need = 1;
164 config_need = optarg;
165 break;
166
167 case 505:
168 opt.new = 1;
169 break;
170
171 case 506:
172 opt.fast = 1;
173 break;
174
175 case 507:
176 opt.silent = 1;
177 break;
178
179 case 508:
180 opt.boot = 1;
181 break;
182
183 case 509:
184 opt.config_active = 1;
185 config_active = optarg;
186 break;
187
188 case 510:
189 if(*optarg) add_str_list(&opt.only, optarg);
190 break;
191
192 case 1000 ... 1100:
193 opt.scan = 1;
194 if(scan_items + 1 < sizeof scan_item / sizeof *scan_item) {
195 scan_item[scan_items++] = i - 1000;
196 }
197 break;
198
199 default:
200 help();
201 return 1;
202 }
203 }
204
205 scan_item[scan_items] = 0;
206
207 if(opt.scan && !opt.list) {
208 if(argv[optind] || !scan_items) return help(), 1;
209 rc = do_scan(scan_item);
210 if(found_items) {
211 unlink(HARDWARE_DIR "/.update"); /* the old file */
212 unlink(HARDWARE_UNIQUE_KEYS "/.update"); /* so we trigger a rescan */
213 if((f = fopen(HARDWARE_UNIQUE_KEYS "/.update", "a"))) fclose(f);
214 }
215 ok = 1;
216 }
217
218 if(opt.show) {
219 do_show(id);
220 ok = 1;
221 }
222
223 if(opt.list) {
224 do_list(scan_item);
225 ok = 1;
226 }
227
228 if(opt.config_cfg) {
229 if(!argv[optind]) return help(), 1;
230 do_config(1, config_cfg, argv[optind]);
231 ok = 1;
232 }
233
234 if(opt.config_avail) {
235 if(!argv[optind]) return help(), 1;
236 do_config(2, config_avail, argv[optind]);
237 ok = 1;
238 }
239
240 if(opt.config_need) {
241 if(!argv[optind]) return help(), 1;
242 do_config(3, config_need, argv[optind]);
243 ok = 1;
244 }
245
246 if(opt.config_active) {
247 if(!argv[optind]) return help(), 1;
248 do_config(4, config_active, argv[optind]);
249 ok = 1;
250 }
251
252 if(!ok) help();
253
254#endif /* !defined(LIBHD_TINY) */
255
256 return rc;
257}
258
259void help()
260{
261 fprintf(stderr,
262 "Usage: hwscan [options]\n"
263 "Show information about currently known hardware.\n"
264 " --list show list of known hardware\n"
265 " --version show libhd version\n"
266 " --silent don't show hardware config changes\n"
267 " --boot run only if we haven't been disabled via 'hwprobe=-scan'\n"
268 " --cfg=state id change 'configured' status; id is one of the\n"
269 " ids from 'hwscan --list'\n"
270 " state is one of new, no, yes\n"
271 " --avail=state id change 'available' status\n"
272 " --need=state id change 'needed' status\n"
273 " --active=state id change 'active' status\n"
274 " --hw_item probe for hw_item and update status info\n"
275 " hw_item is one of:\n"
276 " all, bios, block, bluetooth, braille, bridge, camera, cdrom, chipcard, cpu,\n"
277 " disk, dsl, dvb, floppy, framebuffer, gfxcard, hub, ide, isapnp, isdn,\n"
278 " joystick, keyboard, memory, modem, monitor, mouse, netcard, network,\n"
279 " partition, pci, pcmcia, pcmcia-ctrl, pppoe, printer, scanner, scsi, smp,\n"
280 " sound, storage-ctrl, sys, tape, tv, usb, usb-ctrl, vbe, wlan, zip\n"
281 );
282}
283
284#ifndef LIBHD_TINY
285
286int do_scan(hd_hw_item_t *items)
287{
288 int run_config = 0;
289 hd_status_t status = { };
290 hd_data_t *hd_data;
291 hd_t *hd, *hd1;
292 int err = 0;
293
294 if(opt.fast) opt.fast = fast_ok(items);
295
296 hd_data = calloc(1, sizeof *hd_data);
297
298 if(opt.boot) {
299 /* look if we have been disabled */
300 hd_clear_probe_feature(hd_data, pr_all);
301 hd_scan(hd_data);
302 hd_set_probe_feature(hd_data, pr_scan);
303 if(!hd_probe_feature(hd_data, pr_scan)) {
304 hd_free_hd_data(hd_data);
305 free(hd_data);
306 return 0;
307 }
308 }
309
310 hd_data->only = opt.only;
311 opt.only = NULL;
312
313 hd_data->flags.list_all = 1;
314 hd_data->flags.fast = opt.fast;
315
316 hd = hd_list2(hd_data, items, 1);
317
318 if(hd) found_items = 1;
319
320 for(hd1 = hd; hd1; hd1 = hd1->next) {
321 err = hd_write_config(hd_data, hd1);
322 if(verbose >= 2) {
323 printf(
324 "write=%d %s: (cfg=%s, avail=%s, need=%s, active=%s",
325 err,
326 hd1->unique_id,
327 hd_status_value_name(hd1->status.configured),
328 hd_status_value_name(hd1->status.available),
329 hd_status_value_name(hd1->status.needed),
330 hd_status_value_name(hd1->status.active)
331 );
332 if(hd1->unix_dev_name) {
333 printf(", dev=%s", hd1->unix_dev_name);
334 }
335 printf(
336 ") %s\n",
337 hd1->model
338 );
339
340 }
341 if(err) break;
342 }
343
344 if(err) {
345 fprintf(stderr,
346 "Error writing configuration for %s (%s)\n",
347 hd1->unique_id,
348 hd1->model
349 );
350 exit(1);
351 }
352
353 hd = hd_free_hd_list(hd);
354
355 if(opt.new) {
356 status.configured = status_new;
357 }
358 else {
359 status.reconfig = status_yes;
360 }
361
362 hd = hd_list_with_status2(hd_data, items, status);
363 if(hd) run_config = 1;
364
365 if(verbose) {
366 for(hd1 = hd; hd1; hd1 = hd1->next) {
367 printf(
368 "%s: (cfg=%s, avail=%s, need=%s, active=%s",
369 hd1->unique_id,
370 hd_status_value_name(hd1->status.configured),
371 hd_status_value_name(hd1->status.available),
372 hd_status_value_name(hd1->status.needed),
373 hd_status_value_name(hd1->status.active)
374 );
375 if(hd1->unix_dev_name) {
376 printf(", dev=%s", hd1->unix_dev_name);
377 }
378 printf(
379 ") %s\n",
380 hd1->model
381 );
382 }
383 }
384 else if(!opt.silent) {
385 for(hd1 = hd; hd1; hd1 = hd1->next) printf("%s\n", hd1->unique_id);
386 }
387
388 hd = hd_free_hd_list(hd);
389
390 hd_free_hd_data(hd_data);
391 free(hd_data);
392
393 return run_config ^ 1;
394}
395
396
397int do_show(char *id)
398{
399 hd_data_t *hd_data;
400 hd_t *hd;
401
402 hd_data = calloc(1, sizeof *hd_data);
403
404 if ( id[0] == '/' ){
405 int nr=0;
406 char *_id = 0;
407 hd_t *hd_manual;
408
409 hd_manual = hd_list(hd_data, hw_manual, 1, NULL);
410 for(hd = hd_manual; hd; hd = hd->next) {
411 if(hd->status.available != status_yes) continue;
412 if(!search_str_list(hd->unix_dev_names, id)) continue;
413 _id = hd->unique_id;
414 nr++;
415 }
416
417 if ( nr == 1 ) /* > 1 means our database is not okay */
418 hd = hd_read_config(hd_data, _id);
419 }else
420 hd = hd_read_config(hd_data, id);
421
422 if(hd) {
423 hd_data->debug = -1;
424 hd_dump_entry(hd_data, hd, stdout);
425 hd = hd_free_hd_list(hd);
426 }
427 else {
428 printf("no such hardware item: %s\n", id);
429 }
430
431 hd_free_hd_data(hd_data);
432 free(hd_data);
433
434 return 0;
435}
436
437
438int do_list(hd_hw_item_t *items)
439{
440 hd_data_t *hd_data;
441 hd_t *hd, *hd_manual;
442 char *s;
443 char status[64];
444 int i;
445
446 hd_data = calloc(1, sizeof *hd_data);
447
448 hd_manual = hd_list(hd_data, hw_manual, 1, NULL);
449
450 for(hd = hd_manual; hd; hd = hd->next) {
451 if(opt.scan && ! has_hw_class(hd, items)) continue;
452
453 strcpy(status, "(");
454
455 i = 0;
456 if(hd->status.configured && (s = hd_status_value_name(hd->status.configured))) {
457 sprintf(status + strlen(status), "%scfg=%s", i ? ", " : "", s);
458 i++;
459 }
460
461 if(hd->status.available && (s = hd_status_value_name(hd->status.available))) {
462 sprintf(status + strlen(status), "%savail=%s", i ? ", " : "", s);
463 i++;
464 }
465
466 if(hd->status.needed && (s = hd_status_value_name(hd->status.needed))) {
467 sprintf(status + strlen(status), "%sneed=%s", i ? ", " : "", s);
468 i++;
469 }
470
471 if(hd->status.active && (s = hd_status_value_name(hd->status.active))) {
472 sprintf(status + strlen(status), "%sactive=%s", i ? ", " : "", s);
473 i++;
474 }
475
476 strcat(status, ")");
477
478 s = hd_hw_item_name(hd->hw_class);
479 if(!s) s = "???";
480
481 printf("%s: %-32s %-16s %s\n", hd->unique_id, status, s, hd->model);
482 if(hd->config_string) {
483 printf(" configured as: \"%s\"\n", hd->config_string);
484 }
485 }
486
487 hd_free_hd_list(hd_manual);
488
489 hd_free_hd_data(hd_data);
490 free(hd_data);
491
492 return 0;
493}
494
495
496int do_config(int type, char *val, char *id)
497{
498 hd_data_t *hd_data;
499 hd_t *hd;
500 hd_status_value_t status = 0;
501 int i;
502 char *s;
503
504 hd_data = calloc(1, sizeof *hd_data);
505
506 if ( id[0] == '/' ){
507 int nr=0;
508 char *_id = 0;
509 hd_t *hd_manual;
510
511 hd_manual = hd_list(hd_data, hw_manual, 1, NULL);
512 for(hd = hd_manual; hd; hd = hd->next) {
513 if(hd->status.available != status_yes) continue;
514 if(!search_str_list(hd->unix_dev_names, id)) continue;
515 _id = hd->unique_id;
516 nr++;
517 }
518 if ( nr == 1 )
519 hd = hd_read_config(hd_data, _id);
520 }else
521 hd = hd_read_config(hd_data, id);
522
523 if(hd) {
524 for(i = 1; i < 8; i++) {
525 s = hd_status_value_name(i);
526 if(s && !strcmp(val, s)) {
527 status = i;
528 break;
529 }
530 }
531 if(!status) {
532 printf("invalid status: %s\n", val);
533 }
534 else {
535 switch(type) {
536 case 1:
537 hd->status.configured = status;
538 break;
539
540 case 2:
541 hd->status.available = status;
542 break;
543
544 case 3:
545 hd->status.needed = status;
546 break;
547
548 case 4:
549 hd->status.active = status;
550 break;
551 }
552 hd_write_config(hd_data, hd);
553 }
554 hd = hd_free_hd_list(hd);
555 }
556 else {
557 printf("no such hardware item: %s\n", id);
558 }
559
560 hd_free_hd_data(hd_data);
561 free(hd_data);
562
563 return 0;
564}
565
566
567/*
568 * Check whether a 'fast' scan would suffice to re-check the presence
569 * of all known hardware.
570 */
571int fast_ok(hd_hw_item_t *items)
572{
573 hd_data_t *hd_data;
574 hd_t *hd, *hd1;
575 int ok = 1;
576
577 if(!has_item(items, hw_mouse) && !has_item(items, hw_storage_ctrl)) {
578 return 1;
579 }
580
581 hd_data = calloc(1, sizeof *hd_data);
582
583 hd_data->flags.list_all = 1;
584
585 hd = hd_list(hd_data, hw_manual, 1, NULL);
586
587 for(hd1 = hd; hd1; hd1 = hd1->next) {
588 /* serial mice */
589 if(hd1->hw_class == hw_mouse && hd1->bus.id == bus_serial) {
590 ok = 0;
591 break;
592 }
593 /* parallel zip */
594 if(hd1->hw_class == hw_storage_ctrl && hd1->bus.id == bus_parallel) {
595 ok = 0;
596 break;
597 }
598 }
599
600 hd_free_hd_data(hd_data);
601 free(hd_data);
602
603 return ok;
604}
605
606
607/* check if item is in items */
608int has_item(hd_hw_item_t *items, hd_hw_item_t item)
609{
610 while(*items) if(*items++ == item) return 1;
611
612 return 0;
613}
614
615
616/* check if one of items is in hw_class */
617int has_hw_class(hd_t *hd, hd_hw_item_t *items)
618{
619 while(*items) if(hd_is_hw_class(hd, *items++)) return 1;
620
621 return 0;
622}
623
624
625#endif /* !defined(LIBHD_TINY) */