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