man: fix typo
[platform/upstream/kmod.git] / tools / kmod.c
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 }