install-sh revision 76888252
176888252Smrg#!/bin/sh 276888252Smrg# install - install a program, script, or datafile 376888252Smrg 476888252Smrgscriptversion=2005-05-14.22 576888252Smrg 676888252Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 776888252Smrg# later released in X11R6 (xc/config/util/install.sh) with the 876888252Smrg# following copyright and license. 976888252Smrg# 1076888252Smrg# Copyright (C) 1994 X Consortium 1176888252Smrg# 1276888252Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1376888252Smrg# of this software and associated documentation files (the "Software"), to 1476888252Smrg# deal in the Software without restriction, including without limitation the 1576888252Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1676888252Smrg# sell copies of the Software, and to permit persons to whom the Software is 1776888252Smrg# furnished to do so, subject to the following conditions: 1876888252Smrg# 1976888252Smrg# The above copyright notice and this permission notice shall be included in 2076888252Smrg# all copies or substantial portions of the Software. 2176888252Smrg# 2276888252Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2376888252Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2476888252Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2576888252Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2676888252Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2776888252Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2876888252Smrg# 2976888252Smrg# Except as contained in this notice, the name of the X Consortium shall not 3076888252Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3176888252Smrg# ings in this Software without prior written authorization from the X Consor- 3276888252Smrg# tium. 3376888252Smrg# 3476888252Smrg# 3576888252Smrg# FSF changes to this file are in the public domain. 3676888252Smrg# 3776888252Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3876888252Smrg# `make' implicit rules from creating a file called install from it 3976888252Smrg# when there is no Makefile. 4076888252Smrg# 4176888252Smrg# This script is compatible with the BSD install script, but was written 4276888252Smrg# from scratch. It can only install one file at a time, a restriction 4376888252Smrg# shared with many OS's install programs. 4476888252Smrg 4576888252Smrg# set DOITPROG to echo to test this script 4676888252Smrg 4776888252Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 4876888252Smrgdoit="${DOITPROG-}" 4976888252Smrg 5076888252Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 5176888252Smrg 5276888252Smrgmvprog="${MVPROG-mv}" 5376888252Smrgcpprog="${CPPROG-cp}" 5476888252Smrgchmodprog="${CHMODPROG-chmod}" 5576888252Smrgchownprog="${CHOWNPROG-chown}" 5676888252Smrgchgrpprog="${CHGRPPROG-chgrp}" 5776888252Smrgstripprog="${STRIPPROG-strip}" 5876888252Smrgrmprog="${RMPROG-rm}" 5976888252Smrgmkdirprog="${MKDIRPROG-mkdir}" 6076888252Smrg 6176888252Smrgchmodcmd="$chmodprog 0755" 6276888252Smrgchowncmd= 6376888252Smrgchgrpcmd= 6476888252Smrgstripcmd= 6576888252Smrgrmcmd="$rmprog -f" 6676888252Smrgmvcmd="$mvprog" 6776888252Smrgsrc= 6876888252Smrgdst= 6976888252Smrgdir_arg= 7076888252Smrgdstarg= 7176888252Smrgno_target_directory= 7276888252Smrg 7376888252Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 7476888252Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 7576888252Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 7676888252Smrg or: $0 [OPTION]... -d DIRECTORIES... 7776888252Smrg 7876888252SmrgIn the 1st form, copy SRCFILE to DSTFILE. 7976888252SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 8076888252SmrgIn the 4th, create DIRECTORIES. 8176888252Smrg 8276888252SmrgOptions: 8376888252Smrg-c (ignored) 8476888252Smrg-d create directories instead of installing files. 8576888252Smrg-g GROUP $chgrpprog installed files to GROUP. 8676888252Smrg-m MODE $chmodprog installed files to MODE. 8776888252Smrg-o USER $chownprog installed files to USER. 8876888252Smrg-s $stripprog installed files. 8976888252Smrg-t DIRECTORY install into DIRECTORY. 9076888252Smrg-T report an error if DSTFILE is a directory. 9176888252Smrg--help display this help and exit. 9276888252Smrg--version display version info and exit. 9376888252Smrg 9476888252SmrgEnvironment variables override the default commands: 9576888252Smrg CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 9676888252Smrg" 9776888252Smrg 9876888252Smrgwhile test -n "$1"; do 9976888252Smrg case $1 in 10076888252Smrg -c) shift 10176888252Smrg continue;; 10276888252Smrg 10376888252Smrg -d) dir_arg=true 10476888252Smrg shift 10576888252Smrg continue;; 10676888252Smrg 10776888252Smrg -g) chgrpcmd="$chgrpprog $2" 10876888252Smrg shift 10976888252Smrg shift 11076888252Smrg continue;; 11176888252Smrg 11276888252Smrg --help) echo "$usage"; exit $?;; 11376888252Smrg 11476888252Smrg -m) chmodcmd="$chmodprog $2" 11576888252Smrg shift 11676888252Smrg shift 11776888252Smrg continue;; 11876888252Smrg 11976888252Smrg -o) chowncmd="$chownprog $2" 12076888252Smrg shift 12176888252Smrg shift 12276888252Smrg continue;; 12376888252Smrg 12476888252Smrg -s) stripcmd=$stripprog 12576888252Smrg shift 12676888252Smrg continue;; 12776888252Smrg 12876888252Smrg -t) dstarg=$2 12976888252Smrg shift 13076888252Smrg shift 13176888252Smrg continue;; 13276888252Smrg 13376888252Smrg -T) no_target_directory=true 13476888252Smrg shift 13576888252Smrg continue;; 13676888252Smrg 13776888252Smrg --version) echo "$0 $scriptversion"; exit $?;; 13876888252Smrg 13976888252Smrg *) # When -d is used, all remaining arguments are directories to create. 14076888252Smrg # When -t is used, the destination is already specified. 14176888252Smrg test -n "$dir_arg$dstarg" && break 14276888252Smrg # Otherwise, the last argument is the destination. Remove it from $@. 14376888252Smrg for arg 14476888252Smrg do 14576888252Smrg if test -n "$dstarg"; then 14676888252Smrg # $@ is not empty: it contains at least $arg. 14776888252Smrg set fnord "$@" "$dstarg" 14876888252Smrg shift # fnord 14976888252Smrg fi 15076888252Smrg shift # arg 15176888252Smrg dstarg=$arg 15276888252Smrg done 15376888252Smrg break;; 15476888252Smrg esac 15576888252Smrgdone 15676888252Smrg 15776888252Smrgif test -z "$1"; then 15876888252Smrg if test -z "$dir_arg"; then 15976888252Smrg echo "$0: no input file specified." >&2 16076888252Smrg exit 1 16176888252Smrg fi 16276888252Smrg # It's OK to call `install-sh -d' without argument. 16376888252Smrg # This can happen when creating conditional directories. 16476888252Smrg exit 0 16576888252Smrgfi 16676888252Smrg 16776888252Smrgfor src 16876888252Smrgdo 16976888252Smrg # Protect names starting with `-'. 17076888252Smrg case $src in 17176888252Smrg -*) src=./$src ;; 17276888252Smrg esac 17376888252Smrg 17476888252Smrg if test -n "$dir_arg"; then 17576888252Smrg dst=$src 17676888252Smrg src= 17776888252Smrg 17876888252Smrg if test -d "$dst"; then 17976888252Smrg mkdircmd=: 18076888252Smrg chmodcmd= 18176888252Smrg else 18276888252Smrg mkdircmd=$mkdirprog 18376888252Smrg fi 18476888252Smrg else 18576888252Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 18676888252Smrg # might cause directories to be created, which would be especially bad 18776888252Smrg # if $src (and thus $dsttmp) contains '*'. 18876888252Smrg if test ! -f "$src" && test ! -d "$src"; then 18976888252Smrg echo "$0: $src does not exist." >&2 19076888252Smrg exit 1 19176888252Smrg fi 19276888252Smrg 19376888252Smrg if test -z "$dstarg"; then 19476888252Smrg echo "$0: no destination specified." >&2 19576888252Smrg exit 1 19676888252Smrg fi 19776888252Smrg 19876888252Smrg dst=$dstarg 19976888252Smrg # Protect names starting with `-'. 20076888252Smrg case $dst in 20176888252Smrg -*) dst=./$dst ;; 20276888252Smrg esac 20376888252Smrg 20476888252Smrg # If destination is a directory, append the input filename; won't work 20576888252Smrg # if double slashes aren't ignored. 20676888252Smrg if test -d "$dst"; then 20776888252Smrg if test -n "$no_target_directory"; then 20876888252Smrg echo "$0: $dstarg: Is a directory" >&2 20976888252Smrg exit 1 21076888252Smrg fi 21176888252Smrg dst=$dst/`basename "$src"` 21276888252Smrg fi 21376888252Smrg fi 21476888252Smrg 21576888252Smrg # This sed command emulates the dirname command. 21676888252Smrg dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 21776888252Smrg 21876888252Smrg # Make sure that the destination directory exists. 21976888252Smrg 22076888252Smrg # Skip lots of stat calls in the usual case. 22176888252Smrg if test ! -d "$dstdir"; then 22276888252Smrg defaultIFS=' 22376888252Smrg ' 22476888252Smrg IFS="${IFS-$defaultIFS}" 22576888252Smrg 22676888252Smrg oIFS=$IFS 22776888252Smrg # Some sh's can't handle IFS=/ for some reason. 22876888252Smrg IFS='%' 22976888252Smrg set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 23076888252Smrg shift 23176888252Smrg IFS=$oIFS 23276888252Smrg 23376888252Smrg pathcomp= 23476888252Smrg 23576888252Smrg while test $# -ne 0 ; do 23676888252Smrg pathcomp=$pathcomp$1 23776888252Smrg shift 23876888252Smrg if test ! -d "$pathcomp"; then 23976888252Smrg $mkdirprog "$pathcomp" 24076888252Smrg # mkdir can fail with a `File exist' error in case several 24176888252Smrg # install-sh are creating the directory concurrently. This 24276888252Smrg # is OK. 24376888252Smrg test -d "$pathcomp" || exit 24476888252Smrg fi 24576888252Smrg pathcomp=$pathcomp/ 24676888252Smrg done 24776888252Smrg fi 24876888252Smrg 24976888252Smrg if test -n "$dir_arg"; then 25076888252Smrg $doit $mkdircmd "$dst" \ 25176888252Smrg && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 25276888252Smrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 25376888252Smrg && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 25476888252Smrg && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 25576888252Smrg 25676888252Smrg else 25776888252Smrg dstfile=`basename "$dst"` 25876888252Smrg 25976888252Smrg # Make a couple of temp file names in the proper directory. 26076888252Smrg dsttmp=$dstdir/_inst.$$_ 26176888252Smrg rmtmp=$dstdir/_rm.$$_ 26276888252Smrg 26376888252Smrg # Trap to clean up those temp files at exit. 26476888252Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 26576888252Smrg trap '(exit $?); exit' 1 2 13 15 26676888252Smrg 26776888252Smrg # Copy the file name to the temp name. 26876888252Smrg $doit $cpprog "$src" "$dsttmp" && 26976888252Smrg 27076888252Smrg # and set any options; do chmod last to preserve setuid bits. 27176888252Smrg # 27276888252Smrg # If any of these fail, we abort the whole thing. If we want to 27376888252Smrg # ignore errors from any of these, just make sure not to ignore 27476888252Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 27576888252Smrg # 27676888252Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 27776888252Smrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 27876888252Smrg && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 27976888252Smrg && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 28076888252Smrg 28176888252Smrg # Now rename the file to the real destination. 28276888252Smrg { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 28376888252Smrg || { 28476888252Smrg # The rename failed, perhaps because mv can't rename something else 28576888252Smrg # to itself, or perhaps because mv is so ancient that it does not 28676888252Smrg # support -f. 28776888252Smrg 28876888252Smrg # Now remove or move aside any old file at destination location. 28976888252Smrg # We try this two ways since rm can't unlink itself on some 29076888252Smrg # systems and the destination file might be busy for other 29176888252Smrg # reasons. In this case, the final cleanup might fail but the new 29276888252Smrg # file should still install successfully. 29376888252Smrg { 29476888252Smrg if test -f "$dstdir/$dstfile"; then 29576888252Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 29676888252Smrg || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 29776888252Smrg || { 29876888252Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 29976888252Smrg (exit 1); exit 1 30076888252Smrg } 30176888252Smrg else 30276888252Smrg : 30376888252Smrg fi 30476888252Smrg } && 30576888252Smrg 30676888252Smrg # Now rename the file to the real destination. 30776888252Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 30876888252Smrg } 30976888252Smrg } 31076888252Smrg fi || { (exit 1); exit 1; } 31176888252Smrgdone 31276888252Smrg 31376888252Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 31476888252Smrg{ 31576888252Smrg (exit 0); exit 0 31676888252Smrg} 31776888252Smrg 31876888252Smrg# Local variables: 31976888252Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 32076888252Smrg# time-stamp-start: "scriptversion=" 32176888252Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 32276888252Smrg# time-stamp-end: "$" 32376888252Smrg# End: 324