install-sh revision 264fa531
1264fa531Smrg#!/bin/sh 2264fa531Smrg# 3264fa531Smrg# install - install a program, script, or datafile 4264fa531Smrg# 5264fa531Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 6264fa531Smrg# later released in X11R6 (xc/config/util/install.sh) with the 7264fa531Smrg# following copyright and license. 8264fa531Smrg# 9264fa531Smrg# Copyright (C) 1994 X Consortium 10264fa531Smrg# 11264fa531Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 12264fa531Smrg# of this software and associated documentation files (the "Software"), to 13264fa531Smrg# deal in the Software without restriction, including without limitation the 14264fa531Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 15264fa531Smrg# sell copies of the Software, and to permit persons to whom the Software is 16264fa531Smrg# furnished to do so, subject to the following conditions: 17264fa531Smrg# 18264fa531Smrg# The above copyright notice and this permission notice shall be included in 19264fa531Smrg# all copies or substantial portions of the Software. 20264fa531Smrg# 21264fa531Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22264fa531Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23264fa531Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24264fa531Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 25264fa531Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 26264fa531Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27264fa531Smrg# 28264fa531Smrg# Except as contained in this notice, the name of the X Consortium shall not 29264fa531Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 30264fa531Smrg# ings in this Software without prior written authorization from the X Consor- 31264fa531Smrg# tium. 32264fa531Smrg# 33264fa531Smrg# 34264fa531Smrg# FSF changes to this file are in the public domain. 35264fa531Smrg# 36264fa531Smrg# Calling this script install-sh is preferred over install.sh, to prevent 37264fa531Smrg# `make' implicit rules from creating a file called install from it 38264fa531Smrg# when there is no Makefile. 39264fa531Smrg# 40264fa531Smrg# This script is compatible with the BSD install script, but was written 41264fa531Smrg# from scratch. It can only install one file at a time, a restriction 42264fa531Smrg# shared with many OS's install programs. 43264fa531Smrg 44264fa531Smrg 45264fa531Smrg# set DOITPROG to echo to test this script 46264fa531Smrg 47264fa531Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 48264fa531Smrgdoit="${DOITPROG-}" 49264fa531Smrg 50264fa531Smrg 51264fa531Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 52264fa531Smrg 53264fa531Smrgmvprog="${MVPROG-mv}" 54264fa531Smrgcpprog="${CPPROG-cp}" 55264fa531Smrgchmodprog="${CHMODPROG-chmod}" 56264fa531Smrgchownprog="${CHOWNPROG-chown}" 57264fa531Smrgchgrpprog="${CHGRPPROG-chgrp}" 58264fa531Smrgstripprog="${STRIPPROG-strip}" 59264fa531Smrgrmprog="${RMPROG-rm}" 60264fa531Smrgmkdirprog="${MKDIRPROG-mkdir}" 61264fa531Smrg 62264fa531Smrgtransformbasename="" 63264fa531Smrgtransform_arg="" 64264fa531Smrginstcmd="$mvprog" 65264fa531Smrgchmodcmd="$chmodprog 0755" 66264fa531Smrgchowncmd="" 67264fa531Smrgchgrpcmd="" 68264fa531Smrgstripcmd="" 69264fa531Smrgrmcmd="$rmprog -f" 70264fa531Smrgmvcmd="$mvprog" 71264fa531Smrgsrc="" 72264fa531Smrgdst="" 73264fa531Smrgdir_arg="" 74264fa531Smrg 75264fa531Smrgwhile [ x"$1" != x ]; do 76264fa531Smrg case $1 in 77264fa531Smrg -c) instcmd=$cpprog 78264fa531Smrg shift 79264fa531Smrg continue;; 80264fa531Smrg 81264fa531Smrg -d) dir_arg=true 82264fa531Smrg shift 83264fa531Smrg continue;; 84264fa531Smrg 85264fa531Smrg -m) chmodcmd="$chmodprog $2" 86264fa531Smrg shift 87264fa531Smrg shift 88264fa531Smrg continue;; 89264fa531Smrg 90264fa531Smrg -o) chowncmd="$chownprog $2" 91264fa531Smrg shift 92264fa531Smrg shift 93264fa531Smrg continue;; 94264fa531Smrg 95264fa531Smrg -g) chgrpcmd="$chgrpprog $2" 96264fa531Smrg shift 97264fa531Smrg shift 98264fa531Smrg continue;; 99264fa531Smrg 100264fa531Smrg -s) stripcmd=$stripprog 101264fa531Smrg shift 102264fa531Smrg continue;; 103264fa531Smrg 104264fa531Smrg -t=*) transformarg=`echo $1 | sed 's/-t=//'` 105264fa531Smrg shift 106264fa531Smrg continue;; 107264fa531Smrg 108264fa531Smrg -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 109264fa531Smrg shift 110264fa531Smrg continue;; 111264fa531Smrg 112264fa531Smrg *) if [ x"$src" = x ] 113264fa531Smrg then 114264fa531Smrg src=$1 115264fa531Smrg else 116264fa531Smrg # this colon is to work around a 386BSD /bin/sh bug 117264fa531Smrg : 118264fa531Smrg dst=$1 119264fa531Smrg fi 120264fa531Smrg shift 121264fa531Smrg continue;; 122264fa531Smrg esac 123264fa531Smrgdone 124264fa531Smrg 125264fa531Smrgif [ x"$src" = x ] 126264fa531Smrgthen 127264fa531Smrg echo "$0: no input file specified" >&2 128264fa531Smrg exit 1 129264fa531Smrgelse 130264fa531Smrg : 131264fa531Smrgfi 132264fa531Smrg 133264fa531Smrgif [ x"$dir_arg" != x ]; then 134264fa531Smrg dst=$src 135264fa531Smrg src="" 136264fa531Smrg 137264fa531Smrg if [ -d "$dst" ]; then 138264fa531Smrg instcmd=: 139264fa531Smrg chmodcmd="" 140264fa531Smrg else 141264fa531Smrg instcmd=$mkdirprog 142264fa531Smrg fi 143264fa531Smrgelse 144264fa531Smrg 145264fa531Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 146264fa531Smrg# might cause directories to be created, which would be especially bad 147264fa531Smrg# if $src (and thus $dsttmp) contains '*'. 148264fa531Smrg 149264fa531Smrg if [ -f "$src" ] || [ -d "$src" ] 150264fa531Smrg then 151264fa531Smrg : 152264fa531Smrg else 153264fa531Smrg echo "$0: $src does not exist" >&2 154264fa531Smrg exit 1 155264fa531Smrg fi 156264fa531Smrg 157264fa531Smrg if [ x"$dst" = x ] 158264fa531Smrg then 159264fa531Smrg echo "$0: no destination specified" >&2 160264fa531Smrg exit 1 161264fa531Smrg else 162264fa531Smrg : 163264fa531Smrg fi 164264fa531Smrg 165264fa531Smrg# If destination is a directory, append the input filename; if your system 166264fa531Smrg# does not like double slashes in filenames, you may need to add some logic 167264fa531Smrg 168264fa531Smrg if [ -d "$dst" ] 169264fa531Smrg then 170264fa531Smrg dst=$dst/`basename "$src"` 171264fa531Smrg else 172264fa531Smrg : 173264fa531Smrg fi 174264fa531Smrgfi 175264fa531Smrg 176264fa531Smrg## this sed command emulates the dirname command 177264fa531Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 178264fa531Smrg 179264fa531Smrg# Make sure that the destination directory exists. 180264fa531Smrg# this part is taken from Noah Friedman's mkinstalldirs script 181264fa531Smrg 182264fa531Smrg# Skip lots of stat calls in the usual case. 183264fa531Smrgif [ ! -d "$dstdir" ]; then 184264fa531SmrgdefaultIFS=' 185264fa531Smrg ' 186264fa531SmrgIFS="${IFS-$defaultIFS}" 187264fa531Smrg 188264fa531SmrgoIFS=$IFS 189264fa531Smrg# Some sh's can't handle IFS=/ for some reason. 190264fa531SmrgIFS='%' 191264fa531Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 192264fa531SmrgIFS=$oIFS 193264fa531Smrg 194264fa531Smrgpathcomp='' 195264fa531Smrg 196264fa531Smrgwhile [ $# -ne 0 ] ; do 197264fa531Smrg pathcomp=$pathcomp$1 198264fa531Smrg shift 199264fa531Smrg 200264fa531Smrg if [ ! -d "$pathcomp" ] ; 201264fa531Smrg then 202264fa531Smrg $mkdirprog "$pathcomp" 203264fa531Smrg else 204264fa531Smrg : 205264fa531Smrg fi 206264fa531Smrg 207264fa531Smrg pathcomp=$pathcomp/ 208264fa531Smrgdone 209264fa531Smrgfi 210264fa531Smrg 211264fa531Smrgif [ x"$dir_arg" != x ] 212264fa531Smrgthen 213264fa531Smrg $doit $instcmd "$dst" && 214264fa531Smrg 215264fa531Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 216264fa531Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 217264fa531Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 218264fa531Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 219264fa531Smrgelse 220264fa531Smrg 221264fa531Smrg# If we're going to rename the final executable, determine the name now. 222264fa531Smrg 223264fa531Smrg if [ x"$transformarg" = x ] 224264fa531Smrg then 225264fa531Smrg dstfile=`basename "$dst"` 226264fa531Smrg else 227264fa531Smrg dstfile=`basename "$dst" $transformbasename | 228264fa531Smrg sed $transformarg`$transformbasename 229264fa531Smrg fi 230264fa531Smrg 231264fa531Smrg# don't allow the sed command to completely eliminate the filename 232264fa531Smrg 233264fa531Smrg if [ x"$dstfile" = x ] 234264fa531Smrg then 235264fa531Smrg dstfile=`basename "$dst"` 236264fa531Smrg else 237264fa531Smrg : 238264fa531Smrg fi 239264fa531Smrg 240264fa531Smrg# Make a couple of temp file names in the proper directory. 241264fa531Smrg 242264fa531Smrg dsttmp=$dstdir/_inst.$$_ 243264fa531Smrg rmtmp=$dstdir/_rm.$$_ 244264fa531Smrg 245264fa531Smrg# Trap to clean up temp files at exit. 246264fa531Smrg 247264fa531Smrg trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 248264fa531Smrg trap '(exit $?); exit' 1 2 13 15 249264fa531Smrg 250264fa531Smrg# Move or copy the file name to the temp name 251264fa531Smrg 252264fa531Smrg $doit $instcmd "$src" "$dsttmp" && 253264fa531Smrg 254264fa531Smrg# and set any options; do chmod last to preserve setuid bits 255264fa531Smrg 256264fa531Smrg# If any of these fail, we abort the whole thing. If we want to 257264fa531Smrg# ignore errors from any of these, just make sure not to ignore 258264fa531Smrg# errors from the above "$doit $instcmd $src $dsttmp" command. 259264fa531Smrg 260264fa531Smrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 261264fa531Smrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 262264fa531Smrg if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 263264fa531Smrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 264264fa531Smrg 265264fa531Smrg# Now remove or move aside any old file at destination location. We try this 266264fa531Smrg# two ways since rm can't unlink itself on some systems and the destination 267264fa531Smrg# file might be busy for other reasons. In this case, the final cleanup 268264fa531Smrg# might fail but the new file should still install successfully. 269264fa531Smrg 270264fa531Smrg{ 271264fa531Smrg if [ -f "$dstdir/$dstfile" ] 272264fa531Smrg then 273264fa531Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 274264fa531Smrg $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 275264fa531Smrg { 276264fa531Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 277264fa531Smrg (exit 1); exit 278264fa531Smrg } 279264fa531Smrg else 280264fa531Smrg : 281264fa531Smrg fi 282264fa531Smrg} && 283264fa531Smrg 284264fa531Smrg# Now rename the file to the real destination. 285264fa531Smrg 286264fa531Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 287264fa531Smrg 288264fa531Smrgfi && 289264fa531Smrg 290264fa531Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 291264fa531Smrg 292264fa531Smrg{ 293264fa531Smrg (exit 0); exit 294264fa531Smrg} 295