cpio: testsuite for http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=466771
[oweals/busybox.git] / modutils / modprobe.c
index a67ddea9b59e382a618670eb1d1f3e5c8b0aba70..1a4f5d4d42c60f404a4a316ef46919cf1c9ff373 100644 (file)
@@ -15,6 +15,8 @@
 #include <sys/utsname.h>
 #include <fnmatch.h>
 
+#define line_buffer bb_common_bufsiz1
+
 struct mod_opt_t {     /* one-way list of options to pass to a module */
        char *  m_opt_val;
        struct mod_opt_t * m_next;
@@ -22,17 +24,18 @@ struct mod_opt_t {  /* one-way list of options to pass to a module */
 
 struct dep_t { /* one-way list of dependency rules */
        /* a dependency rule */
-       char *  m_name;                         /* the module name*/
-       char *  m_path;                         /* the module file path */
-       struct mod_opt_t *  m_options;          /* the module options */
+       char *  m_name;                     /* the module name*/
+       char *  m_path;                     /* the module file path */
+       struct mod_opt_t *  m_options;      /* the module options */
 
-       int     m_isalias  : 1;                 /* the module is an alias */
-       int     m_reserved : 15;                /* stuffin' */
+       unsigned int m_isalias      :1;     /* the module is an alias */
+       unsigned int m_isblacklisted:1;     /* the module is blacklisted */
+       unsigned int m_reserved     :14;    /* stuffin' */
 
-       int     m_depcnt   : 16;                /* the number of dependable module(s) */
-       char ** m_deparr;                       /* the list of dependable module(s) */
+       unsigned int m_depcnt       :16;    /* the number of dependable module(s) */
+       char ** m_deparr;                   /* the list of dependable module(s) */
 
-       struct dep_t * m_next;                  /* the next dependency rule */
+       struct dep_t * m_next;              /* the next dependency rule */
 };
 
 struct mod_list_t {    /* two-way list of modules to process */
@@ -48,7 +51,7 @@ struct mod_list_t {   /* two-way list of modules to process */
 
 static struct dep_t *depend;
 
-#define main_options "acdklnqrst:vVC:"
+#define MAIN_OPT_STR "acdklnqrst:vVC:"
 #define INSERT_ALL     1        /* a */
 #define DUMP_CONF_EXIT 2        /* c */
 #define D_OPT_IGNORED  4        /* d */
@@ -63,14 +66,12 @@ static struct dep_t *depend;
 #define VERSION_ONLY   2048     /* V */
 #define CONFIG_FILE    4096     /* C */
 
-#define autoclean       (main_opts & AUTOCLEAN_FLG)
-#define show_only       (main_opts & SHOW_ONLY)
-#define quiet           (main_opts & QUIET)
-#define remove_opt      (main_opts & REMOVE_OPT)
-#define do_syslog       (main_opts & DO_SYSLOG)
-#define verbose         (main_opts & VERBOSE)
-
-static int main_opts;
+#define autoclean       (option_mask32 & AUTOCLEAN_FLG)
+#define show_only       (option_mask32 & SHOW_ONLY)
+#define quiet           (option_mask32 & QUIET)
+#define remove_opt      (option_mask32 & REMOVE_OPT)
+#define do_syslog       (option_mask32 & DO_SYSLOG)
+#define verbose         (option_mask32 & VERBOSE)
 
 static int parse_tag_value(char *buffer, char **ptag, char **pvalue)
 {
@@ -78,12 +79,15 @@ static int parse_tag_value(char *buffer, char **ptag, char **pvalue)
 
        buffer = skip_whitespace(buffer);
        tag = value = buffer;
-       while (!isspace(*value))
-               if (!*value) return 0;
-               else value++;
-       *value++ = 0;
+       while (!isspace(*value)) {
+               if (!*value)
+                       return 0;
+               value++;
+       }
+       *value++ = '\0';
        value = skip_whitespace(value);
-       if (!*value) return 0;
+       if (!*value)
+               return 0;
 
        *ptag = tag;
        *pvalue = value;
@@ -102,14 +106,14 @@ static struct mod_opt_t *append_option(struct mod_opt_t *opt_list, char *opt)
                while (ol->m_next) {
                        ol = ol->m_next;
                }
-               ol->m_next = xmalloc(sizeof(struct mod_opt_t));
+               ol->m_next = xzalloc(sizeof(struct mod_opt_t));
                ol = ol->m_next;
        } else {
-               ol = opt_list = xmalloc(sizeof(struct mod_opt_t));
+               ol = opt_list = xzalloc(sizeof(struct mod_opt_t));
        }
 
        ol->m_opt_val = xstrdup(opt);
-       ol->m_next = NULL;
+       /*ol->m_next = NULL; - done by xzalloc*/
 
        return opt_list;
 }
@@ -190,7 +194,8 @@ static char *parse_command_string(char *src, char **dst)
                                case '0':
                                        /* We escaped a special character. For now, keep
                                         * both the back-slash and the following char. */
-                                       tmp_str++; src++;
+                                       tmp_str++;
+                                       src++;
                                        break;
                                default:
                                        /* We escaped a space or a single or double quote,
@@ -226,6 +231,13 @@ static char *parse_command_string(char *src, char **dst)
 #define parse_command_string(src, dst) (0)
 #endif /* ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS */
 
+static int is_conf_command(char *buffer, const char *command)
+{
+       int len = strlen(command);
+       return ((strstr(buffer, command) == buffer) &&
+                       isspace(buffer[len]));
+}
+
 /*
  * This function reads aliases and default module options from a configuration file
  * (/etc/modprobe.conf syntax). It supports includes (only files, no directories).
@@ -238,16 +250,13 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf
 
        while (reads(fd, buffer, buflen)) {
                int l;
-               char *p;
 
-               p = strchr(buffer, '#');
-               if (p)
-                       *p = 0;
+               *strchrnul(buffer, '#') = '\0';
 
                l = strlen(buffer);
 
                while (l && isspace(buffer[l-1])) {
-                       buffer[l-1] = 0;
+                       buffer[l-1] = '\0';
                        l--;
                }
 
@@ -256,66 +265,80 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf
                        continue;
                }
 
-               if (!continuation_line) {
-                       if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) {
-                               char *alias, *mod;
+               if (continuation_line)
+                       continue;
 
-                               if (parse_tag_value(buffer + 6, &alias, &mod)) {
-                                       /* handle alias as a module dependent on the aliased module */
-                                       if (!*current) {
-                                               (*first) = (*current) = xzalloc(sizeof(struct dep_t));
-                                       } else {
-                                               (*current)->m_next = xzalloc(sizeof(struct dep_t));
-                                               (*current) = (*current)->m_next;
-                                       }
-                                       (*current)->m_name  = xstrdup(alias);
-                                       (*current)->m_isalias = 1;
+               if (is_conf_command(buffer, "alias")) {
+                       char *alias, *mod;
 
-                                       if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) {
-                                               (*current)->m_depcnt = 0;
-                                               (*current)->m_deparr = 0;
-                                       } else {
-                                               (*current)->m_depcnt  = 1;
-                                               (*current)->m_deparr  = xmalloc(1 * sizeof(char *));
-                                               (*current)->m_deparr[0] = xstrdup(mod);
-                                       }
-                                       (*current)->m_next    = 0;
+                       if (parse_tag_value(buffer + 6, &alias, &mod)) {
+                               /* handle alias as a module dependent on the aliased module */
+                               if (!*current) {
+                                       (*first) = (*current) = xzalloc(sizeof(struct dep_t));
+                               } else {
+                                       (*current)->m_next = xzalloc(sizeof(struct dep_t));
+                                       (*current) = (*current)->m_next;
                                }
-                       } else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) {
-                               char *mod, *opt;
+                               (*current)->m_name = xstrdup(alias);
+                               (*current)->m_isalias = 1;
 
-                               /* split the line in the module/alias name, and options */
-                               if (parse_tag_value(buffer + 8, &mod, &opt)) {
-                                       struct dep_t *dt;
-
-                                       /* find the corresponding module */
-                                       for (dt = *first; dt; dt = dt->m_next) {
-                                               if (strcmp(dt->m_name, mod) == 0)
-                                                       break;
-                                       }
-                                       if (dt) {
-                                               if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) {
-                                                       char* new_opt = NULL;
-                                                       while ((opt = parse_command_string(opt, &new_opt))) {
-                                                               dt->m_options = append_option(dt->m_options, new_opt);
-                                                       }
-                                               } else {
-                                                       dt->m_options = append_option(dt->m_options, opt);
-                                               }
-                                       }
+                               if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) {
+                                       /*(*current)->m_depcnt = 0; - done by xzalloc */
+                                       /*(*current)->m_deparr = 0;*/
+                               } else {
+                                       (*current)->m_depcnt = 1;
+                                       (*current)->m_deparr = xmalloc(sizeof(char *));
+                                       (*current)->m_deparr[0] = xstrdup(mod);
                                }
-                       } else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) {
-                               int fdi; char *filename;
+                               /*(*current)->m_next = NULL; - done by xzalloc */
+                       }
+               } else if (is_conf_command(buffer, "options")) {
+                       char *mod, *opt;
 
-                               filename = skip_whitespace(buffer + 8);
+                       /* split the line in the module/alias name, and options */
+                       if (parse_tag_value(buffer + 8, &mod, &opt)) {
+                               struct dep_t *dt;
 
-                               if ((fdi = open(filename, O_RDONLY)) >= 0) {
-                                       include_conf(first, current, buffer, buflen, fdi);
-                                       close(fdi);
+                               /* find the corresponding module */
+                               for (dt = *first; dt; dt = dt->m_next) {
+                                       if (strcmp(dt->m_name, mod) == 0)
+                                               break;
                                }
+                               if (dt) {
+                                       if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) {
+                                               char* new_opt = NULL;
+                                               while ((opt = parse_command_string(opt, &new_opt))) {
+                                                       dt->m_options = append_option(dt->m_options, new_opt);
+                                               }
+                                       } else {
+                                               dt->m_options = append_option(dt->m_options, opt);
+                                       }
+                               }
+                       }
+               } else if (is_conf_command(buffer, "include")) {
+                       int fdi;
+                       char *filename;
+
+                       filename = skip_whitespace(buffer + 8);
+                       fdi = open(filename, O_RDONLY);
+                       if (fdi >= 0) {
+                               include_conf(first, current, buffer, buflen, fdi);
+                               close(fdi);
+                       }
+               } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST &&
+                               (is_conf_command(buffer, "blacklist"))) {
+                       char *mod;
+                       struct dep_t *dt;
+
+                       mod = skip_whitespace(buffer + 10);
+                       for (dt = *first; dt; dt = dt->m_next) {
+                               if (strcmp(dt->m_name, mod) == 0)
+                                       break;
                        }
+                       if (dt)
+                               dt->m_isblacklisted = 1;
                }
-       }
+       } /* while (reads(...)) */
 }
 
 /*
@@ -327,9 +350,8 @@ static struct dep_t *build_dep(void)
 {
        int fd;
        struct utsname un;
-       struct dep_t *first = 0;
-       struct dep_t *current = 0;
-       char buffer[2048];
+       struct dep_t *first = NULL;
+       struct dep_t *current = NULL;
        char *filename;
        int continuation_line = 0;
        int k_version;
@@ -342,24 +364,24 @@ static struct dep_t *build_dep(void)
                k_version = un.release[2] - '0';
        }
 
-       filename = xasprintf("/lib/modules/%s/modules.dep", un.release);
+       filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/"CONFIG_DEFAULT_DEPMOD_FILE, un.release);
        fd = open(filename, O_RDONLY);
        if (ENABLE_FEATURE_CLEAN_UP)
                free(filename);
        if (fd < 0) {
                /* Ok, that didn't work.  Fall back to looking in /lib/modules */
-               fd = open("/lib/modules/modules.dep", O_RDONLY);
+               fd = open(CONFIG_DEFAULT_MODULES_DIR"/"CONFIG_DEFAULT_DEPMOD_FILE, O_RDONLY);
                if (fd < 0) {
-                       return 0;
+                       bb_error_msg_and_die("cannot parse " CONFIG_DEFAULT_DEPMOD_FILE);
                }
        }
 
-       while (reads(fd, buffer, sizeof(buffer))) {
-               int l = strlen(buffer);
+       while (reads(fd, line_buffer, sizeof(line_buffer))) {
+               int l = strlen(line_buffer);
                char *p = 0;
 
-               while (l > 0 && isspace(buffer[l-1])) {
-                       buffer[l-1] = 0;
+               while (l > 0 && isspace(line_buffer[l-1])) {
+                       line_buffer[l-1] = '\0';
                        l--;
                }
 
@@ -371,7 +393,7 @@ static struct dep_t *build_dep(void)
                /* Is this a new module dep description? */
                if (!continuation_line) {
                        /* find the dep beginning */
-                       char *col = strchr(buffer, ':');
+                       char *col = strchr(line_buffer, ':');
                        char *dot = col;
 
                        if (col) {
@@ -381,53 +403,49 @@ static struct dep_t *build_dep(void)
                                char *mod;
 
                                /* Find the beginning of the module file name */
-                               *col = 0;
-                               mods = bb_basename(buffer);
+                               *col = '\0';
+                               mods = bb_basename(line_buffer);
 
                                /* find the path of the module */
-                               modpath = strchr(buffer, '/'); /* ... and this is the path */
+                               modpath = strchr(line_buffer, '/'); /* ... and this is the path */
                                if (!modpath)
-                                       modpath = buffer; /* module with no path */
+                                       modpath = line_buffer; /* module with no path */
                                /* find the end of the module name in the file name */
                                if (ENABLE_FEATURE_2_6_MODULES &&
-                                    (k_version > 4) && (*(col-3) == '.') &&
-                                   (*(col-2) == 'k') && (*(col-1) == 'o'))
+                                   (k_version > 4) && (col[-3] == '.') &&
+                                   (col[-2] == 'k') && (col[-1] == 'o'))
                                        dot = col - 3;
-                               else
-                                       if ((*(col-2) == '.') && (*(col-1) == 'o'))
-                                               dot = col - 2;
+                               else if ((col[-2] == '.') && (col[-1] == 'o'))
+                                       dot = col - 2;
 
                                mod = xstrndup(mods, dot - mods);
 
                                /* enqueue new module */
                                if (!current) {
-                                       first = current = xmalloc(sizeof(struct dep_t));
+                                       first = current = xzalloc(sizeof(struct dep_t));
                                } else {
-                                       current->m_next = xmalloc(sizeof(struct dep_t));
+                                       current->m_next = xzalloc(sizeof(struct dep_t));
                                        current = current->m_next;
                                }
-                               current->m_name    = mod;
-                               current->m_path    = xstrdup(modpath);
-                               current->m_options = NULL;
-                               current->m_isalias = 0;
-                               current->m_depcnt  = 0;
-                               current->m_deparr  = 0;
-                               current->m_next    = 0;
+                               current->m_name = mod;
+                               current->m_path = xstrdup(modpath);
+                               /*current->m_options = NULL; - xzalloc did it*/
+                               /*current->m_isalias = 0;*/
+                               /*current->m_depcnt = 0;*/
+                               /*current->m_deparr = 0;*/
+                               /*current->m_next = 0;*/
 
                                p = col + 1;
                        } else
                                /* this line is not a dep description */
-                               p = 0;
+                               p = NULL;
                } else
                        /* It's a dep description continuation */
-                       p = buffer;
-
-               while (p && *p && isblank(*p))
-                       p++;
+                       p = line_buffer;
 
                /* p points to the first dependable module; if NULL, no dependable module */
-               if (p && *p) {
-                       char *end = &buffer[l-1];
+               if (p && (p = skip_whitespace(p))[0] != '\0') {
+                       char *end = &line_buffer[l-1];
                        const char *deps;
                        char *dep;
                        char *next;
@@ -440,26 +458,23 @@ static struct dep_t *build_dep(void)
                                /* search the end of the dependency */
                                next = strchr(p, ' ');
                                if (next) {
-                                       *next = 0;
+                                       *next = '\0';
                                        next--;
                                } else
                                        next = end;
 
                                /* find the beginning of the module file name */
                                deps = bb_basename(p);
-                               if (deps == p) {
-                                       while (isblank(*deps))
-                                               deps++;
-                               }
+                               if (deps == p)
+                                       deps = skip_whitespace(deps);
 
                                /* find the end of the module name in the file name */
                                if (ENABLE_FEATURE_2_6_MODULES
-                                && (k_version > 4) && (*(next-2) == '.')
-                                && (*(next-1) == 'k') && (*next == 'o'))
+                                && (k_version > 4) && (next[-2] == '.')
+                                && (next[-1] == 'k') && (next[0] == 'o'))
                                        ext = 3;
-                               else
-                                       if ((*(next-1) == '.') && (*next == 'o'))
-                                               ext = 2;
+                               else if ((next[-1] == '.') && (next[0] == 'o'))
+                                       ext = 2;
 
                                /* Cope with blank lines */
                                if ((next-deps-ext+1) <= 0)
@@ -467,21 +482,16 @@ static struct dep_t *build_dep(void)
                                dep = xstrndup(deps, next - deps - ext + 1);
 
                                /* Add the new dependable module name */
-                               current->m_depcnt++;
-                               current->m_deparr = xrealloc(current->m_deparr,
-                                               sizeof(char *) * current->m_depcnt);
-                               current->m_deparr[current->m_depcnt - 1] = dep;
+                               current->m_deparr = xrealloc_vector(current->m_deparr, 2, current->m_depcnt);
+                               current->m_deparr[current->m_depcnt++] = dep;
 
                                p = next + 2;
                        } while (next < end);
                }
 
                /* is there other dependable module(s) ? */
-               if (buffer[l-1] == '\\')
-                       continuation_line = 1;
-               else
-                       continuation_line = 0;
-       }
+               continuation_line = (line_buffer[l-1] == '\\');
+       } /* while (reads(...)) */
        close(fd);
 
        /*
@@ -498,39 +508,39 @@ static struct dep_t *build_dep(void)
                                fd = open("/etc/conf.modules", O_RDONLY);
 
        if (fd >= 0) {
-               include_conf(&first, &current, buffer, sizeof(buffer), fd);
+               include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
                close(fd);
        }
 
        /* Only 2.6 has a modules.alias file */
        if (ENABLE_FEATURE_2_6_MODULES) {
                /* Parse kernel-declared module aliases */
-               filename = xasprintf("/lib/modules/%s/modules.alias", un.release);
+               filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.alias", un.release);
                fd = open(filename, O_RDONLY);
                if (fd < 0) {
                        /* Ok, that didn't work.  Fall back to looking in /lib/modules */
-                       fd = open("/lib/modules/modules.alias", O_RDONLY);
+                       fd = open(CONFIG_DEFAULT_MODULES_DIR"/modules.alias", O_RDONLY);
                }
                if (ENABLE_FEATURE_CLEAN_UP)
                        free(filename);
 
                if (fd >= 0) {
-                       include_conf(&first, &current, buffer, sizeof(buffer), fd);
+                       include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
                        close(fd);
                }
 
                /* Parse kernel-declared symbol aliases */
-               filename = xasprintf("/lib/modules/%s/modules.symbols", un.release);
+               filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.symbols", un.release);
                fd = open(filename, O_RDONLY);
                if (fd < 0) {
                        /* Ok, that didn't work.  Fall back to looking in /lib/modules */
-                       fd = open("/lib/modules/modules.symbols", O_RDONLY);
+                       fd = open(CONFIG_DEFAULT_MODULES_DIR"/modules.symbols", O_RDONLY);
                }
                if (ENABLE_FEATURE_CLEAN_UP)
                        free(filename);
 
                if (fd >= 0) {
-                       include_conf(&first, &current, buffer, sizeof(buffer), fd);
+                       include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
                        close(fd);
                }
        }
@@ -542,16 +552,15 @@ static struct dep_t *build_dep(void)
 static int already_loaded(const char *name)
 {
        int fd, ret = 0;
-       char buffer[4096];
 
        fd = open("/proc/modules", O_RDONLY);
        if (fd < 0)
                return -1;
 
-       while (reads(fd, buffer, sizeof(buffer))) {
+       while (reads(fd, line_buffer, sizeof(line_buffer))) {
                char *p;
 
-               p = strchr (buffer, ' ');
+               p = strchr(line_buffer, ' ');
                if (p) {
                        const char *n;
 
@@ -559,8 +568,8 @@ static int already_loaded(const char *name)
                        // the idiosyncrasy that _ and - are interchangeable because the
                        // 2.6 kernel does weird things.
 
-                       *p = 0;
-                       for (p = buffer, n = name; ; p++, n++) {
+                       *p = '\0';
+                       for (p = line_buffer, n = name; ; p++, n++) {
                                if (*p != *n) {
                                        if ((*p == '_' || *p == '-') && (*n == '_' || *n == '-'))
                                                continue;
@@ -574,8 +583,8 @@ static int already_loaded(const char *name)
                        }
                }
        }
-done:
-       close (fd);
+ done:
+       close(fd);
        return ret;
 }
 
@@ -623,7 +632,7 @@ static int mod_process(const struct mod_list_t *list, int do_insert)
                                while (opts) {
                                        /* Add one more option */
                                        argc++;
-                                       argv = xrealloc(argv,(argc + 1)* sizeof(char*));
+                                       argv = xrealloc(argv, (argc + 1) * sizeof(char*));
                                        argv[argc-1] = opts->m_opt_val;
                                        opts = opts->m_next;
                                }
@@ -698,9 +707,8 @@ static int check_pattern(const char* pat_src, const char* mod_src)
                }
 
                return ret;
-       } else {
-               return fnmatch(pat_src, mod_src, 0);
        }
+       return fnmatch(pat_src, mod_src, 0);
 }
 
 /*
@@ -712,8 +720,8 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
 {
        struct mod_list_t *find;
        struct dep_t *dt;
-       struct mod_opt_t *opt = 0;
-       char *path = 0;
+       struct mod_opt_t *opt = NULL;
+       char *path = NULL;
 
        /* Search for the given module name amongst all dependency rules.
         * The module name in a dependency rule can be a shell pattern,
@@ -737,7 +745,9 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
                        struct dep_t *adt;
 
                        for (adt = depend; adt; adt = adt->m_next) {
-                               if (check_pattern(adt->m_name, dt->m_deparr[0]) == 0)
+                               if (check_pattern(adt->m_name, dt->m_deparr[0]) == 0 &&
+                                               !(ENABLE_FEATURE_MODPROBE_BLACKLIST &&
+                                                       adt->m_isblacklisted))
                                        break;
                        }
                        if (adt) {
@@ -765,8 +775,8 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
 
        // search for duplicates
        for (find = *head; find; find = find->m_next) {
-               if (!strcmp(mod, find->m_name)) {
-                       // found ->dequeue it
+               if (strcmp(mod, find->m_name) == 0) {
+                       // found -> dequeue it
 
                        if (find->m_prev)
                                find->m_prev->m_next = find->m_next;
@@ -783,7 +793,7 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
        }
 
        if (!find) { // did not find a duplicate
-               find = xmalloc(sizeof(struct mod_list_t));
+               find = xzalloc(sizeof(struct mod_list_t));
                find->m_name = mod;
                find->m_path = path;
                find->m_options = opt;
@@ -793,7 +803,7 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
        if (*tail)
                (*tail)->m_next = find;
        find->m_prev = *tail;
-       find->m_next = 0;
+       find->m_next = NULL; /* possibly NOT done by xzalloc! */
 
        if (!*head)
                *head = find;
@@ -867,24 +877,24 @@ int modprobe_main(int argc, char **argv)
        int rc = EXIT_SUCCESS;
        char *unused;
 
-       opt_complementary = "?V-:q-v:v-q";
-       main_opts = getopt32(argv, "acdklnqrst:vVC:",
-                                                       &unused, &unused);
-       if (main_opts & (DUMP_CONF_EXIT | LIST_ALL))
+       opt_complementary = "q-v:v-q";
+       getopt32(argv, MAIN_OPT_STR, &unused, &unused);
+
+       if (option_mask32 & (DUMP_CONF_EXIT | LIST_ALL))
                return EXIT_SUCCESS;
-       if (main_opts & (RESTRICT_DIR | CONFIG_FILE))
+       if (option_mask32 & (RESTRICT_DIR | CONFIG_FILE))
                bb_error_msg_and_die("-t and -C not supported");
 
        depend = build_dep();
 
        if (!depend)
-               bb_error_msg_and_die("cannot parse modules.dep");
+               bb_error_msg_and_die("cannot parse "CONFIG_DEFAULT_DEPMOD_FILE);
 
        if (remove_opt) {
                do {
-                       if (mod_remove(optind < argc ?
-                                               argv[optind] : NULL)) {
-                               bb_error_msg("failed to remove module %s",
+                       /* argv[optind] can be NULL here */
+                       if (mod_remove(argv[optind])) {
+                               bb_error_msg("failed to %s module %s", "remove",
                                                argv[optind]);
                                rc = EXIT_FAILURE;
                        }
@@ -894,7 +904,7 @@ int modprobe_main(int argc, char **argv)
                        bb_error_msg_and_die("no module or pattern provided");
 
                if (mod_insert(argv[optind], argc - optind - 1, argv + optind + 1))
-                       bb_error_msg_and_die("failed to load module %s", argv[optind]);
+                       bb_error_msg_and_die("failed to %s module %s", "load", argv[optind]);
        }
 
        /* Here would be a good place to free up memory allocated during the dependencies build. */