lsmod.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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 void check_tainted(void) { putchar('\n'); }
  63. #endif
  64. int lsmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  65. int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  66. {
  67. #if ENABLE_FEATURE_LSMOD_PRETTY_2_6_OUTPUT
  68. char *token[4];
  69. parser_t *parser = config_open("/proc/modules");
  70. init_unicode();
  71. printf("%-24sSize Used by", "Module");
  72. check_tainted();
  73. if (ENABLE_FEATURE_2_4_MODULES
  74. && get_linux_version_code() < KERNEL_VERSION(2,6,0)
  75. ) {
  76. while (config_read(parser, token, 4, 3, "# \t", PARSE_NORMAL)) {
  77. if (token[3] != NULL && token[3][0] == '[') {
  78. token[3]++;
  79. token[3][strlen(token[3])-1] = '\0';
  80. } else
  81. token[3] = (char *) "";
  82. # if ENABLE_UNICODE_SUPPORT
  83. {
  84. uni_stat_t uni_stat;
  85. char *uni_name = unicode_conv_to_printable(&uni_stat, token[0]);
  86. unsigned pad_len = (uni_stat.unicode_width > 19) ? 0 : 19 - uni_stat.unicode_width;
  87. printf("%s%*s %8s %2s %s\n", uni_name, pad_len, "", token[1], token[2], token[3]);
  88. free(uni_name);
  89. }
  90. # else
  91. printf("%-19s %8s %2s %s\n", token[0], token[1], token[2], token[3]);
  92. # endif
  93. }
  94. } else {
  95. while (config_read(parser, token, 4, 4, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) {
  96. // N.B. token[3] is either '-' (module is not used by others)
  97. // or comma-separated list ended by comma
  98. // so trimming the trailing char is just what we need!
  99. if (token[3][0])
  100. token[3][strlen(token[3]) - 1] = '\0';
  101. # if ENABLE_UNICODE_SUPPORT
  102. {
  103. uni_stat_t uni_stat;
  104. char *uni_name = unicode_conv_to_printable(&uni_stat, token[0]);
  105. unsigned pad_len = (uni_stat.unicode_width > 19) ? 0 : 19 - uni_stat.unicode_width;
  106. printf("%s%*s %8s %2s %s\n", uni_name, pad_len, "", token[1], token[2], token[3]);
  107. free(uni_name);
  108. }
  109. # else
  110. printf("%-19s %8s %2s %s\n", token[0], token[1], token[2], token[3]);
  111. # endif
  112. }
  113. }
  114. if (ENABLE_FEATURE_CLEAN_UP)
  115. config_close(parser);
  116. #else
  117. check_tainted();
  118. xprint_and_close_file(xfopen_for_read("/proc/modules"));
  119. #endif
  120. return EXIT_SUCCESS;
  121. }