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