source: branches/3.2/mindi-busybox/modutils/modinfo.c @ 3232

Last change on this file since 3232 was 3232, checked in by bruno, 5 years ago
  • Update mindi-busybox to 1.21.1
  • Property svn:eol-style set to native
File size: 4.1 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
9//applet:IF_MODINFO(APPLET(modinfo, BB_DIR_SBIN, BB_SUID_DROP))
10
11//kbuild:lib-$(CONFIG_MODINFO) += modinfo.o modutils.o
12
13//config:config MODINFO
14//config:   bool "modinfo"
15//config:   default y
16//config:   select PLATFORM_LINUX
17//config:   help
18//config:     Show information about a Linux Kernel module
19
20#include <fnmatch.h>
21#include <sys/utsname.h> /* uname() */
22#include "libbb.h"
23#include "modutils.h"
24
25
26enum {
27    OPT_TAGS = (1 << 12) - 1, /* shortcut count */
28    OPT_F = (1 << 12), /* field name */
29    OPT_0 = (1 << 13), /* \0 as separator */
30};
31
32struct modinfo_env {
33    char *field;
34    int tags;
35};
36
37static int display(const char *data, const char *pattern, int flag)
38{
39    if (flag) {
40        int n = printf("%s:", pattern);
41        while (n++ < 16)
42            bb_putchar(' ');
43    }
44    return printf("%s%c", data, (option_mask32 & OPT_0) ? '\0' : '\n');
45}
46
47static void modinfo(const char *path, const char *version,
48            const struct modinfo_env *env)
49{
50    static const char *const shortcuts[] = {
51        "filename",
52        "license",
53        "author",
54        "description",
55        "version",
56        "alias",
57        "srcversion",
58        "depends",
59        "uts_release",
60        "vermagic",
61        "parm",
62        "firmware",
63    };
64    size_t len;
65    int j, length;
66    char *ptr, *the_module;
67    const char *field = env->field;
68    int tags = env->tags;
69
70    if (tags & 1) { /* filename */
71        display(path, shortcuts[0], 1 != tags);
72    }
73
74    len = MAXINT(ssize_t);
75    the_module = xmalloc_open_zipped_read_close(path, &len);
76    if (!the_module) {
77        if (path[0] == '/')
78            return;
79        /* Newer depmod puts relative paths in modules.dep */
80        path = xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, version, path);
81        the_module = xmalloc_open_zipped_read_close(path, &len);
82        free((char*)path);
83        if (!the_module)
84            return;
85    }
86
87    if (field)
88        tags |= OPT_F;
89    for (j = 1; (1<<j) & (OPT_TAGS + OPT_F); j++) {
90        const char *pattern;
91
92        if (!((1<<j) & tags))
93            continue;
94        pattern = field;
95        if ((1<<j) & OPT_TAGS)
96            pattern = shortcuts[j];
97        length = strlen(pattern);
98        ptr = the_module;
99        while (1) {
100            ptr = memchr(ptr, *pattern, len - (ptr - (char*)the_module));
101            if (ptr == NULL) /* no occurance left, done */
102                break;
103            if (strncmp(ptr, pattern, length) == 0 && ptr[length] == '=') {
104                /* field prefixes are 0x80 or 0x00 */
105                if ((ptr[-1] & 0x7F) == '\0') {
106                    ptr += length + 1;
107                    ptr += display(ptr, pattern, (1<<j) != tags);
108                }
109            }
110            ++ptr;
111        }
112    }
113    free(the_module);
114}
115
116//usage:#define modinfo_trivial_usage
117//usage:       "[-adlp0] [-F keyword] MODULE"
118//usage:#define modinfo_full_usage "\n\n"
119//usage:       "    -a      Shortcut for '-F author'"
120//usage:     "\n    -d      Shortcut for '-F description'"
121//usage:     "\n    -l      Shortcut for '-F license'"
122//usage:     "\n    -p      Shortcut for '-F parm'"
123//usage:     "\n    -F keyword  Keyword to look for"
124//usage:     "\n    -0      Separate output with NULs"
125//usage:#define modinfo_example_usage
126//usage:       "$ modinfo -F vermagic loop\n"
127
128int modinfo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
129int modinfo_main(int argc UNUSED_PARAM, char **argv)
130{
131    struct modinfo_env env;
132    char name[MODULE_NAME_LEN];
133    struct utsname uts;
134    parser_t *parser;
135    char *colon, *tokens[2];
136    unsigned opts;
137    unsigned i;
138
139    env.field = NULL;
140    opt_complementary = "-1"; /* minimum one param */
141    opts = getopt32(argv, "nladvAsDumpF:0", &env.field);
142    env.tags = opts & OPT_TAGS ? opts & OPT_TAGS : OPT_TAGS;
143    argv += optind;
144
145    uname(&uts);
146    parser = config_open2(
147        xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, uts.release, CONFIG_DEFAULT_DEPMOD_FILE),
148        xfopen_for_read
149    );
150
151    while (config_read(parser, tokens, 2, 1, "# \t", PARSE_NORMAL)) {
152        colon = last_char_is(tokens[0], ':');
153        if (colon == NULL)
154            continue;
155        *colon = '\0';
156        filename2modname(tokens[0], name);
157        for (i = 0; argv[i]; i++) {
158            if (fnmatch(argv[i], name, 0) == 0) {
159                modinfo(tokens[0], uts.release, &env);
160                argv[i] = (char *) "";
161            }
162        }
163    }
164    if (ENABLE_FEATURE_CLEAN_UP)
165        config_close(parser);
166
167    for (i = 0; argv[i]; i++) {
168        if (argv[i][0]) {
169            modinfo(argv[i], uts.release, &env);
170        }
171    }
172
173    return 0;
174}
Note: See TracBrowser for help on using the repository browser.