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 {