18fae3551SRodney W. Grimes /* 28fae3551SRodney W. Grimes * Copyright (c) 1989, 1993 38fae3551SRodney W. Grimes * The Regents of the University of California. All rights reserved. 48fae3551SRodney W. Grimes * 58fae3551SRodney W. Grimes * This code is derived from software contributed to Berkeley by 68fae3551SRodney W. Grimes * Kevin Fall. 78fae3551SRodney W. Grimes * 88fae3551SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 98fae3551SRodney W. Grimes * modification, are permitted provided that the following conditions 108fae3551SRodney W. Grimes * are met: 118fae3551SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 128fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 138fae3551SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 148fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 158fae3551SRodney W. Grimes * documentation and/or other materials provided with the distribution. 168fae3551SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 178fae3551SRodney W. Grimes * may be used to endorse or promote products derived from this software 188fae3551SRodney W. Grimes * without specific prior written permission. 198fae3551SRodney W. Grimes * 208fae3551SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 218fae3551SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 228fae3551SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 238fae3551SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 248fae3551SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 258fae3551SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 268fae3551SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 278fae3551SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 288fae3551SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 298fae3551SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 308fae3551SRodney W. Grimes * SUCH DAMAGE. 318fae3551SRodney W. Grimes */ 328fae3551SRodney W. Grimes 338fae3551SRodney W. Grimes #ifndef lint 347c9e694fSBruce Evans static const char copyright[] = 358fae3551SRodney W. Grimes "@(#) Copyright (c) 1989, 1993\n\ 368fae3551SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 378fae3551SRodney W. Grimes #endif /* not lint */ 388fae3551SRodney W. Grimes 398fae3551SRodney W. Grimes #ifndef lint 407c9e694fSBruce Evans #if 0 418fae3551SRodney W. Grimes static char sccsid[] = "@(#)mknod.c 8.1 (Berkeley) 6/5/93"; 427c9e694fSBruce Evans #endif 43fbb3447fSPhilippe Charnier static const char rcsid[] = 447f3dea24SPeter Wemm "$FreeBSD$"; 458fae3551SRodney W. Grimes #endif /* not lint */ 468fae3551SRodney W. Grimes 478fae3551SRodney W. Grimes #include <sys/types.h> 488fae3551SRodney W. Grimes #include <sys/stat.h> 498fae3551SRodney W. Grimes 50fbb3447fSPhilippe Charnier #include <err.h> 517c9e694fSBruce Evans #include <errno.h> 527c9e694fSBruce Evans #include <stdio.h> 537c9e694fSBruce Evans #include <stdlib.h> 547c9e694fSBruce Evans #include <unistd.h> 552dc15252SDavid E. O'Brien #include <grp.h> 562dc15252SDavid E. O'Brien #include <pwd.h> 572dc15252SDavid E. O'Brien #include <string.h> 58fbb3447fSPhilippe Charnier 59fbb3447fSPhilippe Charnier static void 605224d0a1SXin LI usage(void) 61fbb3447fSPhilippe Charnier { 622dc15252SDavid E. O'Brien 632dc15252SDavid E. O'Brien (void)fprintf(stderr, 642dc15252SDavid E. O'Brien "usage: mknod name [b | c] major minor [owner:group]\n"); 65fbb3447fSPhilippe Charnier exit(1); 66fbb3447fSPhilippe Charnier } 677c9e694fSBruce Evans 682dc15252SDavid E. O'Brien static u_long 695224d0a1SXin LI id(const char *name, const char *type) 702dc15252SDavid E. O'Brien { 712dc15252SDavid E. O'Brien u_long val; 722dc15252SDavid E. O'Brien char *ep; 732dc15252SDavid E. O'Brien 742dc15252SDavid E. O'Brien /* 752dc15252SDavid E. O'Brien * XXX 762dc15252SDavid E. O'Brien * We know that uid_t's and gid_t's are unsigned longs. 772dc15252SDavid E. O'Brien */ 782dc15252SDavid E. O'Brien errno = 0; 792dc15252SDavid E. O'Brien val = strtoul(name, &ep, 10); 802dc15252SDavid E. O'Brien if (errno) 812dc15252SDavid E. O'Brien err(1, "%s", name); 822dc15252SDavid E. O'Brien if (*ep != '\0') 832dc15252SDavid E. O'Brien errx(1, "%s: illegal %s name", name, type); 842dc15252SDavid E. O'Brien return (val); 852dc15252SDavid E. O'Brien } 862dc15252SDavid E. O'Brien 872dc15252SDavid E. O'Brien static gid_t 885224d0a1SXin LI a_gid(const char *s) 892dc15252SDavid E. O'Brien { 902dc15252SDavid E. O'Brien struct group *gr; 912dc15252SDavid E. O'Brien 922dc15252SDavid E. O'Brien if (*s == '\0') /* Argument was "uid[:.]". */ 932dc15252SDavid E. O'Brien errx(1, "group must be specified when the owner is"); 942dc15252SDavid E. O'Brien return ((gr = getgrnam(s)) == NULL) ? id(s, "group") : gr->gr_gid; 952dc15252SDavid E. O'Brien } 962dc15252SDavid E. O'Brien 972dc15252SDavid E. O'Brien static uid_t 985224d0a1SXin LI a_uid(const char *s) 992dc15252SDavid E. O'Brien { 1002dc15252SDavid E. O'Brien struct passwd *pw; 1012dc15252SDavid E. O'Brien 1022dc15252SDavid E. O'Brien if (*s == '\0') /* Argument was "[:.]gid". */ 1032dc15252SDavid E. O'Brien errx(1, "owner must be specified when the group is"); 1042dc15252SDavid E. O'Brien return ((pw = getpwnam(s)) == NULL) ? id(s, "user") : pw->pw_uid; 1052dc15252SDavid E. O'Brien } 1062dc15252SDavid E. O'Brien 1077c9e694fSBruce Evans int 1085224d0a1SXin LI main(int argc, char **argv) 1098fae3551SRodney W. Grimes { 1107c9e694fSBruce Evans int range_error; 1112dc15252SDavid E. O'Brien uid_t uid; 1122dc15252SDavid E. O'Brien gid_t gid; 1132dc15252SDavid E. O'Brien mode_t mode; 1142dc15252SDavid E. O'Brien dev_t dev; 1152dc15252SDavid E. O'Brien char *cp, *endp; 1162dc15252SDavid E. O'Brien long mymajor, myminor; 1178fae3551SRodney W. Grimes 1182dc15252SDavid E. O'Brien if (argc != 5 && argc != 6) 119fbb3447fSPhilippe Charnier usage(); 1208fae3551SRodney W. Grimes 1218fae3551SRodney W. Grimes mode = 0666; 1228fae3551SRodney W. Grimes if (argv[2][0] == 'c') 1238fae3551SRodney W. Grimes mode |= S_IFCHR; 1248fae3551SRodney W. Grimes else if (argv[2][0] == 'b') 1258fae3551SRodney W. Grimes mode |= S_IFBLK; 12686eaffafSPhilippe Charnier else 12786eaffafSPhilippe Charnier errx(1, "node must be type 'b' or 'c'"); 1288fae3551SRodney W. Grimes 1297c9e694fSBruce Evans errno = 0; 13095b9c18aSPoul-Henning Kamp mymajor = (long)strtoul(argv[3], &endp, 0); 13186eaffafSPhilippe Charnier if (endp == argv[3] || *endp != '\0') 13286eaffafSPhilippe Charnier errx(1, "%s: non-numeric major number", argv[3]); 1337c9e694fSBruce Evans range_error = errno; 1347c9e694fSBruce Evans errno = 0; 13595b9c18aSPoul-Henning Kamp myminor = (long)strtoul(argv[4], &endp, 0); 13686eaffafSPhilippe Charnier if (endp == argv[4] || *endp != '\0') 13786eaffafSPhilippe Charnier errx(1, "%s: non-numeric minor number", argv[4]); 1387c9e694fSBruce Evans range_error |= errno; 13995b9c18aSPoul-Henning Kamp dev = makedev(mymajor, myminor); 14025412fdfSMatt Jacob if (range_error || major(dev) != (u_int) mymajor || 14198397198SXin LI (long)(u_int)minor(dev) != myminor) 14286eaffafSPhilippe Charnier errx(1, "major or minor number too large"); 143ce6bb537SJoerg Wunsch 1442dc15252SDavid E. O'Brien uid = gid = -1; 1452dc15252SDavid E. O'Brien if (6 == argc) { 1462dc15252SDavid E. O'Brien /* have owner:group */ 1472dc15252SDavid E. O'Brien if ((cp = strchr(argv[5], ':')) != NULL) { 1482dc15252SDavid E. O'Brien *cp++ = '\0'; 1492dc15252SDavid E. O'Brien gid = a_gid(cp); 1502dc15252SDavid E. O'Brien } else 1512dc15252SDavid E. O'Brien usage(); 1522dc15252SDavid E. O'Brien uid = a_uid(argv[5]); 1532dc15252SDavid E. O'Brien } 1542dc15252SDavid E. O'Brien 15586eaffafSPhilippe Charnier if (mknod(argv[1], mode, dev) != 0) 15686eaffafSPhilippe Charnier err(1, "%s", argv[1]); 1572dc15252SDavid E. O'Brien if (6 == argc) 1582dc15252SDavid E. O'Brien if (chown(argv[1], uid, gid)) 1592dc15252SDavid E. O'Brien err(1, "setting ownership on %s", argv[1]); 1608fae3551SRodney W. Grimes exit(0); 1618fae3551SRodney W. Grimes } 162