1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* Copyright (c) 1987, 1988 Microsoft Corporation */ 31 /* All Rights Reserved */ 32 33 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ 34 35 /* 36 * mknod - build special file 37 * 38 * mknod name [ b ] [ c ] major minor 39 * mknod name p (named pipe) 40 * 41 * MODIFICATION HISTORY 42 * M000 11 Apr 83 andyp 3.0 upgrade 43 * - (Mostly uncommented). Picked up 3.0 source. 44 * - Added header. Changed usage message. Replaced hard-coded 45 * makedev with one from <sys/types.h>. 46 * - Added mechanism for creating name space files. 47 * - Added some error checks. 48 * - Semi-major reorganition. 49 */ 50 51 #include <sys/types.h> 52 #include <stdio.h> 53 #include <unistd.h> 54 #include <stdlib.h> 55 #include <errno.h> 56 #include <sys/stat.h> 57 #include <sys/mkdev.h> 58 59 #define ACC 0666 60 61 static int domk(const char *path, const mode_t mode, const dev_t arg); 62 static long number(const char *s); 63 static void usage(void); 64 65 int 66 main(int argc, char **argv) 67 { 68 mode_t mode; 69 dev_t arg; 70 major_t majno; 71 minor_t minno; 72 73 if (argc < 3 || argc > 5) 74 usage(); 75 76 if (argv[2][1] != '\0') 77 usage(); 78 79 if (argc == 3) { 80 switch (argv[2][0]) { 81 case 'p': 82 mode = S_IFIFO; 83 arg = 0; /* (not used) */ 84 break; 85 default: 86 usage(); 87 /* NO RETURN */ 88 } 89 } else if (argc == 5) { 90 switch (argv[2][0]) { 91 case 'b': 92 mode = S_IFBLK; 93 break; 94 case 'c': 95 mode = S_IFCHR; 96 break; 97 default: 98 usage(); 99 } 100 majno = (major_t)number(argv[3]); 101 if (majno == (major_t)-1 || majno > MAXMAJ) { 102 (void) fprintf(stderr, "mknod: invalid major number " 103 "'%s' - valid range is 0-%lu\n", argv[3], MAXMAJ); 104 return (2); 105 } 106 minno = (minor_t)number(argv[4]); 107 if (minno == (minor_t)-1 || minno > MAXMIN) { 108 (void) fprintf(stderr, "mknod: invalid minor number " 109 "'%s' - valid range is 0-%lu\n", argv[4], MAXMIN); 110 return (2); 111 } 112 arg = makedev(majno, minno); 113 } else 114 usage(); 115 116 return (domk(argv[1], (mode | ACC), arg) ? 2 : 0); 117 } 118 119 static int 120 domk(const char *path, const mode_t mode, const dev_t arg) 121 { 122 int ec; 123 124 if ((ec = mknod(path, mode, arg)) == -1) { 125 perror("mknod"); 126 } else { 127 /* chown() return deliberately ignored */ 128 (void) chown(path, getuid(), getgid()); 129 } 130 return (ec); 131 } 132 133 static long 134 number(const char *s) 135 { 136 long n; 137 138 errno = 0; 139 n = strtol(s, NULL, 0); 140 if (errno != 0 || n < 0) 141 return (-1); 142 return (n); 143 } 144 145 static void 146 usage(void) 147 { 148 (void) fprintf(stderr, "usage: mknod name [ b/c major minor ] [ p ]\n"); 149 exit(2); 150 } 151