install-sh revision b1cb5b87
1b1cb5b87Smrg#!/bin/sh 2b1cb5b87Smrg# 3b1cb5b87Smrg# install - install a program, script, or datafile 4b1cb5b87Smrg# 5b1cb5b87Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 6b1cb5b87Smrg# later released in X11R6 (xc/config/util/install.sh) with the 7b1cb5b87Smrg# following copyright and license. 8b1cb5b87Smrg# 9b1cb5b87Smrg# Copyright (C) 1994 X Consortium 10b1cb5b87Smrg# 11b1cb5b87Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 12b1cb5b87Smrg# of this software and associated documentation files (the "Software"), to 13b1cb5b87Smrg# deal in the Software without restriction, including without limitation the 14b1cb5b87Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 15b1cb5b87Smrg# sell copies of the Software, and to permit persons to whom the Software is 16b1cb5b87Smrg# furnished to do so, subject to the following conditions: 17b1cb5b87Smrg# 18b1cb5b87Smrg# The above copyright notice and this permission notice shall be included in 19b1cb5b87Smrg# all copies or substantial portions of the Software. 20b1cb5b87Smrg# 21b1cb5b87Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22b1cb5b87Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23b1cb5b87Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24b1cb5b87Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 25b1cb5b87Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 26b1cb5b87Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27b1cb5b87Smrg# 28b1cb5b87Smrg# Except as contained in this notice, the name of the X Consortium shall not 29b1cb5b87Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 30b1cb5b87Smrg# ings in this Software without prior written authorization from the X Consor- 31b1cb5b87Smrg# tium. 32b1cb5b87Smrg# 33b1cb5b87Smrg# 34b1cb5b87Smrg# FSF changes to this file are in the public domain. 35b1cb5b87Smrg# 36b1cb5b87Smrg# Calling this script install-sh is preferred over install.sh, to prevent 37b1cb5b87Smrg# `make' implicit rules from creating a file called install from it 38b1cb5b87Smrg# when there is no Makefile. 39b1cb5b87Smrg# 40b1cb5b87Smrg# This script is compatible with the BSD install script, but was written 41b1cb5b87Smrg# from scratch. It can only install one file at a time, a restriction 42b1cb5b87Smrg# shared with many OS's install programs. 43b1cb5b87Smrg 44b1cb5b87Smrg 45b1cb5b87Smrg# set DOITPROG to echo to test this script 46b1cb5b87Smrg 47b1cb5b87Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 48b1cb5b87Smrgdoit="${DOITPROG-}" 49b1cb5b87Smrg 50b1cb5b87Smrg 51b1cb5b87Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 52b1cb5b87Smrg 53b1cb5b87Smrgmvprog="${MVPROG-mv}" 54b1cb5b87Smrgcpprog="${CPPROG-cp}" 55b1cb5b87Smrgchmodprog="${CHMODPROG-chmod}" 56b1cb5b87Smrgchownprog="${CHOWNPROG-chown}" 57b1cb5b87Smrgchgrpprog="${CHGRPPROG-chgrp}" 58b1cb5b87Smrgstripprog="${STRIPPROG-strip}" 59b1cb5b87Smrgrmprog="${RMPROG-rm}" 60b1cb5b87Smrgmkdirprog="${MKDIRPROG-mkdir}" 61b1cb5b87Smrg 62b1cb5b87Smrgtransformbasename="" 63b1cb5b87Smrgtransform_arg="" 64b1cb5b87Smrginstcmd="$mvprog" 65b1cb5b87Smrgchmodcmd="$chmodprog 0755" 66b1cb5b87Smrgchowncmd="" 67b1cb5b87Smrgchgrpcmd="" 68b1cb5b87Smrgstripcmd="" 69b1cb5b87Smrgrmcmd="$rmprog -f" 70b1cb5b87Smrgmvcmd="$mvprog" 71b1cb5b87Smrgsrc="" 72b1cb5b87Smrgdst="" 73b1cb5b87Smrgdir_arg="" 74b1cb5b87Smrg 75b1cb5b87Smrgwhile [ x"$1" != x ]; do 76b1cb5b87Smrg case $1 in 77b1cb5b87Smrg -c) instcmd=$cpprog 78b1cb5b87Smrg shift 79b1cb5b87Smrg continue;; 80b1cb5b87Smrg 81b1cb5b87Smrg -d) dir_arg=true 82b1cb5b87Smrg shift 83b1cb5b87Smrg continue;; 84b1cb5b87Smrg 85b1cb5b87Smrg -m) chmodcmd="$chmodprog $2" 86b1cb5b87Smrg shift 87b1cb5b87Smrg shift 88b1cb5b87Smrg continue;; 89b1cb5b87Smrg 90b1cb5b87Smrg -o) chowncmd="$chownprog $2" 91b1cb5b87Smrg shift 92b1cb5b87Smrg shift 93b1cb5b87Smrg continue;; 94b1cb5b87Smrg 95b1cb5b87Smrg -g) chgrpcmd="$chgrpprog $2" 96b1cb5b87Smrg shift 97b1cb5b87Smrg shift 98b1cb5b87Smrg continue;; 99b1cb5b87Smrg 100b1cb5b87Smrg -s) stripcmd=$stripprog 101b1cb5b87Smrg shift 102b1cb5b87Smrg continue;; 103b1cb5b87Smrg 104b1cb5b87Smrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 105b1cb5b87Smrg shift 106b1cb5b87Smrg continue;; 107b1cb5b87Smrg 108b1cb5b87Smrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 109b1cb5b87Smrg shift 110b1cb5b87Smrg continue;; 111b1cb5b87Smrg 112b1cb5b87Smrg *) if [ x"$src" = x ] 113b1cb5b87Smrg then 114b1cb5b87Smrg src=$1 115b1cb5b87Smrg else 116b1cb5b87Smrg # this colon is to work around a 386BSD /bin/sh bug 117b1cb5b87Smrg : 118b1cb5b87Smrg dst=$1 119b1cb5b87Smrg fi 120b1cb5b87Smrg shift 121b1cb5b87Smrg continue;; 122b1cb5b87Smrg esac 123b1cb5b87Smrgdone 124b1cb5b87Smrg 125b1cb5b87Smrgif [ x"$src" = x ] 126b1cb5b87Smrgthen 127b1cb5b87Smrg echo "$0: no input file specified" >&2 128b1cb5b87Smrg exit 1 129b1cb5b87Smrgelse 130b1cb5b87Smrg : 131b1cb5b87Smrgfi 132b1cb5b87Smrg 133b1cb5b87Smrgif [ x"$dir_arg" != x ]; then 134b1cb5b87Smrg dst=$src 135b1cb5b87Smrg src="" 136b1cb5b87Smrg 137b1cb5b87Smrg if [ -d "$dst" ]; then 138b1cb5b87Smrg instcmd=: 139b1cb5b87Smrg chmodcmd="" 140b1cb5b87Smrg else 141b1cb5b87Smrg instcmd=$mkdirprog 142b1cb5b87Smrg fi 143b1cb5b87Smrgelse 144b1cb5b87Smrg 145b1cb5b87Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 146b1cb5b87Smrg# might cause directories to be created, which would be especially bad 147b1cb5b87Smrg# if $src (and thus $dsttmp) contains '*'. 148b1cb5b87Smrg 149b1cb5b87Smrg if [ -f "$src" ] || [ -d "$src" ] 150b1cb5b87Smrg then 151b1cb5b87Smrg : 152b1cb5b87Smrg else 153b1cb5b87Smrg echo "$0: $src does not exist" >&2 154b1cb5b87Smrg exit 1 155b1cb5b87Smrg fi 156b1cb5b87Smrg 157b1cb5b87Smrg if [ x"$dst" = x ] 158b1cb5b87Smrg then 159b1cb5b87Smrg echo "$0: no destination specified" >&2 160b1cb5b87Smrg exit 1 161b1cb5b87Smrg else 162b1cb5b87Smrg : 163b1cb5b87Smrg fi 164b1cb5b87Smrg 165b1cb5b87Smrg# If destination is a directory, append the input filename; if your system 166b1cb5b87Smrg# does not like double slashes in filenames, you may need to add some logic 167b1cb5b87Smrg 168b1cb5b87Smrg if [ -d "$dst" ] 169b1cb5b87Smrg then 170b1cb5b87Smrg dst=$dst/`basename "$src"` 171b1cb5b87Smrg else 172b1cb5b87Smrg : 173b1cb5b87Smrg fi 174b1cb5b87Smrgfi 175b1cb5b87Smrg 176b1cb5b87Smrg## this sed command emulates the dirname command 177b1cb5b87Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 178b1cb5b87Smrg 179b1cb5b87Smrg# Make sure that the destination directory exists. 180b1cb5b87Smrg# this part is taken from Noah Friedman's mkinstalldirs script 181b1cb5b87Smrg 182b1cb5b87Smrg# Skip lots of stat calls in the usual case. 183b1cb5b87Smrgif [ ! -d "$dstdir" ]; then 184b1cb5b87SmrgdefaultIFS=' 185b1cb5b87Smrg ' 186b1cb5b87SmrgIFS="${IFS-$defaultIFS}" 187b1cb5b87Smrg 188b1cb5b87SmrgoIFS=$IFS 189b1cb5b87Smrg# Some sh's can't handle IFS=/ for some reason. 190b1cb5b87SmrgIFS='%' 191b1cb5b87Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 192b1cb5b87SmrgIFS=$oIFS 193b1cb5b87Smrg 194b1cb5b87Smrgpathcomp='' 195b1cb5b87Smrg 196b1cb5b87Smrgwhile [ $# -ne 0 ] ; do 197b1cb5b87Smrg pathcomp=$pathcomp$1 198b1cb5b87Smrg shift 199b1cb5b87Smrg 200b1cb5b87Smrg if [ ! -d "$pathcomp" ] ; 201b1cb5b87Smrg then 202b1cb5b87Smrg $mkdirprog "$pathcomp" 203b1cb5b87Smrg else 204b1cb5b87Smrg : 205b1cb5b87Smrg fi 206b1cb5b87Smrg 207b1cb5b87Smrg pathcomp=$pathcomp/ 208b1cb5b87Smrgdone 209b1cb5b87Smrgfi 210b1cb5b87Smrg 211b1cb5b87Smrgif [ x"$dir_arg" != x ] 212b1cb5b87Smrgthen 213b1cb5b87Smrg $doit $instcmd "$dst" && 214b1cb5b87Smrg 215b1cb5b87Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 216b1cb5b87Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 217b1cb5b87Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 218b1cb5b87Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 219b1cb5b87Smrgelse 220b1cb5b87Smrg 221b1cb5b87Smrg# If we're going to rename the final executable, determine the name now. 222b1cb5b87Smrg 223b1cb5b87Smrg if [ x"$transformarg" = x ] 224b1cb5b87Smrg then 225b1cb5b87Smrg dstfile=`basename "$dst"` 226b1cb5b87Smrg else 227b1cb5b87Smrg dstfile=`basename "$dst" $transformbasename | 228b1cb5b87Smrg sed $transformarg`$transformbasename 229b1cb5b87Smrg fi 230b1cb5b87Smrg 231b1cb5b87Smrg# don't allow the sed command to completely eliminate the filename 232b1cb5b87Smrg 233b1cb5b87Smrg if [ x"$dstfile" = x ] 234b1cb5b87Smrg then 235b1cb5b87Smrg dstfile=`basename "$dst"` 236b1cb5b87Smrg else 237b1cb5b87Smrg : 238b1cb5b87Smrg fi 239b1cb5b87Smrg 240b1cb5b87Smrg# Make a couple of temp file names in the proper directory. 241b1cb5b87Smrg 242b1cb5b87Smrg dsttmp=$dstdir/_inst.$$_ 243b1cb5b87Smrg rmtmp=$dstdir/_rm.$$_ 244b1cb5b87Smrg 245b1cb5b87Smrg# Trap to clean up temp files at exit. 246b1cb5b87Smrg 247b1cb5b87Smrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 248b1cb5b87Smrg trap '(exit $?); exit' 1 2 13 15 249b1cb5b87Smrg 250b1cb5b87Smrg# Move or copy the file name to the temp name 251b1cb5b87Smrg 252b1cb5b87Smrg $doit $instcmd "$src" "$dsttmp" && 253b1cb5b87Smrg 254b1cb5b87Smrg# and set any options; do chmod last to preserve setuid bits 255b1cb5b87Smrg 256b1cb5b87Smrg# If any of these fail, we abort the whole thing. If we want to 257b1cb5b87Smrg# ignore errors from any of these, just make sure not to ignore 258b1cb5b87Smrg# errors from the above "$doit $instcmd $src $dsttmp" command. 259b1cb5b87Smrg 260b1cb5b87Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 261b1cb5b87Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 262b1cb5b87Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 263b1cb5b87Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 264b1cb5b87Smrg 265b1cb5b87Smrg# Now remove or move aside any old file at destination location. We try this 266b1cb5b87Smrg# two ways since rm can't unlink itself on some systems and the destination 267b1cb5b87Smrg# file might be busy for other reasons. In this case, the final cleanup 268b1cb5b87Smrg# might fail but the new file should still install successfully. 269b1cb5b87Smrg 270b1cb5b87Smrg{ 271b1cb5b87Smrg if [ -f "$dstdir/$dstfile" ] 272b1cb5b87Smrg then 273b1cb5b87Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 274b1cb5b87Smrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 275b1cb5b87Smrg { 276b1cb5b87Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 277b1cb5b87Smrg (exit 1); exit 278b1cb5b87Smrg } 279b1cb5b87Smrg else 280b1cb5b87Smrg : 281b1cb5b87Smrg fi 282b1cb5b87Smrg} && 283b1cb5b87Smrg 284b1cb5b87Smrg# Now rename the file to the real destination. 285b1cb5b87Smrg 286b1cb5b87Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 287b1cb5b87Smrg 288b1cb5b87Smrgfi && 289b1cb5b87Smrg 290b1cb5b87Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 291b1cb5b87Smrg 292b1cb5b87Smrg{ 293b1cb5b87Smrg (exit 0); exit 294b1cb5b87Smrg} 295