From 55e547eb6fad0d3ced00a62f04160016d90baabe Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Mon, 26 May 2008 12:01:49 +0000 Subject: - add simple first-draft unoptimized depmod just to proove Vladimir Dronnikov wrong text data bss dec hex filename 569 0 0 569 239 modutils/depmod.o --- modutils/Config.in | 6 +++ modutils/Kbuild | 1 + modutils/depmod.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 modutils/depmod.c (limited to 'modutils') diff --git a/modutils/Config.in b/modutils/Config.in index c5e596d1d..bffb521c4 100644 --- a/modutils/Config.in +++ b/modutils/Config.in @@ -5,6 +5,12 @@ menu "Linux Module Utilities" +config DEPMOD + bool "depmod" + default n + help + depmod generates modules.dep (FIXME: elaborate) + config INSMOD bool "insmod" default n diff --git a/modutils/Kbuild b/modutils/Kbuild index cff02b4f2..40ea0efbe 100644 --- a/modutils/Kbuild +++ b/modutils/Kbuild @@ -5,6 +5,7 @@ # Licensed under the GPL v2, see the file LICENSE in this tarball. lib-y:= +lib-$(CONFIG_DEPMOD) += depmod.o lib-$(CONFIG_INSMOD) += insmod.o lib-$(CONFIG_LSMOD) += lsmod.o lib-$(CONFIG_MODPROBE) += modprobe.o diff --git a/modutils/depmod.c b/modutils/depmod.c new file mode 100644 index 000000000..9131dc1ab --- /dev/null +++ b/modutils/depmod.c @@ -0,0 +1,116 @@ +/* vi: set sw=4 ts=4: */ +/* + * depmod - generate modules.dep + * Copyright (c) 2008 Bernhard Fischer + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#undef _GNU_SOURCE +#define _GNU_SOURCE +#include +#include /* uname() */ + +struct globals { + llist_t *lst; +}; +#define G (*(struct globals*)&bb_common_bufsiz1) +/* We have to zero it out because of NOEXEC */ +#define INIT_G() memset(&G, 0, sizeof(G)) + +static int fill_lst(const char *modulename, struct stat ATTRIBUTE_UNUSED *sb, + void ATTRIBUTE_UNUSED *data, int ATTRIBUTE_UNUSED depth) +{ + llist_add_to_end(&G.lst, strdup(modulename)); + return TRUE; +} + +static int fileAction(const char *fname, struct stat ATTRIBUTE_UNUSED *sb, + void *data, int ATTRIBUTE_UNUSED depth) +{ + size_t seen = 0; + size_t len = MAXINT(ssize_t); + void *the_module = xmalloc_open_read_close(fname, &len), *ptr = the_module; + const char *deps; + RESERVE_CONFIG_BUFFER(depends, 512); + RESERVE_CONFIG_BUFFER(buf1, 512); + + memset(buf1, 0, sizeof(buf1)); + memset(depends, 0, sizeof(depends)); + sprintf(buf1, "\n%s:", fname); + + if (last_char_is(fname, 'o') == NULL) /* not a module */ + goto done; + write((int)data, buf1, strlen(buf1)); +//bb_info_msg("[%d] fname='%s'", (int)data, fname); + do { + /* search for a 'd' */ + ptr = memchr(ptr, 'd', len - seen); + if (ptr == NULL) /* no d left, done */ + break; + if (sscanf(ptr, "depends=%s", depends) == 1) + break; + seen = ++ptr - the_module; + } while (1); +//bb_info_msg(" depends='%s'", depends); + deps = depends; + while (*deps) { + llist_t * _lst = G.lst; + ptr = memchr(deps, ',', strlen(deps)); + if (ptr != NULL) + *(char*)ptr = '\0'; + /* remember the length of the current dependency plus eventual 0 byte */ + len = strlen(deps) + (ptr != NULL); + sprintf(buf1, "/%s.", deps); /* make sure we match the correct file */ + while (_lst) { + ptr = strstr(_lst->data, buf1); + if (ptr != NULL) + break; /* found it */ + _lst = _lst->link; + } + if (_lst && _lst->data) { + const char separator = ' '; +//bb_info_msg("[%s] -> '%s'", deps, _lst->data); + write((int)data, &separator, 1); + write((int)data, _lst->data, strlen(_lst->data)); + + deps += len; + } + } +done: + RELEASE_CONFIG_BUFFER(depends); + RELEASE_CONFIG_BUFFER(buf1); + free(the_module); + return TRUE; +} + +int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int depmod_main(int ATTRIBUTE_UNUSED argc, char **argv) +{ + int retval = EXIT_SUCCESS; +// static const char moddir_base[] ALIGN1 = "/lib/modules/%s"; + + int fd = xopen3("/tmp/modules.dep", O_CREAT|O_WRONLY|O_TRUNC, + S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH); + argv++; + do { + if (!recursive_action(*argv, + ACTION_RECURSE, /* flags */ + fill_lst, /* file action */ + NULL, /* dir action */ + NULL, /* user data */ + 0) || /* depth */ + !recursive_action(*argv, + ACTION_RECURSE, /* flags */ + fileAction, /* file action */ + NULL, /* dir action */ + (void*)fd, /* user data */ + 0)) { /* depth */ + retval = EXIT_FAILURE; + } + } while (*++argv); + + if (ENABLE_FEATURE_CLEAN_UP) + close(fd); + return retval; +} -- cgit v1.2.3