1b528cefcSMark Murray#!/bin/sh 2b528cefcSMark Murray# 3b528cefcSMark Murray# install - install a program, script, or datafile 48373020dSJacques Vidrine# 51c43270aSJacques Vidrine# This originates from X11R5 (mit/util/scripts/install.sh), which was 61c43270aSJacques Vidrine# later released in X11R6 (xc/config/util/install.sh) with the 71c43270aSJacques Vidrine# following copyright and license. 88373020dSJacques Vidrine# 91c43270aSJacques Vidrine# Copyright (C) 1994 X Consortium 101c43270aSJacques Vidrine# 111c43270aSJacques Vidrine# Permission is hereby granted, free of charge, to any person obtaining a copy 121c43270aSJacques Vidrine# of this software and associated documentation files (the "Software"), to 131c43270aSJacques Vidrine# deal in the Software without restriction, including without limitation the 141c43270aSJacques Vidrine# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 151c43270aSJacques Vidrine# sell copies of the Software, and to permit persons to whom the Software is 161c43270aSJacques Vidrine# furnished to do so, subject to the following conditions: 171c43270aSJacques Vidrine# 181c43270aSJacques Vidrine# The above copyright notice and this permission notice shall be included in 191c43270aSJacques Vidrine# all copies or substantial portions of the Software. 201c43270aSJacques Vidrine# 211c43270aSJacques Vidrine# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 221c43270aSJacques Vidrine# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 231c43270aSJacques Vidrine# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 241c43270aSJacques Vidrine# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 251c43270aSJacques Vidrine# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 261c43270aSJacques Vidrine# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 271c43270aSJacques Vidrine# 281c43270aSJacques Vidrine# Except as contained in this notice, the name of the X Consortium shall not 291c43270aSJacques Vidrine# be used in advertising or otherwise to promote the sale, use or other deal- 301c43270aSJacques Vidrine# ings in this Software without prior written authorization from the X Consor- 311c43270aSJacques Vidrine# tium. 321c43270aSJacques Vidrine# 331c43270aSJacques Vidrine# 341c43270aSJacques Vidrine# FSF changes to this file are in the public domain. 35b528cefcSMark Murray# 36b528cefcSMark Murray# Calling this script install-sh is preferred over install.sh, to prevent 37b528cefcSMark Murray# `make' implicit rules from creating a file called install from it 38b528cefcSMark Murray# when there is no Makefile. 39b528cefcSMark Murray# 40b528cefcSMark Murray# This script is compatible with the BSD install script, but was written 418373020dSJacques Vidrine# from scratch. It can only install one file at a time, a restriction 428373020dSJacques Vidrine# shared with many OS's install programs. 43b528cefcSMark Murray 44b528cefcSMark Murray 45b528cefcSMark Murray# set DOITPROG to echo to test this script 46b528cefcSMark Murray 47b528cefcSMark Murray# Don't use :- since 4.3BSD and earlier shells don't like it. 48b528cefcSMark Murraydoit="${DOITPROG-}" 49b528cefcSMark Murray 50b528cefcSMark Murray 51b528cefcSMark Murray# put in absolute paths if you don't have them in your path; or use env. vars. 52b528cefcSMark Murray 53b528cefcSMark Murraymvprog="${MVPROG-mv}" 54b528cefcSMark Murraycpprog="${CPPROG-cp}" 55b528cefcSMark Murraychmodprog="${CHMODPROG-chmod}" 56b528cefcSMark Murraychownprog="${CHOWNPROG-chown}" 57b528cefcSMark Murraychgrpprog="${CHGRPPROG-chgrp}" 58b528cefcSMark Murraystripprog="${STRIPPROG-strip}" 59b528cefcSMark Murrayrmprog="${RMPROG-rm}" 60b528cefcSMark Murraymkdirprog="${MKDIRPROG-mkdir}" 61b528cefcSMark Murray 628373020dSJacques Vidrinetransformbasename="" 63b528cefcSMark Murraytransform_arg="" 64b528cefcSMark Murrayinstcmd="$mvprog" 65b528cefcSMark Murraychmodcmd="$chmodprog 0755" 66b528cefcSMark Murraychowncmd="" 67b528cefcSMark Murraychgrpcmd="" 68b528cefcSMark Murraystripcmd="" 69b528cefcSMark Murrayrmcmd="$rmprog -f" 70b528cefcSMark Murraymvcmd="$mvprog" 71b528cefcSMark Murraysrc="" 72b528cefcSMark Murraydst="" 73b528cefcSMark Murraydir_arg="" 74b528cefcSMark Murray 75b528cefcSMark Murraywhile [ x"$1" != x ]; do 76b528cefcSMark Murray case $1 in 771c43270aSJacques Vidrine -c) instcmd=$cpprog 78b528cefcSMark Murray shift 79b528cefcSMark Murray continue;; 80b528cefcSMark Murray 81b528cefcSMark Murray -d) dir_arg=true 82b528cefcSMark Murray shift 83b528cefcSMark Murray continue;; 84b528cefcSMark Murray 85b528cefcSMark Murray -m) chmodcmd="$chmodprog $2" 86b528cefcSMark Murray shift 87b528cefcSMark Murray shift 88b528cefcSMark Murray continue;; 89b528cefcSMark Murray 90b528cefcSMark Murray -o) chowncmd="$chownprog $2" 91b528cefcSMark Murray shift 92b528cefcSMark Murray shift 93b528cefcSMark Murray continue;; 94b528cefcSMark Murray 95b528cefcSMark Murray -g) chgrpcmd="$chgrpprog $2" 96b528cefcSMark Murray shift 97b528cefcSMark Murray shift 98b528cefcSMark Murray continue;; 99b528cefcSMark Murray 1001c43270aSJacques Vidrine -s) stripcmd=$stripprog 101b528cefcSMark Murray shift 102b528cefcSMark Murray continue;; 103b528cefcSMark Murray 104b528cefcSMark Murray -t=*) transformarg=`echo $1 | sed 's/-t=//'` 105b528cefcSMark Murray shift 106b528cefcSMark Murray continue;; 107b528cefcSMark Murray 108b528cefcSMark Murray -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 109b528cefcSMark Murray shift 110b528cefcSMark Murray continue;; 111b528cefcSMark Murray 112b528cefcSMark Murray *) if [ x"$src" = x ] 113b528cefcSMark Murray then 114b528cefcSMark Murray src=$1 115b528cefcSMark Murray else 116b528cefcSMark Murray # this colon is to work around a 386BSD /bin/sh bug 117b528cefcSMark Murray : 118b528cefcSMark Murray dst=$1 119b528cefcSMark Murray fi 120b528cefcSMark Murray shift 121b528cefcSMark Murray continue;; 122b528cefcSMark Murray esac 123b528cefcSMark Murraydone 124b528cefcSMark Murray 125b528cefcSMark Murrayif [ x"$src" = x ] 126b528cefcSMark Murraythen 1271c43270aSJacques Vidrine echo "$0: no input file specified" >&2 128b528cefcSMark Murray exit 1 129b528cefcSMark Murrayelse 1308373020dSJacques Vidrine : 131b528cefcSMark Murrayfi 132b528cefcSMark Murray 133b528cefcSMark Murrayif [ x"$dir_arg" != x ]; then 134b528cefcSMark Murray dst=$src 135b528cefcSMark Murray src="" 136b528cefcSMark Murray 1371c43270aSJacques Vidrine if [ -d "$dst" ]; then 138b528cefcSMark Murray instcmd=: 1398373020dSJacques Vidrine chmodcmd="" 140b528cefcSMark Murray else 1418373020dSJacques Vidrine instcmd=$mkdirprog 142b528cefcSMark Murray fi 143b528cefcSMark Murrayelse 144b528cefcSMark Murray 145b528cefcSMark Murray# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 146b528cefcSMark Murray# might cause directories to be created, which would be especially bad 147b528cefcSMark Murray# if $src (and thus $dsttmp) contains '*'. 148b528cefcSMark Murray 1491c43270aSJacques Vidrine if [ -f "$src" ] || [ -d "$src" ] 150b528cefcSMark Murray then 1518373020dSJacques Vidrine : 152b528cefcSMark Murray else 1531c43270aSJacques Vidrine echo "$0: $src does not exist" >&2 154b528cefcSMark Murray exit 1 155b528cefcSMark Murray fi 156b528cefcSMark Murray 157b528cefcSMark Murray if [ x"$dst" = x ] 158b528cefcSMark Murray then 1591c43270aSJacques Vidrine echo "$0: no destination specified" >&2 160b528cefcSMark Murray exit 1 161b528cefcSMark Murray else 1628373020dSJacques Vidrine : 163b528cefcSMark Murray fi 164b528cefcSMark Murray 165b528cefcSMark Murray# If destination is a directory, append the input filename; if your system 166b528cefcSMark Murray# does not like double slashes in filenames, you may need to add some logic 167b528cefcSMark Murray 1681c43270aSJacques Vidrine if [ -d "$dst" ] 169b528cefcSMark Murray then 1701c43270aSJacques Vidrine dst=$dst/`basename "$src"` 171b528cefcSMark Murray else 1728373020dSJacques Vidrine : 173b528cefcSMark Murray fi 174b528cefcSMark Murrayfi 175b528cefcSMark Murray 176b528cefcSMark Murray## this sed command emulates the dirname command 1771c43270aSJacques Vidrinedstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 178b528cefcSMark Murray 179b528cefcSMark Murray# Make sure that the destination directory exists. 180b528cefcSMark Murray# this part is taken from Noah Friedman's mkinstalldirs script 181b528cefcSMark Murray 182b528cefcSMark Murray# Skip lots of stat calls in the usual case. 183b528cefcSMark Murrayif [ ! -d "$dstdir" ]; then 184b528cefcSMark MurraydefaultIFS=' 185b528cefcSMark Murray ' 1861c43270aSJacques VidrineIFS="${IFS-$defaultIFS}" 187b528cefcSMark Murray 1881c43270aSJacques VidrineoIFS=$IFS 189b528cefcSMark Murray# Some sh's can't handle IFS=/ for some reason. 190b528cefcSMark MurrayIFS='%' 1911c43270aSJacques Vidrineset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 1921c43270aSJacques VidrineIFS=$oIFS 193b528cefcSMark Murray 194b528cefcSMark Murraypathcomp='' 195b528cefcSMark Murray 196b528cefcSMark Murraywhile [ $# -ne 0 ] ; do 1971c43270aSJacques Vidrine pathcomp=$pathcomp$1 198b528cefcSMark Murray shift 199b528cefcSMark Murray 2001c43270aSJacques Vidrine if [ ! -d "$pathcomp" ] ; 201b528cefcSMark Murray then 2021c43270aSJacques Vidrine $mkdirprog "$pathcomp" 203b528cefcSMark Murray else 2048373020dSJacques Vidrine : 205b528cefcSMark Murray fi 206b528cefcSMark Murray 2071c43270aSJacques Vidrine pathcomp=$pathcomp/ 208b528cefcSMark Murraydone 209b528cefcSMark Murrayfi 210b528cefcSMark Murray 211b528cefcSMark Murrayif [ x"$dir_arg" != x ] 212b528cefcSMark Murraythen 2131c43270aSJacques Vidrine $doit $instcmd "$dst" && 214b528cefcSMark Murray 2151c43270aSJacques Vidrine if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 2161c43270aSJacques Vidrine if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 2171c43270aSJacques Vidrine if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 2181c43270aSJacques Vidrine if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 219b528cefcSMark Murrayelse 220b528cefcSMark Murray 221b528cefcSMark Murray# If we're going to rename the final executable, determine the name now. 222b528cefcSMark Murray 223b528cefcSMark Murray if [ x"$transformarg" = x ] 224b528cefcSMark Murray then 2251c43270aSJacques Vidrine dstfile=`basename "$dst"` 226b528cefcSMark Murray else 2271c43270aSJacques Vidrine dstfile=`basename "$dst" $transformbasename | 228b528cefcSMark Murray sed $transformarg`$transformbasename 229b528cefcSMark Murray fi 230b528cefcSMark Murray 231b528cefcSMark Murray# don't allow the sed command to completely eliminate the filename 232b528cefcSMark Murray 233b528cefcSMark Murray if [ x"$dstfile" = x ] 234b528cefcSMark Murray then 2351c43270aSJacques Vidrine dstfile=`basename "$dst"` 236b528cefcSMark Murray else 2378373020dSJacques Vidrine : 238b528cefcSMark Murray fi 239b528cefcSMark Murray 2401c43270aSJacques Vidrine# Make a couple of temp file names in the proper directory. 241b528cefcSMark Murray 2421c43270aSJacques Vidrine dsttmp=$dstdir/_inst.$$_ 2431c43270aSJacques Vidrine rmtmp=$dstdir/_rm.$$_ 2441c43270aSJacques Vidrine 2451c43270aSJacques Vidrine# Trap to clean up temp files at exit. 2461c43270aSJacques Vidrine 2471c43270aSJacques Vidrine trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 2481c43270aSJacques Vidrine trap '(exit $?); exit' 1 2 13 15 249b528cefcSMark Murray 250b528cefcSMark Murray# Move or copy the file name to the temp name 251b528cefcSMark Murray 2521c43270aSJacques Vidrine $doit $instcmd "$src" "$dsttmp" && 253b528cefcSMark Murray 254b528cefcSMark Murray# and set any options; do chmod last to preserve setuid bits 255b528cefcSMark Murray 256b528cefcSMark Murray# If any of these fail, we abort the whole thing. If we want to 257b528cefcSMark Murray# ignore errors from any of these, just make sure not to ignore 258b528cefcSMark Murray# errors from the above "$doit $instcmd $src $dsttmp" command. 259b528cefcSMark Murray 2601c43270aSJacques Vidrine if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 2611c43270aSJacques Vidrine if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 2621c43270aSJacques Vidrine if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 2631c43270aSJacques Vidrine if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 2641c43270aSJacques Vidrine 2651c43270aSJacques Vidrine# Now remove or move aside any old file at destination location. We try this 2661c43270aSJacques Vidrine# two ways since rm can't unlink itself on some systems and the destination 2671c43270aSJacques Vidrine# file might be busy for other reasons. In this case, the final cleanup 2681c43270aSJacques Vidrine# might fail but the new file should still install successfully. 2691c43270aSJacques Vidrine 2701c43270aSJacques Vidrine{ 2711c43270aSJacques Vidrine if [ -f "$dstdir/$dstfile" ] 2721c43270aSJacques Vidrine then 2731c43270aSJacques Vidrine $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 2741c43270aSJacques Vidrine $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 2751c43270aSJacques Vidrine { 2761c43270aSJacques Vidrine echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 2771c43270aSJacques Vidrine (exit 1); exit 2781c43270aSJacques Vidrine } 2791c43270aSJacques Vidrine else 2801c43270aSJacques Vidrine : 2811c43270aSJacques Vidrine fi 2821c43270aSJacques Vidrine} && 283b528cefcSMark Murray 284b528cefcSMark Murray# Now rename the file to the real destination. 285b528cefcSMark Murray 2861c43270aSJacques Vidrine $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 287b528cefcSMark Murray 288b528cefcSMark Murrayfi && 289b528cefcSMark Murray 2901c43270aSJacques Vidrine# The final little trick to "correctly" pass the exit status to the exit trap. 291b528cefcSMark Murray 2921c43270aSJacques Vidrine{ 2931c43270aSJacques Vidrine (exit 0); exit 2941c43270aSJacques Vidrine} 295