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