Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sbin/kldload/kldload.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 1997 Doug Rabson
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/types.h>
30
#include <sys/param.h>
31
#include <sys/linker.h>
32
#include <sys/sysctl.h>
33
#include <sys/stat.h>
34
#include <err.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#include <unistd.h>
39
#include <errno.h>
40
41
#define PATHCTL "kern.module_path"
42
43
/*
44
* Check to see if the requested module is specified as a filename with no
45
* path. If so and if a file by the same name exists in the module path,
46
* warn the user that the module in the path will be used in preference.
47
*/
48
static int
49
path_check(const char *kldname, int quiet)
50
{
51
char *path, *tmppath, *element;
52
struct stat sb;
53
int mib[5];
54
char kldpath[MAXPATHLEN];
55
size_t miblen, pathlen;
56
dev_t dev;
57
ino_t ino;
58
int found;
59
60
if (strchr(kldname, '/') != NULL)
61
return (0);
62
if (strstr(kldname, ".ko") == NULL)
63
return (0);
64
if (stat(kldname, &sb) != 0)
65
return (0);
66
67
found = 0;
68
dev = sb.st_dev;
69
ino = sb.st_ino;
70
71
miblen = nitems(mib);
72
if (sysctlnametomib(PATHCTL, mib, &miblen) != 0)
73
err(1, "sysctlnametomib(%s)", PATHCTL);
74
if (sysctl(mib, miblen, NULL, &pathlen, NULL, 0) == -1)
75
err(1, "getting path: sysctl(%s) - size only", PATHCTL);
76
path = malloc(pathlen + 1);
77
if (path == NULL)
78
err(1, "allocating %lu bytes for the path",
79
(unsigned long)pathlen + 1);
80
if (sysctl(mib, miblen, path, &pathlen, NULL, 0) == -1)
81
err(1, "getting path: sysctl(%s)", PATHCTL);
82
tmppath = path;
83
84
while ((element = strsep(&tmppath, ";")) != NULL) {
85
strlcpy(kldpath, element, MAXPATHLEN);
86
if (kldpath[strlen(kldpath) - 1] != '/') {
87
strlcat(kldpath, "/", MAXPATHLEN);
88
}
89
strlcat(kldpath, kldname, MAXPATHLEN);
90
91
if (stat(kldpath, &sb) == -1)
92
continue;
93
94
found = 1;
95
96
if (sb.st_dev != dev || sb.st_ino != ino) {
97
if (!quiet)
98
warnx("%s will be loaded from %s, not the "
99
"current directory", kldname, element);
100
break;
101
} else if (sb.st_dev == dev && sb.st_ino == ino)
102
break;
103
}
104
105
free(path);
106
107
if (!found) {
108
if (!quiet)
109
warnx("%s is not in the module path", kldname);
110
return (-1);
111
}
112
113
return (0);
114
}
115
116
static void
117
usage(void)
118
{
119
120
fprintf(stderr, "usage: kldload [-nqv] file ...\n");
121
exit(1);
122
}
123
124
int
125
main(int argc, char** argv)
126
{
127
int c;
128
int check_loaded;
129
int errors;
130
int fileid;
131
int quiet;
132
int verbose;
133
134
errors = 0;
135
verbose = 0;
136
quiet = 0;
137
check_loaded = 0;
138
139
while ((c = getopt(argc, argv, "nqv")) != -1) {
140
switch (c) {
141
case 'q':
142
quiet = 1;
143
verbose = 0;
144
break;
145
case 'v':
146
verbose = 1;
147
quiet = 0;
148
break;
149
case 'n':
150
check_loaded = 1;
151
break;
152
default:
153
usage();
154
}
155
}
156
argc -= optind;
157
argv += optind;
158
159
if (argc == 0)
160
usage();
161
162
while (argc-- != 0) {
163
if (path_check(argv[0], quiet) == 0) {
164
fileid = kldload(argv[0]);
165
if (fileid < 0) {
166
if (check_loaded != 0 && errno == EEXIST) {
167
if (verbose)
168
printf("%s is already "
169
"loaded\n", argv[0]);
170
} else {
171
if (!quiet) {
172
switch (errno) {
173
case EEXIST:
174
warnx("can't load %s: module "
175
"already loaded or "
176
"in kernel", argv[0]);
177
break;
178
case ENOEXEC:
179
warnx("an error occurred while "
180
"loading module %s. "
181
"Please check dmesg(8) for "
182
"more details.", argv[0]);
183
break;
184
default:
185
warn("can't load %s", argv[0]);
186
break;
187
}
188
}
189
errors++;
190
}
191
} else {
192
if (verbose)
193
printf("Loaded %s, id=%d\n", argv[0],
194
fileid);
195
}
196
} else
197
errors++;
198
argv++;
199
}
200
201
return (errors ? 1 : 0);
202
}
203
204