install-sh revision 56f6b22b
156f6b22bSmrg#!/bin/sh 256f6b22bSmrg# 356f6b22bSmrg# install - install a program, script, or datafile 456f6b22bSmrg# 556f6b22bSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 656f6b22bSmrg# later released in X11R6 (xc/config/util/install.sh) with the 756f6b22bSmrg# following copyright and license. 856f6b22bSmrg# 956f6b22bSmrg# Copyright (C) 1994 X Consortium 1056f6b22bSmrg# 1156f6b22bSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1256f6b22bSmrg# of this software and associated documentation files (the "Software"), to 1356f6b22bSmrg# deal in the Software without restriction, including without limitation the 1456f6b22bSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1556f6b22bSmrg# sell copies of the Software, and to permit persons to whom the Software is 1656f6b22bSmrg# furnished to do so, subject to the following conditions: 1756f6b22bSmrg# 1856f6b22bSmrg# The above copyright notice and this permission notice shall be included in 1956f6b22bSmrg# all copies or substantial portions of the Software. 2056f6b22bSmrg# 2156f6b22bSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2256f6b22bSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2356f6b22bSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2456f6b22bSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2556f6b22bSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2656f6b22bSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2756f6b22bSmrg# 2856f6b22bSmrg# Except as contained in this notice, the name of the X Consortium shall not 2956f6b22bSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 3056f6b22bSmrg# ings in this Software without prior written authorization from the X Consor- 3156f6b22bSmrg# tium. 3256f6b22bSmrg# 3356f6b22bSmrg# 3456f6b22bSmrg# FSF changes to this file are in the public domain. 3556f6b22bSmrg# 3656f6b22bSmrg# Calling this script install-sh is preferred over install.sh, to prevent 3756f6b22bSmrg# `make' implicit rules from creating a file called install from it 3856f6b22bSmrg# when there is no Makefile. 3956f6b22bSmrg# 4056f6b22bSmrg# This script is compatible with the BSD install script, but was written 4156f6b22bSmrg# from scratch. It can only install one file at a time, a restriction 4256f6b22bSmrg# shared with many OS's install programs. 4356f6b22bSmrg 4456f6b22bSmrg 4556f6b22bSmrg# set DOITPROG to echo to test this script 4656f6b22bSmrg 4756f6b22bSmrg# Don't use :- since 4.3BSD and earlier shells don't like it. 4856f6b22bSmrgdoit="${DOITPROG-}" 4956f6b22bSmrg 5056f6b22bSmrg 5156f6b22bSmrg# put in absolute paths if you don't have them in your path; or use env. vars. 5256f6b22bSmrg 5356f6b22bSmrgmvprog="${MVPROG-mv}" 5456f6b22bSmrgcpprog="${CPPROG-cp}" 5556f6b22bSmrgchmodprog="${CHMODPROG-chmod}" 5656f6b22bSmrgchownprog="${CHOWNPROG-chown}" 5756f6b22bSmrgchgrpprog="${CHGRPPROG-chgrp}" 5856f6b22bSmrgstripprog="${STRIPPROG-strip}" 5956f6b22bSmrgrmprog="${RMPROG-rm}" 6056f6b22bSmrgmkdirprog="${MKDIRPROG-mkdir}" 6156f6b22bSmrg 6256f6b22bSmrgtransformbasename="" 6356f6b22bSmrgtransform_arg="" 6456f6b22bSmrginstcmd="$mvprog" 6556f6b22bSmrgchmodcmd="$chmodprog 0755" 6656f6b22bSmrgchowncmd="" 6756f6b22bSmrgchgrpcmd="" 6856f6b22bSmrgstripcmd="" 6956f6b22bSmrgrmcmd="$rmprog -f" 7056f6b22bSmrgmvcmd="$mvprog" 7156f6b22bSmrgsrc="" 7256f6b22bSmrgdst="" 7356f6b22bSmrgdir_arg="" 7456f6b22bSmrg 7556f6b22bSmrgwhile [ x"$1" != x ]; do 7656f6b22bSmrg case $1 in 7756f6b22bSmrg -c) instcmd=$cpprog 7856f6b22bSmrg shift 7956f6b22bSmrg continue;; 8056f6b22bSmrg 8156f6b22bSmrg -d) dir_arg=true 8256f6b22bSmrg shift 8356f6b22bSmrg continue;; 8456f6b22bSmrg 8556f6b22bSmrg -m) chmodcmd="$chmodprog $2" 8656f6b22bSmrg shift 8756f6b22bSmrg shift 8856f6b22bSmrg continue;; 8956f6b22bSmrg 9056f6b22bSmrg -o) chowncmd="$chownprog $2" 9156f6b22bSmrg shift 9256f6b22bSmrg shift 9356f6b22bSmrg continue;; 9456f6b22bSmrg 9556f6b22bSmrg -g) chgrpcmd="$chgrpprog $2" 9656f6b22bSmrg shift 9756f6b22bSmrg shift 9856f6b22bSmrg continue;; 9956f6b22bSmrg 10056f6b22bSmrg -s) stripcmd=$stripprog 10156f6b22bSmrg shift 10256f6b22bSmrg continue;; 10356f6b22bSmrg 10456f6b22bSmrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 10556f6b22bSmrg shift 10656f6b22bSmrg continue;; 10756f6b22bSmrg 10856f6b22bSmrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 10956f6b22bSmrg shift 11056f6b22bSmrg continue;; 11156f6b22bSmrg 11256f6b22bSmrg *) if [ x"$src" = x ] 11356f6b22bSmrg then 11456f6b22bSmrg src=$1 11556f6b22bSmrg else 11656f6b22bSmrg # this colon is to work around a 386BSD /bin/sh bug 11756f6b22bSmrg : 11856f6b22bSmrg dst=$1 11956f6b22bSmrg fi 12056f6b22bSmrg shift 12156f6b22bSmrg continue;; 12256f6b22bSmrg esac 12356f6b22bSmrgdone 12456f6b22bSmrg 12556f6b22bSmrgif [ x"$src" = x ] 12656f6b22bSmrgthen 12756f6b22bSmrg echo "$0: no input file specified" >&2 12856f6b22bSmrg exit 1 12956f6b22bSmrgelse 13056f6b22bSmrg : 13156f6b22bSmrgfi 13256f6b22bSmrg 13356f6b22bSmrgif [ x"$dir_arg" != x ]; then 13456f6b22bSmrg dst=$src 13556f6b22bSmrg src="" 13656f6b22bSmrg 13756f6b22bSmrg if [ -d "$dst" ]; then 13856f6b22bSmrg instcmd=: 13956f6b22bSmrg chmodcmd="" 14056f6b22bSmrg else 14156f6b22bSmrg instcmd=$mkdirprog 14256f6b22bSmrg fi 14356f6b22bSmrgelse 14456f6b22bSmrg 14556f6b22bSmrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 14656f6b22bSmrg# might cause directories to be created, which would be especially bad 14756f6b22bSmrg# if $src (and thus $dsttmp) contains '*'. 14856f6b22bSmrg 14956f6b22bSmrg if [ -f "$src" ] || [ -d "$src" ] 15056f6b22bSmrg then 15156f6b22bSmrg : 15256f6b22bSmrg else 15356f6b22bSmrg echo "$0: $src does not exist" >&2 15456f6b22bSmrg exit 1 15556f6b22bSmrg fi 15656f6b22bSmrg 15756f6b22bSmrg if [ x"$dst" = x ] 15856f6b22bSmrg then 15956f6b22bSmrg echo "$0: no destination specified" >&2 16056f6b22bSmrg exit 1 16156f6b22bSmrg else 16256f6b22bSmrg : 16356f6b22bSmrg fi 16456f6b22bSmrg 16556f6b22bSmrg# If destination is a directory, append the input filename; if your system 16656f6b22bSmrg# does not like double slashes in filenames, you may need to add some logic 16756f6b22bSmrg 16856f6b22bSmrg if [ -d "$dst" ] 16956f6b22bSmrg then 17056f6b22bSmrg dst=$dst/`basename "$src"` 17156f6b22bSmrg else 17256f6b22bSmrg : 17356f6b22bSmrg fi 17456f6b22bSmrgfi 17556f6b22bSmrg 17656f6b22bSmrg## this sed command emulates the dirname command 17756f6b22bSmrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 17856f6b22bSmrg 17956f6b22bSmrg# Make sure that the destination directory exists. 18056f6b22bSmrg# this part is taken from Noah Friedman's mkinstalldirs script 18156f6b22bSmrg 18256f6b22bSmrg# Skip lots of stat calls in the usual case. 18356f6b22bSmrgif [ ! -d "$dstdir" ]; then 18456f6b22bSmrgdefaultIFS=' 18556f6b22bSmrg ' 18656f6b22bSmrgIFS="${IFS-$defaultIFS}" 18756f6b22bSmrg 18856f6b22bSmrgoIFS=$IFS 18956f6b22bSmrg# Some sh's can't handle IFS=/ for some reason. 19056f6b22bSmrgIFS='%' 19156f6b22bSmrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 19256f6b22bSmrgIFS=$oIFS 19356f6b22bSmrg 19456f6b22bSmrgpathcomp='' 19556f6b22bSmrg 19656f6b22bSmrgwhile [ $# -ne 0 ] ; do 19756f6b22bSmrg pathcomp=$pathcomp$1 19856f6b22bSmrg shift 19956f6b22bSmrg 20056f6b22bSmrg if [ ! -d "$pathcomp" ] ; 20156f6b22bSmrg then 20256f6b22bSmrg $mkdirprog "$pathcomp" 20356f6b22bSmrg else 20456f6b22bSmrg : 20556f6b22bSmrg fi 20656f6b22bSmrg 20756f6b22bSmrg pathcomp=$pathcomp/ 20856f6b22bSmrgdone 20956f6b22bSmrgfi 21056f6b22bSmrg 21156f6b22bSmrgif [ x"$dir_arg" != x ] 21256f6b22bSmrgthen 21356f6b22bSmrg $doit $instcmd "$dst" && 21456f6b22bSmrg 21556f6b22bSmrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 21656f6b22bSmrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 21756f6b22bSmrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 21856f6b22bSmrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 21956f6b22bSmrgelse 22056f6b22bSmrg 22156f6b22bSmrg# If we're going to rename the final executable, determine the name now. 22256f6b22bSmrg 22356f6b22bSmrg if [ x"$transformarg" = x ] 22456f6b22bSmrg then 22556f6b22bSmrg dstfile=`basename "$dst"` 22656f6b22bSmrg else 22756f6b22bSmrg dstfile=`basename "$dst" $transformbasename | 22856f6b22bSmrg sed $transformarg`$transformbasename 22956f6b22bSmrg fi 23056f6b22bSmrg 23156f6b22bSmrg# don't allow the sed command to completely eliminate the filename 23256f6b22bSmrg 23356f6b22bSmrg if [ x"$dstfile" = x ] 23456f6b22bSmrg then 23556f6b22bSmrg dstfile=`basename "$dst"` 23656f6b22bSmrg else 23756f6b22bSmrg : 23856f6b22bSmrg fi 23956f6b22bSmrg 24056f6b22bSmrg# Make a couple of temp file names in the proper directory. 24156f6b22bSmrg 24256f6b22bSmrg dsttmp=$dstdir/_inst.$$_ 24356f6b22bSmrg rmtmp=$dstdir/_rm.$$_ 24456f6b22bSmrg 24556f6b22bSmrg# Trap to clean up temp files at exit. 24656f6b22bSmrg 24756f6b22bSmrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 24856f6b22bSmrg trap '(exit $?); exit' 1 2 13 15 24956f6b22bSmrg 25056f6b22bSmrg# Move or copy the file name to the temp name 25156f6b22bSmrg 25256f6b22bSmrg $doit $instcmd "$src" "$dsttmp" && 25356f6b22bSmrg 25456f6b22bSmrg# and set any options; do chmod last to preserve setuid bits 25556f6b22bSmrg 25656f6b22bSmrg# If any of these fail, we abort the whole thing. If we want to 25756f6b22bSmrg# ignore errors from any of these, just make sure not to ignore 25856f6b22bSmrg# errors from the above "$doit $instcmd $src $dsttmp" command. 25956f6b22bSmrg 26056f6b22bSmrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 26156f6b22bSmrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 26256f6b22bSmrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 26356f6b22bSmrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 26456f6b22bSmrg 26556f6b22bSmrg# Now remove or move aside any old file at destination location. We try this 26656f6b22bSmrg# two ways since rm can't unlink itself on some systems and the destination 26756f6b22bSmrg# file might be busy for other reasons. In this case, the final cleanup 26856f6b22bSmrg# might fail but the new file should still install successfully. 26956f6b22bSmrg 27056f6b22bSmrg{ 27156f6b22bSmrg if [ -f "$dstdir/$dstfile" ] 27256f6b22bSmrg then 27356f6b22bSmrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 27456f6b22bSmrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 27556f6b22bSmrg { 27656f6b22bSmrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 27756f6b22bSmrg (exit 1); exit 27856f6b22bSmrg } 27956f6b22bSmrg else 28056f6b22bSmrg : 28156f6b22bSmrg fi 28256f6b22bSmrg} && 28356f6b22bSmrg 28456f6b22bSmrg# Now rename the file to the real destination. 28556f6b22bSmrg 28656f6b22bSmrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 28756f6b22bSmrg 28856f6b22bSmrgfi && 28956f6b22bSmrg 29056f6b22bSmrg# The final little trick to "correctly" pass the exit status to the exit trap. 29156f6b22bSmrg 29256f6b22bSmrg{ 29356f6b22bSmrg (exit 0); exit 29456f6b22bSmrg} 295