/* vi: set sw=4 ts=4: */
/*
 * modinfo - retrieve module info
 * Copyright (c) 2008 Pascal Bellard
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
//config:config MODINFO
//config:	bool "modinfo (24 kb)"
//config:	default y
//config:	help
//config:	Show information about a Linux Kernel module

//applet:IF_MODINFO(APPLET_NOEXEC(modinfo, modinfo, BB_DIR_SBIN, BB_SUID_DROP, modinfo))

//kbuild:lib-$(CONFIG_MODINFO) += modinfo.o modutils.o

#include <fnmatch.h>
#include <sys/utsname.h> /* uname() */
#include "libbb.h"
#include "modutils.h"

static const char *const shortcuts[] ALIGN_PTR = {
	"filename",	// -n
	"author",	// -a
	"description",	// -d
	"license",	// -l
	"parm",		// -p
	"version",	// the rest has no shortcut options
	"alias",
	"srcversion",
	"depends",
	"uts_release",
	"intree",
	"vermagic",
	"firmware",
};

enum {
	OPT_0 = (1 << 0), /* \0 as separator */
	OPT_F = (1 << 1), /* field name */
	/* first bits are for -nadlp options, the rest are for
	 * fields not selectable with "shortcut" options
	 */
	OPT_n = (1 << 2),
	OPT_TAGS = ((1 << ARRAY_SIZE(shortcuts)) - 1) << 2,
};

static void display(const char *data, const char *pattern)
{
	int flag = option_mask32 >> 1; /* shift out -0 bit */
	if (flag & (flag-1)) {
		/* more than one field to show: print "FIELD:" pfx */
		int n = printf("%s:", pattern);
		while (n++ < 16)
			bb_putchar(' ');
	}
	printf("%s%c", data, (option_mask32 & OPT_0) ? '\0' : '\n');
}

static void modinfo(const char *path, const char *version,
			const char *field)
{
	size_t len;
	int j;
	char *ptr, *the_module;
	char *allocated;
	int tags = option_mask32;

	allocated = NULL;
	len = MAXINT(ssize_t);
	the_module = xmalloc_open_zipped_read_close(path, &len);
	if (!the_module) {
		if (path[0] == '/')
			return;
		/* Newer depmod puts relative paths in modules.dep */
		path = allocated = xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, version, path);
		the_module = xmalloc_open_zipped_read_close(path, &len);
		if (!the_module) {
			bb_error_msg("module '%s' not found", path);
			goto ret;
		}
	}

	for (j = 1; (1<<j) & (OPT_TAGS|OPT_F); j++) {
		const char *pattern;

		if (!((1<<j) & tags))
			continue;

		pattern = field;
		if ((1<<j) & OPT_TAGS)
			pattern = shortcuts[j-2];

		if (strcmp(pattern, shortcuts[0]) == 0) {
			/* "-n" or "-F filename" */
			display(path, shortcuts[0]);
			continue;
		}

		ptr = the_module;
		while (1) {
			char *after_pattern;

			ptr = memchr(ptr, *pattern, len - (ptr - (char*)the_module));
			if (ptr == NULL) /* no occurrence left, done */
				break;
			after_pattern = is_prefixed_with(ptr, pattern);
			if (after_pattern && *after_pattern == '=') {
				/* field prefixes are 0x80 or 0x00 */
				if ((ptr[-1] & 0x7F) == 0x00) {
					ptr = after_pattern + 1;
					display(ptr, pattern);
					ptr += strlen(ptr);
				}
			}
			++ptr;
		}
	}
	free(the_module);
 ret:
	free(allocated);
}

//usage:#define modinfo_trivial_usage
//usage:       "[-adlpn0] [-F keyword] MODULE"
//usage:#define modinfo_full_usage "\n\n"
//usage:       "	-a		Shortcut for '-F author'"
//usage:     "\n	-d		Shortcut for '-F description'"
//usage:     "\n	-l		Shortcut for '-F license'"
//usage:     "\n	-p		Shortcut for '-F parm'"
////usage:     "\n	-n		Shortcut for '-F filename'"
//usage:     "\n	-F keyword	Keyword to look for"
//usage:     "\n	-0		NUL terminated output"
//usage:#define modinfo_example_usage
//usage:       "$ modinfo -F vermagic loop\n"

int modinfo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int modinfo_main(int argc UNUSED_PARAM, char **argv)
{
	const char *field;
	char name[MODULE_NAME_LEN];
	struct utsname uts;
	parser_t *parser;
	char *colon, *tokens[2];
	unsigned opts;
	unsigned i;

	field = NULL;
	opts = getopt32(argv, "^" "0F:nadlp" "\0" "-1"/*minimum one arg*/, &field);
	/* If no field selected, show all */
	if (!(opts & (OPT_TAGS|OPT_F)))
		option_mask32 |= OPT_TAGS;
	argv += optind;

	uname(&uts);
	parser = config_open2(
		xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, uts.release, CONFIG_DEFAULT_DEPMOD_FILE),
		xfopen_for_read
	);

	while (config_read(parser, tokens, 2, 1, "# \t", PARSE_NORMAL)) {
		colon = last_char_is(tokens[0], ':');
		if (colon == NULL)
			continue;
		*colon = '\0';
		filename2modname(bb_basename(tokens[0]), name);
		for (i = 0; argv[i]; i++) {
			if (fnmatch(argv[i], name, 0) == 0) {
				modinfo(tokens[0], uts.release, field);
				argv[i] = (char *) "";
			}
		}
	}
	if (ENABLE_FEATURE_CLEAN_UP)
		config_close(parser);

	for (i = 0; argv[i]; i++) {
		if (argv[i][0]) {
			modinfo(argv[i], uts.release, field);
		}
	}

	return 0;
}
