install-sh revision 67332fb9
167332fb9Smrg#!/bin/sh
267332fb9Smrg#
367332fb9Smrg# install - install a program, script, or datafile
467332fb9Smrg#
567332fb9Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
667332fb9Smrg# later released in X11R6 (xc/config/util/install.sh) with the
767332fb9Smrg# following copyright and license.
867332fb9Smrg#
967332fb9Smrg# Copyright (C) 1994 X Consortium
1067332fb9Smrg#
1167332fb9Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1267332fb9Smrg# of this software and associated documentation files (the "Software"), to
1367332fb9Smrg# deal in the Software without restriction, including without limitation the
1467332fb9Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1567332fb9Smrg# sell copies of the Software, and to permit persons to whom the Software is
1667332fb9Smrg# furnished to do so, subject to the following conditions:
1767332fb9Smrg#
1867332fb9Smrg# The above copyright notice and this permission notice shall be included in
1967332fb9Smrg# all copies or substantial portions of the Software.
2067332fb9Smrg#
2167332fb9Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2267332fb9Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2367332fb9Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2467332fb9Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2567332fb9Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2667332fb9Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2767332fb9Smrg#
2867332fb9Smrg# Except as contained in this notice, the name of the X Consortium shall not
2967332fb9Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3067332fb9Smrg# ings in this Software without prior written authorization from the X Consor-
3167332fb9Smrg# tium.
3267332fb9Smrg#
3367332fb9Smrg#
3467332fb9Smrg# FSF changes to this file are in the public domain.
3567332fb9Smrg#
3667332fb9Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3767332fb9Smrg# `make' implicit rules from creating a file called install from it
3867332fb9Smrg# when there is no Makefile.
3967332fb9Smrg#
4067332fb9Smrg# This script is compatible with the BSD install script, but was written
4167332fb9Smrg# from scratch.  It can only install one file at a time, a restriction
4267332fb9Smrg# shared with many OS's install programs.
4367332fb9Smrg
4467332fb9Smrg
4567332fb9Smrg# set DOITPROG to echo to test this script
4667332fb9Smrg
4767332fb9Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
4867332fb9Smrgdoit="${DOITPROG-}"
4967332fb9Smrg
5067332fb9Smrg
5167332fb9Smrg# put in absolute paths if you don't have them in your path; or use env. vars.
5267332fb9Smrg
5367332fb9Smrgmvprog="${MVPROG-mv}"
5467332fb9Smrgcpprog="${CPPROG-cp}"
5567332fb9Smrgchmodprog="${CHMODPROG-chmod}"
5667332fb9Smrgchownprog="${CHOWNPROG-chown}"
5767332fb9Smrgchgrpprog="${CHGRPPROG-chgrp}"
5867332fb9Smrgstripprog="${STRIPPROG-strip}"
5967332fb9Smrgrmprog="${RMPROG-rm}"
6067332fb9Smrgmkdirprog="${MKDIRPROG-mkdir}"
6167332fb9Smrg
6267332fb9Smrgtransformbasename=""
6367332fb9Smrgtransform_arg=""
6467332fb9Smrginstcmd="$mvprog"
6567332fb9Smrgchmodcmd="$chmodprog 0755"
6667332fb9Smrgchowncmd=""
6767332fb9Smrgchgrpcmd=""
6867332fb9Smrgstripcmd=""
6967332fb9Smrgrmcmd="$rmprog -f"
7067332fb9Smrgmvcmd="$mvprog"
7167332fb9Smrgsrc=""
7267332fb9Smrgdst=""
7367332fb9Smrgdir_arg=""
7467332fb9Smrg
7567332fb9Smrgwhile [ x"$1" != x ]; do
7667332fb9Smrg    case $1 in
7767332fb9Smrg	-c) instcmd=$cpprog
7867332fb9Smrg	    shift
7967332fb9Smrg	    continue;;
8067332fb9Smrg
8167332fb9Smrg	-d) dir_arg=true
8267332fb9Smrg	    shift
8367332fb9Smrg	    continue;;
8467332fb9Smrg
8567332fb9Smrg	-m) chmodcmd="$chmodprog $2"
8667332fb9Smrg	    shift
8767332fb9Smrg	    shift
8867332fb9Smrg	    continue;;
8967332fb9Smrg
9067332fb9Smrg	-o) chowncmd="$chownprog $2"
9167332fb9Smrg	    shift
9267332fb9Smrg	    shift
9367332fb9Smrg	    continue;;
9467332fb9Smrg
9567332fb9Smrg	-g) chgrpcmd="$chgrpprog $2"
9667332fb9Smrg	    shift
9767332fb9Smrg	    shift
9867332fb9Smrg	    continue;;
9967332fb9Smrg
10067332fb9Smrg	-s) stripcmd=$stripprog
10167332fb9Smrg	    shift
10267332fb9Smrg	    continue;;
10367332fb9Smrg
10467332fb9Smrg	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
10567332fb9Smrg	    shift
10667332fb9Smrg	    continue;;
10767332fb9Smrg
10867332fb9Smrg	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
10967332fb9Smrg	    shift
11067332fb9Smrg	    continue;;
11167332fb9Smrg
11267332fb9Smrg	*)  if [ x"$src" = x ]
11367332fb9Smrg	    then
11467332fb9Smrg		src=$1
11567332fb9Smrg	    else
11667332fb9Smrg		# this colon is to work around a 386BSD /bin/sh bug
11767332fb9Smrg		:
11867332fb9Smrg		dst=$1
11967332fb9Smrg	    fi
12067332fb9Smrg	    shift
12167332fb9Smrg	    continue;;
12267332fb9Smrg    esac
12367332fb9Smrgdone
12467332fb9Smrg
12567332fb9Smrgif [ x"$src" = x ]
12667332fb9Smrgthen
12767332fb9Smrg	echo "$0: no input file specified" >&2
12867332fb9Smrg	exit 1
12967332fb9Smrgelse
13067332fb9Smrg	:
13167332fb9Smrgfi
13267332fb9Smrg
13367332fb9Smrgif [ x"$dir_arg" != x ]; then
13467332fb9Smrg	dst=$src
13567332fb9Smrg	src=""
13667332fb9Smrg
13767332fb9Smrg	if [ -d "$dst" ]; then
13867332fb9Smrg		instcmd=:
13967332fb9Smrg		chmodcmd=""
14067332fb9Smrg	else
14167332fb9Smrg		instcmd=$mkdirprog
14267332fb9Smrg	fi
14367332fb9Smrgelse
14467332fb9Smrg
14567332fb9Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
14667332fb9Smrg# might cause directories to be created, which would be especially bad
14767332fb9Smrg# if $src (and thus $dsttmp) contains '*'.
14867332fb9Smrg
14967332fb9Smrg	if [ -f "$src" ] || [ -d "$src" ]
15067332fb9Smrg	then
15167332fb9Smrg		:
15267332fb9Smrg	else
15367332fb9Smrg		echo "$0: $src does not exist" >&2
15467332fb9Smrg		exit 1
15567332fb9Smrg	fi
15667332fb9Smrg
15767332fb9Smrg	if [ x"$dst" = x ]
15867332fb9Smrg	then
15967332fb9Smrg		echo "$0: no destination specified" >&2
16067332fb9Smrg		exit 1
16167332fb9Smrg	else
16267332fb9Smrg		:
16367332fb9Smrg	fi
16467332fb9Smrg
16567332fb9Smrg# If destination is a directory, append the input filename; if your system
16667332fb9Smrg# does not like double slashes in filenames, you may need to add some logic
16767332fb9Smrg
16867332fb9Smrg	if [ -d "$dst" ]
16967332fb9Smrg	then
17067332fb9Smrg		dst=$dst/`basename "$src"`
17167332fb9Smrg	else
17267332fb9Smrg		:
17367332fb9Smrg	fi
17467332fb9Smrgfi
17567332fb9Smrg
17667332fb9Smrg## this sed command emulates the dirname command
17767332fb9Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
17867332fb9Smrg
17967332fb9Smrg# Make sure that the destination directory exists.
18067332fb9Smrg#  this part is taken from Noah Friedman's mkinstalldirs script
18167332fb9Smrg
18267332fb9Smrg# Skip lots of stat calls in the usual case.
18367332fb9Smrgif [ ! -d "$dstdir" ]; then
18467332fb9SmrgdefaultIFS='
18567332fb9Smrg	'
18667332fb9SmrgIFS="${IFS-$defaultIFS}"
18767332fb9Smrg
18867332fb9SmrgoIFS=$IFS
18967332fb9Smrg# Some sh's can't handle IFS=/ for some reason.
19067332fb9SmrgIFS='%'
19167332fb9Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
19267332fb9SmrgIFS=$oIFS
19367332fb9Smrg
19467332fb9Smrgpathcomp=''
19567332fb9Smrg
19667332fb9Smrgwhile [ $# -ne 0 ] ; do
19767332fb9Smrg	pathcomp=$pathcomp$1
19867332fb9Smrg	shift
19967332fb9Smrg
20067332fb9Smrg	if [ ! -d "$pathcomp" ] ;
20167332fb9Smrg        then
20267332fb9Smrg		$mkdirprog "$pathcomp"
20367332fb9Smrg	else
20467332fb9Smrg		:
20567332fb9Smrg	fi
20667332fb9Smrg
20767332fb9Smrg	pathcomp=$pathcomp/
20867332fb9Smrgdone
20967332fb9Smrgfi
21067332fb9Smrg
21167332fb9Smrgif [ x"$dir_arg" != x ]
21267332fb9Smrgthen
21367332fb9Smrg	$doit $instcmd "$dst" &&
21467332fb9Smrg
21567332fb9Smrg	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
21667332fb9Smrg	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
21767332fb9Smrg	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
21867332fb9Smrg	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
21967332fb9Smrgelse
22067332fb9Smrg
22167332fb9Smrg# If we're going to rename the final executable, determine the name now.
22267332fb9Smrg
22367332fb9Smrg	if [ x"$transformarg" = x ]
22467332fb9Smrg	then
22567332fb9Smrg		dstfile=`basename "$dst"`
22667332fb9Smrg	else
22767332fb9Smrg		dstfile=`basename "$dst" $transformbasename |
22867332fb9Smrg			sed $transformarg`$transformbasename
22967332fb9Smrg	fi
23067332fb9Smrg
23167332fb9Smrg# don't allow the sed command to completely eliminate the filename
23267332fb9Smrg
23367332fb9Smrg	if [ x"$dstfile" = x ]
23467332fb9Smrg	then
23567332fb9Smrg		dstfile=`basename "$dst"`
23667332fb9Smrg	else
23767332fb9Smrg		:
23867332fb9Smrg	fi
23967332fb9Smrg
24067332fb9Smrg# Make a couple of temp file names in the proper directory.
24167332fb9Smrg
24267332fb9Smrg	dsttmp=$dstdir/_inst.$$_
24367332fb9Smrg	rmtmp=$dstdir/_rm.$$_
24467332fb9Smrg
24567332fb9Smrg# Trap to clean up temp files at exit.
24667332fb9Smrg
24767332fb9Smrg	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
24867332fb9Smrg	trap '(exit $?); exit' 1 2 13 15
24967332fb9Smrg
25067332fb9Smrg# Move or copy the file name to the temp name
25167332fb9Smrg
25267332fb9Smrg	$doit $instcmd "$src" "$dsttmp" &&
25367332fb9Smrg
25467332fb9Smrg# and set any options; do chmod last to preserve setuid bits
25567332fb9Smrg
25667332fb9Smrg# If any of these fail, we abort the whole thing.  If we want to
25767332fb9Smrg# ignore errors from any of these, just make sure not to ignore
25867332fb9Smrg# errors from the above "$doit $instcmd $src $dsttmp" command.
25967332fb9Smrg
26067332fb9Smrg	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
26167332fb9Smrg	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
26267332fb9Smrg	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
26367332fb9Smrg	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
26467332fb9Smrg
26567332fb9Smrg# Now remove or move aside any old file at destination location.  We try this
26667332fb9Smrg# two ways since rm can't unlink itself on some systems and the destination
26767332fb9Smrg# file might be busy for other reasons.  In this case, the final cleanup
26867332fb9Smrg# might fail but the new file should still install successfully.
26967332fb9Smrg
27067332fb9Smrg{
27167332fb9Smrg	if [ -f "$dstdir/$dstfile" ]
27267332fb9Smrg	then
27367332fb9Smrg		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
27467332fb9Smrg		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
27567332fb9Smrg		{
27667332fb9Smrg		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
27767332fb9Smrg		  (exit 1); exit
27867332fb9Smrg		}
27967332fb9Smrg	else
28067332fb9Smrg		:
28167332fb9Smrg	fi
28267332fb9Smrg} &&
28367332fb9Smrg
28467332fb9Smrg# Now rename the file to the real destination.
28567332fb9Smrg
28667332fb9Smrg	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
28767332fb9Smrg
28867332fb9Smrgfi &&
28967332fb9Smrg
29067332fb9Smrg# The final little trick to "correctly" pass the exit status to the exit trap.
29167332fb9Smrg
29267332fb9Smrg{
29367332fb9Smrg	(exit 0); exit
29467332fb9Smrg}
295