install-sh revision 1cc8c64f
11cc8c64fSmrg#!/bin/sh 21cc8c64fSmrg# 31cc8c64fSmrg# install - install a program, script, or datafile 41cc8c64fSmrg# 51cc8c64fSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 61cc8c64fSmrg# later released in X11R6 (xc/config/util/install.sh) with the 71cc8c64fSmrg# following copyright and license. 81cc8c64fSmrg# 91cc8c64fSmrg# Copyright (C) 1994 X Consortium 101cc8c64fSmrg# 111cc8c64fSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 121cc8c64fSmrg# of this software and associated documentation files (the "Software"), to 131cc8c64fSmrg# deal in the Software without restriction, including without limitation the 141cc8c64fSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 151cc8c64fSmrg# sell copies of the Software, and to permit persons to whom the Software is 161cc8c64fSmrg# furnished to do so, subject to the following conditions: 171cc8c64fSmrg# 181cc8c64fSmrg# The above copyright notice and this permission notice shall be included in 191cc8c64fSmrg# all copies or substantial portions of the Software. 201cc8c64fSmrg# 211cc8c64fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 221cc8c64fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 231cc8c64fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 241cc8c64fSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 251cc8c64fSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 261cc8c64fSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 271cc8c64fSmrg# 281cc8c64fSmrg# Except as contained in this notice, the name of the X Consortium shall not 291cc8c64fSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 301cc8c64fSmrg# ings in this Software without prior written authorization from the X Consor- 311cc8c64fSmrg# tium. 321cc8c64fSmrg# 331cc8c64fSmrg# 341cc8c64fSmrg# FSF changes to this file are in the public domain. 351cc8c64fSmrg# 361cc8c64fSmrg# Calling this script install-sh is preferred over install.sh, to prevent 371cc8c64fSmrg# `make' implicit rules from creating a file called install from it 381cc8c64fSmrg# when there is no Makefile. 391cc8c64fSmrg# 401cc8c64fSmrg# This script is compatible with the BSD install script, but was written 411cc8c64fSmrg# from scratch. It can only install one file at a time, a restriction 421cc8c64fSmrg# shared with many OS's install programs. 431cc8c64fSmrg 441cc8c64fSmrg 451cc8c64fSmrg# set DOITPROG to echo to test this script 461cc8c64fSmrg 471cc8c64fSmrg# Don't use :- since 4.3BSD and earlier shells don't like it. 481cc8c64fSmrgdoit="${DOITPROG-}" 491cc8c64fSmrg 501cc8c64fSmrg 511cc8c64fSmrg# put in absolute paths if you don't have them in your path; or use env. vars. 521cc8c64fSmrg 531cc8c64fSmrgmvprog="${MVPROG-mv}" 541cc8c64fSmrgcpprog="${CPPROG-cp}" 551cc8c64fSmrgchmodprog="${CHMODPROG-chmod}" 561cc8c64fSmrgchownprog="${CHOWNPROG-chown}" 571cc8c64fSmrgchgrpprog="${CHGRPPROG-chgrp}" 581cc8c64fSmrgstripprog="${STRIPPROG-strip}" 591cc8c64fSmrgrmprog="${RMPROG-rm}" 601cc8c64fSmrgmkdirprog="${MKDIRPROG-mkdir}" 611cc8c64fSmrg 621cc8c64fSmrgtransformbasename="" 631cc8c64fSmrgtransform_arg="" 641cc8c64fSmrginstcmd="$mvprog" 651cc8c64fSmrgchmodcmd="$chmodprog 0755" 661cc8c64fSmrgchowncmd="" 671cc8c64fSmrgchgrpcmd="" 681cc8c64fSmrgstripcmd="" 691cc8c64fSmrgrmcmd="$rmprog -f" 701cc8c64fSmrgmvcmd="$mvprog" 711cc8c64fSmrgsrc="" 721cc8c64fSmrgdst="" 731cc8c64fSmrgdir_arg="" 741cc8c64fSmrg 751cc8c64fSmrgwhile [ x"$1" != x ]; do 761cc8c64fSmrg case $1 in 771cc8c64fSmrg -c) instcmd=$cpprog 781cc8c64fSmrg shift 791cc8c64fSmrg continue;; 801cc8c64fSmrg 811cc8c64fSmrg -d) dir_arg=true 821cc8c64fSmrg shift 831cc8c64fSmrg continue;; 841cc8c64fSmrg 851cc8c64fSmrg -m) chmodcmd="$chmodprog $2" 861cc8c64fSmrg shift 871cc8c64fSmrg shift 881cc8c64fSmrg continue;; 891cc8c64fSmrg 901cc8c64fSmrg -o) chowncmd="$chownprog $2" 911cc8c64fSmrg shift 921cc8c64fSmrg shift 931cc8c64fSmrg continue;; 941cc8c64fSmrg 951cc8c64fSmrg -g) chgrpcmd="$chgrpprog $2" 961cc8c64fSmrg shift 971cc8c64fSmrg shift 981cc8c64fSmrg continue;; 991cc8c64fSmrg 1001cc8c64fSmrg -s) stripcmd=$stripprog 1011cc8c64fSmrg shift 1021cc8c64fSmrg continue;; 1031cc8c64fSmrg 1041cc8c64fSmrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 1051cc8c64fSmrg shift 1061cc8c64fSmrg continue;; 1071cc8c64fSmrg 1081cc8c64fSmrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 1091cc8c64fSmrg shift 1101cc8c64fSmrg continue;; 1111cc8c64fSmrg 1121cc8c64fSmrg *) if [ x"$src" = x ] 1131cc8c64fSmrg then 1141cc8c64fSmrg src=$1 1151cc8c64fSmrg else 1161cc8c64fSmrg # this colon is to work around a 386BSD /bin/sh bug 1171cc8c64fSmrg : 1181cc8c64fSmrg dst=$1 1191cc8c64fSmrg fi 1201cc8c64fSmrg shift 1211cc8c64fSmrg continue;; 1221cc8c64fSmrg esac 1231cc8c64fSmrgdone 1241cc8c64fSmrg 1251cc8c64fSmrgif [ x"$src" = x ] 1261cc8c64fSmrgthen 1271cc8c64fSmrg echo "$0: no input file specified" >&2 1281cc8c64fSmrg exit 1 1291cc8c64fSmrgelse 1301cc8c64fSmrg : 1311cc8c64fSmrgfi 1321cc8c64fSmrg 1331cc8c64fSmrgif [ x"$dir_arg" != x ]; then 1341cc8c64fSmrg dst=$src 1351cc8c64fSmrg src="" 1361cc8c64fSmrg 1371cc8c64fSmrg if [ -d "$dst" ]; then 1381cc8c64fSmrg instcmd=: 1391cc8c64fSmrg chmodcmd="" 1401cc8c64fSmrg else 1411cc8c64fSmrg instcmd=$mkdirprog 1421cc8c64fSmrg fi 1431cc8c64fSmrgelse 1441cc8c64fSmrg 1451cc8c64fSmrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 1461cc8c64fSmrg# might cause directories to be created, which would be especially bad 1471cc8c64fSmrg# if $src (and thus $dsttmp) contains '*'. 1481cc8c64fSmrg 1491cc8c64fSmrg if [ -f "$src" ] || [ -d "$src" ] 1501cc8c64fSmrg then 1511cc8c64fSmrg : 1521cc8c64fSmrg else 1531cc8c64fSmrg echo "$0: $src does not exist" >&2 1541cc8c64fSmrg exit 1 1551cc8c64fSmrg fi 1561cc8c64fSmrg 1571cc8c64fSmrg if [ x"$dst" = x ] 1581cc8c64fSmrg then 1591cc8c64fSmrg echo "$0: no destination specified" >&2 1601cc8c64fSmrg exit 1 1611cc8c64fSmrg else 1621cc8c64fSmrg : 1631cc8c64fSmrg fi 1641cc8c64fSmrg 1651cc8c64fSmrg# If destination is a directory, append the input filename; if your system 1661cc8c64fSmrg# does not like double slashes in filenames, you may need to add some logic 1671cc8c64fSmrg 1681cc8c64fSmrg if [ -d "$dst" ] 1691cc8c64fSmrg then 1701cc8c64fSmrg dst=$dst/`basename "$src"` 1711cc8c64fSmrg else 1721cc8c64fSmrg : 1731cc8c64fSmrg fi 1741cc8c64fSmrgfi 1751cc8c64fSmrg 1761cc8c64fSmrg## this sed command emulates the dirname command 1771cc8c64fSmrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 1781cc8c64fSmrg 1791cc8c64fSmrg# Make sure that the destination directory exists. 1801cc8c64fSmrg# this part is taken from Noah Friedman's mkinstalldirs script 1811cc8c64fSmrg 1821cc8c64fSmrg# Skip lots of stat calls in the usual case. 1831cc8c64fSmrgif [ ! -d "$dstdir" ]; then 1841cc8c64fSmrgdefaultIFS=' 1851cc8c64fSmrg ' 1861cc8c64fSmrgIFS="${IFS-$defaultIFS}" 1871cc8c64fSmrg 1881cc8c64fSmrgoIFS=$IFS 1891cc8c64fSmrg# Some sh's can't handle IFS=/ for some reason. 1901cc8c64fSmrgIFS='%' 1911cc8c64fSmrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 1921cc8c64fSmrgIFS=$oIFS 1931cc8c64fSmrg 1941cc8c64fSmrgpathcomp='' 1951cc8c64fSmrg 1961cc8c64fSmrgwhile [ $# -ne 0 ] ; do 1971cc8c64fSmrg pathcomp=$pathcomp$1 1981cc8c64fSmrg shift 1991cc8c64fSmrg 2001cc8c64fSmrg if [ ! -d "$pathcomp" ] ; 2011cc8c64fSmrg then 2021cc8c64fSmrg $mkdirprog "$pathcomp" 2031cc8c64fSmrg else 2041cc8c64fSmrg : 2051cc8c64fSmrg fi 2061cc8c64fSmrg 2071cc8c64fSmrg pathcomp=$pathcomp/ 2081cc8c64fSmrgdone 2091cc8c64fSmrgfi 2101cc8c64fSmrg 2111cc8c64fSmrgif [ x"$dir_arg" != x ] 2121cc8c64fSmrgthen 2131cc8c64fSmrg $doit $instcmd "$dst" && 2141cc8c64fSmrg 2151cc8c64fSmrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 2161cc8c64fSmrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 2171cc8c64fSmrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 2181cc8c64fSmrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 2191cc8c64fSmrgelse 2201cc8c64fSmrg 2211cc8c64fSmrg# If we're going to rename the final executable, determine the name now. 2221cc8c64fSmrg 2231cc8c64fSmrg if [ x"$transformarg" = x ] 2241cc8c64fSmrg then 2251cc8c64fSmrg dstfile=`basename "$dst"` 2261cc8c64fSmrg else 2271cc8c64fSmrg dstfile=`basename "$dst" $transformbasename | 2281cc8c64fSmrg sed $transformarg`$transformbasename 2291cc8c64fSmrg fi 2301cc8c64fSmrg 2311cc8c64fSmrg# don't allow the sed command to completely eliminate the filename 2321cc8c64fSmrg 2331cc8c64fSmrg if [ x"$dstfile" = x ] 2341cc8c64fSmrg then 2351cc8c64fSmrg dstfile=`basename "$dst"` 2361cc8c64fSmrg else 2371cc8c64fSmrg : 2381cc8c64fSmrg fi 2391cc8c64fSmrg 2401cc8c64fSmrg# Make a couple of temp file names in the proper directory. 2411cc8c64fSmrg 2421cc8c64fSmrg dsttmp=$dstdir/_inst.$$_ 2431cc8c64fSmrg rmtmp=$dstdir/_rm.$$_ 2441cc8c64fSmrg 2451cc8c64fSmrg# Trap to clean up temp files at exit. 2461cc8c64fSmrg 2471cc8c64fSmrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 2481cc8c64fSmrg trap '(exit $?); exit' 1 2 13 15 2491cc8c64fSmrg 2501cc8c64fSmrg# Move or copy the file name to the temp name 2511cc8c64fSmrg 2521cc8c64fSmrg $doit $instcmd "$src" "$dsttmp" && 2531cc8c64fSmrg 2541cc8c64fSmrg# and set any options; do chmod last to preserve setuid bits 2551cc8c64fSmrg 2561cc8c64fSmrg# If any of these fail, we abort the whole thing. If we want to 2571cc8c64fSmrg# ignore errors from any of these, just make sure not to ignore 2581cc8c64fSmrg# errors from the above "$doit $instcmd $src $dsttmp" command. 2591cc8c64fSmrg 2601cc8c64fSmrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 2611cc8c64fSmrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 2621cc8c64fSmrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 2631cc8c64fSmrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 2641cc8c64fSmrg 2651cc8c64fSmrg# Now remove or move aside any old file at destination location. We try this 2661cc8c64fSmrg# two ways since rm can't unlink itself on some systems and the destination 2671cc8c64fSmrg# file might be busy for other reasons. In this case, the final cleanup 2681cc8c64fSmrg# might fail but the new file should still install successfully. 2691cc8c64fSmrg 2701cc8c64fSmrg{ 2711cc8c64fSmrg if [ -f "$dstdir/$dstfile" ] 2721cc8c64fSmrg then 2731cc8c64fSmrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 2741cc8c64fSmrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 2751cc8c64fSmrg { 2761cc8c64fSmrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 2771cc8c64fSmrg (exit 1); exit 2781cc8c64fSmrg } 2791cc8c64fSmrg else 2801cc8c64fSmrg : 2811cc8c64fSmrg fi 2821cc8c64fSmrg} && 2831cc8c64fSmrg 2841cc8c64fSmrg# Now rename the file to the real destination. 2851cc8c64fSmrg 2861cc8c64fSmrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 2871cc8c64fSmrg 2881cc8c64fSmrgfi && 2891cc8c64fSmrg 2901cc8c64fSmrg# The final little trick to "correctly" pass the exit status to the exit trap. 2911cc8c64fSmrg 2921cc8c64fSmrg{ 2931cc8c64fSmrg (exit 0); exit 2941cc8c64fSmrg} 295