/* vi: set sw=4 ts=4: */
/*
 * depmod - generate modules.dep
 * Copyright (c) 2008 Bernhard Fischer
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <libbb.h>
#include <sys/utsname.h> /* uname() */
/*
 * Theory of operation:
 * - iterate over all modules and record their full path
 * - iterate over all modules looking for "depends=" entries
 *   for each depends, look through our list of full paths and emit if found
 */

typedef struct dep_lst_t {
	char *name;
	llist_t *dependencies;
	llist_t *aliases;
	struct dep_lst_t *next;
} dep_lst_t;

struct globals {
	dep_lst_t *lst; /* modules without their corresponding extension */
};
#define G (*(struct globals*)&bb_common_bufsiz1)
/* We have to zero it out because of NOEXEC */
#define INIT_G() memset(&G, 0, sizeof(G))

static char* find_keyword(void *the_module, size_t len, const char * const word)
{
	char *ptr = the_module;
	do {
		/* search for the first char in word */
		ptr = memchr(ptr, *word, len - (ptr - (char*)the_module));
		if (ptr == NULL) /* no occurance left, done */
			return NULL;
		if (!strncmp(ptr, word, strlen(word))) {
			ptr += strlen(word);
			break;
		}
		++ptr;
	} while (1);
	return ptr;
}
static int FAST_FUNC fileAction(const char *fname, struct stat *sb,
					void UNUSED_PARAM *data, int UNUSED_PARAM depth)
{
	size_t len = sb->st_size;
	void *the_module;
	char *ptr;
	int fd;
	char *depends, *deps;
	dep_lst_t *this;

	if (strrstr(fname, ".ko") == NULL) /* not a module */
		goto skip;

/*XXX: FIXME: does not handle compressed modules!
 * There should be a function that looks at the extension and sets up
 * open_transformer for us.
 */
	fd = xopen(fname, O_RDONLY);
	the_module = mmap(NULL, len, PROT_READ, MAP_SHARED
#if defined MAP_POPULATE
						|MAP_POPULATE
#endif
						, fd, 0);
	close(fd);
	if (the_module == MAP_FAILED)
		bb_perror_msg_and_die("mmap");

	this = xzalloc(sizeof(dep_lst_t));
	this->name = xstrdup(fname);
	this->next = G.lst;
	G.lst = this;
//bb_info_msg("fname='%s'", fname);
	ptr = find_keyword(the_module, len, "depends=");
	if (!*ptr)
		goto d_none;
	deps = depends = xstrdup(ptr);
//bb_info_msg(" depends='%s'", depends);
	while (deps) {
		ptr = strsep(&deps, ",");
//bb_info_msg("[%s] -> '%s'", fname, (char*)ptr);
		llist_add_to_end(&this->dependencies, xstrdup(ptr));
	}
	free(depends);
 d_none:
	if (ENABLE_FEATURE_DEPMOD_ALIAS)
	{
		size_t pos = 0;
		do {
			ptr = find_keyword(the_module + pos, len - pos, "alias=");
			if (ptr) {
//bb_info_msg("[%s] alias '%s'", fname, (char*)ptr);
					llist_add_to_end(&this->aliases, xstrdup(ptr));
			} else
				break;
			pos = (ptr - (char*)the_module);
		} while (1);
	}
	munmap(the_module, sb->st_size);
 skip:
	return TRUE;
}

int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int depmod_main(int argc UNUSED_PARAM, char **argv)
{
	int ret;
	size_t moddir_base_len = 0; /* length of the "-b basedir" */
	char *moddir_base = NULL, *moddir, *system_map, *chp;
	FILE *filedes = stdout;
	enum {
		ARG_a = (1<<0), /* All modules, ignore mods in argv */
		ARG_A = (1<<1), /* Only emit .ko that are newer than modules.dep file */
		ARG_b = (1<<2), /* not /lib/modules/$(uname -r)/ but this base-dir */
		ARG_e = (1<<3), /* with -F, print unresolved symbols */
		ARG_F = (1<<4), /* System.map that contains the symbols */
		ARG_n = (1<<5)  /* dry-run, print to stdout only */
	};
	INIT_G();

	getopt32(argv, "aAb:eF:n", &moddir_base, &system_map);
	argv += optind;

	/* If a version is provided, then that kernel version’s module directory
	 * is used, rather than the current kernel version (as returned by
	 * "uname -r").  */
	if (*argv && (sscanf(*argv, "%d.%d.%d", &ret, &ret, &ret) == 3)) {
		moddir = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, *argv++);
	} else {
		struct utsname uts;
		if (uname(&uts) < 0)
			bb_simple_perror_msg_and_die("uname");
		moddir = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, uts.release);
	}
	/* If no modules are given on the command-line, -a is on per default.  */
	option_mask32 |= *argv == NULL;

	if (option_mask32 & ARG_b) {
		moddir_base_len = strlen(moddir_base) + 1;
		xchdir(moddir_base);
	}

	if (!(option_mask32 & ARG_n)) { /* --dry-run */
		chp = concat_path_file(moddir, CONFIG_DEFAULT_DEPMOD_FILE);
		filedes = xfopen(chp, "w");
		if (ENABLE_FEATURE_CLEAN_UP)
			free(chp);
	}
	ret = EXIT_SUCCESS;
	do {
		chp = option_mask32 & ARG_a ? moddir : (*argv + moddir_base_len);

		if (!recursive_action(chp,
				ACTION_RECURSE, /* flags */
				fileAction, /* file action */
				NULL, /* dir action */
				NULL, /* user data */
				0)) { /* depth */
			ret = EXIT_FAILURE;
		}
	} while (!(option_mask32 & ARG_a) && *++argv);

	{
	dep_lst_t *mods = G.lst;

	/* Fixup the module names in the depends list */
	while (mods) {
		llist_t *deps = NULL, *old_deps = mods->dependencies;

		while (old_deps) {
			dep_lst_t *all = G.lst;
			char *longname = NULL;
			char *shortname = llist_pop(&old_deps);

			while (all) {
				char *nam =
					xstrdup(bb_get_last_path_component_nostrip(all->name));
				char *tmp = strrstr(nam, ".ko");

				*tmp = '\0';
				if (!strcmp(nam, shortname)) {
					if (ENABLE_FEATURE_CLEAN_UP)
						free(nam);
					longname = all->name;
					break;
				}
				free(nam);
				all = all->next;
			}
			llist_add_to_end(&deps, longname);
		}
		mods->dependencies = deps;
		mods = mods->next;
	}

#if ENABLE_FEATURE_DEPMOD_PRUNE_FANCY
	/* modprobe allegedly wants dependencies without duplicates, i.e.
	 * mod1: mod2 mod3
	 * mod2: mod3
	 * mod3:
	 * implies that mod1 directly depends on mod2 and _not_ mod3 as mod3 is
	 * already implicitely pulled in via mod2. This leaves us with:
	 * mod1: mod2
	 * mod2: mod3
	 * mod3:
	 */
	mods = G.lst;
	while (mods) {
		llist_t *deps = mods->dependencies;
		while (deps) {
			dep_lst_t *all = G.lst;
			while (all) {
				if (!strcmp(all->name, deps->data)) {
					llist_t *implied = all->dependencies;
					while (implied) {
						/* XXX:FIXME: erm, it would be nicer to just
						 * llist_unlink(&mods->dependencies, implied)  */
						llist_t *prune = mods->dependencies;
						while (prune) {
							if (!strcmp(implied->data, prune->data))
								break;
							prune = prune->link;
						}
//if (prune) bb_info_msg("[%s] '%s' implies '%s', removing", mods->name, all->name, implied->data);
						llist_unlink(&mods->dependencies, prune);
						implied = implied->link;
					}
				}
				all = all->next;
			}
			deps = deps->link;
		}
		mods = mods->next;
	}
#endif

	mods = G.lst;
	/* Finally print them.  */
	while (mods) {
		fprintf(filedes, "%s:", mods->name);
		/* If we did not resolve all modules, then it's likely that we just did
		 * not see the names of all prerequisites (which will be NULL in this
		 * case).  */
		while (mods->dependencies) {
			char *the_dep = llist_pop(&mods->dependencies);
			if (the_dep)
				fprintf(filedes, " %s", the_dep);
		}
		fprintf(filedes, "\n");
		if (ENABLE_FEATURE_DEPMOD_ALIAS)
		{
			char *shortname =
				xstrdup(bb_get_last_path_component_nostrip(mods->name));
			char *tmp = strrstr(shortname, ".ko");

			*tmp = '\0';

			while (mods->aliases) {
				fprintf(filedes, "alias %s %s\n",
					(char*)llist_pop(&mods->aliases),
					shortname);
			}
			free(shortname);
		}
		mods = mods->next;
	}
	}

	if (ENABLE_FEATURE_CLEAN_UP) {
		fclose_if_not_stdin(filedes);
		free(moddir);
		while (G.lst) {
			dep_lst_t *old = G.lst;
			G.lst = G.lst->next;
			free(old->name);
			free(old);
		}
	}
	return ret;
}
