blob: 42390275304ff4dfaf3c0cedffb68d0c99fe9e84 [file] [log] [blame]
Lucas De Marchi8900b912011-12-22 02:33:36 -02001/*
2 * kmod - one tool to rule them all
3 *
Lucas De Marchie6b0e492013-01-16 11:27:21 -02004 * Copyright (C) 2011-2013 ProFUSION embedded systems
Lucas De Marchi8900b912011-12-22 02:33:36 -02005 *
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
Lucas De Marchi8900b912011-12-22 02:33:36 -020020#include <errno.h>
Lucas De Marchibc854322011-12-23 02:56:27 -020021#include <getopt.h>
Lucas De Marchic2e42862014-10-03 01:41:42 -030022#include <stdio.h>
23#include <stdlib.h>
Lucas De Marchi8900b912011-12-22 02:33:36 -020024#include <string.h>
Lucas De Marchic2e42862014-10-03 01:41:42 -030025
Lucas De Marchi8900b912011-12-22 02:33:36 -020026#include <libkmod.h>
Lucas De Marchic2e42862014-10-03 01:41:42 -030027
Lucas De Marchi8900b912011-12-22 02:33:36 -020028#include "kmod.h"
29
Lucas De Marchibc854322011-12-23 02:56:27 -020030static const char options_s[] = "+hV";
31static const struct option options[] = {
32 { "help", no_argument, NULL, 'h' },
33 { "version", no_argument, NULL, 'V' },
34 {}
35};
36
Lucas De Marchi8900b912011-12-22 02:33:36 -020037static const struct kmod_cmd kmod_cmd_help;
38
39static const struct kmod_cmd *kmod_cmds[] = {
40 &kmod_cmd_help,
Lucas De Marchi252c51a2011-12-23 11:33:02 -020041 &kmod_cmd_list,
Tom Gundersendb6f2fc2013-04-16 22:39:55 +020042 &kmod_cmd_static_nodes,
Lucas De Marchi8900b912011-12-22 02:33:36 -020043};
44
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020045static const struct kmod_cmd *kmod_compat_cmds[] = {
46 &kmod_cmd_compat_lsmod,
Lucas De Marchif712ebc2011-12-22 03:39:11 -020047 &kmod_cmd_compat_rmmod,
Lucas De Marchiad602692011-12-22 03:45:07 -020048 &kmod_cmd_compat_insmod,
Lucas De Marchi769becb2011-12-22 03:50:54 -020049 &kmod_cmd_compat_modinfo,
Lucas De Marchifa29c0e2011-12-22 03:54:46 -020050 &kmod_cmd_compat_modprobe,
Lucas De Marchif6cf14c2011-12-27 19:56:33 -020051 &kmod_cmd_compat_depmod,
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020052};
53
Lucas De Marchi8900b912011-12-22 02:33:36 -020054static int kmod_help(int argc, char *argv[])
55{
56 size_t i;
57
Lucas De Marchia458e362011-12-23 11:35:48 -020058 printf("kmod - Manage kernel modules: list, load, unload, etc\n"
Lucas De Marchibc854322011-12-23 02:56:27 -020059 "Usage:\n"
60 "\t%s [options] command [command_options]\n\n"
61 "Options:\n"
62 "\t-V, --version show version\n"
63 "\t-h, --help show this help\n\n"
64 "Commands:\n", basename(argv[0]));
Lucas De Marchi8900b912011-12-22 02:33:36 -020065
66 for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) {
67 if (kmod_cmds[i]->help != NULL) {
68 printf(" %-12s %s\n", kmod_cmds[i]->name,
69 kmod_cmds[i]->help);
70 }
71 }
72
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -020073 puts("\nkmod also handles gracefully if called from following symlinks:");
74
75 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
76 if (kmod_compat_cmds[i]->help != NULL) {
77 printf(" %-12s %s\n", kmod_compat_cmds[i]->name,
78 kmod_compat_cmds[i]->help);
79 }
80 }
Lucas De Marchi35a29aa2011-12-22 19:21:11 -020081
Lucas De Marchi8900b912011-12-22 02:33:36 -020082 return EXIT_SUCCESS;
83}
84
85static const struct kmod_cmd kmod_cmd_help = {
86 .name = "help",
87 .cmd = kmod_help,
88 .help = "Show help message",
89};
90
Lucas De Marchi35a29aa2011-12-22 19:21:11 -020091static int handle_kmod_commands(int argc, char *argv[])
Lucas De Marchi8900b912011-12-22 02:33:36 -020092{
93 const char *cmd;
94 int err = 0;
95 size_t i;
96
Lucas De Marchibc854322011-12-23 02:56:27 -020097 for (;;) {
98 int c;
99
100 c = getopt_long(argc, argv, options_s, options, NULL);
101 if (c == -1)
102 break;
103
104 switch (c) {
105 case 'h':
106 kmod_help(argc, argv);
107 return EXIT_SUCCESS;
108 case 'V':
109 puts("kmod version " VERSION);
110 return EXIT_SUCCESS;
111 case '?':
112 return EXIT_FAILURE;
113 default:
114 fprintf(stderr, "Error: unexpected getopt_long() value '%c'.\n", c);
115 return EXIT_FAILURE;
116 }
117 }
118
119 if (optind >= argc) {
Lucas De Marchi9b966da2011-12-23 11:44:28 -0200120 fputs("missing command\n", stderr);
121 goto fail;
Lucas De Marchi8900b912011-12-22 02:33:36 -0200122 }
123
Lucas De Marchibc854322011-12-23 02:56:27 -0200124 cmd = argv[optind];
Lucas De Marchi8900b912011-12-22 02:33:36 -0200125
Lucas De Marchi9b966da2011-12-23 11:44:28 -0200126 for (i = 0, err = -EINVAL; i < ARRAY_SIZE(kmod_cmds); i++) {
Lucas De Marchi8900b912011-12-22 02:33:36 -0200127 if (strcmp(kmod_cmds[i]->name, cmd) != 0)
128 continue;
129
130 err = kmod_cmds[i]->cmd(--argc, ++argv);
131 }
132
Lucas De Marchi8900b912011-12-22 02:33:36 -0200133 if (err < 0) {
Lucas De Marchi9b966da2011-12-23 11:44:28 -0200134 fprintf(stderr, "invalid command '%s'\n", cmd);
135 goto fail;
Lucas De Marchi8900b912011-12-22 02:33:36 -0200136 }
137
138 return err;
Lucas De Marchi9b966da2011-12-23 11:44:28 -0200139
140fail:
141 kmod_help(argc, argv);
142 return EXIT_FAILURE;
Lucas De Marchi8900b912011-12-22 02:33:36 -0200143}
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200144
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200145
146static int handle_kmod_compat_commands(int argc, char *argv[])
147{
148 const char *cmd;
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200149 size_t i;
150
151 cmd = basename(argv[0]);
152
153 for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
Leandro Pereira4783d692011-12-27 18:22:30 -0200154 if (strcmp(kmod_compat_cmds[i]->name, cmd) == 0)
155 return kmod_compat_cmds[i]->cmd(argc, argv);
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200156 }
157
Leandro Pereira4783d692011-12-27 18:22:30 -0200158 return -ENOENT;
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200159}
160
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200161int main(int argc, char *argv[])
162{
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200163 int err;
164
Lucas De Marchi7c04aee2012-11-06 19:20:09 -0200165 if (strcmp(program_invocation_short_name, "kmod") == 0)
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200166 err = handle_kmod_commands(argc, argv);
167 else
Lucas De Marchi6fcf69e2011-12-22 03:01:45 -0200168 err = handle_kmod_compat_commands(argc, argv);
Lucas De Marchi35a29aa2011-12-22 19:21:11 -0200169
170 return err;
171}