blob: 557c2da4be2ee55e06c6979d8485a7b68f6c1531 [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,
Lucas De Marchi252c51a2011-12-23 11:33:02 -020039 &kmod_cmd_list,
Lucas De Marchi8900b912011-12-22 02:33:36 -020040};
41
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020042static const struct kmod_cmd *kmod_compat_cmds[] = {
43 &kmod_cmd_compat_lsmod,
Lucas De Marchif712ebc2011-12-22 03:39:11 -020044 &kmod_cmd_compat_rmmod,
Lucas De Marchiad602692011-12-22 03:45:07 -020045 &kmod_cmd_compat_insmod,
Lucas De Marchi769becb2011-12-22 03:50:54 -020046 &kmod_cmd_compat_modinfo,
Lucas De Marchifa29c0e2011-12-22 03:54:46 -020047 &kmod_cmd_compat_modprobe,
Lucas De Marchif6cf14c2011-12-27 19:56:33 -020048 &kmod_cmd_compat_depmod,
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020049};
50
Lucas De Marchi8900b912011-12-22 02:33:36 -020051static int kmod_help(int argc, char *argv[])
52{
53 size_t i;
54
Lucas De Marchia458e362011-12-23 11:35:48 -020055 printf("kmod - Manage kernel modules: list, load, unload, etc\n"
Lucas De Marchibc854322011-12-23 02:56:27 -020056 "Usage:\n"
57 "\t%s [options] command [command_options]\n\n"
58 "Options:\n"
59 "\t-V, --version show version\n"
60 "\t-h, --help show this help\n\n"
61 "Commands:\n", basename(argv[0]));
Lucas De Marchi8900b912011-12-22 02:33:36 -020062
63 for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) {
64 if (kmod_cmds[i]->help != NULL) {
65 printf(" %-12s %s\n", kmod_cmds[i]->name,
66 kmod_cmds[i]->help);
67 }
68 }
69
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020070 puts("\nkmod also handles gracefully if called from following symlinks:");
71
72 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
73 if (kmod_compat_cmds[i]->help != NULL) {
74 printf(" %-12s %s\n", kmod_compat_cmds[i]->name,
75 kmod_compat_cmds[i]->help);
76 }
77 }
Lucas De Marchi35a29aa2011-12-22 19:21:11 -020078
Lucas De Marchi8900b912011-12-22 02:33:36 -020079 return EXIT_SUCCESS;
80}
81
82static const struct kmod_cmd kmod_cmd_help = {
83 .name = "help",
84 .cmd = kmod_help,
85 .help = "Show help message",
86};
87
Lucas De Marchi35a29aa2011-12-22 19:21:11 -020088static int handle_kmod_commands(int argc, char *argv[])
Lucas De Marchi8900b912011-12-22 02:33:36 -020089{
90 const char *cmd;
91 int err = 0;
92 size_t i;
93
Lucas De Marchibc854322011-12-23 02:56:27 -020094 for (;;) {
95 int c;
96
97 c = getopt_long(argc, argv, options_s, options, NULL);
98 if (c == -1)
99 break;
100
101 switch (c) {
102 case 'h':
103 kmod_help(argc, argv);
104 return EXIT_SUCCESS;
105 case 'V':
106 puts("kmod version " VERSION);
107 return EXIT_SUCCESS;
108 case '?':
109 return EXIT_FAILURE;
110 default:
111 fprintf(stderr, "Error: unexpected getopt_long() value '%c'.\n", c);
112 return EXIT_FAILURE;
113 }
114 }
115
116 if (optind >= argc) {
Lucas De Marchi9b966da2011-12-23 11:44:28 -0200117 fputs("missing command\n", stderr);
118 goto fail;
Lucas De Marchi8900b912011-12-22 02:33:36 -0200119 }
120
Lucas De Marchibc854322011-12-23 02:56:27 -0200121 cmd = argv[optind];
Lucas De Marchi8900b912011-12-22 02:33:36 -0200122
Lucas De Marchi9b966da2011-12-23 11:44:28 -0200123 for (i = 0, err = -EINVAL; i < ARRAY_SIZE(kmod_cmds); i++) {
Lucas De Marchi8900b912011-12-22 02:33:36 -0200124 if (strcmp(kmod_cmds[i]->name, cmd) != 0)
125 continue;
126
127 err = kmod_cmds[i]->cmd(--argc, ++argv);
128 }
129
Lucas De Marchi8900b912011-12-22 02:33:36 -0200130 if (err < 0) {
Lucas De Marchi9b966da2011-12-23 11:44:28 -0200131 fprintf(stderr, "invalid command '%s'\n", cmd);
132 goto fail;
Lucas De Marchi8900b912011-12-22 02:33:36 -0200133 }
134
135 return err;
Lucas De Marchi9b966da2011-12-23 11:44:28 -0200136
137fail:
138 kmod_help(argc, argv);
139 return EXIT_FAILURE;
Lucas De Marchi8900b912011-12-22 02:33:36 -0200140}
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200141
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200142
143static int handle_kmod_compat_commands(int argc, char *argv[])
144{
145 const char *cmd;
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200146 size_t i;
147
148 cmd = basename(argv[0]);
149
150 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
Leandro Pereira4783d692011-12-27 18:22:30 -0200151 if (strcmp(kmod_compat_cmds[i]->name, cmd) == 0)
152 return kmod_compat_cmds[i]->cmd(argc, argv);
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200153 }
154
Leandro Pereira4783d692011-12-27 18:22:30 -0200155 return -ENOENT;
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200156}
157
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200158int main(int argc, char *argv[])
159{
160 const char *binname = basename(argv[0]);
161 int err;
162
163 if (strcmp(binname, "kmod") == 0)
164 err = handle_kmod_commands(argc, argv);
165 else
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200166 err = handle_kmod_compat_commands(argc, argv);
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200167
168 return err;
169}