Busybox insmod fixes: modules with short names, return codes
[tomato.git] / release / src / router / busybox / modutils / insmod.c
blob43d2171db3cf881ae0a6720d8c97792e24610f8d
1 /* vi: set sw=4 ts=4: */
2 /*
3 * Mini insmod implementation for busybox
5 * Copyright (C) 2008 Timo Teras <timo.teras@iki.fi>
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */
10 #include "libbb.h"
11 #include "modutils.h"
12 #include <fnmatch.h>
14 static char *m_filename;
16 static int FAST_FUNC check_module_name_match(const char *filename,
17 struct stat *statbuf UNUSED_PARAM,
18 void *userdata, int depth UNUSED_PARAM)
20 char *fullname = (char *) userdata;
21 char *tmp;
23 if (fullname[0] == '\0')
24 return FALSE;
26 tmp = bb_get_last_path_component_nostrip(filename);
27 if (strcmp(tmp, fullname) == 0) {
28 /* Stop searching if we find a match */
29 m_filename = xstrdup(filename);
30 return FALSE;
32 return TRUE;
35 int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
36 int insmod_main(int argc UNUSED_PARAM, char **argv)
38 struct stat st;
39 char *filename;
40 FILE *fp = NULL;
41 int rc;
43 /* Compat note:
44 * 2.6 style insmod has no options and required filename
45 * (not module name - .ko can't be omitted).
46 * 2.4 style insmod can take module name without .o
47 * and performs module search in default directories
48 * or in $MODPATH.
51 USE_FEATURE_2_4_MODULES(
52 getopt32(argv, INSMOD_OPTS INSMOD_ARGS);
53 argv += optind - 1;
56 filename = *++argv;
57 if (!filename)
58 bb_show_usage();
60 m_filename = NULL;
61 /* Get a filedesc for the module. Check if we have a complete path */
62 if (stat(filename, &st) < 0 || !S_ISREG(st.st_mode) ||
63 (fp = fopen_for_read(filename)) == NULL) {
64 /* Hmm. Could not open it. Search /lib/modules/ */
65 int r, pos;
66 char *module_dir;
68 pos = strlen(filename) - 2;
69 if (get_linux_version_code() < KERNEL_VERSION(2,6,0)) {
70 if (pos < 0) pos = 0;
71 if (strncmp(&filename[pos], ".o", 2) !=0)
72 filename = xasprintf("%s.o", filename);
73 } else {
74 if (--pos < 0) pos = 0;
75 if (strncmp(&filename[pos], ".ko", 3) !=0)
76 filename = xasprintf("%s.ko", filename);
79 module_dir = xmalloc_readlink(CONFIG_DEFAULT_MODULES_DIR);
80 if (!module_dir)
81 module_dir = xstrdup(CONFIG_DEFAULT_MODULES_DIR);
82 r = recursive_action(module_dir, ACTION_RECURSE,
83 check_module_name_match, NULL, filename, 0);
84 free(module_dir);
85 if (r)
86 bb_error_msg_and_die("%s: module not found", filename);
87 if (m_filename == NULL || ((fp = fopen_for_read(m_filename)) == NULL)) {
88 bb_error_msg_and_die("%s: module not found", filename);
90 filename = m_filename;
92 if (fp != NULL)
93 fclose(fp);
95 rc = bb_init_module(filename, parse_cmdline_module_options(argv));
96 if (rc)
97 bb_error_msg("can't insert '%s': %s", filename, moderror(rc));
99 free(m_filename);
100 return rc;