/* vi: set sw=4 ts=4: */
/*
 * simplified modprobe
 *
 * Copyright (c) 2008 Vladimir Dronnikov
 * Copyright (c) 2008 Bernhard Reutner-Fischer (initial depmod code)
 *
 * Licensed under GPLv2, see file LICENSE in this tarball for details.
 */

#include "libbb.h"

#include <sys/utsname.h> /* uname() */
#include <fnmatch.h>

extern int init_module(void *module, unsigned long len, const char *options);
extern int delete_module(const char *module, unsigned flags);
extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);


#define dbg1_error_msg(...) ((void)0)
#define dbg2_error_msg(...) ((void)0)
//#define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__)
//#define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__)

#define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb"

enum {
	OPT_q = (1 << 0), /* be quiet */
	OPT_r = (1 << 1), /* module removal instead of loading */
};

typedef struct module_info {
	char *pathname;
	char *aliases;
	char *deps;
} module_info;

/*
 * GLOBALS
 */
struct globals {
	module_info *modinfo;
	char *module_load_options;
	smallint dep_bb_seen;
	smallint wrote_dep_bb_ok;
	int module_count;
	int module_found_idx;
	int stringbuf_idx;
	char stringbuf[32 * 1024]; /* some modules have lots of stuff */
	/* for example, drivers/media/video/saa7134/saa7134.ko */
};
#define G (*ptr_to_globals)
#define modinfo             (G.modinfo            )
#define dep_bb_seen         (G.dep_bb_seen        )
#define wrote_dep_bb_ok     (G.wrote_dep_bb_ok    )
#define module_count        (G.module_count       )
#define module_found_idx    (G.module_found_idx   )
#define module_load_options (G.module_load_options)
#define stringbuf_idx       (G.stringbuf_idx      )
#define stringbuf           (G.stringbuf          )
#define INIT_G() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
} while (0)


static void appendc(char c)
{
	if (stringbuf_idx < sizeof(stringbuf))
		stringbuf[stringbuf_idx++] = c;
}

static void bksp(void)
{
	if (stringbuf_idx)
		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;
}

static char* copy_stringbuf(void)
{
	char *copy = xmalloc(stringbuf_idx);
	return memcpy(copy, stringbuf, stringbuf_idx);
}

static char* find_keyword(char *ptr, size_t len, const char *word)
{
	int wlen;

	if (!ptr) /* happens if xmalloc_open_zipped_read_close cannot read it */
		return NULL;

	wlen = strlen(word);
	len -= wlen - 1;
	while ((ssize_t)len > 0) {
		char *old = ptr;
		/* search for the first char in word */
		ptr = memchr(ptr, *word, len);
		if (ptr == NULL) /* no occurance left, done */
			break;
		if (strncmp(ptr, word, wlen) == 0)
			return ptr + wlen; /* found, return ptr past it */
		++ptr;
		len -= (ptr - old);
	}
	return NULL;
}

static void replace(char *s, char what, char with)
{
	while (*s) {
		if (what == *s)
			*s = with;
		++s;
	}
}

/* Take "word word", return malloced "word",NUL,"word",NUL,NUL */
static char* str_2_list(const char *str)
{
	int len = strlen(str) + 1;
	char *dst = xmalloc(len + 1);

	dst[len] = '\0';
	memcpy(dst, str, len);
//TODO: protect against 2+ spaces: "word  word"
	replace(dst, ' ', '\0');
	return dst;
}

/* We use error numbers in a loose translation... */
static const char *moderror(int err)
{
	switch (err) {
	case ENOEXEC:
		return "invalid module format";
	case ENOENT:
		return "unknown symbol in module or invalid parameter";
	case ESRCH:
		return "module has wrong symbol version";
	case EINVAL: /* "invalid parameter" */
		return "unknown symbol in module or invalid parameter"
		+ sizeof("unknown symbol in module or");
	default:
		return strerror(err);
	}
}

static int load_module(const char *fname, const char *options)
{
#if 1
	int r;
	size_t len = MAXINT(ssize_t);
	char *module_image;
	dbg1_error_msg("load_module('%s','%s')", fname, options);

	module_image = xmalloc_open_zipped_read_close(fname, &len);
	r = (!module_image || init_module(module_image, len, options ? options : "") != 0);
	free(module_image);
	dbg1_error_msg("load_module:%d", r);
	return r; /* 0 = success */
#else
	/* For testing */
	dbg1_error_msg("load_module('%s','%s')", fname, options);
	return 1;
#endif
}

static void parse_module(module_info *info, const char *pathname)
{
	char *module_image;
	char *ptr;
	size_t len;
	size_t pos;
	dbg1_error_msg("parse_module('%s')", pathname);

	/* Read (possibly compressed) module */
	len = 64 * 1024 * 1024; /* 64 Mb at most */
	module_image = xmalloc_open_zipped_read_close(pathname, &len);
//TODO: optimize redundant module body reads

	/* "alias1 symbol:sym1 alias2 symbol:sym2" */
	reset_stringbuf();
	pos = 0;
	while (1) {
		ptr = find_keyword(module_image + pos, len - pos, "alias=");
		if (!ptr) {
			ptr = find_keyword(module_image + pos, len - pos, "__ksymtab_");
			if (!ptr)
				break;
			/* DOCME: __ksymtab_gpl and __ksymtab_strings occur
			 * in many modules. What do they mean? */
			if (strcmp(ptr, "gpl") == 0 || strcmp(ptr, "strings") == 0)
				goto skip;
			dbg2_error_msg("alias:'symbol:%s'", ptr);
			append("symbol:");
		} else {
			dbg2_error_msg("alias:'%s'", ptr);
		}
		append(ptr);
		appendc(' ');
 skip:
		pos = (ptr - module_image);
	}
	bksp(); /* remove last ' ' */
	appendc('\0');
	info->aliases = copy_stringbuf();

	/* "dependency1 depandency2" */
	reset_stringbuf();
	ptr = find_keyword(module_image, len, "depends=");
	if (ptr && *ptr) {
		replace(ptr, ',', ' ');
		replace(ptr, '-', '_');
		dbg2_error_msg("dep:'%s'", ptr);
		append(ptr);
	}
	appendc('\0');
	info->deps = copy_stringbuf();

	free(module_image);
}

static int pathname_matches_modname(const char *pathname, const char *modname)
{
	const char *fname = bb_get_last_path_component_nostrip(pathname);
	const char *suffix = strrstr(fname, ".ko");
//TODO: can do without malloc?
	char *name = xstrndup(fname, suffix - fname);
	int r;
	replace(name, '-', '_');
	r = (strcmp(name, modname) == 0);
	free(name);
	return r;
}

static FAST_FUNC int fileAction(const char *pathname,
		struct stat *sb UNUSED_PARAM,
		void *modname_to_match,
		int depth UNUSED_PARAM)
{
	int cur;
	const char *fname;

	pathname += 2; /* skip "./" */
	fname = bb_get_last_path_component_nostrip(pathname);
	if (!strrstr(fname, ".ko")) {
		dbg1_error_msg("'%s' is not a module", pathname);
		return TRUE; /* not a module, continue search */
	}

	cur = module_count++;
	modinfo = xrealloc_vector(modinfo, 12, cur);
	modinfo[cur].pathname = xstrdup(pathname);
	/*modinfo[cur].aliases = NULL; - xrealloc_vector did it */
	/*modinfo[cur+1].pathname = NULL;*/

	if (!pathname_matches_modname(fname, modname_to_match)) {
		dbg1_error_msg("'%s' module name doesn't match", pathname);
		return TRUE; /* module name doesn't match, continue search */
	}

	dbg1_error_msg("'%s' module name matches", pathname);
	module_found_idx = cur;
	parse_module(&modinfo[cur], pathname);

	if (!(option_mask32 & OPT_r)) {
		if (load_module(pathname, module_load_options) == 0) {
			/* Load was successful, there is nothing else to do.
			 * This can happen ONLY for "top-level" module load,
			 * not a dep, because deps dont do dirscan. */
			exit(EXIT_SUCCESS);
		}
	}

	return TRUE;
}

static int load_dep_bb(void)
{
	char *line;
	FILE *fp = fopen_for_read(DEPFILE_BB);

	if (!fp)
		return 0;

	dep_bb_seen = 1;
	dbg1_error_msg("loading "DEPFILE_BB);

	/* Why? There is a rare scenario: we did not find modprobe.dep.bb,
	 * we scanned the dir and found no module by name, then we search
	 * for alias (full scan), and we decided to generate modprobe.dep.bb.
	 * But we see modprobe.dep.bb.new! Other modprobe is at work!
	 * We wait and other modprobe renames it to modprobe.dep.bb.
	 * Now we can use it.
	 * But we already have modinfo[] filled, and "module_count = 0"
	 * makes us start anew. Yes, we leak modinfo[].xxx pointers -
	 * there is not much of data there anyway. */
	module_count = 0;
	memset(&modinfo[0], 0, sizeof(modinfo[0]));

	while ((line = xmalloc_fgetline(fp)) != NULL) {
		char* space;
		int cur;

		if (!line[0]) {
			free(line);
			continue;
		}
		space = strchrnul(line, ' ');
		cur = module_count++;
		modinfo = xrealloc_vector(modinfo, 12, cur);
		/*modinfo[cur+1].pathname = NULL; - xrealloc_vector did it */
		modinfo[cur].pathname = line; /* we take ownership of malloced block here */
		if (*space)
			*space++ = '\0';
		modinfo[cur].aliases = space;
		modinfo[cur].deps = xmalloc_fgetline(fp) ? : xzalloc(1);
		if (modinfo[cur].deps[0]) {
			/* deps are not "", so next line must be empty */
			line = xmalloc_fgetline(fp);
			/* Refuse to work with damaged config file */
			if (line && line[0])
				bb_error_msg_and_die("error in %s at '%s'", DEPFILE_BB, line);
			free(line);
		}
	}
	return 1;
}

static int start_dep_bb_writeout(void)
{
	int fd;

	/* depmod -n: write result to stdout */
	if (applet_name[0] == 'd' && (option_mask32 & 1))
		return STDOUT_FILENO;

	fd = open(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644);
	if (fd < 0) {
		if (errno == EEXIST) {
			int count = 5 * 20;
			dbg1_error_msg(DEPFILE_BB".new exists, waiting for "DEPFILE_BB);
			while (1) {
				usleep(1000*1000 / 20);
				if (load_dep_bb()) {
					dbg1_error_msg(DEPFILE_BB" appeared");
					return -2; /* magic number */
				}
				if (!--count)
					break;
			}
			bb_error_msg("deleting stale %s", DEPFILE_BB".new");
			fd = open_or_warn(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC);
		}
	}
	dbg1_error_msg("opened "DEPFILE_BB".new:%d", fd);
	return fd;
}

static void write_out_dep_bb(int fd)
{
	int i;
	FILE *fp;

	/* We want good error reporting. fdprintf is not good enough. */
	fp = fdopen(fd, "w");
	if (!fp) {
		close(fd);
		goto err;
	}
	i = 0;
	while (modinfo[i].pathname) {
		fprintf(fp, "%s%s%s\n" "%s%s\n",
			modinfo[i].pathname, modinfo[i].aliases[0] ? " " : "", modinfo[i].aliases,
			modinfo[i].deps, modinfo[i].deps[0] ? "\n" : "");
		i++;
	}
	/* Badly formatted depfile is a no-no. Be paranoid. */
	errno = 0;
	if (ferror(fp) | fclose(fp)) /* | instead of || is intended */
		goto err;

	if (fd == STDOUT_FILENO) /* it was depmod -n */
		goto ok;

	if (rename(DEPFILE_BB".new", DEPFILE_BB) != 0) {
 err:
		bb_perror_msg("can't create %s", DEPFILE_BB);
		unlink(DEPFILE_BB".new");
	} else {
 ok:
		wrote_dep_bb_ok = 1;
		dbg1_error_msg("created "DEPFILE_BB);
	}
}

static module_info* find_alias(const char *alias)
{
	int i;
	int dep_bb_fd;
	module_info *result;
	dbg1_error_msg("find_alias('%s')", alias);

 try_again:
	/* First try to find by name (cheaper) */
	i = 0;
	while (modinfo[i].pathname) {
		if (pathname_matches_modname(modinfo[i].pathname, alias)) {
			dbg1_error_msg("found '%s' in module '%s'",
					alias, modinfo[i].pathname);
			if (!modinfo[i].aliases) {
				parse_module(&modinfo[i], modinfo[i].pathname);
			}
			return &modinfo[i];
		}
		i++;
	}

	/* Ok, we definitely have to scan module bodies. This is a good
	 * moment to generate modprobe.dep.bb, if it does not exist yet */
	dep_bb_fd = dep_bb_seen ? -1 : start_dep_bb_writeout();
	if (dep_bb_fd == -2) /* modprobe.dep.bb appeared? */
		goto try_again;

	/* Scan all module bodies, extract modinfo (it contains aliases) */
	i = 0;
	result = NULL;
	while (modinfo[i].pathname) {
		char *desc, *s;
		if (!modinfo[i].aliases) {
			parse_module(&modinfo[i], modinfo[i].pathname);
		}
		if (result) {
			i++;
			continue;
		}
		/* "alias1 symbol:sym1 alias2 symbol:sym2" */
		desc = str_2_list(modinfo[i].aliases);
		/* Does matching substring exist? */
		for (s = desc; *s; s += strlen(s) + 1) {
			/* Aliases in module bodies can be defined with
			 * shell patterns. Example:
			 * "pci:v000010DEd000000D9sv*sd*bc*sc*i*".
			 * Plain strcmp() won't catch that */
			if (fnmatch(s, alias, 0) == 0) {
				dbg1_error_msg("found alias '%s' in module '%s'",
						alias, modinfo[i].pathname);
				result = &modinfo[i];
				break;
			}
		}
		free(desc);
		if (result && dep_bb_fd < 0)
			return result;
		i++;
	}

	/* Create module.dep.bb if needed */
	if (dep_bb_fd >= 0) {
		write_out_dep_bb(dep_bb_fd);
	}

	dbg1_error_msg("find_alias '%s' returns %p", alias, result);
	return result;
}

#if ENABLE_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED
// TODO: open only once, invent config_rewind()
static int already_loaded(const char *name)
{
	int ret = 0;
	char *s;
	parser_t *parser = config_open2("/proc/modules", xfopen_for_read);
	while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) {
		if (strcmp(s, name) == 0) {
			ret = 1;
			break;
		}
	}
	config_close(parser);
	return ret;
}
#else
#define already_loaded(name) is_rmmod
#endif

/*
 * Given modules definition and module name (or alias, or symbol)
 * load/remove the module respecting dependencies.
 * NB: also called by depmod with bogus name "/",
 * just in order to force modprobe.dep.bb creation.
*/
#if !ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE
#define process_module(a,b) process_module(a)
#define cmdline_options ""
#endif
static void process_module(char *name, const char *cmdline_options)
{
	char *s, *deps, *options;
	module_info *info;
	int is_rmmod = (option_mask32 & OPT_r) != 0;
	dbg1_error_msg("process_module('%s','%s')", name, cmdline_options);

	replace(name, '-', '_');

	dbg1_error_msg("already_loaded:%d is_rmmod:%d", already_loaded(name), is_rmmod);
	if (already_loaded(name) != is_rmmod) {
		dbg1_error_msg("nothing to do for '%s'", name);
		return;
	}

	options = NULL;
	if (!is_rmmod) {
		char *opt_filename = xasprintf("/etc/modules/%s", name);
		options = xmalloc_open_read_close(opt_filename, NULL);
		if (options)
			replace(options, '\n', ' ');
#if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE
		if (cmdline_options) {
			/* NB: cmdline_options always have one leading ' '
			 * (see main()), we remove it here */
			char *op = xasprintf(options ? "%s %s" : "%s %s" + 3,
						cmdline_options + 1, options);
			free(options);
			options = op;
		}
#endif
		free(opt_filename);
		module_load_options = options;
		dbg1_error_msg("process_module('%s'): options:'%s'", name, options);
	}

	if (!module_count) {
		/* Scan module directory. This is done only once.
		 * It will attempt module load, and will exit(EXIT_SUCCESS)
		 * on success. */
		module_found_idx = -1;
		recursive_action(".",
			ACTION_RECURSE, /* flags */
			fileAction, /* file action */
			NULL, /* dir action */
			name, /* user data */
			0); /* depth */
		dbg1_error_msg("dirscan complete");
		/* Module was not found, or load failed, or is_rmmod */
		if (module_found_idx >= 0) { /* module was found */
			info = &modinfo[module_found_idx];
		} else { /* search for alias, not a plain module name */
			info = find_alias(name);
		}
	} else {
		info = find_alias(name);
	}

	/* rmmod? unload it by name */
	if (is_rmmod) {
		if (delete_module(name, O_NONBLOCK | O_EXCL) != 0
		 && !(option_mask32 & OPT_q)
		) {
			bb_perror_msg("remove '%s'", name);
			goto ret;
		}
		/* N.B. we do not stop here -
		 * continue to unload modules on which the module depends:
		 * "-r --remove: option causes modprobe to remove a module.
		 * If the modules it depends on are also unused, modprobe
		 * will try to remove them, too." */
	}

	if (!info) {
		/* both dirscan and find_alias found nothing */
		if (applet_name[0] != 'd') /* it wasn't depmod */
			bb_error_msg("module '%s' not found", name);
//TODO: _and_die()?
		goto ret;
	}

	/* Iterate thru dependencies, trying to (un)load them */
	deps = str_2_list(info->deps);
	for (s = deps; *s; s += strlen(s) + 1) {
		//if (strcmp(name, s) != 0) // N.B. do loops exist?
		dbg1_error_msg("recurse on dep '%s'", s);
		process_module(s, NULL);
		dbg1_error_msg("recurse on dep '%s' done", s);
	}
	free(deps);

	/* modprobe -> load it */
	if (!is_rmmod && (options && !strstr(options, "blacklist"))) {
		errno = 0;
		if (load_module(info->pathname, options) != 0) {
			if (EEXIST != errno) {
				bb_error_msg("'%s': %s",
						info->pathname,
						moderror(errno));
			} else {
				dbg1_error_msg("'%s': %s",
						info->pathname,
						moderror(errno));
			}
		}
	}
 ret:
	free(options);
//TODO: return load attempt result from process_module.
//If dep didn't load ok, continuing makes little sense.
}
#undef cmdline_options


/* For reference, module-init-tools v3.4 options:

# insmod
Usage: insmod filename [args]

# rmmod --help
Usage: rmmod [-fhswvV] modulename ...
 -f (or --force) forces a module unload, and may crash your
    machine. This requires the Forced Module Removal option
    when the kernel was compiled.
 -h (or --help) prints this help text
 -s (or --syslog) says use syslog, not stderr
 -v (or --verbose) enables more messages
 -V (or --version) prints the version code
 -w (or --wait) begins module removal even if it is used
    and will stop new users from accessing the module (so it
    should eventually fall to zero).

# modprobe
Usage: modprobe [-v] [-V] [-C config-file] [-n] [-i] [-q] [-b]
    [-o <modname>] [ --dump-modversions ] <modname> [parameters...]
modprobe -r [-n] [-i] [-v] <modulename> ...
modprobe -l -t <dirname> [ -a <modulename> ...]

# depmod --help
depmod 3.4 -- part of module-init-tools
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.
Options:
    -a, --all           Probe all modules
    -A, --quick         Only does the work if there's a new module
    -n, --show          Write the dependency file on stdout only
    -e, --errsyms       Report not supplied symbols
    -V, --version       Print the release version
    -v, --verbose       Enable verbose mode
    -h, --help          Print this usage message
The following options are useful for people managing distributions:
    -b basedirectory
    --basedir basedirectory
                        Use an image of a module tree
    -F kernelsyms
    --filesyms kernelsyms
                        Use the file instead of the current kernel symbols
*/

int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
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;)

	/* are we lsmod? -> just dump /proc/modules */
	if ('l' == applet0) {
		xprint_and_close_file(xfopen_for_read("/proc/modules"));
		return EXIT_SUCCESS;
	}

	INIT_G();

	/* Prevent ugly corner cases with no modules at all */
	modinfo = xzalloc(sizeof(modinfo[0]));

	if ('i' != applet0) { /* not insmod */
		/* Goto modules directory */
		xchdir(CONFIG_DEFAULT_MODULES_DIR);
	}
	uname(&uts); /* never fails */

	/* depmod? */
	if ('d' == applet0) {
		/* Supported:
		 * -n: print result to stdout
		 * -a: process all modules (default)
		 * optional VERSION parameter
		 * Ignored:
		 * -A: do work only if a module is newer than depfile
		 * -e: report any symbols which a module needs
		 *  which are not supplied by other modules or the kernel
		 * -F FILE: System.map (symbols for -e)
		 * -q, -r, -u: noop?
		 * Not supported:
		 * -b BASEDIR: (TODO!) modules are in
		 *  $BASEDIR/lib/modules/$VERSION
		 * -v: human readable deps to stdout
		 * -V: version (don't want to support it - people may depend
		 *  on it as an indicator of "standard" depmod)
		 * -h: help (well duh)
		 * module1.o module2.o parameters (just ignored for now)
		 */
		getopt32(argv, "na" "AeF:qru" /* "b:vV", NULL */, NULL);
		argv += optind;
		/* if (argv[0] && argv[1]) bb_show_usage(); */
		/* Goto $VERSION directory */
		xchdir(argv[0] ? argv[0] : uts.release);
		/* Force full module scan by asking to find a bogus module.
		 * This will generate modules.dep.bb as a side effect. */
		process_module((char*)"/", NULL);
		return !wrote_dep_bb_ok;
	}

	/* insmod, modprobe, rmmod require at least one argument */
	opt_complementary = "-1";
	/* only -q (quiet) and -r (rmmod),
	 * the rest are accepted and ignored (compat) */
	getopt32(argv, "qrfsvw");
	argv += optind;

	/* are we rmmod? -> simulate modprobe -r */
	if ('r' == applet0) {
		option_mask32 |= OPT_r;
	}

	if ('i' != applet0) { /* not insmod */
		/* Goto $VERSION directory */
		xchdir(uts.release);
	}

#if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE
	/* If not rmmod, parse possible module options given on command line.
	 * insmod/modprobe takes one module name, the rest are parameters. */
	options = NULL;
	if ('r' != applet0) {
		char **arg = argv;
		while (*++arg) {
			/* Enclose options in quotes */
			char *s = options;
			options = xasprintf("%s \"%s\"", s ? s : "", *arg);
			free(s);
			*arg = NULL;
		}
	}
#else
	if ('r' != applet0)
		argv[1] = NULL;
#endif

	if ('i' == applet0) { /* insmod */
		size_t len;
		void *map;

		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("")
				) != 0)
			bb_error_msg_and_die("cannot insert '%s': %s",
					*argv, moderror(errno));
		return 0;
	}

	/* Try to load modprobe.dep.bb */
	load_dep_bb();

	/* Load/remove modules.
	 * Only rmmod loops here, modprobe has only argv[0] */
	do {
		process_module(*argv++, options);
	} while (*argv);

	if (ENABLE_FEATURE_CLEAN_UP) {
		USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);)
	}
	return EXIT_SUCCESS;
}
