install-sh revision 91a17321
191a17321Smrg#!/bin/sh 291a17321Smrg# install - install a program, script, or datafile 391a17321Smrg 491a17321Smrgscriptversion=2005-05-14.22 591a17321Smrg 691a17321Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 791a17321Smrg# later released in X11R6 (xc/config/util/install.sh) with the 891a17321Smrg# following copyright and license. 991a17321Smrg# 1091a17321Smrg# Copyright (C) 1994 X Consortium 1191a17321Smrg# 1291a17321Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1391a17321Smrg# of this software and associated documentation files (the "Software"), to 1491a17321Smrg# deal in the Software without restriction, including without limitation the 1591a17321Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1691a17321Smrg# sell copies of the Software, and to permit persons to whom the Software is 1791a17321Smrg# furnished to do so, subject to the following conditions: 1891a17321Smrg# 1991a17321Smrg# The above copyright notice and this permission notice shall be included in 2091a17321Smrg# all copies or substantial portions of the Software. 2191a17321Smrg# 2291a17321Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2391a17321Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2491a17321Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2591a17321Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2691a17321Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2791a17321Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2891a17321Smrg# 2991a17321Smrg# Except as contained in this notice, the name of the X Consortium shall not 3091a17321Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3191a17321Smrg# ings in this Software without prior written authorization from the X Consor- 3291a17321Smrg# tium. 3391a17321Smrg# 3491a17321Smrg# 3591a17321Smrg# FSF changes to this file are in the public domain. 3691a17321Smrg# 3791a17321Smrg# Calling this script install-sh is preferred over install.sh, to prevent 3891a17321Smrg# `make' implicit rules from creating a file called install from it 3991a17321Smrg# when there is no Makefile. 4091a17321Smrg# 4191a17321Smrg# This script is compatible with the BSD install script, but was written 4291a17321Smrg# from scratch. It can only install one file at a time, a restriction 4391a17321Smrg# shared with many OS's install programs. 4491a17321Smrg 4591a17321Smrg# set DOITPROG to echo to test this script 4691a17321Smrg 4791a17321Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 4891a17321Smrgdoit="${DOITPROG-}" 4991a17321Smrg 5091a17321Smrg# put in absolute paths if you don't have them in your path; or use env. vars. 5191a17321Smrg 5291a17321Smrgmvprog="${MVPROG-mv}" 5391a17321Smrgcpprog="${CPPROG-cp}" 5491a17321Smrgchmodprog="${CHMODPROG-chmod}" 5591a17321Smrgchownprog="${CHOWNPROG-chown}" 5691a17321Smrgchgrpprog="${CHGRPPROG-chgrp}" 5791a17321Smrgstripprog="${STRIPPROG-strip}" 5891a17321Smrgrmprog="${RMPROG-rm}" 5991a17321Smrgmkdirprog="${MKDIRPROG-mkdir}" 6091a17321Smrg 6191a17321Smrgchmodcmd="$chmodprog 0755" 6291a17321Smrgchowncmd= 6391a17321Smrgchgrpcmd= 6491a17321Smrgstripcmd= 6591a17321Smrgrmcmd="$rmprog -f" 6691a17321Smrgmvcmd="$mvprog" 6791a17321Smrgsrc= 6891a17321Smrgdst= 6991a17321Smrgdir_arg= 7091a17321Smrgdstarg= 7191a17321Smrgno_target_directory= 7291a17321Smrg 7391a17321Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 7491a17321Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 7591a17321Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 7691a17321Smrg or: $0 [OPTION]... -d DIRECTORIES... 7791a17321Smrg 7891a17321SmrgIn the 1st form, copy SRCFILE to DSTFILE. 7991a17321SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 8091a17321SmrgIn the 4th, create DIRECTORIES. 8191a17321Smrg 8291a17321SmrgOptions: 8391a17321Smrg-c (ignored) 8491a17321Smrg-d create directories instead of installing files. 8591a17321Smrg-g GROUP $chgrpprog installed files to GROUP. 8691a17321Smrg-m MODE $chmodprog installed files to MODE. 8791a17321Smrg-o USER $chownprog installed files to USER. 8891a17321Smrg-s $stripprog installed files. 8991a17321Smrg-t DIRECTORY install into DIRECTORY. 9091a17321Smrg-T report an error if DSTFILE is a directory. 9191a17321Smrg--help display this help and exit. 9291a17321Smrg--version display version info and exit. 9391a17321Smrg 9491a17321SmrgEnvironment variables override the default commands: 9591a17321Smrg CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 9691a17321Smrg" 9791a17321Smrg 9891a17321Smrgwhile test -n "$1"; do 9991a17321Smrg case $1 in 10091a17321Smrg -c) shift 10191a17321Smrg continue;; 10291a17321Smrg 10391a17321Smrg -d) dir_arg=true 10491a17321Smrg shift 10591a17321Smrg continue;; 10691a17321Smrg 10791a17321Smrg -g) chgrpcmd="$chgrpprog $2" 10891a17321Smrg shift 10991a17321Smrg shift 11091a17321Smrg continue;; 11191a17321Smrg 11291a17321Smrg --help) echo "$usage"; exit $?;; 11391a17321Smrg 11491a17321Smrg -m) chmodcmd="$chmodprog $2" 11591a17321Smrg shift 11691a17321Smrg shift 11791a17321Smrg continue;; 11891a17321Smrg 11991a17321Smrg -o) chowncmd="$chownprog $2" 12091a17321Smrg shift 12191a17321Smrg shift 12291a17321Smrg continue;; 12391a17321Smrg 12491a17321Smrg -s) stripcmd=$stripprog 12591a17321Smrg shift 12691a17321Smrg continue;; 12791a17321Smrg 12891a17321Smrg -t) dstarg=$2 12991a17321Smrg shift 13091a17321Smrg shift 13191a17321Smrg continue;; 13291a17321Smrg 13391a17321Smrg -T) no_target_directory=true 13491a17321Smrg shift 13591a17321Smrg continue;; 13691a17321Smrg 13791a17321Smrg --version) echo "$0 $scriptversion"; exit $?;; 13891a17321Smrg 13991a17321Smrg *) # When -d is used, all remaining arguments are directories to create. 14091a17321Smrg # When -t is used, the destination is already specified. 14191a17321Smrg test -n "$dir_arg$dstarg" && break 14291a17321Smrg # Otherwise, the last argument is the destination. Remove it from $@. 14391a17321Smrg for arg 14491a17321Smrg do 14591a17321Smrg if test -n "$dstarg"; then 14691a17321Smrg # $@ is not empty: it contains at least $arg. 14791a17321Smrg set fnord "$@" "$dstarg" 14891a17321Smrg shift # fnord 14991a17321Smrg fi 15091a17321Smrg shift # arg 15191a17321Smrg dstarg=$arg 15291a17321Smrg done 15391a17321Smrg break;; 15491a17321Smrg esac 15591a17321Smrgdone 15691a17321Smrg 15791a17321Smrgif test -z "$1"; then 15891a17321Smrg if test -z "$dir_arg"; then 15991a17321Smrg echo "$0: no input file specified." >&2 16091a17321Smrg exit 1 16191a17321Smrg fi 16291a17321Smrg # It's OK to call `install-sh -d' without argument. 16391a17321Smrg # This can happen when creating conditional directories. 16491a17321Smrg exit 0 16591a17321Smrgfi 16691a17321Smrg 16791a17321Smrgfor src 16891a17321Smrgdo 16991a17321Smrg # Protect names starting with `-'. 17091a17321Smrg case $src in 17191a17321Smrg -*) src=./$src ;; 17291a17321Smrg esac 17391a17321Smrg 17491a17321Smrg if test -n "$dir_arg"; then 17591a17321Smrg dst=$src 17691a17321Smrg src= 17791a17321Smrg 17891a17321Smrg if test -d "$dst"; then 17991a17321Smrg mkdircmd=: 18091a17321Smrg chmodcmd= 18191a17321Smrg else 18291a17321Smrg mkdircmd=$mkdirprog 18391a17321Smrg fi 18491a17321Smrg else 18591a17321Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 18691a17321Smrg # might cause directories to be created, which would be especially bad 18791a17321Smrg # if $src (and thus $dsttmp) contains '*'. 18891a17321Smrg if test ! -f "$src" && test ! -d "$src"; then 18991a17321Smrg echo "$0: $src does not exist." >&2 19091a17321Smrg exit 1 19191a17321Smrg fi 19291a17321Smrg 19391a17321Smrg if test -z "$dstarg"; then 19491a17321Smrg echo "$0: no destination specified." >&2 19591a17321Smrg exit 1 19691a17321Smrg fi 19791a17321Smrg 19891a17321Smrg dst=$dstarg 19991a17321Smrg # Protect names starting with `-'. 20091a17321Smrg case $dst in 20191a17321Smrg -*) dst=./$dst ;; 20291a17321Smrg esac 20391a17321Smrg 20491a17321Smrg # If destination is a directory, append the input filename; won't work 20591a17321Smrg # if double slashes aren't ignored. 20691a17321Smrg if test -d "$dst"; then 20791a17321Smrg if test -n "$no_target_directory"; then 20891a17321Smrg echo "$0: $dstarg: Is a directory" >&2 20991a17321Smrg exit 1 21091a17321Smrg fi 21191a17321Smrg dst=$dst/`basename "$src"` 21291a17321Smrg fi 21391a17321Smrg fi 21491a17321Smrg 21591a17321Smrg # This sed command emulates the dirname command. 21691a17321Smrg dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 21791a17321Smrg 21891a17321Smrg # Make sure that the destination directory exists. 21991a17321Smrg 22091a17321Smrg # Skip lots of stat calls in the usual case. 22191a17321Smrg if test ! -d "$dstdir"; then 22291a17321Smrg defaultIFS=' 22391a17321Smrg ' 22491a17321Smrg IFS="${IFS-$defaultIFS}" 22591a17321Smrg 22691a17321Smrg oIFS=$IFS 22791a17321Smrg # Some sh's can't handle IFS=/ for some reason. 22891a17321Smrg IFS='%' 22991a17321Smrg set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 23091a17321Smrg shift 23191a17321Smrg IFS=$oIFS 23291a17321Smrg 23391a17321Smrg pathcomp= 23491a17321Smrg 23591a17321Smrg while test $# -ne 0 ; do 23691a17321Smrg pathcomp=$pathcomp$1 23791a17321Smrg shift 23891a17321Smrg if test ! -d "$pathcomp"; then 23991a17321Smrg $mkdirprog "$pathcomp" 24091a17321Smrg # mkdir can fail with a `File exist' error in case several 24191a17321Smrg # install-sh are creating the directory concurrently. This 24291a17321Smrg # is OK. 24391a17321Smrg test -d "$pathcomp" || exit 24491a17321Smrg fi 24591a17321Smrg pathcomp=$pathcomp/ 24691a17321Smrg done 24791a17321Smrg fi 24891a17321Smrg 24991a17321Smrg if test -n "$dir_arg"; then 25091a17321Smrg $doit $mkdircmd "$dst" \ 25191a17321Smrg && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 25291a17321Smrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 25391a17321Smrg && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 25491a17321Smrg && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 25591a17321Smrg 25691a17321Smrg else 25791a17321Smrg dstfile=`basename "$dst"` 25891a17321Smrg 25991a17321Smrg # Make a couple of temp file names in the proper directory. 26091a17321Smrg dsttmp=$dstdir/_inst.$$_ 26191a17321Smrg rmtmp=$dstdir/_rm.$$_ 26291a17321Smrg 26391a17321Smrg # Trap to clean up those temp files at exit. 26491a17321Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 26591a17321Smrg trap '(exit $?); exit' 1 2 13 15 26691a17321Smrg 26791a17321Smrg # Copy the file name to the temp name. 26891a17321Smrg $doit $cpprog "$src" "$dsttmp" && 26991a17321Smrg 27091a17321Smrg # and set any options; do chmod last to preserve setuid bits. 27191a17321Smrg # 27291a17321Smrg # If any of these fail, we abort the whole thing. If we want to 27391a17321Smrg # ignore errors from any of these, just make sure not to ignore 27491a17321Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 27591a17321Smrg # 27691a17321Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 27791a17321Smrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 27891a17321Smrg && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 27991a17321Smrg && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 28091a17321Smrg 28191a17321Smrg # Now rename the file to the real destination. 28291a17321Smrg { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 28391a17321Smrg || { 28491a17321Smrg # The rename failed, perhaps because mv can't rename something else 28591a17321Smrg # to itself, or perhaps because mv is so ancient that it does not 28691a17321Smrg # support -f. 28791a17321Smrg 28891a17321Smrg # Now remove or move aside any old file at destination location. 28991a17321Smrg # We try this two ways since rm can't unlink itself on some 29091a17321Smrg # systems and the destination file might be busy for other 29191a17321Smrg # reasons. In this case, the final cleanup might fail but the new 29291a17321Smrg # file should still install successfully. 29391a17321Smrg { 29491a17321Smrg if test -f "$dstdir/$dstfile"; then 29591a17321Smrg $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 29691a17321Smrg || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 29791a17321Smrg || { 29891a17321Smrg echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 29991a17321Smrg (exit 1); exit 1 30091a17321Smrg } 30191a17321Smrg else 30291a17321Smrg : 30391a17321Smrg fi 30491a17321Smrg } && 30591a17321Smrg 30691a17321Smrg # Now rename the file to the real destination. 30791a17321Smrg $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 30891a17321Smrg } 30991a17321Smrg } 31091a17321Smrg fi || { (exit 1); exit 1; } 31191a17321Smrgdone 31291a17321Smrg 31391a17321Smrg# The final little trick to "correctly" pass the exit status to the exit trap. 31491a17321Smrg{ 31591a17321Smrg (exit 0); exit 0 31691a17321Smrg} 31791a17321Smrg 31891a17321Smrg# Local variables: 31991a17321Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 32091a17321Smrg# time-stamp-start: "scriptversion=" 32191a17321Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 32291a17321Smrg# time-stamp-end: "$" 32391a17321Smrg# End: 324