/*
 * depmod.c: generate module dependency meta-data (aliases, etc.)
 *
 * (C) 2002 Rusty Russell IBM Corporation
 * (C) 2006-2011 Jon Masters <jcm@jonmasters.org>, and others.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#define _GNU_SOURCE /* asprintf */

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <elf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/utsname.h>
#include <sys/mman.h>

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

#include "util.h"
#include "zlibsupport.h"
#include "depmod.h"
#include "logging.h"
#include "index.h"
#include "elfops.h"
#include "tables.h"
#include "config_filter.h"

#include "testing.h"

#ifndef MODULE_DIR
#define MODULE_DIR "/lib/modules/"
#endif

#ifndef MODULE_BUILTIN_KEY
#define MODULE_BUILTIN_KEY "built-in"
#endif

/* used to replace one module with another based on conf override entries */
struct module_overrides
{
	/* Next override */
	struct module_overrides *next;

	/* overridden module */
	char *modfile;
};

/* used to specify the order in which /lib/modules subdirs are searched */
struct module_search
{
	/* Next search */
	struct module_search *next;

	/* search path */
	char *search_path;
	size_t len;
};

static char sym_prefix; /* used for -P option */
static unsigned int skipchars; /* prefix target part of basedir to skip over */
static unsigned int make_map_files = 1; /* default to on */
static unsigned int force_map_files = 0; /* default to on */

#define SYMBOL_HASH_SIZE 1024
struct symbol
{
	struct symbol *next;
	struct module *owner;
	uint64_t ver;
	char name[0];
};

static struct symbol *symbolhash[SYMBOL_HASH_SIZE];

/**
 * tdb_hash - calculate hash entry for a symbol (algorithm from gdbm, via tdb)
 *
 * @name:	symbol name
 *
 */
static inline unsigned int tdb_hash(const char *name)
{
	unsigned value;	/* Used to compute the hash value.  */
	unsigned   i;	/* Used to cycle through random values. */

	/* Set the initial value from the key size. */
	for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
		value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));

	return (1103515243 * value + 12345);
}

/**
 * skip_symprefix - remove extraneous prefix character on some architectures
 *
 * @symname:	symbol name to process for prefix character removal
 *
 */
static const char *skip_symprefix(const char *symname)
{
	return symname + (symname[0] == sym_prefix ? 1 : 0);
}

/**
 * add_symbol - add a symbol to the symbol hash list
 *
 * @name:	symbol name
 * @ver:	symbol version (checksum)
 * @owner:	module owning this symbol
 *
 */
static void add_symbol(const char *name, uint64_t ver, struct module *owner)
{
	unsigned int hash;
	struct symbol *new = NOFAIL(malloc(sizeof *new + strlen(name) + 1));

	new->owner = owner;
	new->ver = ver;
	strcpy(new->name, name);

	hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
	new->next = symbolhash[hash];
	symbolhash[hash] = new;
}

static int print_unknown, check_symvers;

/**
 * find_symbol - lookup module owning a symbol in the symbol hash list
 *
 * @name:	symbol name
 * @ver:	symbol version
 * @modname:	pathname of module requesting lookup (being processed)
 * @weak:	whether the symbol is weakly defined or not
 *
 * This function is used during dependency calculation to match the
 * dependencies a module says it requires with symbols we have seen.
 * calculate_deps calls us after it has load_dep_syms on a module.
 *
 */
static struct module *find_symbol(const char *name, uint64_t ver,
		const char *modname, int weak)
{
	struct symbol *s;

	/* For our purposes, .foo matches foo.  PPC64 needs this. */
	if (name[0] == '.')
		name++;
	name = skip_symprefix(name);

	for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
		if (streq(s->name, name))
			break;
	}
	if (s) {
		if (ver && s->ver && s->ver != ver && print_unknown && !weak)
			warn("%s disagrees about version of symbol %s\n",
					modname, name);
		return s->owner;
	}

	if (print_unknown && !weak)
		warn("%s needs unknown symbol %s\n", modname, name);

	return NULL;
}

/**
 * add_dep - add a module dependency
 *
 * @mod:	module name
 * @depends_on:	new module dependency
 *
 */
static void add_dep(struct module *mod, struct module *depends_on)
{
	unsigned int i;

	for (i = 0; i < mod->num_deps; i++)
		if (mod->deps[i] == depends_on)
			return;

	mod->deps = NOFAIL(realloc(mod->deps, sizeof(mod->deps[0])*(mod->num_deps+1)));
	mod->deps[mod->num_deps++] = depends_on;
}

/**
 * add_fake_syms - symbols not explicitly otherwise provided
 *
 * The kernel provides a few dependencies within the module loader.
 *
 */
static void add_fake_syms(void)
{
	/* __this_module is magic inserted by kernel loader. */
	add_symbol("__this_module", 0, NULL);
	/* On S390, this is faked up too */
	add_symbol("_GLOBAL_OFFSET_TABLE_", 0, NULL);
}

/**
 * load_system_map - load list of symbols from the System.map
 *
 * @filename:	path to the System.map-like file
 *
 */
static void load_system_map(const char *filename)
{
	FILE *system_map;
	char line[10240];
	const char ksymstr[] = "__ksymtab_";
	const int ksymstr_len = strlen(ksymstr);

	system_map = fopen(filename, "r");
	if (!system_map)
		fatal("Could not open '%s': %s\n", filename, strerror(errno));

	/* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
	while (fgets(line, sizeof(line)-1, system_map)) {
		char *ptr;
		const char *cptr;

		/* Snip \n */
		ptr = strchr(line, '\n');
		if (ptr)
			*ptr = '\0';

		ptr = strchr(line, ' ');
		if (!ptr || !(ptr = strchr(ptr + 1, ' ')))
			continue;

		/* Skip the space before symbol name */
		cptr = skip_symprefix(ptr + 1);

		/* Covers gpl-only and normal symbols. */
		if (strstarts(cptr, ksymstr))
			add_symbol(cptr + ksymstr_len, 0, NULL);
	}

	fclose(system_map);
	add_fake_syms();
}

/**
 * load_module_symvers - load list of symbol versions from the module.symvers
 *
 * @filename:	path to the module.symvers-like file
 *
 */
static void load_module_symvers(const char *filename)
{
	FILE *module_symvers;
	char line[10240];

	module_symvers = fopen(filename, "r");
	if (!module_symvers)
		fatal("Could not open '%s': %s\n", filename, strerror(errno));

	/* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
	while (fgets(line, sizeof(line)-1, module_symvers)) {
		const char *ver, *sym, *where;

		ver = strtok(line, " \t");
		sym = strtok(NULL, " \t");
		where = strtok(NULL, " \t");
		if (!ver || !sym || !where)
			continue;

		if (streq(where, "vmlinux"))
			add_symbol(skip_symprefix(sym), strtoull(ver, NULL, 16), NULL);
	}

	fclose(module_symvers);
	add_fake_syms();
}

static const struct option options[] = { { "all", 0, NULL, 'a' },
				   { "quick", 0, NULL, 'A' },
				   { "basedir", 1, NULL, 'b' },
				   { "config", 1, NULL, 'C' },
				   { "symvers", 1, NULL, 'E' },
				   { "filesyms", 1, NULL, 'F' },
				   { "errsyms", 0, NULL, 'e' },
				   { "unresolved-error", 0, NULL, 'u' },
				   { "quiet", 0, NULL, 'q' },
				   { "root", 0, NULL, 'r' },
				   { "verbose", 0, NULL, 'v' },
				   { "show", 0, NULL, 'n' },
				   { "dry-run", 0, NULL, 'n' },
				   { "symbol-prefix", 0, NULL, 'P' },
				   { "help", 0, NULL, 'h' },
				   { "version", 0, NULL, 'V' },
				   { "warn", 0, NULL, 'w' },
				   { "map", 0, NULL, 'm' },
				   { NULL, 0, NULL, 0 } };

/**
 * is_version_number - is the option a kernel version or module name
 *
 * @version:	possible version number
 *
 */
static int is_version_number(const char *version)
{
	unsigned int dummy;

	return (sscanf(version, "%u.%u", &dummy, &dummy) == 2);
}

/**
 * old_module_version - is the kernel version too old for these tools
 *
 * @version:	version number
 *
 */
static int old_module_version(const char *version)
{
	/* Expect three part version (but won't fail it only two part). */
	unsigned int major, sub, minor;

	sscanf(version, "%u.%u.%u", &major, &sub, &minor);

	if (major > 2) return 0;
	if (major < 2) return 1;

	/* 2.x */
	if (sub > 5) return 0;
	if (sub < 5) return 1;

	/* 2.5.x */
	if (minor >= 48) return 0;
	return 1;
}

/**
 * print_usage - output a list of all possible options
 *
 * @name: not currently used
 *
 */
static void print_usage(const char *name)
{
	fprintf(stderr,
	"%s " VERSION " -- part of " PACKAGE "\n"
	"%s -[aA] [-n -e -v -q -V -r -u -w -m]\n"
	"      [-b basedirectory] [forced_version]\n"
	"depmod [-n -e -v -q -r -u -w] [-F kernelsyms] module1.ko module2.ko ...\n"
	"If no arguments (except options) are given, \"depmod -a\" is assumed\n"
	"\n"
	"depmod will output a dependancy list suitable for the modprobe utility.\n"
	"\n"
	"\n"
	"Options:\n"
	"\t-a, --all            Probe all modules\n"
	"\t-A, --quick          Only does the work if there's a new module\n"
	"\t-e, --errsyms        Report not supplied symbols\n"
	"\t-m, --map            Create the legacy map files\n"
	"\t-n, --show           Write the dependency file on stdout only\n"
	"\t-P, --symbol-prefix  Architecture symbol prefix\n"
	"\t-V, --version        Print the release version\n"
	"\t-v, --verbose        Enable verbose mode\n"
	"\t-w, --warn		Warn on duplicates\n"
	"\t-h, --help           Print this usage message\n"
	"\n"
	"The following options are useful for people managing distributions:\n"
	"\t-b basedirectory\n"
	"\t    --basedir basedirectory    Use an image of a module tree.\n"
	"\t-F kernelsyms\n"
	"\t    --filesyms kernelsyms      Use the file instead of the\n"
	"\t                               current kernel symbols.\n"
	"\t-E Module.symvers\n"
	"\t    --symvers Module.symvers   Use Module.symvers file to check\n"
	"\t                               symbol versions.\n",
	"depmod", "depmod");
}

/**
 * ends_in - check file extension
 *
 * @name:	filename
 * @ext:	extension to check
 *
 */
static int ends_in(const char *name, const char *ext)
{
	unsigned int namelen, extlen;

	/* Grab lengths */
	namelen = strlen(name);
	extlen = strlen(ext);

	if (namelen < extlen) return 0;

	if (streq(name + namelen - extlen, ext))
		return 1;
	return 0;
}

/**
 * grab_module - open module ELF file and load symbol data
 *
 * @dirname:	path prefix
 * @filename:	filename within path
 *
 */
static struct module *grab_module(const char *dirname, const char *filename)
{
	struct module *new;

	new = NOFAIL(malloc(sizeof(*new)
			    + strlen(dirname?:"") + 1 + strlen(filename) + 1));
	if (dirname)
		sprintf(new->pathname, "%s/%s", dirname, filename);
	else
		strcpy(new->pathname, filename);
	new->basename = my_basename(new->pathname);

	INIT_LIST_HEAD(&new->dep_list);
	new->order = INDEX_PRIORITY_MIN;

	new->file = grab_elf_file(new->pathname);
	if (!new->file) {
		warn("Can't read module %s: %s\n",
		     new->pathname, strerror(errno));
		free(new);
		return NULL;
	}
	return new;
}

/* We use this on-stack structure to track recursive calls to has_dep_loop */
struct module_traverse
{
	struct module_traverse *prev;
	struct module *mod;
};

/**
 * in_loop - determine if a module dependency loop exists
 *
 * @mod:	current module
 * @traverse:	on-stack structure created as module deps were processed
 *
 */
static int in_loop(struct module *mod, const struct module_traverse *traverse)
{
	const struct module_traverse *i;

	for (i = traverse; i; i = i->prev) {
		if (i->mod == mod)
			return 1;
	}
	return 0;
}

/**
 * report_loop - report (once) that a dependency loop exists for a module
 *
 * @mod:	module with dep loop
 * @traverse:	on-stack structure created as module deps were processed
 *
 */
static void report_loop(const struct module *mod,
			const struct module_traverse *traverse)
{
	const struct module_traverse *i;

	/* Check that start is least alphabetically.  eg.  a depends
	   on b depends on a will get reported for a, not b.  */
	for (i = traverse->prev; i->prev; i = i->prev) {
		if (strcmp(mod->pathname, i->mod->pathname) > 0)
			return;
	}

	/* Is start in the loop?  If not, don't report now. eg. a
	   depends on b which depends on c which depends on b.  Don't
	   report when generating depends for a. */
	if (mod != i->mod)
		return;

	warn("Loop detected: %s ", mod->pathname);
	for (i = traverse->prev; i->prev; i = i->prev)
		fprintf(stderr, "needs %s ", i->mod->basename);
	fprintf(stderr, "which needs %s again!\n", i->mod->basename);
}

/**
 * has_dep_loop - iterate over all module deps and check for loops
 *
 * @module:	module to process
 * @prev:	previously processed dependency
 *
 * This function is called recursively, following every dep and creating
 * a module_traverse on the stack describing each dependency encountered.
 * Determining a loop is as simple (and slow) as finding repetitions.
 *
 * This is slow, but we can't leave the user without any modules, so we
 * need to detect loops and just fail those modules that cause loops.
 *
 */
static int has_dep_loop(struct module *module, struct module_traverse *prev)
{
	unsigned int i;
	struct module_traverse traverse = { .prev = prev, .mod = module };

	if (in_loop(module, prev)) {
		report_loop(module, &traverse);
		return 1;
	}

	for (i = 0; i < module->num_deps; i++)
		if (has_dep_loop(module->deps[i], &traverse))
			return 1;
	return 0;
}

/**
 * order_dep_list - expand all module deps recursively and in order
 *
 * @start:	module being processed
 * @mod:	recursive dep
 *
 * We expand all of the dependencies of the dependencies of a module
 * and ensure that the lowest dependency is loaded first, etc.
 *
 */
static void order_dep_list(struct module *start, struct module *mod)
{
	unsigned int i;

	for (i = 0; i < mod->num_deps; i++) {
		/* If it was previously depended on, move it to the
		   tail.  ie. if a needs b and c, and c needs b, we
		   must order b after c. */
		list_del(&mod->deps[i]->dep_list);
		list_add_tail(&mod->deps[i]->dep_list, &start->dep_list);
		order_dep_list(start, mod->deps[i]);
	}
}

static struct module *deleted = NULL;

/**
 * del_module - remove from list of modules
 *
 * @modules:	list of modules
 * @delme:	module to remove
 *
 */
static void del_module(struct module **modules, struct module *delme)
{
	struct module **i;

	/* Find pointer to it. */ 
	if (modules) {
		for (i = modules; *i != delme; i = &(*i)->next);
		
		*i = delme->next;
	}
	
	/* Save on a list to quiet valgrind.
	   Can't free - other modules may depend on them */
	delme->next = deleted;
	deleted = delme;
}

/**
 * compress_path - strip out common path prefix for modules
 *
 * @path:	path to module
 * @basedir:	top level modules directory
 *
 * Modules are typically located in /lib/modules. There is no need to
 * store the same common path prefix for all modules - make paths
 * relative to directory that contains the dep information files.
 *
 */
static const char *compress_path(const char *path, const char *basedir)
{
	int len = strlen(basedir);

	if (strncmp(path, basedir, len) == 0)
		path += len + 1;
	return path;
}

/**
 * output_deps - create ascii text file representation of module deps
 *
 * @modules:	list of modules
 * @out:	output file
 * @dirname:	output directory
 *
 */
static int output_deps(struct module *modules,
			FILE *out, char *dirname)
{
	struct module *i;

	for (i = modules; i; i = i->next) {
		struct list_head *j, *tmp;
		order_dep_list(i, i);

		fprintf(out, "%s:", compress_path(i->pathname, dirname));
		list_for_each_safe(j, tmp, &i->dep_list) {
			struct module *dep
				= list_entry(j, struct module, dep_list);
			fprintf(out, " %s",
			        compress_path(dep->pathname, dirname));
			list_del_init(j);
		}
		fprintf(out, "\n");
	}
	return 1;
}

/* warn whenever duplicate module aliases, deps, or symbols are found. */
static int warn_dups = 0;

/**
 * output_deps_bin - create binary trie representation of module deps
 *
 * @modules:	list of modules
 * @out:	output binary file
 * @dirname:	output directory
 *
 * This optimized dependency file contains an ordered structure that is
 * more easily processed by modprobe in a time sensitive manner.
 *
 */
static int output_deps_bin(struct module *modules,
			FILE *out, char *dirname)
{
	struct module *i;
	struct index_node *index;
	char *line;
	char *p;

	index = index_create();

	for (i = modules; i; i = i->next) {
		struct list_head *j, *tmp;
		char modname[strlen(i->pathname)+1];
		
		order_dep_list(i, i);
		
		filename2modname(modname, i->pathname);
		nofail_asprintf(&line, "%s:",
		                compress_path(i->pathname, dirname));
		p = line;
		list_for_each_safe(j, tmp, &i->dep_list) {
			struct module *dep
				= list_entry(j, struct module, dep_list);
			nofail_asprintf(&line, "%s %s",
			                p,
			                compress_path(dep->pathname, dirname));
			free(p);
			p = line;
			list_del_init(j);
		}
		if (index_insert(index, modname, line, i->order) && warn_dups)
			warn("duplicate module deps:\n%s\n",line);
		free(line);
	}
	
	index_write(index, out);
	index_destroy(index);

	return 1;
}

/**
 * smells_like_module - detect common module extensions
 *
 * @name:	filename
 *
 */
static int smells_like_module(const char *name)
{
	return ends_in(name,".ko") || ends_in(name, ".ko.gz");
}

typedef struct module *(*do_module_t)(const char *dirname,
				      const char *filename,
				      struct module *next,
				      struct module_search *search,
				      struct module_overrides *overrides);

/**
 * is_higher_priority - find modules replacing other modules
 *
 * @newpath:	new module path
 * @oldpath:	old module path
 * @search:	path search order
 * @overrides:	module override directives
 *
 * Compares one module (path) to another module (path) and determines
 * whether the new module should replace the existing module of the
 * same name. Overriding is handled very coarsely for the moment.
 *
 */
static int is_higher_priority(const char *newpath, const char *oldpath,
			      struct module_search *search,
			      struct module_overrides *overrides)
{
	struct module_search *tmp;
	struct module_overrides *ovtmp;
	int i = 0;
	int prio_builtin = -1;
	int prio_new = -1;
	int prio_old = -1;

/* The names already match, now we check for overrides and directory search
 * order
 */
	for (ovtmp = overrides; ovtmp != NULL; ovtmp = ovtmp->next) {
		if (streq(ovtmp->modfile, newpath))
			return 1;
		if (streq(ovtmp->modfile, oldpath))
			return 0;
	}
	for (i = 0, tmp = search; tmp != NULL; tmp = tmp->next, i++) {
		if (streq(tmp->search_path, MODULE_BUILTIN_KEY))
			prio_builtin = i;
		else if (strncmp(tmp->search_path, newpath, tmp->len) == 0)
			prio_new = i;
		else if (strncmp(tmp->search_path, oldpath, tmp->len) == 0)
			prio_old = i;
	}
	if (prio_new < 0)
		prio_new = prio_builtin;
	if (prio_old < 0)
		prio_old = prio_builtin;

	return prio_new > prio_old;
}

/**
 * do_module - process a module file
 *
 * @dirname:	directory containing module
 * @filename:	module disk file
 * @list:	list of modules
 * @search:	path search order
 * @overrides:	module override directives
 *
 */
static struct module *do_module(const char *dirname,
				       const char *filename,
				       struct module *list,
				       struct module_search *search,
				       struct module_overrides *overrides)
{
	struct module *new, **i;

	new = grab_module(dirname, filename);
	if (!new)
		return list;

	/* Check if module is already in the list. */
	for (i = &list; *i; i = &(*i)->next) {

		if (streq((*i)->basename, filename)) {
			char newpath[strlen(dirname) + strlen("/")
				      + strlen(filename) + 1];

			sprintf(newpath, "%s/%s", dirname, filename);

			/* if module matches an existing entry (name) but */
			/* has a higher priority, replace existing entry. */
			if (is_higher_priority(newpath, (*i)->pathname,search,
					       overrides)) {
				del_module(i, *i);
				
				new->next = *i;
				*i = new;
			} else
				del_module(NULL, new);

			return list;
		}
	}

	/* Not in the list already. Just prepend. */
	new->next = list;
	return new;
}

/**
 * grab_dir - process a directory of modules
 *
 * @dirname:	directory name
 * @dir:	open directory reference
 * @do_mod:	do_module function to use
 * @search:	path search order
 * @overrides:	module overrides directives
 *
 */
static struct module *grab_dir(const char *dirname,
			       DIR *dir,
			       struct module *next,
			       do_module_t do_mod,
			       struct module_search *search,
			       struct module_overrides *overrides)
{
	struct dirent *dirent;

	while ((dirent = readdir(dir)) != NULL) {
		if (smells_like_module(dirent->d_name))
			next = do_mod(dirname, dirent->d_name, next,
				      search, overrides);
		else if (!streq(dirent->d_name, ".")
			 && !streq(dirent->d_name, "..")
			 && !streq(dirent->d_name, "source")
			 && !streq(dirent->d_name, "build")) {

			DIR *sub;
			char subdir[strlen(dirname) + 1
				   + strlen(dirent->d_name) + 1];
			sprintf(subdir, "%s/%s", dirname, dirent->d_name);
			sub = opendir(subdir);
			if (sub) {
				next = grab_dir(subdir, sub, next, do_mod,
						search, overrides);
				closedir(sub);
			}
		}
	}
	return next;
}

/**
 * grab_basedir - top-level module processing
 *
 * @dirname:	top-level directory name
 * @search:	path search order
 * @overrides:	module overrides directives
 *
 */
static struct module *grab_basedir(const char *dirname,
				   struct module_search *search,
				   struct module_overrides *overrides)
{
	DIR *dir;
	struct module *list;

	dir = opendir(dirname);
	if (!dir) {
		warn("Couldn't open directory %s: %s\n",
		     dirname, strerror(errno));
		return NULL;
	}
	list = grab_dir(dirname, dir, NULL, do_module, search, overrides);
	closedir(dir);

	return list;
}

/**
 * sort_modules - order modules in list on modules.order if available
 *
 * @dirname:	directory name
 * @list:	module list
 *
 * Using the modules.order file (if available), give every module an index
 * based on its position in the file, and order list based on the index. If
 * no ordering data is available, fallback to existing unordered list.
 *
 */
static struct module *sort_modules(const char *dirname, struct module *list)
{
	struct module *tlist = NULL, **tpos = &tlist;
	FILE *modorder;
	int dir_len = strlen(dirname) + 1;
	char file_name[dir_len + strlen("modules.order") + 1];
	char line[10240];
	unsigned int linenum = 0;

	sprintf(file_name, "%s/%s", dirname, "modules.order");

	modorder = fopen(file_name, "r");
	if (!modorder) {
		/* Older kernels don't generate modules.order.  Just
		   return if the file doesn't exist. */
		if (errno == ENOENT)
			return list;
		fatal("Could not open '%s': %s\n", file_name, strerror(errno));
	}

	sprintf(line, "%s/", dirname);

	/* move modules listed in modorder file to tlist in order */
	while (fgets(line, sizeof(line), modorder)) {
		struct module **pos, *mod;
		int len = strlen(line);

		linenum++;
		if (line[len - 1] == '\n')
			line[len - 1] = '\0';

		for (pos = &list; (mod = *pos); pos = &(*pos)->next) {
			if (streq(line, mod->pathname + dir_len)) {
				mod->order = linenum;
				*pos = mod->next;
				mod->next = NULL;
				*tpos = mod;
				tpos = &mod->next;
				break;
			}
		}
	}

	/* append the rest */
	*tpos = list;

	fclose(modorder);

	return tlist;
}

/**
 * calculate_deps - calculate deps for module
 *
 * @module:	module to process
 *
 */
static void calculate_deps(struct module *module)
{
	unsigned int i;
	struct string_table *symnames;
	struct string_table *symtypes;
	uint64_t *symvers = NULL;
	struct elf_file *file;

	module->num_deps = 0;
	module->deps = NULL;
	file = module->file;

	symnames = file->ops->load_dep_syms(file, &symtypes,
			check_symvers ? &symvers : NULL);
	if (!symnames || !symtypes)
		return;

	for (i = 0; i < symnames->cnt; i++) {
		const char *name;
		uint64_t ver;
		struct module *owner;
		int weak;

		name = symnames->str[i];
		ver = symvers ? symvers[i] : 0;
		weak = (*(symtypes->str[i]) == 'W');
		owner = find_symbol(name, ver, module->pathname, weak);
		if (owner) {
			info("%s needs \"%s\": %s\n",
			       module->pathname, name,
			       owner->pathname);
			add_dep(module, owner);
		}
	}

	free(symnames);
	free(symtypes);
	free(symvers);
}

/**
 * parse_modules - process the modules list
 *
 * @module:	module list
 *
 * Process each module in the (sorted by sort_modules) list for symbols,
 * dependencies, and other meta-data that will be output later.
 *
 */
static struct module *parse_modules(struct module *list)
{
	struct module *i;
	struct elf_file *file;
	struct string_table *syms;
	int j;

	for (i = list; i; i = i->next) {
		uint64_t *symvers = NULL;
		file = i->file;
		syms = file->ops->load_symbols(file,
				check_symvers ? &symvers : NULL);
		if (syms) {
			for (j = 0; j < syms->cnt; j++)
				add_symbol(skip_symprefix(syms->str[j]),
					symvers ? symvers[j] : 0, i);
			strtbl_free(syms);
		}
		free(symvers);
		file->ops->fetch_tables(file, &i->tables);
	}
	
	for (i = list; i; i = i->next)
		calculate_deps(i);
	
	/* Strip out modules with dependency loops. */
 again:
	for (i = list; i; i = i->next) {
		if (has_dep_loop(i, NULL)) {
			warn("Module %s ignored, due to loop\n",
			     i->pathname + skipchars);
			del_module(&list, i);
			goto again;
		}
	}
	
	return list;
}

/**
 * output_symbols - output symbol alias information
 *
 * @unused:	unused
 * @out:	output file reference
 * @dirname:	output directory
 *
 * Output the symbol hash table, in the form of symbol alias entries, to
 * an ascii text file of the form modules.symbols (depending on file).
 *
 */
static int output_symbols(struct module *unused, FILE *out, char *dirname)
{
	unsigned int i;

	fprintf(out, "# Aliases for symbols, used by symbol_request().\n");
	for (i = 0; i < SYMBOL_HASH_SIZE; i++) {
		struct symbol *s;

		for (s = symbolhash[i]; s; s = s->next) {
			if (s->owner) {
				char modname[strlen(s->owner->pathname)+1];
				filename2modname(modname, s->owner->pathname);
				fprintf(out, "alias symbol:%s %s\n",
					s->name, modname);
			}
		}
	}
	return 1;
}

/**
 * output_symbols_bin - output symbol alias information in binary format
 *
 * @unused:	unused
 * @out:	output file reference
 * @dirname:	output directory
 *
 * Output the symbol hash table, in the form of symbol alias entries, to
 * a trie ordered output file e.g. of the form modules.symbols.bin.
 *
 */
static int output_symbols_bin(struct module *unused, FILE *out, char *dirname)
{
	struct index_node *index;
	unsigned int i;
	char *alias;
	int duplicate;

	index = index_create();
	
	for (i = 0; i < SYMBOL_HASH_SIZE; i++) {
		struct symbol *s;

		for (s = symbolhash[i]; s; s = s->next) {
			if (s->owner) {
				char modname[strlen(s->owner->pathname)+1];
				filename2modname(modname, s->owner->pathname);
				nofail_asprintf(&alias, "symbol:%s", s->name);
				duplicate = index_insert(index, alias, modname,
							 s->owner->order);
				if (duplicate && warn_dups)
					warn("duplicate module syms:\n%s %s\n",
						alias, modname);
				free(alias);
			}
		}
	}
	
	index_write(index, out);
	index_destroy(index);

	return 1;
}

/**
 * output_builtin_bin - output list of built-in modules in binary format
 *
 * @unused:	unused
 * @out:	output file reference
 * @dirname:	output directory
 *
 */
static int output_builtin_bin(struct module *unused, FILE *out, char *dirname)
{
	struct index_node *index;
	char *textfile, *line;
	unsigned int linenum;
	FILE *f;

	nofail_asprintf(&textfile, "%s/modules.builtin", dirname);
	if (!(f = fopen(textfile, "r"))) {
		if (errno != ENOENT)
			fatal("Could not open '%s': %s\n",
					textfile, strerror(errno));
		free(textfile);
		return 0;
	}
	free(textfile);
	index = index_create();

	while ((line = getline_wrapped(f, &linenum)) != NULL) {
		char *module = line;

		if (!*line || *line == '#') {
			free(line);
			continue;
		}
		filename2modname(module, module);
		index_insert(index, module, "", 0);
		free(line);
	}
	fclose(f);
	index_write(index, out);
	index_destroy(index);

	return 1;
}

/**
 * output_aliases - output list of module aliases
 *
 * @modules:	list of modules
 * @out:	output file reference
 * @dirname:	output directory
 *
 */
static int output_aliases(struct module *modules, FILE *out, char *dirname)
{
	struct module *i;
	struct elf_file *file;
	struct string_table *tbl;
	int j;

	fprintf(out, "# Aliases extracted from modules themselves.\n");
	for (i = modules; i; i = i->next) {
		char modname[strlen(i->pathname)+1];

		file = i->file;
		filename2modname(modname, i->pathname);

		/* Grab from old-style .modalias section. */
		tbl = file->ops->load_strings(file, ".modalias", NULL);
		for (j = 0; tbl && j < tbl->cnt; j++)
			fprintf(out, "alias %s %s\n", tbl->str[j], modname);
		strtbl_free(tbl);

		/* Grab from new-style .modinfo section. */
		tbl = file->ops->load_strings(file, ".modinfo", NULL);
		for (j = 0; tbl && j < tbl->cnt; j++) {
			const char *p = tbl->str[j];
			if (strstarts(p, "alias="))
				fprintf(out, "alias %s %s\n",
					p + strlen("alias="), modname);
		}
		strtbl_free(tbl);
	}
	return 1;
}

/**
 * output_aliases_bin - output list of module aliases in binary format
 *
 * @modules:	list of modules
 * @out:	outout file reference
 * @dirname:	output directory
 *
 */
static int output_aliases_bin(struct module *modules, FILE *out, char *dirname)
{
	struct module *i;
	struct elf_file *file;
	struct string_table *tbl;
	int j;
	char *alias;
	struct index_node *index;
	int duplicate;

	index = index_create();
	
	for (i = modules; i; i = i->next) {
		char modname[strlen(i->pathname)+1];

		file = i->file;
		filename2modname(modname, i->pathname);

		/* Grab from old-style .modalias section. */
		tbl = file->ops->load_strings(file, ".modalias", NULL);
		for (j = 0; tbl && j < tbl->cnt; j++) {
			alias = NOFAIL(strdup(tbl->str[j]));
			underscores(alias);
			duplicate = index_insert(index, alias, modname, i->order);
			if (duplicate && warn_dups)
				warn("duplicate module alias:\n%s %s\n",
					alias, modname);
			free(alias);
		}
		strtbl_free(tbl);

		/* Grab from new-style .modinfo section. */
		tbl = file->ops->load_strings(file, ".modinfo", NULL);
		for (j = 0; tbl && j < tbl->cnt; j++) {
			const char *p = tbl->str[j];
			if (strstarts(p, "alias=")) {
				alias = NOFAIL(strdup(p + strlen("alias=")));
				underscores(alias);
				duplicate = index_insert(index, alias, modname, i->order);
				if (duplicate && warn_dups)
					warn("duplicate module alias:\n%s %s\n",
						alias, modname);
				free(alias);
			}
		}
		strtbl_free(tbl);
	}
	
	index_write(index, out);
	index_destroy(index);

	return 1;
}

/**
 * output_softdeps - output module softdeps (non-implicit dependencies)
 *
 * @modules:	list of modules
 * @out:	output file reference
 * @dirname:	output directory
 *
 */
static int output_softdeps(struct module *modules, FILE *out, char *dirname)
{
	struct module *i;
	struct elf_file *file;
	struct string_table *tbl;
	int j;

	fprintf(out, "# Soft dependencies extracted from modules themselves.\n");
	fprintf(out, "# Copy, with a .conf extension, to /etc/modprobe.d to use "
		"it with modprobe.\n");
	for (i = modules; i; i = i->next) {
		char modname[strlen(i->pathname)+1];

		file = i->file;
		filename2modname(modname, i->pathname);

		/* Grab from new-style .modinfo section. */
		tbl = file->ops->load_strings(file, ".modinfo", NULL);
		for (j = 0; tbl && j < tbl->cnt; j++) {
			const char *p = tbl->str[j];
			if (strstarts(p, "softdep="))
				fprintf(out, "softdep %s %s\n",
					modname, p + strlen("softdep="));
		}
		strtbl_free(tbl);
	}
	return 1;
}

/**
 * output_devname - output device names required by modules
 *
 * @modules:	list of modules
 * @out:	output file reference
 * @dirname:	output directory
 *
 */
static int output_devname(struct module *modules, FILE *out, char *dirname)
{
	struct module *m;

	fprintf(out, "# Device nodes to trigger on-demand module loading.\n");
	for (m = modules; m != NULL; m = m->next) {
		struct string_table *tbl;
		int i;
		char type = '\0';
		const char *devname = NULL;

		tbl = m->file->ops->load_strings(m->file, ".modinfo", NULL);
		for (i = 0; tbl && i < tbl->cnt; i++) {
			const char *p = tbl->str[i];
			unsigned int maj, min;

			if (sscanf(p, "alias=char-major-%u-%u", &maj, &min) == 2)
				type = 'c';
			else if (sscanf(p, "alias=block-major-%u-%u", &maj, &min) == 2)
				type = 'b';
			else if (strstarts(p, "alias=devname:"))
				devname = &p[strlen("alias=devname:")];

			if (type && devname) {
				char modname[strlen(m->pathname)+1];

				filename2modname(modname, m->pathname);
				fprintf(out, "%s %s %c%u:%u\n",
					modname, devname, type, maj, min);
				break;
			}
		}
		strtbl_free(tbl);
	}
	return 1;
}

struct depfile {
	const char *name;
	int (*func)(struct module *, FILE *, char *dirname);
	int map_file;
};

/* The possible output files - those with map_file unset typically not made */
static const struct depfile depfiles[] = {
	{ "modules.dep", output_deps, 0 }, /* This is what we check for '-A'. */
	{ "modules.dep.bin", output_deps_bin, 0 },
	{ "modules.pcimap", output_pci_table, 1 },
	{ "modules.usbmap", output_usb_table, 1 },
	{ "modules.ccwmap", output_ccw_table, 1 },
	{ "modules.ieee1394map", output_ieee1394_table, 1 },
	{ "modules.isapnpmap", output_isapnp_table, 1 },
	{ "modules.inputmap", output_input_table, 1 },
	{ "modules.ofmap", output_of_table, 1 },
	{ "modules.seriomap", output_serio_table, 1 },
	{ "modules.alias", output_aliases, 0 },
	{ "modules.alias.bin", output_aliases_bin, 0 },
	{ "modules.softdep", output_softdeps, 0 },
	{ "modules.symbols", output_symbols, 0 },
	{ "modules.symbols.bin", output_symbols_bin, 0 },
	{ "modules.builtin.bin", output_builtin_bin, 0 },
	{ "modules.devname", output_devname, 0 },
};

/**
 * any_modules_newer - determine if modules are newer than ref time
 *
 * @dirname:	directory to process
 * @mtime:	comparison time
 *
 * The worst case is that we process modules we didn't need to. It is
 * therefore safer to go with "true" if we can't figure it out.
 *
 */
static int any_modules_newer(const char *dirname, time_t mtime)
{
	DIR *dir;
	struct dirent *dirent;

	dir = opendir(dirname);
	if (!dir)
		return 1;

	while ((dirent = readdir(dir)) != NULL) {
		struct stat st;
		char file[strlen(dirname) + 1 + strlen(dirent->d_name) + 1];

		if (streq(dirent->d_name, ".") || streq(dirent->d_name, ".."))
			continue;

		sprintf(file, "%s/%s", dirname, dirent->d_name);
		if (lstat(file, &st) != 0)
			goto ret_true;

		if (smells_like_module(dirent->d_name)) {
			if (st.st_mtime > mtime)
				goto ret_true;
		} else if (S_ISDIR(st.st_mode)) {
			if (any_modules_newer(file, mtime))
				goto ret_true;
		}
	}
	closedir(dir);
	return 0;

ret_true:
	closedir(dir);
	return 1;
}

/**
 * depfile_out_of_date - check if module dep files are older than any modules
 *
 * @dirname:	directory to process
 *
 * Use any_modules_newer to determine if the dep files are up to date.
 *
 */
static int depfile_out_of_date(const char *dirname)
{
	struct stat st;
	char depfile[strlen(dirname) + 1 + strlen(depfiles[0].name) + 1];

	sprintf(depfile, "%s/%s", dirname, depfiles[0].name);

	if (stat(depfile, &st) != 0)
		return 1;

	return any_modules_newer(dirname, st.st_mtime);
}

/**
 * strsep_skipspace - skip over delimitors in strings
 *
 * @string:	string to process
 * @delim:	delimitor (e.g. ' ')
 *
 */
static char *strsep_skipspace(char **string, char *delim)
{
	if (!*string)
		return NULL;
	*string += strspn(*string, delim);
	return strsep(string, delim);
}

/**
 * add_search - add a new module search path
 *
 * @search_path:	path to search
 * @len:		length of path
 * @search:		list of search paths
 *
 */
static struct module_search *add_search(const char *search_path,
					size_t len,
					struct module_search *search)
{

	struct module_search *new;
	
	new = NOFAIL(malloc(sizeof(*new)));
	new->search_path = NOFAIL(strdup(search_path));
	new->len = len;
	new->next = search;

	return new;
	
}

/**
 * add_override - add a new module override entry
 *
 * @modfile:	name of module file
 * @overrides:	list of override entries
 *
 */
static struct module_overrides *add_override(const char *modfile,
					     struct module_overrides *overrides)
{

	struct module_overrides *new;
	
	new = NOFAIL(malloc(sizeof(*new)));
	new->modfile = NOFAIL(strdup(modfile));
	new->next = overrides;

	return new;
	
}

static int parse_config_scan(const char *filename,
			     const char *basedir,
			     const char *kernelversion,
			     struct module_search **search,
			     struct module_overrides **overrides);

/**
 * parse_config_file - process an individual configuration file
 *
 * @filename:		name of config file
 * @basedir:		module base directory
 * @kernelversion:	kernel version to process
 * @search:		search path order
 * @overrides:		module override entries
 *
 */
static int parse_config_file(const char *filename,
			     const char *basedir,
			     const char *kernelversion,
			     struct module_search **search,
			     struct module_overrides **overrides)
{
	char *line;
	unsigned int linenum = 0;
	FILE *cfile;

	cfile = fopen(filename, "r");
	if (!cfile) {
		if (errno != ENOENT)
			fatal("could not open '%s', reason: %s\n", filename,
			      strerror(errno));
		return 0;
	}

	while ((line = getline_wrapped(cfile, &linenum)) != NULL) {
		char *ptr = line;
		char *cmd, *modname;

		cmd = strsep_skipspace(&ptr, "\t ");

		if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0') {
			free(line);
			continue;
		}

		if (streq(cmd, "search")) {
			char *search_path;
			
			while ((search_path = strsep_skipspace(&ptr, "\t "))) {
				char *dirname;
				size_t len;

				if (strcmp(search_path,
						MODULE_BUILTIN_KEY) == 0) {
					*search = add_search(MODULE_BUILTIN_KEY,
							     0, *search);
					continue;
				}
				nofail_asprintf(&dirname, "%s%s%s/%s", basedir,
					MODULE_DIR, kernelversion, search_path);
				len = strlen(dirname);
				*search = add_search(dirname, len, *search);
				free(dirname);
			}
		} else if (streq(cmd, "override")) {
			char *pathname = NULL, *version, *subdir;
			modname = strsep_skipspace(&ptr, "\t ");
			version = strsep_skipspace(&ptr, "\t ");
			subdir = strsep_skipspace(&ptr, "\t ");

			if (!regex_match(kernelversion, (const char *)version))
				continue;

			nofail_asprintf(&pathname, "%s%s%s/%s/%s.ko", basedir,
				MODULE_DIR, kernelversion, subdir, modname);

			*overrides = add_override(pathname, *overrides);
			free(pathname);
		} else if (streq(cmd, "include")) {
			char *newfilename;

			newfilename = strsep_skipspace(&ptr, "\t ");
			if (!newfilename) {
				grammar(cmd, filename, linenum);
			} else {
				warn("\"include %s\" is deprecated, "
				     "please use /etc/depmod.d\n", newfilename);
				if (strstarts(newfilename, "/etc/depmod.d")) {
					warn("\"include /etc/depmod.d\" is "
					     "the default, ignored\n");
				} else {
					if (!parse_config_scan(newfilename, basedir,
							       kernelversion,
							       search, overrides))
					warn("Failed to open included"
					     " config file %s: %s\n",
					     newfilename, strerror(errno));
				}
			}
		} else if (streq(cmd, "make_map_files")) {
			char *option;

			option = strsep_skipspace(&ptr, "\t ");
			if (!option)
				grammar(cmd, filename, linenum);
			else {
				if (streq(option, "yes"))
					make_map_files = 1;
				else if (streq(option, "no"))
					make_map_files = 0;
				else
					grammar(cmd, filename, linenum);
			}
                } else
                        grammar(cmd, filename, linenum);

                free(line);
        }
        fclose(cfile);
        return 1;
}

/**
 * parse_config_scan - handle a directory of config files
 *
 * @filename:		name of directory
 * @basedir:		module base directory
 * @kernelversion:	kernel version to process
 * @search:		search path order
 * @overrides:		module override entries
 *
 */
static int parse_config_scan(const char *filename,
			     const char *basedir,
			     const char *kernelversion,
			     struct module_search **search,
			     struct module_overrides **overrides)
{
	DIR *dir;
	int ret = 0;

	dir = opendir(filename);
	if (dir) {
		struct file_entry {
			struct list_head node;
			char name[];
		};
		LIST_HEAD(files_list);
		struct file_entry *fe, *fe_tmp;
		struct dirent *i;

		/* sort files from directory into list */
		while ((i = readdir(dir)) != NULL) {
			size_t len;

			if (i->d_name[0] == '.')
				continue;
			if (!config_filter(i->d_name))
				continue;

			len = strlen(i->d_name);
			if (len < 6 || strcmp(&i->d_name[len-5], ".conf") != 0)
				warn("All config files need .conf: %s/%s, "
				     "it will be ignored in a future release.\n",
				     filename, i->d_name);
			fe = malloc(sizeof(struct file_entry) + len + 1);
			if (fe == NULL)
				continue;
			strcpy(fe->name, i->d_name);
			list_for_each_entry(fe_tmp, &files_list, node)
				if (strcmp(fe_tmp->name, fe->name) >= 0)
					break;
			list_add_tail(&fe->node, &fe_tmp->node);
		}
		closedir(dir);

		/* parse list of files */
		list_for_each_entry_safe(fe, fe_tmp, &files_list, node) {
			char *cfgfile;

			nofail_asprintf(&cfgfile, "%s/%s", filename, fe->name);
			if (!parse_config_file(cfgfile, basedir, kernelversion,
					       search, overrides))
				warn("Failed to open config file "
				     "%s: %s\n", fe->name, strerror(errno));
			free(cfgfile);
			list_del(&fe->node);
			free(fe);
		}

		ret = 1;
	} else {
		if (parse_config_file(filename, basedir, kernelversion, search,
				      overrides))
			ret = 1;
	}

	return ret;
}

/**
 * parse_toplevel_config - handle top-level depmod.conf, depmod.d
 *
 * @filename:		possibly overridden config
 * @basedir:		module base directory
 * @kernelversion:	kernel version to process
 * @search:		search path order
 * @overrides:		module override entries
 *
 */
static void parse_toplevel_config(const char *filename,
				  const char *basedir,
				  const char *kernelversion,
				  struct module_search **search,
				  struct module_overrides **overrides)
{
	if (filename) {
		if (!parse_config_scan(filename, basedir, kernelversion, search,
				 overrides))
			fatal("Failed to open config file %s: %s\n",
			      filename, strerror(errno));
		return;
	}

	/* deprecated config file */
	if (parse_config_file("/etc/depmod.conf", basedir, kernelversion,
			      search, overrides) > 0)
		warn("Deprecated config file /etc/depmod.conf, "
		      "all config files belong into /etc/depmod.d/.\n");

	/* default config */
	parse_config_scan("/etc/depmod.d", basedir, kernelversion,
			  search, overrides);
}

/* Local to main, but not freed on exit.  Keep valgrind quiet. */
static struct module *list = NULL;
static struct module_search *search = NULL;
static struct module_overrides *overrides = NULL;

int main(int argc, char *argv[])
{
	int opt, all = 0, maybe_all = 0, doing_stdout = 0;
	char *basedir = "", *dirname, *version;
	char *system_map = NULL, *module_symvers = NULL;
	int i;
	const char *config = NULL;

	if (native_endianness() == 0)
		abort();

	while ((opt = getopt_long(argc, argv, "aAb:C:E:F:euqrvnP:hVwm", options, NULL))
	       != -1) {
		switch (opt) {
		case 'a':
			all = 1;
			break;
		case 'A':
			maybe_all = 1;
			break;
		case 'b':
			basedir = optarg;
			skipchars = strlen(basedir);
			break;
		case 'C':
			config = optarg;
			break;
		case 'E':
			module_symvers = optarg;
			check_symvers = 1;
			break;
		case 'F':
			system_map = optarg;
			break;
		case 'e':
			print_unknown = 1;
			break;
		case 'u':
		case 'q':
		case 'r':
			break;
		case 'v':
			verbose = 1;
			break;
		case 'n':
			doing_stdout = 1;
			break;
		case 'P':
			if (optarg[1] != '\0')
				fatal("-P only takes a single char\n");
			sym_prefix = optarg[0];
			break;
		case 'h':
			print_usage(argv[0]);
			exit(0);
			break;
		case 'V':
			printf("%s %s\n", PACKAGE, VERSION);
			exit(0);
		case 'w':
			warn_dups = 1;
			break;
		case 'm':
			force_map_files = 1;
			break;
		default:
			print_usage(argv[0]);
			exit(1);
		}
	}

	if (module_symvers)
		load_module_symvers(module_symvers);
	else if (system_map)
		load_system_map(system_map);
	else if (print_unknown) {
		warn("-e needs -E or -F\n");
		print_unknown = 0;
	}

	/* They can specify the version naked on the command line */
	if (optind < argc && is_version_number(argv[optind])) {
		version = NOFAIL(strdup(argv[optind]));
		optind++;
	} else {
		struct utsname buf;
		uname(&buf);
		version = NOFAIL(strdup(buf.release));
	}

	/* Check for old version. */
	if (old_module_version(version)) {
		fprintf(stderr, "Kernel version %s requires old depmod\n",
			version);
		exit(2);
	}

	/* Depmod -a by default if no names. */
	if (optind == argc)
		all = 1;

	nofail_asprintf(&dirname, "%s%s%s", basedir, MODULE_DIR, version);

	if (maybe_all) {
		if (!doing_stdout && !depfile_out_of_date(dirname))
			exit(0);
		all = 1;
	}

	parse_toplevel_config(config, basedir, version, &search, &overrides);

	/* For backward compatibility add "updates" to the head of the search
	 * list here. But only if there was no "search" option specified.
	 */
	if (!search) {
		char *dirname;
		size_t len;

		nofail_asprintf(&dirname, "%s%s%s/updates", basedir,
				MODULE_DIR, version);
		len = strlen(dirname);
		search = add_search(dirname, len, search);
	}
	if (!all) {
		/* Do command line args. */
		for (opt = optind; opt < argc; opt++) {
			struct module *new;

			if (argv[opt][0] != '/')
				fatal("modules must be specified using absolute paths.\n"
					"\"%s\" is a relative path\n", argv[opt]);

			new = grab_module(NULL, argv[opt]);
			if (!new) {
				/* cmd-line specified modules must exist */
				fatal("grab_module() failed for module %s\n", argv[opt]);
			}
			new->next = list;
			list = new;
		}
	} else {
		list = grab_basedir(dirname,search,overrides);
	}
	list = sort_modules(dirname,list);
	list = parse_modules(list);

	for (i = 0; i < ARRAY_SIZE(depfiles); i++) {
		FILE *out;
		int res;
		const struct depfile *d = &depfiles[i];
		char depname[strlen(dirname) + 1 + strlen(d->name) + 1];
		char tmpname[strlen(dirname) + 1 + strlen(d->name) +
						strlen(".temp") + 1];

		if (d->map_file && !make_map_files && !force_map_files)
			continue;

		sprintf(depname, "%s/%s", dirname, d->name);
		sprintf(tmpname, "%s/%s.temp", dirname, d->name);
		if (!doing_stdout) {
			out = fopen(tmpname, "w");
			if (!out)
				fatal("Could not open %s for writing: %s\n",
					tmpname, strerror(errno));
		} else {
			out = stdout;
			if (ends_in(depname, ".bin"))
				continue;
		}
		res = d->func(list, out, dirname);
		if (doing_stdout)
			continue;
		fclose(out);
		if (res) {
			if (rename(tmpname, depname) < 0)
				fatal("Could not rename %s into %s: %s\n",
					tmpname, depname, strerror(errno));
		} else {
			if (unlink(tmpname) < 0)
				warn("Could not delete %s: %s\n",
					tmpname, strerror(errno));
		}
	}

	free(dirname);
	free(version);
	
	return 0;
}
