install-sh revision 3eed67fa
13eed67faSmbalmer#!/bin/sh 23eed67faSmbalmer# install - install a program, script, or datafile 33eed67faSmbalmer 43eed67faSmbalmerscriptversion=2005-05-14.22 53eed67faSmbalmer 63eed67faSmbalmer# This originates from X11R5 (mit/util/scripts/install.sh), which was 73eed67faSmbalmer# later released in X11R6 (xc/config/util/install.sh) with the 83eed67faSmbalmer# following copyright and license. 93eed67faSmbalmer# 103eed67faSmbalmer# Copyright (C) 1994 X Consortium 113eed67faSmbalmer# 123eed67faSmbalmer# Permission is hereby granted, free of charge, to any person obtaining a copy 133eed67faSmbalmer# of this software and associated documentation files (the "Software"), to 143eed67faSmbalmer# deal in the Software without restriction, including without limitation the 153eed67faSmbalmer# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 163eed67faSmbalmer# sell copies of the Software, and to permit persons to whom the Software is 173eed67faSmbalmer# furnished to do so, subject to the following conditions: 183eed67faSmbalmer# 193eed67faSmbalmer# The above copyright notice and this permission notice shall be included in 203eed67faSmbalmer# all copies or substantial portions of the Software. 213eed67faSmbalmer# 223eed67faSmbalmer# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 233eed67faSmbalmer# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 243eed67faSmbalmer# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 253eed67faSmbalmer# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 263eed67faSmbalmer# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 273eed67faSmbalmer# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 283eed67faSmbalmer# 293eed67faSmbalmer# Except as contained in this notice, the name of the X Consortium shall not 303eed67faSmbalmer# be used in advertising or otherwise to promote the sale, use or other deal- 313eed67faSmbalmer# ings in this Software without prior written authorization from the X Consor- 323eed67faSmbalmer# tium. 333eed67faSmbalmer# 343eed67faSmbalmer# 353eed67faSmbalmer# FSF changes to this file are in the public domain. 363eed67faSmbalmer# 373eed67faSmbalmer# Calling this script install-sh is preferred over install.sh, to prevent 383eed67faSmbalmer# `make' implicit rules from creating a file called install from it 393eed67faSmbalmer# when there is no Makefile. 403eed67faSmbalmer# 413eed67faSmbalmer# This script is compatible with the BSD install script, but was written 423eed67faSmbalmer# from scratch. It can only install one file at a time, a restriction 433eed67faSmbalmer# shared with many OS's install programs. 443eed67faSmbalmer 453eed67faSmbalmer# set DOITPROG to echo to test this script 463eed67faSmbalmer 473eed67faSmbalmer# Don't use :- since 4.3BSD and earlier shells don't like it. 483eed67faSmbalmerdoit="${DOITPROG-}" 493eed67faSmbalmer 503eed67faSmbalmer# put in absolute paths if you don't have them in your path; or use env. vars. 513eed67faSmbalmer 523eed67faSmbalmermvprog="${MVPROG-mv}" 533eed67faSmbalmercpprog="${CPPROG-cp}" 543eed67faSmbalmerchmodprog="${CHMODPROG-chmod}" 553eed67faSmbalmerchownprog="${CHOWNPROG-chown}" 563eed67faSmbalmerchgrpprog="${CHGRPPROG-chgrp}" 573eed67faSmbalmerstripprog="${STRIPPROG-strip}" 583eed67faSmbalmerrmprog="${RMPROG-rm}" 593eed67faSmbalmermkdirprog="${MKDIRPROG-mkdir}" 603eed67faSmbalmer 613eed67faSmbalmerchmodcmd="$chmodprog 0755" 623eed67faSmbalmerchowncmd= 633eed67faSmbalmerchgrpcmd= 643eed67faSmbalmerstripcmd= 653eed67faSmbalmerrmcmd="$rmprog -f" 663eed67faSmbalmermvcmd="$mvprog" 673eed67faSmbalmersrc= 683eed67faSmbalmerdst= 693eed67faSmbalmerdir_arg= 703eed67faSmbalmerdstarg= 713eed67faSmbalmerno_target_directory= 723eed67faSmbalmer 733eed67faSmbalmerusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 743eed67faSmbalmer or: $0 [OPTION]... SRCFILES... DIRECTORY 753eed67faSmbalmer or: $0 [OPTION]... -t DIRECTORY SRCFILES... 763eed67faSmbalmer or: $0 [OPTION]... -d DIRECTORIES... 773eed67faSmbalmer 783eed67faSmbalmerIn the 1st form, copy SRCFILE to DSTFILE. 793eed67faSmbalmerIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 803eed67faSmbalmerIn the 4th, create DIRECTORIES. 813eed67faSmbalmer 823eed67faSmbalmerOptions: 833eed67faSmbalmer-c (ignored) 843eed67faSmbalmer-d create directories instead of installing files. 853eed67faSmbalmer-g GROUP $chgrpprog installed files to GROUP. 863eed67faSmbalmer-m MODE $chmodprog installed files to MODE. 873eed67faSmbalmer-o USER $chownprog installed files to USER. 883eed67faSmbalmer-s $stripprog installed files. 893eed67faSmbalmer-t DIRECTORY install into DIRECTORY. 903eed67faSmbalmer-T report an error if DSTFILE is a directory. 913eed67faSmbalmer--help display this help and exit. 923eed67faSmbalmer--version display version info and exit. 933eed67faSmbalmer 943eed67faSmbalmerEnvironment variables override the default commands: 953eed67faSmbalmer CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 963eed67faSmbalmer" 973eed67faSmbalmer 983eed67faSmbalmerwhile test -n "$1"; do 993eed67faSmbalmer case $1 in 1003eed67faSmbalmer -c) shift 1013eed67faSmbalmer continue;; 1023eed67faSmbalmer 1033eed67faSmbalmer -d) dir_arg=true 1043eed67faSmbalmer shift 1053eed67faSmbalmer continue;; 1063eed67faSmbalmer 1073eed67faSmbalmer -g) chgrpcmd="$chgrpprog $2" 1083eed67faSmbalmer shift 1093eed67faSmbalmer shift 1103eed67faSmbalmer continue;; 1113eed67faSmbalmer 1123eed67faSmbalmer --help) echo "$usage"; exit $?;; 1133eed67faSmbalmer 1143eed67faSmbalmer -m) chmodcmd="$chmodprog $2" 1153eed67faSmbalmer shift 1163eed67faSmbalmer shift 1173eed67faSmbalmer continue;; 1183eed67faSmbalmer 1193eed67faSmbalmer -o) chowncmd="$chownprog $2" 1203eed67faSmbalmer shift 1213eed67faSmbalmer shift 1223eed67faSmbalmer continue;; 1233eed67faSmbalmer 1243eed67faSmbalmer -s) stripcmd=$stripprog 1253eed67faSmbalmer shift 1263eed67faSmbalmer continue;; 1273eed67faSmbalmer 1283eed67faSmbalmer -t) dstarg=$2 1293eed67faSmbalmer shift 1303eed67faSmbalmer shift 1313eed67faSmbalmer continue;; 1323eed67faSmbalmer 1333eed67faSmbalmer -T) no_target_directory=true 1343eed67faSmbalmer shift 1353eed67faSmbalmer continue;; 1363eed67faSmbalmer 1373eed67faSmbalmer --version) echo "$0 $scriptversion"; exit $?;; 1383eed67faSmbalmer 1393eed67faSmbalmer *) # When -d is used, all remaining arguments are directories to create. 1403eed67faSmbalmer # When -t is used, the destination is already specified. 1413eed67faSmbalmer test -n "$dir_arg$dstarg" && break 1423eed67faSmbalmer # Otherwise, the last argument is the destination. Remove it from $@. 1433eed67faSmbalmer for arg 1443eed67faSmbalmer do 1453eed67faSmbalmer if test -n "$dstarg"; then 1463eed67faSmbalmer # $@ is not empty: it contains at least $arg. 1473eed67faSmbalmer set fnord "$@" "$dstarg" 1483eed67faSmbalmer shift # fnord 1493eed67faSmbalmer fi 1503eed67faSmbalmer shift # arg 1513eed67faSmbalmer dstarg=$arg 1523eed67faSmbalmer done 1533eed67faSmbalmer break;; 1543eed67faSmbalmer esac 1553eed67faSmbalmerdone 1563eed67faSmbalmer 1573eed67faSmbalmerif test -z "$1"; then 1583eed67faSmbalmer if test -z "$dir_arg"; then 1593eed67faSmbalmer echo "$0: no input file specified." >&2 1603eed67faSmbalmer exit 1 1613eed67faSmbalmer fi 1623eed67faSmbalmer # It's OK to call `install-sh -d' without argument. 1633eed67faSmbalmer # This can happen when creating conditional directories. 1643eed67faSmbalmer exit 0 1653eed67faSmbalmerfi 1663eed67faSmbalmer 1673eed67faSmbalmerfor src 1683eed67faSmbalmerdo 1693eed67faSmbalmer # Protect names starting with `-'. 1703eed67faSmbalmer case $src in 1713eed67faSmbalmer -*) src=./$src ;; 1723eed67faSmbalmer esac 1733eed67faSmbalmer 1743eed67faSmbalmer if test -n "$dir_arg"; then 1753eed67faSmbalmer dst=$src 1763eed67faSmbalmer src= 1773eed67faSmbalmer 1783eed67faSmbalmer if test -d "$dst"; then 1793eed67faSmbalmer mkdircmd=: 1803eed67faSmbalmer chmodcmd= 1813eed67faSmbalmer else 1823eed67faSmbalmer mkdircmd=$mkdirprog 1833eed67faSmbalmer fi 1843eed67faSmbalmer else 1853eed67faSmbalmer # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 1863eed67faSmbalmer # might cause directories to be created, which would be especially bad 1873eed67faSmbalmer # if $src (and thus $dsttmp) contains '*'. 1883eed67faSmbalmer if test ! -f "$src" && test ! -d "$src"; then 1893eed67faSmbalmer echo "$0: $src does not exist." >&2 1903eed67faSmbalmer exit 1 1913eed67faSmbalmer fi 1923eed67faSmbalmer 1933eed67faSmbalmer if test -z "$dstarg"; then 1943eed67faSmbalmer echo "$0: no destination specified." >&2 1953eed67faSmbalmer exit 1 1963eed67faSmbalmer fi 1973eed67faSmbalmer 1983eed67faSmbalmer dst=$dstarg 1993eed67faSmbalmer # Protect names starting with `-'. 2003eed67faSmbalmer case $dst in 2013eed67faSmbalmer -*) dst=./$dst ;; 2023eed67faSmbalmer esac 2033eed67faSmbalmer 2043eed67faSmbalmer # If destination is a directory, append the input filename; won't work 2053eed67faSmbalmer # if double slashes aren't ignored. 2063eed67faSmbalmer if test -d "$dst"; then 2073eed67faSmbalmer if test -n "$no_target_directory"; then 2083eed67faSmbalmer echo "$0: $dstarg: Is a directory" >&2 2093eed67faSmbalmer exit 1 2103eed67faSmbalmer fi 2113eed67faSmbalmer dst=$dst/`basename "$src"` 2123eed67faSmbalmer fi 2133eed67faSmbalmer fi 2143eed67faSmbalmer 2153eed67faSmbalmer # This sed command emulates the dirname command. 2163eed67faSmbalmer dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 2173eed67faSmbalmer 2183eed67faSmbalmer # Make sure that the destination directory exists. 2193eed67faSmbalmer 2203eed67faSmbalmer # Skip lots of stat calls in the usual case. 2213eed67faSmbalmer if test ! -d "$dstdir"; then 2223eed67faSmbalmer defaultIFS=' 2233eed67faSmbalmer ' 2243eed67faSmbalmer IFS="${IFS-$defaultIFS}" 2253eed67faSmbalmer 2263eed67faSmbalmer oIFS=$IFS 2273eed67faSmbalmer # Some sh's can't handle IFS=/ for some reason. 2283eed67faSmbalmer IFS='%' 2293eed67faSmbalmer set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 2303eed67faSmbalmer shift 2313eed67faSmbalmer IFS=$oIFS 2323eed67faSmbalmer 2333eed67faSmbalmer pathcomp= 2343eed67faSmbalmer 2353eed67faSmbalmer while test $# -ne 0 ; do 2363eed67faSmbalmer pathcomp=$pathcomp$1 2373eed67faSmbalmer shift 2383eed67faSmbalmer if test ! -d "$pathcomp"; then 2393eed67faSmbalmer $mkdirprog "$pathcomp" 2403eed67faSmbalmer # mkdir can fail with a `File exist' error in case several 2413eed67faSmbalmer # install-sh are creating the directory concurrently. This 2423eed67faSmbalmer # is OK. 2433eed67faSmbalmer test -d "$pathcomp" || exit 2443eed67faSmbalmer fi 2453eed67faSmbalmer pathcomp=$pathcomp/ 2463eed67faSmbalmer done 2473eed67faSmbalmer fi 2483eed67faSmbalmer 2493eed67faSmbalmer if test -n "$dir_arg"; then 2503eed67faSmbalmer $doit $mkdircmd "$dst" \ 2513eed67faSmbalmer && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 2523eed67faSmbalmer && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 2533eed67faSmbalmer && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 2543eed67faSmbalmer && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 2553eed67faSmbalmer 2563eed67faSmbalmer else 2573eed67faSmbalmer dstfile=`basename "$dst"` 2583eed67faSmbalmer 2593eed67faSmbalmer # Make a couple of temp file names in the proper directory. 2603eed67faSmbalmer dsttmp=$dstdir/_inst.$$_ 2613eed67faSmbalmer rmtmp=$dstdir/_rm.$$_ 2623eed67faSmbalmer 2633eed67faSmbalmer # Trap to clean up those temp files at exit. 2643eed67faSmbalmer trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 2653eed67faSmbalmer trap '(exit $?); exit' 1 2 13 15 2663eed67faSmbalmer 2673eed67faSmbalmer # Copy the file name to the temp name. 2683eed67faSmbalmer $doit $cpprog "$src" "$dsttmp" && 2693eed67faSmbalmer 2703eed67faSmbalmer # and set any options; do chmod last to preserve setuid bits. 2713eed67faSmbalmer # 2723eed67faSmbalmer # If any of these fail, we abort the whole thing. If we want to 2733eed67faSmbalmer # ignore errors from any of these, just make sure not to ignore 2743eed67faSmbalmer # errors from the above "$doit $cpprog $src $dsttmp" command. 2753eed67faSmbalmer # 2763eed67faSmbalmer { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 2773eed67faSmbalmer && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 2783eed67faSmbalmer && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 2793eed67faSmbalmer && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 2803eed67faSmbalmer 2813eed67faSmbalmer # Now rename the file to the real destination. 2823eed67faSmbalmer { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 2833eed67faSmbalmer || { 2843eed67faSmbalmer # The rename failed, perhaps because mv can't rename something else 2853eed67faSmbalmer # to itself, or perhaps because mv is so ancient that it does not 2863eed67faSmbalmer # support -f. 2873eed67faSmbalmer 2883eed67faSmbalmer # Now remove or move aside any old file at destination location. 2893eed67faSmbalmer # We try this two ways since rm can't unlink itself on some 2903eed67faSmbalmer # systems and the destination file might be busy for other 2913eed67faSmbalmer # reasons. In this case, the final cleanup might fail but the new 2923eed67faSmbalmer # file should still install successfully. 2933eed67faSmbalmer { 2943eed67faSmbalmer if test -f "$dstdir/$dstfile"; then 2953eed67faSmbalmer $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 2963eed67faSmbalmer || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 2973eed67faSmbalmer || { 2983eed67faSmbalmer echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 2993eed67faSmbalmer (exit 1); exit 1 3003eed67faSmbalmer } 3013eed67faSmbalmer else 3023eed67faSmbalmer : 3033eed67faSmbalmer fi 3043eed67faSmbalmer } && 3053eed67faSmbalmer 3063eed67faSmbalmer # Now rename the file to the real destination. 3073eed67faSmbalmer $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 3083eed67faSmbalmer } 3093eed67faSmbalmer } 3103eed67faSmbalmer fi || { (exit 1); exit 1; } 3113eed67faSmbalmerdone 3123eed67faSmbalmer 3133eed67faSmbalmer# The final little trick to "correctly" pass the exit status to the exit trap. 3143eed67faSmbalmer{ 3153eed67faSmbalmer (exit 0); exit 0 3163eed67faSmbalmer} 3173eed67faSmbalmer 3183eed67faSmbalmer# Local variables: 3193eed67faSmbalmer# eval: (add-hook 'write-file-hooks 'time-stamp) 3203eed67faSmbalmer# time-stamp-start: "scriptversion=" 3213eed67faSmbalmer# time-stamp-format: "%:y-%02m-%02d.%02H" 3223eed67faSmbalmer# time-stamp-end: "$" 3233eed67faSmbalmer# End: 324