xref: /aosp_15_r20/external/toybox/toys/other/modinfo.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
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