1 /* 2 * kmod - one tool to rule them all 3 * 4 * Copyright (C) 2011-2013 ProFUSION embedded systems 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include <errno.h> 21 #include <getopt.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include <shared/util.h> 27 28 #include <libkmod/libkmod.h> 29 30 #include "kmod.h" 31 32 static const char options_s[] = "+hV"; 33 static const struct option options[] = { 34 { "help", no_argument, NULL, 'h' }, 35 { "version", no_argument, NULL, 'V' }, 36 {} 37 }; 38 39 static const struct kmod_cmd kmod_cmd_help; 40 41 static const struct kmod_cmd *kmod_cmds[] = { 42 &kmod_cmd_help, 43 &kmod_cmd_list, 44 &kmod_cmd_static_nodes, 45 46 #ifdef ENABLE_EXPERIMENTAL 47 &kmod_cmd_insert, 48 &kmod_cmd_remove, 49 #endif 50 }; 51 52 static const struct kmod_cmd *kmod_compat_cmds[] = { 53 &kmod_cmd_compat_lsmod, 54 &kmod_cmd_compat_rmmod, 55 &kmod_cmd_compat_insmod, 56 &kmod_cmd_compat_modinfo, 57 &kmod_cmd_compat_modprobe, 58 &kmod_cmd_compat_depmod, 59 }; 60 61 static int kmod_help(int argc, char *argv[]) 62 { 63 size_t i; 64 65 printf("kmod - Manage kernel modules: list, load, unload, etc\n" 66 "Usage:\n" 67 "\t%s [options] command [command_options]\n\n" 68 "Options:\n" 69 "\t-V, --version show version\n" 70 "\t-h, --help show this help\n\n" 71 "Commands:\n", basename(argv[0])); 72 73 for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) { 74 if (kmod_cmds[i]->help != NULL) { 75 printf(" %-12s %s\n", kmod_cmds[i]->name, 76 kmod_cmds[i]->help); 77 } 78 } 79 80 puts("\nkmod also handles gracefully if called from following symlinks:"); 81 82 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) { 83 if (kmod_compat_cmds[i]->help != NULL) { 84 printf(" %-12s %s\n", kmod_compat_cmds[i]->name, 85 kmod_compat_cmds[i]->help); 86 } 87 } 88 89 return EXIT_SUCCESS; 90 } 91 92 static const struct kmod_cmd kmod_cmd_help = { 93 .name = "help", 94 .cmd = kmod_help, 95 .help = "Show help message", 96 }; 97 98 static int handle_kmod_commands(int argc, char *argv[]) 99 { 100 const char *cmd; 101 int err = 0; 102 size_t i; 103 104 for (;;) { 105 int c; 106 107 c = getopt_long(argc, argv, options_s, options, NULL); 108 if (c == -1) 109 break; 110 111 switch (c) { 112 case 'h': 113 kmod_help(argc, argv); 114 return EXIT_SUCCESS; 115 case 'V': 116 puts(PACKAGE " version " VERSION); 117 puts(KMOD_FEATURES); 118 return EXIT_SUCCESS; 119 case '?': 120 return EXIT_FAILURE; 121 default: 122 fprintf(stderr, "Error: unexpected getopt_long() value '%c'.\n", c); 123 return EXIT_FAILURE; 124 } 125 } 126 127 if (optind >= argc) { 128 fputs("missing command\n", stderr); 129 goto fail; 130 } 131 132 cmd = argv[optind]; 133 134 for (i = 0, err = -EINVAL; i < ARRAY_SIZE(kmod_cmds); i++) { 135 if (streq(kmod_cmds[i]->name, cmd)) { 136 err = kmod_cmds[i]->cmd(--argc, ++argv); 137 break; 138 } 139 } 140 141 if (err < 0) { 142 fprintf(stderr, "invalid command '%s'\n", cmd); 143 goto fail; 144 } 145 146 return err; 147 148 fail: 149 kmod_help(argc, argv); 150 return EXIT_FAILURE; 151 } 152 153 154 static int handle_kmod_compat_commands(int argc, char *argv[]) 155 { 156 const char *cmd; 157 size_t i; 158 159 cmd = basename(argv[0]); 160 161 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) { 162 if (streq(kmod_compat_cmds[i]->name, cmd)) 163 return kmod_compat_cmds[i]->cmd(argc, argv); 164 } 165 166 return -ENOENT; 167 } 168 169 int main(int argc, char *argv[]) 170 { 171 int err; 172 173 if (streq(program_invocation_short_name, "kmod")) 174 err = handle_kmod_commands(argc, argv); 175 else 176 err = handle_kmod_compat_commands(argc, argv); 177 178 return err; 179 } 180