/* vi: set sw=4 ts=4: */
/*
 * Modprobe written from scratch for BusyBox
 *
 * Copyright (c) 2002 by Robert Griebl, griebl@gmx.de
 * Copyright (c) 2003 by Andrew Dennison, andrew.dennison@motec.com.au
 * Copyright (c) 2005 by Jim Bauer, jfbauer@nfr.com
 *
 * Portions Copyright (c) 2005 by Yann E. MORIN, yann.morin.1998@anciens.enib.fr
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/

#include "libbb.h"
#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;
};

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 */

	int     m_isalias  : 1;                 /* the module is an alias */
	int     m_reserved : 15;                /* stuffin' */

	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 mod_list_t {	/* two-way list of modules to process */
	/* a module description */
	const char * m_name;
	char * m_path;
	struct mod_opt_t * m_options;

	struct mod_list_t * m_prev;
	struct mod_list_t * m_next;
};


static struct dep_t *depend;

#define MAIN_OPT_STR "acdklnqrst:vVC:"
#define INSERT_ALL     1        /* a */
#define DUMP_CONF_EXIT 2        /* c */
#define D_OPT_IGNORED  4        /* d */
#define AUTOCLEAN_FLG  8        /* k */
#define LIST_ALL       16       /* l */
#define SHOW_ONLY      32       /* n */
#define QUIET          64       /* q */
#define REMOVE_OPT     128      /* r */
#define DO_SYSLOG      256      /* s */
#define RESTRICT_DIR   512      /* t */
#define VERBOSE        1024     /* v */
#define VERSION_ONLY   2048     /* V */
#define CONFIG_FILE    4096     /* C */

#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)
{
	char *tag, *value;

	buffer = skip_whitespace(buffer);
	tag = value = buffer;
	while (!isspace(*value)) {
		if (!*value)
			return 0;
		value++;
	}
	*value++ = '\0';
	value = skip_whitespace(value);
	if (!*value)
		return 0;

	*ptag = tag;
	*pvalue = value;

	return 1;
}

/*
 * This function appends an option to a list
 */
static struct mod_opt_t *append_option(struct mod_opt_t *opt_list, char *opt)
{
	struct mod_opt_t *ol = opt_list;

	if (ol) {
		while (ol->m_next) {
			ol = ol->m_next;
		}
		ol->m_next = xzalloc(sizeof(struct mod_opt_t));
		ol = ol->m_next;
	} else {
		ol = opt_list = xzalloc(sizeof(struct mod_opt_t));
	}

	ol->m_opt_val = xstrdup(opt);
	/*ol->m_next = NULL; - done by xzalloc*/

	return opt_list;
}

#if ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS
/* static char* parse_command_string(char* src, char **dst);
 *   src: pointer to string containing argument
 *   dst: pointer to where to store the parsed argument
 *   return value: the pointer to the first char after the parsed argument,
 *                 NULL if there was no argument parsed (only trailing spaces).
 *   Note that memory is allocated with xstrdup when a new argument was
 *   parsed. Don't forget to free it!
 */
#define ARG_EMPTY      0x00
#define ARG_IN_DQUOTES 0x01
#define ARG_IN_SQUOTES 0x02
static char *parse_command_string(char *src, char **dst)
{
	int opt_status = ARG_EMPTY;
	char* tmp_str;

	/* Dumb you, I have nothing to do... */
	if (src == NULL) return src;

	/* Skip leading spaces */
	while (*src == ' ') {
		src++;
	}
	/* Is the end of string reached? */
	if (*src == '\0') {
		return NULL;
	}
	/* Reached the start of an argument
	 * By the way, we duplicate a little too much
	 * here but what is too much is freed later. */
	*dst = tmp_str = xstrdup(src);
	/* Get to the end of that argument */
	while (*tmp_str != '\0'
	 && (*tmp_str != ' ' || (opt_status & (ARG_IN_DQUOTES | ARG_IN_SQUOTES)))
	) {
		switch (*tmp_str) {
		case '\'':
			if (opt_status & ARG_IN_DQUOTES) {
				/* Already in double quotes, keep current char as is */
			} else {
				/* shift left 1 char, until end of string: get rid of the opening/closing quotes */
				memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
				/* mark me: we enter or leave single quotes */
				opt_status ^= ARG_IN_SQUOTES;
				/* Back one char, as we need to re-scan the new char there. */
				tmp_str--;
			}
			break;
		case '"':
			if (opt_status & ARG_IN_SQUOTES) {
				/* Already in single quotes, keep current char as is */
			} else {
				/* shift left 1 char, until end of string: get rid of the opening/closing quotes */
				memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
				/* mark me: we enter or leave double quotes */
				opt_status ^= ARG_IN_DQUOTES;
				/* Back one char, as we need to re-scan the new char there. */
				tmp_str--;
			}
			break;
		case '\\':
			if (opt_status & ARG_IN_SQUOTES) {
				/* Between single quotes: keep as is. */
			} else {
				switch (*(tmp_str+1)) {
				case 'a':
				case 'b':
				case 't':
				case 'n':
				case 'v':
				case 'f':
				case 'r':
				case '0':
					/* We escaped a special character. For now, keep
					 * both the back-slash and the following char. */
					tmp_str++;
					src++;
					break;
				default:
					/* We escaped a space or a single or double quote,
					 * or a back-slash, or a non-escapable char. Remove
					 * the '\' and keep the new current char as is. */
					memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
					break;
				}
			}
			break;
		/* Any other char that is special shall appear here.
		 * Example: $ starts a variable
		case '$':
			do_variable_expansion();
			break;
		 * */
		default:
			/* any other char is kept as is. */
			break;
		}
		tmp_str++; /* Go to next char */
		src++; /* Go to next char to find the end of the argument. */
	}
	/* End of string, but still no ending quote */
	if (opt_status & (ARG_IN_DQUOTES | ARG_IN_SQUOTES)) {
		bb_error_msg_and_die("unterminated (single or double) quote in options list: %s", src);
	}
	*tmp_str++ = '\0';
	*dst = xrealloc(*dst, (tmp_str - *dst));
	return src;
}
#else
#define parse_command_string(src, dst)	(0)
#endif /* ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS */

/*
 * This function reads aliases and default module options from a configuration file
 * (/etc/modprobe.conf syntax). It supports includes (only files, no directories).
 */
static void include_conf(struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd)
{
	int continuation_line = 0;

	// alias parsing is not 100% correct (no correct handling of continuation lines within an alias)!

	while (reads(fd, buffer, buflen)) {
		int l;
		char *p;

		p = strchr(buffer, '#');
		if (p)
			*p = '\0';

		l = strlen(buffer);

		while (l && isspace(buffer[l-1])) {
			buffer[l-1] = '\0';
			l--;
		}

		if (l == 0) {
			continuation_line = 0;
			continue;
		}

		if (continuation_line)
			continue;

		if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) {
			char *alias, *mod;

			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 ((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);
				}
				/*(*current)->m_next = NULL; - done by xzalloc */
			}
		} else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) {
			char *mod, *opt;

			/* 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);
					}
				}
			}
		} else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) {
			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);
			}
		}
	} /* while (reads(...)) */
}

/*
 * This function builds a list of dependency rules from /lib/modules/`uname -r`/modules.dep.
 * It then fills every modules and aliases with their default options, found by parsing
 * modprobe.conf (or modules.conf, or conf.modules).
 */
static struct dep_t *build_dep(void)
{
	int fd;
	struct utsname un;
	struct dep_t *first = NULL;
	struct dep_t *current = NULL;
	char *filename;
	int continuation_line = 0;
	int k_version;

	if (uname(&un))
		bb_error_msg_and_die("can't determine kernel version");

	k_version = 0;
	if (un.release[0] == '2') {
		k_version = un.release[2] - '0';
	}

	filename = xasprintf("/lib/modules/%s/modules.dep", 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);
		if (fd < 0) {
			bb_error_msg_and_die("cannot parse modules.dep");
		}
	}

	while (reads(fd, line_buffer, sizeof(line_buffer))) {
		int l = strlen(line_buffer);
		char *p = 0;

		while (l > 0 && isspace(line_buffer[l-1])) {
			line_buffer[l-1] = '\0';
			l--;
		}

		if (l == 0) {
			continuation_line = 0;
			continue;
		}

		/* Is this a new module dep description? */
		if (!continuation_line) {
			/* find the dep beginning */
			char *col = strchr(line_buffer, ':');
			char *dot = col;

			if (col) {
				/* This line is a dep description */
				const char *mods;
				char *modpath;
				char *mod;

				/* Find the beginning of the module file name */
				*col = '\0';
				mods = bb_basename(line_buffer);

				/* find the path of the module */
				modpath = strchr(line_buffer, '/'); /* ... and this is the path */
				if (!modpath)
					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'))
					dot = col - 3;
				else if ((col[-2] == '.') && (col[-1] == 'o'))
					dot = col - 2;

				mod = xstrndup(mods, dot - mods);

				/* enqueue new 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 = 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 = NULL;
		} else
			/* It's a dep description continuation */
			p = line_buffer;

		while (p && *p && isblank(*p))
			p++;

		/* p points to the first dependable module; if NULL, no dependable module */
		if (p && *p) {
			char *end = &line_buffer[l-1];
			const char *deps;
			char *dep;
			char *next;
			int ext = 0;

			while (isblank(*end) || (*end == '\\'))
				end--;

			do {
				/* search the end of the dependency */
				next = strchr(p, ' ');
				if (next) {
					*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++;
				}

				/* 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[0] == 'o'))
					ext = 3;
				else if ((next[-1] == '.') && (next[0] == 'o'))
					ext = 2;

				/* Cope with blank lines */
				if ((next-deps-ext+1) <= 0)
					continue;
				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;

				p = next + 2;
			} while (next < end);
		}

		/* is there other dependable module(s) ? */
		continuation_line = (line_buffer[l-1] == '\\');
	} /* while (reads(...)) */
	close(fd);

	/*
	 * First parse system-specific options and aliases
	 * as they take precedence over the kernel ones.
	 * >=2.6: we only care about modprobe.conf
	 * <=2.4: we care about modules.conf and conf.modules
	 */
	if (ENABLE_FEATURE_2_6_MODULES
	 && (fd = open("/etc/modprobe.conf", O_RDONLY)) < 0)
		if (ENABLE_FEATURE_2_4_MODULES
		 && (fd = open("/etc/modules.conf", O_RDONLY)) < 0)
			if (ENABLE_FEATURE_2_4_MODULES)
				fd = open("/etc/conf.modules", O_RDONLY);

	if (fd >= 0) {
		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);
		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);
		}
		if (ENABLE_FEATURE_CLEAN_UP)
			free(filename);

		if (fd >= 0) {
			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);
		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);
		}
		if (ENABLE_FEATURE_CLEAN_UP)
			free(filename);

		if (fd >= 0) {
			include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
			close(fd);
		}
	}

	return first;
}

/* return 1 = loaded, 0 = not loaded, -1 = can't tell */
static int already_loaded(const char *name)
{
	int fd, ret = 0;

	fd = open("/proc/modules", O_RDONLY);
	if (fd < 0)
		return -1;

	while (reads(fd, line_buffer, sizeof(line_buffer))) {
		char *p;

		p = strchr(line_buffer, ' ');
		if (p) {
			const char *n;

			// Truncate buffer at first space and check for matches, with
			// the idiosyncrasy that _ and - are interchangeable because the
			// 2.6 kernel does weird things.

			*p = '\0';
			for (p = line_buffer, n = name; ; p++, n++) {
				if (*p != *n) {
					if ((*p == '_' || *p == '-') && (*n == '_' || *n == '-'))
						continue;
					break;
				}
				// If we made it to the end, that's a match.
				if (!*p) {
					ret = 1;
					goto done;
				}
			}
		}
	}
 done:
	close(fd);
	return ret;
}

static int mod_process(const struct mod_list_t *list, int do_insert)
{
	int rc = 0;
	char **argv = NULL;
	struct mod_opt_t *opts;
	int argc_malloc; /* never used when CONFIG_FEATURE_CLEAN_UP not defined */
	int argc;

	while (list) {
		argc = 0;
		if (ENABLE_FEATURE_CLEAN_UP)
			argc_malloc = 0;
		/* If CONFIG_FEATURE_CLEAN_UP is not defined, then we leak memory
		 * each time we allocate memory for argv.
		 * But it is (quite) small amounts of memory that leak each
		 * time a module is loaded,  and it is reclaimed when modprobe
		 * exits anyway (even when standalone shell?).
		 * This could become a problem when loading a module with LOTS of
		 * dependencies, with LOTS of options for each dependencies, with
		 * very little memory on the target... But in that case, the module
		 * would not load because there is no more memory, so there's no
		 * problem. */
		/* enough for minimal insmod (5 args + NULL) or rmmod (3 args + NULL) */
		argv = xmalloc(6 * sizeof(char*));
		if (do_insert) {
			if (already_loaded(list->m_name) != 1) {
				argv[argc++] = (char*)"insmod";
				if (ENABLE_FEATURE_2_4_MODULES) {
					if (do_syslog)
						argv[argc++] = (char*)"-s";
					if (autoclean)
						argv[argc++] = (char*)"-k";
					if (quiet)
						argv[argc++] = (char*)"-q";
					else if (verbose) /* verbose and quiet are mutually exclusive */
						argv[argc++] = (char*)"-v";
				}
				argv[argc++] = list->m_path;
				if (ENABLE_FEATURE_CLEAN_UP)
					argc_malloc = argc;
				opts = list->m_options;
				while (opts) {
					/* Add one more option */
					argc++;
					argv = xrealloc(argv, (argc + 1) * sizeof(char*));
					argv[argc-1] = opts->m_opt_val;
					opts = opts->m_next;
				}
			}
		} else {
			/* modutils uses short name for removal */
			if (already_loaded(list->m_name) != 0) {
				argv[argc++] = (char*)"rmmod";
				if (do_syslog)
					argv[argc++] = (char*)"-s";
				argv[argc++] = (char*)list->m_name;
				if (ENABLE_FEATURE_CLEAN_UP)
					argc_malloc = argc;
			}
		}
		argv[argc] = NULL;

		if (argc) {
			if (verbose) {
				printf("%s module %s\n", do_insert?"Loading":"Unloading", list->m_name);
			}
			if (!show_only) {
				int rc2 = wait4pid(spawn(argv));

				if (do_insert) {
					rc = rc2; /* only last module matters */
				} else if (!rc2) {
					rc = 0; /* success if remove any mod */
				}
			}
			if (ENABLE_FEATURE_CLEAN_UP) {
				/* the last value in the array has index == argc, but
				 * it is the terminating NULL, so we must not free it. */
				while (argc_malloc < argc) {
					free(argv[argc_malloc++]);
				}
			}
		}
		if (ENABLE_FEATURE_CLEAN_UP) {
			free(argv);
			argv = NULL;
		}
		list = do_insert ? list->m_prev : list->m_next;
	}
	return (show_only) ? 0 : rc;
}

/*
 * Check the matching between a pattern and a module name.
 * We need this as *_* is equivalent to *-*, even in pattern matching.
 */
static int check_pattern(const char* pat_src, const char* mod_src)
{
	int ret;

	if (ENABLE_FEATURE_MODPROBE_FANCY_ALIAS) {
		char* pat;
		char* mod;
		char* p;

		pat = xstrdup(pat_src);
		mod = xstrdup(mod_src);

		for (p = pat; (p = strchr(p, '-')); *p++ = '_');
		for (p = mod; (p = strchr(p, '-')); *p++ = '_');

		ret = fnmatch(pat, mod, 0);

		if (ENABLE_FEATURE_CLEAN_UP) {
			free(pat);
			free(mod);
		}

		return ret;
	}
	return fnmatch(pat_src, mod_src, 0);
}

/*
 * Builds the dependency list (aka stack) of a module.
 * head: the highest module in the stack (last to insmod, first to rmmod)
 * tail: the lowest module in the stack (first to insmod, last to rmmod)
 */
static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **tail)
{
	struct mod_list_t *find;
	struct dep_t *dt;
	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,
	 * so try to match the given module name against such a pattern.
	 * Of course if the name in the dependency rule is a plain string,
	 * then we consider it a pattern, and matching will still work. */
	for (dt = depend; dt; dt = dt->m_next) {
		if (check_pattern(dt->m_name, mod) == 0) {
			break;
		}
	}

	if (!dt) {
		bb_error_msg("module %s not found", mod);
		return;
	}

	// resolve alias names
	while (dt->m_isalias) {
		if (dt->m_depcnt == 1) {
			struct dep_t *adt;

			for (adt = depend; adt; adt = adt->m_next) {
				if (check_pattern(adt->m_name, dt->m_deparr[0]) == 0)
					break;
			}
			if (adt) {
				/* This is the module we are aliased to */
				struct mod_opt_t *opts = dt->m_options;
				/* Option of the alias are appended to the options of the module */
				while (opts) {
					adt->m_options = append_option(adt->m_options, opts->m_opt_val);
					opts = opts->m_next;
				}
				dt = adt;
			} else {
				bb_error_msg("module %s not found", mod);
				return;
			}
		} else {
			bb_error_msg("bad alias %s", dt->m_name);
			return;
		}
	}

	mod = dt->m_name;
	path = dt->m_path;
	opt = dt->m_options;

	// search for duplicates
	for (find = *head; find; find = find->m_next) {
		if (strcmp(mod, find->m_name) == 0) {
			// found -> dequeue it

			if (find->m_prev)
				find->m_prev->m_next = find->m_next;
			else
				*head = find->m_next;

			if (find->m_next)
				find->m_next->m_prev = find->m_prev;
			else
				*tail = find->m_prev;

			break; // there can be only one duplicate
		}
	}

	if (!find) { // did not find a duplicate
		find = xzalloc(sizeof(struct mod_list_t));
		find->m_name = mod;
		find->m_path = path;
		find->m_options = opt;
	}

	// enqueue at tail
	if (*tail)
		(*tail)->m_next = find;
	find->m_prev = *tail;
	find->m_next = NULL; /* possibly NOT done by xzalloc! */

	if (!*head)
		*head = find;
	*tail = find;

	if (dt) {
		int i;

		/* Add all dependable module for that new module */
		for (i = 0; i < dt->m_depcnt; i++)
			check_dep(dt->m_deparr[i], head, tail);
	}
}

static int mod_insert(char *mod, int argc, char **argv)
{
	struct mod_list_t *tail = NULL;
	struct mod_list_t *head = NULL;
	int rc;

	// get dep list for module mod
	check_dep(mod, &head, &tail);

	rc = 1;
	if (head && tail) {
		if (argc) {
			int i;
			// append module args
			for (i = 0; i < argc; i++)
				head->m_options = append_option(head->m_options, argv[i]);
		}

		// process tail ---> head
		rc = mod_process(tail, 1);
		if (rc) {
			/*
			 * In case of using udev, multiple instances of modprobe can be
			 * spawned to load the same module (think of two same usb devices,
			 * for example; or cold-plugging at boot time). Thus we shouldn't
			 * fail if the module was loaded, and not by us.
			 */
			if (already_loaded(mod))
				rc = 0;
		}
	}
	return rc;
}

static int mod_remove(char *mod)
{
	int rc;
	static const struct mod_list_t rm_a_dummy = { "-a", NULL, NULL, NULL, NULL };

	struct mod_list_t *head = NULL;
	struct mod_list_t *tail = NULL;

	if (mod)
		check_dep(mod, &head, &tail);
	else  // autoclean
		head = tail = (struct mod_list_t*) &rm_a_dummy;

	rc = 1;
	if (head && tail)
		rc = mod_process(head, 0);  // process head ---> tail
	return rc;
}

int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int modprobe_main(int argc, char **argv)
{
	int rc = EXIT_SUCCESS;
	char *unused;

	opt_complementary = "?V-:q-v:v-q";
	getopt32(argv, MAIN_OPT_STR, &unused, &unused);

	if (option_mask32 & (DUMP_CONF_EXIT | LIST_ALL))
		return EXIT_SUCCESS;
	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");

	if (remove_opt) {
		do {
			/* argv[optind] can be NULL here */
			if (mod_remove(argv[optind])) {
				bb_error_msg("failed to remove module %s",
						argv[optind]);
				rc = EXIT_FAILURE;
			}
		} while (++optind < argc);
	} else {
		if (optind >= argc)
			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]);
	}

	/* Here would be a good place to free up memory allocated during the dependencies build. */

	return rc;
}
