source: MondoRescue/branches/3.3/mindi-busybox/modutils/modinfo.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * modinfo - retrieve module info
4 * Copyright (c) 2008 Pascal Bellard
5 *
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7 */
8//config:config MODINFO
9//config: bool "modinfo"
10//config: default y
11//config: select PLATFORM_LINUX
12//config: help
13//config: Show information about a Linux Kernel module
14
15//applet:IF_MODINFO(APPLET(modinfo, BB_DIR_SBIN, BB_SUID_DROP))
16
17//kbuild:lib-$(CONFIG_MODINFO) += modinfo.o modutils.o
18
19#include <fnmatch.h>
20#include <sys/utsname.h> /* uname() */
21#include "libbb.h"
22#include "modutils.h"
23
24static const char *const shortcuts[] = {
25 "filename", // -n
26 "author", // -a
27 "description", // -d
28 "license", // -l
29 "parm", // -p
30 "version", // the rest has no shortcut options
31 "alias",
32 "srcversion",
33 "depends",
34 "uts_release",
35 "intree",
36 "vermagic",
37 "firmware",
38};
39
40enum {
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
45 */
46 OPT_n = (1 << 2),
47 OPT_TAGS = ((1 << ARRAY_SIZE(shortcuts)) - 1) << 2,
48};
49
50static void display(const char *data, const char *pattern)
51{
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);
56 while (n++ < 16)
57 bb_putchar(' ');
58 }
59 printf("%s%c", data, (option_mask32 & OPT_0) ? '\0' : '\n');
60}
61
62static void modinfo(const char *path, const char *version,
63 const char *field)
64{
65 size_t len;
66 int j;
67 char *ptr, *the_module;
68 char *allocated;
69 int tags = option_mask32;
70
71 allocated = NULL;
72 len = MAXINT(ssize_t);
73 the_module = xmalloc_open_zipped_read_close(path, &len);
74 if (!the_module) {
75 if (path[0] == '/')
76 return;
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);
80 if (!the_module) {
81 bb_error_msg("module '%s' not found", path);
82 goto ret;
83 }
84 }
85
86 for (j = 1; (1<<j) & (OPT_TAGS|OPT_F); j++) {
87 const char *pattern;
88
89 if (!((1<<j) & tags))
90 continue;
91
92 pattern = field;
93 if ((1<<j) & OPT_TAGS)
94 pattern = shortcuts[j-2];
95
96 if (strcmp(pattern, shortcuts[0]) == 0) {
97 /* "-n" or "-F filename" */
98 display(path, shortcuts[0]);
99 continue;
100 }
101
102 ptr = the_module;
103 while (1) {
104 char *after_pattern;
105
106 ptr = memchr(ptr, *pattern, len - (ptr - (char*)the_module));
107 if (ptr == NULL) /* no occurance left, done */
108 break;
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);
115 ptr += strlen(ptr);
116 }
117 }
118 ++ptr;
119 }
120 }
121 free(the_module);
122 ret:
123 free(allocated);
124}
125
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"
138
139int modinfo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
140int modinfo_main(int argc UNUSED_PARAM, char **argv)
141{
142 const char *field;
143 char name[MODULE_NAME_LEN];
144 struct utsname uts;
145 parser_t *parser;
146 char *colon, *tokens[2];
147 unsigned opts;
148 unsigned i;
149
150 field = NULL;
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;
156 argv += optind;
157
158 uname(&uts);
159 parser = config_open2(
160 xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, uts.release, CONFIG_DEFAULT_DEPMOD_FILE),
161 xfopen_for_read
162 );
163
164 while (config_read(parser, tokens, 2, 1, "# \t", PARSE_NORMAL)) {
165 colon = last_char_is(tokens[0], ':');
166 if (colon == NULL)
167 continue;
168 *colon = '\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 *) "";
174 }
175 }
176 }
177 if (ENABLE_FEATURE_CLEAN_UP)
178 config_close(parser);
179
180 for (i = 0; argv[i]; i++) {
181 if (argv[i][0]) {
182 modinfo(argv[i], uts.release, field);
183 }
184 }
185
186 return 0;
187}
Note: See TracBrowser for help on using the repository browser.