150276Speter#! /bin/sh 250276Speter# 350276Speter# install - install a program, script, or datafile 450276Speter# 5174993Srafan# This originates from X11R5 (mit/util/scripts/install.sh), which was 6174993Srafan# later released in X11R6 (xc/config/util/install.sh) with the 7174993Srafan# following copyright and license. 862449Speter# 9174993Srafan# Copyright (C) 1994 X Consortium 1062449Speter# 11174993Srafan# Permission is hereby granted, free of charge, to any person obtaining a copy 12174993Srafan# of this software and associated documentation files (the "Software"), to 13174993Srafan# deal in the Software without restriction, including without limitation the 14174993Srafan# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 15174993Srafan# sell copies of the Software, and to permit persons to whom the Software is 16174993Srafan# furnished to do so, subject to the following conditions: 17174993Srafan# 18174993Srafan# The above copyright notice and this permission notice shall be included in 19174993Srafan# all copies or substantial portions of the Software. 20174993Srafan# 21174993Srafan# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22174993Srafan# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23174993Srafan# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24174993Srafan# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 25174993Srafan# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 26174993Srafan# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27174993Srafan# 28174993Srafan# Except as contained in this notice, the name of the X Consortium shall not 29174993Srafan# be used in advertising or otherwise to promote the sale, use or other deal- 30174993Srafan# ings in this Software without prior written authorization from the X Consor- 31174993Srafan# tium. 32174993Srafan# 33174993Srafan# 34174993Srafan# FSF changes to this file are in the public domain. 35174993Srafan# 3650276Speter# Calling this script install-sh is preferred over install.sh, to prevent 3750276Speter# `make' implicit rules from creating a file called install from it 3850276Speter# when there is no Makefile. 3950276Speter# 4050276Speter# This script is compatible with the BSD install script, but was written 4162449Speter# from scratch. It can only install one file at a time, a restriction 4262449Speter# shared with many OS's install programs. 4350276Speter 4450276Speter 4550276Speter# set DOITPROG to echo to test this script 4650276Speter 4750276Speter# Don't use :- since 4.3BSD and earlier shells don't like it. 4850276Speterdoit="${DOITPROG-}" 4950276Speter 5050276Speter 5150276Speter# put in absolute paths if you don't have them in your path; or use env. vars. 5250276Speter 5350276Spetermvprog="${MVPROG-mv}" 5450276Spetercpprog="${CPPROG-cp}" 5550276Speterchmodprog="${CHMODPROG-chmod}" 5650276Speterchownprog="${CHOWNPROG-chown}" 5750276Speterchgrpprog="${CHGRPPROG-chgrp}" 5850276Speterstripprog="${STRIPPROG-strip}" 5950276Speterrmprog="${RMPROG-rm}" 6050276Spetermkdirprog="${MKDIRPROG-mkdir}" 6150276Speter 6262449Spetertransformbasename="" 6350276Spetertransform_arg="" 6450276Speterinstcmd="$mvprog" 6550276Speterchmodcmd="$chmodprog 0755" 6650276Speterchowncmd="" 6750276Speterchgrpcmd="" 6850276Speterstripcmd="" 6950276Speterrmcmd="$rmprog -f" 7050276Spetermvcmd="$mvprog" 7150276Spetersrc="" 7250276Speterdst="" 7350276Speterdir_arg="" 7450276Speter 7550276Speterwhile [ x"$1" != x ]; do 7650276Speter case $1 in 77174993Srafan -c) instcmd=$cpprog 7850276Speter shift 7950276Speter continue;; 8050276Speter 8150276Speter -d) dir_arg=true 8250276Speter shift 8350276Speter continue;; 8450276Speter 8550276Speter -m) chmodcmd="$chmodprog $2" 8650276Speter shift 8750276Speter shift 8850276Speter continue;; 8950276Speter 9050276Speter -o) chowncmd="$chownprog $2" 9150276Speter shift 9250276Speter shift 9350276Speter continue;; 9450276Speter 9550276Speter -g) chgrpcmd="$chgrpprog $2" 9650276Speter shift 9750276Speter shift 9850276Speter continue;; 9950276Speter 100174993Srafan -s) stripcmd=$stripprog 10150276Speter shift 10250276Speter continue;; 10350276Speter 10450276Speter -t=*) transformarg=`echo $1 | sed 's/-t=//'` 10550276Speter shift 10650276Speter continue;; 10750276Speter 10850276Speter -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 10950276Speter shift 11050276Speter continue;; 11150276Speter 11250276Speter *) if [ x"$src" = x ] 11350276Speter then 11450276Speter src=$1 11550276Speter else 11650276Speter # this colon is to work around a 386BSD /bin/sh bug 11750276Speter : 11850276Speter dst=$1 11950276Speter fi 12050276Speter shift 12150276Speter continue;; 12250276Speter esac 12350276Speterdone 12450276Speter 12550276Speterif [ x"$src" = x ] 12650276Speterthen 127174993Srafan echo "$0: no input file specified" >&2 12850276Speter exit 1 12950276Speterelse 130166124Srafan : 13150276Speterfi 13250276Speter 13350276Speterif [ x"$dir_arg" != x ]; then 13450276Speter dst=$src 13550276Speter src="" 136166124Srafan 137174993Srafan if [ -d "$dst" ]; then 13850276Speter instcmd=: 139166124Srafan chmodcmd="" 14050276Speter else 141166124Srafan instcmd=$mkdirprog 14250276Speter fi 14350276Speterelse 14450276Speter 14550276Speter# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 146166124Srafan# might cause directories to be created, which would be especially bad 14750276Speter# if $src (and thus $dsttmp) contains '*'. 14850276Speter 149174993Srafan if [ -f "$src" ] || [ -d "$src" ] 15050276Speter then 151166124Srafan : 15250276Speter else 153174993Srafan echo "$0: $src does not exist" >&2 15450276Speter exit 1 15550276Speter fi 156166124Srafan 15750276Speter if [ x"$dst" = x ] 15850276Speter then 159174993Srafan echo "$0: no destination specified" >&2 16050276Speter exit 1 16150276Speter else 162166124Srafan : 16350276Speter fi 16450276Speter 16550276Speter# If destination is a directory, append the input filename; if your system 16650276Speter# does not like double slashes in filenames, you may need to add some logic 16750276Speter 168174993Srafan if [ -d "$dst" ] 16950276Speter then 170174993Srafan dst=$dst/`basename "$src"` 17150276Speter else 172166124Srafan : 17350276Speter fi 17450276Speterfi 17550276Speter 17650276Speter## this sed command emulates the dirname command 177174993Srafandstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 17850276Speter 17950276Speter# Make sure that the destination directory exists. 18050276Speter# this part is taken from Noah Friedman's mkinstalldirs script 18150276Speter 18250276Speter# Skip lots of stat calls in the usual case. 18350276Speterif [ ! -d "$dstdir" ]; then 184166124SrafandefaultIFS=' 185166124Srafan ' 186174993SrafanIFS="${IFS-$defaultIFS}" 18750276Speter 188174993SrafanoIFS=$IFS 18950276Speter# Some sh's can't handle IFS=/ for some reason. 19050276SpeterIFS='%' 191174993Srafanset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 192174993SrafanIFS=$oIFS 19350276Speter 19450276Speterpathcomp='' 19550276Speter 19650276Speterwhile [ $# -ne 0 ] ; do 197174993Srafan pathcomp=$pathcomp$1 19850276Speter shift 19950276Speter 200174993Srafan if [ ! -d "$pathcomp" ] ; 20150276Speter then 202174993Srafan $mkdirprog "$pathcomp" 20350276Speter else 204166124Srafan : 20550276Speter fi 20650276Speter 207174993Srafan pathcomp=$pathcomp/ 20850276Speterdone 20950276Speterfi 21050276Speter 21150276Speterif [ x"$dir_arg" != x ] 21250276Speterthen 213174993Srafan $doit $instcmd "$dst" && 21450276Speter 215174993Srafan if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 216174993Srafan if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 217174993Srafan if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 218174993Srafan if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 21950276Speterelse 22050276Speter 22150276Speter# If we're going to rename the final executable, determine the name now. 22250276Speter 223166124Srafan if [ x"$transformarg" = x ] 22450276Speter then 225174993Srafan dstfile=`basename "$dst"` 22650276Speter else 227174993Srafan dstfile=`basename "$dst" $transformbasename | 22850276Speter sed $transformarg`$transformbasename 22950276Speter fi 23050276Speter 23150276Speter# don't allow the sed command to completely eliminate the filename 23250276Speter 233166124Srafan if [ x"$dstfile" = x ] 23450276Speter then 235174993Srafan dstfile=`basename "$dst"` 23650276Speter else 237166124Srafan : 23850276Speter fi 23950276Speter 240174993Srafan# Make a couple of temp file names in the proper directory. 24150276Speter 24250276Speter dsttmp=$dstdir/#inst.$$# 243174993Srafan rmtmp=$dstdir/#rm.$$# 24450276Speter 245174993Srafan# Trap to clean up temp files at exit. 246174993Srafan 247174993Srafan trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 248174993Srafan trap '(exit $?); exit' 1 2 13 15 249174993Srafan 25050276Speter# Move or copy the file name to the temp name 25150276Speter 252174993Srafan $doit $instcmd "$src" "$dsttmp" && 25350276Speter 25450276Speter# and set any options; do chmod last to preserve setuid bits 25550276Speter 25650276Speter# If any of these fail, we abort the whole thing. If we want to 25750276Speter# ignore errors from any of these, just make sure not to ignore 25850276Speter# errors from the above "$doit $instcmd $src $dsttmp" command. 25950276Speter 260174993Srafan if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 261174993Srafan if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 262174993Srafan if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 263174993Srafan if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 26450276Speter 265174993Srafan# Now remove or move aside any old file at destination location. We try this 266174993Srafan# two ways since rm can't unlink itself on some systems and the destination 267174993Srafan# file might be busy for other reasons. In this case, the final cleanup 268174993Srafan# might fail but the new file should still install successfully. 269174993Srafan 270174993Srafan{ 271174993Srafan if [ -f "$dstdir/$dstfile" ] 272174993Srafan then 273174993Srafan $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 274174993Srafan $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 275174993Srafan { 276174993Srafan echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 277174993Srafan (exit 1); exit 278174993Srafan } 279174993Srafan else 280174993Srafan : 281174993Srafan fi 282174993Srafan} && 283174993Srafan 28450276Speter# Now rename the file to the real destination. 28550276Speter 286174993Srafan $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 28750276Speter 28850276Speterfi && 28950276Speter 290174993Srafan# The final little trick to "correctly" pass the exit status to the exit trap. 29150276Speter 292174993Srafan{ 293174993Srafan (exit 0); exit 294174993Srafan} 295