install-sh revision 174832
1117610Sdes#!/bin/sh 2117610Sdes# install - install a program, script, or datafile 3141098Sdes 4174832Sdesscriptversion=2005-05-14.22 5141098Sdes 6141098Sdes# This originates from X11R5 (mit/util/scripts/install.sh), which was 7141098Sdes# later released in X11R6 (xc/config/util/install.sh) with the 8141098Sdes# following copyright and license. 9117610Sdes# 10141098Sdes# Copyright (C) 1994 X Consortium 11117610Sdes# 12141098Sdes# Permission is hereby granted, free of charge, to any person obtaining a copy 13141098Sdes# of this software and associated documentation files (the "Software"), to 14141098Sdes# deal in the Software without restriction, including without limitation the 15141098Sdes# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16141098Sdes# sell copies of the Software, and to permit persons to whom the Software is 17141098Sdes# furnished to do so, subject to the following conditions: 18117610Sdes# 19141098Sdes# The above copyright notice and this permission notice shall be included in 20141098Sdes# all copies or substantial portions of the Software. 21141098Sdes# 22141098Sdes# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23141098Sdes# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24141098Sdes# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25141098Sdes# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26141098Sdes# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27141098Sdes# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28141098Sdes# 29141098Sdes# Except as contained in this notice, the name of the X Consortium shall not 30141098Sdes# be used in advertising or otherwise to promote the sale, use or other deal- 31141098Sdes# ings in this Software without prior written authorization from the X Consor- 32141098Sdes# tium. 33141098Sdes# 34141098Sdes# 35141098Sdes# FSF changes to this file are in the public domain. 36141098Sdes# 37117610Sdes# Calling this script install-sh is preferred over install.sh, to prevent 38117610Sdes# `make' implicit rules from creating a file called install from it 39117610Sdes# when there is no Makefile. 40117610Sdes# 41117610Sdes# This script is compatible with the BSD install script, but was written 42117610Sdes# from scratch. It can only install one file at a time, a restriction 43117610Sdes# shared with many OS's install programs. 44117610Sdes 45117610Sdes# set DOITPROG to echo to test this script 46117610Sdes 47117610Sdes# Don't use :- since 4.3BSD and earlier shells don't like it. 48117610Sdesdoit="${DOITPROG-}" 49117610Sdes 50117610Sdes# put in absolute paths if you don't have them in your path; or use env. vars. 51117610Sdes 52117610Sdesmvprog="${MVPROG-mv}" 53117610Sdescpprog="${CPPROG-cp}" 54117610Sdeschmodprog="${CHMODPROG-chmod}" 55117610Sdeschownprog="${CHOWNPROG-chown}" 56117610Sdeschgrpprog="${CHGRPPROG-chgrp}" 57117610Sdesstripprog="${STRIPPROG-strip}" 58117610Sdesrmprog="${RMPROG-rm}" 59117610Sdesmkdirprog="${MKDIRPROG-mkdir}" 60117610Sdes 61117610Sdeschmodcmd="$chmodprog 0755" 62141098Sdeschowncmd= 63141098Sdeschgrpcmd= 64141098Sdesstripcmd= 65117610Sdesrmcmd="$rmprog -f" 66117610Sdesmvcmd="$mvprog" 67141098Sdessrc= 68141098Sdesdst= 69141098Sdesdir_arg= 70174832Sdesdstarg= 71174832Sdesno_target_directory= 72117610Sdes 73174832Sdesusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 74141098Sdes or: $0 [OPTION]... SRCFILES... DIRECTORY 75174832Sdes or: $0 [OPTION]... -t DIRECTORY SRCFILES... 76174832Sdes or: $0 [OPTION]... -d DIRECTORIES... 77117610Sdes 78174832SdesIn the 1st form, copy SRCFILE to DSTFILE. 79174832SdesIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 80174832SdesIn the 4th, create DIRECTORIES. 81117610Sdes 82141098SdesOptions: 83174832Sdes-c (ignored) 84141098Sdes-d create directories instead of installing files. 85174832Sdes-g GROUP $chgrpprog installed files to GROUP. 86174832Sdes-m MODE $chmodprog installed files to MODE. 87174832Sdes-o USER $chownprog installed files to USER. 88174832Sdes-s $stripprog installed files. 89174832Sdes-t DIRECTORY install into DIRECTORY. 90174832Sdes-T report an error if DSTFILE is a directory. 91141098Sdes--help display this help and exit. 92141098Sdes--version display version info and exit. 93117610Sdes 94141098SdesEnvironment variables override the default commands: 95141098Sdes CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 96141098Sdes" 97117610Sdes 98141098Sdeswhile test -n "$1"; do 99141098Sdes case $1 in 100174832Sdes -c) shift 101141098Sdes continue;; 102117610Sdes 103141098Sdes -d) dir_arg=true 104141098Sdes shift 105141098Sdes continue;; 106117610Sdes 107141098Sdes -g) chgrpcmd="$chgrpprog $2" 108141098Sdes shift 109141098Sdes shift 110141098Sdes continue;; 111117610Sdes 112174832Sdes --help) echo "$usage"; exit $?;; 113117610Sdes 114141098Sdes -m) chmodcmd="$chmodprog $2" 115141098Sdes shift 116141098Sdes shift 117141098Sdes continue;; 118117610Sdes 119141098Sdes -o) chowncmd="$chownprog $2" 120141098Sdes shift 121141098Sdes shift 122141098Sdes continue;; 123117610Sdes 124141098Sdes -s) stripcmd=$stripprog 125141098Sdes shift 126141098Sdes continue;; 127117610Sdes 128174832Sdes -t) dstarg=$2 129174832Sdes shift 130174832Sdes shift 131174832Sdes continue;; 132117610Sdes 133174832Sdes -T) no_target_directory=true 134174832Sdes shift 135174832Sdes continue;; 136117610Sdes 137174832Sdes --version) echo "$0 $scriptversion"; exit $?;; 138174832Sdes 139141098Sdes *) # When -d is used, all remaining arguments are directories to create. 140174832Sdes # When -t is used, the destination is already specified. 141174832Sdes test -n "$dir_arg$dstarg" && break 142141098Sdes # Otherwise, the last argument is the destination. Remove it from $@. 143141098Sdes for arg 144141098Sdes do 145141098Sdes if test -n "$dstarg"; then 146141098Sdes # $@ is not empty: it contains at least $arg. 147141098Sdes set fnord "$@" "$dstarg" 148141098Sdes shift # fnord 149141098Sdes fi 150141098Sdes shift # arg 151141098Sdes dstarg=$arg 152141098Sdes done 153141098Sdes break;; 154141098Sdes esac 155141098Sdesdone 156141098Sdes 157141098Sdesif test -z "$1"; then 158141098Sdes if test -z "$dir_arg"; then 159141098Sdes echo "$0: no input file specified." >&2 160141098Sdes exit 1 161141098Sdes fi 162141098Sdes # It's OK to call `install-sh -d' without argument. 163141098Sdes # This can happen when creating conditional directories. 164141098Sdes exit 0 165117610Sdesfi 166117610Sdes 167141098Sdesfor src 168141098Sdesdo 169141098Sdes # Protect names starting with `-'. 170141098Sdes case $src in 171141098Sdes -*) src=./$src ;; 172141098Sdes esac 173117610Sdes 174141098Sdes if test -n "$dir_arg"; then 175141098Sdes dst=$src 176141098Sdes src= 177117610Sdes 178141098Sdes if test -d "$dst"; then 179174832Sdes mkdircmd=: 180141098Sdes chmodcmd= 181141098Sdes else 182174832Sdes mkdircmd=$mkdirprog 183141098Sdes fi 184141098Sdes else 185174832Sdes # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 186141098Sdes # might cause directories to be created, which would be especially bad 187141098Sdes # if $src (and thus $dsttmp) contains '*'. 188141098Sdes if test ! -f "$src" && test ! -d "$src"; then 189141098Sdes echo "$0: $src does not exist." >&2 190141098Sdes exit 1 191141098Sdes fi 192117610Sdes 193141098Sdes if test -z "$dstarg"; then 194141098Sdes echo "$0: no destination specified." >&2 195141098Sdes exit 1 196141098Sdes fi 197117610Sdes 198141098Sdes dst=$dstarg 199141098Sdes # Protect names starting with `-'. 200141098Sdes case $dst in 201141098Sdes -*) dst=./$dst ;; 202141098Sdes esac 203117610Sdes 204141098Sdes # If destination is a directory, append the input filename; won't work 205141098Sdes # if double slashes aren't ignored. 206141098Sdes if test -d "$dst"; then 207174832Sdes if test -n "$no_target_directory"; then 208174832Sdes echo "$0: $dstarg: Is a directory" >&2 209174832Sdes exit 1 210174832Sdes fi 211141098Sdes dst=$dst/`basename "$src"` 212141098Sdes fi 213141098Sdes fi 214117610Sdes 215141098Sdes # This sed command emulates the dirname command. 216174832Sdes dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 217117610Sdes 218141098Sdes # Make sure that the destination directory exists. 219117610Sdes 220141098Sdes # Skip lots of stat calls in the usual case. 221141098Sdes if test ! -d "$dstdir"; then 222141098Sdes defaultIFS=' 223141098Sdes ' 224141098Sdes IFS="${IFS-$defaultIFS}" 225117610Sdes 226141098Sdes oIFS=$IFS 227141098Sdes # Some sh's can't handle IFS=/ for some reason. 228141098Sdes IFS='%' 229174832Sdes set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 230174832Sdes shift 231141098Sdes IFS=$oIFS 232117610Sdes 233141098Sdes pathcomp= 234117610Sdes 235141098Sdes while test $# -ne 0 ; do 236141098Sdes pathcomp=$pathcomp$1 237141098Sdes shift 238141098Sdes if test ! -d "$pathcomp"; then 239174832Sdes $mkdirprog "$pathcomp" 240141098Sdes # mkdir can fail with a `File exist' error in case several 241141098Sdes # install-sh are creating the directory concurrently. This 242141098Sdes # is OK. 243174832Sdes test -d "$pathcomp" || exit 244141098Sdes fi 245141098Sdes pathcomp=$pathcomp/ 246141098Sdes done 247141098Sdes fi 248117610Sdes 249141098Sdes if test -n "$dir_arg"; then 250174832Sdes $doit $mkdircmd "$dst" \ 251141098Sdes && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 252141098Sdes && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 253141098Sdes && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 254141098Sdes && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 255117610Sdes 256141098Sdes else 257174832Sdes dstfile=`basename "$dst"` 258117610Sdes 259141098Sdes # Make a couple of temp file names in the proper directory. 260141098Sdes dsttmp=$dstdir/_inst.$$_ 261141098Sdes rmtmp=$dstdir/_rm.$$_ 262117610Sdes 263141098Sdes # Trap to clean up those temp files at exit. 264174832Sdes trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 265141098Sdes trap '(exit $?); exit' 1 2 13 15 266117610Sdes 267174832Sdes # Copy the file name to the temp name. 268174832Sdes $doit $cpprog "$src" "$dsttmp" && 269117610Sdes 270141098Sdes # and set any options; do chmod last to preserve setuid bits. 271141098Sdes # 272141098Sdes # If any of these fail, we abort the whole thing. If we want to 273141098Sdes # ignore errors from any of these, just make sure not to ignore 274174832Sdes # errors from the above "$doit $cpprog $src $dsttmp" command. 275141098Sdes # 276141098Sdes { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 277141098Sdes && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 278141098Sdes && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 279141098Sdes && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 280117610Sdes 281141098Sdes # Now rename the file to the real destination. 282141098Sdes { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 283141098Sdes || { 284141098Sdes # The rename failed, perhaps because mv can't rename something else 285141098Sdes # to itself, or perhaps because mv is so ancient that it does not 286141098Sdes # support -f. 287117610Sdes 288141098Sdes # Now remove or move aside any old file at destination location. 289141098Sdes # We try this two ways since rm can't unlink itself on some 290141098Sdes # systems and the destination file might be busy for other 291141098Sdes # reasons. In this case, the final cleanup might fail but the new 292141098Sdes # file should still install successfully. 293141098Sdes { 294141098Sdes if test -f "$dstdir/$dstfile"; then 295141098Sdes $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 296141098Sdes || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 297141098Sdes || { 298141098Sdes echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 299174832Sdes (exit 1); exit 1 300141098Sdes } 301141098Sdes else 302141098Sdes : 303141098Sdes fi 304141098Sdes } && 305117610Sdes 306141098Sdes # Now rename the file to the real destination. 307141098Sdes $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 308141098Sdes } 309141098Sdes } 310174832Sdes fi || { (exit 1); exit 1; } 311141098Sdesdone 312117610Sdes 313141098Sdes# The final little trick to "correctly" pass the exit status to the exit trap. 314141098Sdes{ 315174832Sdes (exit 0); exit 0 316141098Sdes} 317117610Sdes 318141098Sdes# Local variables: 319141098Sdes# eval: (add-hook 'write-file-hooks 'time-stamp) 320141098Sdes# time-stamp-start: "scriptversion=" 321141098Sdes# time-stamp-format: "%:y-%02m-%02d.%02H" 322141098Sdes# time-stamp-end: "$" 323141098Sdes# End: 324