aboutsummaryrefslogtreecommitdiff
path: root/sbin/mknod
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2000-01-06 05:20:14 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2000-01-06 05:20:14 +0000
commit2dc152529e1e81a7ffe584080625bb7b02acdd7b (patch)
tree4b49f8321612878797a0a5dedbd3e837cb519218 /sbin/mknod
parent833f7023485f5869598f9e6e3635e859ca63bd6d (diff)
downloadsrc-2dc152529e1e81a7ffe584080625bb7b02acdd7b.tar.gz
src-2dc152529e1e81a7ffe584080625bb7b02acdd7b.zip
Add chown(8)-like functionality. This will allow us to not use chown(8)
in MAKEDEV(8) -- removing the need of having /usr mounted.
Notes
Notes: svn path=/head/; revision=55496
Diffstat (limited to 'sbin/mknod')
-rw-r--r--sbin/mknod/mknod.831
-rw-r--r--sbin/mknod/mknod.c73
2 files changed, 98 insertions, 6 deletions
diff --git a/sbin/mknod/mknod.8 b/sbin/mknod/mknod.8
index 8994d091bb98..2232c9a5224b 100644
--- a/sbin/mknod/mknod.8
+++ b/sbin/mknod/mknod.8
@@ -43,6 +43,7 @@
.Ar name
.Op Cm c | Cm b
.Ar major minor
+.Op owner:group
.Sh DESCRIPTION
The
.Nm mknod
@@ -90,6 +91,23 @@ The minor device number tells the kernel which subunit
the node corresponds to on the device; for example,
a subunit may be a filesystem partition
or a tty line.
+.It Ar "owner \: group"
+The
+.Ar owner
+.Ar group
+operand pair is optional, however, if one is specified, they both must be
+specified.
+The
+.Ar owner
+may be either a numeric user ID or a user name.
+If a user name is also a numeric user ID, the operand is used as a
+user name.
+The
+.Ar group
+may be either a numeric group ID or a group name.
+Simular to the user name,
+if a group name is also a numeric group ID, the operand is used as a
+group name.
.El
.Pp
Major and minor device numbers can be given in any format acceptable to
@@ -99,10 +117,21 @@ so that a leading
indicates a hexadecimal number, and a leading
.Ql 0
will cause the number to be interpreted as octal.
+.Sh COMPATIBILITY
+The
+.Xr chown 8
+like functionality is specific to
+.Fx
+and was added so that
+.Pa /dev/MAKEDEV
+wound not depend on
+.Pa /usr
+being mounted.
.Sh SEE ALSO
.Xr mkfifo 1 ,
.Xr mknod 2 ,
-.Xr MAKEDEV 8
+.Xr MAKEDEV 8 ,
+.Xr chown 8
.Sh HISTORY
A
.Nm
diff --git a/sbin/mknod/mknod.c b/sbin/mknod/mknod.c
index 822d5f2cd149..98c0612a4295 100644
--- a/sbin/mknod/mknod.c
+++ b/sbin/mknod/mknod.c
@@ -56,26 +56,75 @@ static const char rcsid[] =
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <grp.h>
+#include <pwd.h>
+#include <string.h>
static void
usage()
{
- (void)fprintf(stderr, "usage: mknod name [b | c] major minor\n");
+
+ (void)fprintf(stderr,
+ "usage: mknod name [b | c] major minor [owner:group]\n");
exit(1);
}
+static u_long
+id(name, type)
+ char *name, *type;
+{
+ u_long val;
+ char *ep;
+
+ /*
+ * XXX
+ * We know that uid_t's and gid_t's are unsigned longs.
+ */
+ errno = 0;
+ val = strtoul(name, &ep, 10);
+ if (errno)
+ err(1, "%s", name);
+ if (*ep != '\0')
+ errx(1, "%s: illegal %s name", name, type);
+ return (val);
+}
+
+static gid_t
+a_gid(s)
+ char *s;
+{
+ struct group *gr;
+
+ if (*s == '\0') /* Argument was "uid[:.]". */
+ errx(1, "group must be specified when the owner is");
+ return ((gr = getgrnam(s)) == NULL) ? id(s, "group") : gr->gr_gid;
+}
+
+static uid_t
+a_uid(s)
+ char *s;
+{
+ struct passwd *pw;
+
+ if (*s == '\0') /* Argument was "[:.]gid". */
+ errx(1, "owner must be specified when the group is");
+ return ((pw = getpwnam(s)) == NULL) ? id(s, "user") : pw->pw_uid;
+}
+
int
main(argc, argv)
int argc;
char **argv;
{
+ int range_error;
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
dev_t dev;
- char *endp;
+ char *cp, *endp;
long mymajor, myminor;
- mode_t mode;
- int range_error;
- if (argc != 5)
+ if (argc != 5 && argc != 6)
usage();
mode = 0666;
@@ -101,7 +150,21 @@ main(argc, argv)
minor(dev) != (u_int) myminor)
errx(1, "major or minor number too large");
+ uid = gid = -1;
+ if (6 == argc) {
+ /* have owner:group */
+ if ((cp = strchr(argv[5], ':')) != NULL) {
+ *cp++ = '\0';
+ gid = a_gid(cp);
+ } else
+ usage();
+ uid = a_uid(argv[5]);
+ }
+
if (mknod(argv[1], mode, dev) != 0)
err(1, "%s", argv[1]);
+ if (6 == argc)
+ if (chown(argv[1], uid, gid))
+ err(1, "setting ownership on %s", argv[1]);
exit(0);
}