aboutsummaryrefslogtreecommitdiff
path: root/toys/pending/lspci.c
diff options
context:
space:
mode:
authorIsaac Dunham <idunham@lavabit.com>2013-08-07 11:51:26 -0500
committerIsaac Dunham <idunham@lavabit.com>2013-08-07 11:51:26 -0500
commit17ea5644d93ff1ced28d3602ac244cb6022f3ba6 (patch)
tree9ac5ba66d5626fa9e1fee29547285bf29563979b /toys/pending/lspci.c
parent142ebdcfbe01007cd86d699d85dc608bbcaacf82 (diff)
downloadtoybox-17ea5644d93ff1ced28d3602ac244cb6022f3ba6.tar.gz
This is the preliminary version of lspci text output support (the location
of pci.ids is hard-coded to /usr/share/misc/pci.ids, as found on Debian/Ubuntu). +88 lines in two files, including reformatting, comments, whitespace, and build configuration as well as new code. The changes: -Add library code to look up descriptions. -Add a counter for -n (for the sake of -nn) -Add the file stream "db" to GLOBALS and open it conditionally -Add name fields to bufs -Look up text if enabled and -n is passed never or twice -Print text if lookup succeeded
Diffstat (limited to 'toys/pending/lspci.c')
-rw-r--r--toys/pending/lspci.c94
1 files changed, 87 insertions, 7 deletions
diff --git a/toys/pending/lspci.c b/toys/pending/lspci.c
index caa62141..16fd0f60 100644
--- a/toys/pending/lspci.c
+++ b/toys/pending/lspci.c
@@ -1,29 +1,87 @@
/*
* lspci - written by Isaac Dunham
-USE_LSPCI(NEWTOY(lspci, "emkns:", TOYFLAG_USR|TOYFLAG_BIN))
+USE_LSPCI(NEWTOY(lspci, "emkn@", TOYFLAG_USR|TOYFLAG_BIN))
config LSPCI
bool "lspci"
default n
help
- usage: lspci [-ekmn]
+ usage: lspci [-ekmn@]
List PCI devices.
-e Print all 6 digits in class (like elspci)
-k Print kernel driver
-m Machine parseable format
- -n Numeric output (default)
+ -n Numeric output
+
+config LSPCI_TEXT
+ bool "lspci readable output"
+ depends on LSPCI
+ default n
+ help
+ lspci without -n prints readable descriptions;
+ lspci -nn prints both readable and numeric description
*/
#define FOR_lspci
#include "toys.h"
+extern int find_in_db(char * , char * , FILE * , char * , char * );
+
+GLOBALS(
+long numeric;
+
+FILE * db;
+)
+
+char * id_check_match(char * id, char * buf)
+{
+ int i = 0;
+ while (id[i]) {
+ if (id[i] == buf[i]) {
+ i++;
+ } else {
+ return (char *)0L;
+ }
+ }
+ return (buf + i + 2);
+}
+
+/*
+ * In: vendid, devid, fil
+ * Out: vname, devname
+ * Out must be zeroed before use.
+ * vmame and devname must be char[256], zeroed out
+ * Returns (2 - number of IDs matched): vendor must be matched for
+ * dev to be matched
+ */
+int find_in_db(char * vendid, char * devid, FILE * fil,
+ char * vname, char * devname)
+{
+ fseek(fil, 0, SEEK_SET);
+ char buf[256], *vtext = 0L, *dtext = 0L;
+ while (!(vname[0])) {
+ //loop through
+ if (fgets(buf, 255, fil)==NULL) return 2;
+ if ((vtext = id_check_match(vendid, buf)))
+ strncpy(vname, vtext, strlen(vtext) - 1);
+ }
+ while (!(devname[0])) {
+ if ((fgets(buf, 255, fil)==NULL) || (buf[0] != '\t' ))
+ return 1;
+ if ((dtext = id_check_match(devid, buf + 1)))
+ strncpy(devname, dtext, strlen(dtext) - 1);
+ }
+ return 0; /* Succeeded in matching both */
+}
int do_lspci(struct dirtree *new)
{
- int alen = 8, dirfd;
+ int alen = 8, dirfd, res = 2; //no textual descriptions read
char *dname = dirtree_path(new, &alen);
+ memset(toybuf, 0, 4096);
struct {
- char class[16], vendor[16], device[16], module[256];
+ char class[16], vendor[16], device[16], module[256],
+ vname[256], devname[256];
} *bufs = (void*)(toybuf + 2);
if (!strcmp("/sys/bus/pci/devices", dname)) return DIRTREE_RECURSE;
@@ -52,8 +110,22 @@ int do_lspci(struct dirtree *new)
if (readlink(dname, bufs->module, sizeof(bufs->module)) != -1)
driver = basename(bufs->module);
}
- printf(fmt, new->name + 5, bufs->class, bufs->vendor, bufs->device,
- driver);
+ if (CFG_LSPCI_TEXT && (TT.numeric != 1)) {
+ res = find_in_db(bufs->vendor, bufs->device, TT.db,
+ bufs->vname, bufs->devname);
+ }
+ if (CFG_LSPCI_TEXT && (TT.numeric == 2)) {
+ fmt = toys.optflags & FLAG_m
+ ? "%s, \"%s\" \"%s [%s]\" \"%s [%s]\" \"%s\"\n"
+ : "%s Class %s: %s [%s] %s [%s] %s\n";
+ printf(fmt, new->name + 5, bufs->class, bufs->vname, bufs->vendor,
+ bufs->devname, bufs->device, driver);
+ } else {
+ printf(fmt, new->name + 5, bufs->class,
+ (res < 2) ? bufs->vname : bufs->vendor,
+ !(res) ? bufs->devname : bufs->device, driver);
+ }
+
}
}
return 0;
@@ -61,5 +133,13 @@ int do_lspci(struct dirtree *new)
void lspci_main(void)
{
+ if (CFG_LSPCI_TEXT && (TT.numeric != 1)) {
+ TT.db = fopen("/usr/share/misc/pci.ids", "r");
+ if (errno) {
+ TT.numeric = 1;
+ error_msg("could not open PCI ID db");
+ }
+ }
+
dirtree_read("/sys/bus/pci/devices", do_lspci);
}