install-sh revision 6ea72052
16ea72052Smrg#!/bin/sh 26ea72052Smrg# 36ea72052Smrg# install - install a program, script, or datafile 46ea72052Smrg# 56ea72052Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 66ea72052Smrg# later released in X11R6 (xc/config/util/install.sh) with the 76ea72052Smrg# following copyright and license. 86ea72052Smrg# 96ea72052Smrg# Copyright (C) 1994 X Consortium 106ea72052Smrg# 116ea72052Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 126ea72052Smrg# of this software and associated documentation files (the "Software"), to 136ea72052Smrg# deal in the Software without restriction, including without limitation the 146ea72052Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 156ea72052Smrg# sell copies of the Software, and to permit persons to whom the Software is 166ea72052Smrg# furnished to do so, subject to the following conditions: 176ea72052Smrg# 186ea72052Smrg# The above copyright notice and this permission notice shall be included in 196ea72052Smrg# all copies or substantial portions of the Software. 206ea72052Smrg# 216ea72052Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 226ea72052Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 236ea72052Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 246ea72052Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 256ea72052Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 266ea72052Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 276ea72052Smrg# 286ea72052Smrg# Except as contained in this notice, the name of the X Consortium shall not 296ea72052Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 306ea72052Smrg# ings in this Software without prior written authorization from the X Consor- 316ea72052Smrg# tium. 326ea72052Smrg# 336ea72052Smrg# 346ea72052Smrg# FSF changes to this file are in the public domain. 356ea72052Smrg# 366ea72052Smrg# Calling this script install-sh is preferred over install.sh, to prevent 376ea72052Smrg# `make' implicit rules from creating a file called install from it 386ea72052Smrg# when there is no Makefile. 396ea72052Smrg# 406ea72052Smrg# This script is compatible with the BSD install script, but was written 416ea72052Smrg# from scratch. It can only install one file at a time, a restriction 426ea72052Smrg# shared with many OS's install programs. 436ea72052Smrg 446ea72052Smrg 456ea72052Smrg# set DOITPROG to echo to test this script 466ea72052Smrg 476ea72052Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 486ea72052Smrgdoit="${DOITPROG-}" 496ea72052Smrg 506ea72052Smrg 516ea72052Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 526ea72052Smrg 536ea72052Smrgmvprog="${MVPROG-mv}" 546ea72052Smrgcpprog="${CPPROG-cp}" 556ea72052Smrgchmodprog="${CHMODPROG-chmod}" 566ea72052Smrgchownprog="${CHOWNPROG-chown}" 576ea72052Smrgchgrpprog="${CHGRPPROG-chgrp}" 586ea72052Smrgstripprog="${STRIPPROG-strip}" 596ea72052Smrgrmprog="${RMPROG-rm}" 606ea72052Smrgmkdirprog="${MKDIRPROG-mkdir}" 616ea72052Smrg 626ea72052Smrgtransformbasename="" 636ea72052Smrgtransform_arg="" 646ea72052Smrginstcmd="$mvprog" 656ea72052Smrgchmodcmd="$chmodprog 0755" 666ea72052Smrgchowncmd="" 676ea72052Smrgchgrpcmd="" 686ea72052Smrgstripcmd="" 696ea72052Smrgrmcmd="$rmprog -f" 706ea72052Smrgmvcmd="$mvprog" 716ea72052Smrgsrc="" 726ea72052Smrgdst="" 736ea72052Smrgdir_arg="" 746ea72052Smrg 756ea72052Smrgwhile [ x"$1" != x ]; do 766ea72052Smrg case $1 in 776ea72052Smrg -c) instcmd=$cpprog 786ea72052Smrg shift 796ea72052Smrg continue;; 806ea72052Smrg 816ea72052Smrg -d) dir_arg=true 826ea72052Smrg shift 836ea72052Smrg continue;; 846ea72052Smrg 856ea72052Smrg -m) chmodcmd="$chmodprog $2" 866ea72052Smrg shift 876ea72052Smrg shift 886ea72052Smrg continue;; 896ea72052Smrg 906ea72052Smrg -o) chowncmd="$chownprog $2" 916ea72052Smrg shift 926ea72052Smrg shift 936ea72052Smrg continue;; 946ea72052Smrg 956ea72052Smrg -g) chgrpcmd="$chgrpprog $2" 966ea72052Smrg shift 976ea72052Smrg shift 986ea72052Smrg continue;; 996ea72052Smrg 1006ea72052Smrg -s) stripcmd=$stripprog 1016ea72052Smrg shift 1026ea72052Smrg continue;; 1036ea72052Smrg 1046ea72052Smrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 1056ea72052Smrg shift 1066ea72052Smrg continue;; 1076ea72052Smrg 1086ea72052Smrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 1096ea72052Smrg shift 1106ea72052Smrg continue;; 1116ea72052Smrg 1126ea72052Smrg *) if [ x"$src" = x ] 1136ea72052Smrg then 1146ea72052Smrg src=$1 1156ea72052Smrg else 1166ea72052Smrg # this colon is to work around a 386BSD /bin/sh bug 1176ea72052Smrg : 1186ea72052Smrg dst=$1 1196ea72052Smrg fi 1206ea72052Smrg shift 1216ea72052Smrg continue;; 1226ea72052Smrg esac 1236ea72052Smrgdone 1246ea72052Smrg 1256ea72052Smrgif [ x"$src" = x ] 1266ea72052Smrgthen 1276ea72052Smrg echo "$0: no input file specified" >&2 1286ea72052Smrg exit 1 1296ea72052Smrgelse 1306ea72052Smrg : 1316ea72052Smrgfi 1326ea72052Smrg 1336ea72052Smrgif [ x"$dir_arg" != x ]; then 1346ea72052Smrg dst=$src 1356ea72052Smrg src="" 1366ea72052Smrg 1376ea72052Smrg if [ -d "$dst" ]; then 1386ea72052Smrg instcmd=: 1396ea72052Smrg chmodcmd="" 1406ea72052Smrg else 1416ea72052Smrg instcmd=$mkdirprog 1426ea72052Smrg fi 1436ea72052Smrgelse 1446ea72052Smrg 1456ea72052Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 1466ea72052Smrg# might cause directories to be created, which would be especially bad 1476ea72052Smrg# if $src (and thus $dsttmp) contains '*'. 1486ea72052Smrg 1496ea72052Smrg if [ -f "$src" ] || [ -d "$src" ] 1506ea72052Smrg then 1516ea72052Smrg : 1526ea72052Smrg else 1536ea72052Smrg echo "$0: $src does not exist" >&2 1546ea72052Smrg exit 1 1556ea72052Smrg fi 1566ea72052Smrg 1576ea72052Smrg if [ x"$dst" = x ] 1586ea72052Smrg then 1596ea72052Smrg echo "$0: no destination specified" >&2 1606ea72052Smrg exit 1 1616ea72052Smrg else 1626ea72052Smrg : 1636ea72052Smrg fi 1646ea72052Smrg 1656ea72052Smrg# If destination is a directory, append the input filename; if your system 1666ea72052Smrg# does not like double slashes in filenames, you may need to add some logic 1676ea72052Smrg 1686ea72052Smrg if [ -d "$dst" ] 1696ea72052Smrg then 1706ea72052Smrg dst=$dst/`basename "$src"` 1716ea72052Smrg else 1726ea72052Smrg : 1736ea72052Smrg fi 1746ea72052Smrgfi 1756ea72052Smrg 1766ea72052Smrg## this sed command emulates the dirname command 1776ea72052Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 1786ea72052Smrg 1796ea72052Smrg# Make sure that the destination directory exists. 1806ea72052Smrg# this part is taken from Noah Friedman's mkinstalldirs script 1816ea72052Smrg 1826ea72052Smrg# Skip lots of stat calls in the usual case. 1836ea72052Smrgif [ ! -d "$dstdir" ]; then 1846ea72052SmrgdefaultIFS=' 1856ea72052Smrg ' 1866ea72052SmrgIFS="${IFS-$defaultIFS}" 1876ea72052Smrg 1886ea72052SmrgoIFS=$IFS 1896ea72052Smrg# Some sh's can't handle IFS=/ for some reason. 1906ea72052SmrgIFS='%' 1916ea72052Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 1926ea72052SmrgIFS=$oIFS 1936ea72052Smrg 1946ea72052Smrgpathcomp='' 1956ea72052Smrg 1966ea72052Smrgwhile [ $# -ne 0 ] ; do 1976ea72052Smrg pathcomp=$pathcomp$1 1986ea72052Smrg shift 1996ea72052Smrg 2006ea72052Smrg if [ ! -d "$pathcomp" ] ; 2016ea72052Smrg then 2026ea72052Smrg $mkdirprog "$pathcomp" 2036ea72052Smrg else 2046ea72052Smrg : 2056ea72052Smrg fi 2066ea72052Smrg 2076ea72052Smrg pathcomp=$pathcomp/ 2086ea72052Smrgdone 2096ea72052Smrgfi 2106ea72052Smrg 2116ea72052Smrgif [ x"$dir_arg" != x ] 2126ea72052Smrgthen 2136ea72052Smrg $doit $instcmd "$dst" && 2146ea72052Smrg 2156ea72052Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 2166ea72052Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 2176ea72052Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 2186ea72052Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 2196ea72052Smrgelse 2206ea72052Smrg 2216ea72052Smrg# If we're going to rename the final executable, determine the name now. 2226ea72052Smrg 2236ea72052Smrg if [ x"$transformarg" = x ] 2246ea72052Smrg then 2256ea72052Smrg dstfile=`basename "$dst"` 2266ea72052Smrg else 2276ea72052Smrg dstfile=`basename "$dst" $transformbasename | 2286ea72052Smrg sed $transformarg`$transformbasename 2296ea72052Smrg fi 2306ea72052Smrg 2316ea72052Smrg# don't allow the sed command to completely eliminate the filename 2326ea72052Smrg 2336ea72052Smrg if [ x"$dstfile" = x ] 2346ea72052Smrg then 2356ea72052Smrg dstfile=`basename "$dst"` 2366ea72052Smrg else 2376ea72052Smrg : 2386ea72052Smrg fi 2396ea72052Smrg 2406ea72052Smrg# Make a couple of temp file names in the proper directory. 2416ea72052Smrg 2426ea72052Smrg dsttmp=$dstdir/_inst.$$_ 2436ea72052Smrg rmtmp=$dstdir/_rm.$$_ 2446ea72052Smrg 2456ea72052Smrg# Trap to clean up temp files at exit. 2466ea72052Smrg 2476ea72052Smrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 2486ea72052Smrg trap '(exit $?); exit' 1 2 13 15 2496ea72052Smrg 2506ea72052Smrg# Move or copy the file name to the temp name 2516ea72052Smrg 2526ea72052Smrg $doit $instcmd "$src" "$dsttmp" && 2536ea72052Smrg 2546ea72052Smrg# and set any options; do chmod last to preserve setuid bits 2556ea72052Smrg 2566ea72052Smrg# If any of these fail, we abort the whole thing. If we want to 2576ea72052Smrg# ignore errors from any of these, just make sure not to ignore 2586ea72052Smrg# errors from the above "$doit $instcmd $src $dsttmp" command. 2596ea72052Smrg 2606ea72052Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 2616ea72052Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 2626ea72052Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 2636ea72052Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 2646ea72052Smrg 2656ea72052Smrg# Now remove or move aside any old file at destination location. We try this 2666ea72052Smrg# two ways since rm can't unlink itself on some systems and the destination 2676ea72052Smrg# file might be busy for other reasons. In this case, the final cleanup 2686ea72052Smrg# might fail but the new file should still install successfully. 2696ea72052Smrg 2706ea72052Smrg{ 2716ea72052Smrg if [ -f "$dstdir/$dstfile" ] 2726ea72052Smrg then 2736ea72052Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 2746ea72052Smrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 2756ea72052Smrg { 2766ea72052Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 2776ea72052Smrg (exit 1); exit 2786ea72052Smrg } 2796ea72052Smrg else 2806ea72052Smrg : 2816ea72052Smrg fi 2826ea72052Smrg} && 2836ea72052Smrg 2846ea72052Smrg# Now rename the file to the real destination. 2856ea72052Smrg 2866ea72052Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 2876ea72052Smrg 2886ea72052Smrgfi && 2896ea72052Smrg 2906ea72052Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 2916ea72052Smrg 2926ea72052Smrg{ 2936ea72052Smrg (exit 0); exit 2946ea72052Smrg} 295