install-sh revision 98049353
198049353Smrg#!/bin/sh 298049353Smrg# 398049353Smrg# install - install a program, script, or datafile 498049353Smrg# 598049353Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 698049353Smrg# later released in X11R6 (xc/config/util/install.sh) with the 798049353Smrg# following copyright and license. 898049353Smrg# 998049353Smrg# Copyright (C) 1994 X Consortium 1098049353Smrg# 1198049353Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1298049353Smrg# of this software and associated documentation files (the "Software"), to 1398049353Smrg# deal in the Software without restriction, including without limitation the 1498049353Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1598049353Smrg# sell copies of the Software, and to permit persons to whom the Software is 1698049353Smrg# furnished to do so, subject to the following conditions: 1798049353Smrg# 1898049353Smrg# The above copyright notice and this permission notice shall be included in 1998049353Smrg# all copies or substantial portions of the Software. 2098049353Smrg# 2198049353Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2298049353Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2398049353Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2498049353Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2598049353Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2698049353Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2798049353Smrg# 2898049353Smrg# Except as contained in this notice, the name of the X Consortium shall not 2998049353Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3098049353Smrg# ings in this Software without prior written authorization from the X Consor- 3198049353Smrg# tium. 3298049353Smrg# 3398049353Smrg# 3498049353Smrg# FSF changes to this file are in the public domain. 3598049353Smrg# 3698049353Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3798049353Smrg# `make' implicit rules from creating a file called install from it 3898049353Smrg# when there is no Makefile. 3998049353Smrg# 4098049353Smrg# This script is compatible with the BSD install script, but was written 4198049353Smrg# from scratch. It can only install one file at a time, a restriction 4298049353Smrg# shared with many OS's install programs. 4398049353Smrg 4498049353Smrg 4598049353Smrg# set DOITPROG to echo to test this script 4698049353Smrg 4798049353Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 4898049353Smrgdoit="${DOITPROG-}" 4998049353Smrg 5098049353Smrg 5198049353Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 5298049353Smrg 5398049353Smrgmvprog="${MVPROG-mv}" 5498049353Smrgcpprog="${CPPROG-cp}" 5598049353Smrgchmodprog="${CHMODPROG-chmod}" 5698049353Smrgchownprog="${CHOWNPROG-chown}" 5798049353Smrgchgrpprog="${CHGRPPROG-chgrp}" 5898049353Smrgstripprog="${STRIPPROG-strip}" 5998049353Smrgrmprog="${RMPROG-rm}" 6098049353Smrgmkdirprog="${MKDIRPROG-mkdir}" 6198049353Smrg 6298049353Smrgtransformbasename="" 6398049353Smrgtransform_arg="" 6498049353Smrginstcmd="$mvprog" 6598049353Smrgchmodcmd="$chmodprog 0755" 6698049353Smrgchowncmd="" 6798049353Smrgchgrpcmd="" 6898049353Smrgstripcmd="" 6998049353Smrgrmcmd="$rmprog -f" 7098049353Smrgmvcmd="$mvprog" 7198049353Smrgsrc="" 7298049353Smrgdst="" 7398049353Smrgdir_arg="" 7498049353Smrg 7598049353Smrgwhile [ x"$1" != x ]; do 7698049353Smrg case $1 in 7798049353Smrg -c) instcmd=$cpprog 7898049353Smrg shift 7998049353Smrg continue;; 8098049353Smrg 8198049353Smrg -d) dir_arg=true 8298049353Smrg shift 8398049353Smrg continue;; 8498049353Smrg 8598049353Smrg -m) chmodcmd="$chmodprog $2" 8698049353Smrg shift 8798049353Smrg shift 8898049353Smrg continue;; 8998049353Smrg 9098049353Smrg -o) chowncmd="$chownprog $2" 9198049353Smrg shift 9298049353Smrg shift 9398049353Smrg continue;; 9498049353Smrg 9598049353Smrg -g) chgrpcmd="$chgrpprog $2" 9698049353Smrg shift 9798049353Smrg shift 9898049353Smrg continue;; 9998049353Smrg 10098049353Smrg -s) stripcmd=$stripprog 10198049353Smrg shift 10298049353Smrg continue;; 10398049353Smrg 10498049353Smrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 10598049353Smrg shift 10698049353Smrg continue;; 10798049353Smrg 10898049353Smrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 10998049353Smrg shift 11098049353Smrg continue;; 11198049353Smrg 11298049353Smrg *) if [ x"$src" = x ] 11398049353Smrg then 11498049353Smrg src=$1 11598049353Smrg else 11698049353Smrg # this colon is to work around a 386BSD /bin/sh bug 11798049353Smrg : 11898049353Smrg dst=$1 11998049353Smrg fi 12098049353Smrg shift 12198049353Smrg continue;; 12298049353Smrg esac 12398049353Smrgdone 12498049353Smrg 12598049353Smrgif [ x"$src" = x ] 12698049353Smrgthen 12798049353Smrg echo "$0: no input file specified" >&2 12898049353Smrg exit 1 12998049353Smrgelse 13098049353Smrg : 13198049353Smrgfi 13298049353Smrg 13398049353Smrgif [ x"$dir_arg" != x ]; then 13498049353Smrg dst=$src 13598049353Smrg src="" 13698049353Smrg 13798049353Smrg if [ -d "$dst" ]; then 13898049353Smrg instcmd=: 13998049353Smrg chmodcmd="" 14098049353Smrg else 14198049353Smrg instcmd=$mkdirprog 14298049353Smrg fi 14398049353Smrgelse 14498049353Smrg 14598049353Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 14698049353Smrg# might cause directories to be created, which would be especially bad 14798049353Smrg# if $src (and thus $dsttmp) contains '*'. 14898049353Smrg 14998049353Smrg if [ -f "$src" ] || [ -d "$src" ] 15098049353Smrg then 15198049353Smrg : 15298049353Smrg else 15398049353Smrg echo "$0: $src does not exist" >&2 15498049353Smrg exit 1 15598049353Smrg fi 15698049353Smrg 15798049353Smrg if [ x"$dst" = x ] 15898049353Smrg then 15998049353Smrg echo "$0: no destination specified" >&2 16098049353Smrg exit 1 16198049353Smrg else 16298049353Smrg : 16398049353Smrg fi 16498049353Smrg 16598049353Smrg# If destination is a directory, append the input filename; if your system 16698049353Smrg# does not like double slashes in filenames, you may need to add some logic 16798049353Smrg 16898049353Smrg if [ -d "$dst" ] 16998049353Smrg then 17098049353Smrg dst=$dst/`basename "$src"` 17198049353Smrg else 17298049353Smrg : 17398049353Smrg fi 17498049353Smrgfi 17598049353Smrg 17698049353Smrg## this sed command emulates the dirname command 17798049353Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 17898049353Smrg 17998049353Smrg# Make sure that the destination directory exists. 18098049353Smrg# this part is taken from Noah Friedman's mkinstalldirs script 18198049353Smrg 18298049353Smrg# Skip lots of stat calls in the usual case. 18398049353Smrgif [ ! -d "$dstdir" ]; then 18498049353SmrgdefaultIFS=' 18598049353Smrg ' 18698049353SmrgIFS="${IFS-$defaultIFS}" 18798049353Smrg 18898049353SmrgoIFS=$IFS 18998049353Smrg# Some sh's can't handle IFS=/ for some reason. 19098049353SmrgIFS='%' 19198049353Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 19298049353SmrgIFS=$oIFS 19398049353Smrg 19498049353Smrgpathcomp='' 19598049353Smrg 19698049353Smrgwhile [ $# -ne 0 ] ; do 19798049353Smrg pathcomp=$pathcomp$1 19898049353Smrg shift 19998049353Smrg 20098049353Smrg if [ ! -d "$pathcomp" ] ; 20198049353Smrg then 20298049353Smrg $mkdirprog "$pathcomp" 20398049353Smrg else 20498049353Smrg : 20598049353Smrg fi 20698049353Smrg 20798049353Smrg pathcomp=$pathcomp/ 20898049353Smrgdone 20998049353Smrgfi 21098049353Smrg 21198049353Smrgif [ x"$dir_arg" != x ] 21298049353Smrgthen 21398049353Smrg $doit $instcmd "$dst" && 21498049353Smrg 21598049353Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 21698049353Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 21798049353Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 21898049353Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 21998049353Smrgelse 22098049353Smrg 22198049353Smrg# If we're going to rename the final executable, determine the name now. 22298049353Smrg 22398049353Smrg if [ x"$transformarg" = x ] 22498049353Smrg then 22598049353Smrg dstfile=`basename "$dst"` 22698049353Smrg else 22798049353Smrg dstfile=`basename "$dst" $transformbasename | 22898049353Smrg sed $transformarg`$transformbasename 22998049353Smrg fi 23098049353Smrg 23198049353Smrg# don't allow the sed command to completely eliminate the filename 23298049353Smrg 23398049353Smrg if [ x"$dstfile" = x ] 23498049353Smrg then 23598049353Smrg dstfile=`basename "$dst"` 23698049353Smrg else 23798049353Smrg : 23898049353Smrg fi 23998049353Smrg 24098049353Smrg# Make a couple of temp file names in the proper directory. 24198049353Smrg 24298049353Smrg dsttmp=$dstdir/_inst.$$_ 24398049353Smrg rmtmp=$dstdir/_rm.$$_ 24498049353Smrg 24598049353Smrg# Trap to clean up temp files at exit. 24698049353Smrg 24798049353Smrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 24898049353Smrg trap '(exit $?); exit' 1 2 13 15 24998049353Smrg 25098049353Smrg# Move or copy the file name to the temp name 25198049353Smrg 25298049353Smrg $doit $instcmd "$src" "$dsttmp" && 25398049353Smrg 25498049353Smrg# and set any options; do chmod last to preserve setuid bits 25598049353Smrg 25698049353Smrg# If any of these fail, we abort the whole thing. If we want to 25798049353Smrg# ignore errors from any of these, just make sure not to ignore 25898049353Smrg# errors from the above "$doit $instcmd $src $dsttmp" command. 25998049353Smrg 26098049353Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 26198049353Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 26298049353Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 26398049353Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 26498049353Smrg 26598049353Smrg# Now remove or move aside any old file at destination location. We try this 26698049353Smrg# two ways since rm can't unlink itself on some systems and the destination 26798049353Smrg# file might be busy for other reasons. In this case, the final cleanup 26898049353Smrg# might fail but the new file should still install successfully. 26998049353Smrg 27098049353Smrg{ 27198049353Smrg if [ -f "$dstdir/$dstfile" ] 27298049353Smrg then 27398049353Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 27498049353Smrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 27598049353Smrg { 27698049353Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 27798049353Smrg (exit 1); exit 27898049353Smrg } 27998049353Smrg else 28098049353Smrg : 28198049353Smrg fi 28298049353Smrg} && 28398049353Smrg 28498049353Smrg# Now rename the file to the real destination. 28598049353Smrg 28698049353Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 28798049353Smrg 28898049353Smrgfi && 28998049353Smrg 29098049353Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 29198049353Smrg 29298049353Smrg{ 29398049353Smrg (exit 0); exit 29498049353Smrg} 295