summaryrefslogtreecommitdiff
path: root/usr.bin/xinstall
diff options
context:
space:
mode:
authorRodney W. Grimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
committerRodney W. Grimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
commit9b50d9027575220cb6dd09b3e62f03f511e908b8 (patch)
treedefc987843071f19a5891a97145437d43cba2af8 /usr.bin/xinstall
parentefd31c5952bb9bb2485c109382100127424f8611 (diff)
downloadsrc-test2-9b50d9027575220cb6dd09b3e62f03f511e908b8.tar.gz
src-test2-9b50d9027575220cb6dd09b3e62f03f511e908b8.zip
Notes
Diffstat (limited to 'usr.bin/xinstall')
-rw-r--r--usr.bin/xinstall/Makefile12
-rw-r--r--usr.bin/xinstall/install.1124
-rw-r--r--usr.bin/xinstall/pathnames.h36
-rw-r--r--usr.bin/xinstall/xinstall.c358
4 files changed, 530 insertions, 0 deletions
diff --git a/usr.bin/xinstall/Makefile b/usr.bin/xinstall/Makefile
new file mode 100644
index 000000000000..69de3ab13bd7
--- /dev/null
+++ b/usr.bin/xinstall/Makefile
@@ -0,0 +1,12 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= xinstall
+SRCS= stat_flags.c xinstall.c
+MAN1= install.0
+.PATH: ${.CURDIR}/../../bin/ls
+
+install: maninstall
+ install ${STRIP} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ ${PROG} ${DESTDIR}${BINDIR}/install
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/xinstall/install.1 b/usr.bin/xinstall/install.1
new file mode 100644
index 000000000000..c35c7a5bd792
--- /dev/null
+++ b/usr.bin/xinstall/install.1
@@ -0,0 +1,124 @@
+.\" Copyright (c) 1987, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)install.1 8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt INSTALL 1
+.Os BSD 4.2
+.Sh NAME
+.Nm install
+.Nd install binaries
+.Sh SYNOPSIS
+.Nm install
+.Op Fl cs
+.Op Fl f Ar flags
+.Op Fl g Ar group
+.Op Fl m Ar mode
+.Op Fl o Ar owner
+.Ar file1 file2
+.Nm install
+.Op Fl cs
+.Op Fl f Ar flags
+.Op Fl g Ar group
+.Op Fl m Ar mode
+.Op Fl o Ar owner
+.Ar file1
+\&...
+.Ar fileN directory
+.Sh DESCRIPTION
+The file(s) are moved (or copied if the
+.Fl c
+option is specified) to the target file or directory.
+If the destination is a directory, then the
+.Ar file
+is moved into
+.Ar directory
+with its original filename.
+If the target file already exists, it is overwritten if permissions
+allow.
+.Pp
+.Bl -tag -width Ds
+.It Fl c
+Copy the file.
+This flag turns off the default behavior of
+.Nm install
+where it deletes the original file after creating the target.
+.It Fl f
+Specify the target's file flags.
+(See
+.Xr chflags 1
+for a list of possible flags and their meanings.)
+.It Fl g
+Specify a group.
+.It Fl m
+Specify an alternate mode.
+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 o
+Specify an owner.
+.It Fl s
+.Nm Install
+exec's the command
+.Xr strip 1
+to strip binaries so that install can be portable over a large
+number of systems and binary types.
+.El
+.Pp
+By default,
+.Nm install
+preserves all file flags, with the exception of the ``nodump'' flag.
+.Pp
+The
+.Nm install
+utility attempts to prevent moving a file onto itself.
+.Pp
+Installing
+.Pa /dev/null
+creates an empty file.
+.Pp
+Upon successful completion a value of 0 is returned.
+Otherwise, a value of 1 is returned.
+.Sh SEE ALSO
+.Xr chflags 1 ,
+.Xr chgrp 1 ,
+.Xr chmod 1 ,
+.Xr cp 1 ,
+.Xr mv 1 ,
+.Xr strip 1 ,
+.Xr chown 8
+.Sh HISTORY
+The
+.Nm install
+utility appeared in
+.Bx 4.2 .
diff --git a/usr.bin/xinstall/pathnames.h b/usr.bin/xinstall/pathnames.h
new file mode 100644
index 000000000000..853b83c0244e
--- /dev/null
+++ b/usr.bin/xinstall/pathnames.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define _PATH_STRIP "/usr/bin/strip"
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c
new file mode 100644
index 000000000000..4c41fa805105
--- /dev/null
+++ b/usr.bin/xinstall/xinstall.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1987, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)xinstall.c 8.1 (Berkeley) 7/21/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pathnames.h"
+
+struct passwd *pp;
+struct group *gp;
+int docopy, dostrip;
+int mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
+char *group, *owner, pathbuf[MAXPATHLEN];
+
+#define DIRECTORY 0x01 /* Tell install it's a directory. */
+#define SETFLAGS 0x02 /* Tell install to set flags. */
+
+void copy __P((int, char *, int, char *, off_t));
+void err __P((const char *, ...));
+void install __P((char *, char *, u_long, u_int));
+u_long string_to_flags __P((char **, u_long *, u_long *));
+void strip __P((char *));
+void usage __P((void));
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct stat from_sb, to_sb;
+ mode_t *set;
+ u_long fset;
+ u_int iflags;
+ int ch, no_target;
+ char *flags, *to_name;
+
+ iflags = 0;
+ while ((ch = getopt(argc, argv, "cf:g:m:o:s")) != EOF)
+ switch((char)ch) {
+ case 'c':
+ docopy = 1;
+ break;
+ case 'f':
+ flags = optarg;
+ if (string_to_flags(&flags, &fset, NULL))
+ err("%s: invalid flag", flags);
+ iflags |= SETFLAGS;
+ break;
+ case 'g':
+ group = optarg;
+ break;
+ case 'm':
+ if (!(set = setmode(optarg)))
+ err("%s: invalid file mode", optarg);
+ mode = getmode(set, 0);
+ break;
+ case 'o':
+ owner = optarg;
+ break;
+ case 's':
+ dostrip = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc < 2)
+ usage();
+
+ /* get group and owner id's */
+ if (group && !(gp = getgrnam(group)))
+ err("unknown group %s", group);
+ if (owner && !(pp = getpwnam(owner)))
+ err("unknown user %s", owner);
+
+ no_target = stat(to_name = argv[argc - 1], &to_sb);
+ if (!no_target && (to_sb.st_mode & S_IFMT) == S_IFDIR) {
+ for (; *argv != to_name; ++argv)
+ install(*argv, to_name, fset, iflags | DIRECTORY);
+ exit(0);
+ }
+
+ /* can't do file1 file2 directory/file */
+ if (argc != 2)
+ usage();
+
+ if (!no_target) {
+ if (stat(*argv, &from_sb))
+ err("%s: %s", *argv, strerror(errno));
+ if (!S_ISREG(to_sb.st_mode))
+ err("%s: %s", to_name, strerror(EFTYPE));
+ if (to_sb.st_dev == from_sb.st_dev &&
+ to_sb.st_ino == from_sb.st_ino)
+ err("%s and %s are the same file", *argv, to_name);
+ /*
+ * Unlink now... avoid ETXTBSY errors later. Try and turn
+ * off the append/immutable bits -- if we fail, go ahead,
+ * it might work.
+ */
+#define NOCHANGEBITS (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
+ if (to_sb.st_flags & NOCHANGEBITS)
+ (void)chflags(to_name,
+ to_sb.st_flags & ~(NOCHANGEBITS));
+ (void)unlink(to_name);
+ }
+ install(*argv, to_name, fset, iflags);
+ exit(0);
+}
+
+/*
+ * install --
+ * build a path name and install the file
+ */
+void
+install(from_name, to_name, fset, flags)
+ char *from_name, *to_name;
+ u_long fset;
+ u_int flags;
+{
+ struct stat from_sb, to_sb;
+ int devnull, from_fd, to_fd, serrno;
+ char *p;
+
+ /* If try to install NULL file to a directory, fails. */
+ if (flags & DIRECTORY || strcmp(from_name, _PATH_DEVNULL)) {
+ if (stat(from_name, &from_sb))
+ err("%s: %s", from_name, strerror(errno));
+ if (!S_ISREG(from_sb.st_mode))
+ err("%s: %s", from_name, strerror(EFTYPE));
+ /* Build the target path. */
+ if (flags & DIRECTORY) {
+ (void)snprintf(pathbuf, sizeof(pathbuf), "%s/%s",
+ to_name,
+ (p = rindex(from_name, '/')) ? ++p : from_name);
+ to_name = pathbuf;
+ }
+ devnull = 0;
+ } else {
+ from_sb.st_flags = 0; /* XXX */
+ devnull = 1;
+ }
+
+ /*
+ * Unlink now... avoid ETXTBSY errors later. Try and turn
+ * off the append/immutable bits -- if we fail, go ahead,
+ * it might work.
+ */
+ if (stat(to_name, &to_sb) == 0 &&
+ to_sb.st_flags & (NOCHANGEBITS))
+ (void)chflags(to_name, to_sb.st_flags & ~(NOCHANGEBITS));
+ (void)unlink(to_name);
+
+ /* Create target. */
+ if ((to_fd = open(to_name,
+ O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)) < 0)
+ err("%s: %s", to_name, strerror(errno));
+ if (!devnull) {
+ if ((from_fd = open(from_name, O_RDONLY, 0)) < 0) {
+ (void)unlink(to_name);
+ err("%s: %s", from_name, strerror(errno));
+ }
+ copy(from_fd, from_name, to_fd, to_name, from_sb.st_size);
+ (void)close(from_fd);
+ }
+ if (dostrip)
+ strip(to_name);
+ /*
+ * Set owner, group, mode for target; do the chown first,
+ * chown may lose the setuid bits.
+ */
+ if ((group || owner) &&
+ fchown(to_fd, owner ? pp->pw_uid : -1, group ? gp->gr_gid : -1)) {
+ serrno = errno;
+ (void)unlink(to_name);
+ err("%s: chown/chgrp: %s", to_name, strerror(serrno));
+ }
+ if (fchmod(to_fd, mode)) {
+ serrno = errno;
+ (void)unlink(to_name);
+ err("%s: chmod: %s", to_name, strerror(serrno));
+ }
+
+ /*
+ * If provided a set of flags, set them, otherwise, preserve the
+ * flags, except for the dump flag.
+ */
+ if (fchflags(to_fd,
+ flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) {
+ serrno = errno;
+ (void)unlink(to_name);
+ err("%s: chflags: %s", to_name, strerror(serrno));
+ }
+
+ (void)close(to_fd);
+ if (!docopy && !devnull && unlink(from_name))
+ err("%s: %s", from_name, strerror(errno));
+}
+
+/*
+ * copy --
+ * copy from one file to another
+ */
+void
+copy(from_fd, from_name, to_fd, to_name, size)
+ register int from_fd, to_fd;
+ char *from_name, *to_name;
+ off_t size;
+{
+ register int nr, nw;
+ int serrno;
+ char *p, buf[MAXBSIZE];
+
+ /*
+ * Mmap and write if less than 8M (the limit is so we don't totally
+ * trash memory on big files. This is really a minor hack, but it
+ * wins some CPU back.
+ */
+ if (size <= 8 * 1048576) {
+ if ((p = mmap(NULL, (size_t)size, PROT_READ,
+ 0, from_fd, (off_t)0)) == (char *)-1)
+ err("%s: %s", from_name, strerror(errno));
+ if (write(to_fd, p, size) != size)
+ err("%s: %s", to_name, strerror(errno));
+ } else {
+ while ((nr = read(from_fd, buf, sizeof(buf))) > 0)
+ if ((nw = write(to_fd, buf, nr)) != nr) {
+ serrno = errno;
+ (void)unlink(to_name);
+ err("%s: %s",
+ to_name, strerror(nw > 0 ? EIO : serrno));
+ }
+ if (nr != 0) {
+ serrno = errno;
+ (void)unlink(to_name);
+ err("%s: %s", from_name, strerror(serrno));
+ }
+ }
+}
+
+/*
+ * strip --
+ * use strip(1) to strip the target file
+ */
+void
+strip(to_name)
+ char *to_name;
+{
+ int serrno, status;
+
+ switch (vfork()) {
+ case -1:
+ serrno = errno;
+ (void)unlink(to_name);
+ err("forks: %s", strerror(errno));
+ case 0:
+ execl(_PATH_STRIP, "strip", to_name, NULL);
+ err("%s: %s", _PATH_STRIP, strerror(errno));
+ default:
+ if (wait(&status) == -1 || status)
+ (void)unlink(to_name);
+ }
+}
+
+/*
+ * usage --
+ * print a usage message and die
+ */
+void
+usage()
+{
+ (void)fprintf(stderr,
+"usage: install [-cs] [-f flags] [-g group] [-m mode] [-o owner] file1 file2;\n\tor file1 ... fileN directory\n");
+ exit(1);
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+err(const char *fmt, ...)
+#else
+err(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void)fprintf(stderr, "install: ");
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ exit(1);
+ /* NOTREACHED */
+}