modutils.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * Common modutils related functions for busybox
  3. *
  4. * Copyright (C) 2008 by Timo Teras <timo.teras@iki.fi>
  5. *
  6. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  7. */
  8. #include "modutils.h"
  9. #ifdef __UCLIBC__
  10. extern int init_module(void *module, unsigned long len, const char *options);
  11. extern int delete_module(const char *module, unsigned int flags);
  12. #else
  13. # include <sys/syscall.h>
  14. # define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
  15. # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
  16. #endif
  17. void FAST_FUNC replace(char *s, char what, char with)
  18. {
  19. while (*s) {
  20. if (what == *s)
  21. *s = with;
  22. ++s;
  23. }
  24. }
  25. char * FAST_FUNC replace_underscores(char *s)
  26. {
  27. replace(s, '-', '_');
  28. return s;
  29. }
  30. int FAST_FUNC string_to_llist(char *string, llist_t **llist, const char *delim)
  31. {
  32. char *tok;
  33. int len = 0;
  34. while ((tok = strsep(&string, delim)) != NULL) {
  35. if (tok[0] == '\0')
  36. continue;
  37. llist_add_to_end(llist, xstrdup(tok));
  38. len += strlen(tok);
  39. }
  40. return len;
  41. }
  42. char * FAST_FUNC filename2modname(const char *filename, char *modname)
  43. {
  44. int i;
  45. char *from;
  46. if (filename == NULL)
  47. return NULL;
  48. if (modname == NULL)
  49. modname = xmalloc(MODULE_NAME_LEN);
  50. from = bb_get_last_path_component_nostrip(filename);
  51. for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '\0' && from[i] != '.'; i++)
  52. modname[i] = (from[i] == '-') ? '_' : from[i];
  53. modname[i] = '\0';
  54. return modname;
  55. }
  56. const char * FAST_FUNC moderror(int err)
  57. {
  58. switch (err) {
  59. case -1:
  60. return "no such module";
  61. case ENOEXEC:
  62. return "invalid module format";
  63. case ENOENT:
  64. return "unknown symbol in module, or unknown parameter";
  65. case ESRCH:
  66. return "module has wrong symbol version";
  67. case ENOSYS:
  68. return "kernel does not support requested operation";
  69. default:
  70. return strerror(err);
  71. }
  72. }
  73. char * FAST_FUNC parse_cmdline_module_options(char **argv)
  74. {
  75. char *options;
  76. int optlen;
  77. options = xzalloc(1);
  78. optlen = 0;
  79. while (*++argv) {
  80. options = xrealloc(options, optlen + 2 + strlen(*argv) + 2);
  81. /* Spaces handled by "" pairs, but no way of escaping quotes */
  82. optlen += sprintf(options + optlen, (strchr(*argv, ' ') ? "\"%s\" " : "%s "), *argv);
  83. }
  84. return options;
  85. }
  86. int FAST_FUNC bb_init_module(const char *filename, const char *options)
  87. {
  88. size_t len;
  89. char *image;
  90. int rc;
  91. if (!options)
  92. options = "";
  93. #if ENABLE_FEATURE_2_4_MODULES
  94. if (get_linux_version_code() < KERNEL_VERSION(2,6,0))
  95. return bb_init_module_24(filename, options);
  96. #endif
  97. /* Use the 2.6 way */
  98. len = INT_MAX - 4095;
  99. rc = ENOENT;
  100. image = xmalloc_open_zipped_read_close(filename, &len);
  101. if (image) {
  102. rc = 0;
  103. if (init_module(image, len, options) != 0)
  104. rc = errno;
  105. free(image);
  106. }
  107. return rc;
  108. }
  109. int FAST_FUNC bb_delete_module(const char *module, unsigned int flags)
  110. {
  111. return delete_module(module, flags);
  112. }