171d7fec4Smrg#!/bin/sh 271d7fec4Smrg# install - install a program, script, or datafile 371d7fec4Smrg 471d7fec4Smrgscriptversion=2005-05-14.22 571d7fec4Smrg 671d7fec4Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 771d7fec4Smrg# later released in X11R6 (xc/config/util/install.sh) with the 871d7fec4Smrg# following copyright and license. 971d7fec4Smrg# 1071d7fec4Smrg# Copyright (C) 1994 X Consortium 1171d7fec4Smrg# 1271d7fec4Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1371d7fec4Smrg# of this software and associated documentation files (the "Software"), to 1471d7fec4Smrg# deal in the Software without restriction, including without limitation the 1571d7fec4Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1671d7fec4Smrg# sell copies of the Software, and to permit persons to whom the Software is 1771d7fec4Smrg# furnished to do so, subject to the following conditions: 1871d7fec4Smrg# 1971d7fec4Smrg# The above copyright notice and this permission notice shall be included in 2071d7fec4Smrg# all copies or substantial portions of the Software. 2171d7fec4Smrg# 2271d7fec4Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2371d7fec4Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2471d7fec4Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2571d7fec4Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2671d7fec4Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2771d7fec4Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2871d7fec4Smrg# 2971d7fec4Smrg# Except as contained in this notice, the name of the X Consortium shall not 3071d7fec4Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3171d7fec4Smrg# ings in this Software without prior written authorization from the X Consor- 3271d7fec4Smrg# tium. 3371d7fec4Smrg# 3471d7fec4Smrg# 3571d7fec4Smrg# FSF changes to this file are in the public domain. 3671d7fec4Smrg# 3771d7fec4Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3871d7fec4Smrg# `make' implicit rules from creating a file called install from it 3971d7fec4Smrg# when there is no Makefile. 4071d7fec4Smrg# 4171d7fec4Smrg# This script is compatible with the BSD install script, but was written 4271d7fec4Smrg# from scratch. It can only install one file at a time, a restriction 4371d7fec4Smrg# shared with many OS's install programs. 4471d7fec4Smrg 4571d7fec4Smrg# set DOITPROG to echo to test this script 4671d7fec4Smrg 4771d7fec4Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 4871d7fec4Smrgdoit="${DOITPROG-}" 4971d7fec4Smrg 5071d7fec4Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 5171d7fec4Smrg 5271d7fec4Smrgmvprog="${MVPROG-mv}" 5371d7fec4Smrgcpprog="${CPPROG-cp}" 5471d7fec4Smrgchmodprog="${CHMODPROG-chmod}" 5571d7fec4Smrgchownprog="${CHOWNPROG-chown}" 5671d7fec4Smrgchgrpprog="${CHGRPPROG-chgrp}" 5771d7fec4Smrgstripprog="${STRIPPROG-strip}" 5871d7fec4Smrgrmprog="${RMPROG-rm}" 5971d7fec4Smrgmkdirprog="${MKDIRPROG-mkdir}" 6071d7fec4Smrg 6171d7fec4Smrgchmodcmd="$chmodprog 0755" 6271d7fec4Smrgchowncmd= 6371d7fec4Smrgchgrpcmd= 6471d7fec4Smrgstripcmd= 6571d7fec4Smrgrmcmd="$rmprog -f" 6671d7fec4Smrgmvcmd="$mvprog" 6771d7fec4Smrgsrc= 6871d7fec4Smrgdst= 6971d7fec4Smrgdir_arg= 7071d7fec4Smrgdstarg= 7171d7fec4Smrgno_target_directory= 7271d7fec4Smrg 7371d7fec4Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 7471d7fec4Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 7571d7fec4Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 7671d7fec4Smrg or: $0 [OPTION]... -d DIRECTORIES... 7771d7fec4Smrg 7871d7fec4SmrgIn the 1st form, copy SRCFILE to DSTFILE. 7971d7fec4SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 8071d7fec4SmrgIn the 4th, create DIRECTORIES. 8171d7fec4Smrg 8271d7fec4SmrgOptions: 8371d7fec4Smrg-c (ignored) 8471d7fec4Smrg-d create directories instead of installing files. 8571d7fec4Smrg-g GROUP $chgrpprog installed files to GROUP. 8671d7fec4Smrg-m MODE $chmodprog installed files to MODE. 8771d7fec4Smrg-o USER $chownprog installed files to USER. 8871d7fec4Smrg-s $stripprog installed files. 8971d7fec4Smrg-t DIRECTORY install into DIRECTORY. 9071d7fec4Smrg-T report an error if DSTFILE is a directory. 9171d7fec4Smrg--help display this help and exit. 9271d7fec4Smrg--version display version info and exit. 9371d7fec4Smrg 9471d7fec4SmrgEnvironment variables override the default commands: 9571d7fec4Smrg CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 9671d7fec4Smrg" 9771d7fec4Smrg 9871d7fec4Smrgwhile test -n "$1"; do 9971d7fec4Smrg case $1 in 10071d7fec4Smrg -c) shift 10171d7fec4Smrg continue;; 10271d7fec4Smrg 10371d7fec4Smrg -d) dir_arg=true 10471d7fec4Smrg shift 10571d7fec4Smrg continue;; 10671d7fec4Smrg 10771d7fec4Smrg -g) chgrpcmd="$chgrpprog $2" 10871d7fec4Smrg shift 10971d7fec4Smrg shift 11071d7fec4Smrg continue;; 11171d7fec4Smrg 11271d7fec4Smrg --help) echo "$usage"; exit $?;; 11371d7fec4Smrg 11471d7fec4Smrg -m) chmodcmd="$chmodprog $2" 11571d7fec4Smrg shift 11671d7fec4Smrg shift 11771d7fec4Smrg continue;; 11871d7fec4Smrg 11971d7fec4Smrg -o) chowncmd="$chownprog $2" 12071d7fec4Smrg shift 12171d7fec4Smrg shift 12271d7fec4Smrg continue;; 12371d7fec4Smrg 12471d7fec4Smrg -s) stripcmd=$stripprog 12571d7fec4Smrg shift 12671d7fec4Smrg continue;; 12771d7fec4Smrg 12871d7fec4Smrg -t) dstarg=$2 12971d7fec4Smrg shift 13071d7fec4Smrg shift 13171d7fec4Smrg continue;; 13271d7fec4Smrg 13371d7fec4Smrg -T) no_target_directory=true 13471d7fec4Smrg shift 13571d7fec4Smrg continue;; 13671d7fec4Smrg 13771d7fec4Smrg --version) echo "$0 $scriptversion"; exit $?;; 13871d7fec4Smrg 13971d7fec4Smrg *) # When -d is used, all remaining arguments are directories to create. 14071d7fec4Smrg # When -t is used, the destination is already specified. 14171d7fec4Smrg test -n "$dir_arg$dstarg" && break 14271d7fec4Smrg # Otherwise, the last argument is the destination. Remove it from $@. 14371d7fec4Smrg for arg 14471d7fec4Smrg do 14571d7fec4Smrg if test -n "$dstarg"; then 14671d7fec4Smrg # $@ is not empty: it contains at least $arg. 14771d7fec4Smrg set fnord "$@" "$dstarg" 14871d7fec4Smrg shift # fnord 14971d7fec4Smrg fi 15071d7fec4Smrg shift # arg 15171d7fec4Smrg dstarg=$arg 15271d7fec4Smrg done 15371d7fec4Smrg break;; 15471d7fec4Smrg esac 15571d7fec4Smrgdone 15671d7fec4Smrg 15771d7fec4Smrgif test -z "$1"; then 15871d7fec4Smrg if test -z "$dir_arg"; then 15971d7fec4Smrg echo "$0: no input file specified." >&2 16071d7fec4Smrg exit 1 16171d7fec4Smrg fi 16271d7fec4Smrg # It's OK to call `install-sh -d' without argument. 16371d7fec4Smrg # This can happen when creating conditional directories. 16471d7fec4Smrg exit 0 16571d7fec4Smrgfi 16671d7fec4Smrg 16771d7fec4Smrgfor src 16871d7fec4Smrgdo 16971d7fec4Smrg # Protect names starting with `-'. 17071d7fec4Smrg case $src in 17171d7fec4Smrg -*) src=./$src ;; 17271d7fec4Smrg esac 17371d7fec4Smrg 17471d7fec4Smrg if test -n "$dir_arg"; then 17571d7fec4Smrg dst=$src 17671d7fec4Smrg src= 17771d7fec4Smrg 17871d7fec4Smrg if test -d "$dst"; then 17971d7fec4Smrg mkdircmd=: 18071d7fec4Smrg chmodcmd= 18171d7fec4Smrg else 18271d7fec4Smrg mkdircmd=$mkdirprog 18371d7fec4Smrg fi 18471d7fec4Smrg else 18571d7fec4Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 18671d7fec4Smrg # might cause directories to be created, which would be especially bad 18771d7fec4Smrg # if $src (and thus $dsttmp) contains '*'. 18871d7fec4Smrg if test ! -f "$src" && test ! -d "$src"; then 18971d7fec4Smrg echo "$0: $src does not exist." >&2 19071d7fec4Smrg exit 1 19171d7fec4Smrg fi 19271d7fec4Smrg 19371d7fec4Smrg if test -z "$dstarg"; then 19471d7fec4Smrg echo "$0: no destination specified." >&2 19571d7fec4Smrg exit 1 19671d7fec4Smrg fi 19771d7fec4Smrg 19871d7fec4Smrg dst=$dstarg 19971d7fec4Smrg # Protect names starting with `-'. 20071d7fec4Smrg case $dst in 20171d7fec4Smrg -*) dst=./$dst ;; 20271d7fec4Smrg esac 20371d7fec4Smrg 20471d7fec4Smrg # If destination is a directory, append the input filename; won't work 20571d7fec4Smrg # if double slashes aren't ignored. 20671d7fec4Smrg if test -d "$dst"; then 20771d7fec4Smrg if test -n "$no_target_directory"; then 20871d7fec4Smrg echo "$0: $dstarg: Is a directory" >&2 20971d7fec4Smrg exit 1 21071d7fec4Smrg fi 21171d7fec4Smrg dst=$dst/`basename "$src"` 21271d7fec4Smrg fi 21371d7fec4Smrg fi 21471d7fec4Smrg 21571d7fec4Smrg # This sed command emulates the dirname command. 21671d7fec4Smrg dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 21771d7fec4Smrg 21871d7fec4Smrg # Make sure that the destination directory exists. 21971d7fec4Smrg 22071d7fec4Smrg # Skip lots of stat calls in the usual case. 22171d7fec4Smrg if test ! -d "$dstdir"; then 22271d7fec4Smrg defaultIFS=' 22371d7fec4Smrg ' 22471d7fec4Smrg IFS="${IFS-$defaultIFS}" 22571d7fec4Smrg 22671d7fec4Smrg oIFS=$IFS 22771d7fec4Smrg # Some sh's can't handle IFS=/ for some reason. 22871d7fec4Smrg IFS='%' 22971d7fec4Smrg set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 23071d7fec4Smrg shift 23171d7fec4Smrg IFS=$oIFS 23271d7fec4Smrg 23371d7fec4Smrg pathcomp= 23471d7fec4Smrg 23571d7fec4Smrg while test $# -ne 0 ; do 23671d7fec4Smrg pathcomp=$pathcomp$1 23771d7fec4Smrg shift 23871d7fec4Smrg if test ! -d "$pathcomp"; then 23971d7fec4Smrg $mkdirprog "$pathcomp" 24071d7fec4Smrg # mkdir can fail with a `File exist' error in case several 24171d7fec4Smrg # install-sh are creating the directory concurrently. This 24271d7fec4Smrg # is OK. 24371d7fec4Smrg test -d "$pathcomp" || exit 24471d7fec4Smrg fi 24571d7fec4Smrg pathcomp=$pathcomp/ 24671d7fec4Smrg done 24771d7fec4Smrg fi 24871d7fec4Smrg 24971d7fec4Smrg if test -n "$dir_arg"; then 25071d7fec4Smrg $doit $mkdircmd "$dst" \ 25171d7fec4Smrg && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 25271d7fec4Smrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 25371d7fec4Smrg && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 25471d7fec4Smrg && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 25571d7fec4Smrg 25671d7fec4Smrg else 25771d7fec4Smrg dstfile=`basename "$dst"` 25871d7fec4Smrg 25971d7fec4Smrg # Make a couple of temp file names in the proper directory. 26071d7fec4Smrg dsttmp=$dstdir/_inst.$$_ 26171d7fec4Smrg rmtmp=$dstdir/_rm.$$_ 26271d7fec4Smrg 26371d7fec4Smrg # Trap to clean up those temp files at exit. 26471d7fec4Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 26571d7fec4Smrg trap '(exit $?); exit' 1 2 13 15 26671d7fec4Smrg 26771d7fec4Smrg # Copy the file name to the temp name. 26871d7fec4Smrg $doit $cpprog "$src" "$dsttmp" && 26971d7fec4Smrg 27071d7fec4Smrg # and set any options; do chmod last to preserve setuid bits. 27171d7fec4Smrg # 27271d7fec4Smrg # If any of these fail, we abort the whole thing. If we want to 27371d7fec4Smrg # ignore errors from any of these, just make sure not to ignore 27471d7fec4Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 27571d7fec4Smrg # 27671d7fec4Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 27771d7fec4Smrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 27871d7fec4Smrg && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 27971d7fec4Smrg && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 28071d7fec4Smrg 28171d7fec4Smrg # Now rename the file to the real destination. 28271d7fec4Smrg { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 28371d7fec4Smrg || { 28471d7fec4Smrg # The rename failed, perhaps because mv can't rename something else 28571d7fec4Smrg # to itself, or perhaps because mv is so ancient that it does not 28671d7fec4Smrg # support -f. 28771d7fec4Smrg 28871d7fec4Smrg # Now remove or move aside any old file at destination location. 28971d7fec4Smrg # We try this two ways since rm can't unlink itself on some 29071d7fec4Smrg # systems and the destination file might be busy for other 29171d7fec4Smrg # reasons. In this case, the final cleanup might fail but the new 29271d7fec4Smrg # file should still install successfully. 29371d7fec4Smrg { 29471d7fec4Smrg if test -f "$dstdir/$dstfile"; then 29571d7fec4Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 29671d7fec4Smrg || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 29771d7fec4Smrg || { 29871d7fec4Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 29971d7fec4Smrg (exit 1); exit 1 30071d7fec4Smrg } 30171d7fec4Smrg else 30271d7fec4Smrg : 30371d7fec4Smrg fi 30471d7fec4Smrg } && 30571d7fec4Smrg 30671d7fec4Smrg # Now rename the file to the real destination. 30771d7fec4Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 30871d7fec4Smrg } 30971d7fec4Smrg } 31071d7fec4Smrg fi || { (exit 1); exit 1; } 31171d7fec4Smrgdone 31271d7fec4Smrg 31371d7fec4Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 31471d7fec4Smrg{ 31571d7fec4Smrg (exit 0); exit 0 31671d7fec4Smrg} 31771d7fec4Smrg 31871d7fec4Smrg# Local variables: 31971d7fec4Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 32071d7fec4Smrg# time-stamp-start: "scriptversion=" 32171d7fec4Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 32271d7fec4Smrg# time-stamp-end: "$" 32371d7fec4Smrg# End: 324