diff options
author | Bernhard Reutner-Fischer | 2008-05-26 12:01:49 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer | 2008-05-26 12:01:49 +0000 |
commit | 55e547eb6fad0d3ced00a62f04160016d90baabe (patch) | |
tree | ecfd0a9d9a662c807ecb881d8e683fc22e7d6d17 /modutils/depmod.c | |
parent | a0e17f7df6d4c65ecab7339e9899b294ff8bc04e (diff) | |
download | busybox-55e547eb6fad0d3ced00a62f04160016d90baabe.zip busybox-55e547eb6fad0d3ced00a62f04160016d90baabe.tar.gz |
- 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
Diffstat (limited to 'modutils/depmod.c')
-rw-r--r-- | modutils/depmod.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/modutils/depmod.c b/modutils/depmod.c new file mode 100644 index 0000000..9131dc1 --- /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 <libbb.h> +#include <sys/utsname.h> /* 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; +} |