1 /* vi: set sw=4 ts=4: */
3 * modinfo - retrieve module info
4 * Copyright (c) 2008 Pascal Bellard
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 //config:config MODINFO
9 //config: bool "modinfo"
11 //config: select PLATFORM_LINUX
13 //config: Show information about a Linux Kernel module
15 //applet:IF_MODINFO(APPLET(modinfo, BB_DIR_SBIN, BB_SUID_DROP))
17 //kbuild:lib-$(CONFIG_MODINFO) += modinfo.o modutils.o
20 #include <sys/utsname.h> /* uname() */
24 static const char *const shortcuts
[] = {
30 "version", // the rest has no shortcut options
41 OPT_0
= (1 << 0), /* \0 as separator */
42 OPT_F
= (1 << 1), /* field name */
43 /* first bits are for -nadlp options, the rest are for
44 * fields not selectable with "shortcut" options
47 OPT_TAGS
= ((1 << ARRAY_SIZE(shortcuts
)) - 1) << 2,
50 static void display(const char *data
, const char *pattern
)
52 int flag
= option_mask32
>> 1; /* shift out -0 bit */
53 if (flag
& (flag
-1)) {
54 /* more than one field to show: print "FIELD:" pfx */
55 int n
= printf("%s:", pattern
);
59 printf("%s%c", data
, (option_mask32
& OPT_0
) ? '\0' : '\n');
62 static void modinfo(const char *path
, const char *version
,
67 char *ptr
, *the_module
;
69 int tags
= option_mask32
;
72 len
= MAXINT(ssize_t
);
73 the_module
= xmalloc_open_zipped_read_close(path
, &len
);
77 /* Newer depmod puts relative paths in modules.dep */
78 path
= allocated
= xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR
, version
, path
);
79 the_module
= xmalloc_open_zipped_read_close(path
, &len
);
81 bb_error_msg("module '%s' not found", path
);
86 for (j
= 1; (1<<j
) & (OPT_TAGS
|OPT_F
); j
++) {
93 if ((1<<j
) & OPT_TAGS
)
94 pattern
= shortcuts
[j
-2];
96 if (strcmp(pattern
, shortcuts
[0]) == 0) {
97 /* "-n" or "-F filename" */
98 display(path
, shortcuts
[0]);
106 ptr
= memchr(ptr
, *pattern
, len
- (ptr
- (char*)the_module
));
107 if (ptr
== NULL
) /* no occurance left, done */
109 after_pattern
= is_prefixed_with(ptr
, pattern
);
110 if (after_pattern
&& *after_pattern
== '=') {
111 /* field prefixes are 0x80 or 0x00 */
112 if ((ptr
[-1] & 0x7F) == 0x00) {
113 ptr
= after_pattern
+ 1;
114 display(ptr
, pattern
);
126 //usage:#define modinfo_trivial_usage
127 //usage: "[-adlpn0] [-F keyword] MODULE"
128 //usage:#define modinfo_full_usage "\n\n"
129 //usage: " -a Shortcut for '-F author'"
130 //usage: "\n -d Shortcut for '-F description'"
131 //usage: "\n -l Shortcut for '-F license'"
132 //usage: "\n -p Shortcut for '-F parm'"
133 ////usage: "\n -n Shortcut for '-F filename'"
134 //usage: "\n -F keyword Keyword to look for"
135 //usage: "\n -0 Separate output with NULs"
136 //usage:#define modinfo_example_usage
137 //usage: "$ modinfo -F vermagic loop\n"
139 int modinfo_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
140 int modinfo_main(int argc UNUSED_PARAM
, char **argv
)
143 char name
[MODULE_NAME_LEN
];
146 char *colon
, *tokens
[2];
151 opt_complementary
= "-1"; /* minimum one param */
152 opts
= getopt32(argv
, "0F:nadlp", &field
);
153 /* If no field selected, show all */
154 if (!(opts
& (OPT_TAGS
|OPT_F
)))
155 option_mask32
|= OPT_TAGS
;
159 parser
= config_open2(
160 xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR
, uts
.release
, CONFIG_DEFAULT_DEPMOD_FILE
),
164 while (config_read(parser
, tokens
, 2, 1, "# \t", PARSE_NORMAL
)) {
165 colon
= last_char_is(tokens
[0], ':');
169 filename2modname(bb_basename(tokens
[0]), name
);
170 for (i
= 0; argv
[i
]; i
++) {
171 if (fnmatch(argv
[i
], name
, 0) == 0) {
172 modinfo(tokens
[0], uts
.release
, field
);
173 argv
[i
] = (char *) "";
177 if (ENABLE_FEATURE_CLEAN_UP
)
178 config_close(parser
);
180 for (i
= 0; argv
[i
]; i
++) {
182 modinfo(argv
[i
], uts
.release
, field
);