Mercurial > hg > toybox
comparison toys/other/lspci.c @ 1432:cd5c62119391 draft
Promote lspci.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 11 Aug 2014 20:15:19 -0500 |
parents | toys/pending/lspci.c@e36306d6eece |
children | e85e5f3b87c2 |
comparison
equal
deleted
inserted
replaced
1431:e36306d6eece | 1432:cd5c62119391 |
---|---|
1 /* | |
2 * lspci - written by Isaac Dunham | |
3 | |
4 USE_LSPCI(NEWTOY(lspci, "emkn"USE_LSPCI_TEXT("@i:"), TOYFLAG_USR|TOYFLAG_BIN)) | |
5 | |
6 config LSPCI | |
7 bool "lspci" | |
8 default y | |
9 help | |
10 usage: lspci [-ekm] | |
11 | |
12 List PCI devices. | |
13 | |
14 -e Print all 6 digits in class | |
15 -k Print kernel driver | |
16 -m Machine parseable format | |
17 | |
18 config LSPCI_TEXT | |
19 bool "lspci readable output" | |
20 depends on LSPCI | |
21 default y | |
22 help | |
23 usage: lspci [-n] [-i FILE ] | |
24 | |
25 -n Numeric output (repeat for readable and numeric) | |
26 -i PCI ID database (default /usr/share/misc/pci.ids) | |
27 | |
28 */ | |
29 | |
30 #define FOR_lspci | |
31 #include "toys.h" | |
32 | |
33 GLOBALS( | |
34 char *ids; | |
35 long numeric; | |
36 | |
37 FILE *db; | |
38 ) | |
39 | |
40 int do_lspci(struct dirtree *new) | |
41 { | |
42 char *p = toybuf, *vendor = toybuf+9, *device = toybuf+18, | |
43 driver[256], *vbig = 0, *dbig = 0, **fields; | |
44 int dirfd; | |
45 | |
46 if (!new->parent) return DIRTREE_RECURSE; | |
47 | |
48 // Parse data out of /proc | |
49 | |
50 if (-1 == (dirfd = openat(dirtree_parentfd(new), new->name, O_RDONLY))) | |
51 return 0; | |
52 | |
53 *driver = 0; | |
54 if (toys.optflags & FLAG_k) | |
55 readlinkat(dirfd, "driver", driver, sizeof(driver)); | |
56 | |
57 for (fields = (char*[]){"class", "vendor", "device", 0}; *fields; fields++) { | |
58 int fd, size = 6 + 2*((toys.optflags & FLAG_e) && p == toybuf); | |
59 *p = 0; | |
60 | |
61 if (-1 == (fd = openat(dirfd, *fields, O_RDONLY))) { | |
62 close(dirfd); | |
63 return 0; | |
64 } | |
65 xreadall(fd, p, size); | |
66 memmove(p, p+2, size -= 2); | |
67 p[size] = 0; | |
68 close(fd); | |
69 p += 9; | |
70 } | |
71 | |
72 close(dirfd); | |
73 | |
74 // Lookup/display data from pci.ids? | |
75 | |
76 if (CFG_LSPCI_TEXT && TT.db) { | |
77 if (TT.numeric != 1) { | |
78 char *s; | |
79 | |
80 fseek(TT.db, 0, SEEK_SET); | |
81 while (!vbig || !dbig) { | |
82 s = p; | |
83 if (!fgets(s, sizeof(toybuf)-(p-toybuf)-1, TT.db)) break; | |
84 while (isspace(*s)) s++; | |
85 if (*s == '#') continue; | |
86 if (vbig && s == p) break; | |
87 if (strstart(&s, vbig ? device : vendor)) { | |
88 if (vbig) dbig = s+2; | |
89 else vbig = s+2; | |
90 s += strlen(s); | |
91 s[-1] = 0; // trim ending newline | |
92 p = s + 1; | |
93 } | |
94 } | |
95 } | |
96 | |
97 if (TT.numeric > 1) { | |
98 printf((toys.optflags & FLAG_m) | |
99 ? "%s, \"%s\" \"%s [%s]\" \"%s [%s]\"" | |
100 : "%s Class %s: %s [%s] %s [%s]", | |
101 new->name+5, toybuf, vbig ? vbig : "", vendor, | |
102 dbig ? dbig : "", device); | |
103 | |
104 goto driver; | |
105 } | |
106 } | |
107 | |
108 printf((toys.optflags & FLAG_m) ? "%s \"%s\" \"%s\" \"%s\"" | |
109 : "%s Class %s: %s:%s", new->name+5, toybuf, | |
110 vbig ? vbig : vendor, dbig ? dbig : device); | |
111 | |
112 driver: | |
113 if (*driver) | |
114 printf((toys.optflags & FLAG_m) ? " \"%s\"" : " %s", basename(driver)); | |
115 xputc('\n'); | |
116 | |
117 return 0; | |
118 } | |
119 | |
120 void lspci_main(void) | |
121 { | |
122 if (CFG_LSPCI_TEXT && TT.numeric != 1) { | |
123 if (!TT.ids) TT.ids = "/usr/share/misc/pci.ids"; | |
124 if (!(TT.db = fopen(TT.ids, "r"))) | |
125 perror_msg("could not open PCI ID db"); | |
126 } | |
127 | |
128 dirtree_read("/sys/bus/pci/devices", do_lspci); | |
129 } |