install-sh revision 4fb28925
14fb28925Smrg#!/bin/sh 24fb28925Smrg# 34fb28925Smrg# install - install a program, script, or datafile 44fb28925Smrg# 54fb28925Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 64fb28925Smrg# later released in X11R6 (xc/config/util/install.sh) with the 74fb28925Smrg# following copyright and license. 84fb28925Smrg# 94fb28925Smrg# Copyright (C) 1994 X Consortium 104fb28925Smrg# 114fb28925Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 124fb28925Smrg# of this software and associated documentation files (the "Software"), to 134fb28925Smrg# deal in the Software without restriction, including without limitation the 144fb28925Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 154fb28925Smrg# sell copies of the Software, and to permit persons to whom the Software is 164fb28925Smrg# furnished to do so, subject to the following conditions: 174fb28925Smrg# 184fb28925Smrg# The above copyright notice and this permission notice shall be included in 194fb28925Smrg# all copies or substantial portions of the Software. 204fb28925Smrg# 214fb28925Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 224fb28925Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 234fb28925Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 244fb28925Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 254fb28925Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 264fb28925Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 274fb28925Smrg# 284fb28925Smrg# Except as contained in this notice, the name of the X Consortium shall not 294fb28925Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 304fb28925Smrg# ings in this Software without prior written authorization from the X Consor- 314fb28925Smrg# tium. 324fb28925Smrg# 334fb28925Smrg# 344fb28925Smrg# FSF changes to this file are in the public domain. 354fb28925Smrg# 364fb28925Smrg# Calling this script install-sh is preferred over install.sh, to prevent 374fb28925Smrg# `make' implicit rules from creating a file called install from it 384fb28925Smrg# when there is no Makefile. 394fb28925Smrg# 404fb28925Smrg# This script is compatible with the BSD install script, but was written 414fb28925Smrg# from scratch. It can only install one file at a time, a restriction 424fb28925Smrg# shared with many OS's install programs. 434fb28925Smrg 444fb28925Smrg 454fb28925Smrg# set DOITPROG to echo to test this script 464fb28925Smrg 474fb28925Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 484fb28925Smrgdoit="${DOITPROG-}" 494fb28925Smrg 504fb28925Smrg 514fb28925Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 524fb28925Smrg 534fb28925Smrgmvprog="${MVPROG-mv}" 544fb28925Smrgcpprog="${CPPROG-cp}" 554fb28925Smrgchmodprog="${CHMODPROG-chmod}" 564fb28925Smrgchownprog="${CHOWNPROG-chown}" 574fb28925Smrgchgrpprog="${CHGRPPROG-chgrp}" 584fb28925Smrgstripprog="${STRIPPROG-strip}" 594fb28925Smrgrmprog="${RMPROG-rm}" 604fb28925Smrgmkdirprog="${MKDIRPROG-mkdir}" 614fb28925Smrg 624fb28925Smrgtransformbasename="" 634fb28925Smrgtransform_arg="" 644fb28925Smrginstcmd="$mvprog" 654fb28925Smrgchmodcmd="$chmodprog 0755" 664fb28925Smrgchowncmd="" 674fb28925Smrgchgrpcmd="" 684fb28925Smrgstripcmd="" 694fb28925Smrgrmcmd="$rmprog -f" 704fb28925Smrgmvcmd="$mvprog" 714fb28925Smrgsrc="" 724fb28925Smrgdst="" 734fb28925Smrgdir_arg="" 744fb28925Smrg 754fb28925Smrgwhile [ x"$1" != x ]; do 764fb28925Smrg case $1 in 774fb28925Smrg -c) instcmd=$cpprog 784fb28925Smrg shift 794fb28925Smrg continue;; 804fb28925Smrg 814fb28925Smrg -d) dir_arg=true 824fb28925Smrg shift 834fb28925Smrg continue;; 844fb28925Smrg 854fb28925Smrg -m) chmodcmd="$chmodprog $2" 864fb28925Smrg shift 874fb28925Smrg shift 884fb28925Smrg continue;; 894fb28925Smrg 904fb28925Smrg -o) chowncmd="$chownprog $2" 914fb28925Smrg shift 924fb28925Smrg shift 934fb28925Smrg continue;; 944fb28925Smrg 954fb28925Smrg -g) chgrpcmd="$chgrpprog $2" 964fb28925Smrg shift 974fb28925Smrg shift 984fb28925Smrg continue;; 994fb28925Smrg 1004fb28925Smrg -s) stripcmd=$stripprog 1014fb28925Smrg shift 1024fb28925Smrg continue;; 1034fb28925Smrg 1044fb28925Smrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 1054fb28925Smrg shift 1064fb28925Smrg continue;; 1074fb28925Smrg 1084fb28925Smrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 1094fb28925Smrg shift 1104fb28925Smrg continue;; 1114fb28925Smrg 1124fb28925Smrg *) if [ x"$src" = x ] 1134fb28925Smrg then 1144fb28925Smrg src=$1 1154fb28925Smrg else 1164fb28925Smrg # this colon is to work around a 386BSD /bin/sh bug 1174fb28925Smrg : 1184fb28925Smrg dst=$1 1194fb28925Smrg fi 1204fb28925Smrg shift 1214fb28925Smrg continue;; 1224fb28925Smrg esac 1234fb28925Smrgdone 1244fb28925Smrg 1254fb28925Smrgif [ x"$src" = x ] 1264fb28925Smrgthen 1274fb28925Smrg echo "$0: no input file specified" >&2 1284fb28925Smrg exit 1 1294fb28925Smrgelse 1304fb28925Smrg : 1314fb28925Smrgfi 1324fb28925Smrg 1334fb28925Smrgif [ x"$dir_arg" != x ]; then 1344fb28925Smrg dst=$src 1354fb28925Smrg src="" 1364fb28925Smrg 1374fb28925Smrg if [ -d "$dst" ]; then 1384fb28925Smrg instcmd=: 1394fb28925Smrg chmodcmd="" 1404fb28925Smrg else 1414fb28925Smrg instcmd=$mkdirprog 1424fb28925Smrg fi 1434fb28925Smrgelse 1444fb28925Smrg 1454fb28925Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 1464fb28925Smrg# might cause directories to be created, which would be especially bad 1474fb28925Smrg# if $src (and thus $dsttmp) contains '*'. 1484fb28925Smrg 1494fb28925Smrg if [ -f "$src" ] || [ -d "$src" ] 1504fb28925Smrg then 1514fb28925Smrg : 1524fb28925Smrg else 1534fb28925Smrg echo "$0: $src does not exist" >&2 1544fb28925Smrg exit 1 1554fb28925Smrg fi 1564fb28925Smrg 1574fb28925Smrg if [ x"$dst" = x ] 1584fb28925Smrg then 1594fb28925Smrg echo "$0: no destination specified" >&2 1604fb28925Smrg exit 1 1614fb28925Smrg else 1624fb28925Smrg : 1634fb28925Smrg fi 1644fb28925Smrg 1654fb28925Smrg# If destination is a directory, append the input filename; if your system 1664fb28925Smrg# does not like double slashes in filenames, you may need to add some logic 1674fb28925Smrg 1684fb28925Smrg if [ -d "$dst" ] 1694fb28925Smrg then 1704fb28925Smrg dst=$dst/`basename "$src"` 1714fb28925Smrg else 1724fb28925Smrg : 1734fb28925Smrg fi 1744fb28925Smrgfi 1754fb28925Smrg 1764fb28925Smrg## this sed command emulates the dirname command 1774fb28925Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 1784fb28925Smrg 1794fb28925Smrg# Make sure that the destination directory exists. 1804fb28925Smrg# this part is taken from Noah Friedman's mkinstalldirs script 1814fb28925Smrg 1824fb28925Smrg# Skip lots of stat calls in the usual case. 1834fb28925Smrgif [ ! -d "$dstdir" ]; then 1844fb28925SmrgdefaultIFS=' 1854fb28925Smrg ' 1864fb28925SmrgIFS="${IFS-$defaultIFS}" 1874fb28925Smrg 1884fb28925SmrgoIFS=$IFS 1894fb28925Smrg# Some sh's can't handle IFS=/ for some reason. 1904fb28925SmrgIFS='%' 1914fb28925Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 1924fb28925SmrgIFS=$oIFS 1934fb28925Smrg 1944fb28925Smrgpathcomp='' 1954fb28925Smrg 1964fb28925Smrgwhile [ $# -ne 0 ] ; do 1974fb28925Smrg pathcomp=$pathcomp$1 1984fb28925Smrg shift 1994fb28925Smrg 2004fb28925Smrg if [ ! -d "$pathcomp" ] ; 2014fb28925Smrg then 2024fb28925Smrg $mkdirprog "$pathcomp" 2034fb28925Smrg else 2044fb28925Smrg : 2054fb28925Smrg fi 2064fb28925Smrg 2074fb28925Smrg pathcomp=$pathcomp/ 2084fb28925Smrgdone 2094fb28925Smrgfi 2104fb28925Smrg 2114fb28925Smrgif [ x"$dir_arg" != x ] 2124fb28925Smrgthen 2134fb28925Smrg $doit $instcmd "$dst" && 2144fb28925Smrg 2154fb28925Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 2164fb28925Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 2174fb28925Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 2184fb28925Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 2194fb28925Smrgelse 2204fb28925Smrg 2214fb28925Smrg# If we're going to rename the final executable, determine the name now. 2224fb28925Smrg 2234fb28925Smrg if [ x"$transformarg" = x ] 2244fb28925Smrg then 2254fb28925Smrg dstfile=`basename "$dst"` 2264fb28925Smrg else 2274fb28925Smrg dstfile=`basename "$dst" $transformbasename | 2284fb28925Smrg sed $transformarg`$transformbasename 2294fb28925Smrg fi 2304fb28925Smrg 2314fb28925Smrg# don't allow the sed command to completely eliminate the filename 2324fb28925Smrg 2334fb28925Smrg if [ x"$dstfile" = x ] 2344fb28925Smrg then 2354fb28925Smrg dstfile=`basename "$dst"` 2364fb28925Smrg else 2374fb28925Smrg : 2384fb28925Smrg fi 2394fb28925Smrg 2404fb28925Smrg# Make a couple of temp file names in the proper directory. 2414fb28925Smrg 2424fb28925Smrg dsttmp=$dstdir/_inst.$$_ 2434fb28925Smrg rmtmp=$dstdir/_rm.$$_ 2444fb28925Smrg 2454fb28925Smrg# Trap to clean up temp files at exit. 2464fb28925Smrg 2474fb28925Smrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 2484fb28925Smrg trap '(exit $?); exit' 1 2 13 15 2494fb28925Smrg 2504fb28925Smrg# Move or copy the file name to the temp name 2514fb28925Smrg 2524fb28925Smrg $doit $instcmd "$src" "$dsttmp" && 2534fb28925Smrg 2544fb28925Smrg# and set any options; do chmod last to preserve setuid bits 2554fb28925Smrg 2564fb28925Smrg# If any of these fail, we abort the whole thing. If we want to 2574fb28925Smrg# ignore errors from any of these, just make sure not to ignore 2584fb28925Smrg# errors from the above "$doit $instcmd $src $dsttmp" command. 2594fb28925Smrg 2604fb28925Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 2614fb28925Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 2624fb28925Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 2634fb28925Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 2644fb28925Smrg 2654fb28925Smrg# Now remove or move aside any old file at destination location. We try this 2664fb28925Smrg# two ways since rm can't unlink itself on some systems and the destination 2674fb28925Smrg# file might be busy for other reasons. In this case, the final cleanup 2684fb28925Smrg# might fail but the new file should still install successfully. 2694fb28925Smrg 2704fb28925Smrg{ 2714fb28925Smrg if [ -f "$dstdir/$dstfile" ] 2724fb28925Smrg then 2734fb28925Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 2744fb28925Smrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 2754fb28925Smrg { 2764fb28925Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 2774fb28925Smrg (exit 1); exit 2784fb28925Smrg } 2794fb28925Smrg else 2804fb28925Smrg : 2814fb28925Smrg fi 2824fb28925Smrg} && 2834fb28925Smrg 2844fb28925Smrg# Now rename the file to the real destination. 2854fb28925Smrg 2864fb28925Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 2874fb28925Smrg 2884fb28925Smrgfi && 2894fb28925Smrg 2904fb28925Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 2914fb28925Smrg 2924fb28925Smrg{ 2934fb28925Smrg (exit 0); exit 2944fb28925Smrg} 295