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