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