/* vi: set sw=4 ts=4: */
/*
 * depmod - generate modules.dep
 * Copyright (c) 2008 Bernhard Reutner-Fischer
 * Copyrihgt (c) 2008 Timo Teras <timo.teras@iki.fi>
 * Copyright (c) 2008 Vladimir Dronnikov
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
//config:config DEPMOD
//config:	bool "depmod (27 kb)"
//config:	default y
//config:	help
//config:	depmod generates modules.dep (and potentially modules.alias
//config:	and modules.symbols) that contain dependency information
//config:	for modprobe.

//applet:IF_DEPMOD(IF_NOT_MODPROBE_SMALL(APPLET(depmod, BB_DIR_SBIN, BB_SUID_DROP)))

//kbuild:ifneq ($(CONFIG_MODPROBE_SMALL),y)
//kbuild:lib-$(CONFIG_DEPMOD) += depmod.o modutils.o
//kbuild:endif

#include "libbb.h"
#include "modutils.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
 */

static int FAST_FUNC parse_module(struct recursive_state *state,
		const char *fname,
		struct stat *sb UNUSED_PARAM)
{
	module_db *modules = state->userData;
	char *image, *ptr;
	module_entry *e;

	/* Arbitrary. Was sb->st_size, but that breaks .gz etc */
	size_t len = (64*1024*1024 - 4096);

	if (strrstr(fname, ".ko") == NULL)
		return TRUE;

	image = xmalloc_open_zipped_read_close(fname, &len);

	e = moddb_get_or_create(modules, bb_get_last_path_component_nostrip(fname));
	e->name = xstrdup(fname + 2); /* skip "./" */

	for (ptr = image; ptr < image + len - 10; ptr++) {
		if (is_prefixed_with(ptr, "depends=")) {
			char *u;

			ptr += 8;
			for (u = ptr; *u; u++)
				if (*u == '-')
					*u = '_';
			ptr += string_to_llist(ptr, &e->deps, ",");
		} else if (ENABLE_FEATURE_MODUTILS_ALIAS
		 && is_prefixed_with(ptr, "alias=")
		) {
			llist_add_to(&e->aliases, xstrdup(ptr + 6));
			ptr += strlen(ptr);
		} else if (ENABLE_FEATURE_MODUTILS_SYMBOLS
		 && is_prefixed_with(ptr, "__ksymtab_")
		) {
			ptr += 10;
			if (is_prefixed_with(ptr, "gpl")
			 || strcmp(ptr, "strings") == 0
			) {
				continue;
			}
			llist_add_to(&e->symbols, xstrdup(ptr));
			ptr += strlen(ptr);
		}
	}
	free(image);

	return TRUE;
}

static void order_dep_list(module_db *modules, module_entry *start, llist_t *add)
{
	module_entry *m;
	llist_t *n;

	for (n = add; n != NULL; n = n->link) {
		m = moddb_get(modules, n->data);
		if (m == NULL)
			continue;

		/* unlink current entry */
		m->dnext->dprev = m->dprev;
		m->dprev->dnext = m->dnext;

		/* and add it to tail */
		m->dnext = start;
		m->dprev = start->dprev;
		start->dprev->dnext = m;
		start->dprev = m;

		/* recurse */
		order_dep_list(modules, start, m->deps);
	}
}

static void xfreopen_write(const char *file, FILE *f)
{
	if (freopen(file, "w", f) == NULL)
		bb_perror_msg_and_die("can't open '%s'", file);
}

//usage:#if !ENABLE_MODPROBE_SMALL
//usage:#define depmod_trivial_usage "[-n] [-b BASE] [VERSION] [MODFILES]..."
//usage:#define depmod_full_usage "\n\n"
//usage:       "Generate modules.dep, alias, and symbols files"
//usage:     "\n"
//usage:     "\n	-b BASE	Use BASE/lib/modules/VERSION"
//usage:     "\n	-n	Dry run: print files to stdout"
//usage:#endif

/* Upstream usage:
 * [-aAenv] [-C FILE or DIR] [-b BASE] [-F System.map] [VERSION] [MODFILES]...
 *	-a --all
 *		Probe all modules. Default if no MODFILES.
 *	-A --quick
 *		Check modules.dep's mtime against module files' mtimes.
 *	-b --basedir BASE
 *		Use $BASE/lib/modules/VERSION
 *	-C --config FILE or DIR
 *		Path to /etc/depmod.conf or /etc/depmod.d/
 *	-e --errsyms
 *		When combined with the -F option, this reports any symbols
 *		which are not supplied by other modules or kernel.
 *	-F --filesyms System.map
 *	-n --dry-run
 *		Print modules.dep etc to standard output
 *	-v --verbose
 *		Print to stdout all the symbols each module depends on
 *		and the module's file name which provides that symbol.
 *	-r	No-op
 *	-u	No-op
 *	-q	No-op
 *
 * So far we only support: [-n] [-b BASE] [VERSION] [MODFILES]...
 * Accepted but ignored:
 * -aAe
 * -F System.map
 * -C FILE/DIR
 *
 * Not accepted: -v
 */
enum {
	//OPT_a = (1 << 0), /* All modules, ignore mods in argv */
	//OPT_A = (1 << 1), /* Only emit .ko that are newer than modules.dep file */
	OPT_b = (1 << 2), /* base directory when modules are in staging area */
	//OPT_e = (1 << 3), /* with -F, print unresolved symbols */
	//OPT_F = (1 << 4), /* System.map that contains the symbols */
	OPT_n = (1 << 5), /* dry-run, print to stdout only */
	OPT_r = (1 << 6), /* Compat dummy. Linux Makefile uses it */
	OPT_u = (1 << 7), /* -u,--unresolved-error: ignored */
	OPT_q = (1 << 8), /* -q,--quiet: ignored */
	OPT_C = (1 << 9), /* -C,--config etc_modules_conf: ignored */
};

int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int depmod_main(int argc UNUSED_PARAM, char **argv)
{
	module_db modules;
	module_entry *m, *dep;
	const char *moddir_base = "/";
	char *moddir, *version;
	struct utsname uts;
	unsigned i;
	int tmp;

	getopt32(argv, "aAb:eF:nruqC:", &moddir_base, NULL, NULL);
	argv += optind;

	/* goto modules location */
	xchdir(moddir_base);

	/* 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, "%u.%u.%u", &tmp, &tmp, &tmp) == 3) {
		version = *argv++;
	} else {
		uname(&uts);
		version = uts.release;
	}
	moddir = concat_path_file(&CONFIG_DEFAULT_MODULES_DIR[1], version);
	xchdir(moddir);
	if (ENABLE_FEATURE_CLEAN_UP)
		free(moddir);

	/* Scan modules */
	memset(&modules, 0, sizeof(modules));
	if (*argv) {
		do {
			recursive_action(*argv, 0 /* no ACTION_RECURSE! */,
				parse_module, NULL, &modules);
		} while (*++argv);
	} else {
		recursive_action(".", ACTION_RECURSE,
				parse_module, NULL, &modules);
	}

	/* Generate dependency and alias files */
	if (!(option_mask32 & OPT_n))
		xfreopen_write(CONFIG_DEFAULT_DEPMOD_FILE, stdout);

	moddb_foreach_module(&modules, m, i) {
		printf("%s:", m->name);

		order_dep_list(&modules, m, m->deps);
		while (m->dnext != m) {
			dep = m->dnext;
			printf(" %s", dep->name);

			/* unlink current entry */
			dep->dnext->dprev = dep->dprev;
			dep->dprev->dnext = dep->dnext;
			dep->dnext = dep->dprev = dep;
		}
		bb_putchar('\n');
	}

#if ENABLE_FEATURE_MODUTILS_ALIAS
	if (!(option_mask32 & OPT_n))
		xfreopen_write("modules.alias", stdout);
	moddb_foreach_module(&modules, m, i) {
		while (m->aliases) {
			/*
			 * Last word used to be a basename
			 * (filename with path and .ko.* stripped)
			 * at the time of module-init-tools 3.4.
			 * kmod v.12 uses module name, i.e., s/-/_/g.
			 */
			printf("alias %s %s\n",
				(char*)llist_pop(&m->aliases),
				m->modname);
		}
	}
#endif
#if ENABLE_FEATURE_MODUTILS_SYMBOLS
	if (!(option_mask32 & OPT_n))
		xfreopen_write("modules.symbols", stdout);
	moddb_foreach_module(&modules, m, i) {
		while (m->symbols) {
			printf("alias symbol:%s %s\n",
				(char*)llist_pop(&m->symbols),
				m->modname);
		}
	}
#endif

	if (ENABLE_FEATURE_CLEAN_UP)
		moddb_free(&modules);

	return EXIT_SUCCESS;
}
