.\" $Id: install.man,v 8.15 2012/09/06 18:07:46 ksb Exp $ .\" Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana .\" 47907. All rights reserved. .\" $Compile: Display%h .\" $Display: ${groff:-groff} -tbl -Tascii -man %f | ${PAGER:-less} .\" $Install: %b -mDeinstall %o %f && cp %f $DESTDIR/usr/local/man/man1/install.1 .\" $Deinstall: ${rm-rm} -f $DESTDIR/usr/local/man/[cm]a[nt]1/install.1* .\" .\" Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb .\" Jeff Smith, jsmith@cc.purdue.edu, purdue!jsmith .\" .\" This software is not subject to any license of the American Telephone .\" and Telegraph Company or the Regents of the University of California. .\" .\" Permission is granted to anyone to use this software for any purpose on .\" any computer system, and to alter it and redistribute it freely, subject .\" to the following restrictions: .\" .\" 1. Neither the authors nor Purdue University are responsible for any .\" consequences of the use of this software. .\" .\" 2. The origin of this software must not be misrepresented, either by .\" explicit claim or by omission. Credit to the authors and Purdue .\" University must appear in documentation and sources. .\" .\" 3. Altered versions must be plainly marked as such, and must not be .\" misrepresented as being the original software. .\" .\" 4. This notice may not be removed or altered. .\" .TH INSTALL 1 LOCAL .SH NAME install - update files or directories in a controlled environment .SH SYNOPSIS .ds PN "install \fI\*(PN\fP [\fB\-1DclnNpqsv\fP] [\fB\-C\fP\~\fIchecklist\fP] [\fB\-H\fP\~\fIhardlinks\fP] [\fB\-S\fP\~\fIsymlinks\fP] [\fB\-g\fP\~\fIgroup\fP] [\fB\-m\fP\~\fImode\fP] [\fB\-o\fP\~\fIowner\fP] \fIfiles\fP \fIdestination\fP .sp 1 \fI\*(PN\fP \fB\-d\fP [\fB\-hnqrv\fP] [\fB\-C\fP\~\fIchecklist\fP] [\fB\-g\fP\~\fIgroup\fP] [\fB\-m\fP\~\fImode\fP] [\fB\-o\fP\~\fIowner\fP] \fIdirectory\fP .sp 1 \fI\*(PN\fP \-[\fBhV\fP] [\fB\-C\fP\~\fIchecklist\fP] .sp 1 \fI\*(PN\fP \fB\-R\fP [\fB\-1dlnqsv\fP] [\fB\-C\fP\~\fIchecklist\fP] [\fB\-H\fP\~\fIhardlinks\fP] [\fB\-S\fP\~\fIsymlinks\fP] [\fB\-g\fP\~\fIgroup\fP] [\fB\-m\fP\~\fImode\fP] [\fB\-o\fP\~\fIowner\fP] \fIdestination\fP .SH DESCRIPTION .PP \fIInstall\fP is a tool for updating system files in a controlled environment. The design philosophy of \fI\*(PN\fP is to automate the installation process and put it as much out of reach of human carelessness as possible, while providing a flexible, easy to use tool. \fIInstall\fP provides the following features: .IP \(bu \fIInstall\fP increases system security by providing a controlled installation environment. It checks the actions of the superuser against a configuration file that you build (either by hand or using \fBinstck\fP(8l)), and can prevent grievous mistakes such as installing a shell setuid to a privileged user, or installing a world\(hywritable password file. An appropriate configuration file can guarantee that files are installed with correct owner, group and mode, that \fBstrip\fP(1) is run on binaries and \fBranlib\fP(1) is run on libraries. Regardless of whether you create a configuration file, \fI\*(PN\fP warns you of many possible errors, unless you make it quiet with its \fB\-q\fP option. For instance, if you install a new version of the \fBex\fP(1) editor and forget to update its links, \fI\*(PN\fP will notice the extra links to the existing version and warn you that you might be making a mistake. .IP \(bu Installed files do not overwrite current versions. The current version is backed up to a subdirectory of its dot directory (named \*(lqOLD\*(rq by default), where it may be easily re\(hyinstalled in the case of an unforeseen bug. The companion program \fBpurge\fP(8l) removes these backed\(hyup files after a user\(hyspecified interval. By default, if you repeatedly install new versions of a file, \fI\*(PN\fP creates a series of backups, providing a primitive form of version control (really a live back-out path). .IP \(bu \fIInstall\fP increases accountability by logging the actions of the superuser. This makes it easier to track down errors after the fact. .IP \(bu \fIInstall\fP simplifies \fBmake\fP(1) recipe files by allowing you to combine operations that would require several steps into a single one (e.g., you can specify in a single command line a file's ownership, group, mode, whether to run \fBstrip\fP(1) or \fBranlib\fP(1), and which hard or soft links should be made). .IP \(bu Despite its power and potential complexity, \fI\*(PN\fP is easy to use interactively because it intuits appropriate installation parameters for you, either by using those associated with an existing file, or its compilation\(hydependent defaults. In most cases you do not have to specify a file's owner, group, or mode unless you want them to be different from an existing file or the compilation\(hydependent defaults. Typical interactive usage is simply \*(lqinstall file destination.\*(rq .IP \(bu \fIInstall\fP is as careful as it can be to complete an installation once it is begun. There is a point in the code where \fBrename\fP(2) is used to commit the \fIdestination\fP file (after it ha updated any hardlinks. The failure window there leaves (some of) the links with the new binary and some with the old. Any such inconsistent state may be repaired with \fBinstck\fP(8l). (Unfortunately, this is not true under operating systems that do not provide an atomic \fB rename\fP(2) system call). This is true even when \fI\*(PN\fP must copy files across file system boundaries. .IP \(bu \fIInstall\fP may also be used to remove (de\(hyinstall) files in a controlled manner. A deletion moves the targets to OLD without installing a new copy of the file (or the links). .IP \(bu Finally, \fI\*(PN\fP currently runs on a variety of architectures and operating systems and is easy to port to new platforms. .SH USAGE .SS Terminology .PP The user specifies one or more \fIfiles\fP to install, and a \fIdestination\fP, which may be either a full or relative pathname ending in a file name or an existing directory name (if the directory does not exist, \fI\*(PN\fP thinks you mean to create a new file). The special name \*(lq\-\*(rq may be used for the \fIfile\fP argument to indicate \fIstdin\fP (see EXAMPLES). In this case, \fIdestination\fP \fBmust not\fP be a directory, since \fI\*(PN\fP cannot guess the name the file should have when installed. .PP Because the user may specify more than one \fIfiles\fP, and \fIdestination\fP may be an existing directory or a file which may or may not exist, \fI\*(PN\fP must also internally keep track of a \fIdestdir\fP (\*(lqdestination directory\*(rq, i.e., the directory in which to place the file to install), and a \fItarget\fP (the full pathname that each file to install will have when it is installed in \fIdestdir\fP). The \fItarget\fP and \fIdestdir\fP are constructed from the \fIfiles\fP and \fIdestination\fP arguments as described below. .PP For each name in \fIfiles\fP, \fI\*(PN\fP determines a \fItarget\fP name as follows: If \fIdestination\fP is an existing directory, \fI\*(PN\fP catenates the last component of \fIfile\fP to \fIdestination\fP to arrive at the \fItarget\fP name. If \fIdestination\fP does not exist or is an existing file, \fI\*(PN\fP takes \fIdestination\fP to be the \fItarget\fP. In the latter case \fIdestdir\fP is simply \fIdestination\fP minus its last component. If this reduction leaves \fIdestdir\fP empty then it is set to \*(lq.\*(rq. (E.g., if \fIdestination\fP were \fB/etc/motd\fP then \fIdestdir\fP would be \fB/etc\fP, but if \fIdestination\fP were just \fBmotd\fP then \fIdestdir\fP would be \*(lq.\*(rq.) N.B.: If more than one \fIfiles\fP are specified, \fIdestination\fP \fBmust\fP be an existing directory. .SE .PP Examples are the easiest way to clarify this terminology. .RS .sp 1 In the command \*(lqinstall motd /etc/motd\*(rq: .sp 1 .RS .TS l l . file: motd destination: /etc/motd destdir: /etc target: /etc/motd .TE .RE .sp 1 In the command \*(lqinstall motd /etc\*(rq: .sp 1 .RS .TS l l . file: motd destination: /etc destdir: /etc target: /etc/motd .TE .RE .sp 1 In the command sequence \*(lqcd /etc; \fI\*(PN\fP motd.new motd\*(rq: .sp 1 .RS .TS l l . file: motd.new destination: motd destdir: . (dot) target: ./motd .TE .RE .RE .sp 1 .SS Installation Parameters .PP If the file permissions, ownership or group ownership are not specified on the command line and \fItarget\fP exists, \fI\*(PN\fP duplicates its group, ownership, and mode. Otherwise, if the \fItarget\fP doesn't exist and the invoker is the superuser, \fI\*(PN\fP uses its compilation\(hydependent defaults. Otherwise, \fI\*(PN\fP uses the effective uid, the effective gid, and a compilation\(hydependent mode. \fIInstall\fP may also be configured to inherit the mode and ownerships from the \fIdestdir\fP. (Use the \fB\-V\fP option to view the compilation\(hydependent defaults.) .PP Note: \fI\*(PN\fP can only change ownership if invoked by the superuser; however, any user may specify a different group as long as the group is allowed by \fBchown\fP(2). .SE .SS Method of Operation .PP \fIInstall\fP first checks the proposed owner, group, and mode against the configuration file. It also checks whether the \fItarget\fP should have \fBstrip\fP(1) or \fBranlib\fP(1) run on it after installation. \fIInstall\fP aborts if it finds discrepancies between the configuration file and the proposed installation parameters. (If necessary, you can override the configuration file with \*(lq\fB\-C\fP/dev/null\*(rq). .PP \fIInstall\fP then looks for an existing \fItarget\fP and backs it up to a subdirectory of \fIdestdir\fP named \*(lqOLD\*(rq, which \fI\*(PN\fP will create if it doesn't exist. The backup is actually just a hard link to the existing \fItarget\fP. (If a backup file of the same name already exists in \*(lqOLD\*(rq, \fI\*(PN\fP first renames it by appending \fBmktemp\fP to make a new filename). .PP After backing up an existing \fItarget\fP, \fI\*(PN\fP may copy the new \fIfile\fP to a temporary to \fIdestdir\fP/OLD/\fIrandom-name\fP. This step is taken to ensure that both \fIfile\fP and \fItarget\fP are in the same file system so that \fBrename\fP(2) may be used for the final installation. This reduces the window in which files might be left in an inconsistent state due to a system crash or signal. Consequently the \*(lqOLD\*(rq subdirectory must \fBnot\fP be a file system mount point, since the \fBrename\fP(2) would fail (or a symbolic link to another partition). .PP Next \fI\*(PN\fP updates any hard links and soft (symbolic) links given under the \fB\-H\fP or \fB\-S\fP options. All links point at the installed \fItarget\fP. Existing symbolic links which point to the correct file are left unchanged, otherwise removed and replaced with the correct spelling. Existing correct hard links are unlinked and replaced, without a backup. Links which point to a file other than the \fItarget\fP are backed up to \*(lqOLD\*(rq and linked. \fIInstall\fP prints a warning in this case. .PP Lastly (the copy of) the new file is \fIrename\fP'd to the \fIdestination\fP name. .PP For security reasons, \fI\*(PN\fP drops setuid and setgid bits when files are moved to the \*(lqOLD\*(rq directory. .SE .SH OPTIONS .TP .nf \fB\-1\fP .fi After a successful installation \fI\*(PN\fP removes any previous backup in \*(lqOLD\*(rq. Thus \fI\*(PN\fP will keep exactly one previous revision of the installed file. .TP .nf \fB\-c\fP .fi Do not unlink the \fIfiles\fP. In effect this always copies the source files to OLD to install them. This is implied for a source file named \*(lq-\*(rq (\fIstdin\fP). .TP .nf \fB\-C\fP \fIcheckfile\fP .fi Search \fIcheckfile\fP for an expression that matches the \fItarget\fP. If \fI\*(PN\fP finds such an expression it will check the proposed modes (etc.) against those listed in the checkfile; any differences cause \fI\*(PN\fP to abort the installation. This mechanism is provided to protect the superuser from installing, for instance, the shell setuid root, as in: .RS install \-m7555 \-o root \-g wheel sh /bin .RE (note the extra \*(lq5\*(rq). See \fBinstall.cf\fP(5l) and \fBinstck\fP(8l). .TP .nf \fB\-d\fP .fi Build a directory rather than a plain file. If the directory is an OLD directory it is built with appropriate modes (see \fB\-V\fP below). .TP .nf \fB\-D\fP .fi Don't back up an existing \fItarget\fP (the \*(lqDestroy\*(rq option). This is useful when a trivially correctable problem such as a spelling error in a print statement is found in a recently installed product, or when the \fItarget\fP can be regenerated easily and is installed frequently. Sites that do not wish to keep backups but still want to take advantage of the checkfile could set this option in the environment. .TP .nf \fB\-g\fP \fIgroup\fP .fi Install the file with group ownership \fIgroup\fP. If no \fB\-g\fP option is given \fI\*(PN\fP will decide the group to use: .RS \(bu if there is an existing \fItarget\fP use its group .br \(bu if we are the superuser use a compilation\(hydependent group .br \(bu else use the effective group id .RE .TP .nf \fB\-h\fP .fi Print a summary of \fI\*(PN\fP's usage (the \*(lqhelp\*(rq option). .TP .nf \fB\-H\fP \fIhardlinks\fP .fi Specify a colon separated list of hard links that should be made to the \fItarget\fP after it is installed. (See EXAMPLES below.) .TP .nf \fB\-l\fP .fi Run \fBranlib\fP(1) on the installed \fItargets\fP. Under System V this option has no significance, but \fBmust\fP be given to pass the default checkfile (see \fBinstall.cf\fP(5l)). This allows Makefiles to work under all versions of UNIX. .TP .nf \fB\-m\fP \fImode\fP .fi Install the file with permissions \fImode\fP. \fIMode\fP may be given in either octal mode or in the symbolic form used by \fBls\fP(1) (e.g., \*(lq755\*(rq) is equivalent to \*(lqrwxr-xr-x\*(rq). If the \fB\-m\fP option is not given, \fI\*(PN\fP will decide the mode to use: .br .RS \(bu if there is an existing \fItarget\fP use its mode .br \(bu if we are the superuser use a compilation\(hydependent mode .br \(bu else use a compilation\(hydependent user mode .RE .TP .nf \fB\-n\fP .fi Give an approximate execution trace by printing the (almost) equivalent shell commands, but don't do anything. This is useful for debugging \fI\*(PN\fP or seeing what a difficult command line would do if you ran it. .TP .nf \fB\-N\fP .fi If the file presently exists fail the installation. The prevents some race conditions. Beware that I never use it, it is not portable to any other version of \fB\*(PN\fP. .TP .nf \fB\-o\fP \fIowner\fP .fi Change ownership of \fIfile\fP to \fIowner\fP (superuser only). If no \fB\-o\fP option is given \fI\*(PN\fP will decide the owner to use: .RS \(bu if there is an existing \fItarget\fP use its owner .br \(bu if we are the superuser use a compilation\(hydependent owner .br \(bu else use our effective uid .RE .TP .nf \fB\-p\fP .fi Preserve the time stamp of \fIfiles\fP in \fItargets\fP. .TP .nf \fB\-q\fP .fi Normally \fI\*(PN\fP informs you about a variety of possible errors. This option turns off that behavior and is not recommended except for special circumstances. Caveat emptor. .TP .nf \fB\-r\fP .fi Under \fB\-d\fP build all intervening directories between \*(lq/\*(rq and \fIdestination\fP. .TP .nf \fB\-R\fP .fi Remove (de\(hyinstall) a file by moving it into the OLD subdirectory. A temporary shell script is created to replace the \fItarget\fP, installed (which removes the existing \fItarget\fP to \*(lqOLD\*(rq), and removed. .TP .nf \fB\-s\fP .fi Run \fBstrip\fP(1) on the installed \fItargets\fP. .TP .nf \fB\-S\fP \fIsymlinks\fP .fi Specify a colon separated list of symbolic links that \fI\*(PN\fP should point at the installed file. (See EXAMPLES below.) .TP .nf \fB\-v\fP .fi Be verbose. Run \fBls\fP(1) on the backed up file and the \fItarget\fP. Notify the user of all side effects of this installation. .TP .nf \fB\-V\fP .fi View \fI\*(PN\fP's version and compilation\(hydependent owner, group and mode tables. .SH EXAMPLES .TP .nf \fI\*(PN\fP motd /etc .fi Install \fImotd\fP as \fB/etc/motd\fP. Create the directory \fI/etc/OLD\fP if it does not exist. If \fB/etc/motd\fP exists move it to \fB/etc/OLD/motd\fP and duplicate its ownership, group and mode; otherwise, use defaults. (Which will typically make the message of the day file mode 0755.) .TP .nf \fI\*(PN\fP \-c1 \-m 755 foo.sh /etc/foo .fi Install \fBfoo.sh\fP as \fB/etc/foo\fP. Do not unlink \fBfoo.sh\fP after the installation. Set permissions appropriate for a shell script on \fB/etc/foo\fP. If \fB/etc/OLD/foo\fP exists, overwrite it instead of moving it to a new name (i.e., retain a single backup of \fB/etc/foo\fP in \fB/etc/OLD\fP). .TP .nf \fI\*(PN\fP foo bar baz /usr/lib .fi Install the files \fBfoo\fP, \fBbar\fP and \fBbaz\fP as \fB/usr/lib/foo\fP, \fB/usr/lib/bar\fP, and \fB/usr/lib/baz\fP. Use the modes of the existing files or defaults. .TP .nf \fI\*(PN\fP \-vsm6751 \-oroot \-gkmem sendmail /usr/lib .fi Install \fBsendmail\fP as \fB/usr/lib/sendmail\fP, owned by root, grouped to kmem, and with the setuid and setgid permission bits set. Strip \fB/usr/lib/sendmail\fP after its installation and be verbose. .TP .nf \fI\*(PN\fP \-d \-m \-rwxrwxrwt /tmp .fi Build the directory \fB/tmp\fP with the default owner and group, mode 777, and with the \*(lqsticky\*(rq bit set. .TP .nf \fI\*(PN\fP \-c \-m1755 \-Hview:vi:edit:e:/usr/bin/ex a.out /usr/ucb/ex .fi Install the \fBex\fP editor with all of its hard links (\fB/usr/ucb/view\fP, \fB/usr/ucb/vi\fP, \fB/usr/ucb/edit\fP, \fB/usr/ucb/e\fP, \fBand /usr/bin/ex\fP). Replacing \fB\-H\fP with \fB\-S\fP would cause \fI\*(PN\fP to build symbolic links on machines which support them. .TP .nf \fI\*(PN\fP \-d \-r /usr/local/lib/mk .fi Recursively build any and all of the directories \fB/usr\fP, \fB/usr/local\fP, \fB/usr/local/lib\fP, and \fB/usr/local/lib/mk\fP that do not already exist. Silently do nothing if they already exist (very useful in Makefiles). .TP .nf \fI\*(PN\fP \-V .fi Output the version of \fI\*(PN\fP and a table of compiled in defaults. Output when run as the superuser might look similar to this, depending on the compilation defaults: .RS .TS l s s l s s l l l. install: version: $\&Id: main.c,v 8.16 2010/11/05 17:28:19 ksb Exp $ install: configuration file: /usr/local/etc/install.cf install: syslog facility: 144 install: superuser defaults: install: owner is file=root dir=root OLD=root install: group is file=binary dir=binary OLD=binary install: mode is file=0755 dir=0755 OLD=inherited .TE .RE .TP .nf ssh some.other.host \fI\*(PN\fP \- /etc/motd < motd.some.other.host .fi This example shows a way to use \*(lq\-\*(rq to advantage. It is often useful when \fBrdist\fP(1) is overkill or otherwise inappropriate. For instance, if you had a Makefile that generated files named \fBhost1.motd\fP, \fBhost2.motd\fP, \fBhost3.motd\fP, etc., and wanted to install them on those hosts, you could do something like this: .sp 1 .nf .na .KS .RS for host in host1 host2 host3; do .RS ssh $host \fI\*(PN\fP \- /etc/motd < $host.motd .RE done .KE .RE or with \fBxapply\fP .RS xapply 'ssh %[1.-$] \fI\*(PN\fP \- /etc/motd <%1' *.motd .RE .fi .ad .sp 1 .SH DIAGNOSTICS .KS .PP Unless made quiet by \fB\-q\fP, \fI\*(PN\fP will warn the installer if: .RS .br \(bu the owner, group, or mode changes .br \(bu the setuid, setgid, or sticky bits change .br \(bu a setuid program is loaded with the \*(lq#!\*(rq magic number .br \(bu \fItarget\fP does not exist (this is a prophylactic against typographical errors\(emsee CAVEATS below) .RE .KE .KS .PP \fIInstall\fP will abort the installation if: .RS .br \(bu \fI\*(PN\fP cannot make a backup of an existing \fItarget\fP .br \(bu a setuid program\'s owner was not specified with the mode .br \(bu a setgid program\'s group was not specified with the mode .br \(bu the specified owner, group, or mode failed to match the checkfile .br \(bu the superuser installs a setuid program that is not in the checkfile (this is a compile time option) .RE .KE .SH ENVIRONMENT .PP The environment variable \fBINSTALL\fP may be used to set command line options. Such options are read before any explicit command line options, e.g. .sp 1 .RS INSTALL=-v ; export INSTALL .RE will turn on \*(lqverbose\*(rq mode for all subsequent invocations of \fI\*(PN\fP. .SH BUGS .PP \fIInstall\fP does not use file locking, so it's possible for two competing \fI\*(PN\fP processes to lose data. .PP The trace option (\fB\-n\fP) doesn't always show exactly what \fI\*(PN\fP would do. It may show OLD directories being made several times, and inherited modes don't propagate correctly under \fB\-drn\fP. .PP The link counts shown for \fB\-H\fP hard links made in the trace output are wrong (too small) as the links are being built. .SH COMPATIBILITY .PP Some versions of \fI\*(PN\fP allow numeric owner (under \fB\-o\fP) and group (under \fB\-g\fP) specifications. This version does not offer that because the main goal of the program is to prevent installation errors, and assuming you know the uid of any login but the superuser is error-prone, at best. .SH CAVEATS .PP \(bu \fIInstall\fP will not build character special files. Use \fBmknod\fP(8) instead. .PP If /bin doesn't exist, the command: .RS install ls /bin .RE will make \fI/bin\fP be a copy of the binary \fBls\fP. This is an unavoidable consequence of allowing the \fIdestination\fP to be a directory. You can avoid this by using \*(lqinstall \-d \fIdirectory\fP\*(rq in Makefiles to ensure that destination directories exist, e.g., .nf .na .RS install: product .RS install \-d /bin install product /bin .RE .RE .fi .ad .sp 1 \fIInstall\fP does nothing and exits normally if the directory already exists, so it's safe to include lines like this in your Makefiles. You can also use \fBinstck\fP(8l) to ensure that all system directories are built correctly. .PP \(bu \fIInstall\fP can cover up mistakes of omission in Makefiles by copying the modes on a previously installed target. For example, the invocation of \fI\*(PN\fP from a Makefile might not specify that the \fIdestination\fP should be setuid root, but so long as the \fItarget\fP existed \fI\*(PN\fP would hide the error by copying the modes of the existing \fItarget\fP. The problem in the Makefile would not be found unless the \fItarget\fP were removed prior to installation. Use \fBinstck\fP(8l) to generate a configuration file to avoid this problem. .PP \(bu \fIInstall\fP and \fBpurge\fP(8l) assume that they own the file namespace in the \*(lqOLD\*(rq subdirectories. If other programs create, modify or delete files in the \*(lqOLD\*(rq subdirectories, they will probably collide with one of \fI\*(PN\fP or \fBpurge\fP(8l) eventually. .SH FILES .TS l l. /usr/local/lib/install.cf the default check list file .../OLD/#inst* temporary files made for installations .../OLD/#bogus* links made to running binaries to avoid ETXTBSY .../OLD/* copies of previously installed files .TE .SH AUTHORS Kevin Braunsdorf, Purdue University Computing Center (install at ksb dot npcguild.org) .br Jeff Smith, Purdue University Computing Center .br Copyright \*(co 1990 Purdue Research Foundation. All rights reserved. .SH "SEE ALSO" .hlm 0 install.cf(5l), instck(8l), purge(8l), vinst(1l), chgrp(1), ls(1), make(1), ranlib(1), strip(1), intro(2), syslog(3), chown(2), chown(8), mknod(8)