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