/*
 * libkmod - interface to kernel module operations
 *
 * Copyright (C) 2011-2013  ProFUSION embedded systems
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fnmatch.h>
#include <inttypes.h>
#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#ifdef HAVE_LINUX_MODULE_H
#include <linux/module.h>
#endif

#include <shared/util.h>

#include "libkmod.h"
#include "libkmod-internal.h"

/**
 * SECTION:libkmod-module
 * @short_description: operate on kernel modules
 */

enum kmod_module_builtin {
    KMOD_MODULE_BUILTIN_UNKNOWN,
    KMOD_MODULE_BUILTIN_NO,
    KMOD_MODULE_BUILTIN_YES,
};

/**
 * kmod_module:
 *
 * Opaque object representing a module.
 */
struct kmod_module {
	struct kmod_ctx *ctx;
	char *hashkey;
	char *name;
	char *path;
	struct kmod_list *dep;
	char *options;
	const char *install_commands;	/* owned by kmod_config */
	const char *remove_commands;	/* owned by kmod_config */
	char *alias; /* only set if this module was created from an alias */
	struct kmod_file *file;
	int n_dep;
	int refcount;
	struct {
		bool dep : 1;
		bool options : 1;
		bool install_commands : 1;
		bool remove_commands : 1;
	} init;

	/*
	 * mark if module is builtin, i.e. it's present on modules.builtin
	 * file. This is set as soon as it is needed or as soon as we know
	 * about it, i.e. the module was created from builtin lookup.
	 */
	enum kmod_module_builtin builtin;

	/*
	 * private field used by kmod_module_get_probe_list() to detect
	 * dependency loops
	 */
	bool visited : 1;

	/*
	 * set by kmod_module_get_probe_list: indicates for probe_insert()
	 * whether the module's command and softdep should be ignored
	 */
	bool ignorecmd : 1;

	/*
	 * set by kmod_module_get_probe_list: indicates whether this is the
	 * module the user asked for or its dependency, or whether this
	 * is a softdep only
	 */
	bool required : 1;
};

static inline const char *path_join(const char *path, size_t prefixlen,
							char buf[PATH_MAX])
{
	size_t pathlen;

	if (path[0] == '/')
		return path;

	pathlen = strlen(path);
	if (prefixlen + pathlen + 1 >= PATH_MAX)
		return NULL;

	memcpy(buf + prefixlen, path, pathlen + 1);
	return buf;
}

static inline bool module_is_inkernel(struct kmod_module *mod)
{
	int state = kmod_module_get_initstate(mod);

	if (state == KMOD_MODULE_LIVE ||
			state == KMOD_MODULE_BUILTIN)
		return true;

	return false;
}

int kmod_module_parse_depline(struct kmod_module *mod, char *line)
{
	struct kmod_ctx *ctx = mod->ctx;
	struct kmod_list *list = NULL;
	const char *dirname;
	char buf[PATH_MAX];
	char *p, *saveptr;
	int err = 0, n = 0;
	size_t dirnamelen;

	if (mod->init.dep)
		return mod->n_dep;
	assert(mod->dep == NULL);
	mod->init.dep = true;

	p = strchr(line, ':');
	if (p == NULL)
		return 0;

	*p = '\0';
	dirname = kmod_get_dirname(mod->ctx);
	dirnamelen = strlen(dirname);
	if (dirnamelen + 2 >= PATH_MAX)
		return 0;

	memcpy(buf, dirname, dirnamelen);
	buf[dirnamelen] = '/';
	dirnamelen++;
	buf[dirnamelen] = '\0';

	if (mod->path == NULL) {
		const char *str = path_join(line, dirnamelen, buf);
		if (str == NULL)
			return 0;
		mod->path = strdup(str);
		if (mod->path == NULL)
			return 0;
	}

	p++;
	for (p = strtok_r(p, " \t", &saveptr); p != NULL;
					p = strtok_r(NULL, " \t", &saveptr)) {
		struct kmod_module *depmod = NULL;
		const char *path;

		path = path_join(p, dirnamelen, buf);
		if (path == NULL) {
			ERR(ctx, "could not join path '%s' and '%s'.\n",
			    dirname, p);
			goto fail;
		}

		err = kmod_module_new_from_path(ctx, path, &depmod);
		if (err < 0) {
			ERR(ctx, "ctx=%p path=%s error=%s\n",
						ctx, path, strerror(-err));
			goto fail;
		}

		DBG(ctx, "add dep: %s\n", path);

		list = kmod_list_prepend(list, depmod);
		n++;
	}

	DBG(ctx, "%d dependencies for %s\n", n, mod->name);

	mod->dep = list;
	mod->n_dep = n;
	return n;

fail:
	kmod_module_unref_list(list);
	mod->init.dep = false;
	return err;
}

void kmod_module_set_visited(struct kmod_module *mod, bool visited)
{
	mod->visited = visited;
}

void kmod_module_set_builtin(struct kmod_module *mod, bool builtin)
{
	mod->builtin =
		builtin ? KMOD_MODULE_BUILTIN_YES : KMOD_MODULE_BUILTIN_NO;
}

void kmod_module_set_required(struct kmod_module *mod, bool required)
{
	mod->required = required;
}

bool kmod_module_is_builtin(struct kmod_module *mod)
{
	if (mod->builtin == KMOD_MODULE_BUILTIN_UNKNOWN) {
		kmod_module_set_builtin(mod,
					kmod_lookup_alias_is_builtin(mod->ctx, mod->name));
	}

	return mod->builtin == KMOD_MODULE_BUILTIN_YES;
}
/*
 * Memory layout with alias:
 *
 * struct kmod_module {
 *        hashkey -----.
 *        alias -----. |
 *        name ----. | |
 * }               | | |
 * name <----------' | |
 * alias <-----------' |
 * name\alias <--------'
 *
 * Memory layout without alias:
 *
 * struct kmod_module {
 *        hashkey ---.
 *        alias -----|----> NULL
 *        name ----. |
 * }               | |
 * name <----------'-'
 *
 * @key is "name\alias" or "name" (in which case alias == NULL)
 */
static int kmod_module_new(struct kmod_ctx *ctx, const char *key,
				const char *name, size_t namelen,
				const char *alias, size_t aliaslen,
				struct kmod_module **mod)
{
	struct kmod_module *m;
	size_t keylen;

	m = kmod_pool_get_module(ctx, key);
	if (m != NULL) {
		*mod = kmod_module_ref(m);
		return 0;
	}

	if (alias == NULL)
		keylen = namelen;
	else
		keylen = namelen + aliaslen + 1;

	m = malloc(sizeof(*m) + (alias == NULL ? 1 : 2) * (keylen + 1));
	if (m == NULL)
		return -ENOMEM;

	memset(m, 0, sizeof(*m));

	m->ctx = kmod_ref(ctx);
	m->name = (char *)m + sizeof(*m);
	memcpy(m->name, key, keylen + 1);
	if (alias == NULL) {
		m->hashkey = m->name;
		m->alias = NULL;
	} else {
		m->name[namelen] = '\0';
		m->alias = m->name + namelen + 1;
		m->hashkey = m->name + keylen + 1;
		memcpy(m->hashkey, key, keylen + 1);
	}

	m->refcount = 1;
	kmod_pool_add_module(ctx, m, m->hashkey);
	*mod = m;

	return 0;
}

/**
 * kmod_module_new_from_name:
 * @ctx: kmod library context
 * @name: name of the module
 * @mod: where to save the created struct kmod_module
 *
 * Create a new struct kmod_module using the module name. @name can not be an
 * alias, file name or anything else; it must be a module name. There's no
 * check if the module exists in the system.
 *
 * This function is also used internally by many others that return a new
 * struct kmod_module or a new list of modules.
 *
 * The initial refcount is 1, and needs to be decremented to release the
 * resources of the kmod_module. Since libkmod keeps track of all
 * kmod_modules created, they are all released upon @ctx destruction too. Do
 * not unref @ctx before all the desired operations with the returned
 * kmod_module are done.
 *
 * Returns: 0 on success or < 0 otherwise. It fails if name is not a valid
 * module name or if memory allocation failed.
 */
KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx,
						const char *name,
						struct kmod_module **mod)
{
	size_t namelen;
	char name_norm[PATH_MAX];

	if (ctx == NULL || name == NULL || mod == NULL)
		return -ENOENT;

	modname_normalize(name, name_norm, &namelen);

	return kmod_module_new(ctx, name_norm, name_norm, namelen, NULL, 0, mod);
}

int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias,
				const char *name, struct kmod_module **mod)
{
	int err;
	char key[PATH_MAX];
	size_t namelen = strlen(name);
	size_t aliaslen = strlen(alias);

	if (namelen + aliaslen + 2 > PATH_MAX)
		return -ENAMETOOLONG;

	memcpy(key, name, namelen);
	memcpy(key + namelen + 1, alias, aliaslen + 1);
	key[namelen] = '\\';

	err = kmod_module_new(ctx, key, name, namelen, alias, aliaslen, mod);
	if (err < 0)
		return err;

	return 0;
}

/**
 * kmod_module_new_from_path:
 * @ctx: kmod library context
 * @path: path where to find the given module
 * @mod: where to save the created struct kmod_module
 *
 * Create a new struct kmod_module using the module path. @path must be an
 * existent file with in the filesystem and must be accessible to libkmod.
 *
 * The initial refcount is 1, and needs to be decremented to release the
 * resources of the kmod_module. Since libkmod keeps track of all
 * kmod_modules created, they are all released upon @ctx destruction too. Do
 * not unref @ctx before all the desired operations with the returned
 * kmod_module are done.
 *
 * If @path is relative, it's treated as relative to the current working
 * directory. Otherwise, give an absolute path.
 *
 * Returns: 0 on success or < 0 otherwise. It fails if file does not exist, if
 * it's not a valid file for a kmod_module or if memory allocation failed.
 */
KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
						const char *path,
						struct kmod_module **mod)
{
	struct kmod_module *m;
	int err;
	struct stat st;
	char name[PATH_MAX];
	char *abspath;
	size_t namelen;

	if (ctx == NULL || path == NULL || mod == NULL)
		return -ENOENT;

	abspath = path_make_absolute_cwd(path);
	if (abspath == NULL) {
		DBG(ctx, "no absolute path for %s\n", path);
		return -ENOMEM;
	}

	err = stat(abspath, &st);
	if (err < 0) {
		err = -errno;
		DBG(ctx, "stat %s: %s\n", path, strerror(errno));
		free(abspath);
		return err;
	}

	if (path_to_modname(path, name, &namelen) == NULL) {
		DBG(ctx, "could not get modname from path %s\n", path);
		free(abspath);
		return -ENOENT;
	}

	m = kmod_pool_get_module(ctx, name);
	if (m != NULL) {
		if (m->path == NULL)
			m->path = abspath;
		else if (streq(m->path, abspath))
			free(abspath);
		else {
			ERR(ctx, "kmod_module '%s' already exists with different path: new-path='%s' old-path='%s'\n",
							name, abspath, m->path);
			free(abspath);
			return -EEXIST;
		}

		kmod_module_ref(m);
	} else {
		err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m);
		if (err < 0) {
			free(abspath);
			return err;
		}

		m->path = abspath;
	}

	m->builtin = KMOD_MODULE_BUILTIN_NO;
	*mod = m;

	return 0;
}

/**
 * kmod_module_unref:
 * @mod: kmod module
 *
 * Drop a reference of the kmod module. If the refcount reaches zero, its
 * resources are released.
 *
 * Returns: NULL if @mod is NULL or if the module was released. Otherwise it
 * returns the passed @mod with its refcount decremented.
 */
KMOD_EXPORT struct kmod_module *kmod_module_unref(struct kmod_module *mod)
{
	if (mod == NULL)
		return NULL;

	if (--mod->refcount > 0)
		return mod;

	DBG(mod->ctx, "kmod_module %p released\n", mod);

	kmod_pool_del_module(mod->ctx, mod, mod->hashkey);
	kmod_module_unref_list(mod->dep);

	if (mod->file)
		kmod_file_unref(mod->file);

	kmod_unref(mod->ctx);
	free(mod->options);
	free(mod->path);
	free(mod);
	return NULL;
}

/**
 * kmod_module_ref:
 * @mod: kmod module
 *
 * Take a reference of the kmod module, incrementing its refcount.
 *
 * Returns: the passed @module with its refcount incremented.
 */
KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
{
	if (mod == NULL)
		return NULL;

	mod->refcount++;

	return mod;
}

typedef int (*lookup_func)(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3)));

static int __kmod_module_new_from_lookup(struct kmod_ctx *ctx, const lookup_func lookup[],
					 size_t lookup_count, const char *s,
					 struct kmod_list **list)
{
	unsigned int i;

	for (i = 0; i < lookup_count; i++) {
		int err;

		err = lookup[i](ctx, s, list);
		if (err < 0 && err != -ENOSYS)
			return err;
		else if (*list != NULL)
			return 0;
	}

	return 0;
}

/**
 * kmod_module_new_from_lookup:
 * @ctx: kmod library context
 * @given_alias: alias to look for
 * @list: an empty list where to save the list of modules matching
 * @given_alias
 *
 * Create a new list of kmod modules using an alias or module name and lookup
 * libkmod's configuration files and indexes in order to find the module.
 * Once it's found in one of the places, it stops searching and create the
 * list of modules that is saved in @list.
 *
 * The search order is: 1. aliases in configuration file; 2. module names in
 * modules.dep index; 3. symbol aliases in modules.symbols index; 4. aliases
 * from install commands; 5. builtin indexes from kernel.
 *
 * The initial refcount is 1, and needs to be decremented to release the
 * resources of the kmod_module. The returned @list must be released by
 * calling kmod_module_unref_list(). Since libkmod keeps track of all
 * kmod_modules created, they are all released upon @ctx destruction too. Do
 * not unref @ctx before all the desired operations with the returned list are
 * completed.
 *
 * Returns: 0 on success or < 0 otherwise. It fails if any of the lookup
 * methods failed, which is basically due to memory allocation fail. If module
 * is not found, it still returns 0, but @list is an empty list.
 */
KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
						const char *given_alias,
						struct kmod_list **list)
{
	const lookup_func lookup[] = {
		kmod_lookup_alias_from_config,
		kmod_lookup_alias_from_moddep_file,
		kmod_lookup_alias_from_symbols_file,
		kmod_lookup_alias_from_commands,
		kmod_lookup_alias_from_aliases_file,
		kmod_lookup_alias_from_builtin_file,
		kmod_lookup_alias_from_kernel_builtin_file,
	};
	char alias[PATH_MAX];
	int err;

	if (ctx == NULL || given_alias == NULL)
		return -ENOENT;

	if (list == NULL || *list != NULL) {
		ERR(ctx, "An empty list is needed to create lookup\n");
		return -ENOSYS;
	}

	if (alias_normalize(given_alias, alias, NULL) < 0) {
		DBG(ctx, "invalid alias: %s\n", given_alias);
		return -EINVAL;
	}

	DBG(ctx, "input alias=%s, normalized=%s\n", given_alias, alias);

	err = __kmod_module_new_from_lookup(ctx, lookup, ARRAY_SIZE(lookup),
					    alias, list);

	DBG(ctx, "lookup=%s found=%d\n", alias, err >= 0 && *list);

	if (err < 0) {
		kmod_module_unref_list(*list);
		*list = NULL;
	}

	return err;
}

/**
 * kmod_module_new_from_name_lookup:
 * @ctx: kmod library context
 * @modname: module name to look for
 * @mod: returned module on success
 *
 * Lookup by module name, without considering possible aliases. This is similar
 * to kmod_module_new_from_lookup(), but don't consider as source indexes and
 * configurations that work with aliases. When succesful, this always resolves
 * to one and only one module.
 *
 * The search order is: 1. module names in modules.dep index;
 * 2. builtin indexes from kernel.
 *
 * The initial refcount is 1, and needs to be decremented to release the
 * resources of the kmod_module. Since libkmod keeps track of all
 * kmod_modules created, they are all released upon @ctx destruction too. Do
 * not unref @ctx before all the desired operations with the returned list are
 * completed.
 *
 * Returns: 0 on success or < 0 otherwise. It fails if any of the lookup
 * methods failed, which is basically due to memory allocation failure. If
 * module is not found, it still returns 0, but @mod is left untouched.
 */
KMOD_EXPORT int kmod_module_new_from_name_lookup(struct kmod_ctx *ctx,
						 const char *modname,
						 struct kmod_module **mod)
{
	const lookup_func lookup[] = {
		kmod_lookup_alias_from_moddep_file,
		kmod_lookup_alias_from_builtin_file,
		kmod_lookup_alias_from_kernel_builtin_file,
	};
	char name_norm[PATH_MAX];
	struct kmod_list *list = NULL;
	int err;

	if (ctx == NULL || modname == NULL || mod == NULL)
		return -ENOENT;

	modname_normalize(modname, name_norm, NULL);

	DBG(ctx, "input modname=%s, normalized=%s\n", modname, name_norm);

	err = __kmod_module_new_from_lookup(ctx, lookup, ARRAY_SIZE(lookup),
					    name_norm, &list);

	DBG(ctx, "lookup=%s found=%d\n", name_norm, err >= 0 && list);

	if (err >= 0 && list != NULL)
		*mod = kmod_module_get_module(list);

	kmod_module_unref_list(list);

	return err;
}

/**
 * kmod_module_unref_list:
 * @list: list of kmod modules
 *
 * Drop a reference of each kmod module in @list and releases the resources
 * taken by the list itself.
 *
 * Returns: 0
 */
KMOD_EXPORT int kmod_module_unref_list(struct kmod_list *list)
{
	for (; list != NULL; list = kmod_list_remove(list))
		kmod_module_unref(list->data);

	return 0;
}

/**
 * kmod_module_get_filtered_blacklist:
 * @ctx: kmod library context
 * @input: list of kmod_module to be filtered with blacklist
 * @output: where to save the new list
 *
 * This function should not be used. Use kmod_module_apply_filter instead.
 *
 * Given a list @input, this function filter it out with config's blacklist
 * and save it in @output.
 *
 * Returns: 0 on success or < 0 otherwise. @output is saved with the updated
 * list.
 */
KMOD_EXPORT int kmod_module_get_filtered_blacklist(const struct kmod_ctx *ctx,
						const struct kmod_list *input,
						struct kmod_list **output)
{
	return kmod_module_apply_filter(ctx, KMOD_FILTER_BLACKLIST, input, output);
}

static const struct kmod_list *module_get_dependencies_noref(const struct kmod_module *mod)
{
	if (!mod->init.dep) {
		/* lazy init */
		char *line = kmod_search_moddep(mod->ctx, mod->name);

		if (line == NULL)
			return NULL;

		kmod_module_parse_depline((struct kmod_module *)mod, line);
		free(line);

		if (!mod->init.dep)
			return NULL;
	}

	return mod->dep;
}

/**
 * kmod_module_get_dependencies:
 * @mod: kmod module
 *
 * Search the modules.dep index to find the dependencies of the given @mod.
 * The result is cached in @mod, so subsequent calls to this function will
 * return the already searched list of modules.
 *
 * Returns: NULL on failure. Otherwise it returns a list of kmod modules
 * that can be released by calling kmod_module_unref_list().
 */
KMOD_EXPORT struct kmod_list *kmod_module_get_dependencies(const struct kmod_module *mod)
{
	struct kmod_list *l, *l_new, *list_new = NULL;

	if (mod == NULL)
		return NULL;

	module_get_dependencies_noref(mod);

	kmod_list_foreach(l, mod->dep) {
		l_new = kmod_list_append(list_new, kmod_module_ref(l->data));
		if (l_new == NULL) {
			kmod_module_unref(l->data);
			goto fail;
		}

		list_new = l_new;
	}

	return list_new;

fail:
	ERR(mod->ctx, "out of memory\n");
	kmod_module_unref_list(list_new);
	return NULL;
}

/**
 * kmod_module_get_module:
 * @entry: an entry in a list of kmod modules.
 *
 * Get the kmod module of this @entry in the list, increasing its refcount.
 * After it's used, unref it. Since the refcount is incremented upon return,
 * you still have to call kmod_module_unref_list() to release the list of kmod
 * modules.
 *
 * Returns: NULL on failure or the kmod_module contained in this list entry
 * with its refcount incremented.
 */
KMOD_EXPORT struct kmod_module *kmod_module_get_module(const struct kmod_list *entry)
{
	if (entry == NULL)
		return NULL;

	return kmod_module_ref(entry->data);
}

/**
 * kmod_module_get_name:
 * @mod: kmod module
 *
 * Get the name of this kmod module. Name is always available, independently
 * if it was created by kmod_module_new_from_name() or another function and
 * it's always normalized (dashes are replaced with underscores).
 *
 * Returns: the name of this kmod module.
 */
KMOD_EXPORT const char *kmod_module_get_name(const struct kmod_module *mod)
{
	if (mod == NULL)
		return NULL;

	return mod->name;
}

/**
 * kmod_module_get_path:
 * @mod: kmod module
 *
 * Get the path of this kmod module. If this kmod module was not created by
 * path, it can search the modules.dep index in order to find out the module
 * under context's dirname.
 *
 * Returns: the path of this kmod module or NULL if such information is not
 * available.
 */
KMOD_EXPORT const char *kmod_module_get_path(const struct kmod_module *mod)
{
	char *line;

	if (mod == NULL)
		return NULL;

	DBG(mod->ctx, "name='%s' path='%s'\n", mod->name, mod->path);

	if (mod->path != NULL)
		return mod->path;
	if (mod->init.dep)
		return NULL;

	/* lazy init */
	line = kmod_search_moddep(mod->ctx, mod->name);
	if (line == NULL)
		return NULL;

	kmod_module_parse_depline((struct kmod_module *) mod, line);
	free(line);

	return mod->path;
}


extern long delete_module(const char *name, unsigned int flags);

/**
 * kmod_module_remove_module:
 * @mod: kmod module
 * @flags: flags used when removing the module.
 * KMOD_REMOVE_FORCE: force remove module regardless if it's still in
 * use by a kernel subsystem or other process; passed directly to Linux kernel
 * KMOD_REMOVE_NOWAIT: is always enforced, causing us to pass O_NONBLOCK to
 * delete_module(2).
 * KMOD_REMOVE_NOLOG: when module removal fails, do not log anything as the
 * caller may want to handle retries and log when appropriate.
 *
 * Remove a module from Linux kernel.
 *
 * Returns: 0 on success or < 0 on failure.
 */
KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
							unsigned int flags)
{
	unsigned int libkmod_flags = flags & 0xff;

	int err;

	if (mod == NULL)
		return -ENOENT;

	/* Filter out other flags and force ONONBLOCK */
	flags &= KMOD_REMOVE_FORCE;
	flags |= KMOD_REMOVE_NOWAIT;

	err = delete_module(mod->name, flags);
	if (err != 0) {
		err = -errno;
		if (!(libkmod_flags & KMOD_REMOVE_NOLOG))
			ERR(mod->ctx, "could not remove '%s': %m\n", mod->name);
	}

	return err;
}

extern long init_module(const void *mem, unsigned long len, const char *args);

/**
 * kmod_module_insert_module:
 * @mod: kmod module
 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
 * behavior of this function, valid flags are
 * KMOD_INSERT_FORCE_VERMAGIC: ignore kernel version magic;
 * KMOD_INSERT_FORCE_MODVERSION: ignore symbol version hashes.
 * @options: module's options to pass to Linux Kernel.
 *
 * Insert a module in Linux kernel. It opens the file pointed by @mod,
 * mmap'ing it and passing to kernel.
 *
 * Returns: 0 on success or < 0 on failure. If module is already loaded it
 * returns -EEXIST.
 */
KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
							unsigned int flags,
							const char *options)
{
	int err;
	const void *mem;
	off_t size;
	struct kmod_elf *elf;
	const char *path;
	const char *args = options ? options : "";

	if (mod == NULL)
		return -ENOENT;

	path = kmod_module_get_path(mod);
	if (path == NULL) {
		ERR(mod->ctx, "could not find module by name='%s'\n", mod->name);
		return -ENOENT;
	}

	if (!mod->file) {
		mod->file = kmod_file_open(mod->ctx, path);
		if (mod->file == NULL) {
			err = -errno;
			return err;
		}
	}

	if (kmod_file_get_direct(mod->file)) {
		unsigned int kernel_flags = 0;

		if (flags & KMOD_INSERT_FORCE_VERMAGIC)
			kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC;
		if (flags & KMOD_INSERT_FORCE_MODVERSION)
			kernel_flags |= MODULE_INIT_IGNORE_MODVERSIONS;

		err = finit_module(kmod_file_get_fd(mod->file), args, kernel_flags);
		if (err == 0 || errno != ENOSYS)
			goto init_finished;
	}

	if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
		elf = kmod_file_get_elf(mod->file);
		if (elf == NULL) {
			err = -errno;
			return err;
		}

		if (flags & KMOD_INSERT_FORCE_MODVERSION) {
			err = kmod_elf_strip_section(elf, "__versions");
			if (err < 0)
				INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
		}

		if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
			err = kmod_elf_strip_vermagic(elf);
			if (err < 0)
				INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
		}

		mem = kmod_elf_get_memory(elf);
	} else {
		mem = kmod_file_get_contents(mod->file);
	}
	size = kmod_file_get_size(mod->file);

	err = init_module(mem, size, args);
init_finished:
	if (err < 0) {
		err = -errno;
		INFO(mod->ctx, "Failed to insert module '%s': %m\n", path);
	}
	return err;
}

static bool module_is_blacklisted(struct kmod_module *mod)
{
	struct kmod_ctx *ctx = mod->ctx;
	const struct kmod_config *config = kmod_get_config(ctx);
	const struct kmod_list *bl = config->blacklists;
	const struct kmod_list *l;

	kmod_list_foreach(l, bl) {
		const char *modname = kmod_blacklist_get_modname(l);

		if (streq(modname, mod->name))
			return true;
	}

	return false;
}

/**
 * kmod_module_apply_filter
 * @ctx: kmod library context
 * @filter_type: bitmask to filter modules out, valid types are
 * KMOD_FILTER_BLACKLIST: filter modules in blacklist out;
 * KMOD_FILTER_BUILTIN: filter builtin modules out.
 * @input: list of kmod_module to be filtered
 * @output: where to save the new list
 *
 * Given a list @input, this function filter it out by the filter mask
 * and save it in @output.
 *
 * Returns: 0 on success or < 0 otherwise. @output is saved with the updated
 * list.
 */
KMOD_EXPORT int kmod_module_apply_filter(const struct kmod_ctx *ctx,
						enum kmod_filter filter_type,
						const struct kmod_list *input,
						struct kmod_list **output)
{
	const struct kmod_list *li;

	if (ctx == NULL || output == NULL)
		return -ENOENT;

	*output = NULL;
	if (input == NULL)
		return 0;

	kmod_list_foreach(li, input) {
		struct kmod_module *mod = li->data;
		struct kmod_list *node;

		if ((filter_type & KMOD_FILTER_BLACKLIST) &&
				module_is_blacklisted(mod))
			continue;

		if ((filter_type & KMOD_FILTER_BUILTIN)
		    && kmod_module_is_builtin(mod))
			continue;

		node = kmod_list_append(*output, mod);
		if (node == NULL)
			goto fail;

		*output = node;
		kmod_module_ref(mod);
	}

	return 0;

fail:
	kmod_module_unref_list(*output);
	*output = NULL;
	return -ENOMEM;
}

static int command_do(struct kmod_module *mod, const char *type,
							const char *cmd)
{
	const char *modname = kmod_module_get_name(mod);
	int err;

	DBG(mod->ctx, "%s %s\n", type, cmd);

	setenv("MODPROBE_MODULE", modname, 1);
	err = system(cmd);
	unsetenv("MODPROBE_MODULE");

	if (err == -1) {
		ERR(mod->ctx, "Could not run %s command '%s' for module %s: %m\n",
		    type, cmd, modname);
		return -EINVAL;
	}

	if (WEXITSTATUS(err)) {
		ERR(mod->ctx, "Error running %s command '%s' for module %s: retcode %d\n",
		    type, cmd, modname, WEXITSTATUS(err));
		return -EINVAL;
	}

	return 0;
}

struct probe_insert_cb {
	int (*run_install)(struct kmod_module *m, const char *cmd, void *data);
	void *data;
};

static int module_do_install_commands(struct kmod_module *mod,
					const char *options,
					struct probe_insert_cb *cb)
{
	const char *command = kmod_module_get_install_commands(mod);
	char *p;
	_cleanup_free_ char *cmd;
	int err;
	size_t cmdlen, options_len, varlen;

	assert(command);

	if (options == NULL)
		options = "";

	options_len = strlen(options);
	cmdlen = strlen(command);
	varlen = sizeof("$CMDLINE_OPTS") - 1;

	cmd = memdup(command, cmdlen + 1);
	if (cmd == NULL)
		return -ENOMEM;

	while ((p = strstr(cmd, "$CMDLINE_OPTS")) != NULL) {
		size_t prefixlen = p - cmd;
		size_t suffixlen = cmdlen - prefixlen - varlen;
		size_t slen = cmdlen - varlen + options_len;
		char *suffix = p + varlen;
		char *s = malloc(slen + 1);
		if (!s)
			return -ENOMEM;

		memcpy(s, cmd, p - cmd);
		memcpy(s + prefixlen, options, options_len);
		memcpy(s + prefixlen + options_len, suffix, suffixlen);
		s[slen] = '\0';

		free(cmd);
		cmd = s;
		cmdlen = slen;
	}

	if (cb->run_install != NULL)
		err = cb->run_install(mod, cmd, cb->data);
	else
		err = command_do(mod, "install", cmd);

	return err;
}

static char *module_options_concat(const char *opt, const char *xopt)
{
	// TODO: we might need to check if xopt overrides options on opt
	size_t optlen = opt == NULL ? 0 : strlen(opt);
	size_t xoptlen = xopt == NULL ? 0 : strlen(xopt);
	char *r;

	if (optlen == 0 && xoptlen == 0)
		return NULL;

	r = malloc(optlen + xoptlen + 2);

	if (opt != NULL) {
		memcpy(r, opt, optlen);
		r[optlen] = ' ';
		optlen++;
	}

	if (xopt != NULL)
		memcpy(r + optlen, xopt, xoptlen);

	r[optlen + xoptlen] = '\0';

	return r;
}

static int __kmod_module_get_probe_list(struct kmod_module *mod,
						bool required,
						bool ignorecmd,
						struct kmod_list **list);

/* re-entrant */
static int __kmod_module_fill_softdep(struct kmod_module *mod,
						struct kmod_list **list)
{
	struct kmod_list *pre = NULL, *post = NULL, *l;
	int err;

	err = kmod_module_get_softdeps(mod, &pre, &post);
	if (err < 0) {
		ERR(mod->ctx, "could not get softdep: %s\n",
							strerror(-err));
		goto fail;
	}

	kmod_list_foreach(l, pre) {
		struct kmod_module *m = l->data;
		err = __kmod_module_get_probe_list(m, false, false, list);
		if (err < 0)
			goto fail;
	}

	l = kmod_list_append(*list, kmod_module_ref(mod));
	if (l == NULL) {
		kmod_module_unref(mod);
		err = -ENOMEM;
		goto fail;
	}
	*list = l;
	mod->ignorecmd = (pre != NULL || post != NULL);

	kmod_list_foreach(l, post) {
		struct kmod_module *m = l->data;
		err = __kmod_module_get_probe_list(m, false, false, list);
		if (err < 0)
			goto fail;
	}

fail:
	kmod_module_unref_list(pre);
	kmod_module_unref_list(post);

	return err;
}

/* re-entrant */
static int __kmod_module_get_probe_list(struct kmod_module *mod,
						bool required,
						bool ignorecmd,
						struct kmod_list **list)
{
	struct kmod_list *dep, *l;
	int err = 0;

	if (mod->visited) {
		DBG(mod->ctx, "Ignore module '%s': already visited\n",
								mod->name);
		return 0;
	}
	mod->visited = true;

	dep = kmod_module_get_dependencies(mod);
	if (required) {
		/*
		 * Called from kmod_module_probe_insert_module(); set the
		 * ->required flag on mod and all its dependencies before
		 * they are possibly visited through some softdeps.
		 */
		mod->required = true;
		kmod_list_foreach(l, dep) {
			struct kmod_module *m = l->data;
			m->required = true;
		}
	}

	kmod_list_foreach(l, dep) {
		struct kmod_module *m = l->data;
		err = __kmod_module_fill_softdep(m, list);
		if (err < 0)
			goto finish;
	}

	if (ignorecmd) {
		l = kmod_list_append(*list, kmod_module_ref(mod));
		if (l == NULL) {
			kmod_module_unref(mod);
			err = -ENOMEM;
			goto finish;
		}
		*list = l;
		mod->ignorecmd = true;
	} else
		err = __kmod_module_fill_softdep(mod, list);

finish:
	kmod_module_unref_list(dep);
	return err;
}

static int kmod_module_get_probe_list(struct kmod_module *mod,
						bool ignorecmd,
						struct kmod_list **list)
{
	int err;

	assert(mod != NULL);
	assert(list != NULL && *list == NULL);

	/*
	 * Make sure we don't get screwed by previous calls to this function
	 */
	kmod_set_modules_visited(mod->ctx, false);
	kmod_set_modules_required(mod->ctx, false);

	err = __kmod_module_get_probe_list(mod, true, ignorecmd, list);
	if (err < 0) {
		kmod_module_unref_list(*list);
		*list = NULL;
	}

	return err;
}

/**
 * kmod_module_probe_insert_module:
 * @mod: kmod module
 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
 * behavior of this function, valid flags are
 * KMOD_PROBE_FORCE_VERMAGIC: ignore kernel version magic;
 * KMOD_PROBE_FORCE_MODVERSION: ignore symbol version hashes;
 * KMOD_PROBE_IGNORE_COMMAND: whether the probe should ignore install
 * commands and softdeps configured in the system;
 * KMOD_PROBE_IGNORE_LOADED: do not check whether the module is already
 * live in kernel or not;
 * KMOD_PROBE_DRY_RUN: dry run, do not insert module, just call the
 * associated callback function;
 * KMOD_PROBE_FAIL_ON_LOADED: if KMOD_PROBE_IGNORE_LOADED is not specified
 * and the module is already live in kernel, the function will fail if this
 * flag is specified;
 * KMOD_PROBE_APPLY_BLACKLIST_ALL: probe will apply KMOD_FILTER_BLACKLIST
 * filter to this module and its dependencies. If any of the dependencies (or
 * the module) is blacklisted, the probe will fail, unless the blacklisted
 * module is already live in kernel;
 * KMOD_PROBE_APPLY_BLACKLIST: probe will fail if the module is blacklisted;
 * KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY: probe will fail if the module is an
 * alias and is blacklisted.
 * @extra_options: module's options to pass to Linux Kernel. It applies only
 * to @mod, not to its dependencies.
 * @run_install: function to run when @mod is backed by an install command.
 * @data: data to give back to @run_install callback
 * @print_action: function to call with the action being taken (install or
 * insmod). It's useful for tools like modprobe when running with verbose
 * output or in dry-run mode.
 *
 * Insert a module in Linux kernel resolving dependencies, soft dependencies,
 * install commands and applying blacklist.
 *
 * If @run_install is NULL, this function will fork and exec by calling
 * system(3). Don't pass a NULL argument in @run_install if your binary is
 * setuid/setgid (see warning in system(3)). If you need control over the
 * execution of an install command, give a callback function instead.
 *
 * Returns: 0 on success, > 0 if stopped by a reason given in @flags or < 0 on
 * failure.
 */
KMOD_EXPORT int kmod_module_probe_insert_module(struct kmod_module *mod,
			unsigned int flags, const char *extra_options,
			int (*run_install)(struct kmod_module *m,
						const char *cmd, void *data),
			const void *data,
			void (*print_action)(struct kmod_module *m,
						bool install,
						const char *options))
{
	struct kmod_list *list = NULL, *l;
	struct probe_insert_cb cb;
	int err;

	if (mod == NULL)
		return -ENOENT;

	if (!(flags & KMOD_PROBE_IGNORE_LOADED)
					&& module_is_inkernel(mod)) {
		if (flags & KMOD_PROBE_FAIL_ON_LOADED)
			return -EEXIST;
		else
			return 0;
	}

	/*
	 * Ugly assignement + check. We need to check if we were told to check
	 * blacklist and also return the reason why we failed.
	 * KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY will take effect only if the
	 * module is an alias, so we also need to check it
	 */
	if ((mod->alias != NULL && ((err = flags & KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY)))
			|| (err = flags & KMOD_PROBE_APPLY_BLACKLIST_ALL)
			|| (err = flags & KMOD_PROBE_APPLY_BLACKLIST)) {
		if (module_is_blacklisted(mod))
			return err;
	}

	err = kmod_module_get_probe_list(mod,
				!!(flags & KMOD_PROBE_IGNORE_COMMAND), &list);
	if (err < 0)
		return err;

	if (flags & KMOD_PROBE_APPLY_BLACKLIST_ALL) {
		struct kmod_list *filtered = NULL;

		err = kmod_module_apply_filter(mod->ctx,
				KMOD_FILTER_BLACKLIST, list, &filtered);
		if (err < 0)
			return err;

		kmod_module_unref_list(list);
		if (filtered == NULL)
			return KMOD_PROBE_APPLY_BLACKLIST_ALL;

		list = filtered;
	}

	cb.run_install = run_install;
	cb.data = (void *) data;

	kmod_list_foreach(l, list) {
		struct kmod_module *m = l->data;
		const char *moptions = kmod_module_get_options(m);
		const char *cmd = kmod_module_get_install_commands(m);
		char *options;

		if (!(flags & KMOD_PROBE_IGNORE_LOADED)
						&& module_is_inkernel(m)) {
			DBG(mod->ctx, "Ignoring module '%s': already loaded\n",
								m->name);
			err = -EEXIST;
			goto finish_module;
		}

		options = module_options_concat(moptions,
					m == mod ? extra_options : NULL);

		if (cmd != NULL && !m->ignorecmd) {
			if (print_action != NULL)
				print_action(m, true, options ?: "");

			if (!(flags & KMOD_PROBE_DRY_RUN))
				err = module_do_install_commands(m, options,
									&cb);
		} else {
			if (print_action != NULL)
				print_action(m, false, options ?: "");

			if (!(flags & KMOD_PROBE_DRY_RUN))
				err = kmod_module_insert_module(m, flags,
								options);
		}

		free(options);

finish_module:
		/*
		 * Treat "already loaded" error. If we were told to stop on
		 * already loaded and the module being loaded is not a softdep
		 * or dep, bail out. Otherwise, just ignore and continue.
		 *
		 * We need to check here because of race conditions. We
		 * checked first if module was already loaded but it may have
		 * been loaded between the check and the moment we try to
		 * insert it.
		 */
		if (err == -EEXIST && m == mod &&
				(flags & KMOD_PROBE_FAIL_ON_LOADED))
			break;

		/*
		 * Ignore errors from softdeps
		 */
		if (err == -EEXIST || !m->required)
			err = 0;

		else if (err < 0)
			break;
	}

	kmod_module_unref_list(list);
	return err;
}

/**
 * kmod_module_get_options:
 * @mod: kmod module
 *
 * Get options of this kmod module. Options come from the configuration file
 * and are cached in @mod. The first call to this function will search for
 * this module in configuration and subsequent calls return the cached string.
 *
 * Returns: a string with all the options separated by spaces. This string is
 * owned by @mod, do not free it.
 */
KMOD_EXPORT const char *kmod_module_get_options(const struct kmod_module *mod)
{
	if (mod == NULL)
		return NULL;

	if (!mod->init.options) {
		/* lazy init */
		struct kmod_module *m = (struct kmod_module *)mod;
		const struct kmod_list *l;
		const struct kmod_config *config;
		char *opts = NULL;
		size_t optslen = 0;

		config = kmod_get_config(mod->ctx);

		kmod_list_foreach(l, config->options) {
			const char *modname = kmod_option_get_modname(l);
			const char *str;
			size_t len;
			void *tmp;

			DBG(mod->ctx, "modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
			if (!(streq(modname, mod->name) || (mod->alias != NULL &&
						streq(modname, mod->alias))))
				continue;

			DBG(mod->ctx, "passed = modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
			str = kmod_option_get_options(l);
			len = strlen(str);
			if (len < 1)
				continue;

			tmp = realloc(opts, optslen + len + 2);
			if (tmp == NULL) {
				free(opts);
				goto failed;
			}

			opts = tmp;

			if (optslen > 0) {
				opts[optslen] = ' ';
				optslen++;
			}

			memcpy(opts + optslen, str, len);
			optslen += len;
			opts[optslen] = '\0';
		}

		m->init.options = true;
		m->options = opts;
	}

	return mod->options;

failed:
	ERR(mod->ctx, "out of memory\n");
	return NULL;
}

/**
 * kmod_module_get_install_commands:
 * @mod: kmod module
 *
 * Get install commands for this kmod module. Install commands come from the
 * configuration file and are cached in @mod. The first call to this function
 * will search for this module in configuration and subsequent calls return
 * the cached string. The install commands are returned as they were in the
 * configuration, concatenated by ';'. No other processing is made in this
 * string.
 *
 * Returns: a string with all install commands separated by semicolons. This
 * string is owned by @mod, do not free it.
 */
KMOD_EXPORT const char *kmod_module_get_install_commands(const struct kmod_module *mod)
{
	if (mod == NULL)
		return NULL;

	if (!mod->init.install_commands) {
		/* lazy init */
		struct kmod_module *m = (struct kmod_module *)mod;
		const struct kmod_list *l;
		const struct kmod_config *config;

		config = kmod_get_config(mod->ctx);

		kmod_list_foreach(l, config->install_commands) {
			const char *modname = kmod_command_get_modname(l);

			if (fnmatch(modname, mod->name, 0) != 0)
				continue;

			m->install_commands = kmod_command_get_command(l);

			/*
			 * find only the first command, as modprobe from
			 * module-init-tools does
			 */
			break;
		}

		m->init.install_commands = true;
	}

	return mod->install_commands;
}

void kmod_module_set_install_commands(struct kmod_module *mod, const char *cmd)
{
	mod->init.install_commands = true;
	mod->install_commands = cmd;
}

static struct kmod_list *lookup_softdep(struct kmod_ctx *ctx, const char * const * array, unsigned int count)
{
	struct kmod_list *ret = NULL;
	unsigned i;

	for (i = 0; i < count; i++) {
		const char *depname = array[i];
		struct kmod_list *lst = NULL;
		int err;

		err = kmod_module_new_from_lookup(ctx, depname, &lst);
		if (err < 0) {
			ERR(ctx, "failed to lookup soft dependency '%s', continuing anyway.\n", depname);
			continue;
		} else if (lst != NULL)
			ret = kmod_list_append_list(ret, lst);
	}
	return ret;
}

/**
 * kmod_module_get_softdeps:
 * @mod: kmod module
 * @pre: where to save the list of preceding soft dependencies.
 * @post: where to save the list of post soft dependencies.
 *
 * Get soft dependencies for this kmod module. Soft dependencies come
 * from configuration file and are not cached in @mod because it may include
 * dependency cycles that would make we leak kmod_module. Any call
 * to this function will search for this module in configuration, allocate a
 * list and return the result.
 *
 * Both @pre and @post are newly created list of kmod_module and
 * should be unreferenced with kmod_module_unref_list().
 *
 * Returns: 0 on success or < 0 otherwise.
 */
KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod,
						struct kmod_list **pre,
						struct kmod_list **post)
{
	const struct kmod_list *l;
	const struct kmod_config *config;

	if (mod == NULL || pre == NULL || post == NULL)
		return -ENOENT;

	assert(*pre == NULL);
	assert(*post == NULL);

	config = kmod_get_config(mod->ctx);

	kmod_list_foreach(l, config->softdeps) {
		const char *modname = kmod_softdep_get_name(l);
		const char * const *array;
		unsigned count;

		if (fnmatch(modname, mod->name, 0) != 0)
			continue;

		array = kmod_softdep_get_pre(l, &count);
		*pre = lookup_softdep(mod->ctx, array, count);
		array = kmod_softdep_get_post(l, &count);
		*post = lookup_softdep(mod->ctx, array, count);

		/*
		 * find only the first command, as modprobe from
		 * module-init-tools does
		 */
		break;
	}

	return 0;
}

/**
 * kmod_module_get_remove_commands:
 * @mod: kmod module
 *
 * Get remove commands for this kmod module. Remove commands come from the
 * configuration file and are cached in @mod. The first call to this function
 * will search for this module in configuration and subsequent calls return
 * the cached string. The remove commands are returned as they were in the
 * configuration, concatenated by ';'. No other processing is made in this
 * string.
 *
 * Returns: a string with all remove commands separated by semicolons. This
 * string is owned by @mod, do not free it.
 */
KMOD_EXPORT const char *kmod_module_get_remove_commands(const struct kmod_module *mod)
{
	if (mod == NULL)
		return NULL;

	if (!mod->init.remove_commands) {
		/* lazy init */
		struct kmod_module *m = (struct kmod_module *)mod;
		const struct kmod_list *l;
		const struct kmod_config *config;

		config = kmod_get_config(mod->ctx);

		kmod_list_foreach(l, config->remove_commands) {
			const char *modname = kmod_command_get_modname(l);

			if (fnmatch(modname, mod->name, 0) != 0)
				continue;

			m->remove_commands = kmod_command_get_command(l);

			/*
			 * find only the first command, as modprobe from
			 * module-init-tools does
			 */
			break;
		}

		m->init.remove_commands = true;
	}

	return mod->remove_commands;
}

void kmod_module_set_remove_commands(struct kmod_module *mod, const char *cmd)
{
	mod->init.remove_commands = true;
	mod->remove_commands = cmd;
}

/**
 * SECTION:libkmod-loaded
 * @short_description: currently loaded modules
 *
 * Information about currently loaded modules, as reported by Linux kernel.
 * These information are not cached by libkmod and are always read from /sys
 * and /proc/modules.
 */

/**
 * kmod_module_new_from_loaded:
 * @ctx: kmod library context
 * @list: where to save the list of loaded modules
 *
 * Create a new list of kmod modules with all modules currently loaded in
 * kernel. It uses /proc/modules to get the names of loaded modules and to
 * create kmod modules by calling kmod_module_new_from_name() in each of them.
 * They are put in @list in no particular order.
 *
 * The initial refcount is 1, and needs to be decremented to release the
 * resources of the kmod_module. The returned @list must be released by
 * calling kmod_module_unref_list(). Since libkmod keeps track of all
 * kmod_modules created, they are all released upon @ctx destruction too. Do
 * not unref @ctx before all the desired operations with the returned list are
 * completed.
 *
 * Returns: 0 on success or < 0 on error.
 */
KMOD_EXPORT int kmod_module_new_from_loaded(struct kmod_ctx *ctx,
						struct kmod_list **list)
{
	struct kmod_list *l = NULL;
	FILE *fp;
	char line[4096];

	if (ctx == NULL || list == NULL)
		return -ENOENT;

	fp = fopen("/proc/modules", "re");
	if (fp == NULL) {
		int err = -errno;
		ERR(ctx, "could not open /proc/modules: %s\n", strerror(errno));
		return err;
	}

	while (fgets(line, sizeof(line), fp)) {
		struct kmod_module *m;
		struct kmod_list *node;
		int err;
		size_t len = strlen(line);
		char *saveptr, *name = strtok_r(line, " \t", &saveptr);

		err = kmod_module_new_from_name(ctx, name, &m);
		if (err < 0) {
			ERR(ctx, "could not get module from name '%s': %s\n",
				name, strerror(-err));
			goto eat_line;
		}

		node = kmod_list_append(l, m);
		if (node)
			l = node;
		else {
			ERR(ctx, "out of memory\n");
			kmod_module_unref(m);
		}
eat_line:
		while (line[len - 1] != '\n' && fgets(line, sizeof(line), fp))
			len = strlen(line);
	}

	fclose(fp);
	*list = l;

	return 0;
}

/**
 * kmod_module_initstate_str:
 * @state: the state as returned by kmod_module_get_initstate()
 *
 * Translate a initstate to a string.
 *
 * Returns: the string associated to the @state. This string is statically
 * allocated, do not free it.
 */
KMOD_EXPORT const char *kmod_module_initstate_str(enum kmod_module_initstate state)
{
	switch (state) {
	case KMOD_MODULE_BUILTIN:
		return "builtin";
	case KMOD_MODULE_LIVE:
		return "live";
	case KMOD_MODULE_COMING:
		return "coming";
	case KMOD_MODULE_GOING:
		return "going";
	default:
		return NULL;
	}
}

/**
 * kmod_module_get_initstate:
 * @mod: kmod module
 *
 * Get the initstate of this @mod, as returned by Linux Kernel, by reading
 * /sys filesystem.
 *
 * Returns: < 0 on error or module state if module is found in kernel, valid states are
 * KMOD_MODULE_BUILTIN: module is builtin;
 * KMOD_MODULE_LIVE: module is live in kernel;
 * KMOD_MODULE_COMING: module is being loaded;
 * KMOD_MODULE_GOING: module is being unloaded.
 */
KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
{
	char path[PATH_MAX], buf[32];
	int fd, err, pathlen;

	if (mod == NULL)
		return -ENOENT;

	/* remove const: this can only change internal state */
	if (kmod_module_is_builtin((struct kmod_module *)mod))
		return KMOD_MODULE_BUILTIN;

	pathlen = snprintf(path, sizeof(path),
				"/sys/module/%s/initstate", mod->name);
	fd = open(path, O_RDONLY|O_CLOEXEC);
	if (fd < 0) {
		err = -errno;

		DBG(mod->ctx, "could not open '%s': %s\n",
			path, strerror(-err));

		if (pathlen > (int)sizeof("/initstate") - 1) {
			struct stat st;
			path[pathlen - (sizeof("/initstate") - 1)] = '\0';
			if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
				return KMOD_MODULE_COMING;
		}

		DBG(mod->ctx, "could not open '%s': %s\n",
			path, strerror(-err));
		return err;
	}

	err = read_str_safe(fd, buf, sizeof(buf));
	close(fd);
	if (err < 0) {
		ERR(mod->ctx, "could not read from '%s': %s\n",
			path, strerror(-err));
		return err;
	}

	if (streq(buf, "live\n"))
		return KMOD_MODULE_LIVE;
	else if (streq(buf, "coming\n"))
		return KMOD_MODULE_COMING;
	else if (streq(buf, "going\n"))
		return KMOD_MODULE_GOING;

	ERR(mod->ctx, "unknown %s: '%s'\n", path, buf);
	return -EINVAL;
}

/**
 * kmod_module_get_size:
 * @mod: kmod module
 *
 * Get the size of this kmod module as returned by Linux kernel. If supported,
 * the size is read from the coresize attribute in /sys/module. For older
 * kernels, this falls back on /proc/modules and searches for the specified
 * module to get its size.
 *
 * Returns: the size of this kmod module.
 */
KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
{
	FILE *fp;
	char line[4096];
	int lineno = 0;
	long size = -ENOENT;
	int dfd, cfd;

	if (mod == NULL)
		return -ENOENT;

	/* try to open the module dir in /sys. If this fails, don't
	 * bother trying to find the size as we know the module isn't
	 * loaded.
	 */
	snprintf(line, sizeof(line), "/sys/module/%s", mod->name);
	dfd = open(line, O_RDONLY|O_CLOEXEC);
	if (dfd < 0)
		return -errno;

	/* available as of linux 3.3.x */
	cfd = openat(dfd, "coresize", O_RDONLY|O_CLOEXEC);
	if (cfd >= 0) {
		if (read_str_long(cfd, &size, 10) < 0)
			ERR(mod->ctx, "failed to read coresize from %s\n", line);
		close(cfd);
		goto done;
	}

	/* fall back on parsing /proc/modules */
	fp = fopen("/proc/modules", "re");
	if (fp == NULL) {
		int err = -errno;
		ERR(mod->ctx,
		    "could not open /proc/modules: %s\n", strerror(errno));
		close(dfd);
		return err;
	}

	while (fgets(line, sizeof(line), fp)) {
		size_t len = strlen(line);
		char *saveptr, *endptr, *tok = strtok_r(line, " \t", &saveptr);
		long value;

		lineno++;
		if (tok == NULL || !streq(tok, mod->name))
			goto eat_line;

		tok = strtok_r(NULL, " \t", &saveptr);
		if (tok == NULL) {
			ERR(mod->ctx,
			"invalid line format at /proc/modules:%d\n", lineno);
			break;
		}

		value = strtol(tok, &endptr, 10);
		if (endptr == tok || *endptr != '\0') {
			ERR(mod->ctx,
			"invalid line format at /proc/modules:%d\n", lineno);
			break;
		}

		size = value;
		break;
eat_line:
		while (line[len - 1] != '\n' && fgets(line, sizeof(line), fp))
			len = strlen(line);
	}
	fclose(fp);

done:
	close(dfd);
	return size;
}

/**
 * kmod_module_get_refcnt:
 * @mod: kmod module
 *
 * Get the ref count of this @mod, as returned by Linux Kernel, by reading
 * /sys filesystem.
 *
 * Returns: the reference count on success or < 0 on failure.
 */
KMOD_EXPORT int kmod_module_get_refcnt(const struct kmod_module *mod)
{
	char path[PATH_MAX];
	long refcnt;
	int fd, err;

	if (mod == NULL)
		return -ENOENT;

	snprintf(path, sizeof(path), "/sys/module/%s/refcnt", mod->name);
	fd = open(path, O_RDONLY|O_CLOEXEC);
	if (fd < 0) {
		err = -errno;
		DBG(mod->ctx, "could not open '%s': %s\n",
			path, strerror(errno));
		return err;
	}

	err = read_str_long(fd, &refcnt, 10);
	close(fd);
	if (err < 0) {
		ERR(mod->ctx, "could not read integer from '%s': '%s'\n",
			path, strerror(-err));
		return err;
	}

	return (int)refcnt;
}

/**
 * kmod_module_get_holders:
 * @mod: kmod module
 *
 * Get a list of kmod modules that are holding this @mod, as returned by Linux
 * Kernel. After use, free the @list by calling kmod_module_unref_list().
 *
 * Returns: a new list of kmod modules on success or NULL on failure.
 */
KMOD_EXPORT struct kmod_list *kmod_module_get_holders(const struct kmod_module *mod)
{
	char dname[PATH_MAX];
	struct kmod_list *list = NULL;
	struct dirent *dent;
	DIR *d;

	if (mod == NULL || mod->ctx == NULL)
		return NULL;

	snprintf(dname, sizeof(dname), "/sys/module/%s/holders", mod->name);

	d = opendir(dname);
	if (d == NULL) {
		ERR(mod->ctx, "could not open '%s': %s\n",
						dname, strerror(errno));
		return NULL;
	}

	for (dent = readdir(d); dent != NULL; dent = readdir(d)) {
		struct kmod_module *holder;
		struct kmod_list *l;
		int err;

		if (dent->d_name[0] == '.') {
			if (dent->d_name[1] == '\0' ||
			    (dent->d_name[1] == '.' && dent->d_name[2] == '\0'))
				continue;
		}

		err = kmod_module_new_from_name(mod->ctx, dent->d_name,
						&holder);
		if (err < 0) {
			ERR(mod->ctx, "could not create module for '%s': %s\n",
				dent->d_name, strerror(-err));
			goto fail;
		}

		l = kmod_list_append(list, holder);
		if (l != NULL) {
			list = l;
		} else {
			ERR(mod->ctx, "out of memory\n");
			kmod_module_unref(holder);
			goto fail;
		}
	}

	closedir(d);
	return list;

fail:
	closedir(d);
	kmod_module_unref_list(list);
	return NULL;
}

struct kmod_module_section {
	unsigned long address;
	char name[];
};

static void kmod_module_section_free(struct kmod_module_section *section)
{
	free(section);
}

/**
 * kmod_module_get_sections:
 * @mod: kmod module
 *
 * Get a list of kmod sections of this @mod, as returned by Linux Kernel. The
 * structure contained in this list is internal to libkmod and their fields
 * can be obtained by calling kmod_module_section_get_name() and
 * kmod_module_section_get_address().
 *
 * After use, free the @list by calling kmod_module_section_free_list().
 *
 * Returns: a new list of kmod module sections on success or NULL on failure.
 */
KMOD_EXPORT struct kmod_list *kmod_module_get_sections(const struct kmod_module *mod)
{
	char dname[PATH_MAX];
	struct kmod_list *list = NULL;
	struct dirent *dent;
	DIR *d;
	int dfd;

	if (mod == NULL)
		return NULL;

	snprintf(dname, sizeof(dname), "/sys/module/%s/sections", mod->name);

	d = opendir(dname);
	if (d == NULL) {
		ERR(mod->ctx, "could not open '%s': %s\n",
			dname, strerror(errno));
		return NULL;
	}

	dfd = dirfd(d);

	for (dent = readdir(d); dent; dent = readdir(d)) {
		struct kmod_module_section *section;
		struct kmod_list *l;
		unsigned long address;
		size_t namesz;
		int fd, err;

		if (dent->d_name[0] == '.') {
			if (dent->d_name[1] == '\0' ||
			    (dent->d_name[1] == '.' && dent->d_name[2] == '\0'))
				continue;
		}

		fd = openat(dfd, dent->d_name, O_RDONLY|O_CLOEXEC);
		if (fd < 0) {
			ERR(mod->ctx, "could not open '%s/%s': %m\n",
							dname, dent->d_name);
			goto fail;
		}

		err = read_str_ulong(fd, &address, 16);
		close(fd);
		if (err < 0) {
			ERR(mod->ctx, "could not read long from '%s/%s': %m\n",
							dname, dent->d_name);
			goto fail;
		}

		namesz = strlen(dent->d_name) + 1;
		section = malloc(sizeof(*section) + namesz);

		if (section == NULL) {
			ERR(mod->ctx, "out of memory\n");
			goto fail;
		}

		section->address = address;
		memcpy(section->name, dent->d_name, namesz);

		l = kmod_list_append(list, section);
		if (l != NULL) {
			list = l;
		} else {
			ERR(mod->ctx, "out of memory\n");
			free(section);
			goto fail;
		}
	}

	closedir(d);
	return list;

fail:
	closedir(d);
	kmod_module_unref_list(list);
	return NULL;
}

/**
 * kmod_module_section_get_module_name:
 * @entry: a list entry representing a kmod module section
 *
 * Get the name of a kmod module section.
 *
 * After use, free the @list by calling kmod_module_section_free_list().
 *
 * Returns: the name of this kmod module section on success or NULL on
 * failure. The string is owned by the section, do not free it.
 */
KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)
{
	struct kmod_module_section *section;

	if (entry == NULL)
		return NULL;

	section = entry->data;
	return section->name;
}

/**
 * kmod_module_section_get_address:
 * @entry: a list entry representing a kmod module section
 *
 * Get the address of a kmod module section.
 *
 * After use, free the @list by calling kmod_module_section_free_list().
 *
 * Returns: the address of this kmod module section on success or ULONG_MAX
 * on failure.
 */
KMOD_EXPORT unsigned long kmod_module_section_get_address(const struct kmod_list *entry)
{
	struct kmod_module_section *section;

	if (entry == NULL)
		return (unsigned long)-1;

	section = entry->data;
	return section->address;
}

/**
 * kmod_module_section_free_list:
 * @list: kmod module section list
 *
 * Release the resources taken by @list
 */
KMOD_EXPORT void kmod_module_section_free_list(struct kmod_list *list)
{
	while (list) {
		kmod_module_section_free(list->data);
		list = kmod_list_remove(list);
	}
}

static struct kmod_elf *kmod_module_get_elf(const struct kmod_module *mod)
{
	if (mod->file == NULL) {
		const char *path = kmod_module_get_path(mod);

		if (path == NULL) {
			errno = ENOENT;
			return NULL;
		}

		((struct kmod_module *)mod)->file = kmod_file_open(mod->ctx,
									path);
		if (mod->file == NULL)
			return NULL;
	}

	return kmod_file_get_elf(mod->file);
}

struct kmod_module_info {
	char *key;
	char value[];
};

static struct kmod_module_info *kmod_module_info_new(const char *key, size_t keylen, const char *value, size_t valuelen)
{
	struct kmod_module_info *info;

	info = malloc(sizeof(struct kmod_module_info) + keylen + valuelen + 2);
	if (info == NULL)
		return NULL;

	info->key = (char *)info + sizeof(struct kmod_module_info)
		    + valuelen + 1;
	memcpy(info->key, key, keylen);
	info->key[keylen] = '\0';
	memcpy(info->value, value, valuelen);
	info->value[valuelen] = '\0';
	return info;
}

static void kmod_module_info_free(struct kmod_module_info *info)
{
	free(info);
}

static struct kmod_list *kmod_module_info_append(struct kmod_list **list, const char *key, size_t keylen, const char *value, size_t valuelen)
{
	struct kmod_module_info *info;
	struct kmod_list *n;

	info = kmod_module_info_new(key, keylen, value, valuelen);
	if (info == NULL)
		return NULL;
	n = kmod_list_append(*list, info);
	if (n != NULL)
		*list = n;
	else
		kmod_module_info_free(info);
	return n;
}

static char *kmod_module_hex_to_str(const char *hex, size_t len)
{
	char *str;
	int i;
	int j;
	const size_t line_limit = 20;
	size_t str_len;

	str_len = len * 3; /* XX: or XX\0 */
	str_len += ((str_len + line_limit - 1) / line_limit - 1) * 3; /* \n\t\t */

	str = malloc(str_len);
	if (str == NULL)
		return NULL;

	for (i = 0, j = 0; i < (int)len; i++) {
		j += sprintf(str + j, "%02X", (unsigned char)hex[i]);
		if (i < (int)len - 1) {
			str[j++] = ':';

			if ((i + 1) % line_limit == 0)
				j += sprintf(str + j, "\n\t\t");
		}
	}
	return str;
}

static struct kmod_list *kmod_module_info_append_hex(struct kmod_list **list,
						     const char *key,
						     size_t keylen,
						     const char *value,
						     size_t valuelen)
{
	char *hex;
	struct kmod_list *n;

	if (valuelen > 0) {
		/* Display as 01:12:DE:AD:BE:EF:... */
		hex = kmod_module_hex_to_str(value, valuelen);
		if (hex == NULL)
			goto list_error;
		n = kmod_module_info_append(list, key, keylen, hex, strlen(hex));
		free(hex);
		if (n == NULL)
			goto list_error;
	} else {
		n = kmod_module_info_append(list, key, keylen, NULL, 0);
		if (n == NULL)
			goto list_error;
	}

	return n;

list_error:
	return NULL;
}

/**
 * kmod_module_get_info:
 * @mod: kmod module
 * @list: where to return list of module information. Use
 *        kmod_module_info_get_key() and
 *        kmod_module_info_get_value(). Release this list with
 *        kmod_module_info_free_list()
 *
 * Get a list of entries in ELF section ".modinfo", these contain
 * alias, license, depends, vermagic and other keys with respective
 * values. If the module is signed (CONFIG_MODULE_SIG), information
 * about the module signature is included as well: signer,
 * sig_key and sig_hashalgo.
 *
 * After use, free the @list by calling kmod_module_info_free_list().
 *
 * Returns: number of entries in @list on success or < 0 otherwise.
 */
KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
{
	struct kmod_elf *elf;
	char **strings;
	int i, count, ret = -ENOMEM;
	struct kmod_signature_info sig_info = {};

	if (mod == NULL || list == NULL)
		return -ENOENT;

	assert(*list == NULL);

	/* remove const: this can only change internal state */
	if (kmod_module_is_builtin((struct kmod_module *)mod)) {
		count = kmod_builtin_get_modinfo(mod->ctx,
						kmod_module_get_name(mod),
						&strings);
		if (count < 0)
			return count;
	} else {
		elf = kmod_module_get_elf(mod);
		if (elf == NULL)
			return -errno;

		count = kmod_elf_get_strings(elf, ".modinfo", &strings);
		if (count < 0)
			return count;
	}

	for (i = 0; i < count; i++) {
		struct kmod_list *n;
		const char *key, *value;
		size_t keylen, valuelen;

		key = strings[i];
		value = strchr(key, '=');
		if (value == NULL) {
			keylen = strlen(key);
			valuelen = 0;
			value = key;
		} else {
			keylen = value - key;
			value++;
			valuelen = strlen(value);
		}

		n = kmod_module_info_append(list, key, keylen, value, valuelen);
		if (n == NULL)
			goto list_error;
	}

	if (mod->file && kmod_module_signature_info(mod->file, &sig_info)) {
		struct kmod_list *n;

		n = kmod_module_info_append(list, "sig_id", strlen("sig_id"),
				sig_info.id_type, strlen(sig_info.id_type));
		if (n == NULL)
			goto list_error;
		count++;

		n = kmod_module_info_append(list, "signer", strlen("signer"),
				sig_info.signer, sig_info.signer_len);
		if (n == NULL)
			goto list_error;
		count++;


		n = kmod_module_info_append_hex(list, "sig_key", strlen("sig_key"),
						sig_info.key_id,
						sig_info.key_id_len);
		if (n == NULL)
			goto list_error;
		count++;

		n = kmod_module_info_append(list,
				"sig_hashalgo", strlen("sig_hashalgo"),
				sig_info.hash_algo, strlen(sig_info.hash_algo));
		if (n == NULL)
			goto list_error;
		count++;

		/*
		 * Omit sig_info.algo for now, as these
		 * are currently constant.
		 */
		n = kmod_module_info_append_hex(list, "signature",
						strlen("signature"),
						sig_info.sig,
						sig_info.sig_len);

		if (n == NULL)
			goto list_error;
		count++;

	}
	ret = count;

list_error:
	/* aux structures freed in normal case also */
	kmod_module_signature_info_free(&sig_info);

	if (ret < 0) {
		kmod_module_info_free_list(*list);
		*list = NULL;
	}
	free(strings);
	return ret;
}

/**
 * kmod_module_info_get_key:
 * @entry: a list entry representing a kmod module info
 *
 * Get the key of a kmod module info.
 *
 * Returns: the key of this kmod module info on success or NULL on
 * failure. The string is owned by the info, do not free it.
 */
KMOD_EXPORT const char *kmod_module_info_get_key(const struct kmod_list *entry)
{
	struct kmod_module_info *info;

	if (entry == NULL)
		return NULL;

	info = entry->data;
	return info->key;
}

/**
 * kmod_module_info_get_value:
 * @entry: a list entry representing a kmod module info
 *
 * Get the value of a kmod module info.
 *
 * Returns: the value of this kmod module info on success or NULL on
 * failure. The string is owned by the info, do not free it.
 */
KMOD_EXPORT const char *kmod_module_info_get_value(const struct kmod_list *entry)
{
	struct kmod_module_info *info;

	if (entry == NULL)
		return NULL;

	info = entry->data;
	return info->value;
}

/**
 * kmod_module_info_free_list:
 * @list: kmod module info list
 *
 * Release the resources taken by @list
 */
KMOD_EXPORT void kmod_module_info_free_list(struct kmod_list *list)
{
	while (list) {
		kmod_module_info_free(list->data);
		list = kmod_list_remove(list);
	}
}

struct kmod_module_version {
	uint64_t crc;
	char symbol[];
};

static struct kmod_module_version *kmod_module_versions_new(uint64_t crc, const char *symbol)
{
	struct kmod_module_version *mv;
	size_t symbollen = strlen(symbol) + 1;

	mv = malloc(sizeof(struct kmod_module_version) + symbollen);
	if (mv == NULL)
		return NULL;

	mv->crc = crc;
	memcpy(mv->symbol, symbol, symbollen);
	return mv;
}

static void kmod_module_version_free(struct kmod_module_version *version)
{
	free(version);
}

/**
 * kmod_module_get_versions:
 * @mod: kmod module
 * @list: where to return list of module versions. Use
 *        kmod_module_version_get_symbol() and
 *        kmod_module_version_get_crc(). Release this list with
 *        kmod_module_versions_free_list()
 *
 * Get a list of entries in ELF section "__versions".
 *
 * After use, free the @list by calling kmod_module_versions_free_list().
 *
 * Returns: 0 on success or < 0 otherwise.
 */
KMOD_EXPORT int kmod_module_get_versions(const struct kmod_module *mod, struct kmod_list **list)
{
	struct kmod_elf *elf;
	struct kmod_modversion *versions;
	int i, count, ret = 0;

	if (mod == NULL || list == NULL)
		return -ENOENT;

	assert(*list == NULL);

	elf = kmod_module_get_elf(mod);
	if (elf == NULL)
		return -errno;

	count = kmod_elf_get_modversions(elf, &versions);
	if (count < 0)
		return count;

	for (i = 0; i < count; i++) {
		struct kmod_module_version *mv;
		struct kmod_list *n;

		mv = kmod_module_versions_new(versions[i].crc, versions[i].symbol);
		if (mv == NULL) {
			ret = -errno;
			kmod_module_versions_free_list(*list);
			*list = NULL;
			goto list_error;
		}

		n = kmod_list_append(*list, mv);
		if (n != NULL)
			*list = n;
		else {
			kmod_module_version_free(mv);
			kmod_module_versions_free_list(*list);
			*list = NULL;
			ret = -ENOMEM;
			goto list_error;
		}
	}
	ret = count;

list_error:
	free(versions);
	return ret;
}

/**
 * kmod_module_version_get_symbol:
 * @entry: a list entry representing a kmod module versions
 *
 * Get the symbol of a kmod module versions.
 *
 * Returns: the symbol of this kmod module versions on success or NULL
 * on failure. The string is owned by the versions, do not free it.
 */
KMOD_EXPORT const char *kmod_module_version_get_symbol(const struct kmod_list *entry)
{
	struct kmod_module_version *version;

	if (entry == NULL || entry->data == NULL)
		return NULL;

	version = entry->data;
	return version->symbol;
}

/**
 * kmod_module_version_get_crc:
 * @entry: a list entry representing a kmod module version
 *
 * Get the crc of a kmod module version.
 *
 * Returns: the crc of this kmod module version if available, otherwise default to 0.
 */
KMOD_EXPORT uint64_t kmod_module_version_get_crc(const struct kmod_list *entry)
{
	struct kmod_module_version *version;

	if (entry == NULL || entry->data == NULL)
		return 0;

	version = entry->data;
	return version->crc;
}

/**
 * kmod_module_versions_free_list:
 * @list: kmod module versions list
 *
 * Release the resources taken by @list
 */
KMOD_EXPORT void kmod_module_versions_free_list(struct kmod_list *list)
{
	while (list) {
		kmod_module_version_free(list->data);
		list = kmod_list_remove(list);
	}
}

struct kmod_module_symbol {
	uint64_t crc;
	char symbol[];
};

static struct kmod_module_symbol *kmod_module_symbols_new(uint64_t crc, const char *symbol)
{
	struct kmod_module_symbol *mv;
	size_t symbollen = strlen(symbol) + 1;

	mv = malloc(sizeof(struct kmod_module_symbol) + symbollen);
	if (mv == NULL)
		return NULL;

	mv->crc = crc;
	memcpy(mv->symbol, symbol, symbollen);
	return mv;
}

static void kmod_module_symbol_free(struct kmod_module_symbol *symbol)
{
	free(symbol);
}

/**
 * kmod_module_get_symbols:
 * @mod: kmod module
 * @list: where to return list of module symbols. Use
 *        kmod_module_symbol_get_symbol() and
 *        kmod_module_symbol_get_crc(). Release this list with
 *        kmod_module_symbols_free_list()
 *
 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
 *
 * After use, free the @list by calling kmod_module_symbols_free_list().
 *
 * Returns: 0 on success or < 0 otherwise.
 */
KMOD_EXPORT int kmod_module_get_symbols(const struct kmod_module *mod, struct kmod_list **list)
{
	struct kmod_elf *elf;
	struct kmod_modversion *symbols;
	int i, count, ret = 0;

	if (mod == NULL || list == NULL)
		return -ENOENT;

	assert(*list == NULL);

	elf = kmod_module_get_elf(mod);
	if (elf == NULL)
		return -errno;

	count = kmod_elf_get_symbols(elf, &symbols);
	if (count < 0)
		return count;

	for (i = 0; i < count; i++) {
		struct kmod_module_symbol *mv;
		struct kmod_list *n;

		mv = kmod_module_symbols_new(symbols[i].crc, symbols[i].symbol);
		if (mv == NULL) {
			ret = -errno;
			kmod_module_symbols_free_list(*list);
			*list = NULL;
			goto list_error;
		}

		n = kmod_list_append(*list, mv);
		if (n != NULL)
			*list = n;
		else {
			kmod_module_symbol_free(mv);
			kmod_module_symbols_free_list(*list);
			*list = NULL;
			ret = -ENOMEM;
			goto list_error;
		}
	}
	ret = count;

list_error:
	free(symbols);
	return ret;
}

/**
 * kmod_module_symbol_get_symbol:
 * @entry: a list entry representing a kmod module symbols
 *
 * Get the symbol of a kmod module symbols.
 *
 * Returns: the symbol of this kmod module symbols on success or NULL
 * on failure. The string is owned by the symbols, do not free it.
 */
KMOD_EXPORT const char *kmod_module_symbol_get_symbol(const struct kmod_list *entry)
{
	struct kmod_module_symbol *symbol;

	if (entry == NULL || entry->data == NULL)
		return NULL;

	symbol = entry->data;
	return symbol->symbol;
}

/**
 * kmod_module_symbol_get_crc:
 * @entry: a list entry representing a kmod module symbol
 *
 * Get the crc of a kmod module symbol.
 *
 * Returns: the crc of this kmod module symbol if available, otherwise default to 0.
 */
KMOD_EXPORT uint64_t kmod_module_symbol_get_crc(const struct kmod_list *entry)
{
	struct kmod_module_symbol *symbol;

	if (entry == NULL || entry->data == NULL)
		return 0;

	symbol = entry->data;
	return symbol->crc;
}

/**
 * kmod_module_symbols_free_list:
 * @list: kmod module symbols list
 *
 * Release the resources taken by @list
 */
KMOD_EXPORT void kmod_module_symbols_free_list(struct kmod_list *list)
{
	while (list) {
		kmod_module_symbol_free(list->data);
		list = kmod_list_remove(list);
	}
}

struct kmod_module_dependency_symbol {
	uint64_t crc;
	uint8_t bind;
	char symbol[];
};

static struct kmod_module_dependency_symbol *kmod_module_dependency_symbols_new(uint64_t crc, uint8_t bind, const char *symbol)
{
	struct kmod_module_dependency_symbol *mv;
	size_t symbollen = strlen(symbol) + 1;

	mv = malloc(sizeof(struct kmod_module_dependency_symbol) + symbollen);
	if (mv == NULL)
		return NULL;

	mv->crc = crc;
	mv->bind = bind;
	memcpy(mv->symbol, symbol, symbollen);
	return mv;
}

static void kmod_module_dependency_symbol_free(struct kmod_module_dependency_symbol *dependency_symbol)
{
	free(dependency_symbol);
}

/**
 * kmod_module_get_dependency_symbols:
 * @mod: kmod module
 * @list: where to return list of module dependency_symbols. Use
 *        kmod_module_dependency_symbol_get_symbol() and
 *        kmod_module_dependency_symbol_get_crc(). Release this list with
 *        kmod_module_dependency_symbols_free_list()
 *
 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
 *
 * After use, free the @list by calling
 * kmod_module_dependency_symbols_free_list().
 *
 * Returns: 0 on success or < 0 otherwise.
 */
KMOD_EXPORT int kmod_module_get_dependency_symbols(const struct kmod_module *mod, struct kmod_list **list)
{
	struct kmod_elf *elf;
	struct kmod_modversion *symbols;
	int i, count, ret = 0;

	if (mod == NULL || list == NULL)
		return -ENOENT;

	assert(*list == NULL);

	elf = kmod_module_get_elf(mod);
	if (elf == NULL)
		return -errno;

	count = kmod_elf_get_dependency_symbols(elf, &symbols);
	if (count < 0)
		return count;

	for (i = 0; i < count; i++) {
		struct kmod_module_dependency_symbol *mv;
		struct kmod_list *n;

		mv = kmod_module_dependency_symbols_new(symbols[i].crc,
							symbols[i].bind,
							symbols[i].symbol);
		if (mv == NULL) {
			ret = -errno;
			kmod_module_dependency_symbols_free_list(*list);
			*list = NULL;
			goto list_error;
		}

		n = kmod_list_append(*list, mv);
		if (n != NULL)
			*list = n;
		else {
			kmod_module_dependency_symbol_free(mv);
			kmod_module_dependency_symbols_free_list(*list);
			*list = NULL;
			ret = -ENOMEM;
			goto list_error;
		}
	}
	ret = count;

list_error:
	free(symbols);
	return ret;
}

/**
 * kmod_module_dependency_symbol_get_symbol:
 * @entry: a list entry representing a kmod module dependency_symbols
 *
 * Get the dependency symbol of a kmod module
 *
 * Returns: the symbol of this kmod module dependency_symbols on success or NULL
 * on failure. The string is owned by the dependency_symbols, do not free it.
 */
KMOD_EXPORT const char *kmod_module_dependency_symbol_get_symbol(const struct kmod_list *entry)
{
	struct kmod_module_dependency_symbol *dependency_symbol;

	if (entry == NULL || entry->data == NULL)
		return NULL;

	dependency_symbol = entry->data;
	return dependency_symbol->symbol;
}

/**
 * kmod_module_dependency_symbol_get_crc:
 * @entry: a list entry representing a kmod module dependency_symbol
 *
 * Get the crc of a kmod module dependency_symbol.
 *
 * Returns: the crc of this kmod module dependency_symbol if available, otherwise default to 0.
 */
KMOD_EXPORT uint64_t kmod_module_dependency_symbol_get_crc(const struct kmod_list *entry)
{
	struct kmod_module_dependency_symbol *dependency_symbol;

	if (entry == NULL || entry->data == NULL)
		return 0;

	dependency_symbol = entry->data;
	return dependency_symbol->crc;
}

/**
 * kmod_module_dependency_symbol_get_bind:
 * @entry: a list entry representing a kmod module dependency_symbol
 *
 * Get the bind type of a kmod module dependency_symbol.
 *
 * Returns: the bind of this kmod module dependency_symbol on success
 * or < 0 on failure.
 */
KMOD_EXPORT int kmod_module_dependency_symbol_get_bind(const struct kmod_list *entry)
{
	struct kmod_module_dependency_symbol *dependency_symbol;

	if (entry == NULL || entry->data == NULL)
		return 0;

	dependency_symbol = entry->data;
	return dependency_symbol->bind;
}

/**
 * kmod_module_dependency_symbols_free_list:
 * @list: kmod module dependency_symbols list
 *
 * Release the resources taken by @list
 */
KMOD_EXPORT void kmod_module_dependency_symbols_free_list(struct kmod_list *list)
{
	while (list) {
		kmod_module_dependency_symbol_free(list->data);
		list = kmod_list_remove(list);
	}
}

/**
 * kmod_module_get_builtin:
 * @ctx: kmod library context
 * @list: where to save the builtin module list
 *
 * Returns: 0 on success or < 0 otherwise.
 */
int kmod_module_get_builtin(struct kmod_ctx *ctx, struct kmod_list **list)
{
	struct kmod_builtin_iter *iter;
	int err = 0;

	iter = kmod_builtin_iter_new(ctx);
	if (!iter)
		return -errno;

	while (kmod_builtin_iter_next(iter)) {
		struct kmod_module *mod = NULL;
		char modname[PATH_MAX];

		if (!kmod_builtin_iter_get_modname(iter, modname)) {
			err = -errno;
			goto fail;
		}

		err = kmod_module_new_from_name(ctx, modname, &mod);
		if (err < 0)
			goto fail;

		kmod_module_set_builtin(mod, true);

		*list = kmod_list_append(*list, mod);
	}

	kmod_builtin_iter_free(iter);
	return err;
fail:
	kmod_builtin_iter_free(iter);
	kmod_module_unref_list(*list);
	*list = NULL;
	return err;
}
