/* vi: set sw=4 ts=4: */
/*
 * Modprobe written from scratch for BusyBox
 *
 * Copyright (c) 2008 Timo Teras <timo.teras@iki.fi>
 * Copyright (c) 2008 Vladimir Dronnikov
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#include "libbb.h"
#include "modutils.h"
#include <sys/utsname.h>
#include <fnmatch.h>

struct modprobe_option {
	char *module;
	char *option;
};

struct modprobe_conf {
	char probename[MODULE_NAME_LEN];
	llist_t *options;
	llist_t *aliases;
#if ENABLE_FEATURE_MODPROBE_BLACKLIST
#define add_to_blacklist(conf, name) llist_add_to(&conf->blacklist, name)
#define check_blacklist(conf, name) (llist_find(conf->blacklist, name) == NULL)
	llist_t *blacklist;
#else
#define add_to_blacklist(conf, name) do {} while (0)
#define check_blacklist(conf, name) (1)
#endif
};

#define MODPROBE_OPTS	"acdlnrt:VC:" USE_FEATURE_MODPROBE_BLACKLIST("b")
enum {
	MODPROBE_OPT_INSERT_ALL	= (INSMOD_OPT_UNUSED << 0), /* a */
	MODPROBE_OPT_DUMP_ONLY	= (INSMOD_OPT_UNUSED << 1), /* c */
	MODPROBE_OPT_D		= (INSMOD_OPT_UNUSED << 2), /* d */
	MODPROBE_OPT_LIST_ONLY	= (INSMOD_OPT_UNUSED << 3), /* l */
	MODPROBE_OPT_SHOW_ONLY	= (INSMOD_OPT_UNUSED << 4), /* n */
	MODPROBE_OPT_REMOVE	= (INSMOD_OPT_UNUSED << 5), /* r */
	MODPROBE_OPT_RESTRICT	= (INSMOD_OPT_UNUSED << 6), /* t */
	MODPROBE_OPT_VERONLY	= (INSMOD_OPT_UNUSED << 7), /* V */
	MODPROBE_OPT_CONFIGFILE	= (INSMOD_OPT_UNUSED << 8), /* C */
	MODPROBE_OPT_BLACKLIST	= (INSMOD_OPT_UNUSED << 9) * ENABLE_FEATURE_MODPROBE_BLACKLIST,
};

static llist_t *loaded;

static int read_config(struct modprobe_conf *conf, const char *path);

static void add_option(llist_t **all_opts, const char *module, const char *opts)
{
	struct modprobe_option *o;

	o = xzalloc(sizeof(struct modprobe_option));
	if (module)
		o->module = filename2modname(module, NULL);
	o->option = xstrdup(opts);
	llist_add_to(all_opts, o);
}

static int FAST_FUNC config_file_action(const char *filename,
					struct stat *statbuf UNUSED_PARAM,
					void *userdata,
					int depth UNUSED_PARAM)
{
	struct modprobe_conf *conf = (struct modprobe_conf *) userdata;
	RESERVE_CONFIG_BUFFER(modname, MODULE_NAME_LEN);
	char *tokens[3];
	parser_t *p;
	int rc = TRUE;

	if (bb_basename(filename)[0] == '.')
		goto error;

	p = config_open2(filename, fopen_for_read);
	if (p == NULL) {
		rc = FALSE;
		goto error;
	}

	while (config_read(p, tokens, 3, 2, "# \t", PARSE_NORMAL)) {
		if (strcmp(tokens[0], "alias") == 0) {
			filename2modname(tokens[1], modname);
			if (tokens[2] &&
			    fnmatch(modname, conf->probename, 0) == 0)
				llist_add_to(&conf->aliases,
					filename2modname(tokens[2], NULL));
		} else if (strcmp(tokens[0], "options") == 0) {
			if (tokens[2])
				add_option(&conf->options, tokens[1], tokens[2]);
		} else if (strcmp(tokens[0], "include") == 0) {
			read_config(conf, tokens[1]);
		} else if (ENABLE_FEATURE_MODPROBE_BLACKLIST &&
			   strcmp(tokens[0], "blacklist") == 0) {
			add_to_blacklist(conf, xstrdup(tokens[1]));
		}
	}
	config_close(p);
error:
	if (ENABLE_FEATURE_CLEAN_UP)
		RELEASE_CONFIG_BUFFER(modname);
	return rc;
}

static int read_config(struct modprobe_conf *conf, const char *path)
{
	return recursive_action(path, ACTION_RECURSE | ACTION_QUIET,
				config_file_action, NULL, conf, 1);
}

static char *gather_options(llist_t *first, const char *module, int usecmdline)
{
	struct modprobe_option *opt;
	llist_t *n;
	char *opts = xstrdup("");
	int optlen = 0;

	for (n = first; n != NULL; n = n->link) {
		opt = (struct modprobe_option *) n->data;

		if (opt->module == NULL && !usecmdline)
			continue;
		if (opt->module != NULL && strcmp(opt->module, module) != 0)
			continue;

		opts = xrealloc(opts, optlen + strlen(opt->option) + 2);
		optlen += sprintf(opts + optlen, "%s ", opt->option);
	}
	return opts;
}

static int do_modprobe(struct modprobe_conf *conf, const char *module)
{
	RESERVE_CONFIG_BUFFER(modname, MODULE_NAME_LEN);
	llist_t *deps = NULL;
	char *fn, *options, *colon = NULL, *tokens[2];
	parser_t *p;
	int rc = -1;

	p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, fopen_for_read);
	if (p == NULL)
		goto error;

	while (config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL)) {
		colon = last_char_is(tokens[0], ':');
		if (colon == NULL)
			continue;

		filename2modname(tokens[0], modname);
		if (strcmp(modname, module) == 0)
			break;

		colon = NULL;
	}
	if (colon == NULL)
		goto error_not_found;

	colon[0] = '\0';
	llist_add_to(&deps, xstrdup(tokens[0]));
	if (tokens[1])
		string_to_llist(tokens[1], &deps, " ");

	if (!(option_mask32 & MODPROBE_OPT_REMOVE))
		deps = llist_rev(deps);

	rc = 0;
	while (deps && rc == 0) {
		fn = llist_pop(&deps);
		filename2modname(fn, modname);
		if (option_mask32 & MODPROBE_OPT_REMOVE) {
			if (bb_delete_module(modname, O_EXCL) != 0)
				rc = errno;
		} else if (llist_find(loaded, modname) == NULL) {
			options = gather_options(conf->options, modname,
						 strcmp(modname, module) == 0);
			rc = bb_init_module(fn, options);
			if (rc == 0)
				llist_add_to(&loaded, xstrdup(modname));
			if (ENABLE_FEATURE_CLEAN_UP)
				free(options);
		}

		if (ENABLE_FEATURE_CLEAN_UP)
			free(fn);
	}

error_not_found:
	config_close(p);
error:
	if (ENABLE_FEATURE_CLEAN_UP)
		RELEASE_CONFIG_BUFFER(modname);
	if (rc > 0 && !(option_mask32 & INSMOD_OPT_SILENT))
		bb_error_msg("Failed to %sload module %s: %s.",
			     (option_mask32 & MODPROBE_OPT_REMOVE) ? "un" : "",
			     module, moderror(rc));
	return rc;
}

int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int modprobe_main(int argc UNUSED_PARAM, char **argv)
{
	struct utsname uts;
	int num_modules, i, rc;
	llist_t *options = NULL;
	parser_t *parser;

	opt_complementary = "q-v:v-q";
	getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS,
		 NULL, NULL);
	argv += optind;
	argc -= optind;

	if (option_mask32 & (MODPROBE_OPT_DUMP_ONLY | MODPROBE_OPT_LIST_ONLY |
			     MODPROBE_OPT_SHOW_ONLY))
		bb_error_msg_and_die("not supported");

	/* goto modules location */
	xchdir(CONFIG_DEFAULT_MODULES_DIR);
	uname(&uts);
	xchdir(uts.release);

	if (option_mask32 & (MODPROBE_OPT_REMOVE | MODPROBE_OPT_INSERT_ALL)) {
		/* each parameter is a module name */
		num_modules = argc;
		if (num_modules == 0) {
			if (bb_delete_module(NULL, O_NONBLOCK|O_EXCL) != 0)
				bb_perror_msg_and_die("rmmod");
			return EXIT_SUCCESS;
		}
	} else {
		/* the only module, the rest of parameters are options */
		num_modules = 1;
		add_option(&options, NULL, parse_cmdline_module_options(argv));
	}

	/* cache modules */
	parser = config_open2("/proc/modules", fopen_for_read);
	if (parser) {
		char *s;
		while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY))
			llist_add_to(&loaded, xstrdup(s));
		config_close(parser);
	}

	for (i = 0; i < num_modules; i++) {
		struct modprobe_conf *conf;

		conf = xzalloc(sizeof(struct modprobe_conf));
		conf->options = options;
		filename2modname(argv[i], conf->probename);
		read_config(conf, "/etc/modprobe.conf");
		read_config(conf, "/etc/modprobe.d");
		if (ENABLE_FEATURE_MODUTILS_SYMBOLS &&
		    conf->aliases == NULL && strncmp(argv[i], "symbol:", 7) == 0)
			read_config(conf, "modules.symbols");

		if (ENABLE_FEATURE_MODUTILS_ALIAS && conf->aliases == NULL)
			read_config(conf, "modules.alias");

		if (conf->aliases == NULL) {
			/* Try if module by literal name is found; literal
			 * names are blacklist only if '-b' is given. */
			if (!(option_mask32 & MODPROBE_OPT_BLACKLIST) ||
			    check_blacklist(conf, conf->probename)) {
				rc = do_modprobe(conf, conf->probename);
				if (rc < 0 && !(option_mask32 & INSMOD_OPT_SILENT))
					bb_error_msg("Module %s not found.", argv[i]);
			}
		} else {
			/* Probe all aliases */
			while (conf->aliases != NULL) {
				char *realname = llist_pop(&conf->aliases);
				if (check_blacklist(conf, realname))
					do_modprobe(conf, realname);
				if (ENABLE_FEATURE_CLEAN_UP)
					free(realname);
			}
		}
	}

	return EXIT_SUCCESS;
}
