Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sbin/devfs/devfs.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2001, 2002 Dima Dorfman.
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
/*
30
* DEVFS control.
31
*/
32
33
#include <sys/param.h>
34
#include <sys/queue.h>
35
36
#include <assert.h>
37
#include <err.h>
38
#include <fcntl.h>
39
#include <paths.h>
40
#include <stdio.h>
41
#include <stdint.h>
42
#include <stdlib.h>
43
#include <string.h>
44
#include <unistd.h>
45
46
#include "extern.h"
47
48
int mpfd;
49
50
static ctbl_t ctbl_main = {
51
{ "rule", rule_main },
52
{ "ruleset", ruleset_main },
53
{ NULL, NULL }
54
};
55
56
int
57
main(int ac, char **av)
58
{
59
const char *mountpt;
60
struct cmd *c;
61
int ch;
62
63
mountpt = NULL;
64
while ((ch = getopt(ac, av, "m:")) != -1)
65
switch (ch) {
66
case 'm':
67
mountpt = optarg;
68
break;
69
default:
70
usage();
71
}
72
ac -= optind;
73
av += optind;
74
if (ac < 1)
75
usage();
76
77
if (mountpt == NULL)
78
mountpt = _PATH_DEV;
79
mpfd = open(mountpt, O_RDONLY);
80
if (mpfd == -1)
81
err(1, "open: %s", mountpt);
82
83
for (c = ctbl_main; c->name != NULL; ++c)
84
if (strcmp(c->name, av[0]) == 0)
85
exit((*c->handler)(ac, av));
86
errx(1, "unknown command: %s", av[0]);
87
}
88
89
/*
90
* Convert an integer to a "number" (ruleset numbers and rule numbers
91
* are 16-bit). If the conversion is successful, num contains the
92
* integer representation of s and 1 is returned; otherwise, 0 is
93
* returned and num is unchanged.
94
*/
95
int
96
atonum(const char *s, uint16_t *num)
97
{
98
unsigned long ul;
99
char *cp;
100
101
ul = strtoul(s, &cp, 10);
102
if (ul > UINT16_MAX || *cp != '\0')
103
return (0);
104
*num = (uint16_t)ul;
105
return (1);
106
}
107
108
/*
109
* Convert user input in ASCII to an integer.
110
*/
111
int
112
eatoi(const char *s)
113
{
114
char *cp;
115
long l;
116
117
l = strtol(s, &cp, 10);
118
if (l > INT_MAX || *cp != '\0')
119
errx(1, "error converting to integer: %s", s);
120
return ((int)l);
121
}
122
123
/*
124
* As atonum(), but the result of failure is death.
125
*/
126
uint16_t
127
eatonum(const char *s)
128
{
129
uint16_t num;
130
131
if (!atonum(s, &num))
132
errx(1, "error converting to number: %s", s); /* XXX clarify */
133
return (num);
134
}
135
136
/*
137
* Read a line from a /FILE/. If the return value isn't 0, it is the
138
* length of the line, a pointer to which exists in /line/. It is the
139
* caller's responsibility to free(3) it. If the return value is 0,
140
* there was an error or we reached EOF, and /line/ is undefined (so,
141
* obviously, the caller shouldn't try to free(3) it).
142
*/
143
size_t
144
efgetln(FILE *fp, char **line)
145
{
146
size_t rv;
147
char *cp;
148
149
cp = fgetln(fp, &rv);
150
if (cp == NULL) {
151
*line = NULL;
152
return (rv);
153
}
154
if (cp[rv - 1] == '\n') {
155
cp[rv - 1] = '\0';
156
*line = strdup(cp);
157
if (*line == NULL)
158
errx(1, "cannot allocate memory");
159
--rv;
160
} else {
161
*line = malloc(rv + 1);
162
if (*line == NULL)
163
errx(1, "cannot allocate memory");
164
memcpy(*line, cp, rv);
165
(*line)[rv] = '\0';
166
}
167
assert(rv == strlen(*line));
168
return (rv);
169
}
170
171
struct ptrstq {
172
STAILQ_ENTRY(ptrstq) tq;
173
void *ptr;
174
};
175
176
/*
177
* Create an argument vector from /line/. The caller must free(3)
178
* /avp/, and /avp[0]/ when the argument vector is no longer
179
* needed unless /acp/ is 0, in which case /avp/ is undefined.
180
* /avp/ is NULL-terminated, so it is actually one longer than /acp/.
181
*/
182
void
183
tokenize(const char *line, int *acp, char ***avp)
184
{
185
static const char *delims = " \t\n";
186
struct ptrstq *pt;
187
STAILQ_HEAD(, ptrstq) plist;
188
char **ap, *cp, *wline, *xcp;
189
190
line += strspn(line, delims);
191
wline = strdup(line);
192
if (wline == NULL)
193
errx(1, "cannot allocate memory");
194
195
STAILQ_INIT(&plist);
196
for (xcp = wline, *acp = 0;
197
(cp = strsep(&xcp, delims)) != NULL;)
198
if (*cp != '\0') {
199
pt = calloc(1, sizeof(*pt));
200
if (pt == NULL)
201
errx(1, "cannot allocate memory");
202
pt->ptr = cp;
203
STAILQ_INSERT_TAIL(&plist, pt, tq);
204
++*acp;
205
}
206
if (*acp == 0)
207
return;
208
assert(STAILQ_FIRST(&plist)->ptr == wline);
209
*avp = malloc(sizeof(**avp) * (*acp + 1));
210
if (*avp == NULL)
211
errx(1, "cannot allocate memory");
212
for (ap = *avp; !STAILQ_EMPTY(&plist);) {
213
pt = STAILQ_FIRST(&plist);
214
*ap = pt->ptr;
215
++ap;
216
assert(ap <= *avp + (*acp));
217
STAILQ_REMOVE_HEAD(&plist, tq);
218
free(pt);
219
}
220
*ap = NULL;
221
}
222
223
void
224
usage(void)
225
{
226
227
fprintf(stderr, "usage: %s\n%s\n",
228
"\tdevfs [-m mount-point] rule [-s ruleset] ...",
229
"\tdevfs [-m mount-point] ruleset ...");
230
exit(1);
231
}
232
233