Mercurial > hg > toybox
comparison toys/pending/lspci.c @ 1289:9b3818b2a054 draft
Cleanup pass on lspci
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 18 May 2014 13:08:36 -0500 |
parents | 8caeba551a28 |
children | 5f59ec6e38ff |
comparison
equal
deleted
inserted
replaced
1288:ecec71144ddd | 1289:9b3818b2a054 |
---|---|
1 /* | 1 /* |
2 * lspci - written by Isaac Dunham | 2 * lspci - written by Isaac Dunham |
3 | 3 |
4 USE_LSPCI(NEWTOY(lspci, "emkn@", TOYFLAG_USR|TOYFLAG_BIN)) | 4 USE_LSPCI(NEWTOY(lspci, "emk"USE_LSPCI_TEXT("n@"), TOYFLAG_USR|TOYFLAG_BIN)) |
5 | 5 |
6 config LSPCI | 6 config LSPCI |
7 bool "lspci" | 7 bool "lspci" |
8 default n | 8 default n |
9 help | 9 help |
10 usage: lspci [-ekmn@] | 10 usage: lspci [-ekm] |
11 | 11 |
12 List PCI devices. | 12 List PCI devices. |
13 -e Print all 6 digits in class (like elspci) | 13 |
14 -k Print kernel driver | 14 -e Print all 6 digits in class (like elspci) |
15 -m Machine parseable format | 15 -k Print kernel driver |
16 -n Numeric output | 16 -m Machine parseable format |
17 | 17 |
18 config LSPCI_TEXT | 18 config LSPCI_TEXT |
19 bool "lspci readable output" | 19 bool "lspci readable output" |
20 depends on LSPCI | 20 depends on LSPCI |
21 default n | 21 default n |
22 help | 22 help |
23 lspci without -n prints readable descriptions; | 23 usage: lspci [-n] |
24 lspci -nn prints both readable and numeric description | 24 |
25 -n Numeric output (repeat for readable and numeric) | |
25 */ | 26 */ |
27 | |
26 #define FOR_lspci | 28 #define FOR_lspci |
27 #include "toys.h" | 29 #include "toys.h" |
28 extern int find_in_db(char * , char * , FILE * , char * , char * ); | |
29 | 30 |
30 GLOBALS( | 31 GLOBALS( |
31 long numeric; | 32 long numeric; |
32 | 33 |
33 FILE * db; | 34 FILE *db; |
34 ) | 35 ) |
35 | 36 |
36 char * id_check_match(char * id, char * buf) | 37 char *id_check_match(char *id, char *buf) |
37 { | 38 { |
38 int i = 0; | 39 int i = 0; |
40 | |
39 while (id[i]) { | 41 while (id[i]) { |
40 if (id[i] == buf[i]) { | 42 if (id[i] == buf[i]) i++; |
41 i++; | 43 else return 0; |
42 } else { | |
43 return (char *)0L; | |
44 } | |
45 } | 44 } |
46 return (buf + i + 2); | 45 return buf + i + 2; |
47 } | 46 } |
48 | 47 |
49 /* | 48 /* |
50 * In: vendid, devid, fil | 49 * In: vendid, devid, fil |
51 * Out: vname, devname | 50 * Out: vname, devname |
52 * Out must be zeroed before use. | 51 * Out must be zeroed before use. |
53 * vmame and devname must be char[256], zeroed out | 52 * vmame and devname must be char[256], zeroed out |
54 * Returns (2 - number of IDs matched): vendor must be matched for | 53 * Returns (2 - number of IDs matched): vendor must be matched for |
55 * dev to be matched | 54 * dev to be matched |
56 */ | 55 */ |
57 int find_in_db(char * vendid, char * devid, FILE * fil, | 56 int find_in_db(char *vendid, char *devid, FILE *fil, char *vname, char *devname) |
58 char * vname, char * devname) | |
59 { | 57 { |
58 char buf[256], *vtext = 0L, *dtext = 0L; | |
59 | |
60 fseek(fil, 0, SEEK_SET); | 60 fseek(fil, 0, SEEK_SET); |
61 char buf[256], *vtext = 0L, *dtext = 0L; | 61 while (!*vname) { |
62 while (!(vname[0])) { | |
63 //loop through | 62 //loop through |
64 if (fgets(buf, 255, fil)==NULL) return 2; | 63 if (!fgets(buf, 255, fil)) return 2; |
65 if ((vtext = id_check_match(vendid, buf))) | 64 if ((vtext = id_check_match(vendid, buf))) |
66 strncpy(vname, vtext, strlen(vtext) - 1); | 65 strncpy(vname, vtext, strlen(vtext) - 1); |
67 } | 66 } |
68 while (!(devname[0])) { | 67 while (!*devname) { |
69 if ((fgets(buf, 255, fil)==NULL) || (buf[0] != '\t' )) | 68 if (!fgets(buf, 255, fil) || *buf != '\t') return 1; |
70 return 1; | |
71 if ((dtext = id_check_match(devid, buf + 1))) | 69 if ((dtext = id_check_match(devid, buf + 1))) |
72 strncpy(devname, dtext, strlen(dtext) - 1); | 70 strncpy(devname, dtext, strlen(dtext) - 1); |
73 } | 71 } |
74 return 0; /* Succeeded in matching both */ | 72 |
73 // matched both | |
74 return 0; | |
75 } | 75 } |
76 | 76 |
77 int do_lspci(struct dirtree *new) | 77 int do_lspci(struct dirtree *new) |
78 { | 78 { |
79 int alen = 8, dirfd, res = 2; //no textual descriptions read | 79 int alen = 8, dirfd, res = 2; //no textual descriptions read |
80 char *dname = dirtree_path(new, &alen); | 80 char *dname = dirtree_path(new, &alen); |
81 | |
81 memset(toybuf, 0, 4096); | 82 memset(toybuf, 0, 4096); |
82 struct { | 83 struct { |
83 char class[16], vendor[16], device[16], module[256], | 84 char class[16], vendor[16], device[16], module[256], |
84 vname[256], devname[256]; | 85 vname[256], devname[256]; |
85 } *bufs = (void*)(toybuf + 2); | 86 } *bufs = (void*)(toybuf + 2); |
86 | 87 |
87 if (!strcmp("/sys/bus/pci/devices", dname)) return DIRTREE_RECURSE; | 88 if (!new->parent) return DIRTREE_RECURSE; |
88 errno = 0; | 89 errno = 0; |
89 dirfd = open(dname, O_RDONLY); | 90 dirfd = open(dname, O_RDONLY); |
90 if (dirfd > 0) { | 91 if (dirfd > 0) { |
91 char *p, **fields = (char*[]){"class", "vendor", "device", ""}; | 92 char *p, **fields = (char*[]){"class", "vendor", "device", ""}; |
92 | 93 |
93 for (p = toybuf; **fields; p+=16, fields++) { | 94 for (p = toybuf; **fields; p+=16, fields++) { |
94 int fd, size; | 95 int fd, size = ((toys.optflags & FLAG_e) && p == toybuf) ? 8 : 6; |
95 | 96 |
96 if ((fd = openat(dirfd, *fields, O_RDONLY)) < 0) continue; | 97 if ((fd = openat(dirfd, *fields, O_RDONLY)) < 0) continue; |
97 size = ((toys.optflags & FLAG_e) && (p == toybuf)) ? 8 : 6; | 98 xread(fd, p, size); |
98 p[read(fd, p, size)] = '\0'; | |
99 close(fd); | 99 close(fd); |
100 | |
101 p[size] = 0; | |
100 } | 102 } |
101 | 103 |
102 close(dirfd); | 104 close(dirfd); |
103 if (!errno) { | 105 if (errno) return 0; |
106 | |
107 { | |
104 char *driver = ""; | 108 char *driver = ""; |
105 char *fmt = toys.optflags & FLAG_m ? "%s, \"%s\" \"%s\" \"%s\" \"%s\"\n" | 109 char *fmt = (toys.optflags & FLAG_m) ? "%s, \"%s\" \"%s\" \"%s\" \"%s\"\n" |
106 : "%s Class %s: %s:%s %s\n"; | 110 : "%s Class %s: %s:%s %s\n"; |
107 | 111 |
108 if (toys.optflags & FLAG_k) { | 112 if (toys.optflags & FLAG_k) { |
109 strcat(dname, "/driver"); | 113 strcat(dname, "/driver"); |
110 if (readlink(dname, bufs->module, sizeof(bufs->module)) != -1) | 114 if (readlink(dname, bufs->module, sizeof(bufs->module)) != -1) |
111 driver = basename(bufs->module); | 115 driver = basename(bufs->module); |
112 } | 116 } |
113 if (CFG_LSPCI_TEXT && (TT.numeric != 1)) { | 117 if (CFG_LSPCI_TEXT && TT.numeric != 1) { |
114 res = find_in_db(bufs->vendor, bufs->device, TT.db, | 118 res = find_in_db(bufs->vendor, bufs->device, TT.db, |
115 bufs->vname, bufs->devname); | 119 bufs->vname, bufs->devname); |
116 } | 120 } |
117 if (CFG_LSPCI_TEXT && (TT.numeric == 2)) { | 121 if (CFG_LSPCI_TEXT && TT.numeric > 1) { |
118 fmt = toys.optflags & FLAG_m | 122 fmt = (toys.optflags & FLAG_m) |
119 ? "%s, \"%s\" \"%s [%s]\" \"%s [%s]\" \"%s\"\n" | 123 ? "%s, \"%s\" \"%s [%s]\" \"%s [%s]\" \"%s\"\n" |
120 : "%s Class %s: %s [%s] %s [%s] %s\n"; | 124 : "%s Class %s: %s [%s] %s [%s] %s\n"; |
121 printf(fmt, new->name + 5, bufs->class, bufs->vname, bufs->vendor, | 125 printf(fmt, new->name + 5, bufs->class, bufs->vname, bufs->vendor, |
122 bufs->devname, bufs->device, driver); | 126 bufs->devname, bufs->device, driver); |
123 } else { | 127 } else { |
124 printf(fmt, new->name + 5, bufs->class, | 128 printf(fmt, new->name + 5, bufs->class, |
125 (res < 2) ? bufs->vname : bufs->vendor, | 129 (res < 2) ? bufs->vname : bufs->vendor, |
126 !(res) ? bufs->devname : bufs->device, driver); | 130 !(res) ? bufs->devname : bufs->device, driver); |
127 } | 131 } |
128 | |
129 } | 132 } |
130 } | 133 } |
134 | |
131 return 0; | 135 return 0; |
132 } | 136 } |
133 | 137 |
134 void lspci_main(void) | 138 void lspci_main(void) |
135 { | 139 { |