/* 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 "busybox.h"
#include <sys/utsname.h>
#include <fnmatch.h>

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_options "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       (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;

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;
		else 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 = xmalloc(sizeof(struct mod_opt_t));
		ol = ol->m_next;
	} else {
		ol = opt_list = xmalloc(sizeof(struct mod_opt_t));
	}

	ol->m_opt_val = xstrdup(opt);
	ol->m_next = NULL;

	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) {
			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;
						(*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;
				}
			} 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);

				if ((fdi = open(filename, O_RDONLY)) >= 0) {
					include_conf(first, current, buffer, buflen, fdi);
					close(fdi);
				}
			}
		}
	}
}

/*
 * 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 = 0;
	struct dep_t *current = 0;
	char buffer[2048];
	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) {
			return 0;
		}
	}

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

		while (l > 0 && isspace(buffer[l-1])) {
			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(buffer, ':');
			char *dot = col;

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

				/* Find the beginning of the module file name */
				*col = 0;
				mods = strrchr(buffer, '/');

				if (!mods)
					mods = buffer; /* no path for this module */
				else
					mods++; /* there was a path for this module... */

				/* find the path of the module */
				modpath = strchr(buffer, '/'); /* ... and this is the path */
				if (!modpath)
					modpath = 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 = xmalloc(sizeof(struct dep_t));
				} else {
					current->m_next = xmalloc(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;

				p = col + 1;
			} else
				/* this line is not a dep description */
				p = 0;
		} else
			/* It's a dep description continuation */
			p = buffer;

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

		/* p points to the first dependable module; if NULL, no dependable module */
		if (p && *p) {
			char *end = &buffer[l-1];
			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 = strrchr(p, '/');

				if (!deps || (deps < p)) {
					deps = p;

					while (isblank(*deps))
						deps++;
				} else
					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'))
					ext = 3;
				else
					if ((*(next-1) == '.') && (*next == '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) ? */
		if (buffer[l-1] == '\\')
			continuation_line = 1;
		else
			continuation_line = 0;
	}
	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, buffer, sizeof(buffer), fd);
		close(fd);
	}

	/* Only 2.6 has a modules.alias file */
	if (ENABLE_FEATURE_2_6_MODULES) {
		/* Parse kernel-declared 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, buffer, sizeof(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;
	char buffer[4096];

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

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

		p = strchr (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 = 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;
	} else {
		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 = 0;
	char *path = 0;

	/* 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)) {
			// 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 = xmalloc(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 = 0;

	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);
int modprobe_main(int argc, char** argv)
{
	int rc = EXIT_SUCCESS;
	char *unused;

	opt_complementary = "?V-:q-v:v-q";
	main_opts = getopt32(argc, argv, "acdklnqrst:vVC:",
							&unused, &unused);
	if (main_opts & (DUMP_CONF_EXIT | LIST_ALL))
		return EXIT_SUCCESS;
	if (main_opts & (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 {
			if (mod_remove(optind < argc ?
						argv[optind] : NULL)) {
				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;
}
