lsmod.c 3.8 KB

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