install-sh revision 5c10afb9
15c10afb9Smrg#!/bin/sh
25c10afb9Smrg#
35c10afb9Smrg# install - install a program, script, or datafile
45c10afb9Smrg#
55c10afb9Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
65c10afb9Smrg# later released in X11R6 (xc/config/util/install.sh) with the
75c10afb9Smrg# following copyright and license.
85c10afb9Smrg#
95c10afb9Smrg# Copyright (C) 1994 X Consortium
105c10afb9Smrg#
115c10afb9Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
125c10afb9Smrg# of this software and associated documentation files (the "Software"), to
135c10afb9Smrg# deal in the Software without restriction, including without limitation the
145c10afb9Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
155c10afb9Smrg# sell copies of the Software, and to permit persons to whom the Software is
165c10afb9Smrg# furnished to do so, subject to the following conditions:
175c10afb9Smrg#
185c10afb9Smrg# The above copyright notice and this permission notice shall be included in
195c10afb9Smrg# all copies or substantial portions of the Software.
205c10afb9Smrg#
215c10afb9Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
225c10afb9Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
235c10afb9Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
245c10afb9Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
255c10afb9Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
265c10afb9Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
275c10afb9Smrg#
285c10afb9Smrg# Except as contained in this notice, the name of the X Consortium shall not
295c10afb9Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
305c10afb9Smrg# ings in this Software without prior written authorization from the X Consor-
315c10afb9Smrg# tium.
325c10afb9Smrg#
335c10afb9Smrg#
345c10afb9Smrg# FSF changes to this file are in the public domain.
355c10afb9Smrg#
365c10afb9Smrg# Calling this script install-sh is preferred over install.sh, to prevent
375c10afb9Smrg# `make' implicit rules from creating a file called install from it
385c10afb9Smrg# when there is no Makefile.
395c10afb9Smrg#
405c10afb9Smrg# This script is compatible with the BSD install script, but was written
415c10afb9Smrg# from scratch.  It can only install one file at a time, a restriction
425c10afb9Smrg# shared with many OS's install programs.
435c10afb9Smrg
445c10afb9Smrg
455c10afb9Smrg# set DOITPROG to echo to test this script
465c10afb9Smrg
475c10afb9Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
485c10afb9Smrgdoit="${DOITPROG-}"
495c10afb9Smrg
505c10afb9Smrg
515c10afb9Smrg# put in absolute paths if you don't have them in your path; or use env. vars.
525c10afb9Smrg
535c10afb9Smrgmvprog="${MVPROG-mv}"
545c10afb9Smrgcpprog="${CPPROG-cp}"
555c10afb9Smrgchmodprog="${CHMODPROG-chmod}"
565c10afb9Smrgchownprog="${CHOWNPROG-chown}"
575c10afb9Smrgchgrpprog="${CHGRPPROG-chgrp}"
585c10afb9Smrgstripprog="${STRIPPROG-strip}"
595c10afb9Smrgrmprog="${RMPROG-rm}"
605c10afb9Smrgmkdirprog="${MKDIRPROG-mkdir}"
615c10afb9Smrg
625c10afb9Smrgtransformbasename=""
635c10afb9Smrgtransform_arg=""
645c10afb9Smrginstcmd="$mvprog"
655c10afb9Smrgchmodcmd="$chmodprog 0755"
665c10afb9Smrgchowncmd=""
675c10afb9Smrgchgrpcmd=""
685c10afb9Smrgstripcmd=""
695c10afb9Smrgrmcmd="$rmprog -f"
705c10afb9Smrgmvcmd="$mvprog"
715c10afb9Smrgsrc=""
725c10afb9Smrgdst=""
735c10afb9Smrgdir_arg=""
745c10afb9Smrg
755c10afb9Smrgwhile [ x"$1" != x ]; do
765c10afb9Smrg    case $1 in
775c10afb9Smrg	-c) instcmd=$cpprog
785c10afb9Smrg	    shift
795c10afb9Smrg	    continue;;
805c10afb9Smrg
815c10afb9Smrg	-d) dir_arg=true
825c10afb9Smrg	    shift
835c10afb9Smrg	    continue;;
845c10afb9Smrg
855c10afb9Smrg	-m) chmodcmd="$chmodprog $2"
865c10afb9Smrg	    shift
875c10afb9Smrg	    shift
885c10afb9Smrg	    continue;;
895c10afb9Smrg
905c10afb9Smrg	-o) chowncmd="$chownprog $2"
915c10afb9Smrg	    shift
925c10afb9Smrg	    shift
935c10afb9Smrg	    continue;;
945c10afb9Smrg
955c10afb9Smrg	-g) chgrpcmd="$chgrpprog $2"
965c10afb9Smrg	    shift
975c10afb9Smrg	    shift
985c10afb9Smrg	    continue;;
995c10afb9Smrg
1005c10afb9Smrg	-s) stripcmd=$stripprog
1015c10afb9Smrg	    shift
1025c10afb9Smrg	    continue;;
1035c10afb9Smrg
1045c10afb9Smrg	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
1055c10afb9Smrg	    shift
1065c10afb9Smrg	    continue;;
1075c10afb9Smrg
1085c10afb9Smrg	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
1095c10afb9Smrg	    shift
1105c10afb9Smrg	    continue;;
1115c10afb9Smrg
1125c10afb9Smrg	*)  if [ x"$src" = x ]
1135c10afb9Smrg	    then
1145c10afb9Smrg		src=$1
1155c10afb9Smrg	    else
1165c10afb9Smrg		# this colon is to work around a 386BSD /bin/sh bug
1175c10afb9Smrg		:
1185c10afb9Smrg		dst=$1
1195c10afb9Smrg	    fi
1205c10afb9Smrg	    shift
1215c10afb9Smrg	    continue;;
1225c10afb9Smrg    esac
1235c10afb9Smrgdone
1245c10afb9Smrg
1255c10afb9Smrgif [ x"$src" = x ]
1265c10afb9Smrgthen
1275c10afb9Smrg	echo "$0: no input file specified" >&2
1285c10afb9Smrg	exit 1
1295c10afb9Smrgelse
1305c10afb9Smrg	:
1315c10afb9Smrgfi
1325c10afb9Smrg
1335c10afb9Smrgif [ x"$dir_arg" != x ]; then
1345c10afb9Smrg	dst=$src
1355c10afb9Smrg	src=""
1365c10afb9Smrg
1375c10afb9Smrg	if [ -d "$dst" ]; then
1385c10afb9Smrg		instcmd=:
1395c10afb9Smrg		chmodcmd=""
1405c10afb9Smrg	else
1415c10afb9Smrg		instcmd=$mkdirprog
1425c10afb9Smrg	fi
1435c10afb9Smrgelse
1445c10afb9Smrg
1455c10afb9Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
1465c10afb9Smrg# might cause directories to be created, which would be especially bad
1475c10afb9Smrg# if $src (and thus $dsttmp) contains '*'.
1485c10afb9Smrg
1495c10afb9Smrg	if [ -f "$src" ] || [ -d "$src" ]
1505c10afb9Smrg	then
1515c10afb9Smrg		:
1525c10afb9Smrg	else
1535c10afb9Smrg		echo "$0: $src does not exist" >&2
1545c10afb9Smrg		exit 1
1555c10afb9Smrg	fi
1565c10afb9Smrg
1575c10afb9Smrg	if [ x"$dst" = x ]
1585c10afb9Smrg	then
1595c10afb9Smrg		echo "$0: no destination specified" >&2
1605c10afb9Smrg		exit 1
1615c10afb9Smrg	else
1625c10afb9Smrg		:
1635c10afb9Smrg	fi
1645c10afb9Smrg
1655c10afb9Smrg# If destination is a directory, append the input filename; if your system
1665c10afb9Smrg# does not like double slashes in filenames, you may need to add some logic
1675c10afb9Smrg
1685c10afb9Smrg	if [ -d "$dst" ]
1695c10afb9Smrg	then
1705c10afb9Smrg		dst=$dst/`basename "$src"`
1715c10afb9Smrg	else
1725c10afb9Smrg		:
1735c10afb9Smrg	fi
1745c10afb9Smrgfi
1755c10afb9Smrg
1765c10afb9Smrg## this sed command emulates the dirname command
1775c10afb9Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
1785c10afb9Smrg
1795c10afb9Smrg# Make sure that the destination directory exists.
1805c10afb9Smrg#  this part is taken from Noah Friedman's mkinstalldirs script
1815c10afb9Smrg
1825c10afb9Smrg# Skip lots of stat calls in the usual case.
1835c10afb9Smrgif [ ! -d "$dstdir" ]; then
1845c10afb9SmrgdefaultIFS='
1855c10afb9Smrg	'
1865c10afb9SmrgIFS="${IFS-$defaultIFS}"
1875c10afb9Smrg
1885c10afb9SmrgoIFS=$IFS
1895c10afb9Smrg# Some sh's can't handle IFS=/ for some reason.
1905c10afb9SmrgIFS='%'
1915c10afb9Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
1925c10afb9SmrgIFS=$oIFS
1935c10afb9Smrg
1945c10afb9Smrgpathcomp=''
1955c10afb9Smrg
1965c10afb9Smrgwhile [ $# -ne 0 ] ; do
1975c10afb9Smrg	pathcomp=$pathcomp$1
1985c10afb9Smrg	shift
1995c10afb9Smrg
2005c10afb9Smrg	if [ ! -d "$pathcomp" ] ;
2015c10afb9Smrg        then
2025c10afb9Smrg		$mkdirprog "$pathcomp"
2035c10afb9Smrg	else
2045c10afb9Smrg		:
2055c10afb9Smrg	fi
2065c10afb9Smrg
2075c10afb9Smrg	pathcomp=$pathcomp/
2085c10afb9Smrgdone
2095c10afb9Smrgfi
2105c10afb9Smrg
2115c10afb9Smrgif [ x"$dir_arg" != x ]
2125c10afb9Smrgthen
2135c10afb9Smrg	$doit $instcmd "$dst" &&
2145c10afb9Smrg
2155c10afb9Smrg	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
2165c10afb9Smrg	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
2175c10afb9Smrg	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
2185c10afb9Smrg	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
2195c10afb9Smrgelse
2205c10afb9Smrg
2215c10afb9Smrg# If we're going to rename the final executable, determine the name now.
2225c10afb9Smrg
2235c10afb9Smrg	if [ x"$transformarg" = x ]
2245c10afb9Smrg	then
2255c10afb9Smrg		dstfile=`basename "$dst"`
2265c10afb9Smrg	else
2275c10afb9Smrg		dstfile=`basename "$dst" $transformbasename |
2285c10afb9Smrg			sed $transformarg`$transformbasename
2295c10afb9Smrg	fi
2305c10afb9Smrg
2315c10afb9Smrg# don't allow the sed command to completely eliminate the filename
2325c10afb9Smrg
2335c10afb9Smrg	if [ x"$dstfile" = x ]
2345c10afb9Smrg	then
2355c10afb9Smrg		dstfile=`basename "$dst"`
2365c10afb9Smrg	else
2375c10afb9Smrg		:
2385c10afb9Smrg	fi
2395c10afb9Smrg
2405c10afb9Smrg# Make a couple of temp file names in the proper directory.
2415c10afb9Smrg
2425c10afb9Smrg	dsttmp=$dstdir/_inst.$$_
2435c10afb9Smrg	rmtmp=$dstdir/_rm.$$_
2445c10afb9Smrg
2455c10afb9Smrg# Trap to clean up temp files at exit.
2465c10afb9Smrg
2475c10afb9Smrg	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
2485c10afb9Smrg	trap '(exit $?); exit' 1 2 13 15
2495c10afb9Smrg
2505c10afb9Smrg# Move or copy the file name to the temp name
2515c10afb9Smrg
2525c10afb9Smrg	$doit $instcmd "$src" "$dsttmp" &&
2535c10afb9Smrg
2545c10afb9Smrg# and set any options; do chmod last to preserve setuid bits
2555c10afb9Smrg
2565c10afb9Smrg# If any of these fail, we abort the whole thing.  If we want to
2575c10afb9Smrg# ignore errors from any of these, just make sure not to ignore
2585c10afb9Smrg# errors from the above "$doit $instcmd $src $dsttmp" command.
2595c10afb9Smrg
2605c10afb9Smrg	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
2615c10afb9Smrg	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
2625c10afb9Smrg	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
2635c10afb9Smrg	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
2645c10afb9Smrg
2655c10afb9Smrg# Now remove or move aside any old file at destination location.  We try this
2665c10afb9Smrg# two ways since rm can't unlink itself on some systems and the destination
2675c10afb9Smrg# file might be busy for other reasons.  In this case, the final cleanup
2685c10afb9Smrg# might fail but the new file should still install successfully.
2695c10afb9Smrg
2705c10afb9Smrg{
2715c10afb9Smrg	if [ -f "$dstdir/$dstfile" ]
2725c10afb9Smrg	then
2735c10afb9Smrg		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
2745c10afb9Smrg		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
2755c10afb9Smrg		{
2765c10afb9Smrg		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
2775c10afb9Smrg		  (exit 1); exit
2785c10afb9Smrg		}
2795c10afb9Smrg	else
2805c10afb9Smrg		:
2815c10afb9Smrg	fi
2825c10afb9Smrg} &&
2835c10afb9Smrg
2845c10afb9Smrg# Now rename the file to the real destination.
2855c10afb9Smrg
2865c10afb9Smrg	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
2875c10afb9Smrg
2885c10afb9Smrgfi &&
2895c10afb9Smrg
2905c10afb9Smrg# The final little trick to "correctly" pass the exit status to the exit trap.
2915c10afb9Smrg
2925c10afb9Smrg{
2935c10afb9Smrg	(exit 0); exit
2945c10afb9Smrg}
295