install-sh revision 0e20ee16
10e20ee16Smrg#!/bin/sh 20e20ee16Smrg# 30e20ee16Smrg# install - install a program, script, or datafile 40e20ee16Smrg# 50e20ee16Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 60e20ee16Smrg# later released in X11R6 (xc/config/util/install.sh) with the 70e20ee16Smrg# following copyright and license. 80e20ee16Smrg# 90e20ee16Smrg# Copyright (C) 1994 X Consortium 100e20ee16Smrg# 110e20ee16Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 120e20ee16Smrg# of this software and associated documentation files (the "Software"), to 130e20ee16Smrg# deal in the Software without restriction, including without limitation the 140e20ee16Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 150e20ee16Smrg# sell copies of the Software, and to permit persons to whom the Software is 160e20ee16Smrg# furnished to do so, subject to the following conditions: 170e20ee16Smrg# 180e20ee16Smrg# The above copyright notice and this permission notice shall be included in 190e20ee16Smrg# all copies or substantial portions of the Software. 200e20ee16Smrg# 210e20ee16Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 220e20ee16Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 230e20ee16Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 240e20ee16Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 250e20ee16Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 260e20ee16Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 270e20ee16Smrg# 280e20ee16Smrg# Except as contained in this notice, the name of the X Consortium shall not 290e20ee16Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 300e20ee16Smrg# ings in this Software without prior written authorization from the X Consor- 310e20ee16Smrg# tium. 320e20ee16Smrg# 330e20ee16Smrg# 340e20ee16Smrg# FSF changes to this file are in the public domain. 350e20ee16Smrg# 360e20ee16Smrg# Calling this script install-sh is preferred over install.sh, to prevent 370e20ee16Smrg# `make' implicit rules from creating a file called install from it 380e20ee16Smrg# when there is no Makefile. 390e20ee16Smrg# 400e20ee16Smrg# This script is compatible with the BSD install script, but was written 410e20ee16Smrg# from scratch. It can only install one file at a time, a restriction 420e20ee16Smrg# shared with many OS's install programs. 430e20ee16Smrg 440e20ee16Smrg 450e20ee16Smrg# set DOITPROG to echo to test this script 460e20ee16Smrg 470e20ee16Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 480e20ee16Smrgdoit="${DOITPROG-}" 490e20ee16Smrg 500e20ee16Smrg 510e20ee16Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 520e20ee16Smrg 530e20ee16Smrgmvprog="${MVPROG-mv}" 540e20ee16Smrgcpprog="${CPPROG-cp}" 550e20ee16Smrgchmodprog="${CHMODPROG-chmod}" 560e20ee16Smrgchownprog="${CHOWNPROG-chown}" 570e20ee16Smrgchgrpprog="${CHGRPPROG-chgrp}" 580e20ee16Smrgstripprog="${STRIPPROG-strip}" 590e20ee16Smrgrmprog="${RMPROG-rm}" 600e20ee16Smrgmkdirprog="${MKDIRPROG-mkdir}" 610e20ee16Smrg 620e20ee16Smrgtransformbasename="" 630e20ee16Smrgtransform_arg="" 640e20ee16Smrginstcmd="$mvprog" 650e20ee16Smrgchmodcmd="$chmodprog 0755" 660e20ee16Smrgchowncmd="" 670e20ee16Smrgchgrpcmd="" 680e20ee16Smrgstripcmd="" 690e20ee16Smrgrmcmd="$rmprog -f" 700e20ee16Smrgmvcmd="$mvprog" 710e20ee16Smrgsrc="" 720e20ee16Smrgdst="" 730e20ee16Smrgdir_arg="" 740e20ee16Smrg 750e20ee16Smrgwhile [ x"$1" != x ]; do 760e20ee16Smrg case $1 in 770e20ee16Smrg -c) instcmd=$cpprog 780e20ee16Smrg shift 790e20ee16Smrg continue;; 800e20ee16Smrg 810e20ee16Smrg -d) dir_arg=true 820e20ee16Smrg shift 830e20ee16Smrg continue;; 840e20ee16Smrg 850e20ee16Smrg -m) chmodcmd="$chmodprog $2" 860e20ee16Smrg shift 870e20ee16Smrg shift 880e20ee16Smrg continue;; 890e20ee16Smrg 900e20ee16Smrg -o) chowncmd="$chownprog $2" 910e20ee16Smrg shift 920e20ee16Smrg shift 930e20ee16Smrg continue;; 940e20ee16Smrg 950e20ee16Smrg -g) chgrpcmd="$chgrpprog $2" 960e20ee16Smrg shift 970e20ee16Smrg shift 980e20ee16Smrg continue;; 990e20ee16Smrg 1000e20ee16Smrg -s) stripcmd=$stripprog 1010e20ee16Smrg shift 1020e20ee16Smrg continue;; 1030e20ee16Smrg 1040e20ee16Smrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 1050e20ee16Smrg shift 1060e20ee16Smrg continue;; 1070e20ee16Smrg 1080e20ee16Smrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 1090e20ee16Smrg shift 1100e20ee16Smrg continue;; 1110e20ee16Smrg 1120e20ee16Smrg *) if [ x"$src" = x ] 1130e20ee16Smrg then 1140e20ee16Smrg src=$1 1150e20ee16Smrg else 1160e20ee16Smrg # this colon is to work around a 386BSD /bin/sh bug 1170e20ee16Smrg : 1180e20ee16Smrg dst=$1 1190e20ee16Smrg fi 1200e20ee16Smrg shift 1210e20ee16Smrg continue;; 1220e20ee16Smrg esac 1230e20ee16Smrgdone 1240e20ee16Smrg 1250e20ee16Smrgif [ x"$src" = x ] 1260e20ee16Smrgthen 1270e20ee16Smrg echo "$0: no input file specified" >&2 1280e20ee16Smrg exit 1 1290e20ee16Smrgelse 1300e20ee16Smrg : 1310e20ee16Smrgfi 1320e20ee16Smrg 1330e20ee16Smrgif [ x"$dir_arg" != x ]; then 1340e20ee16Smrg dst=$src 1350e20ee16Smrg src="" 1360e20ee16Smrg 1370e20ee16Smrg if [ -d "$dst" ]; then 1380e20ee16Smrg instcmd=: 1390e20ee16Smrg chmodcmd="" 1400e20ee16Smrg else 1410e20ee16Smrg instcmd=$mkdirprog 1420e20ee16Smrg fi 1430e20ee16Smrgelse 1440e20ee16Smrg 1450e20ee16Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 1460e20ee16Smrg# might cause directories to be created, which would be especially bad 1470e20ee16Smrg# if $src (and thus $dsttmp) contains '*'. 1480e20ee16Smrg 1490e20ee16Smrg if [ -f "$src" ] || [ -d "$src" ] 1500e20ee16Smrg then 1510e20ee16Smrg : 1520e20ee16Smrg else 1530e20ee16Smrg echo "$0: $src does not exist" >&2 1540e20ee16Smrg exit 1 1550e20ee16Smrg fi 1560e20ee16Smrg 1570e20ee16Smrg if [ x"$dst" = x ] 1580e20ee16Smrg then 1590e20ee16Smrg echo "$0: no destination specified" >&2 1600e20ee16Smrg exit 1 1610e20ee16Smrg else 1620e20ee16Smrg : 1630e20ee16Smrg fi 1640e20ee16Smrg 1650e20ee16Smrg# If destination is a directory, append the input filename; if your system 1660e20ee16Smrg# does not like double slashes in filenames, you may need to add some logic 1670e20ee16Smrg 1680e20ee16Smrg if [ -d "$dst" ] 1690e20ee16Smrg then 1700e20ee16Smrg dst=$dst/`basename "$src"` 1710e20ee16Smrg else 1720e20ee16Smrg : 1730e20ee16Smrg fi 1740e20ee16Smrgfi 1750e20ee16Smrg 1760e20ee16Smrg## this sed command emulates the dirname command 1770e20ee16Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 1780e20ee16Smrg 1790e20ee16Smrg# Make sure that the destination directory exists. 1800e20ee16Smrg# this part is taken from Noah Friedman's mkinstalldirs script 1810e20ee16Smrg 1820e20ee16Smrg# Skip lots of stat calls in the usual case. 1830e20ee16Smrgif [ ! -d "$dstdir" ]; then 1840e20ee16SmrgdefaultIFS=' 1850e20ee16Smrg ' 1860e20ee16SmrgIFS="${IFS-$defaultIFS}" 1870e20ee16Smrg 1880e20ee16SmrgoIFS=$IFS 1890e20ee16Smrg# Some sh's can't handle IFS=/ for some reason. 1900e20ee16SmrgIFS='%' 1910e20ee16Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 1920e20ee16SmrgIFS=$oIFS 1930e20ee16Smrg 1940e20ee16Smrgpathcomp='' 1950e20ee16Smrg 1960e20ee16Smrgwhile [ $# -ne 0 ] ; do 1970e20ee16Smrg pathcomp=$pathcomp$1 1980e20ee16Smrg shift 1990e20ee16Smrg 2000e20ee16Smrg if [ ! -d "$pathcomp" ] ; 2010e20ee16Smrg then 2020e20ee16Smrg $mkdirprog "$pathcomp" 2030e20ee16Smrg else 2040e20ee16Smrg : 2050e20ee16Smrg fi 2060e20ee16Smrg 2070e20ee16Smrg pathcomp=$pathcomp/ 2080e20ee16Smrgdone 2090e20ee16Smrgfi 2100e20ee16Smrg 2110e20ee16Smrgif [ x"$dir_arg" != x ] 2120e20ee16Smrgthen 2130e20ee16Smrg $doit $instcmd "$dst" && 2140e20ee16Smrg 2150e20ee16Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 2160e20ee16Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 2170e20ee16Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 2180e20ee16Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 2190e20ee16Smrgelse 2200e20ee16Smrg 2210e20ee16Smrg# If we're going to rename the final executable, determine the name now. 2220e20ee16Smrg 2230e20ee16Smrg if [ x"$transformarg" = x ] 2240e20ee16Smrg then 2250e20ee16Smrg dstfile=`basename "$dst"` 2260e20ee16Smrg else 2270e20ee16Smrg dstfile=`basename "$dst" $transformbasename | 2280e20ee16Smrg sed $transformarg`$transformbasename 2290e20ee16Smrg fi 2300e20ee16Smrg 2310e20ee16Smrg# don't allow the sed command to completely eliminate the filename 2320e20ee16Smrg 2330e20ee16Smrg if [ x"$dstfile" = x ] 2340e20ee16Smrg then 2350e20ee16Smrg dstfile=`basename "$dst"` 2360e20ee16Smrg else 2370e20ee16Smrg : 2380e20ee16Smrg fi 2390e20ee16Smrg 2400e20ee16Smrg# Make a couple of temp file names in the proper directory. 2410e20ee16Smrg 2420e20ee16Smrg dsttmp=$dstdir/_inst.$$_ 2430e20ee16Smrg rmtmp=$dstdir/_rm.$$_ 2440e20ee16Smrg 2450e20ee16Smrg# Trap to clean up temp files at exit. 2460e20ee16Smrg 2470e20ee16Smrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 2480e20ee16Smrg trap '(exit $?); exit' 1 2 13 15 2490e20ee16Smrg 2500e20ee16Smrg# Move or copy the file name to the temp name 2510e20ee16Smrg 2520e20ee16Smrg $doit $instcmd "$src" "$dsttmp" && 2530e20ee16Smrg 2540e20ee16Smrg# and set any options; do chmod last to preserve setuid bits 2550e20ee16Smrg 2560e20ee16Smrg# If any of these fail, we abort the whole thing. If we want to 2570e20ee16Smrg# ignore errors from any of these, just make sure not to ignore 2580e20ee16Smrg# errors from the above "$doit $instcmd $src $dsttmp" command. 2590e20ee16Smrg 2600e20ee16Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 2610e20ee16Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 2620e20ee16Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 2630e20ee16Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 2640e20ee16Smrg 2650e20ee16Smrg# Now remove or move aside any old file at destination location. We try this 2660e20ee16Smrg# two ways since rm can't unlink itself on some systems and the destination 2670e20ee16Smrg# file might be busy for other reasons. In this case, the final cleanup 2680e20ee16Smrg# might fail but the new file should still install successfully. 2690e20ee16Smrg 2700e20ee16Smrg{ 2710e20ee16Smrg if [ -f "$dstdir/$dstfile" ] 2720e20ee16Smrg then 2730e20ee16Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 2740e20ee16Smrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 2750e20ee16Smrg { 2760e20ee16Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 2770e20ee16Smrg (exit 1); exit 2780e20ee16Smrg } 2790e20ee16Smrg else 2800e20ee16Smrg : 2810e20ee16Smrg fi 2820e20ee16Smrg} && 2830e20ee16Smrg 2840e20ee16Smrg# Now rename the file to the real destination. 2850e20ee16Smrg 2860e20ee16Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 2870e20ee16Smrg 2880e20ee16Smrgfi && 2890e20ee16Smrg 2900e20ee16Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 2910e20ee16Smrg 2920e20ee16Smrg{ 2930e20ee16Smrg (exit 0); exit 2940e20ee16Smrg} 295