diff options
Diffstat (limited to 'tools/kmod.c')
-rw-r--r-- | tools/kmod.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/tools/kmod.c b/tools/kmod.c new file mode 100644 index 0000000..55689c0 --- /dev/null +++ b/tools/kmod.c @@ -0,0 +1,179 @@ +/* + * kmod - one tool to rule them all + * + * Copyright (C) 2011-2013 ProFUSION embedded systems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <errno.h> +#include <getopt.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <shared/util.h> + +#include <libkmod/libkmod.h> + +#include "kmod.h" + +static const char options_s[] = "+hV"; +static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + {} +}; + +static const struct kmod_cmd kmod_cmd_help; + +static const struct kmod_cmd *kmod_cmds[] = { + &kmod_cmd_help, + &kmod_cmd_list, + &kmod_cmd_static_nodes, + +#ifdef ENABLE_EXPERIMENTAL + &kmod_cmd_insert, + &kmod_cmd_remove, +#endif +}; + +static const struct kmod_cmd *kmod_compat_cmds[] = { + &kmod_cmd_compat_lsmod, + &kmod_cmd_compat_rmmod, + &kmod_cmd_compat_insmod, + &kmod_cmd_compat_modinfo, + &kmod_cmd_compat_modprobe, + &kmod_cmd_compat_depmod, +}; + +static int kmod_help(int argc, char *argv[]) +{ + size_t i; + + printf("kmod - Manage kernel modules: list, load, unload, etc\n" + "Usage:\n" + "\t%s [options] command [command_options]\n\n" + "Options:\n" + "\t-V, --version show version\n" + "\t-h, --help show this help\n\n" + "Commands:\n", basename(argv[0])); + + for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) { + if (kmod_cmds[i]->help != NULL) { + printf(" %-12s %s\n", kmod_cmds[i]->name, + kmod_cmds[i]->help); + } + } + + puts("\nkmod also handles gracefully if called from following symlinks:"); + + for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) { + if (kmod_compat_cmds[i]->help != NULL) { + printf(" %-12s %s\n", kmod_compat_cmds[i]->name, + kmod_compat_cmds[i]->help); + } + } + + return EXIT_SUCCESS; +} + +static const struct kmod_cmd kmod_cmd_help = { + .name = "help", + .cmd = kmod_help, + .help = "Show help message", +}; + +static int handle_kmod_commands(int argc, char *argv[]) +{ + const char *cmd; + int err = 0; + size_t i; + + for (;;) { + int c; + + c = getopt_long(argc, argv, options_s, options, NULL); + if (c == -1) + break; + + switch (c) { + case 'h': + kmod_help(argc, argv); + return EXIT_SUCCESS; + case 'V': + puts(PACKAGE " version " VERSION); + puts(KMOD_FEATURES); + return EXIT_SUCCESS; + case '?': + return EXIT_FAILURE; + default: + fprintf(stderr, "Error: unexpected getopt_long() value '%c'.\n", c); + return EXIT_FAILURE; + } + } + + if (optind >= argc) { + fputs("missing command\n", stderr); + goto fail; + } + + cmd = argv[optind]; + + for (i = 0, err = -EINVAL; i < ARRAY_SIZE(kmod_cmds); i++) { + if (streq(kmod_cmds[i]->name, cmd)) { + err = kmod_cmds[i]->cmd(--argc, ++argv); + break; + } + } + + if (err < 0) { + fprintf(stderr, "invalid command '%s'\n", cmd); + goto fail; + } + + return err; + +fail: + kmod_help(argc, argv); + return EXIT_FAILURE; +} + + +static int handle_kmod_compat_commands(int argc, char *argv[]) +{ + const char *cmd; + size_t i; + + cmd = basename(argv[0]); + + for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) { + if (streq(kmod_compat_cmds[i]->name, cmd)) + return kmod_compat_cmds[i]->cmd(argc, argv); + } + + return -ENOENT; +} + +int main(int argc, char *argv[]) +{ + int err; + + if (streq(program_invocation_short_name, "kmod")) + err = handle_kmod_commands(argc, argv); + else + err = handle_kmod_compat_commands(argc, argv); + + return err; +} |