blob: 4c8dc10a70982c282cea32cc1219c1494aaa1414 [file] [log] [blame]
Lucas De Marchi8900b912011-12-22 02:33:36 -02001/*
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>
Lucas De Marchibc854322011-12-23 02:56:27 -020023#include <getopt.h>
Lucas De Marchi8900b912011-12-22 02:33:36 -020024#include <string.h>
25#include <libkmod.h>
26#include "kmod.h"
27
Lucas De Marchibc854322011-12-23 02:56:27 -020028static const char options_s[] = "+hV";
29static const struct option options[] = {
30 { "help", no_argument, NULL, 'h' },
31 { "version", no_argument, NULL, 'V' },
32 {}
33};
34
Lucas De Marchi8900b912011-12-22 02:33:36 -020035static const struct kmod_cmd kmod_cmd_help;
36
37static const struct kmod_cmd *kmod_cmds[] = {
38 &kmod_cmd_help,
39};
40
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020041static const struct kmod_cmd *kmod_compat_cmds[] = {
42 &kmod_cmd_compat_lsmod,
Lucas De Marchif712ebc2011-12-22 03:39:11 -020043 &kmod_cmd_compat_rmmod,
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020044};
45
Lucas De Marchi8900b912011-12-22 02:33:36 -020046static int kmod_help(int argc, char *argv[])
47{
48 size_t i;
49
Lucas De Marchibc854322011-12-23 02:56:27 -020050 printf("Manage kernel modules: list, load, unload, etc\n"
51 "Usage:\n"
52 "\t%s [options] command [command_options]\n\n"
53 "Options:\n"
54 "\t-V, --version show version\n"
55 "\t-h, --help show this help\n\n"
56 "Commands:\n", basename(argv[0]));
Lucas De Marchi8900b912011-12-22 02:33:36 -020057
58 for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) {
59 if (kmod_cmds[i]->help != NULL) {
60 printf(" %-12s %s\n", kmod_cmds[i]->name,
61 kmod_cmds[i]->help);
62 }
63 }
64
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020065 puts("\nkmod also handles gracefully if called from following symlinks:");
66
67 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
68 if (kmod_compat_cmds[i]->help != NULL) {
69 printf(" %-12s %s\n", kmod_compat_cmds[i]->name,
70 kmod_compat_cmds[i]->help);
71 }
72 }
Lucas De Marchi35a29aa2011-12-22 19:21:11 -020073
Lucas De Marchi8900b912011-12-22 02:33:36 -020074 return EXIT_SUCCESS;
75}
76
77static const struct kmod_cmd kmod_cmd_help = {
78 .name = "help",
79 .cmd = kmod_help,
80 .help = "Show help message",
81};
82
Lucas De Marchi35a29aa2011-12-22 19:21:11 -020083static int handle_kmod_commands(int argc, char *argv[])
Lucas De Marchi8900b912011-12-22 02:33:36 -020084{
85 const char *cmd;
86 int err = 0;
87 size_t i;
88
Lucas De Marchibc854322011-12-23 02:56:27 -020089 for (;;) {
90 int c;
91
92 c = getopt_long(argc, argv, options_s, options, NULL);
93 if (c == -1)
94 break;
95
96 switch (c) {
97 case 'h':
98 kmod_help(argc, argv);
99 return EXIT_SUCCESS;
100 case 'V':
101 puts("kmod version " VERSION);
102 return EXIT_SUCCESS;
103 case '?':
104 return EXIT_FAILURE;
105 default:
106 fprintf(stderr, "Error: unexpected getopt_long() value '%c'.\n", c);
107 return EXIT_FAILURE;
108 }
109 }
110
111 if (optind >= argc) {
Lucas De Marchi8900b912011-12-22 02:33:36 -0200112 err = -ENOENT;
113 goto finish;
114 }
115
Lucas De Marchibc854322011-12-23 02:56:27 -0200116 cmd = argv[optind];
Lucas De Marchi8900b912011-12-22 02:33:36 -0200117
118 for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) {
119 if (strcmp(kmod_cmds[i]->name, cmd) != 0)
120 continue;
121
122 err = kmod_cmds[i]->cmd(--argc, ++argv);
123 }
124
125finish:
126 if (err < 0) {
127 fputs("missing or unknown command; "
128 "see 'kmod help' for a list of available commands\n", stderr);
129 }
130
131 return err;
132}
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200133
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200134
135static int handle_kmod_compat_commands(int argc, char *argv[])
136{
137 const char *cmd;
138 int err = -ENOENT;
139 size_t i;
140
141 cmd = basename(argv[0]);
142
143 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
144 if (strcmp(kmod_compat_cmds[i]->name, cmd) != 0)
145 continue;
146
147 err = kmod_compat_cmds[i]->cmd(argc, argv);
148 }
149
150 return err;
151}
152
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200153int main(int argc, char *argv[])
154{
155 const char *binname = basename(argv[0]);
156 int err;
157
158 if (strcmp(binname, "kmod") == 0)
159 err = handle_kmod_commands(argc, argv);
160 else
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200161 err = handle_kmod_compat_commands(argc, argv);
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200162
163 return err;
164}