/* * Common modutils related functions for busybox * * Copyright (C) 2008 by Timo Teras * * 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 # 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-1) && 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 = 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); }