Index: modutils/module-init-tools-3.0-pre10/depmod.c --- modutils~module-init-tools-updates/module-init-tools-3.0-pre10/depmod.c 2004-06-16 16:41:21.000000000 +0200 +++ modutils/module-init-tools-3.0-pre10/depmod.c 2004-06-17 22:49:08.095990640 +0200 @@ -495,6 +495,95 @@ return next; } +/* added by Thomas Vander Stichele + * go through all subdirs of dirname except "updates", + * then override modules with those from "updates" subtree */ +static struct module *grab_basedir(const char *dirname, struct module *next) +{ + DIR *dir; + struct dirent *dirent; + struct module *list = NULL; + struct module *updates = NULL; + struct module *u; + struct module *i; + char *pathname; + char *filename; + int have_updates = 0; + + dir = opendir(dirname); + if (!dir) { + warn("Couldn't open directory %s: %s\n", + dirname, strerror(errno)); + return next; + } + + while ((dirent = readdir(dir)) != NULL) { + struct stat statbuf; + + /* skip updates but mark that we have it */ + if (streq(dirent->d_name, "updates")) { + have_updates = 1; + continue; + } + /* skip ., .. */ + if (streq(dirent->d_name, ".") + || streq(dirent->d_name, "..")) + continue; + + pathname = NOFAIL(malloc(strlen(dirname) + 1 + strlen(dirent->d_name) + 1)); + + sprintf(pathname, "%s/%s", dirname, dirent->d_name); + if (lstat(pathname, &statbuf) != 0) { + warn("Couldn't lstat path %s: %s\n", + pathname, strerror(errno)); + free(pathname); + continue; + } + if (!S_ISDIR(statbuf.st_mode)) { + free(pathname); + continue; + } + list = grab_dir(pathname, list); + free(pathname); + } + if (!have_updates) + return list; + + /* since we have updates, grab a list of them, then remove + * all of the module entries from the previous list having + * the same file name */ + pathname = NOFAIL(malloc(strlen(dirname) + 1 + strlen("updates") + 1)); + sprintf(pathname, "%s/%s", dirname, "updates"); + updates = grab_dir(pathname, updates); + free(pathname); + for (u = updates; u; u = u->next) { + /* stop right at the slash, otherwise updating crc32c.ko + * will also delete libcrc32c.ko */ + filename = strrchr(u->pathname, '/'); + /* construct copied from other part of this file */ + /* could be optimized to do safe deletion instead */ + again: + for (i = list; i; i = i->next) { + char *s = i->pathname + strlen(i->pathname) - strlen(filename); + if (s < i->pathname) { + /* too short to compare, so not the same */ + continue; + } + if streq(filename, s) { + del_module(&list, i); + goto again; + } + } + } + /* chain the updates list to the original list */ + + /* use i->next as condition so we stop on the last one */ + for (i = list; i->next; i = i->next) + ; + i->next = updates; + return list; +} + /* Convert filename to the module name. Works if filename == modname, too. */ static void filename2modname(char *modname, const char *filename) { @@ -747,7 +836,7 @@ for (opt = optind + 1; opt < argc; opt++) list = grab_module("", argv[opt], list); } else { - list = grab_dir(dirname, list); + list = grab_basedir(dirname, list); } for (i = 0; i < sizeof(depfiles)/sizeof(depfiles[0]); i++) { Index: modutils/module-init-tools-3.0-pre10/modinfo.c --- modutils~module-init-tools-updates/module-init-tools-3.0-pre10/modinfo.c 2004-06-16 16:41:21.000000000 +0200 +++ modutils/module-init-tools-3.0-pre10/modinfo.c 2004-06-16 16:53:18.000000000 +0200 @@ -230,11 +230,17 @@ /* Search for it. */ uname(&buf); - asprintf(&dirname, "%s/%s", MODULE_DIR, buf.release); + /* first in updates */ + asprintf(&dirname, "%s/%s/updates", MODULE_DIR, buf.release); data = find_module(dirname, name, size); + free(dirname); + if (!data) { + asprintf(&dirname, "%s/%s", MODULE_DIR, buf.release); + data = find_module(dirname, name, size); + free(dirname); + } if (!data) fprintf(stderr, "modinfo: could not find module %s\n", name); - free(dirname); return data; }