mknod.c revision 1.13 1 1.13 mycroft /* $NetBSD: mknod.c,v 1.13 1998/08/15 09:16:28 mycroft Exp $ */
2 1.7 cgd
3 1.13 mycroft /*-
4 1.13 mycroft * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 1.13 mycroft * All rights reserved.
6 1.13 mycroft *
7 1.13 mycroft * This code is derived from software contributed to The NetBSD Foundation
8 1.13 mycroft * by Charles M. Hannum.
9 1.1 cgd *
10 1.1 cgd * Redistribution and use in source and binary forms, with or without
11 1.1 cgd * modification, are permitted provided that the following conditions
12 1.1 cgd * are met:
13 1.1 cgd * 1. Redistributions of source code must retain the above copyright
14 1.1 cgd * notice, this list of conditions and the following disclaimer.
15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 cgd * notice, this list of conditions and the following disclaimer in the
17 1.1 cgd * documentation and/or other materials provided with the distribution.
18 1.1 cgd * 3. All advertising materials mentioning features or use of this software
19 1.1 cgd * must display the following acknowledgement:
20 1.13 mycroft * This product includes software developed by the NetBSD
21 1.13 mycroft * Foundation, Inc. and its contributors.
22 1.13 mycroft * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.13 mycroft * contributors may be used to endorse or promote products derived
24 1.13 mycroft * from this software without specific prior written permission.
25 1.1 cgd *
26 1.13 mycroft * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.13 mycroft * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.13 mycroft * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.13 mycroft * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.13 mycroft * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.13 mycroft * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.13 mycroft * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.13 mycroft * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.13 mycroft * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.13 mycroft * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.13 mycroft * POSSIBILITY OF SUCH DAMAGE.
37 1.1 cgd */
38 1.1 cgd
39 1.9 lukem #include <sys/cdefs.h>
40 1.1 cgd #ifndef lint
41 1.13 mycroft __COPYRIGHT("@(#) Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.\n");
42 1.13 mycroft __RCSID("$NetBSD: mknod.c,v 1.13 1998/08/15 09:16:28 mycroft Exp $");
43 1.1 cgd #endif /* not lint */
44 1.1 cgd
45 1.1 cgd #include <sys/types.h>
46 1.1 cgd #include <sys/stat.h>
47 1.11 mycroft
48 1.11 mycroft #include <err.h>
49 1.11 mycroft #include <errno.h>
50 1.11 mycroft #include <limits.h>
51 1.1 cgd #include <stdio.h>
52 1.6 cgd #include <stdlib.h>
53 1.6 cgd #include <unistd.h>
54 1.8 jtc
55 1.11 mycroft int main __P((int, char *[]));
56 1.11 mycroft static void usage __P((void));
57 1.11 mycroft typedef dev_t pack_t __P((u_long, u_long, u_long *, u_long *));
58 1.11 mycroft
59 1.11 mycroft
60 1.11 mycroft pack_t pack_native;
61 1.11 mycroft
62 1.11 mycroft dev_t
63 1.11 mycroft pack_native(maj, min, maj2, min2)
64 1.11 mycroft u_long maj, min, *maj2, *min2;
65 1.11 mycroft {
66 1.11 mycroft dev_t dev;
67 1.11 mycroft
68 1.11 mycroft dev = makedev(maj, min);
69 1.11 mycroft *maj2 = major(dev);
70 1.11 mycroft *min2 = minor(dev);
71 1.11 mycroft return (dev);
72 1.11 mycroft }
73 1.11 mycroft
74 1.11 mycroft
75 1.11 mycroft #define major_netbsd(x) ((int32_t)((((x) & 0x000fff00) >> 8)))
76 1.11 mycroft #define minor_netbsd(x) ((int32_t)((((x) & 0xfff00000) >> 12) | \
77 1.11 mycroft (((x) & 0x000000ff) >> 0)))
78 1.11 mycroft #define makedev_netbsd(x,y) ((dev_t)((((x) << 8) & 0x000fff00) | \
79 1.11 mycroft (((y) << 12) & 0xfff00000) | \
80 1.11 mycroft (((y) << 0) & 0x000000ff)))
81 1.11 mycroft
82 1.11 mycroft pack_t pack_netbsd;
83 1.11 mycroft
84 1.11 mycroft dev_t
85 1.11 mycroft pack_netbsd(maj, min, maj2, min2)
86 1.11 mycroft u_long maj, min, *maj2, *min2;
87 1.11 mycroft {
88 1.11 mycroft dev_t dev;
89 1.11 mycroft
90 1.11 mycroft dev = makedev_netbsd(maj, min);
91 1.11 mycroft *maj2 = major_netbsd(dev);
92 1.11 mycroft *min2 = minor_netbsd(dev);
93 1.11 mycroft return (dev);
94 1.11 mycroft }
95 1.11 mycroft
96 1.11 mycroft
97 1.11 mycroft #define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
98 1.11 mycroft #define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0))
99 1.11 mycroft #define makedev_freebsd(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \
100 1.11 mycroft (((y) << 0) & 0xffff00ff)))
101 1.11 mycroft
102 1.11 mycroft pack_t pack_freebsd;
103 1.11 mycroft
104 1.11 mycroft dev_t
105 1.11 mycroft pack_freebsd(maj, min, maj2, min2)
106 1.11 mycroft u_long maj, min, *maj2, *min2;
107 1.11 mycroft {
108 1.11 mycroft dev_t dev;
109 1.11 mycroft
110 1.11 mycroft dev = makedev_freebsd(maj, min);
111 1.11 mycroft *maj2 = major_freebsd(dev);
112 1.11 mycroft *min2 = minor_freebsd(dev);
113 1.11 mycroft return (dev);
114 1.11 mycroft }
115 1.11 mycroft
116 1.11 mycroft
117 1.11 mycroft #define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
118 1.11 mycroft #define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
119 1.11 mycroft #define makedev_8_8(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \
120 1.11 mycroft (((y) << 0) & 0x000000ff)))
121 1.11 mycroft
122 1.11 mycroft pack_t pack_8_8;
123 1.11 mycroft
124 1.11 mycroft dev_t
125 1.11 mycroft pack_8_8(maj, min, maj2, min2)
126 1.11 mycroft u_long maj, min, *maj2, *min2;
127 1.11 mycroft {
128 1.11 mycroft dev_t dev;
129 1.11 mycroft
130 1.11 mycroft dev = makedev_8_8(maj, min);
131 1.11 mycroft *maj2 = major_8_8(dev);
132 1.11 mycroft *min2 = minor_8_8(dev);
133 1.11 mycroft return (dev);
134 1.11 mycroft }
135 1.11 mycroft
136 1.11 mycroft
137 1.11 mycroft #define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20))
138 1.11 mycroft #define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0))
139 1.11 mycroft #define makedev_12_20(x,y) ((dev_t)((((x) << 20) & 0xfff00000) | \
140 1.11 mycroft (((y) << 0) & 0x000fffff)))
141 1.11 mycroft
142 1.11 mycroft pack_t pack_12_20;
143 1.11 mycroft
144 1.11 mycroft dev_t
145 1.11 mycroft pack_12_20(maj, min, maj2, min2)
146 1.11 mycroft u_long maj, min, *maj2, *min2;
147 1.11 mycroft {
148 1.11 mycroft dev_t dev;
149 1.11 mycroft
150 1.11 mycroft dev = makedev_12_20(maj, min);
151 1.11 mycroft *maj2 = major_12_20(dev);
152 1.11 mycroft *min2 = minor_12_20(dev);
153 1.11 mycroft return (dev);
154 1.11 mycroft }
155 1.11 mycroft
156 1.11 mycroft
157 1.11 mycroft #define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18))
158 1.11 mycroft #define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0))
159 1.11 mycroft #define makedev_14_18(x,y) ((dev_t)((((x) << 18) & 0xfffc0000) | \
160 1.11 mycroft (((y) << 0) & 0x0003ffff)))
161 1.11 mycroft
162 1.11 mycroft pack_t pack_14_18;
163 1.11 mycroft
164 1.11 mycroft dev_t
165 1.11 mycroft pack_14_18(maj, min, maj2, min2)
166 1.11 mycroft u_long maj, min, *maj2, *min2;
167 1.11 mycroft {
168 1.11 mycroft dev_t dev;
169 1.11 mycroft
170 1.11 mycroft dev = makedev_14_18(maj, min);
171 1.11 mycroft *maj2 = major_14_18(dev);
172 1.11 mycroft *min2 = minor_14_18(dev);
173 1.11 mycroft return (dev);
174 1.11 mycroft }
175 1.11 mycroft
176 1.11 mycroft
177 1.11 mycroft #define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24))
178 1.11 mycroft #define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0))
179 1.11 mycroft #define makedev_8_24(x,y) ((dev_t)((((x) << 24) & 0xff000000) | \
180 1.11 mycroft (((y) << 0) & 0x00ffffff)))
181 1.11 mycroft
182 1.11 mycroft pack_t pack_8_24;
183 1.11 mycroft
184 1.11 mycroft dev_t
185 1.11 mycroft pack_8_24(maj, min, maj2, min2)
186 1.11 mycroft u_long maj, min, *maj2, *min2;
187 1.11 mycroft {
188 1.11 mycroft dev_t dev;
189 1.11 mycroft
190 1.11 mycroft dev = makedev_8_24(maj, min);
191 1.11 mycroft *maj2 = major_8_24(dev);
192 1.11 mycroft *min2 = minor_8_24(dev);
193 1.11 mycroft return (dev);
194 1.11 mycroft }
195 1.11 mycroft
196 1.11 mycroft
197 1.11 mycroft struct format {
198 1.11 mycroft char *name;
199 1.11 mycroft pack_t *pack;
200 1.11 mycroft } formats[] = {
201 1.11 mycroft {"386bsd", pack_8_8},
202 1.11 mycroft {"4bsd", pack_8_8},
203 1.12 mycroft {"bsdos", pack_12_20},
204 1.11 mycroft {"freebsd", pack_freebsd},
205 1.11 mycroft {"hpux", pack_8_24},
206 1.11 mycroft {"linux", pack_8_8},
207 1.11 mycroft {"native", pack_native},
208 1.11 mycroft {"netbsd", pack_netbsd},
209 1.11 mycroft {"osf1", pack_12_20},
210 1.11 mycroft {"solaris", pack_14_18},
211 1.11 mycroft {"sunos", pack_8_8},
212 1.11 mycroft {"svr3", pack_8_8},
213 1.11 mycroft {"svr4", pack_14_18},
214 1.11 mycroft {"ultrix", pack_8_8},
215 1.11 mycroft };
216 1.11 mycroft
217 1.11 mycroft int compare_format __P((const void *, const void *));
218 1.11 mycroft
219 1.11 mycroft int
220 1.11 mycroft compare_format(key, element)
221 1.11 mycroft const void *key;
222 1.11 mycroft const void *element;
223 1.11 mycroft {
224 1.11 mycroft const char *name;
225 1.11 mycroft const struct format *format;
226 1.11 mycroft
227 1.11 mycroft name = key;
228 1.11 mycroft format = element;
229 1.11 mycroft
230 1.11 mycroft return (strcmp(name, format->name));
231 1.11 mycroft }
232 1.11 mycroft
233 1.1 cgd
234 1.6 cgd int
235 1.1 cgd main(argc, argv)
236 1.1 cgd int argc;
237 1.1 cgd char **argv;
238 1.1 cgd {
239 1.11 mycroft struct format *format;
240 1.11 mycroft pack_t *pack;
241 1.11 mycroft char *p;
242 1.11 mycroft u_long maj, min, maj2, min2;
243 1.8 jtc mode_t mode;
244 1.11 mycroft dev_t dev;
245 1.11 mycroft int ch;
246 1.1 cgd
247 1.11 mycroft pack = pack_native;
248 1.11 mycroft
249 1.11 mycroft while ((ch = getopt(argc, argv, "F:")) != -1) {
250 1.11 mycroft switch (ch) {
251 1.11 mycroft case 'F':
252 1.11 mycroft format = bsearch(optarg, formats,
253 1.11 mycroft sizeof(formats)/sizeof(formats[0]),
254 1.11 mycroft sizeof(formats[0]), compare_format);
255 1.11 mycroft if (format == 0)
256 1.11 mycroft errx(1, "invalid format: %s", optarg);
257 1.11 mycroft pack = format->pack;
258 1.11 mycroft break;
259 1.11 mycroft
260 1.11 mycroft default:
261 1.11 mycroft case '?':
262 1.11 mycroft usage();
263 1.11 mycroft }
264 1.11 mycroft }
265 1.11 mycroft argc -= optind;
266 1.11 mycroft argv += optind;
267 1.11 mycroft
268 1.11 mycroft if (argc != 3 && argc != 4)
269 1.8 jtc usage();
270 1.1 cgd
271 1.1 cgd mode = 0666;
272 1.11 mycroft if (argv[1][0] == 'c')
273 1.1 cgd mode |= S_IFCHR;
274 1.11 mycroft else if (argv[1][0] == 'b')
275 1.1 cgd mode |= S_IFBLK;
276 1.11 mycroft else
277 1.8 jtc errx(1, "node must be type 'b' or 'c'.");
278 1.11 mycroft
279 1.11 mycroft if (argc == 4) {
280 1.11 mycroft maj = strtoul(argv[2], &p, 0);
281 1.11 mycroft if ((p && *p != '\0') || (maj == ULONG_MAX && errno == ERANGE))
282 1.11 mycroft errx(1, "invalid major number: %s", argv[2]);
283 1.11 mycroft
284 1.11 mycroft min = strtoul(argv[3], &p, 0);
285 1.11 mycroft if ((p && *p != '\0') || (min == ULONG_MAX && errno == ERANGE))
286 1.11 mycroft errx(1, "invalid minor number: %s", argv[3]);
287 1.11 mycroft
288 1.11 mycroft dev = (*pack)(maj, min, &maj2, &min2);
289 1.11 mycroft
290 1.11 mycroft if (maj2 != maj)
291 1.11 mycroft errx(1, "major number out of range: %s", argv[2]);
292 1.11 mycroft
293 1.11 mycroft if (min2 != min)
294 1.11 mycroft errx(1, "minor number out of range: %s", argv[3]);
295 1.11 mycroft } else {
296 1.11 mycroft dev = (dev_t) strtoul(argv[2], &p, 0);
297 1.11 mycroft if ((p && *p != '\0') || (dev == ULONG_MAX && errno == ERANGE))
298 1.11 mycroft errx(1, "invalid device number: %s", argv[2]);
299 1.1 cgd }
300 1.1 cgd
301 1.11 mycroft if (mknod(argv[0], mode, dev) < 0)
302 1.11 mycroft err(1, "%s", argv[0]);
303 1.8 jtc
304 1.1 cgd exit(0);
305 1.8 jtc }
306 1.8 jtc
307 1.8 jtc void
308 1.8 jtc usage()
309 1.8 jtc {
310 1.11 mycroft
311 1.11 mycroft fprintf(stderr, "usage: mknod [-F format] name [b | c] major minor\n");
312 1.11 mycroft fprintf(stderr, " mknod name [b | c] number\n");
313 1.8 jtc exit(1);
314 1.1 cgd }
315