1321fbaf8Sespie#!/bin/sh 2321fbaf8Sespie# install - install a program, script, or datafile 3*150b7e42Smiod 4*150b7e42Smiodscriptversion=2005-05-14.22 5*150b7e42Smiod 6*150b7e42Smiod# This originates from X11R5 (mit/util/scripts/install.sh), which was 7*150b7e42Smiod# later released in X11R6 (xc/config/util/install.sh) with the 8*150b7e42Smiod# following copyright and license. 9321fbaf8Sespie# 10*150b7e42Smiod# Copyright (C) 1994 X Consortium 11321fbaf8Sespie# 12*150b7e42Smiod# Permission is hereby granted, free of charge, to any person obtaining a copy 13*150b7e42Smiod# of this software and associated documentation files (the "Software"), to 14*150b7e42Smiod# deal in the Software without restriction, including without limitation the 15*150b7e42Smiod# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16*150b7e42Smiod# sell copies of the Software, and to permit persons to whom the Software is 17*150b7e42Smiod# furnished to do so, subject to the following conditions: 18*150b7e42Smiod# 19*150b7e42Smiod# The above copyright notice and this permission notice shall be included in 20*150b7e42Smiod# all copies or substantial portions of the Software. 21*150b7e42Smiod# 22*150b7e42Smiod# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23*150b7e42Smiod# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24*150b7e42Smiod# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25*150b7e42Smiod# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26*150b7e42Smiod# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27*150b7e42Smiod# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28*150b7e42Smiod# 29*150b7e42Smiod# Except as contained in this notice, the name of the X Consortium shall not 30*150b7e42Smiod# be used in advertising or otherwise to promote the sale, use or other deal- 31*150b7e42Smiod# ings in this Software without prior written authorization from the X Consor- 32*150b7e42Smiod# tium. 33*150b7e42Smiod# 34*150b7e42Smiod# 35*150b7e42Smiod# FSF changes to this file are in the public domain. 36321fbaf8Sespie# 37321fbaf8Sespie# Calling this script install-sh is preferred over install.sh, to prevent 38321fbaf8Sespie# `make' implicit rules from creating a file called install from it 39321fbaf8Sespie# when there is no Makefile. 40321fbaf8Sespie# 41321fbaf8Sespie# This script is compatible with the BSD install script, but was written 42321fbaf8Sespie# from scratch. It can only install one file at a time, a restriction 43321fbaf8Sespie# shared with many OS's install programs. 44321fbaf8Sespie 45321fbaf8Sespie# set DOITPROG to echo to test this script 46321fbaf8Sespie 47321fbaf8Sespie# Don't use :- since 4.3BSD and earlier shells don't like it. 48321fbaf8Sespiedoit="${DOITPROG-}" 49321fbaf8Sespie 50321fbaf8Sespie# put in absolute paths if you don't have them in your path; or use env. vars. 51321fbaf8Sespie 52321fbaf8Sespiemvprog="${MVPROG-mv}" 53321fbaf8Sespiecpprog="${CPPROG-cp}" 54321fbaf8Sespiechmodprog="${CHMODPROG-chmod}" 55321fbaf8Sespiechownprog="${CHOWNPROG-chown}" 56321fbaf8Sespiechgrpprog="${CHGRPPROG-chgrp}" 57321fbaf8Sespiestripprog="${STRIPPROG-strip}" 58321fbaf8Sespiermprog="${RMPROG-rm}" 59321fbaf8Sespiemkdirprog="${MKDIRPROG-mkdir}" 60321fbaf8Sespie 61321fbaf8Sespiechmodcmd="$chmodprog 0755" 62*150b7e42Smiodchowncmd= 63*150b7e42Smiodchgrpcmd= 64*150b7e42Smiodstripcmd= 65321fbaf8Sespiermcmd="$rmprog -f" 66321fbaf8Sespiemvcmd="$mvprog" 67*150b7e42Smiodsrc= 68*150b7e42Smioddst= 69*150b7e42Smioddir_arg= 70*150b7e42Smioddstarg= 71*150b7e42Smiodno_target_directory= 72321fbaf8Sespie 73*150b7e42Smiodusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 74*150b7e42Smiod or: $0 [OPTION]... SRCFILES... DIRECTORY 75*150b7e42Smiod or: $0 [OPTION]... -t DIRECTORY SRCFILES... 76*150b7e42Smiod or: $0 [OPTION]... -d DIRECTORIES... 77*150b7e42Smiod 78*150b7e42SmiodIn the 1st form, copy SRCFILE to DSTFILE. 79*150b7e42SmiodIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 80*150b7e42SmiodIn the 4th, create DIRECTORIES. 81*150b7e42Smiod 82*150b7e42SmiodOptions: 83*150b7e42Smiod-c (ignored) 84*150b7e42Smiod-d create directories instead of installing files. 85*150b7e42Smiod-g GROUP $chgrpprog installed files to GROUP. 86*150b7e42Smiod-m MODE $chmodprog installed files to MODE. 87*150b7e42Smiod-o USER $chownprog installed files to USER. 88*150b7e42Smiod-s $stripprog installed files. 89*150b7e42Smiod-t DIRECTORY install into DIRECTORY. 90*150b7e42Smiod-T report an error if DSTFILE is a directory. 91*150b7e42Smiod--help display this help and exit. 92*150b7e42Smiod--version display version info and exit. 93*150b7e42Smiod 94*150b7e42SmiodEnvironment variables override the default commands: 95*150b7e42Smiod CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 96*150b7e42Smiod" 97*150b7e42Smiod 98*150b7e42Smiodwhile test -n "$1"; do 99321fbaf8Sespie case $1 in 100*150b7e42Smiod -c) shift 101321fbaf8Sespie continue;; 102321fbaf8Sespie 103321fbaf8Sespie -d) dir_arg=true 104321fbaf8Sespie shift 105321fbaf8Sespie continue;; 106321fbaf8Sespie 107*150b7e42Smiod -g) chgrpcmd="$chgrpprog $2" 108*150b7e42Smiod shift 109*150b7e42Smiod shift 110*150b7e42Smiod continue;; 111*150b7e42Smiod 112*150b7e42Smiod --help) echo "$usage"; exit $?;; 113*150b7e42Smiod 114321fbaf8Sespie -m) chmodcmd="$chmodprog $2" 115321fbaf8Sespie shift 116321fbaf8Sespie shift 117321fbaf8Sespie continue;; 118321fbaf8Sespie 119321fbaf8Sespie -o) chowncmd="$chownprog $2" 120321fbaf8Sespie shift 121321fbaf8Sespie shift 122321fbaf8Sespie continue;; 123321fbaf8Sespie 124*150b7e42Smiod -s) stripcmd=$stripprog 125*150b7e42Smiod shift 126*150b7e42Smiod continue;; 127*150b7e42Smiod 128*150b7e42Smiod -t) dstarg=$2 129321fbaf8Sespie shift 130321fbaf8Sespie shift 131321fbaf8Sespie continue;; 132321fbaf8Sespie 133*150b7e42Smiod -T) no_target_directory=true 134321fbaf8Sespie shift 135321fbaf8Sespie continue;; 136321fbaf8Sespie 137*150b7e42Smiod --version) echo "$0 $scriptversion"; exit $?;; 138321fbaf8Sespie 139*150b7e42Smiod *) # When -d is used, all remaining arguments are directories to create. 140*150b7e42Smiod # When -t is used, the destination is already specified. 141*150b7e42Smiod test -n "$dir_arg$dstarg" && break 142*150b7e42Smiod # Otherwise, the last argument is the destination. Remove it from $@. 143*150b7e42Smiod for arg 144*150b7e42Smiod do 145*150b7e42Smiod if test -n "$dstarg"; then 146*150b7e42Smiod # $@ is not empty: it contains at least $arg. 147*150b7e42Smiod set fnord "$@" "$dstarg" 148*150b7e42Smiod shift # fnord 149321fbaf8Sespie fi 150*150b7e42Smiod shift # arg 151*150b7e42Smiod dstarg=$arg 152*150b7e42Smiod done 153*150b7e42Smiod break;; 154321fbaf8Sespie esac 155321fbaf8Sespiedone 156321fbaf8Sespie 157*150b7e42Smiodif test -z "$1"; then 158*150b7e42Smiod if test -z "$dir_arg"; then 159*150b7e42Smiod echo "$0: no input file specified." >&2 160321fbaf8Sespie exit 1 161*150b7e42Smiod fi 162*150b7e42Smiod # It's OK to call `install-sh -d' without argument. 163*150b7e42Smiod # This can happen when creating conditional directories. 164*150b7e42Smiod exit 0 165321fbaf8Sespiefi 166321fbaf8Sespie 167*150b7e42Smiodfor src 168*150b7e42Smioddo 169*150b7e42Smiod # Protect names starting with `-'. 170*150b7e42Smiod case $src in 171*150b7e42Smiod -*) src=./$src ;; 172*150b7e42Smiod esac 173*150b7e42Smiod 174*150b7e42Smiod if test -n "$dir_arg"; then 175321fbaf8Sespie dst=$src 176*150b7e42Smiod src= 177321fbaf8Sespie 178*150b7e42Smiod if test -d "$dst"; then 179*150b7e42Smiod mkdircmd=: 180*150b7e42Smiod chmodcmd= 181321fbaf8Sespie else 182*150b7e42Smiod mkdircmd=$mkdirprog 183321fbaf8Sespie fi 184321fbaf8Sespie else 185*150b7e42Smiod # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 186321fbaf8Sespie # might cause directories to be created, which would be especially bad 187321fbaf8Sespie # if $src (and thus $dsttmp) contains '*'. 188*150b7e42Smiod if test ! -f "$src" && test ! -d "$src"; then 189*150b7e42Smiod echo "$0: $src does not exist." >&2 190321fbaf8Sespie exit 1 191321fbaf8Sespie fi 192321fbaf8Sespie 193*150b7e42Smiod if test -z "$dstarg"; then 194*150b7e42Smiod echo "$0: no destination specified." >&2 195321fbaf8Sespie exit 1 196321fbaf8Sespie fi 197321fbaf8Sespie 198*150b7e42Smiod dst=$dstarg 199*150b7e42Smiod # Protect names starting with `-'. 200*150b7e42Smiod case $dst in 201*150b7e42Smiod -*) dst=./$dst ;; 202*150b7e42Smiod esac 203321fbaf8Sespie 204*150b7e42Smiod # If destination is a directory, append the input filename; won't work 205*150b7e42Smiod # if double slashes aren't ignored. 206*150b7e42Smiod if test -d "$dst"; then 207*150b7e42Smiod if test -n "$no_target_directory"; then 208*150b7e42Smiod echo "$0: $dstarg: Is a directory" >&2 209*150b7e42Smiod exit 1 210*150b7e42Smiod fi 211*150b7e42Smiod dst=$dst/`basename "$src"` 212321fbaf8Sespie fi 213321fbaf8Sespie fi 214321fbaf8Sespie 215*150b7e42Smiod # This sed command emulates the dirname command. 216*150b7e42Smiod dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 217321fbaf8Sespie 218321fbaf8Sespie # Make sure that the destination directory exists. 219321fbaf8Sespie 220321fbaf8Sespie # Skip lots of stat calls in the usual case. 221*150b7e42Smiod if test ! -d "$dstdir"; then 222321fbaf8Sespie defaultIFS=' 223321fbaf8Sespie ' 224*150b7e42Smiod IFS="${IFS-$defaultIFS}" 225321fbaf8Sespie 226*150b7e42Smiod oIFS=$IFS 227321fbaf8Sespie # Some sh's can't handle IFS=/ for some reason. 228321fbaf8Sespie IFS='%' 229*150b7e42Smiod set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 230321fbaf8Sespie shift 231*150b7e42Smiod IFS=$oIFS 232321fbaf8Sespie 233*150b7e42Smiod pathcomp= 234*150b7e42Smiod 235*150b7e42Smiod while test $# -ne 0 ; do 236*150b7e42Smiod pathcomp=$pathcomp$1 237*150b7e42Smiod shift 238*150b7e42Smiod if test ! -d "$pathcomp"; then 239*150b7e42Smiod $mkdirprog "$pathcomp" 240*150b7e42Smiod # mkdir can fail with a `File exist' error in case several 241*150b7e42Smiod # install-sh are creating the directory concurrently. This 242*150b7e42Smiod # is OK. 243*150b7e42Smiod test -d "$pathcomp" || exit 244321fbaf8Sespie fi 245*150b7e42Smiod pathcomp=$pathcomp/ 246321fbaf8Sespie done 247321fbaf8Sespie fi 248321fbaf8Sespie 249*150b7e42Smiod if test -n "$dir_arg"; then 250*150b7e42Smiod $doit $mkdircmd "$dst" \ 251*150b7e42Smiod && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 252*150b7e42Smiod && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 253*150b7e42Smiod && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 254*150b7e42Smiod && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 255321fbaf8Sespie 256321fbaf8Sespie else 257*150b7e42Smiod dstfile=`basename "$dst"` 258321fbaf8Sespie 259*150b7e42Smiod # Make a couple of temp file names in the proper directory. 260*150b7e42Smiod dsttmp=$dstdir/_inst.$$_ 261*150b7e42Smiod rmtmp=$dstdir/_rm.$$_ 262321fbaf8Sespie 263*150b7e42Smiod # Trap to clean up those temp files at exit. 264*150b7e42Smiod trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 265*150b7e42Smiod trap '(exit $?); exit' 1 2 13 15 266321fbaf8Sespie 267*150b7e42Smiod # Copy the file name to the temp name. 268*150b7e42Smiod $doit $cpprog "$src" "$dsttmp" && 269321fbaf8Sespie 270*150b7e42Smiod # and set any options; do chmod last to preserve setuid bits. 271*150b7e42Smiod # 272321fbaf8Sespie # If any of these fail, we abort the whole thing. If we want to 273321fbaf8Sespie # ignore errors from any of these, just make sure not to ignore 274*150b7e42Smiod # errors from the above "$doit $cpprog $src $dsttmp" command. 275*150b7e42Smiod # 276*150b7e42Smiod { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 277*150b7e42Smiod && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 278*150b7e42Smiod && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 279*150b7e42Smiod && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 280321fbaf8Sespie 281321fbaf8Sespie # Now rename the file to the real destination. 282*150b7e42Smiod { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 283*150b7e42Smiod || { 284*150b7e42Smiod # The rename failed, perhaps because mv can't rename something else 285*150b7e42Smiod # to itself, or perhaps because mv is so ancient that it does not 286*150b7e42Smiod # support -f. 287321fbaf8Sespie 288*150b7e42Smiod # Now remove or move aside any old file at destination location. 289*150b7e42Smiod # We try this two ways since rm can't unlink itself on some 290*150b7e42Smiod # systems and the destination file might be busy for other 291*150b7e42Smiod # reasons. In this case, the final cleanup might fail but the new 292*150b7e42Smiod # file should still install successfully. 293*150b7e42Smiod { 294*150b7e42Smiod if test -f "$dstdir/$dstfile"; then 295*150b7e42Smiod $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 296*150b7e42Smiod || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 297*150b7e42Smiod || { 298*150b7e42Smiod echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 299*150b7e42Smiod (exit 1); exit 1 300*150b7e42Smiod } 301*150b7e42Smiod else 302*150b7e42Smiod : 303*150b7e42Smiod fi 304*150b7e42Smiod } && 305321fbaf8Sespie 306*150b7e42Smiod # Now rename the file to the real destination. 307*150b7e42Smiod $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 308*150b7e42Smiod } 309*150b7e42Smiod } 310*150b7e42Smiod fi || { (exit 1); exit 1; } 311*150b7e42Smioddone 312321fbaf8Sespie 313*150b7e42Smiod# The final little trick to "correctly" pass the exit status to the exit trap. 314*150b7e42Smiod{ 315*150b7e42Smiod (exit 0); exit 0 316*150b7e42Smiod} 317321fbaf8Sespie 318*150b7e42Smiod# Local variables: 319*150b7e42Smiod# eval: (add-hook 'write-file-hooks 'time-stamp) 320*150b7e42Smiod# time-stamp-start: "scriptversion=" 321*150b7e42Smiod# time-stamp-format: "%:y-%02m-%02d.%02H" 322*150b7e42Smiod# time-stamp-end: "$" 323*150b7e42Smiod# End: 324