install-sh revision 335e815a
1335e815aSmrg#!/bin/sh 2335e815aSmrg# 3335e815aSmrg# install - install a program, script, or datafile 4335e815aSmrg# 5335e815aSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 6335e815aSmrg# later released in X11R6 (xc/config/util/install.sh) with the 7335e815aSmrg# following copyright and license. 8335e815aSmrg# 9335e815aSmrg# Copyright (C) 1994 X Consortium 10335e815aSmrg# 11335e815aSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 12335e815aSmrg# of this software and associated documentation files (the "Software"), to 13335e815aSmrg# deal in the Software without restriction, including without limitation the 14335e815aSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 15335e815aSmrg# sell copies of the Software, and to permit persons to whom the Software is 16335e815aSmrg# furnished to do so, subject to the following conditions: 17335e815aSmrg# 18335e815aSmrg# The above copyright notice and this permission notice shall be included in 19335e815aSmrg# all copies or substantial portions of the Software. 20335e815aSmrg# 21335e815aSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22335e815aSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23335e815aSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24335e815aSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 25335e815aSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 26335e815aSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27335e815aSmrg# 28335e815aSmrg# Except as contained in this notice, the name of the X Consortium shall not 29335e815aSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 30335e815aSmrg# ings in this Software without prior written authorization from the X Consor- 31335e815aSmrg# tium. 32335e815aSmrg# 33335e815aSmrg# 34335e815aSmrg# FSF changes to this file are in the public domain. 35335e815aSmrg# 36335e815aSmrg# Calling this script install-sh is preferred over install.sh, to prevent 37335e815aSmrg# `make' implicit rules from creating a file called install from it 38335e815aSmrg# when there is no Makefile. 39335e815aSmrg# 40335e815aSmrg# This script is compatible with the BSD install script, but was written 41335e815aSmrg# from scratch. It can only install one file at a time, a restriction 42335e815aSmrg# shared with many OS's install programs. 43335e815aSmrg 44335e815aSmrg 45335e815aSmrg# set DOITPROG to echo to test this script 46335e815aSmrg 47335e815aSmrg# Don't use :- since 4.3BSD and earlier shells don't like it. 48335e815aSmrgdoit="${DOITPROG-}" 49335e815aSmrg 50335e815aSmrg 51335e815aSmrg# put in absolute paths if you don't have them in your path; or use env. vars. 52335e815aSmrg 53335e815aSmrgmvprog="${MVPROG-mv}" 54335e815aSmrgcpprog="${CPPROG-cp}" 55335e815aSmrgchmodprog="${CHMODPROG-chmod}" 56335e815aSmrgchownprog="${CHOWNPROG-chown}" 57335e815aSmrgchgrpprog="${CHGRPPROG-chgrp}" 58335e815aSmrgstripprog="${STRIPPROG-strip}" 59335e815aSmrgrmprog="${RMPROG-rm}" 60335e815aSmrgmkdirprog="${MKDIRPROG-mkdir}" 61335e815aSmrg 62335e815aSmrgtransformbasename="" 63335e815aSmrgtransform_arg="" 64335e815aSmrginstcmd="$mvprog" 65335e815aSmrgchmodcmd="$chmodprog 0755" 66335e815aSmrgchowncmd="" 67335e815aSmrgchgrpcmd="" 68335e815aSmrgstripcmd="" 69335e815aSmrgrmcmd="$rmprog -f" 70335e815aSmrgmvcmd="$mvprog" 71335e815aSmrgsrc="" 72335e815aSmrgdst="" 73335e815aSmrgdir_arg="" 74335e815aSmrg 75335e815aSmrgwhile [ x"$1" != x ]; do 76335e815aSmrg case $1 in 77335e815aSmrg -c) instcmd=$cpprog 78335e815aSmrg shift 79335e815aSmrg continue;; 80335e815aSmrg 81335e815aSmrg -d) dir_arg=true 82335e815aSmrg shift 83335e815aSmrg continue;; 84335e815aSmrg 85335e815aSmrg -m) chmodcmd="$chmodprog $2" 86335e815aSmrg shift 87335e815aSmrg shift 88335e815aSmrg continue;; 89335e815aSmrg 90335e815aSmrg -o) chowncmd="$chownprog $2" 91335e815aSmrg shift 92335e815aSmrg shift 93335e815aSmrg continue;; 94335e815aSmrg 95335e815aSmrg -g) chgrpcmd="$chgrpprog $2" 96335e815aSmrg shift 97335e815aSmrg shift 98335e815aSmrg continue;; 99335e815aSmrg 100335e815aSmrg -s) stripcmd=$stripprog 101335e815aSmrg shift 102335e815aSmrg continue;; 103335e815aSmrg 104335e815aSmrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 105335e815aSmrg shift 106335e815aSmrg continue;; 107335e815aSmrg 108335e815aSmrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 109335e815aSmrg shift 110335e815aSmrg continue;; 111335e815aSmrg 112335e815aSmrg *) if [ x"$src" = x ] 113335e815aSmrg then 114335e815aSmrg src=$1 115335e815aSmrg else 116335e815aSmrg # this colon is to work around a 386BSD /bin/sh bug 117335e815aSmrg : 118335e815aSmrg dst=$1 119335e815aSmrg fi 120335e815aSmrg shift 121335e815aSmrg continue;; 122335e815aSmrg esac 123335e815aSmrgdone 124335e815aSmrg 125335e815aSmrgif [ x"$src" = x ] 126335e815aSmrgthen 127335e815aSmrg echo "$0: no input file specified" >&2 128335e815aSmrg exit 1 129335e815aSmrgelse 130335e815aSmrg : 131335e815aSmrgfi 132335e815aSmrg 133335e815aSmrgif [ x"$dir_arg" != x ]; then 134335e815aSmrg dst=$src 135335e815aSmrg src="" 136335e815aSmrg 137335e815aSmrg if [ -d "$dst" ]; then 138335e815aSmrg instcmd=: 139335e815aSmrg chmodcmd="" 140335e815aSmrg else 141335e815aSmrg instcmd=$mkdirprog 142335e815aSmrg fi 143335e815aSmrgelse 144335e815aSmrg 145335e815aSmrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 146335e815aSmrg# might cause directories to be created, which would be especially bad 147335e815aSmrg# if $src (and thus $dsttmp) contains '*'. 148335e815aSmrg 149335e815aSmrg if [ -f "$src" ] || [ -d "$src" ] 150335e815aSmrg then 151335e815aSmrg : 152335e815aSmrg else 153335e815aSmrg echo "$0: $src does not exist" >&2 154335e815aSmrg exit 1 155335e815aSmrg fi 156335e815aSmrg 157335e815aSmrg if [ x"$dst" = x ] 158335e815aSmrg then 159335e815aSmrg echo "$0: no destination specified" >&2 160335e815aSmrg exit 1 161335e815aSmrg else 162335e815aSmrg : 163335e815aSmrg fi 164335e815aSmrg 165335e815aSmrg# If destination is a directory, append the input filename; if your system 166335e815aSmrg# does not like double slashes in filenames, you may need to add some logic 167335e815aSmrg 168335e815aSmrg if [ -d "$dst" ] 169335e815aSmrg then 170335e815aSmrg dst=$dst/`basename "$src"` 171335e815aSmrg else 172335e815aSmrg : 173335e815aSmrg fi 174335e815aSmrgfi 175335e815aSmrg 176335e815aSmrg## this sed command emulates the dirname command 177335e815aSmrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 178335e815aSmrg 179335e815aSmrg# Make sure that the destination directory exists. 180335e815aSmrg# this part is taken from Noah Friedman's mkinstalldirs script 181335e815aSmrg 182335e815aSmrg# Skip lots of stat calls in the usual case. 183335e815aSmrgif [ ! -d "$dstdir" ]; then 184335e815aSmrgdefaultIFS=' 185335e815aSmrg ' 186335e815aSmrgIFS="${IFS-$defaultIFS}" 187335e815aSmrg 188335e815aSmrgoIFS=$IFS 189335e815aSmrg# Some sh's can't handle IFS=/ for some reason. 190335e815aSmrgIFS='%' 191335e815aSmrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 192335e815aSmrgIFS=$oIFS 193335e815aSmrg 194335e815aSmrgpathcomp='' 195335e815aSmrg 196335e815aSmrgwhile [ $# -ne 0 ] ; do 197335e815aSmrg pathcomp=$pathcomp$1 198335e815aSmrg shift 199335e815aSmrg 200335e815aSmrg if [ ! -d "$pathcomp" ] ; 201335e815aSmrg then 202335e815aSmrg $mkdirprog "$pathcomp" 203335e815aSmrg else 204335e815aSmrg : 205335e815aSmrg fi 206335e815aSmrg 207335e815aSmrg pathcomp=$pathcomp/ 208335e815aSmrgdone 209335e815aSmrgfi 210335e815aSmrg 211335e815aSmrgif [ x"$dir_arg" != x ] 212335e815aSmrgthen 213335e815aSmrg $doit $instcmd "$dst" && 214335e815aSmrg 215335e815aSmrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 216335e815aSmrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 217335e815aSmrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 218335e815aSmrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 219335e815aSmrgelse 220335e815aSmrg 221335e815aSmrg# If we're going to rename the final executable, determine the name now. 222335e815aSmrg 223335e815aSmrg if [ x"$transformarg" = x ] 224335e815aSmrg then 225335e815aSmrg dstfile=`basename "$dst"` 226335e815aSmrg else 227335e815aSmrg dstfile=`basename "$dst" $transformbasename | 228335e815aSmrg sed $transformarg`$transformbasename 229335e815aSmrg fi 230335e815aSmrg 231335e815aSmrg# don't allow the sed command to completely eliminate the filename 232335e815aSmrg 233335e815aSmrg if [ x"$dstfile" = x ] 234335e815aSmrg then 235335e815aSmrg dstfile=`basename "$dst"` 236335e815aSmrg else 237335e815aSmrg : 238335e815aSmrg fi 239335e815aSmrg 240335e815aSmrg# Make a couple of temp file names in the proper directory. 241335e815aSmrg 242335e815aSmrg dsttmp=$dstdir/_inst.$$_ 243335e815aSmrg rmtmp=$dstdir/_rm.$$_ 244335e815aSmrg 245335e815aSmrg# Trap to clean up temp files at exit. 246335e815aSmrg 247335e815aSmrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 248335e815aSmrg trap '(exit $?); exit' 1 2 13 15 249335e815aSmrg 250335e815aSmrg# Move or copy the file name to the temp name 251335e815aSmrg 252335e815aSmrg $doit $instcmd "$src" "$dsttmp" && 253335e815aSmrg 254335e815aSmrg# and set any options; do chmod last to preserve setuid bits 255335e815aSmrg 256335e815aSmrg# If any of these fail, we abort the whole thing. If we want to 257335e815aSmrg# ignore errors from any of these, just make sure not to ignore 258335e815aSmrg# errors from the above "$doit $instcmd $src $dsttmp" command. 259335e815aSmrg 260335e815aSmrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 261335e815aSmrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 262335e815aSmrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 263335e815aSmrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 264335e815aSmrg 265335e815aSmrg# Now remove or move aside any old file at destination location. We try this 266335e815aSmrg# two ways since rm can't unlink itself on some systems and the destination 267335e815aSmrg# file might be busy for other reasons. In this case, the final cleanup 268335e815aSmrg# might fail but the new file should still install successfully. 269335e815aSmrg 270335e815aSmrg{ 271335e815aSmrg if [ -f "$dstdir/$dstfile" ] 272335e815aSmrg then 273335e815aSmrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 274335e815aSmrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 275335e815aSmrg { 276335e815aSmrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 277335e815aSmrg (exit 1); exit 278335e815aSmrg } 279335e815aSmrg else 280335e815aSmrg : 281335e815aSmrg fi 282335e815aSmrg} && 283335e815aSmrg 284335e815aSmrg# Now rename the file to the real destination. 285335e815aSmrg 286335e815aSmrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 287335e815aSmrg 288335e815aSmrgfi && 289335e815aSmrg 290335e815aSmrg# The final little trick to "correctly" pass the exit status to the exit trap. 291335e815aSmrg 292335e815aSmrg{ 293335e815aSmrg (exit 0); exit 294335e815aSmrg} 295