153e90a53Smrg#!/bin/sh 253e90a53Smrg# install - install a program, script, or datafile 353e90a53Smrg 453e90a53Smrgscriptversion=2005-05-14.22 553e90a53Smrg 653e90a53Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 753e90a53Smrg# later released in X11R6 (xc/config/util/install.sh) with the 853e90a53Smrg# following copyright and license. 953e90a53Smrg# 1053e90a53Smrg# Copyright (C) 1994 X Consortium 1153e90a53Smrg# 1253e90a53Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1353e90a53Smrg# of this software and associated documentation files (the "Software"), to 1453e90a53Smrg# deal in the Software without restriction, including without limitation the 1553e90a53Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1653e90a53Smrg# sell copies of the Software, and to permit persons to whom the Software is 1753e90a53Smrg# furnished to do so, subject to the following conditions: 1853e90a53Smrg# 1953e90a53Smrg# The above copyright notice and this permission notice shall be included in 2053e90a53Smrg# all copies or substantial portions of the Software. 2153e90a53Smrg# 2253e90a53Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2353e90a53Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2453e90a53Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2553e90a53Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2653e90a53Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2753e90a53Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2853e90a53Smrg# 2953e90a53Smrg# Except as contained in this notice, the name of the X Consortium shall not 3053e90a53Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3153e90a53Smrg# ings in this Software without prior written authorization from the X Consor- 3253e90a53Smrg# tium. 3353e90a53Smrg# 3453e90a53Smrg# 3553e90a53Smrg# FSF changes to this file are in the public domain. 3653e90a53Smrg# 3753e90a53Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3853e90a53Smrg# `make' implicit rules from creating a file called install from it 3953e90a53Smrg# when there is no Makefile. 4053e90a53Smrg# 4153e90a53Smrg# This script is compatible with the BSD install script, but was written 4253e90a53Smrg# from scratch. It can only install one file at a time, a restriction 4353e90a53Smrg# shared with many OS's install programs. 4453e90a53Smrg 4553e90a53Smrg# set DOITPROG to echo to test this script 4653e90a53Smrg 4753e90a53Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 4853e90a53Smrgdoit="${DOITPROG-}" 4953e90a53Smrg 5053e90a53Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 5153e90a53Smrg 5253e90a53Smrgmvprog="${MVPROG-mv}" 5353e90a53Smrgcpprog="${CPPROG-cp}" 5453e90a53Smrgchmodprog="${CHMODPROG-chmod}" 5553e90a53Smrgchownprog="${CHOWNPROG-chown}" 5653e90a53Smrgchgrpprog="${CHGRPPROG-chgrp}" 5753e90a53Smrgstripprog="${STRIPPROG-strip}" 5853e90a53Smrgrmprog="${RMPROG-rm}" 5953e90a53Smrgmkdirprog="${MKDIRPROG-mkdir}" 6053e90a53Smrg 6153e90a53Smrgchmodcmd="$chmodprog 0755" 6253e90a53Smrgchowncmd= 6353e90a53Smrgchgrpcmd= 6453e90a53Smrgstripcmd= 6553e90a53Smrgrmcmd="$rmprog -f" 6653e90a53Smrgmvcmd="$mvprog" 6753e90a53Smrgsrc= 6853e90a53Smrgdst= 6953e90a53Smrgdir_arg= 7053e90a53Smrgdstarg= 7153e90a53Smrgno_target_directory= 7253e90a53Smrg 7353e90a53Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 7453e90a53Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 7553e90a53Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 7653e90a53Smrg or: $0 [OPTION]... -d DIRECTORIES... 7753e90a53Smrg 7853e90a53SmrgIn the 1st form, copy SRCFILE to DSTFILE. 7953e90a53SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 8053e90a53SmrgIn the 4th, create DIRECTORIES. 8153e90a53Smrg 8253e90a53SmrgOptions: 8353e90a53Smrg-c (ignored) 8453e90a53Smrg-d create directories instead of installing files. 8553e90a53Smrg-g GROUP $chgrpprog installed files to GROUP. 8653e90a53Smrg-m MODE $chmodprog installed files to MODE. 8753e90a53Smrg-o USER $chownprog installed files to USER. 8853e90a53Smrg-s $stripprog installed files. 8953e90a53Smrg-t DIRECTORY install into DIRECTORY. 9053e90a53Smrg-T report an error if DSTFILE is a directory. 9153e90a53Smrg--help display this help and exit. 9253e90a53Smrg--version display version info and exit. 9353e90a53Smrg 9453e90a53SmrgEnvironment variables override the default commands: 9553e90a53Smrg CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 9653e90a53Smrg" 9753e90a53Smrg 9853e90a53Smrgwhile test -n "$1"; do 9953e90a53Smrg case $1 in 10053e90a53Smrg -c) shift 10153e90a53Smrg continue;; 10253e90a53Smrg 10353e90a53Smrg -d) dir_arg=true 10453e90a53Smrg shift 10553e90a53Smrg continue;; 10653e90a53Smrg 10753e90a53Smrg -g) chgrpcmd="$chgrpprog $2" 10853e90a53Smrg shift 10953e90a53Smrg shift 11053e90a53Smrg continue;; 11153e90a53Smrg 11253e90a53Smrg --help) echo "$usage"; exit $?;; 11353e90a53Smrg 11453e90a53Smrg -m) chmodcmd="$chmodprog $2" 11553e90a53Smrg shift 11653e90a53Smrg shift 11753e90a53Smrg continue;; 11853e90a53Smrg 11953e90a53Smrg -o) chowncmd="$chownprog $2" 12053e90a53Smrg shift 12153e90a53Smrg shift 12253e90a53Smrg continue;; 12353e90a53Smrg 12453e90a53Smrg -s) stripcmd=$stripprog 12553e90a53Smrg shift 12653e90a53Smrg continue;; 12753e90a53Smrg 12853e90a53Smrg -t) dstarg=$2 12953e90a53Smrg shift 13053e90a53Smrg shift 13153e90a53Smrg continue;; 13253e90a53Smrg 13353e90a53Smrg -T) no_target_directory=true 13453e90a53Smrg shift 13553e90a53Smrg continue;; 13653e90a53Smrg 13753e90a53Smrg --version) echo "$0 $scriptversion"; exit $?;; 13853e90a53Smrg 13953e90a53Smrg *) # When -d is used, all remaining arguments are directories to create. 14053e90a53Smrg # When -t is used, the destination is already specified. 14153e90a53Smrg test -n "$dir_arg$dstarg" && break 14253e90a53Smrg # Otherwise, the last argument is the destination. Remove it from $@. 14353e90a53Smrg for arg 14453e90a53Smrg do 14553e90a53Smrg if test -n "$dstarg"; then 14653e90a53Smrg # $@ is not empty: it contains at least $arg. 14753e90a53Smrg set fnord "$@" "$dstarg" 14853e90a53Smrg shift # fnord 14953e90a53Smrg fi 15053e90a53Smrg shift # arg 15153e90a53Smrg dstarg=$arg 15253e90a53Smrg done 15353e90a53Smrg break;; 15453e90a53Smrg esac 15553e90a53Smrgdone 15653e90a53Smrg 15753e90a53Smrgif test -z "$1"; then 15853e90a53Smrg if test -z "$dir_arg"; then 15953e90a53Smrg echo "$0: no input file specified." >&2 16053e90a53Smrg exit 1 16153e90a53Smrg fi 16253e90a53Smrg # It's OK to call `install-sh -d' without argument. 16353e90a53Smrg # This can happen when creating conditional directories. 16453e90a53Smrg exit 0 16553e90a53Smrgfi 16653e90a53Smrg 16753e90a53Smrgfor src 16853e90a53Smrgdo 16953e90a53Smrg # Protect names starting with `-'. 17053e90a53Smrg case $src in 17153e90a53Smrg -*) src=./$src ;; 17253e90a53Smrg esac 17353e90a53Smrg 17453e90a53Smrg if test -n "$dir_arg"; then 17553e90a53Smrg dst=$src 17653e90a53Smrg src= 17753e90a53Smrg 17853e90a53Smrg if test -d "$dst"; then 17953e90a53Smrg mkdircmd=: 18053e90a53Smrg chmodcmd= 18153e90a53Smrg else 18253e90a53Smrg mkdircmd=$mkdirprog 18353e90a53Smrg fi 18453e90a53Smrg else 18553e90a53Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 18653e90a53Smrg # might cause directories to be created, which would be especially bad 18753e90a53Smrg # if $src (and thus $dsttmp) contains '*'. 18853e90a53Smrg if test ! -f "$src" && test ! -d "$src"; then 18953e90a53Smrg echo "$0: $src does not exist." >&2 19053e90a53Smrg exit 1 19153e90a53Smrg fi 19253e90a53Smrg 19353e90a53Smrg if test -z "$dstarg"; then 19453e90a53Smrg echo "$0: no destination specified." >&2 19553e90a53Smrg exit 1 19653e90a53Smrg fi 19753e90a53Smrg 19853e90a53Smrg dst=$dstarg 19953e90a53Smrg # Protect names starting with `-'. 20053e90a53Smrg case $dst in 20153e90a53Smrg -*) dst=./$dst ;; 20253e90a53Smrg esac 20353e90a53Smrg 20453e90a53Smrg # If destination is a directory, append the input filename; won't work 20553e90a53Smrg # if double slashes aren't ignored. 20653e90a53Smrg if test -d "$dst"; then 20753e90a53Smrg if test -n "$no_target_directory"; then 20853e90a53Smrg echo "$0: $dstarg: Is a directory" >&2 20953e90a53Smrg exit 1 21053e90a53Smrg fi 21153e90a53Smrg dst=$dst/`basename "$src"` 21253e90a53Smrg fi 21353e90a53Smrg fi 21453e90a53Smrg 21553e90a53Smrg # This sed command emulates the dirname command. 21653e90a53Smrg dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 21753e90a53Smrg 21853e90a53Smrg # Make sure that the destination directory exists. 21953e90a53Smrg 22053e90a53Smrg # Skip lots of stat calls in the usual case. 22153e90a53Smrg if test ! -d "$dstdir"; then 22253e90a53Smrg defaultIFS=' 22353e90a53Smrg ' 22453e90a53Smrg IFS="${IFS-$defaultIFS}" 22553e90a53Smrg 22653e90a53Smrg oIFS=$IFS 22753e90a53Smrg # Some sh's can't handle IFS=/ for some reason. 22853e90a53Smrg IFS='%' 22953e90a53Smrg set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 23053e90a53Smrg shift 23153e90a53Smrg IFS=$oIFS 23253e90a53Smrg 23353e90a53Smrg pathcomp= 23453e90a53Smrg 23553e90a53Smrg while test $# -ne 0 ; do 23653e90a53Smrg pathcomp=$pathcomp$1 23753e90a53Smrg shift 23853e90a53Smrg if test ! -d "$pathcomp"; then 23953e90a53Smrg $mkdirprog "$pathcomp" 24053e90a53Smrg # mkdir can fail with a `File exist' error in case several 24153e90a53Smrg # install-sh are creating the directory concurrently. This 24253e90a53Smrg # is OK. 24353e90a53Smrg test -d "$pathcomp" || exit 24453e90a53Smrg fi 24553e90a53Smrg pathcomp=$pathcomp/ 24653e90a53Smrg done 24753e90a53Smrg fi 24853e90a53Smrg 24953e90a53Smrg if test -n "$dir_arg"; then 25053e90a53Smrg $doit $mkdircmd "$dst" \ 25153e90a53Smrg && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 25253e90a53Smrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 25353e90a53Smrg && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 25453e90a53Smrg && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 25553e90a53Smrg 25653e90a53Smrg else 25753e90a53Smrg dstfile=`basename "$dst"` 25853e90a53Smrg 25953e90a53Smrg # Make a couple of temp file names in the proper directory. 26053e90a53Smrg dsttmp=$dstdir/_inst.$$_ 26153e90a53Smrg rmtmp=$dstdir/_rm.$$_ 26253e90a53Smrg 26353e90a53Smrg # Trap to clean up those temp files at exit. 26453e90a53Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 26553e90a53Smrg trap '(exit $?); exit' 1 2 13 15 26653e90a53Smrg 26753e90a53Smrg # Copy the file name to the temp name. 26853e90a53Smrg $doit $cpprog "$src" "$dsttmp" && 26953e90a53Smrg 27053e90a53Smrg # and set any options; do chmod last to preserve setuid bits. 27153e90a53Smrg # 27253e90a53Smrg # If any of these fail, we abort the whole thing. If we want to 27353e90a53Smrg # ignore errors from any of these, just make sure not to ignore 27453e90a53Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 27553e90a53Smrg # 27653e90a53Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 27753e90a53Smrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 27853e90a53Smrg && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 27953e90a53Smrg && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 28053e90a53Smrg 28153e90a53Smrg # Now rename the file to the real destination. 28253e90a53Smrg { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 28353e90a53Smrg || { 28453e90a53Smrg # The rename failed, perhaps because mv can't rename something else 28553e90a53Smrg # to itself, or perhaps because mv is so ancient that it does not 28653e90a53Smrg # support -f. 28753e90a53Smrg 28853e90a53Smrg # Now remove or move aside any old file at destination location. 28953e90a53Smrg # We try this two ways since rm can't unlink itself on some 29053e90a53Smrg # systems and the destination file might be busy for other 29153e90a53Smrg # reasons. In this case, the final cleanup might fail but the new 29253e90a53Smrg # file should still install successfully. 29353e90a53Smrg { 29453e90a53Smrg if test -f "$dstdir/$dstfile"; then 29553e90a53Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 29653e90a53Smrg || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 29753e90a53Smrg || { 29853e90a53Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 29953e90a53Smrg (exit 1); exit 1 30053e90a53Smrg } 30153e90a53Smrg else 30253e90a53Smrg : 30353e90a53Smrg fi 30453e90a53Smrg } && 30553e90a53Smrg 30653e90a53Smrg # Now rename the file to the real destination. 30753e90a53Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 30853e90a53Smrg } 30953e90a53Smrg } 31053e90a53Smrg fi || { (exit 1); exit 1; } 31153e90a53Smrgdone 31253e90a53Smrg 31353e90a53Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 31453e90a53Smrg{ 31553e90a53Smrg (exit 0); exit 0 31653e90a53Smrg} 31753e90a53Smrg 31853e90a53Smrg# Local variables: 31953e90a53Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 32053e90a53Smrg# time-stamp-start: "scriptversion=" 32153e90a53Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 32253e90a53Smrg# time-stamp-end: "$" 32353e90a53Smrg# End: 324