11558Srgrimes/* 21558Srgrimes * Copyright (c) 1989, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * This code is derived from software contributed to Berkeley by 61558Srgrimes * Kevin Fall. 71558Srgrimes * 81558Srgrimes * Redistribution and use in source and binary forms, with or without 91558Srgrimes * modification, are permitted provided that the following conditions 101558Srgrimes * are met: 111558Srgrimes * 1. Redistributions of source code must retain the above copyright 121558Srgrimes * notice, this list of conditions and the following disclaimer. 131558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141558Srgrimes * notice, this list of conditions and the following disclaimer in the 151558Srgrimes * documentation and/or other materials provided with the distribution. 161558Srgrimes * 4. Neither the name of the University nor the names of its contributors 171558Srgrimes * may be used to endorse or promote products derived from this software 181558Srgrimes * without specific prior written permission. 191558Srgrimes * 201558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301558Srgrimes * SUCH DAMAGE. 311558Srgrimes */ 321558Srgrimes 331558Srgrimes#ifndef lint 3417347Sbdestatic const char copyright[] = 351558Srgrimes"@(#) Copyright (c) 1989, 1993\n\ 361558Srgrimes The Regents of the University of California. All rights reserved.\n"; 371558Srgrimes#endif /* not lint */ 381558Srgrimes 391558Srgrimes#ifndef lint 4017347Sbde#if 0 411558Srgrimesstatic char sccsid[] = "@(#)mknod.c 8.1 (Berkeley) 6/5/93"; 4237422Scharnier#endif 4317347Sbdestatic const char rcsid[] = 4450476Speter "$FreeBSD$"; 451558Srgrimes#endif /* not lint */ 461558Srgrimes 471558Srgrimes#include <sys/types.h> 481558Srgrimes#include <sys/stat.h> 4917347Sbde 5037422Scharnier#include <err.h> 5117347Sbde#include <errno.h> 521558Srgrimes#include <stdio.h> 5317347Sbde#include <stdlib.h> 5417347Sbde#include <unistd.h> 5555496Sobrien#include <grp.h> 5655496Sobrien#include <pwd.h> 5755496Sobrien#include <string.h> 581558Srgrimes 5937422Scharnierstatic void 60170653Sdelphijusage(void) 6137422Scharnier{ 6255496Sobrien 6355496Sobrien (void)fprintf(stderr, 64203277Sed "usage: mknod name\n" 65203277Sed " mknod name [b | c] major minor [owner:group]\n"); 6637422Scharnier exit(1); 6737422Scharnier} 6837422Scharnier 6955496Sobrienstatic u_long 70170653Sdelphijid(const char *name, const char *type) 7155496Sobrien{ 7255496Sobrien u_long val; 7355496Sobrien char *ep; 7455496Sobrien 7555496Sobrien /* 7655496Sobrien * XXX 7755496Sobrien * We know that uid_t's and gid_t's are unsigned longs. 7855496Sobrien */ 7955496Sobrien errno = 0; 8055496Sobrien val = strtoul(name, &ep, 10); 8155496Sobrien if (errno) 8255496Sobrien err(1, "%s", name); 8355496Sobrien if (*ep != '\0') 8455496Sobrien errx(1, "%s: illegal %s name", name, type); 8555496Sobrien return (val); 8655496Sobrien} 8755496Sobrien 8855496Sobrienstatic gid_t 89170653Sdelphija_gid(const char *s) 9055496Sobrien{ 9155496Sobrien struct group *gr; 9255496Sobrien 9355496Sobrien if (*s == '\0') /* Argument was "uid[:.]". */ 9455496Sobrien errx(1, "group must be specified when the owner is"); 9555496Sobrien return ((gr = getgrnam(s)) == NULL) ? id(s, "group") : gr->gr_gid; 9655496Sobrien} 9755496Sobrien 9855496Sobrienstatic uid_t 99170653Sdelphija_uid(const char *s) 10055496Sobrien{ 10155496Sobrien struct passwd *pw; 10255496Sobrien 10355496Sobrien if (*s == '\0') /* Argument was "[:.]gid". */ 10455496Sobrien errx(1, "owner must be specified when the group is"); 10555496Sobrien return ((pw = getpwnam(s)) == NULL) ? id(s, "user") : pw->pw_uid; 10655496Sobrien} 10755496Sobrien 10817347Sbdeint 109170653Sdelphijmain(int argc, char **argv) 1101558Srgrimes{ 11155496Sobrien int range_error; 11255496Sobrien uid_t uid; 11355496Sobrien gid_t gid; 11455496Sobrien mode_t mode; 11517347Sbde dev_t dev; 11655496Sobrien char *cp, *endp; 11746859Sphk long mymajor, myminor; 1181558Srgrimes 119203277Sed if (argc != 2 && argc != 5 && argc != 6) 12037422Scharnier usage(); 1211558Srgrimes 122203277Sed if (argc >= 5) { 123203277Sed mode = 0666; 124203277Sed if (argv[2][0] == 'c') 125203277Sed mode |= S_IFCHR; 126203277Sed else if (argv[2][0] == 'b') 127203277Sed mode |= S_IFBLK; 128203277Sed else 129203277Sed errx(1, "node must be type 'b' or 'c'"); 1301558Srgrimes 131203277Sed errno = 0; 132203277Sed mymajor = (long)strtoul(argv[3], &endp, 0); 133203277Sed if (endp == argv[3] || *endp != '\0') 134203277Sed errx(1, "%s: non-numeric major number", argv[3]); 135203277Sed range_error = errno; 136203277Sed errno = 0; 137203277Sed myminor = (long)strtoul(argv[4], &endp, 0); 138203277Sed if (endp == argv[4] || *endp != '\0') 139203277Sed errx(1, "%s: non-numeric minor number", argv[4]); 140203277Sed range_error |= errno; 141203277Sed dev = makedev(mymajor, myminor); 142215704Sbrucec if (range_error || major(dev) != mymajor || 143203277Sed (long)(u_int)minor(dev) != myminor) 144203277Sed errx(1, "major or minor number too large"); 145203277Sed } else { 146203277Sed mode = 0666 | S_IFCHR; 147203277Sed dev = 0; 148203277Sed } 14917302Sjoerg 15055496Sobrien uid = gid = -1; 15155496Sobrien if (6 == argc) { 15255496Sobrien /* have owner:group */ 15355496Sobrien if ((cp = strchr(argv[5], ':')) != NULL) { 15455496Sobrien *cp++ = '\0'; 15555496Sobrien gid = a_gid(cp); 15655496Sobrien } else 15755496Sobrien usage(); 15855496Sobrien uid = a_uid(argv[5]); 15955496Sobrien } 16055496Sobrien 16126674Scharnier if (mknod(argv[1], mode, dev) != 0) 16226674Scharnier err(1, "%s", argv[1]); 16355496Sobrien if (6 == argc) 16455496Sobrien if (chown(argv[1], uid, gid)) 16555496Sobrien err(1, "setting ownership on %s", argv[1]); 1661558Srgrimes exit(0); 1671558Srgrimes} 168