Home | History | Annotate | Line # | Download | only in mknod
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