Add chown(8)-like functionality. This will allow us to not use chown(8)

in MAKEDEV(8) -- removing the need of having /usr mounted.
This commit is contained in:
obrien 2000-01-06 05:20:14 +00:00
parent 2da2a05a1b
commit f614e0ccf6
2 changed files with 99 additions and 7 deletions

View File

@ -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

View File

@ -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;
{
dev_t dev;
char *endp;
long mymajor, myminor;
mode_t mode;
int range_error;
uid_t uid;
gid_t gid;
mode_t mode;
dev_t dev;
char *cp, *endp;
long mymajor, myminor;
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);
}