diff options
Diffstat (limited to 'modutils/modutils.c')
-rw-r--r-- | modutils/modutils.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/modutils/modutils.c b/modutils/modutils.c new file mode 100644 index 0000000..18ea537 --- /dev/null +++ b/modutils/modutils.c @@ -0,0 +1,141 @@ +/* + * Common modutils related functions for busybox + * + * Copyright (C) 2008 by Timo Teras <timo.teras@iki.fi> + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include "modutils.h" + +#ifdef __UCLIBC__ +extern int init_module(void *module, unsigned long len, const char *options); +extern int delete_module(const char *module, unsigned int flags); +#else +# include <sys/syscall.h> +# define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) +# define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) +#endif + +USE_FEATURE_2_4_MODULES(char *insmod_outputname); + +/* + a libbb candidate from ice age! +*/ +llist_t FAST_FUNC *llist_find(llist_t *first, const char *str) +{ + while (first != NULL) { + if (strcmp(first->data, str) == 0) + return first; + first = first->link; + } + return NULL; +} + +void FAST_FUNC replace(char *s, char what, char with) +{ + while (*s) { + if (what == *s) + *s = with; + ++s; + } +} + +char * FAST_FUNC replace_underscores(char *s) +{ + replace(s, '-', '_'); + return s; +} + +int FAST_FUNC string_to_llist(char *string, llist_t **llist, const char *delim) +{ + char *tok; + int len = 0; + + while ((tok = strsep(&string, delim)) != NULL) { + if (tok[0] == '\0') + continue; + llist_add_to_end(llist, xstrdup(tok)); + len += strlen(tok); + } + return len; +} + +char * FAST_FUNC filename2modname(const char *filename, char *modname) +{ + int i; + char *from; + + if (filename == NULL) + return NULL; + if (modname == NULL) + modname = xmalloc(MODULE_NAME_LEN); + from = bb_get_last_path_component_nostrip(filename); + for (i = 0; i < MODULE_NAME_LEN && from[i] != '\0' && from[i] != '.'; i++) + modname[i] = (from[i] == '-') ? '_' : from[i]; + modname[i] = 0; + + return modname; +} + +const char * FAST_FUNC moderror(int err) +{ + switch (err) { + case -1: + return "no such module"; + case ENOEXEC: + return "invalid module format"; + case ENOENT: + return "unknown symbol in module, or unknown parameter"; + case ESRCH: + return "module has wrong symbol version"; + case ENOSYS: + return "kernel does not support requested operation"; + default: + return strerror(err); + } +} + +char * FAST_FUNC parse_cmdline_module_options(char **argv) +{ + char *options; + int optlen; + + options = xzalloc(1); + optlen = 0; + while (*++argv) { + options = xrealloc(options, optlen + 2 + strlen(*argv) + 2); + /* Spaces handled by "" pairs, but no way of escaping quotes */ + optlen += sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv); + } + return options; +} + +int FAST_FUNC bb_init_module(const char *filename, const char *options) +{ + size_t len = MAXINT(ssize_t); + char *image; + int rc = ENOENT; + +#if ENABLE_FEATURE_2_4_MODULES + if (get_linux_version_code() < KERNEL_VERSION(2,6,0)) + return bb_init_module_24(filename, options); +#endif + + /* Use the 2.6 way */ + image = (char *) xmalloc_open_zipped_read_close(filename, &len); + if (image) { + if (init_module(image, len, options) != 0) + rc = errno; + else + rc = 0; + free(image); + } + + return rc; +} + +int FAST_FUNC bb_delete_module(const char *module, unsigned int flags) +{ + return delete_module(module, flags); +} |