1*cf5a6c84SAndroid Build Coastguard Worker /* modinfo.c - Display module info
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2012 Andre Renaud <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * TODO: cleanup
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Worker USE_MODINFO(NEWTOY(modinfo, "<1b:k:F:0", TOYFLAG_SBIN))
8*cf5a6c84SAndroid Build Coastguard Worker
9*cf5a6c84SAndroid Build Coastguard Worker config MODINFO
10*cf5a6c84SAndroid Build Coastguard Worker bool "modinfo"
11*cf5a6c84SAndroid Build Coastguard Worker default y
12*cf5a6c84SAndroid Build Coastguard Worker help
13*cf5a6c84SAndroid Build Coastguard Worker usage: modinfo [-0] [-b basedir] [-k kernel] [-F field] [module|file...]
14*cf5a6c84SAndroid Build Coastguard Worker
15*cf5a6c84SAndroid Build Coastguard Worker Display module fields for modules specified by name or .ko path.
16*cf5a6c84SAndroid Build Coastguard Worker
17*cf5a6c84SAndroid Build Coastguard Worker -F Only show the given field
18*cf5a6c84SAndroid Build Coastguard Worker -0 Separate fields with NUL rather than newline
19*cf5a6c84SAndroid Build Coastguard Worker -b Use <basedir> as root for /lib/modules/
20*cf5a6c84SAndroid Build Coastguard Worker -k Look in given directory under /lib/modules/
21*cf5a6c84SAndroid Build Coastguard Worker */
22*cf5a6c84SAndroid Build Coastguard Worker
23*cf5a6c84SAndroid Build Coastguard Worker #define FOR_modinfo
24*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
25*cf5a6c84SAndroid Build Coastguard Worker
26*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
27*cf5a6c84SAndroid Build Coastguard Worker char *F, *k, *b;
28*cf5a6c84SAndroid Build Coastguard Worker
29*cf5a6c84SAndroid Build Coastguard Worker long mod;
30*cf5a6c84SAndroid Build Coastguard Worker int count;
31*cf5a6c84SAndroid Build Coastguard Worker )
32*cf5a6c84SAndroid Build Coastguard Worker
output_field(char * field,char * value)33*cf5a6c84SAndroid Build Coastguard Worker static void output_field(char *field, char *value)
34*cf5a6c84SAndroid Build Coastguard Worker {
35*cf5a6c84SAndroid Build Coastguard Worker if (!TT.F) xprintf("%s:%*c", field, 15-(int)strlen(field), ' ');
36*cf5a6c84SAndroid Build Coastguard Worker else if (strcmp(TT.F, field)) return;
37*cf5a6c84SAndroid Build Coastguard Worker xprintf("%s", value);
38*cf5a6c84SAndroid Build Coastguard Worker xputc(FLAG(0) ? 0 : '\n');
39*cf5a6c84SAndroid Build Coastguard Worker }
40*cf5a6c84SAndroid Build Coastguard Worker
modinfo_file(char * full_name)41*cf5a6c84SAndroid Build Coastguard Worker static void modinfo_file(char *full_name)
42*cf5a6c84SAndroid Build Coastguard Worker {
43*cf5a6c84SAndroid Build Coastguard Worker int fd, flen, i;
44*cf5a6c84SAndroid Build Coastguard Worker char *buf = 0, *end, *modinfo_tags[] = {
45*cf5a6c84SAndroid Build Coastguard Worker "license", "author", "description", "firmware", "alias", "srcversion",
46*cf5a6c84SAndroid Build Coastguard Worker "depends", "retpoline", "intree", "name", "vermagic", "parm", "parmtype",
47*cf5a6c84SAndroid Build Coastguard Worker "scmversion",
48*cf5a6c84SAndroid Build Coastguard Worker };
49*cf5a6c84SAndroid Build Coastguard Worker
50*cf5a6c84SAndroid Build Coastguard Worker if (-1 != (fd = open(full_name, O_RDONLY))) {
51*cf5a6c84SAndroid Build Coastguard Worker flen = fdlength(fd);
52*cf5a6c84SAndroid Build Coastguard Worker buf = xmmap(0, flen, PROT_READ, MAP_SHARED, fd, 0);
53*cf5a6c84SAndroid Build Coastguard Worker end = buf + flen;
54*cf5a6c84SAndroid Build Coastguard Worker close(fd);
55*cf5a6c84SAndroid Build Coastguard Worker }
56*cf5a6c84SAndroid Build Coastguard Worker
57*cf5a6c84SAndroid Build Coastguard Worker if (!buf) {
58*cf5a6c84SAndroid Build Coastguard Worker perror_msg_raw(full_name);
59*cf5a6c84SAndroid Build Coastguard Worker return;
60*cf5a6c84SAndroid Build Coastguard Worker }
61*cf5a6c84SAndroid Build Coastguard Worker
62*cf5a6c84SAndroid Build Coastguard Worker TT.count++;
63*cf5a6c84SAndroid Build Coastguard Worker output_field("filename", full_name);
64*cf5a6c84SAndroid Build Coastguard Worker
65*cf5a6c84SAndroid Build Coastguard Worker for (i=0; i<ARRAY_LEN(modinfo_tags); i++) {
66*cf5a6c84SAndroid Build Coastguard Worker char *field = modinfo_tags[i], *p = buf;
67*cf5a6c84SAndroid Build Coastguard Worker int slen = sprintf(toybuf, "%s=", field);
68*cf5a6c84SAndroid Build Coastguard Worker
69*cf5a6c84SAndroid Build Coastguard Worker while (p && p < end) {
70*cf5a6c84SAndroid Build Coastguard Worker p = memmem(p, end-p, toybuf, slen);
71*cf5a6c84SAndroid Build Coastguard Worker if (p) output_field(field, p += slen);
72*cf5a6c84SAndroid Build Coastguard Worker }
73*cf5a6c84SAndroid Build Coastguard Worker }
74*cf5a6c84SAndroid Build Coastguard Worker
75*cf5a6c84SAndroid Build Coastguard Worker munmap(buf, flen);
76*cf5a6c84SAndroid Build Coastguard Worker }
77*cf5a6c84SAndroid Build Coastguard Worker
check_module(struct dirtree * new)78*cf5a6c84SAndroid Build Coastguard Worker static int check_module(struct dirtree *new)
79*cf5a6c84SAndroid Build Coastguard Worker {
80*cf5a6c84SAndroid Build Coastguard Worker char *s;
81*cf5a6c84SAndroid Build Coastguard Worker int len;
82*cf5a6c84SAndroid Build Coastguard Worker
83*cf5a6c84SAndroid Build Coastguard Worker if (!dirtree_notdotdot(new)) return 0;
84*cf5a6c84SAndroid Build Coastguard Worker
85*cf5a6c84SAndroid Build Coastguard Worker if (!S_ISREG(new->st.st_mode)) return DIRTREE_RECURSE;
86*cf5a6c84SAndroid Build Coastguard Worker
87*cf5a6c84SAndroid Build Coastguard Worker s = toys.optargs[TT.mod];
88*cf5a6c84SAndroid Build Coastguard Worker
89*cf5a6c84SAndroid Build Coastguard Worker // The kernel treats - and _ the same, so we should too.
90*cf5a6c84SAndroid Build Coastguard Worker for (len = 0; s[len]; len++) {
91*cf5a6c84SAndroid Build Coastguard Worker if (s[len] == '-' && new->name[len] == '_') continue;
92*cf5a6c84SAndroid Build Coastguard Worker if (s[len] == '_' && new->name[len] == '-') continue;
93*cf5a6c84SAndroid Build Coastguard Worker if (s[len] != new->name[len]) break;
94*cf5a6c84SAndroid Build Coastguard Worker }
95*cf5a6c84SAndroid Build Coastguard Worker if (s[len] || strcmp(new->name+len, ".ko")) return DIRTREE_RECURSE;
96*cf5a6c84SAndroid Build Coastguard Worker
97*cf5a6c84SAndroid Build Coastguard Worker modinfo_file(s = dirtree_path(new, 0));
98*cf5a6c84SAndroid Build Coastguard Worker free(s);
99*cf5a6c84SAndroid Build Coastguard Worker
100*cf5a6c84SAndroid Build Coastguard Worker return DIRTREE_ABORT;
101*cf5a6c84SAndroid Build Coastguard Worker }
102*cf5a6c84SAndroid Build Coastguard Worker
modinfo_main(void)103*cf5a6c84SAndroid Build Coastguard Worker void modinfo_main(void)
104*cf5a6c84SAndroid Build Coastguard Worker {
105*cf5a6c84SAndroid Build Coastguard Worker struct utsname uts;
106*cf5a6c84SAndroid Build Coastguard Worker
107*cf5a6c84SAndroid Build Coastguard Worker // Android (as shipped by Google) currently only has modules on /vendor.
108*cf5a6c84SAndroid Build Coastguard Worker // Android does not support multiple sets of modules for different kernels.
109*cf5a6c84SAndroid Build Coastguard Worker if (CFG_TOYBOX_ON_ANDROID) {
110*cf5a6c84SAndroid Build Coastguard Worker if (!TT.b) TT.b = "/vendor";
111*cf5a6c84SAndroid Build Coastguard Worker if (!TT.k) TT.k = "";
112*cf5a6c84SAndroid Build Coastguard Worker } else {
113*cf5a6c84SAndroid Build Coastguard Worker uname(&uts);
114*cf5a6c84SAndroid Build Coastguard Worker if (!TT.b) TT.b = "";
115*cf5a6c84SAndroid Build Coastguard Worker if (!TT.k) TT.k = uts.release;
116*cf5a6c84SAndroid Build Coastguard Worker }
117*cf5a6c84SAndroid Build Coastguard Worker
118*cf5a6c84SAndroid Build Coastguard Worker for (TT.mod = 0; TT.mod<toys.optc; TT.mod++) {
119*cf5a6c84SAndroid Build Coastguard Worker if (strend(toys.optargs[TT.mod], ".ko")) modinfo_file(toys.optargs[TT.mod]);
120*cf5a6c84SAndroid Build Coastguard Worker else {
121*cf5a6c84SAndroid Build Coastguard Worker char *path = xmprintf("%s/lib/modules/%s", TT.b, TT.k);
122*cf5a6c84SAndroid Build Coastguard Worker
123*cf5a6c84SAndroid Build Coastguard Worker TT.count = 0;
124*cf5a6c84SAndroid Build Coastguard Worker dirtree_read(path, check_module);
125*cf5a6c84SAndroid Build Coastguard Worker if (!TT.count) error_msg("%s: not found", toys.optargs[TT.mod]);
126*cf5a6c84SAndroid Build Coastguard Worker free(path);
127*cf5a6c84SAndroid Build Coastguard Worker }
128*cf5a6c84SAndroid Build Coastguard Worker }
129*cf5a6c84SAndroid Build Coastguard Worker }
130