ash: do not let EXIT trap to fire in `trap`
[oweals/busybox.git] / modutils / modprobe-small.c
index 6eb950f32ea8103136a39a020a0ba8c46ce663cc..e2359d042259c16c31510dcf18685c85bf7509b2 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include "libbb.h"
-
+/* After libbb.h, since it needs sys/types.h on some systems */
 #include <sys/utsname.h> /* uname() */
 #include <fnmatch.h>
 
@@ -44,11 +44,13 @@ struct globals {
        char *module_load_options;
        smallint dep_bb_seen;
        smallint wrote_dep_bb_ok;
-       int module_count;
+       unsigned module_count;
        int module_found_idx;
-       int stringbuf_idx;
-       char stringbuf[32 * 1024]; /* some modules have lots of stuff */
+       unsigned stringbuf_idx;
+       unsigned stringbuf_size;
+       char *stringbuf; /* some modules have lots of stuff */
        /* for example, drivers/media/video/saa7134/saa7134.ko */
+       /* therefore having a fixed biggish buffer is not wise */
 };
 #define G (*ptr_to_globals)
 #define modinfo             (G.modinfo            )
@@ -58,16 +60,29 @@ struct globals {
 #define module_found_idx    (G.module_found_idx   )
 #define module_load_options (G.module_load_options)
 #define stringbuf_idx       (G.stringbuf_idx      )
+#define stringbuf_size      (G.stringbuf_size     )
 #define stringbuf           (G.stringbuf          )
 #define INIT_G() do { \
        SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
 } while (0)
 
+static void append(const char *s)
+{
+       unsigned len = strlen(s);
+       if (stringbuf_idx + len + 15 > stringbuf_size) {
+               stringbuf_size = stringbuf_idx + len + 127;
+               dbg2_error_msg("grow stringbuf to %u", stringbuf_size);
+               stringbuf = xrealloc(stringbuf, stringbuf_size);
+       }
+       memcpy(stringbuf + stringbuf_idx, s, len);
+       stringbuf_idx += len;
+}
 
 static void appendc(char c)
 {
-       if (stringbuf_idx < sizeof(stringbuf))
-               stringbuf[stringbuf_idx++] = c;
+       /* We appendc() only after append(), + 15 trick in append()
+        * makes it unnecessary to check for overflow here */
+       stringbuf[stringbuf_idx++] = c;
 }
 
 static void bksp(void)
@@ -76,15 +91,6 @@ static void bksp(void)
                stringbuf_idx--;
 }
 
-static void append(const char *s)
-{
-       size_t len = strlen(s);
-       if (stringbuf_idx + len < sizeof(stringbuf)) {
-               memcpy(stringbuf + stringbuf_idx, s, len);
-               stringbuf_idx += len;
-       }
-}
-
 static void reset_stringbuf(void)
 {
        stringbuf_idx = 0;
@@ -92,7 +98,7 @@ static void reset_stringbuf(void)
 
 static char* copy_stringbuf(void)
 {
-       char *copy = xmalloc(stringbuf_idx);
+       char *copy = xzalloc(stringbuf_idx + 1); /* terminating NUL */
        return memcpy(copy, stringbuf, stringbuf_idx);
 }
 
@@ -216,8 +222,8 @@ static void parse_module(module_info *info, const char *pathname)
                pos = (ptr - module_image);
        }
        bksp(); /* remove last ' ' */
-       appendc('\0');
        info->aliases = copy_stringbuf();
+       replace(info->aliases, '-', '_');
 
        /* "dependency1 depandency2" */
        reset_stringbuf();
@@ -228,7 +234,6 @@ static void parse_module(module_info *info, const char *pathname)
                dbg2_error_msg("dep:'%s'", ptr);
                append(ptr);
        }
-       appendc('\0');
        info->deps = copy_stringbuf();
 
        free(module_image);
@@ -314,6 +319,7 @@ static int load_dep_bb(void)
 
        while ((line = xmalloc_fgetline(fp)) != NULL) {
                char* space;
+               char* linebuf;
                int cur;
 
                if (!line[0]) {
@@ -328,7 +334,8 @@ static int load_dep_bb(void)
                if (*space)
                        *space++ = '\0';
                modinfo[cur].aliases = space;
-               modinfo[cur].deps = xmalloc_fgetline(fp) ? : xzalloc(1);
+               linebuf = xmalloc_fgetline(fp);
+               modinfo[cur].deps = linebuf ? linebuf : xzalloc(1);
                if (modinfo[cur].deps[0]) {
                        /* deps are not "", so next line must be empty */
                        line = xmalloc_fgetline(fp);
@@ -656,7 +663,7 @@ depmod -[aA] [-n -e -v -q -V -r -u]
       [-b basedirectory] [forced_version]
 depmod [-n -e -v -q -r -u] [-F kernelsyms] module1.ko module2.ko ...
 If no arguments (except options) are given, "depmod -a" is assumed.
-depmod will output a dependancy list suitable for the modprobe utility.
+depmod will output a dependency list suitable for the modprobe utility.
 Options:
     -a, --all           Probe all modules
     -A, --quick         Only does the work if there's a new module
@@ -679,7 +686,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
 {
        struct utsname uts;
        char applet0 = applet_name[0];
-       USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;)
+       IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;)
 
        /* are we lsmod? -> just dump /proc/modules */
        if ('l' == applet0) {
@@ -773,8 +780,8 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
                len = MAXINT(ssize_t);
                map = xmalloc_xopen_read_close(*argv, &len);
                if (init_module(map, len,
-                       USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : "")
-                       SKIP_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE("")
+                       IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : "")
+                       IF_NOT_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE("")
                                ) != 0)
                        bb_error_msg_and_die("can't insert '%s': %s",
                                        *argv, moderror(errno));
@@ -791,7 +798,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
        } while (*argv);
 
        if (ENABLE_FEATURE_CLEAN_UP) {
-               USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);)
+               IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);)
        }
        return EXIT_SUCCESS;
 }