Fix for dpkg-deb, courtesy of Larry Doolittle.
[oweals/busybox.git] / modutils / insmod.c
index be27a1f2b5b2914b82f95d37975f5e72f841ea2a..fc49dcd3444e11ad4a370ab75306f187efc965b1 100644 (file)
@@ -78,7 +78,7 @@
 #ifndef MODUTILS_MODULE_H
 static const int MODUTILS_MODULE_H = 1;
 
-#ident "$Id: insmod.c,v 1.36 2001/01/23 22:30:04 markw Exp $"
+#ident "$Id: insmod.c,v 1.39 2001/01/24 23:59:50 andersen Exp $"
 
 /* This file contains the structures used by the 2.0 and 2.1 kernels.
    We do not use the kernel headers directly because we do not wish
@@ -284,7 +284,7 @@ int delete_module(const char *);
 #ifndef MODUTILS_OBJ_H
 static const int MODUTILS_OBJ_H = 1;
 
-#ident "$Id: insmod.c,v 1.36 2001/01/23 22:30:04 markw Exp $"
+#ident "$Id: insmod.c,v 1.39 2001/01/24 23:59:50 andersen Exp $"
 
 /* The relocatable object is manipulated using elfin types.  */
 
@@ -519,10 +519,6 @@ int arch_init_module (struct obj_file *f, struct new_module *);
 #define _PATH_MODULES  "/lib/modules"
 static const int STRVERSIONLEN = 32;
 
-#if !defined(BB_FEATURE_INSMOD_NEW_KERNEL) && !defined(BB_FEATURE_INSMOD_OLD_KERNEL)
-#error "Must have ether BB_FEATURE_INSMOD_NEW_KERNEL or BB_FEATURE_INSMOD_OLD_KERNEL defined"
-#endif
-
 /*======================================================================*/
 
 int flag_force_load = 0;
@@ -615,7 +611,7 @@ extern int delete_module(const char *);
 
    -- Bryan Rittmeyer <bryan@ixiacom.com>                    */
 
-#ifdef BB_FEATURE_INSMOD_OLD_KERNEL
+#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
 _syscall1(int, get_kernel_syms, struct old_kernel_sym *, ks)
 #endif
 
@@ -1549,7 +1545,7 @@ old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
 
 #endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */
 
-#ifdef BB_FEATURE_INSMOD_OLD_KERNEL
+#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
 
 /* Fetch all the symbols and divvy them up as appropriate for the modules.  */
 
@@ -1757,7 +1753,7 @@ old_init_module(const char *m_name, struct obj_file *f,
 #define old_create_mod_use_count(x) TRUE
 #define old_init_module(x, y, z) TRUE
 
-#endif                                                 /* BB_FEATURE_INSMOD_OLD_KERNEL */
+#endif                                                 /* BB_FEATURE_OLD_MODULE_INTERFACE */
 
 
 
@@ -2036,7 +2032,7 @@ new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
 #endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */
 
 
-#ifdef BB_FEATURE_INSMOD_NEW_KERNEL
+#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
 
 /* Fetch the loaded modules, and all currently exported symbols.  */
 
@@ -2310,7 +2306,7 @@ new_init_module(const char *m_name, struct obj_file *f,
 #define new_create_module_ksymtab(x)
 #define query_module(v, w, x, y, z) -1
 
-#endif                                                 /* BB_FEATURE_INSMOD_NEW_KERNEL */
+#endif                                                 /* BB_FEATURE_NEW_MODULE_INTERFACE */
 
 
 /*======================================================================*/
@@ -2872,6 +2868,7 @@ static void hide_special_symbols(struct obj_file *f)
 
 extern int insmod_main( int argc, char **argv)
 {
+       int opt;
        int k_crcs;
        int k_new_syscalls;
        int len;
@@ -2891,15 +2888,9 @@ extern int insmod_main( int argc, char **argv)
        int m_crcs;
 #endif
 
-
-       if (argc <= 1) {
-               usage(insmod_usage);
-       }
-
        /* Parse any options */
-       while (--argc > 0 && **(++argv) == '-') {
-               while (*(++(*argv))) {
-                       switch (**argv) {
+       while ((opt = getopt(argc, argv, "fkvxL")) > 0) {
+               switch (opt) {
                        case 'f':                       /* force loading */
                                flag_force_load = 1;
                                break;
@@ -2912,20 +2903,26 @@ extern int insmod_main( int argc, char **argv)
                        case 'x':                       /* do not export externs */
                                flag_export = 0;
                                break;
+                       case 'L':                       /* Stub warning */
+                               /* This is needed for compatibility with modprobe.
+                                * In theory, this does locking, but we don't do
+                                * that.  So be careful and plan your life around not
+                                * loading the same module 50 times concurrently. */
+                               break;
                        default:
                                usage(insmod_usage);
-                       }
                }
        }
-
-       if (argc <= 0) {
+       
+       if (argv[optind] == NULL) {
                usage(insmod_usage);
        }
+
        /* Grab the module name */
-       if ((tmp = strrchr(*argv, '/')) != NULL) {
+       if ((tmp = strrchr(argv[optind], '/')) != NULL) {
                tmp++;
        } else {
-               tmp = *argv;
+               tmp = argv[optind];
        }
        len = strlen(tmp);
 
@@ -2936,7 +2933,7 @@ extern int insmod_main( int argc, char **argv)
        strcat(m_fullName, ".o");
 
        /* Get a filedesc for the module */
-       if ((fp = fopen(*argv, "r")) == NULL) {
+       if ((fp = fopen(argv[optind], "r")) == NULL) {
                /* Hmpf.  Could not open it. Search through _PATH_MODULES to find a module named m_name */
                if (recursive_action(_PATH_MODULES, TRUE, FALSE, FALSE,
                                                        findNamedModule, 0, m_fullName) == FALSE) 
@@ -2950,7 +2947,7 @@ extern int insmod_main( int argc, char **argv)
                } else
                        error_msg_and_die("No module named '%s' found in '%s'\n", m_fullName, _PATH_MODULES);
        } else
-               memcpy(m_filename, *argv, strlen(*argv));
+               memcpy(m_filename, argv[optind], strlen(argv[optind]));
 
 
        if ((f = obj_load(fp)) == NULL)
@@ -2996,7 +2993,7 @@ extern int insmod_main( int argc, char **argv)
        k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
 
        if (k_new_syscalls) {
-#ifdef BB_FEATURE_INSMOD_NEW_KERNEL
+#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
                if (!new_get_kernel_symbols())
                        goto out;
                k_crcs = new_is_kernel_checksummed();
@@ -3005,7 +3002,7 @@ extern int insmod_main( int argc, char **argv)
                goto out;
 #endif
        } else {
-#ifdef BB_FEATURE_INSMOD_OLD_KERNEL
+#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
                if (!old_get_kernel_symbols(m_name))
                        goto out;
                k_crcs = old_is_kernel_checksummed();
@@ -3042,6 +3039,9 @@ extern int insmod_main( int argc, char **argv)
        }
        obj_allocate_commons(f);
 
+       /* done with the module name, on to the optional var=value arguments */
+       ++optind;
+
        if (optind < argc) {
                if (m_has_modinfo
                        ? !new_process_module_arguments(f, argc - optind, argv + optind) 
@@ -3061,11 +3061,8 @@ extern int insmod_main( int argc, char **argv)
        m_size = obj_load_size(f);
 
 
-       errno = 0;
        m_addr = create_module(m_name, m_size);
-       switch (errno) {
-       case 0:
-               break;
+       if (m_addr==-1) switch (errno) {
        case EEXIST:
                error_msg("A module named %s already exists\n", m_name);
                goto out;