From 535aef98322ba5da7be0fccca0b43f29639238af Mon Sep 17 00:00:00 2001 From: mycroft Date: Sat, 17 Jan 1998 12:14:31 +0000 Subject: [PATCH] Add a -F option to specify the device number format. Also accept a single opaque device number. --- sbin/mknod/mknod.8 | 38 +++++- sbin/mknod/mknod.c | 304 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 289 insertions(+), 53 deletions(-) diff --git a/sbin/mknod/mknod.8 b/sbin/mknod/mknod.8 index b0798dba658a..6140480d3f67 100644 --- a/sbin/mknod/mknod.8 +++ b/sbin/mknod/mknod.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: mknod.8,v 1.12 1997/10/11 02:59:26 enami Exp $ +.\" $NetBSD: mknod.8,v 1.13 1998/01/17 12:14:31 mycroft Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -33,17 +33,22 @@ .\" .\" @(#)mknod.8 8.2 (Berkeley) 12/11/93 .\" -.Dd December 11, 1993 +.Dd January 17, 1998 .Dt MKNOD 8 -.Os BSD 4 +.Os NetBSD 1.4 .Sh NAME .Nm mknod -.Nd build special file +.Nd make device special file .Sh SYNOPSIS .Nm +.Op Fl F Ar format .Ar name .Op Cm c | Cm b .Ar major minor +.Nm "" +.Ar name +.Op Cm c | Cm b +.Ar number .Sh DESCRIPTION The .Nm @@ -92,6 +97,27 @@ the node corresponds to on the device; for example, a subunit may be a filesystem partition or a tty line. .El +.Pp +Device numbers for different operating systems may be packed in a different +format. To create device nodes that may be used by such an operating system +(e.g. in an exported file system used for netbooting), the +.Fl F +option is used. The following formats are recognized: +native, +386bsd, +4bsd, +freebsd, +hpux, +linux, +netbsd, +osf1, +solaris, +sunos, +svr3, +svr4 and +ultrix. +.Pp +Alternatively, a single opaque device number may be specified. .Sh SEE ALSO .Xr mkfifo 1 , .Xr mkfifo 2 , @@ -102,3 +128,7 @@ A .Nm command appeared in .At v6 . +The +.Fl F +option appeared in +.Nx 1.4 . diff --git a/sbin/mknod/mknod.c b/sbin/mknod/mknod.c index 47c178ae439c..eefe907848d0 100644 --- a/sbin/mknod/mknod.c +++ b/sbin/mknod/mknod.c @@ -1,11 +1,7 @@ -/* $NetBSD: mknod.c,v 1.10 1997/11/05 21:29:29 cgd Exp $ */ +/* $NetBSD: mknod.c,v 1.11 1998/01/17 12:14:34 mycroft Exp $ */ /* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kevin Fall. + * Copyright (c) 1998 Charles M. Hannum. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -17,84 +13,294 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * This product includes software developed by Charles M. Hannum. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\ - The Regents of the University of California. All rights reserved.\n"); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)mknod.c 8.1 (Berkeley) 6/5/93"; -#else -__RCSID("$NetBSD: mknod.c,v 1.10 1997/11/05 21:29:29 cgd Exp $"); -#endif +__COPYRIGHT("@(#) Copyright (c) 1998 Charles M. Hannum. All rights reserved.\n"); +__RCSID("$NetBSD: mknod.c,v 1.11 1998/01/17 12:14:34 mycroft Exp $"); #endif /* not lint */ #include #include + +#include +#include +#include #include #include #include -#include - int main __P((int, char *[])); -static void usage __P((void)); +int main __P((int, char *[])); +static void usage __P((void)); +typedef dev_t pack_t __P((u_long, u_long, u_long *, u_long *)); + + +pack_t pack_native; + +dev_t +pack_native(maj, min, maj2, min2) + u_long maj, min, *maj2, *min2; +{ + dev_t dev; + + dev = makedev(maj, min); + *maj2 = major(dev); + *min2 = minor(dev); + return (dev); +} + + +#define major_netbsd(x) ((int32_t)((((x) & 0x000fff00) >> 8))) +#define minor_netbsd(x) ((int32_t)((((x) & 0xfff00000) >> 12) | \ + (((x) & 0x000000ff) >> 0))) +#define makedev_netbsd(x,y) ((dev_t)((((x) << 8) & 0x000fff00) | \ + (((y) << 12) & 0xfff00000) | \ + (((y) << 0) & 0x000000ff))) + +pack_t pack_netbsd; + +dev_t +pack_netbsd(maj, min, maj2, min2) + u_long maj, min, *maj2, *min2; +{ + dev_t dev; + + dev = makedev_netbsd(maj, min); + *maj2 = major_netbsd(dev); + *min2 = minor_netbsd(dev); + return (dev); +} + + +#define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) +#define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0)) +#define makedev_freebsd(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \ + (((y) << 0) & 0xffff00ff))) + +pack_t pack_freebsd; + +dev_t +pack_freebsd(maj, min, maj2, min2) + u_long maj, min, *maj2, *min2; +{ + dev_t dev; + + dev = makedev_freebsd(maj, min); + *maj2 = major_freebsd(dev); + *min2 = minor_freebsd(dev); + return (dev); +} + + +#define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) +#define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) +#define makedev_8_8(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \ + (((y) << 0) & 0x000000ff))) + +pack_t pack_8_8; + +dev_t +pack_8_8(maj, min, maj2, min2) + u_long maj, min, *maj2, *min2; +{ + dev_t dev; + + dev = makedev_8_8(maj, min); + *maj2 = major_8_8(dev); + *min2 = minor_8_8(dev); + return (dev); +} + + +#define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20)) +#define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0)) +#define makedev_12_20(x,y) ((dev_t)((((x) << 20) & 0xfff00000) | \ + (((y) << 0) & 0x000fffff))) + +pack_t pack_12_20; + +dev_t +pack_12_20(maj, min, maj2, min2) + u_long maj, min, *maj2, *min2; +{ + dev_t dev; + + dev = makedev_12_20(maj, min); + *maj2 = major_12_20(dev); + *min2 = minor_12_20(dev); + return (dev); +} + + +#define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18)) +#define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0)) +#define makedev_14_18(x,y) ((dev_t)((((x) << 18) & 0xfffc0000) | \ + (((y) << 0) & 0x0003ffff))) + +pack_t pack_14_18; + +dev_t +pack_14_18(maj, min, maj2, min2) + u_long maj, min, *maj2, *min2; +{ + dev_t dev; + + dev = makedev_14_18(maj, min); + *maj2 = major_14_18(dev); + *min2 = minor_14_18(dev); + return (dev); +} + + +#define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24)) +#define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0)) +#define makedev_8_24(x,y) ((dev_t)((((x) << 24) & 0xff000000) | \ + (((y) << 0) & 0x00ffffff))) + +pack_t pack_8_24; + +dev_t +pack_8_24(maj, min, maj2, min2) + u_long maj, min, *maj2, *min2; +{ + dev_t dev; + + dev = makedev_8_24(maj, min); + *maj2 = major_8_24(dev); + *min2 = minor_8_24(dev); + return (dev); +} + + +struct format { + char *name; + pack_t *pack; +} formats[] = { + {"386bsd", pack_8_8}, + {"4bsd", pack_8_8}, + {"freebsd", pack_freebsd}, + {"hpux", pack_8_24}, + {"linux", pack_8_8}, + {"native", pack_native}, + {"netbsd", pack_netbsd}, + {"osf1", pack_12_20}, + {"solaris", pack_14_18}, + {"sunos", pack_8_8}, + {"svr3", pack_8_8}, + {"svr4", pack_14_18}, + {"ultrix", pack_8_8}, +}; + +int compare_format __P((const void *, const void *)); + +int +compare_format(key, element) + const void *key; + const void *element; +{ + const char *name; + const struct format *format; + + name = key; + format = element; + + return (strcmp(name, format->name)); +} + int main(argc, argv) int argc; char **argv; { + struct format *format; + pack_t *pack; + char *p; + u_long maj, min, maj2, min2; mode_t mode; + dev_t dev; + int ch; - if (argc != 5) { - usage(); - /* NOTREACHED */ + pack = pack_native; + + while ((ch = getopt(argc, argv, "F:")) != -1) { + switch (ch) { + case 'F': + format = bsearch(optarg, formats, + sizeof(formats)/sizeof(formats[0]), + sizeof(formats[0]), compare_format); + if (format == 0) + errx(1, "invalid format: %s", optarg); + pack = format->pack; + break; + + default: + case '?': + usage(); + } } + argc -= optind; + argv += optind; + + if (argc != 3 && argc != 4) + usage(); mode = 0666; - if (argv[2][0] == 'c') + if (argv[1][0] == 'c') mode |= S_IFCHR; - else if (argv[2][0] == 'b') + else if (argv[1][0] == 'b') mode |= S_IFBLK; - else { + else errx(1, "node must be type 'b' or 'c'."); - /* NOTREACHED */ + + if (argc == 4) { + maj = strtoul(argv[2], &p, 0); + if ((p && *p != '\0') || (maj == ULONG_MAX && errno == ERANGE)) + errx(1, "invalid major number: %s", argv[2]); + + min = strtoul(argv[3], &p, 0); + if ((p && *p != '\0') || (min == ULONG_MAX && errno == ERANGE)) + errx(1, "invalid minor number: %s", argv[3]); + + dev = (*pack)(maj, min, &maj2, &min2); + + if (maj2 != maj) + errx(1, "major number out of range: %s", argv[2]); + + if (min2 != min) + errx(1, "minor number out of range: %s", argv[3]); + } else { + dev = (dev_t) strtoul(argv[2], &p, 0); + if ((p && *p != '\0') || (dev == ULONG_MAX && errno == ERANGE)) + errx(1, "invalid device number: %s", argv[2]); } - if (mknod(argv[1], mode, makedev(atoi(argv[3]), atoi(argv[4]))) < 0) { - err(1, "%s", argv[1]); - /* NOTREACHED */ - } + if (mknod(argv[0], mode, dev) < 0) + err(1, "%s", argv[0]); exit(0); - /* NOTREACHED */ } void usage() { - (void)fprintf(stderr, "usage: mknod name [b | c] major minor\n"); + + fprintf(stderr, "usage: mknod [-F format] name [b | c] major minor\n"); + fprintf(stderr, " mknod name [b | c] number\n"); exit(1); - /* NOTREACHED */ }