summaryrefslogtreecommitdiffstats
path: root/usr.bin/xinstall
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2013-01-11 20:53:28 +0000
committerbrooks <brooks@FreeBSD.org>2013-01-11 20:53:28 +0000
commit4bf0acc9bcbbd91fb107bcca34f1d2041801fa6c (patch)
tree4ae313f6369bc5e75b913bf2ee41423967ae9cc3 /usr.bin/xinstall
parentf96c80800115958325477d08a370cfbf85c9db80 (diff)
downloadFreeBSD-src-4bf0acc9bcbbd91fb107bcca34f1d2041801fa6c.zip
FreeBSD-src-4bf0acc9bcbbd91fb107bcca34f1d2041801fa6c.tar.gz
Implement the -N <dbdir> option which allows an alternate passwd and
group file to be used. This is useful for installing on systems where a user or group does not currently exist. Sponsored by: DARPA, AFRL Obtained from: NetBSD MFC after: 5 days
Diffstat (limited to 'usr.bin/xinstall')
-rw-r--r--usr.bin/xinstall/Makefile8
-rw-r--r--usr.bin/xinstall/install.117
-rw-r--r--usr.bin/xinstall/xinstall.c66
3 files changed, 61 insertions, 30 deletions
diff --git a/usr.bin/xinstall/Makefile b/usr.bin/xinstall/Makefile
index e6ff88e..2a2aace 100644
--- a/usr.bin/xinstall/Makefile
+++ b/usr.bin/xinstall/Makefile
@@ -3,6 +3,14 @@
PROG= xinstall
PROGNAME= install
+SRCS= xinstall.c getid.c
MAN= install.1
+.PATH: ${.CURDIR}/../../contrib/mtree
+CFLAGS+= -I${.CURDIR}/../../contrib/mtree
+CFLAGS+= -I${.CURDIR}/../../lib/libnetbsd
+
+DPADD+= ${LIBUTIL}
+LDADD+= -lutil
+
.include <bsd.prog.mk>
diff --git a/usr.bin/xinstall/install.1 b/usr.bin/xinstall/install.1
index 1c7c415..01b58dc 100644
--- a/usr.bin/xinstall/install.1
+++ b/usr.bin/xinstall/install.1
@@ -41,6 +41,7 @@
.Op Fl f Ar flags
.Op Fl g Ar group
.Op Fl m Ar mode
+.Op Fl N Ar dbdir
.Op Fl o Ar owner
.Ar file1 file2
.Nm
@@ -49,6 +50,7 @@
.Op Fl f Ar flags
.Op Fl g Ar group
.Op Fl m Ar mode
+.Op Fl N Ar dbdir
.Op Fl o Ar owner
.Ar file1 ... fileN directory
.Nm
@@ -56,6 +58,7 @@
.Op Fl v
.Op Fl g Ar group
.Op Fl m Ar mode
+.Op Fl N Ar dbdir
.Op Fl o Ar owner
.Ar directory ...
.Sh DESCRIPTION
@@ -124,6 +127,18 @@ The default mode is set to rwxr-xr-x (0755).
The specified mode may be either an octal or symbolic value; see
.Xr chmod 1
for a description of possible mode values.
+.It Fl N
+Use the user database text file
+.Pa master.passwd
+and group database text file
+.Pa group
+from
+.Ar dbdir ,
+rather than using the results from the system's
+.Xr getpwnam 3
+and
+.Xr getgrnam 3
+(and related) library calls.
.It Fl o
Specify an owner.
A numeric UID is allowed.
@@ -231,6 +246,8 @@ The default was changed to copy in
.Xr mv 1 ,
.Xr strip 1 ,
.Xr mmap 2 ,
+.Xr getgrnam 3 ,
+.Xr getpwnam 3 ,
.Xr chown 8
.Sh HISTORY
The
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c
index 583348a..74f9d20 100644
--- a/usr.bin/xinstall/xinstall.c
+++ b/usr.bin/xinstall/xinstall.c
@@ -62,6 +62,8 @@ __FBSDID("$FreeBSD$");
#include <sysexits.h>
#include <unistd.h>
+#include "mtree.h"
+
/* Bootstrap aid - this doesn't exist in most older releases */
#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1) /* from <sys/mman.h> */
@@ -74,8 +76,6 @@ __FBSDID("$FreeBSD$");
#define NOCHANGEBITS (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
#define BACKUP_SUFFIX ".old"
-static struct passwd *pp;
-static struct group *gp;
static gid_t gid;
static uid_t uid;
static int dobackup, docompare, dodir, dopreserve, dostrip, nommap, safecopy,
@@ -89,7 +89,7 @@ static int create_newfile(const char *, int, struct stat *);
static int create_tempfile(const char *, char *, size_t);
static void install(const char *, const char *, u_long, u_int);
static void install_dir(char *);
-static u_long numeric_id(const char *, const char *);
+static int parseid(const char *, id_t *);
static void strip(const char *);
static int trymmap(int);
static void usage(void);
@@ -107,7 +107,7 @@ main(int argc, char *argv[])
iflags = 0;
group = owner = NULL;
- while ((ch = getopt(argc, argv, "B:bCcdf:g:Mm:o:pSsv")) != -1)
+ while ((ch = getopt(argc, argv, "B:bCcdf:g:Mm:N:o:pSsv")) != -1)
switch((char)ch) {
case 'B':
suffix = optarg;
@@ -143,6 +143,11 @@ main(int argc, char *argv[])
mode = getmode(set, 0);
free(set);
break;
+ case 'N':
+ if (!setup_getid(optarg))
+ err(1, "Unable to use user and group "
+ "databases in `%s'", optarg);
+ break;
case 'o':
owner = optarg;
break;
@@ -186,18 +191,22 @@ main(int argc, char *argv[])
/* get group and owner id's */
if (group != NULL) {
- if ((gp = getgrnam(group)) != NULL)
- gid = gp->gr_gid;
- else
- gid = (gid_t)numeric_id(group, "group");
+ if (gid_from_group(group, &gid) == -1) {
+ id_t id;
+ if (!parseid(group, &id))
+ errx(1, "unknown group %s", group);
+ gid = id;
+ }
} else
gid = (gid_t)-1;
if (owner != NULL) {
- if ((pp = getpwnam(owner)) != NULL)
- uid = pp->pw_uid;
- else
- uid = (uid_t)numeric_id(owner, "user");
+ if (uid_from_user(owner, &uid) == -1) {
+ id_t id;
+ if (!parseid(owner, &id))
+ errx(1, "unknown user %s", owner);
+ uid = id;
+ }
} else
uid = (uid_t)-1;
@@ -244,23 +253,19 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
-static u_long
-numeric_id(const char *name, const char *type)
+/*
+ * parseid --
+ * parse uid or gid from arg into id, returning non-zero if successful
+ */
+static int
+parseid(const char *name, id_t *id)
{
- u_long val;
- char *ep;
-
- /*
- * XXX
- * We know that uid_t's and gid_t's are unsigned longs.
- */
+ char *ep;
errno = 0;
- val = strtoul(name, &ep, 10);
- if (errno)
- err(EX_NOUSER, "%s", name);
- if (*ep != '\0')
- errx(EX_NOUSER, "unknown %s %s", type, name);
- return (val);
+ *id = (id_t)strtoul(name, &ep, 10);
+ if (errno || *ep != '\0')
+ return (0);
+ return (1);
}
/*
@@ -786,10 +791,11 @@ usage(void)
{
(void)fprintf(stderr,
"usage: install [-bCcMpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n"
-" [-o owner] file1 file2\n"
+" [-N dbdir] [-o owner] file1 file2\n"
" install [-bCcMpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n"
-" [-o owner] file1 ... fileN directory\n"
-" install -d [-v] [-g group] [-m mode] [-o owner] directory ...\n");
+" [-N dbdir] [-o owner] file1 ... fileN directory\n"
+" install -d [-v] [-g group] [-m mode] [-N dbdir] [-o owner]\n"
+" directory ...\n");
exit(EX_USAGE);
/* NOTREACHED */
}
OpenPOWER on IntegriCloud