busybox: refresh busybox patches
[openwrt/svn-archive/archive.git] / package / busybox / patches / 470-insmod_search.patch
index 26c5650eb63e010f9a66afe25f6b63bcd15426cc..5853502a82e18720f13eef51edff4a3f13b7bde0 100644 (file)
@@ -1,8 +1,6 @@
-Index: busybox-1.7.2/modutils/insmod.c
-===================================================================
---- busybox-1.7.2.orig/modutils/insmod.c       2007-09-03 13:48:35.000000000 +0200
-+++ busybox-1.7.2/modutils/insmod.c    2007-10-05 01:43:47.686834357 +0200
-@@ -61,19 +61,107 @@
+--- a/modutils/insmod.c
++++ b/modutils/insmod.c
+@@ -61,21 +61,117 @@
  #include "libbb.h"
  #include <libgen.h>
  #include <sys/utsname.h>
@@ -17,18 +15,19 @@ Index: busybox-1.7.2/modutils/insmod.c
  #define ENABLE_FEATURE_2_4_MODULES 1
  #endif
  
--#if !ENABLE_FEATURE_2_4_MODULES
--#define insmod_ng_main insmod_main
-+#if ENABLE_FEATURE_2_4_MODULES
-+int insmod_main_24(int argc, char **argv);
- #endif
+-/*
+- * Big piece of 2.4-specific code
+- */
+ #if ENABLE_FEATURE_2_4_MODULES
 -
++int insmod_main_24(int argc, char **argv);
++#endif
  #if ENABLE_FEATURE_2_6_MODULES
--extern int insmod_ng_main( int argc, char **argv);
+-static int insmod_ng_main(int argc, char **argv);
 +int insmod_main_26(int argc, char **argv);
  #endif
-+int insmod_main(int argc, char **argv);
-+
++int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 +static char *g_filename = NULL;
 +#define _PATH_MODULES "/lib/modules"
 +
@@ -36,20 +35,18 @@ Index: busybox-1.7.2/modutils/insmod.c
 +                                 void *userdata, int depth)
 +{
 +      char *fullname = (char *) userdata;
++      char *tmp;
 +
 +      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 */
-+                      g_filename = xstrdup(filename);
-+                      return FALSE;
-+              }
-+              free(tmp1);
++
++      tmp = bb_get_last_path_component_nostrip(filename);
++      if (strcmp(tmp, fullname) == 0) {
++              /* Stop searching if we find a match */
++              g_filename = xstrdup(filename);
++              return FALSE;
 +      }
++
 +      return TRUE;
 +}
 +
@@ -81,8 +78,12 @@ Index: busybox-1.7.2/modutils/insmod.c
 +              filename = xasprintf("%s%s", filename, suffix);
 +      } else {
 +              filename = strdup(filename);
-+              if ((stat(filename, &st) == 0) && S_ISREG(st.st_mode))
++              if ((stat(filename, &st) == 0) && S_ISREG(st.st_mode)) {
++                      g_filename = filename;
 +                      return 0;
++              }
++              free(filename);
++              return ENOENT;
 +      }
 +
 +      /* next: scan /lib/modules/<release> */
@@ -101,83 +102,276 @@ Index: busybox-1.7.2/modutils/insmod.c
 +              check_module_name_match, 0, filename, 0);
 +
 +      /* Check if we have a complete path */
-+      if (g_filename != NULL) {
-+              if ((stat(g_filename, &st) == 0) && S_ISREG(st.st_mode))
-+                      ret = 0;
-+              else
-+                      free(g_filename);
-+      }
++      if (g_filename == NULL)
++              goto done;
++
++      if ((stat(g_filename, &st) == 0) && S_ISREG(st.st_mode))
++              ret = 0;
++      else
++              free(g_filename);
++
++done:
 +      free(filename);
 +
 +      return ret;
 +}
++
++/*
++ * Big piece of 2.4-specific code
++ */
++#if ENABLE_FEATURE_2_4_MODULES
+ #if ENABLE_FEATURE_INSMOD_LOADINKMEM
+ #define LOADBITS 0
+ #else
+@@ -184,7 +280,6 @@ static int insmod_ng_main(int argc, char
+ /* Microblaze */
+ #if defined(__microblaze__)
+ #define USE_SINGLE
+-#include <linux/elf-em.h>
+ #define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE)
+ #define SHT_RELM      SHT_RELA
+ #define Elf32_RelM    Elf32_Rela
+@@ -452,7 +547,7 @@ enum {
+ /* The system calls unchanged between 2.0 and 2.1.  */
  
+ unsigned long create_module(const char *, size_t);
+-int delete_module(const char *module, unsigned int flags);
++int delete_module(const char *);
  
- #if ENABLE_FEATURE_2_4_MODULES
-@@ -677,7 +765,6 @@
- #endif
  
+ #endif /* module.h */
+@@ -652,7 +747,7 @@ static struct obj_symbol *arch_new_symbo
  
--#define _PATH_MODULES "/lib/modules"
+ static enum obj_reloc arch_apply_relocation(struct obj_file *f,
+                                     struct obj_section *targsec,
+-                                    /*struct obj_section *symsec,*/
++                                    struct obj_section *symsec,
+                                     struct obj_symbol *sym,
+                                     ElfW(RelM) *rel, ElfW(Addr) value);
+@@ -673,6 +768,7 @@ static int obj_gpl_license(struct obj_fi
+ #define SPFX  ""
+ #endif
++
  enum { STRVERSIONLEN = 64 };
  
  /*======================================================================*/
-@@ -790,37 +877,6 @@
- static int n_ext_modules_used;
- extern int delete_module(const char *);
+@@ -788,28 +884,6 @@ static char *m_filename;
+ static char *m_fullName;
  
--static char *m_filename;
--static char *m_fullName;
--
--
 -/*======================================================================*/
 -
 -
--static int check_module_name_match(const char *filename, struct stat *statbuf,
--                              void *userdata, int depth)
+-static int check_module_name_match(const char *filename,
+-              struct stat *statbuf ATTRIBUTE_UNUSED,
+-              void *userdata, int depth ATTRIBUTE_UNUSED)
 -{
 -      char *fullname = (char *) userdata;
+-      char *tmp;
 -
 -      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);
+-
+-      tmp = bb_get_last_path_component_nostrip(filename);
+-      if (strcmp(tmp, fullname) == 0) {
+-              /* Stop searching if we find a match */
+-              m_filename = xstrdup(filename);
+-              return FALSE;
 -      }
 -      return TRUE;
 -}
 -
--
--/*======================================================================*/
--
- static struct obj_file *arch_new_file(void)
+ /*======================================================================*/
+@@ -835,32 +909,20 @@ static struct obj_symbol *arch_new_symbo
+ static enum obj_reloc
+ arch_apply_relocation(struct obj_file *f,
+                               struct obj_section *targsec,
+-                              /*struct obj_section *symsec,*/
++                              struct obj_section *symsec,
+                               struct obj_symbol *sym,
+                               ElfW(RelM) *rel, ElfW(Addr) v)
+ {
+-#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
+- || defined(__sh__) || defined(__s390__) || defined(__x86_64__) \
+- || defined(__powerpc__) || defined(__mips__)
+       struct arch_file *ifile = (struct arch_file *) f;
+-#endif
+       enum obj_reloc ret = obj_reloc_ok;
+       ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
+-#if defined(__arm__) || defined(__H8300H__) || defined(__H8300S__) \
+- || defined(__i386__) || defined(__mc68000__) || defined(__microblaze__) \
+- || defined(__mips__) || defined(__nios2__) || defined(__powerpc__) \
+- || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
+       ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
+-#endif
+ #if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
+       struct arch_symbol *isym = (struct arch_symbol *) sym;
+ #endif
+-#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
+- || defined(__sh__) || defined(__s390__)
+ #if defined(USE_GOT_ENTRIES)
+       ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
+ #endif
+-#endif
+ #if defined(USE_PLT_ENTRIES)
+       ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
+       unsigned long *ip;
+@@ -954,7 +1016,6 @@ arch_apply_relocation(struct obj_file *f
+               case R_386_PLT32:
+               case R_386_PC32:
+-              case R_386_GOTOFF:
+                       *loc += v - dot;
+                       break;
+@@ -973,6 +1034,9 @@ arch_apply_relocation(struct obj_file *f
+               case R_386_GOT32:
+                       goto bb_use_got;
++
++              case R_386_GOTOFF:
++                      *loc += v - got;
+                       break;
+ #elif defined(__microblaze__)
+@@ -1759,7 +1823,7 @@ static int arch_list_add(ElfW(RelM) *rel
+ #if defined(USE_SINGLE)
+-static int arch_single_init(/*ElfW(RelM) *rel,*/ struct arch_single_entry *single,
++static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single,
+                            int offset, int size)
+ {
+       if (single->allocated == 0) {
+@@ -1907,7 +1971,7 @@ static void arch_create_got(struct obj_f
+ #if defined(USE_GOT_ENTRIES)
+                       if (got_allocate) {
+                               got_offset += arch_single_init(
+-                                              /*rel,*/ &intsym->gotent,
++                                              rel, &intsym->gotent,
+                                               got_offset, GOT_ENTRY_SIZE);
+                               got_needed = 1;
+@@ -1921,7 +1985,7 @@ static void arch_create_got(struct obj_f
+                                               plt_offset, PLT_ENTRY_SIZE);
+ #else
+                               plt_offset += arch_single_init(
+-                                              /*rel,*/ &intsym->pltent,
++                                              rel, &intsym->pltent,
+                                               plt_offset, PLT_ENTRY_SIZE);
+ #endif
+                               plt_needed = 1;
+@@ -1959,8 +2023,7 @@ static unsigned long obj_elf_hash_n(cons
+       while (n > 0) {
+               ch = *name++;
+               h = (h << 4) + ch;
+-              g = (h & 0xf0000000);
+-              if (g != 0) {
++              if ((g = (h & 0xf0000000)) != 0) {
+                       h ^= g >> 24;
+                       h &= ~g;
+               }
+@@ -2039,7 +2102,7 @@ obj_add_symbol(struct obj_file *f, const
+       int n_type = ELF_ST_TYPE(info);
+       int n_binding = ELF_ST_BIND(info);
+-      for (sym = f->symtab[hash]; sym; sym = sym->next) {
++      for (sym = f->symtab[hash]; sym; sym = sym->next)
+               if (f->symbol_cmp(sym->name, name) == 0) {
+                       int o_secidx = sym->secidx;
+                       int o_info = sym->info;
+@@ -2098,14 +2161,14 @@ obj_add_symbol(struct obj_file *f, const
+                               return sym;
+                       }
+               }
+-      }
+       /* Completely new symbol.  */
+       sym = arch_new_symbol();
+       sym->next = f->symtab[hash];
+       f->symtab[hash] = sym;
+       sym->ksymidx = -1;
+-      if (ELF_ST_BIND(info) == STB_LOCAL && symidx != (unsigned long)(-1)) {
++
++      if (ELF_ST_BIND(info) == STB_LOCAL && symidx != -1) {
+               if (symidx >= f->local_symtab_size)
+                       bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
+                                       name, (long) symidx, (long) f->local_symtab_size);
+@@ -3228,7 +3291,7 @@ static int obj_relocate(struct obj_file 
+                       /* Do it! */
+                       switch (arch_apply_relocation
+-                                      (f, targsec, /*symsec,*/ intsym, rel, value)
++                                      (f, targsec, symsec, intsym, rel, value)
+                       ) {
+                       case obj_reloc_ok:
+                               break;
+@@ -3307,11 +3370,11 @@ static int obj_create_image(struct obj_f
+ /*======================================================================*/
+-static struct obj_file *obj_load(FILE * fp, int loadprogbits ATTRIBUTE_UNUSED)
++static struct obj_file *obj_load(FILE * fp, int loadprogbits)
  {
-       struct arch_file *f;
-@@ -3952,33 +4008,35 @@
+       struct obj_file *f;
+       ElfW(Shdr) * section_headers;
+-      size_t shnum, i;
++      int shnum, i;
+       char *shstrtab;
+       /* Read the file header.  */
+@@ -3583,7 +3646,7 @@ static int obj_gpl_license(struct obj_fi
+               while (ptr < endptr) {
+                       value = strchr(ptr, '=');
+                       if (value && strncmp(ptr, "license", value-ptr) == 0) {
+-                              unsigned i;
++                              int i;
+                               if (license)
+                                       *license = value+1;
+                               for (i = 0; i < ARRAY_SIZE(gpl_licenses); ++i) {
+@@ -3687,9 +3750,6 @@ static void check_tainted_module(struct 
+  * start of some sections.  this info is used by ksymoops to do better
+  * debugging.
+  */
+-#if !ENABLE_FEATURE_INSMOD_VERSION_CHECKING
+-#define get_module_version(f, str) get_module_version(str)
+-#endif
+ static int
+ get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
+ {
+@@ -3722,8 +3782,7 @@ add_ksymoops_symbols(struct obj_file *f,
+       struct obj_symbol *sym;
+       char *name, *absolute_filename;
+       char str[STRVERSIONLEN];
+-      unsigned i;
+-      int l, lm_name, lfilename, use_ksymtab, version;
++      int i, l, lm_name, lfilename, use_ksymtab, version;
+       struct stat statbuf;
+       /* WARNING: was using realpath, but replaced by readlink to stop using
+@@ -3910,145 +3969,57 @@ static void print_load_map(struct obj_fi
  void print_load_map(struct obj_file *f);
  #endif
  
--int insmod_main( int argc, char **argv);
--int insmod_main( int argc, char **argv)
+-int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+-int insmod_main(int argc, char **argv)
 +int insmod_main_24( int argc, char **argv)
  {
        char *opt_o, *arg1;
-       int len;
+-      int len;
        int k_crcs;
 -      char *tmp, *tmp1;
        unsigned long m_size;
        ElfW(Addr) m_addr;
        struct obj_file *f;
-       struct stat st;
-       char *m_name = 0;
+-      struct stat st;
+-      char *m_name = NULL;
 -      int exit_status = EXIT_FAILURE;
++      char *tmp = NULL, *m_name = NULL;
 +      int ret = EINVAL;
        int m_has_modinfo;
  #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
@@ -186,12 +380,11 @@ Index: busybox-1.7.2/modutils/insmod.c
        int m_version, m_crcs;
  #endif
 -#if ENABLE_FEATURE_CLEAN_UP
--      FILE *fp = 0;
+       FILE *fp = NULL;
 -#else
 -      FILE *fp;
 -#endif
 -      int k_version = 0;
-+      FILE *fp = NULL;
 +      int k_version;
        struct utsname myuname;
  
@@ -206,7 +399,8 @@ Index: busybox-1.7.2/modutils/insmod.c
        /* Parse any options */
        getopt32(argv, OPTION_STR, &opt_o);
        arg1 = argv[optind];
-@@ -3987,110 +4045,18 @@
+       if (option_mask32 & OPT_o) { // -o /* name the output module */
+-              free(m_name);
                m_name = xstrdup(opt_o);
        }
  
@@ -214,7 +408,7 @@ Index: busybox-1.7.2/modutils/insmod.c
 +      if (arg1 == NULL)
                bb_show_usage();
 -      }
--
 -      /* Grab the module name */
 -      tmp1 = xstrdup(arg1);
 -      tmp = basename(tmp1);
@@ -246,15 +440,18 @@ Index: busybox-1.7.2/modutils/insmod.c
 -      else
 -#endif
 -              m_fullName = xasprintf("%s.o", tmp);
++      ret = find_module(arg1);
++      if (ret)
++              goto out;
  
--      if (!m_name) {
+       if (!m_name) {
 -              m_name = tmp;
 -      } else {
 -              free(tmp1);
--              tmp1 = 0;       /* flag for free(m_name) before exit() */
+-              tmp1 = NULL;       /* flag for free(m_name) before exit() */
 -      }
 -
--      /* Get a filedesc for the module.  Check we we have a complete path */
+-      /* Get a filedesc for the module.  Check that we have a complete path */
 -      if (stat(arg1, &st) < 0 || !S_ISREG(st.st_mode)
 -       || (fp = fopen(arg1, "r")) == NULL
 -      ) {
@@ -263,54 +460,53 @@ Index: busybox-1.7.2/modutils/insmod.c
 -              if (k_version) {        /* uname succeedd */
 -                      char *module_dir;
 -                      char *tmdn;
--                      char real_module_dir[FILENAME_MAX];
 -
--                      tmdn = concat_path_file(_PATH_MODULES, myuname.release);
+-                      tmdn = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, 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;
+-                      module_dir = xmalloc_readlink(tmdn);
+-                      if (!module_dir)
+-                              module_dir = xstrdup(tmdn);
 -                      recursive_action(module_dir, ACTION_RECURSE,
--                                      check_module_name_match, 0, m_fullName, 0);
+-                                      check_module_name_match, NULL, m_fullName, 0);
+-                      free(module_dir);
 -                      free(tmdn);
 -              }
 -
 -              /* Check if we have found anything yet */
--              if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL)) {
--                      char module_dir[FILENAME_MAX];
+-              if (!m_filename || ((fp = fopen(m_filename, "r")) == NULL)) {
+-                      int r;
+-                      char *module_dir;
 -
 -                      free(m_filename);
--                      m_filename = 0;
--                      if (realpath (_PATH_MODULES, module_dir) == NULL)
--                              strcpy(module_dir, _PATH_MODULES);
+-                      m_filename = NULL;
+-                      module_dir = xmalloc_readlink(CONFIG_DEFAULT_MODULES_DIR);
+-                      if (!module_dir)
+-                              module_dir = xstrdup(CONFIG_DEFAULT_MODULES_DIR);
 -                      /* No module found under /lib/modules/`uname -r`, this
 -                       * time cast the net a bit wider.  Search /lib/modules/ */
--                      if (!recursive_action(module_dir, ACTION_RECURSE,
--                                                  check_module_name_match, 0, m_fullName, 0)
+-                      r = recursive_action(module_dir, ACTION_RECURSE,
+-                                      check_module_name_match, NULL, m_fullName, 0);
+-                      if (r)
+-                              bb_error_msg_and_die("%s: module not found", m_fullName);
+-                      free(module_dir);
+-                      if (m_filename == NULL
+-                       || ((fp = fopen(m_filename, "r")) == NULL)
 -                      ) {
--                              if (m_filename == 0
--                               || ((fp = fopen(m_filename, "r")) == NULL)
--                              ) {
--                                      bb_error_msg("%s: no module by that name found", m_fullName);
--                                      goto out;
--                              }
--                      } else
--                              bb_error_msg_and_die("%s: no module by that name found", m_fullName);
--              }
+-                              bb_error_msg_and_die("%s: module not found", m_fullName);
+-                      }
++              tmp = xstrdup(arg1);
++              m_name = basename(tmp);
+               }
 -      } else
 -              m_filename = xstrdup(arg1);
--
 -      if (flag_verbose)
 -              printf("Using %s\n", m_filename);
-+      ret = find_module(arg1);
-+      if (ret)
-+              goto out;
+-
 -#if ENABLE_FEATURE_2_6_MODULES
 -      if (k_version > 4) {
 -              argv[optind] = m_filename;
@@ -324,8 +520,8 @@ Index: busybox-1.7.2/modutils/insmod.c
 -#endif
  
        f = obj_load(fp, LOADBITS);
-       if (f == NULL)
-@@ -4120,7 +4086,7 @@
+@@ -4075,7 +4046,7 @@ int insmod_main(int argc, char **argv)
                                "\t%s was compiled for kernel version %s\n"
                                "\twhile this kernel is version %s",
                                flag_force_load ? "warning: " : "",
@@ -334,7 +530,7 @@ Index: busybox-1.7.2/modutils/insmod.c
                        if (!flag_force_load)
                                goto out;
                }
-@@ -4173,7 +4139,7 @@
+@@ -4117,7 +4088,7 @@ int insmod_main(int argc, char **argv)
        hide_special_symbols(f);
  
  #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
@@ -343,48 +539,89 @@ Index: busybox-1.7.2/modutils/insmod.c
  #endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
  
        new_create_module_ksymtab(f);
-@@ -4220,8 +4186,7 @@
+@@ -4126,7 +4097,7 @@ int insmod_main(int argc, char **argv)
+       m_size = obj_load_size(f);
+       m_addr = create_module(m_name, m_size);
+-      if (m_addr == (ElfW(Addr))(-1)) switch (errno) {
++      if (m_addr == -1) switch (errno) {
+               case EEXIST:
+                       bb_error_msg_and_die("a module named %s already exists", m_name);
+               case ENOMEM:
+@@ -4142,36 +4113,37 @@ int insmod_main(int argc, char **argv)
+        * now we can load them directly into the kernel memory
+        */
+       if (!obj_load_progbits(fp, f, (char*)m_addr)) {
+-              delete_module(m_name, 0);
++              delete_module(m_name);
+               goto out;
+       }
+ #endif
+       if (!obj_relocate(f, m_addr)) {
+-              delete_module(m_name, 0);
++              delete_module(m_name);
+               goto out;
+       }
+       if (!new_init_module(m_name, f, m_size)) {
+-              delete_module(m_name, 0);
++              delete_module(m_name);
+               goto out;
+       }
        if (flag_print_load_map)
                print_load_map(f);
  
 -      exit_status = EXIT_SUCCESS;
--
-+      ret = 0;
- out:
++      ret = EXIT_SUCCESS;
 out:
  #if ENABLE_FEATURE_CLEAN_UP
        if (fp)
-@@ -4229,21 +4194,13 @@
-       free(tmp1);
-       if (!tmp1)
+               fclose(fp);
+-      free(tmp1);
+-      if (!tmp1)
++      if (tmp)
++              free(tmp);
++      else if (m_name)
                free(m_name);
 -      free(m_filename);
 +      free(g_filename);
  #endif
-       return exit_status;
+-      return exit_status;
++      return ret;
  }
--
--
- #endif
  
--
+ #endif /* ENABLE_FEATURE_2_4_MODULES */
+@@ -4183,15 +4155,8 @@ int insmod_main(int argc, char **argv)
  #if ENABLE_FEATURE_2_6_MODULES
+ #include <sys/mman.h>
 -
--#include <sys/mman.h>
--#include <asm/unistd.h>
--#include <sys/syscall.h>
--
+-#if defined __UCLIBC__ && !ENABLE_FEATURE_2_4_MODULES
+-/* big time suckage. The old prototype above renders our nice fwd-decl wrong */
+-extern int init_module(void *module, unsigned long len, const char *options);
+-#else
+ #include <asm/unistd.h>
+ #include <sys/syscall.h>
+-#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
+-#endif
  /* We use error numbers in a loose translation... */
  static const char *moderror(int err)
- {
-@@ -4261,19 +4218,33 @@
+@@ -4210,22 +4175,32 @@ static const char *moderror(int err)
        }
  }
  
--int insmod_ng_main(int argc, char **argv);
--int insmod_ng_main(int argc, char **argv)
+-#if !ENABLE_FEATURE_2_4_MODULES
+-int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+-int insmod_main(int argc ATTRIBUTE_UNUSED, char **argv)
+-#else
+-static int insmod_ng_main(int argc ATTRIBUTE_UNUSED, char **argv)
+-#endif
 +int insmod_main_26(int argc, char **argv)
  {
--      long ret;
 -      size_t len;
 +      char *filename, *options;
 +      struct utsname myuname;
@@ -407,20 +644,27 @@ Index: busybox-1.7.2/modutils/insmod.c
        if (!filename)
                bb_show_usage();
  
-+      g_filename = filename;
 +      ret = find_module(filename);
-+      if (ret)
++      if (ret || (g_filename == NULL))
 +              goto done;
 +
        /* Rest is options */
        options = xzalloc(1);
        optlen = 0;
-@@ -4283,36 +4254,46 @@
+@@ -4235,41 +4210,47 @@ static int insmod_ng_main(int argc ATTRI
                optlen += sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv);
        }
  
 -#if 0
--      /* Any special reason why mmap? It isn't performace critical... */
+-      /* Any special reason why mmap? It isn't performance critical. -vda */
+-      /* Yes, xmalloc'ing can use *alot* of RAM. Don't forget that there are
+-       * modules out there that are half a megabyte! mmap()ing is way nicer
+-       * for small mem boxes, i guess. */
+-      /* But after load, these modules will take up that 0.5mb in kernel
+-       * anyway. Using malloc here causes only a transient spike to 1mb,
+-       * after module is loaded, we go back to normal 0.5mb usage
+-       * (in kernel). Also, mmap isn't magic - when we touch mapped data,
+-       * we use memory. -vda */
 -      int fd;
 -      struct stat st;
 -      unsigned long len;
@@ -441,18 +685,19 @@ Index: busybox-1.7.2/modutils/insmod.c
        len = MAXINT(ssize_t);
 -      map = xmalloc_open_read_close(filename, &len);
 -#endif
--
 +      map = xmalloc_open_read_close(g_filename, &len);
-       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);
++      ret = syscall(__NR_init_module, map, len, options);
++      if (ret != 0) {
++              bb_perror_msg_and_die("cannot insert '%s': %s (%li)",
 +                              g_filename, moderror(errno), ret);
-       }
++      }
 +done:
 +      if (g_filename && (g_filename != filename))
 +              free(g_filename);
  
+-      if (init_module(map, len, options) != 0)
+-              bb_error_msg_and_die("cannot insert '%s': %s",
+-                              filename, moderror(errno));
 -      return 0;
 +      return ret;
  }
@@ -463,6 +708,7 @@ Index: busybox-1.7.2/modutils/insmod.c
 +{
 +      int ret;
 +
++      g_filename = NULL;
 +#if ENABLE_FEATURE_2_6_MODULES
 +      ret = insmod_main_26(argc, argv);
 +      if (ret != ENOTSUP)