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