lsmod.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Mini lsmod implementation for busybox
  4. *
  5. * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  6. * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
  7. *
  8. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  9. */
  10. //config:config LSMOD
  11. //config: bool "lsmod (1.9 kb)"
  12. //config: default y
  13. //config: help
  14. //config: lsmod is used to display a list of loaded modules.
  15. //config:
  16. //config:config FEATURE_LSMOD_PRETTY_2_6_OUTPUT
  17. //config: bool "Pretty output"
  18. //config: default y
  19. //config: depends on LSMOD && !MODPROBE_SMALL
  20. //config: help
  21. //config: This option makes output format of lsmod adjusted to
  22. //config: the format of module-init-tools for Linux kernel 2.6.
  23. //config: Increases size somewhat.
  24. //applet:IF_LSMOD(IF_NOT_MODPROBE_SMALL(APPLET_NOEXEC(lsmod, lsmod, BB_DIR_SBIN, BB_SUID_DROP, lsmod)))
  25. //kbuild:ifneq ($(CONFIG_MODPROBE_SMALL),y)
  26. //kbuild:lib-$(CONFIG_LSMOD) += lsmod.o modutils.o
  27. //kbuild:endif
  28. //usage:#if !ENABLE_MODPROBE_SMALL
  29. //usage:#define lsmod_trivial_usage
  30. //usage: ""
  31. //usage:#define lsmod_full_usage "\n\n"
  32. //usage: "List loaded kernel modules"
  33. //usage:#endif
  34. #include "libbb.h"
  35. #include "unicode.h"
  36. #if ENABLE_FEATURE_CHECK_TAINTED_MODULE
  37. enum {
  38. TAINT_PROPRIETORY_MODULE = (1 << 0),
  39. TAINT_FORCED_MODULE = (1 << 1),
  40. TAINT_UNSAFE_SMP = (1 << 2),
  41. };
  42. static void check_tainted(void)
  43. {
  44. int tainted = 0;
  45. char *buf = xmalloc_open_read_close("/proc/sys/kernel/tainted", NULL);
  46. if (buf) {
  47. tainted = atoi(buf);
  48. if (ENABLE_FEATURE_CLEAN_UP)
  49. free(buf);
  50. }
  51. if (tainted) {
  52. printf(" Tainted: %c%c%c\n",
  53. tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G',
  54. tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
  55. tainted & TAINT_UNSAFE_SMP ? 'S' : ' ');
  56. } else {
  57. puts(" Not tainted");
  58. }
  59. }
  60. #else
  61. static ALWAYS_INLINE void check_tainted(void)
  62. {
  63. putchar('\n');
  64. }
  65. #endif
  66. int lsmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  67. int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  68. {
  69. #if ENABLE_FEATURE_LSMOD_PRETTY_2_6_OUTPUT
  70. char *token[4];
  71. parser_t *parser = config_open("/proc/modules");
  72. init_unicode();
  73. printf("%-24sSize Used by", "Module");
  74. check_tainted();
  75. if (ENABLE_FEATURE_2_4_MODULES
  76. && get_linux_version_code() < KERNEL_VERSION(2,6,0)
  77. ) {
  78. while (config_read(parser, token, 4, 3, "# \t", PARSE_NORMAL)) {
  79. if (token[3] != NULL && token[3][0] == '[') {
  80. token[3]++;
  81. token[3][strlen(token[3])-1] = '\0';
  82. } else
  83. token[3] = (char *) "";
  84. # if ENABLE_UNICODE_SUPPORT
  85. {
  86. uni_stat_t uni_stat;
  87. char *uni_name = unicode_conv_to_printable(&uni_stat, token[0]);
  88. unsigned pad_len = (uni_stat.unicode_width > 19) ? 0 : 19 - uni_stat.unicode_width;
  89. printf("%s%*s %8s %2s %s\n", uni_name, pad_len, "", token[1], token[2], token[3]);
  90. free(uni_name);
  91. }
  92. # else
  93. printf("%-19s %8s %2s %s\n", token[0], token[1], token[2], token[3]);
  94. # endif
  95. }
  96. } else {
  97. while (config_read(parser, token, 4, 4, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) {
  98. // N.B. token[3] is either '-' (module is not used by others)
  99. // or comma-separated list ended by comma
  100. // so trimming the trailing char is just what we need!
  101. if (token[3][0])
  102. token[3][strlen(token[3]) - 1] = '\0';
  103. # if ENABLE_UNICODE_SUPPORT
  104. {
  105. uni_stat_t uni_stat;
  106. char *uni_name = unicode_conv_to_printable(&uni_stat, token[0]);
  107. unsigned pad_len = (uni_stat.unicode_width > 19) ? 0 : 19 - uni_stat.unicode_width;
  108. printf("%s%*s %8s %2s %s\n", uni_name, pad_len, "", token[1], token[2], token[3]);
  109. free(uni_name);
  110. }
  111. # else
  112. printf("%-19s %8s %2s %s\n", token[0], token[1], token[2], token[3]);
  113. # endif
  114. }
  115. }
  116. if (ENABLE_FEATURE_CLEAN_UP)
  117. config_close(parser);
  118. #else
  119. check_tainted();
  120. xprint_and_close_file(xfopen_for_read("/proc/modules"));
  121. #endif
  122. return EXIT_SUCCESS;
  123. }