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