install-sh revision 97e8a2e8
197e8a2e8Smrg#!/bin/sh 297e8a2e8Smrg# 397e8a2e8Smrg# install - install a program, script, or datafile 497e8a2e8Smrg# 597e8a2e8Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 697e8a2e8Smrg# later released in X11R6 (xc/config/util/install.sh) with the 797e8a2e8Smrg# following copyright and license. 897e8a2e8Smrg# 997e8a2e8Smrg# Copyright (C) 1994 X Consortium 1097e8a2e8Smrg# 1197e8a2e8Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1297e8a2e8Smrg# of this software and associated documentation files (the "Software"), to 1397e8a2e8Smrg# deal in the Software without restriction, including without limitation the 1497e8a2e8Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1597e8a2e8Smrg# sell copies of the Software, and to permit persons to whom the Software is 1697e8a2e8Smrg# furnished to do so, subject to the following conditions: 1797e8a2e8Smrg# 1897e8a2e8Smrg# The above copyright notice and this permission notice shall be included in 1997e8a2e8Smrg# all copies or substantial portions of the Software. 2097e8a2e8Smrg# 2197e8a2e8Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2297e8a2e8Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2397e8a2e8Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2497e8a2e8Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2597e8a2e8Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2697e8a2e8Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2797e8a2e8Smrg# 2897e8a2e8Smrg# Except as contained in this notice, the name of the X Consortium shall not 2997e8a2e8Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3097e8a2e8Smrg# ings in this Software without prior written authorization from the X Consor- 3197e8a2e8Smrg# tium. 3297e8a2e8Smrg# 3397e8a2e8Smrg# 3497e8a2e8Smrg# FSF changes to this file are in the public domain. 3597e8a2e8Smrg# 3697e8a2e8Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3797e8a2e8Smrg# `make' implicit rules from creating a file called install from it 3897e8a2e8Smrg# when there is no Makefile. 3997e8a2e8Smrg# 4097e8a2e8Smrg# This script is compatible with the BSD install script, but was written 4197e8a2e8Smrg# from scratch. It can only install one file at a time, a restriction 4297e8a2e8Smrg# shared with many OS's install programs. 4397e8a2e8Smrg 4497e8a2e8Smrg 4597e8a2e8Smrg# set DOITPROG to echo to test this script 4697e8a2e8Smrg 4797e8a2e8Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 4897e8a2e8Smrgdoit="${DOITPROG-}" 4997e8a2e8Smrg 5097e8a2e8Smrg 5197e8a2e8Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 5297e8a2e8Smrg 5397e8a2e8Smrgmvprog="${MVPROG-mv}" 5497e8a2e8Smrgcpprog="${CPPROG-cp}" 5597e8a2e8Smrgchmodprog="${CHMODPROG-chmod}" 5697e8a2e8Smrgchownprog="${CHOWNPROG-chown}" 5797e8a2e8Smrgchgrpprog="${CHGRPPROG-chgrp}" 5897e8a2e8Smrgstripprog="${STRIPPROG-strip}" 5997e8a2e8Smrgrmprog="${RMPROG-rm}" 6097e8a2e8Smrgmkdirprog="${MKDIRPROG-mkdir}" 6197e8a2e8Smrg 6297e8a2e8Smrgtransformbasename="" 6397e8a2e8Smrgtransform_arg="" 6497e8a2e8Smrginstcmd="$mvprog" 6597e8a2e8Smrgchmodcmd="$chmodprog 0755" 6697e8a2e8Smrgchowncmd="" 6797e8a2e8Smrgchgrpcmd="" 6897e8a2e8Smrgstripcmd="" 6997e8a2e8Smrgrmcmd="$rmprog -f" 7097e8a2e8Smrgmvcmd="$mvprog" 7197e8a2e8Smrgsrc="" 7297e8a2e8Smrgdst="" 7397e8a2e8Smrgdir_arg="" 7497e8a2e8Smrg 7597e8a2e8Smrgwhile [ x"$1" != x ]; do 7697e8a2e8Smrg case $1 in 7797e8a2e8Smrg -c) instcmd=$cpprog 7897e8a2e8Smrg shift 7997e8a2e8Smrg continue;; 8097e8a2e8Smrg 8197e8a2e8Smrg -d) dir_arg=true 8297e8a2e8Smrg shift 8397e8a2e8Smrg continue;; 8497e8a2e8Smrg 8597e8a2e8Smrg -m) chmodcmd="$chmodprog $2" 8697e8a2e8Smrg shift 8797e8a2e8Smrg shift 8897e8a2e8Smrg continue;; 8997e8a2e8Smrg 9097e8a2e8Smrg -o) chowncmd="$chownprog $2" 9197e8a2e8Smrg shift 9297e8a2e8Smrg shift 9397e8a2e8Smrg continue;; 9497e8a2e8Smrg 9597e8a2e8Smrg -g) chgrpcmd="$chgrpprog $2" 9697e8a2e8Smrg shift 9797e8a2e8Smrg shift 9897e8a2e8Smrg continue;; 9997e8a2e8Smrg 10097e8a2e8Smrg -s) stripcmd=$stripprog 10197e8a2e8Smrg shift 10297e8a2e8Smrg continue;; 10397e8a2e8Smrg 10497e8a2e8Smrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 10597e8a2e8Smrg shift 10697e8a2e8Smrg continue;; 10797e8a2e8Smrg 10897e8a2e8Smrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 10997e8a2e8Smrg shift 11097e8a2e8Smrg continue;; 11197e8a2e8Smrg 11297e8a2e8Smrg *) if [ x"$src" = x ] 11397e8a2e8Smrg then 11497e8a2e8Smrg src=$1 11597e8a2e8Smrg else 11697e8a2e8Smrg # this colon is to work around a 386BSD /bin/sh bug 11797e8a2e8Smrg : 11897e8a2e8Smrg dst=$1 11997e8a2e8Smrg fi 12097e8a2e8Smrg shift 12197e8a2e8Smrg continue;; 12297e8a2e8Smrg esac 12397e8a2e8Smrgdone 12497e8a2e8Smrg 12597e8a2e8Smrgif [ x"$src" = x ] 12697e8a2e8Smrgthen 12797e8a2e8Smrg echo "$0: no input file specified" >&2 12897e8a2e8Smrg exit 1 12997e8a2e8Smrgelse 13097e8a2e8Smrg : 13197e8a2e8Smrgfi 13297e8a2e8Smrg 13397e8a2e8Smrgif [ x"$dir_arg" != x ]; then 13497e8a2e8Smrg dst=$src 13597e8a2e8Smrg src="" 13697e8a2e8Smrg 13797e8a2e8Smrg if [ -d "$dst" ]; then 13897e8a2e8Smrg instcmd=: 13997e8a2e8Smrg chmodcmd="" 14097e8a2e8Smrg else 14197e8a2e8Smrg instcmd=$mkdirprog 14297e8a2e8Smrg fi 14397e8a2e8Smrgelse 14497e8a2e8Smrg 14597e8a2e8Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 14697e8a2e8Smrg# might cause directories to be created, which would be especially bad 14797e8a2e8Smrg# if $src (and thus $dsttmp) contains '*'. 14897e8a2e8Smrg 14997e8a2e8Smrg if [ -f "$src" ] || [ -d "$src" ] 15097e8a2e8Smrg then 15197e8a2e8Smrg : 15297e8a2e8Smrg else 15397e8a2e8Smrg echo "$0: $src does not exist" >&2 15497e8a2e8Smrg exit 1 15597e8a2e8Smrg fi 15697e8a2e8Smrg 15797e8a2e8Smrg if [ x"$dst" = x ] 15897e8a2e8Smrg then 15997e8a2e8Smrg echo "$0: no destination specified" >&2 16097e8a2e8Smrg exit 1 16197e8a2e8Smrg else 16297e8a2e8Smrg : 16397e8a2e8Smrg fi 16497e8a2e8Smrg 16597e8a2e8Smrg# If destination is a directory, append the input filename; if your system 16697e8a2e8Smrg# does not like double slashes in filenames, you may need to add some logic 16797e8a2e8Smrg 16897e8a2e8Smrg if [ -d "$dst" ] 16997e8a2e8Smrg then 17097e8a2e8Smrg dst=$dst/`basename "$src"` 17197e8a2e8Smrg else 17297e8a2e8Smrg : 17397e8a2e8Smrg fi 17497e8a2e8Smrgfi 17597e8a2e8Smrg 17697e8a2e8Smrg## this sed command emulates the dirname command 17797e8a2e8Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 17897e8a2e8Smrg 17997e8a2e8Smrg# Make sure that the destination directory exists. 18097e8a2e8Smrg# this part is taken from Noah Friedman's mkinstalldirs script 18197e8a2e8Smrg 18297e8a2e8Smrg# Skip lots of stat calls in the usual case. 18397e8a2e8Smrgif [ ! -d "$dstdir" ]; then 18497e8a2e8SmrgdefaultIFS=' 18597e8a2e8Smrg ' 18697e8a2e8SmrgIFS="${IFS-$defaultIFS}" 18797e8a2e8Smrg 18897e8a2e8SmrgoIFS=$IFS 18997e8a2e8Smrg# Some sh's can't handle IFS=/ for some reason. 19097e8a2e8SmrgIFS='%' 19197e8a2e8Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 19297e8a2e8SmrgIFS=$oIFS 19397e8a2e8Smrg 19497e8a2e8Smrgpathcomp='' 19597e8a2e8Smrg 19697e8a2e8Smrgwhile [ $# -ne 0 ] ; do 19797e8a2e8Smrg pathcomp=$pathcomp$1 19897e8a2e8Smrg shift 19997e8a2e8Smrg 20097e8a2e8Smrg if [ ! -d "$pathcomp" ] ; 20197e8a2e8Smrg then 20297e8a2e8Smrg $mkdirprog "$pathcomp" 20397e8a2e8Smrg else 20497e8a2e8Smrg : 20597e8a2e8Smrg fi 20697e8a2e8Smrg 20797e8a2e8Smrg pathcomp=$pathcomp/ 20897e8a2e8Smrgdone 20997e8a2e8Smrgfi 21097e8a2e8Smrg 21197e8a2e8Smrgif [ x"$dir_arg" != x ] 21297e8a2e8Smrgthen 21397e8a2e8Smrg $doit $instcmd "$dst" && 21497e8a2e8Smrg 21597e8a2e8Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 21697e8a2e8Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 21797e8a2e8Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 21897e8a2e8Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 21997e8a2e8Smrgelse 22097e8a2e8Smrg 22197e8a2e8Smrg# If we're going to rename the final executable, determine the name now. 22297e8a2e8Smrg 22397e8a2e8Smrg if [ x"$transformarg" = x ] 22497e8a2e8Smrg then 22597e8a2e8Smrg dstfile=`basename "$dst"` 22697e8a2e8Smrg else 22797e8a2e8Smrg dstfile=`basename "$dst" $transformbasename | 22897e8a2e8Smrg sed $transformarg`$transformbasename 22997e8a2e8Smrg fi 23097e8a2e8Smrg 23197e8a2e8Smrg# don't allow the sed command to completely eliminate the filename 23297e8a2e8Smrg 23397e8a2e8Smrg if [ x"$dstfile" = x ] 23497e8a2e8Smrg then 23597e8a2e8Smrg dstfile=`basename "$dst"` 23697e8a2e8Smrg else 23797e8a2e8Smrg : 23897e8a2e8Smrg fi 23997e8a2e8Smrg 24097e8a2e8Smrg# Make a couple of temp file names in the proper directory. 24197e8a2e8Smrg 24297e8a2e8Smrg dsttmp=$dstdir/_inst.$$_ 24397e8a2e8Smrg rmtmp=$dstdir/_rm.$$_ 24497e8a2e8Smrg 24597e8a2e8Smrg# Trap to clean up temp files at exit. 24697e8a2e8Smrg 24797e8a2e8Smrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 24897e8a2e8Smrg trap '(exit $?); exit' 1 2 13 15 24997e8a2e8Smrg 25097e8a2e8Smrg# Move or copy the file name to the temp name 25197e8a2e8Smrg 25297e8a2e8Smrg $doit $instcmd "$src" "$dsttmp" && 25397e8a2e8Smrg 25497e8a2e8Smrg# and set any options; do chmod last to preserve setuid bits 25597e8a2e8Smrg 25697e8a2e8Smrg# If any of these fail, we abort the whole thing. If we want to 25797e8a2e8Smrg# ignore errors from any of these, just make sure not to ignore 25897e8a2e8Smrg# errors from the above "$doit $instcmd $src $dsttmp" command. 25997e8a2e8Smrg 26097e8a2e8Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 26197e8a2e8Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 26297e8a2e8Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 26397e8a2e8Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 26497e8a2e8Smrg 26597e8a2e8Smrg# Now remove or move aside any old file at destination location. We try this 26697e8a2e8Smrg# two ways since rm can't unlink itself on some systems and the destination 26797e8a2e8Smrg# file might be busy for other reasons. In this case, the final cleanup 26897e8a2e8Smrg# might fail but the new file should still install successfully. 26997e8a2e8Smrg 27097e8a2e8Smrg{ 27197e8a2e8Smrg if [ -f "$dstdir/$dstfile" ] 27297e8a2e8Smrg then 27397e8a2e8Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 27497e8a2e8Smrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 27597e8a2e8Smrg { 27697e8a2e8Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 27797e8a2e8Smrg (exit 1); exit 27897e8a2e8Smrg } 27997e8a2e8Smrg else 28097e8a2e8Smrg : 28197e8a2e8Smrg fi 28297e8a2e8Smrg} && 28397e8a2e8Smrg 28497e8a2e8Smrg# Now rename the file to the real destination. 28597e8a2e8Smrg 28697e8a2e8Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 28797e8a2e8Smrg 28897e8a2e8Smrgfi && 28997e8a2e8Smrg 29097e8a2e8Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 29197e8a2e8Smrg 29297e8a2e8Smrg{ 29397e8a2e8Smrg (exit 0); exit 29497e8a2e8Smrg} 295