install-sh revision 08f3b10e
108f3b10eSmrg#!/bin/sh 208f3b10eSmrg# 308f3b10eSmrg# install - install a program, script, or datafile 408f3b10eSmrg# 508f3b10eSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 608f3b10eSmrg# later released in X11R6 (xc/config/util/install.sh) with the 708f3b10eSmrg# following copyright and license. 808f3b10eSmrg# 908f3b10eSmrg# Copyright (C) 1994 X Consortium 1008f3b10eSmrg# 1108f3b10eSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1208f3b10eSmrg# of this software and associated documentation files (the "Software"), to 1308f3b10eSmrg# deal in the Software without restriction, including without limitation the 1408f3b10eSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1508f3b10eSmrg# sell copies of the Software, and to permit persons to whom the Software is 1608f3b10eSmrg# furnished to do so, subject to the following conditions: 1708f3b10eSmrg# 1808f3b10eSmrg# The above copyright notice and this permission notice shall be included in 1908f3b10eSmrg# all copies or substantial portions of the Software. 2008f3b10eSmrg# 2108f3b10eSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2208f3b10eSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2308f3b10eSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2408f3b10eSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2508f3b10eSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2608f3b10eSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2708f3b10eSmrg# 2808f3b10eSmrg# Except as contained in this notice, the name of the X Consortium shall not 2908f3b10eSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 3008f3b10eSmrg# ings in this Software without prior written authorization from the X Consor- 3108f3b10eSmrg# tium. 3208f3b10eSmrg# 3308f3b10eSmrg# 3408f3b10eSmrg# FSF changes to this file are in the public domain. 3508f3b10eSmrg# 3608f3b10eSmrg# Calling this script install-sh is preferred over install.sh, to prevent 3708f3b10eSmrg# `make' implicit rules from creating a file called install from it 3808f3b10eSmrg# when there is no Makefile. 3908f3b10eSmrg# 4008f3b10eSmrg# This script is compatible with the BSD install script, but was written 4108f3b10eSmrg# from scratch. It can only install one file at a time, a restriction 4208f3b10eSmrg# shared with many OS's install programs. 4308f3b10eSmrg 4408f3b10eSmrg 4508f3b10eSmrg# set DOITPROG to echo to test this script 4608f3b10eSmrg 4708f3b10eSmrg# Don't use :- since 4.3BSD and earlier shells don't like it. 4808f3b10eSmrgdoit="${DOITPROG-}" 4908f3b10eSmrg 5008f3b10eSmrg 5108f3b10eSmrg# put in absolute paths if you don't have them in your path; or use env. vars. 5208f3b10eSmrg 5308f3b10eSmrgmvprog="${MVPROG-mv}" 5408f3b10eSmrgcpprog="${CPPROG-cp}" 5508f3b10eSmrgchmodprog="${CHMODPROG-chmod}" 5608f3b10eSmrgchownprog="${CHOWNPROG-chown}" 5708f3b10eSmrgchgrpprog="${CHGRPPROG-chgrp}" 5808f3b10eSmrgstripprog="${STRIPPROG-strip}" 5908f3b10eSmrgrmprog="${RMPROG-rm}" 6008f3b10eSmrgmkdirprog="${MKDIRPROG-mkdir}" 6108f3b10eSmrg 6208f3b10eSmrgtransformbasename="" 6308f3b10eSmrgtransform_arg="" 6408f3b10eSmrginstcmd="$mvprog" 6508f3b10eSmrgchmodcmd="$chmodprog 0755" 6608f3b10eSmrgchowncmd="" 6708f3b10eSmrgchgrpcmd="" 6808f3b10eSmrgstripcmd="" 6908f3b10eSmrgrmcmd="$rmprog -f" 7008f3b10eSmrgmvcmd="$mvprog" 7108f3b10eSmrgsrc="" 7208f3b10eSmrgdst="" 7308f3b10eSmrgdir_arg="" 7408f3b10eSmrg 7508f3b10eSmrgwhile [ x"$1" != x ]; do 7608f3b10eSmrg case $1 in 7708f3b10eSmrg -c) instcmd=$cpprog 7808f3b10eSmrg shift 7908f3b10eSmrg continue;; 8008f3b10eSmrg 8108f3b10eSmrg -d) dir_arg=true 8208f3b10eSmrg shift 8308f3b10eSmrg continue;; 8408f3b10eSmrg 8508f3b10eSmrg -m) chmodcmd="$chmodprog $2" 8608f3b10eSmrg shift 8708f3b10eSmrg shift 8808f3b10eSmrg continue;; 8908f3b10eSmrg 9008f3b10eSmrg -o) chowncmd="$chownprog $2" 9108f3b10eSmrg shift 9208f3b10eSmrg shift 9308f3b10eSmrg continue;; 9408f3b10eSmrg 9508f3b10eSmrg -g) chgrpcmd="$chgrpprog $2" 9608f3b10eSmrg shift 9708f3b10eSmrg shift 9808f3b10eSmrg continue;; 9908f3b10eSmrg 10008f3b10eSmrg -s) stripcmd=$stripprog 10108f3b10eSmrg shift 10208f3b10eSmrg continue;; 10308f3b10eSmrg 10408f3b10eSmrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 10508f3b10eSmrg shift 10608f3b10eSmrg continue;; 10708f3b10eSmrg 10808f3b10eSmrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 10908f3b10eSmrg shift 11008f3b10eSmrg continue;; 11108f3b10eSmrg 11208f3b10eSmrg *) if [ x"$src" = x ] 11308f3b10eSmrg then 11408f3b10eSmrg src=$1 11508f3b10eSmrg else 11608f3b10eSmrg # this colon is to work around a 386BSD /bin/sh bug 11708f3b10eSmrg : 11808f3b10eSmrg dst=$1 11908f3b10eSmrg fi 12008f3b10eSmrg shift 12108f3b10eSmrg continue;; 12208f3b10eSmrg esac 12308f3b10eSmrgdone 12408f3b10eSmrg 12508f3b10eSmrgif [ x"$src" = x ] 12608f3b10eSmrgthen 12708f3b10eSmrg echo "$0: no input file specified" >&2 12808f3b10eSmrg exit 1 12908f3b10eSmrgelse 13008f3b10eSmrg : 13108f3b10eSmrgfi 13208f3b10eSmrg 13308f3b10eSmrgif [ x"$dir_arg" != x ]; then 13408f3b10eSmrg dst=$src 13508f3b10eSmrg src="" 13608f3b10eSmrg 13708f3b10eSmrg if [ -d "$dst" ]; then 13808f3b10eSmrg instcmd=: 13908f3b10eSmrg chmodcmd="" 14008f3b10eSmrg else 14108f3b10eSmrg instcmd=$mkdirprog 14208f3b10eSmrg fi 14308f3b10eSmrgelse 14408f3b10eSmrg 14508f3b10eSmrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 14608f3b10eSmrg# might cause directories to be created, which would be especially bad 14708f3b10eSmrg# if $src (and thus $dsttmp) contains '*'. 14808f3b10eSmrg 14908f3b10eSmrg if [ -f "$src" ] || [ -d "$src" ] 15008f3b10eSmrg then 15108f3b10eSmrg : 15208f3b10eSmrg else 15308f3b10eSmrg echo "$0: $src does not exist" >&2 15408f3b10eSmrg exit 1 15508f3b10eSmrg fi 15608f3b10eSmrg 15708f3b10eSmrg if [ x"$dst" = x ] 15808f3b10eSmrg then 15908f3b10eSmrg echo "$0: no destination specified" >&2 16008f3b10eSmrg exit 1 16108f3b10eSmrg else 16208f3b10eSmrg : 16308f3b10eSmrg fi 16408f3b10eSmrg 16508f3b10eSmrg# If destination is a directory, append the input filename; if your system 16608f3b10eSmrg# does not like double slashes in filenames, you may need to add some logic 16708f3b10eSmrg 16808f3b10eSmrg if [ -d "$dst" ] 16908f3b10eSmrg then 17008f3b10eSmrg dst=$dst/`basename "$src"` 17108f3b10eSmrg else 17208f3b10eSmrg : 17308f3b10eSmrg fi 17408f3b10eSmrgfi 17508f3b10eSmrg 17608f3b10eSmrg## this sed command emulates the dirname command 17708f3b10eSmrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 17808f3b10eSmrg 17908f3b10eSmrg# Make sure that the destination directory exists. 18008f3b10eSmrg# this part is taken from Noah Friedman's mkinstalldirs script 18108f3b10eSmrg 18208f3b10eSmrg# Skip lots of stat calls in the usual case. 18308f3b10eSmrgif [ ! -d "$dstdir" ]; then 18408f3b10eSmrgdefaultIFS=' 18508f3b10eSmrg ' 18608f3b10eSmrgIFS="${IFS-$defaultIFS}" 18708f3b10eSmrg 18808f3b10eSmrgoIFS=$IFS 18908f3b10eSmrg# Some sh's can't handle IFS=/ for some reason. 19008f3b10eSmrgIFS='%' 19108f3b10eSmrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 19208f3b10eSmrgIFS=$oIFS 19308f3b10eSmrg 19408f3b10eSmrgpathcomp='' 19508f3b10eSmrg 19608f3b10eSmrgwhile [ $# -ne 0 ] ; do 19708f3b10eSmrg pathcomp=$pathcomp$1 19808f3b10eSmrg shift 19908f3b10eSmrg 20008f3b10eSmrg if [ ! -d "$pathcomp" ] ; 20108f3b10eSmrg then 20208f3b10eSmrg $mkdirprog "$pathcomp" 20308f3b10eSmrg else 20408f3b10eSmrg : 20508f3b10eSmrg fi 20608f3b10eSmrg 20708f3b10eSmrg pathcomp=$pathcomp/ 20808f3b10eSmrgdone 20908f3b10eSmrgfi 21008f3b10eSmrg 21108f3b10eSmrgif [ x"$dir_arg" != x ] 21208f3b10eSmrgthen 21308f3b10eSmrg $doit $instcmd "$dst" && 21408f3b10eSmrg 21508f3b10eSmrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 21608f3b10eSmrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 21708f3b10eSmrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 21808f3b10eSmrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 21908f3b10eSmrgelse 22008f3b10eSmrg 22108f3b10eSmrg# If we're going to rename the final executable, determine the name now. 22208f3b10eSmrg 22308f3b10eSmrg if [ x"$transformarg" = x ] 22408f3b10eSmrg then 22508f3b10eSmrg dstfile=`basename "$dst"` 22608f3b10eSmrg else 22708f3b10eSmrg dstfile=`basename "$dst" $transformbasename | 22808f3b10eSmrg sed $transformarg`$transformbasename 22908f3b10eSmrg fi 23008f3b10eSmrg 23108f3b10eSmrg# don't allow the sed command to completely eliminate the filename 23208f3b10eSmrg 23308f3b10eSmrg if [ x"$dstfile" = x ] 23408f3b10eSmrg then 23508f3b10eSmrg dstfile=`basename "$dst"` 23608f3b10eSmrg else 23708f3b10eSmrg : 23808f3b10eSmrg fi 23908f3b10eSmrg 24008f3b10eSmrg# Make a couple of temp file names in the proper directory. 24108f3b10eSmrg 24208f3b10eSmrg dsttmp=$dstdir/_inst.$$_ 24308f3b10eSmrg rmtmp=$dstdir/_rm.$$_ 24408f3b10eSmrg 24508f3b10eSmrg# Trap to clean up temp files at exit. 24608f3b10eSmrg 24708f3b10eSmrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 24808f3b10eSmrg trap '(exit $?); exit' 1 2 13 15 24908f3b10eSmrg 25008f3b10eSmrg# Move or copy the file name to the temp name 25108f3b10eSmrg 25208f3b10eSmrg $doit $instcmd "$src" "$dsttmp" && 25308f3b10eSmrg 25408f3b10eSmrg# and set any options; do chmod last to preserve setuid bits 25508f3b10eSmrg 25608f3b10eSmrg# If any of these fail, we abort the whole thing. If we want to 25708f3b10eSmrg# ignore errors from any of these, just make sure not to ignore 25808f3b10eSmrg# errors from the above "$doit $instcmd $src $dsttmp" command. 25908f3b10eSmrg 26008f3b10eSmrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 26108f3b10eSmrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 26208f3b10eSmrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 26308f3b10eSmrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 26408f3b10eSmrg 26508f3b10eSmrg# Now remove or move aside any old file at destination location. We try this 26608f3b10eSmrg# two ways since rm can't unlink itself on some systems and the destination 26708f3b10eSmrg# file might be busy for other reasons. In this case, the final cleanup 26808f3b10eSmrg# might fail but the new file should still install successfully. 26908f3b10eSmrg 27008f3b10eSmrg{ 27108f3b10eSmrg if [ -f "$dstdir/$dstfile" ] 27208f3b10eSmrg then 27308f3b10eSmrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 27408f3b10eSmrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 27508f3b10eSmrg { 27608f3b10eSmrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 27708f3b10eSmrg (exit 1); exit 27808f3b10eSmrg } 27908f3b10eSmrg else 28008f3b10eSmrg : 28108f3b10eSmrg fi 28208f3b10eSmrg} && 28308f3b10eSmrg 28408f3b10eSmrg# Now rename the file to the real destination. 28508f3b10eSmrg 28608f3b10eSmrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 28708f3b10eSmrg 28808f3b10eSmrgfi && 28908f3b10eSmrg 29008f3b10eSmrg# The final little trick to "correctly" pass the exit status to the exit trap. 29108f3b10eSmrg 29208f3b10eSmrg{ 29308f3b10eSmrg (exit 0); exit 29408f3b10eSmrg} 295