--- busybox/modutils/insmod.c 2007-05-11 12:10:43.000000000 +0200 +++ busybox/modutils/insmod.c 2007-05-11 12:12:15.000000000 +0200 @@ -75,6 +75,30 @@ extern int insmod_ng_main( int argc, char **argv); #endif +static char *m_filename; +static char *m_fullName; +#define _PATH_MODULES "/lib/modules" + +static int check_module_name_match(const char *filename, struct stat *statbuf, + void *userdata, int depth) +{ + char *fullname = (char *) userdata; + + if (fullname[0] == '\0') + return FALSE; + else { + char *tmp, *tmp1 = xstrdup(filename); + tmp = bb_get_last_path_component(tmp1); + if (strcmp(tmp, fullname) == 0) { + free(tmp1); + /* Stop searching if we find a match */ + m_filename = xstrdup(filename); + return FALSE; + } + free(tmp1); + } + return TRUE; +} #if ENABLE_FEATURE_2_4_MODULES @@ -680,7 +704,6 @@ #endif -#define _PATH_MODULES "/lib/modules" enum { STRVERSIONLEN = 64 }; /*======================================================================*/ @@ -793,37 +816,6 @@ static int n_ext_modules_used; extern int delete_module(const char *); -static char *m_filename; -static char *m_fullName; - - -/*======================================================================*/ - - -static int check_module_name_match(const char *filename, struct stat *statbuf, - void *userdata, int depth) -{ - char *fullname = (char *) userdata; - - if (fullname[0] == '\0') - return FALSE; - else { - char *tmp, *tmp1 = xstrdup(filename); - tmp = bb_get_last_path_component(tmp1); - if (strcmp(tmp, fullname) == 0) { - free(tmp1); - /* Stop searching if we find a match */ - m_filename = xstrdup(filename); - return FALSE; - } - free(tmp1); - } - return TRUE; -} - - -/*======================================================================*/ - static struct obj_file *arch_new_file(void) { struct arch_file *f; @@ -4265,14 +4257,97 @@ long ret; size_t len; void *map; - char *filename, *options; + char *options, *tmp; + struct stat st; +#if ENABLE_FEATURE_CLEAN_UP + FILE *fp = 0; +#else + FILE *fp; +#endif + int k_version = 0; + struct utsname myuname; - filename = *++argv; - if (!filename) + if (argc < 2) bb_show_usage(); +#if !ENABLE_FEATURE_2_4_MODULES + /* Grab the module name */ + tmp = basename(xstrdup(argv[1])); + len = strlen(tmp); + + if (uname(&myuname) == 0) { + if (myuname.release[0] == '2') { + k_version = myuname.release[2] - '0'; + } + } + + if (len > 3 && tmp[len - 3] == '.' && tmp[len - 2] == 'k' && tmp[len - 1] == 'o') { + len -= 3; + tmp[len] = '\0'; + } + + + m_fullName = xasprintf("%s.ko", tmp); + + /* Get a filedesc for the module. Check we we have a complete path */ + if (stat(argv[1], &st) < 0 || !S_ISREG(st.st_mode) + || (fp = fopen(argv[1], "r")) == NULL + ) { + /* Hmm. Could not open it. First search under /lib/modules/`uname -r`, + * but do not error out yet if we fail to find it... */ + if (k_version) { /* uname succeedd */ + char *module_dir; + char *tmdn; + char real_module_dir[FILENAME_MAX]; + + tmdn = concat_path_file(_PATH_MODULES, myuname.release); + /* Jump through hoops in case /lib/modules/`uname -r` + * is a symlink. We do not want recursive_action to + * follow symlinks, but we do want to follow the + * /lib/modules/`uname -r` dir, So resolve it ourselves + * if it is a link... */ + if (realpath(tmdn, real_module_dir) == NULL) + module_dir = tmdn; + else + module_dir = real_module_dir; + recursive_action(module_dir, TRUE, FALSE, FALSE, + check_module_name_match, 0, m_fullName, 0); + free(tmdn); + } + + /* Check if we have found anything yet */ + if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL)) { + char module_dir[FILENAME_MAX]; + + free(m_filename); + m_filename = 0; + if (realpath (_PATH_MODULES, module_dir) == NULL) + strcpy(module_dir, _PATH_MODULES); + /* No module found under /lib/modules/`uname -r`, this + * time cast the net a bit wider. Search /lib/modules/ */ + if (!recursive_action(module_dir, TRUE, FALSE, FALSE, + check_module_name_match, 0, m_fullName, 0) + ) { + if (m_filename == 0 + || ((fp = fopen(m_filename, "r")) == NULL) + ) { + bb_error_msg("%s: no module by that name found", m_fullName); +#if ENABLE_FEATURE_CLEAN_UP + if(fp) + fclose(fp); + free(m_filename); +#endif + } + } else + bb_error_msg_and_die("%s: no module by that name found", m_fullName); + } + } else + m_filename = xstrdup(argv[1]); +#endif + /* Rest is options */ options = xstrdup(""); + argv++; while (*++argv) { int optlen = strlen(options); options = xrealloc(options, optlen + 2 + strlen(*argv) + 2); @@ -4300,13 +4375,13 @@ } #else len = MAXINT(ssize_t); - map = xmalloc_open_read_close(filename, &len); + map = xmalloc_open_read_close(m_filename, &len); #endif ret = syscall(__NR_init_module, map, len, options); if (ret != 0) { bb_perror_msg_and_die("cannot insert '%s': %s (%li)", - filename, moderror(errno), ret); + m_filename, moderror(errno), ret); } return 0;