]> git.ipfire.org Git - thirdparty/kmod.git/blob - tools/kmod.c
tools: kmod: Add handling of compat insmod
[thirdparty/kmod.git] / tools / kmod.c
1 /*
2 * kmod - one tool to rule them all
3 *
4 * Copyright (C) 2011 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 <stdio.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <getopt.h>
24 #include <string.h>
25 #include <libkmod.h>
26 #include "kmod.h"
27
28 static const char options_s[] = "+hV";
29 static const struct option options[] = {
30 { "help", no_argument, NULL, 'h' },
31 { "version", no_argument, NULL, 'V' },
32 {}
33 };
34
35 static const struct kmod_cmd kmod_cmd_help;
36
37 static const struct kmod_cmd *kmod_cmds[] = {
38 &kmod_cmd_help,
39 };
40
41 static const struct kmod_cmd *kmod_compat_cmds[] = {
42 &kmod_cmd_compat_lsmod,
43 &kmod_cmd_compat_rmmod,
44 &kmod_cmd_compat_insmod,
45 };
46
47 static int kmod_help(int argc, char *argv[])
48 {
49 size_t i;
50
51 printf("Manage kernel modules: list, load, unload, etc\n"
52 "Usage:\n"
53 "\t%s [options] command [command_options]\n\n"
54 "Options:\n"
55 "\t-V, --version show version\n"
56 "\t-h, --help show this help\n\n"
57 "Commands:\n", basename(argv[0]));
58
59 for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) {
60 if (kmod_cmds[i]->help != NULL) {
61 printf(" %-12s %s\n", kmod_cmds[i]->name,
62 kmod_cmds[i]->help);
63 }
64 }
65
66 puts("\nkmod also handles gracefully if called from following symlinks:");
67
68 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
69 if (kmod_compat_cmds[i]->help != NULL) {
70 printf(" %-12s %s\n", kmod_compat_cmds[i]->name,
71 kmod_compat_cmds[i]->help);
72 }
73 }
74
75 return EXIT_SUCCESS;
76 }
77
78 static const struct kmod_cmd kmod_cmd_help = {
79 .name = "help",
80 .cmd = kmod_help,
81 .help = "Show help message",
82 };
83
84 static int handle_kmod_commands(int argc, char *argv[])
85 {
86 const char *cmd;
87 int err = 0;
88 size_t i;
89
90 for (;;) {
91 int c;
92
93 c = getopt_long(argc, argv, options_s, options, NULL);
94 if (c == -1)
95 break;
96
97 switch (c) {
98 case 'h':
99 kmod_help(argc, argv);
100 return EXIT_SUCCESS;
101 case 'V':
102 puts("kmod version " VERSION);
103 return EXIT_SUCCESS;
104 case '?':
105 return EXIT_FAILURE;
106 default:
107 fprintf(stderr, "Error: unexpected getopt_long() value '%c'.\n", c);
108 return EXIT_FAILURE;
109 }
110 }
111
112 if (optind >= argc) {
113 err = -ENOENT;
114 goto finish;
115 }
116
117 cmd = argv[optind];
118
119 for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) {
120 if (strcmp(kmod_cmds[i]->name, cmd) != 0)
121 continue;
122
123 err = kmod_cmds[i]->cmd(--argc, ++argv);
124 }
125
126 finish:
127 if (err < 0) {
128 fputs("missing or unknown command; "
129 "see 'kmod help' for a list of available commands\n", stderr);
130 }
131
132 return err;
133 }
134
135
136 static int handle_kmod_compat_commands(int argc, char *argv[])
137 {
138 const char *cmd;
139 int err = -ENOENT;
140 size_t i;
141
142 cmd = basename(argv[0]);
143
144 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
145 if (strcmp(kmod_compat_cmds[i]->name, cmd) != 0)
146 continue;
147
148 err = kmod_compat_cmds[i]->cmd(argc, argv);
149 }
150
151 return err;
152 }
153
154 int main(int argc, char *argv[])
155 {
156 const char *binname = basename(argv[0]);
157 int err;
158
159 if (strcmp(binname, "kmod") == 0)
160 err = handle_kmod_commands(argc, argv);
161 else
162 err = handle_kmod_compat_commands(argc, argv);
163
164 return err;
165 }