xref: /aosp_15_r20/external/kmod/tools/kmod.c (revision cc4ad7da8cefe208cb129ac2aa9a357c7c72deb2)
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 
47 static const struct kmod_cmd *kmod_compat_cmds[] = {
48 	&kmod_cmd_compat_lsmod,
49 	&kmod_cmd_compat_rmmod,
50 	&kmod_cmd_compat_insmod,
51 	&kmod_cmd_compat_modinfo,
52 	&kmod_cmd_compat_modprobe,
53 	&kmod_cmd_compat_depmod,
54 };
55 
kmod_help(int argc,char * argv[])56 static int kmod_help(int argc, char *argv[])
57 {
58 	size_t i;
59 
60 	printf("kmod - Manage kernel modules: list, load, unload, etc\n"
61 			"Usage:\n"
62 			"\t%s [options] command [command_options]\n\n"
63 			"Options:\n"
64 			"\t-V, --version     show version\n"
65 			"\t-h, --help        show this help\n\n"
66 			"Commands:\n", basename(argv[0]));
67 
68 	for (i = 0; i < ARRAY_SIZE(kmod_cmds); i++) {
69 		if (kmod_cmds[i]->help != NULL) {
70 			printf("  %-12s %s\n", kmod_cmds[i]->name,
71 							kmod_cmds[i]->help);
72 		}
73 	}
74 
75 	puts("\nkmod also handles gracefully if called from following symlinks:");
76 
77 	for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
78 		if (kmod_compat_cmds[i]->help != NULL) {
79 			printf("  %-12s %s\n", kmod_compat_cmds[i]->name,
80 						kmod_compat_cmds[i]->help);
81 		}
82 	}
83 
84 	return EXIT_SUCCESS;
85 }
86 
87 static const struct kmod_cmd kmod_cmd_help = {
88 	.name = "help",
89 	.cmd = kmod_help,
90 	.help = "Show help message",
91 };
92 
handle_kmod_commands(int argc,char * argv[])93 static int handle_kmod_commands(int argc, char *argv[])
94 {
95 	const char *cmd;
96 	int err = 0;
97 	size_t i;
98 
99 	for (;;) {
100 		int c;
101 
102 		c = getopt_long(argc, argv, options_s, options, NULL);
103 		if (c == -1)
104 			break;
105 
106 		switch (c) {
107 		case 'h':
108 			kmod_help(argc, argv);
109 			return EXIT_SUCCESS;
110 		case 'V':
111 			puts(PACKAGE " version " VERSION);
112 			puts(KMOD_FEATURES);
113 			return EXIT_SUCCESS;
114 		case '?':
115 			return EXIT_FAILURE;
116 		default:
117 			fprintf(stderr, "Error: unexpected getopt_long() value '%c'.\n", c);
118 			return EXIT_FAILURE;
119 		}
120 	}
121 
122 	if (optind >= argc) {
123 		fputs("missing command\n", stderr);
124 		goto fail;
125 	}
126 
127 	cmd = argv[optind];
128 
129 	for (i = 0, err = -EINVAL; i < ARRAY_SIZE(kmod_cmds); i++) {
130 		if (streq(kmod_cmds[i]->name, cmd)) {
131 			err = kmod_cmds[i]->cmd(--argc, ++argv);
132 			break;
133 		}
134 	}
135 
136 	if (err < 0) {
137 		fprintf(stderr, "invalid command '%s'\n", cmd);
138 		goto fail;
139 	}
140 
141 	return err;
142 
143 fail:
144 	kmod_help(argc, argv);
145 	return EXIT_FAILURE;
146 }
147 
148 
handle_kmod_compat_commands(int argc,char * argv[])149 static int handle_kmod_compat_commands(int argc, char *argv[])
150 {
151 	const char *cmd;
152 	size_t i;
153 
154 	cmd = basename(argv[0]);
155 
156 	for (i = 0; i < ARRAY_SIZE(kmod_compat_cmds); i++) {
157 		if (streq(kmod_compat_cmds[i]->name, cmd))
158 			return kmod_compat_cmds[i]->cmd(argc, argv);
159 	}
160 
161 	return -ENOENT;
162 }
163 
main(int argc,char * argv[])164 int main(int argc, char *argv[])
165 {
166 	int err;
167 
168 	if (streq(program_invocation_short_name, "kmod"))
169 		err = handle_kmod_commands(argc, argv);
170 	else
171 		err = handle_kmod_compat_commands(argc, argv);
172 
173 	return err;
174 }
175