install-sh revision 3294c433
13294c433Smrg#!/bin/sh 23294c433Smrg# 33294c433Smrg# install - install a program, script, or datafile 43294c433Smrg# 53294c433Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 63294c433Smrg# later released in X11R6 (xc/config/util/install.sh) with the 73294c433Smrg# following copyright and license. 83294c433Smrg# 93294c433Smrg# Copyright (C) 1994 X Consortium 103294c433Smrg# 113294c433Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 123294c433Smrg# of this software and associated documentation files (the "Software"), to 133294c433Smrg# deal in the Software without restriction, including without limitation the 143294c433Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 153294c433Smrg# sell copies of the Software, and to permit persons to whom the Software is 163294c433Smrg# furnished to do so, subject to the following conditions: 173294c433Smrg# 183294c433Smrg# The above copyright notice and this permission notice shall be included in 193294c433Smrg# all copies or substantial portions of the Software. 203294c433Smrg# 213294c433Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 223294c433Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 233294c433Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 243294c433Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 253294c433Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 263294c433Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 273294c433Smrg# 283294c433Smrg# Except as contained in this notice, the name of the X Consortium shall not 293294c433Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 303294c433Smrg# ings in this Software without prior written authorization from the X Consor- 313294c433Smrg# tium. 323294c433Smrg# 333294c433Smrg# 343294c433Smrg# FSF changes to this file are in the public domain. 353294c433Smrg# 363294c433Smrg# Calling this script install-sh is preferred over install.sh, to prevent 373294c433Smrg# `make' implicit rules from creating a file called install from it 383294c433Smrg# when there is no Makefile. 393294c433Smrg# 403294c433Smrg# This script is compatible with the BSD install script, but was written 413294c433Smrg# from scratch. It can only install one file at a time, a restriction 423294c433Smrg# shared with many OS's install programs. 433294c433Smrg 443294c433Smrg 453294c433Smrg# set DOITPROG to echo to test this script 463294c433Smrg 473294c433Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 483294c433Smrgdoit="${DOITPROG-}" 493294c433Smrg 503294c433Smrg 513294c433Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 523294c433Smrg 533294c433Smrgmvprog="${MVPROG-mv}" 543294c433Smrgcpprog="${CPPROG-cp}" 553294c433Smrgchmodprog="${CHMODPROG-chmod}" 563294c433Smrgchownprog="${CHOWNPROG-chown}" 573294c433Smrgchgrpprog="${CHGRPPROG-chgrp}" 583294c433Smrgstripprog="${STRIPPROG-strip}" 593294c433Smrgrmprog="${RMPROG-rm}" 603294c433Smrgmkdirprog="${MKDIRPROG-mkdir}" 613294c433Smrg 623294c433Smrgtransformbasename="" 633294c433Smrgtransform_arg="" 643294c433Smrginstcmd="$mvprog" 653294c433Smrgchmodcmd="$chmodprog 0755" 663294c433Smrgchowncmd="" 673294c433Smrgchgrpcmd="" 683294c433Smrgstripcmd="" 693294c433Smrgrmcmd="$rmprog -f" 703294c433Smrgmvcmd="$mvprog" 713294c433Smrgsrc="" 723294c433Smrgdst="" 733294c433Smrgdir_arg="" 743294c433Smrg 753294c433Smrgwhile [ x"$1" != x ]; do 763294c433Smrg case $1 in 773294c433Smrg -c) instcmd=$cpprog 783294c433Smrg shift 793294c433Smrg continue;; 803294c433Smrg 813294c433Smrg -d) dir_arg=true 823294c433Smrg shift 833294c433Smrg continue;; 843294c433Smrg 853294c433Smrg -m) chmodcmd="$chmodprog $2" 863294c433Smrg shift 873294c433Smrg shift 883294c433Smrg continue;; 893294c433Smrg 903294c433Smrg -o) chowncmd="$chownprog $2" 913294c433Smrg shift 923294c433Smrg shift 933294c433Smrg continue;; 943294c433Smrg 953294c433Smrg -g) chgrpcmd="$chgrpprog $2" 963294c433Smrg shift 973294c433Smrg shift 983294c433Smrg continue;; 993294c433Smrg 1003294c433Smrg -s) stripcmd=$stripprog 1013294c433Smrg shift 1023294c433Smrg continue;; 1033294c433Smrg 1043294c433Smrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 1053294c433Smrg shift 1063294c433Smrg continue;; 1073294c433Smrg 1083294c433Smrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 1093294c433Smrg shift 1103294c433Smrg continue;; 1113294c433Smrg 1123294c433Smrg *) if [ x"$src" = x ] 1133294c433Smrg then 1143294c433Smrg src=$1 1153294c433Smrg else 1163294c433Smrg # this colon is to work around a 386BSD /bin/sh bug 1173294c433Smrg : 1183294c433Smrg dst=$1 1193294c433Smrg fi 1203294c433Smrg shift 1213294c433Smrg continue;; 1223294c433Smrg esac 1233294c433Smrgdone 1243294c433Smrg 1253294c433Smrgif [ x"$src" = x ] 1263294c433Smrgthen 1273294c433Smrg echo "$0: no input file specified" >&2 1283294c433Smrg exit 1 1293294c433Smrgelse 1303294c433Smrg : 1313294c433Smrgfi 1323294c433Smrg 1333294c433Smrgif [ x"$dir_arg" != x ]; then 1343294c433Smrg dst=$src 1353294c433Smrg src="" 1363294c433Smrg 1373294c433Smrg if [ -d "$dst" ]; then 1383294c433Smrg instcmd=: 1393294c433Smrg chmodcmd="" 1403294c433Smrg else 1413294c433Smrg instcmd=$mkdirprog 1423294c433Smrg fi 1433294c433Smrgelse 1443294c433Smrg 1453294c433Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 1463294c433Smrg# might cause directories to be created, which would be especially bad 1473294c433Smrg# if $src (and thus $dsttmp) contains '*'. 1483294c433Smrg 1493294c433Smrg if [ -f "$src" ] || [ -d "$src" ] 1503294c433Smrg then 1513294c433Smrg : 1523294c433Smrg else 1533294c433Smrg echo "$0: $src does not exist" >&2 1543294c433Smrg exit 1 1553294c433Smrg fi 1563294c433Smrg 1573294c433Smrg if [ x"$dst" = x ] 1583294c433Smrg then 1593294c433Smrg echo "$0: no destination specified" >&2 1603294c433Smrg exit 1 1613294c433Smrg else 1623294c433Smrg : 1633294c433Smrg fi 1643294c433Smrg 1653294c433Smrg# If destination is a directory, append the input filename; if your system 1663294c433Smrg# does not like double slashes in filenames, you may need to add some logic 1673294c433Smrg 1683294c433Smrg if [ -d "$dst" ] 1693294c433Smrg then 1703294c433Smrg dst=$dst/`basename "$src"` 1713294c433Smrg else 1723294c433Smrg : 1733294c433Smrg fi 1743294c433Smrgfi 1753294c433Smrg 1763294c433Smrg## this sed command emulates the dirname command 1773294c433Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 1783294c433Smrg 1793294c433Smrg# Make sure that the destination directory exists. 1803294c433Smrg# this part is taken from Noah Friedman's mkinstalldirs script 1813294c433Smrg 1823294c433Smrg# Skip lots of stat calls in the usual case. 1833294c433Smrgif [ ! -d "$dstdir" ]; then 1843294c433SmrgdefaultIFS=' 1853294c433Smrg ' 1863294c433SmrgIFS="${IFS-$defaultIFS}" 1873294c433Smrg 1883294c433SmrgoIFS=$IFS 1893294c433Smrg# Some sh's can't handle IFS=/ for some reason. 1903294c433SmrgIFS='%' 1913294c433Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 1923294c433SmrgIFS=$oIFS 1933294c433Smrg 1943294c433Smrgpathcomp='' 1953294c433Smrg 1963294c433Smrgwhile [ $# -ne 0 ] ; do 1973294c433Smrg pathcomp=$pathcomp$1 1983294c433Smrg shift 1993294c433Smrg 2003294c433Smrg if [ ! -d "$pathcomp" ] ; 2013294c433Smrg then 2023294c433Smrg $mkdirprog "$pathcomp" 2033294c433Smrg else 2043294c433Smrg : 2053294c433Smrg fi 2063294c433Smrg 2073294c433Smrg pathcomp=$pathcomp/ 2083294c433Smrgdone 2093294c433Smrgfi 2103294c433Smrg 2113294c433Smrgif [ x"$dir_arg" != x ] 2123294c433Smrgthen 2133294c433Smrg $doit $instcmd "$dst" && 2143294c433Smrg 2153294c433Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 2163294c433Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 2173294c433Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 2183294c433Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 2193294c433Smrgelse 2203294c433Smrg 2213294c433Smrg# If we're going to rename the final executable, determine the name now. 2223294c433Smrg 2233294c433Smrg if [ x"$transformarg" = x ] 2243294c433Smrg then 2253294c433Smrg dstfile=`basename "$dst"` 2263294c433Smrg else 2273294c433Smrg dstfile=`basename "$dst" $transformbasename | 2283294c433Smrg sed $transformarg`$transformbasename 2293294c433Smrg fi 2303294c433Smrg 2313294c433Smrg# don't allow the sed command to completely eliminate the filename 2323294c433Smrg 2333294c433Smrg if [ x"$dstfile" = x ] 2343294c433Smrg then 2353294c433Smrg dstfile=`basename "$dst"` 2363294c433Smrg else 2373294c433Smrg : 2383294c433Smrg fi 2393294c433Smrg 2403294c433Smrg# Make a couple of temp file names in the proper directory. 2413294c433Smrg 2423294c433Smrg dsttmp=$dstdir/_inst.$$_ 2433294c433Smrg rmtmp=$dstdir/_rm.$$_ 2443294c433Smrg 2453294c433Smrg# Trap to clean up temp files at exit. 2463294c433Smrg 2473294c433Smrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 2483294c433Smrg trap '(exit $?); exit' 1 2 13 15 2493294c433Smrg 2503294c433Smrg# Move or copy the file name to the temp name 2513294c433Smrg 2523294c433Smrg $doit $instcmd "$src" "$dsttmp" && 2533294c433Smrg 2543294c433Smrg# and set any options; do chmod last to preserve setuid bits 2553294c433Smrg 2563294c433Smrg# If any of these fail, we abort the whole thing. If we want to 2573294c433Smrg# ignore errors from any of these, just make sure not to ignore 2583294c433Smrg# errors from the above "$doit $instcmd $src $dsttmp" command. 2593294c433Smrg 2603294c433Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 2613294c433Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 2623294c433Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 2633294c433Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 2643294c433Smrg 2653294c433Smrg# Now remove or move aside any old file at destination location. We try this 2663294c433Smrg# two ways since rm can't unlink itself on some systems and the destination 2673294c433Smrg# file might be busy for other reasons. In this case, the final cleanup 2683294c433Smrg# might fail but the new file should still install successfully. 2693294c433Smrg 2703294c433Smrg{ 2713294c433Smrg if [ -f "$dstdir/$dstfile" ] 2723294c433Smrg then 2733294c433Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 2743294c433Smrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 2753294c433Smrg { 2763294c433Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 2773294c433Smrg (exit 1); exit 2783294c433Smrg } 2793294c433Smrg else 2803294c433Smrg : 2813294c433Smrg fi 2823294c433Smrg} && 2833294c433Smrg 2843294c433Smrg# Now rename the file to the real destination. 2853294c433Smrg 2863294c433Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 2873294c433Smrg 2883294c433Smrgfi && 2893294c433Smrg 2903294c433Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 2913294c433Smrg 2923294c433Smrg{ 2933294c433Smrg (exit 0); exit 2943294c433Smrg} 295