xref: /freebsd/contrib/file/install-sh (revision 75a6cdb3a2a12f1d03a30f3a08dbba598739dcb4)
175a6cdb3SDavid E. O'Brien#! /bin/sh
275a6cdb3SDavid E. O'Brien#
375a6cdb3SDavid E. O'Brien# install - install a program, script, or datafile
475a6cdb3SDavid E. O'Brien# This comes from X11R5.
575a6cdb3SDavid E. O'Brien#
675a6cdb3SDavid E. O'Brien# Calling this script install-sh is preferred over install.sh, to prevent
775a6cdb3SDavid E. O'Brien# `make' implicit rules from creating a file called install from it
875a6cdb3SDavid E. O'Brien# when there is no Makefile.
975a6cdb3SDavid E. O'Brien#
1075a6cdb3SDavid E. O'Brien# This script is compatible with the BSD install script, but was written
1175a6cdb3SDavid E. O'Brien# from scratch.
1275a6cdb3SDavid E. O'Brien#
1375a6cdb3SDavid E. O'Brien
1475a6cdb3SDavid E. O'Brien
1575a6cdb3SDavid E. O'Brien# set DOITPROG to echo to test this script
1675a6cdb3SDavid E. O'Brien
1775a6cdb3SDavid E. O'Brien# Don't use :- since 4.3BSD and earlier shells don't like it.
1875a6cdb3SDavid E. O'Briendoit="${DOITPROG-}"
1975a6cdb3SDavid E. O'Brien
2075a6cdb3SDavid E. O'Brien
2175a6cdb3SDavid E. O'Brien# put in absolute paths if you don't have them in your path; or use env. vars.
2275a6cdb3SDavid E. O'Brien
2375a6cdb3SDavid E. O'Brienmvprog="${MVPROG-mv}"
2475a6cdb3SDavid E. O'Briencpprog="${CPPROG-cp}"
2575a6cdb3SDavid E. O'Brienchmodprog="${CHMODPROG-chmod}"
2675a6cdb3SDavid E. O'Brienchownprog="${CHOWNPROG-chown}"
2775a6cdb3SDavid E. O'Brienchgrpprog="${CHGRPPROG-chgrp}"
2875a6cdb3SDavid E. O'Brienstripprog="${STRIPPROG-strip}"
2975a6cdb3SDavid E. O'Brienrmprog="${RMPROG-rm}"
3075a6cdb3SDavid E. O'Brienmkdirprog="${MKDIRPROG-mkdir}"
3175a6cdb3SDavid E. O'Brien
3275a6cdb3SDavid E. O'Brientranformbasename=""
3375a6cdb3SDavid E. O'Brientransform_arg=""
3475a6cdb3SDavid E. O'Brieninstcmd="$mvprog"
3575a6cdb3SDavid E. O'Brienchmodcmd="$chmodprog 0755"
3675a6cdb3SDavid E. O'Brienchowncmd=""
3775a6cdb3SDavid E. O'Brienchgrpcmd=""
3875a6cdb3SDavid E. O'Brienstripcmd=""
3975a6cdb3SDavid E. O'Brienrmcmd="$rmprog -f"
4075a6cdb3SDavid E. O'Brienmvcmd="$mvprog"
4175a6cdb3SDavid E. O'Briensrc=""
4275a6cdb3SDavid E. O'Briendst=""
4375a6cdb3SDavid E. O'Briendir_arg=""
4475a6cdb3SDavid E. O'Brien
4575a6cdb3SDavid E. O'Brienwhile [ x"$1" != x ]; do
4675a6cdb3SDavid E. O'Brien    case $1 in
4775a6cdb3SDavid E. O'Brien	-c) instcmd="$cpprog"
4875a6cdb3SDavid E. O'Brien	    shift
4975a6cdb3SDavid E. O'Brien	    continue;;
5075a6cdb3SDavid E. O'Brien
5175a6cdb3SDavid E. O'Brien	-d) dir_arg=true
5275a6cdb3SDavid E. O'Brien	    shift
5375a6cdb3SDavid E. O'Brien	    continue;;
5475a6cdb3SDavid E. O'Brien
5575a6cdb3SDavid E. O'Brien	-m) chmodcmd="$chmodprog $2"
5675a6cdb3SDavid E. O'Brien	    shift
5775a6cdb3SDavid E. O'Brien	    shift
5875a6cdb3SDavid E. O'Brien	    continue;;
5975a6cdb3SDavid E. O'Brien
6075a6cdb3SDavid E. O'Brien	-o) chowncmd="$chownprog $2"
6175a6cdb3SDavid E. O'Brien	    shift
6275a6cdb3SDavid E. O'Brien	    shift
6375a6cdb3SDavid E. O'Brien	    continue;;
6475a6cdb3SDavid E. O'Brien
6575a6cdb3SDavid E. O'Brien	-g) chgrpcmd="$chgrpprog $2"
6675a6cdb3SDavid E. O'Brien	    shift
6775a6cdb3SDavid E. O'Brien	    shift
6875a6cdb3SDavid E. O'Brien	    continue;;
6975a6cdb3SDavid E. O'Brien
7075a6cdb3SDavid E. O'Brien	-s) stripcmd="$stripprog"
7175a6cdb3SDavid E. O'Brien	    shift
7275a6cdb3SDavid E. O'Brien	    continue;;
7375a6cdb3SDavid E. O'Brien
7475a6cdb3SDavid E. O'Brien	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
7575a6cdb3SDavid E. O'Brien	    shift
7675a6cdb3SDavid E. O'Brien	    continue;;
7775a6cdb3SDavid E. O'Brien
7875a6cdb3SDavid E. O'Brien	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
7975a6cdb3SDavid E. O'Brien	    shift
8075a6cdb3SDavid E. O'Brien	    continue;;
8175a6cdb3SDavid E. O'Brien
8275a6cdb3SDavid E. O'Brien	*)  if [ x"$src" = x ]
8375a6cdb3SDavid E. O'Brien	    then
8475a6cdb3SDavid E. O'Brien		src=$1
8575a6cdb3SDavid E. O'Brien	    else
8675a6cdb3SDavid E. O'Brien		# this colon is to work around a 386BSD /bin/sh bug
8775a6cdb3SDavid E. O'Brien		:
8875a6cdb3SDavid E. O'Brien		dst=$1
8975a6cdb3SDavid E. O'Brien	    fi
9075a6cdb3SDavid E. O'Brien	    shift
9175a6cdb3SDavid E. O'Brien	    continue;;
9275a6cdb3SDavid E. O'Brien    esac
9375a6cdb3SDavid E. O'Briendone
9475a6cdb3SDavid E. O'Brien
9575a6cdb3SDavid E. O'Brienif [ x"$src" = x ]
9675a6cdb3SDavid E. O'Brienthen
9775a6cdb3SDavid E. O'Brien	echo "install:	no input file specified"
9875a6cdb3SDavid E. O'Brien	exit 1
9975a6cdb3SDavid E. O'Brienelse
10075a6cdb3SDavid E. O'Brien	true
10175a6cdb3SDavid E. O'Brienfi
10275a6cdb3SDavid E. O'Brien
10375a6cdb3SDavid E. O'Brienif [ x"$dir_arg" != x ]; then
10475a6cdb3SDavid E. O'Brien	dst=$src
10575a6cdb3SDavid E. O'Brien	src=""
10675a6cdb3SDavid E. O'Brien
10775a6cdb3SDavid E. O'Brien	if [ -d $dst ]; then
10875a6cdb3SDavid E. O'Brien		instcmd=:
10975a6cdb3SDavid E. O'Brien	else
11075a6cdb3SDavid E. O'Brien		instcmd=mkdir
11175a6cdb3SDavid E. O'Brien	fi
11275a6cdb3SDavid E. O'Brienelse
11375a6cdb3SDavid E. O'Brien
11475a6cdb3SDavid E. O'Brien# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
11575a6cdb3SDavid E. O'Brien# might cause directories to be created, which would be especially bad
11675a6cdb3SDavid E. O'Brien# if $src (and thus $dsttmp) contains '*'.
11775a6cdb3SDavid E. O'Brien
11875a6cdb3SDavid E. O'Brien	if [ -f $src -o -d $src ]
11975a6cdb3SDavid E. O'Brien	then
12075a6cdb3SDavid E. O'Brien		true
12175a6cdb3SDavid E. O'Brien	else
12275a6cdb3SDavid E. O'Brien		echo "install:  $src does not exist"
12375a6cdb3SDavid E. O'Brien		exit 1
12475a6cdb3SDavid E. O'Brien	fi
12575a6cdb3SDavid E. O'Brien
12675a6cdb3SDavid E. O'Brien	if [ x"$dst" = x ]
12775a6cdb3SDavid E. O'Brien	then
12875a6cdb3SDavid E. O'Brien		echo "install:	no destination specified"
12975a6cdb3SDavid E. O'Brien		exit 1
13075a6cdb3SDavid E. O'Brien	else
13175a6cdb3SDavid E. O'Brien		true
13275a6cdb3SDavid E. O'Brien	fi
13375a6cdb3SDavid E. O'Brien
13475a6cdb3SDavid E. O'Brien# If destination is a directory, append the input filename; if your system
13575a6cdb3SDavid E. O'Brien# does not like double slashes in filenames, you may need to add some logic
13675a6cdb3SDavid E. O'Brien
13775a6cdb3SDavid E. O'Brien	if [ -d $dst ]
13875a6cdb3SDavid E. O'Brien	then
13975a6cdb3SDavid E. O'Brien		dst="$dst"/`basename $src`
14075a6cdb3SDavid E. O'Brien	else
14175a6cdb3SDavid E. O'Brien		true
14275a6cdb3SDavid E. O'Brien	fi
14375a6cdb3SDavid E. O'Brienfi
14475a6cdb3SDavid E. O'Brien
14575a6cdb3SDavid E. O'Brien## this sed command emulates the dirname command
14675a6cdb3SDavid E. O'Briendstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
14775a6cdb3SDavid E. O'Brien
14875a6cdb3SDavid E. O'Brien# Make sure that the destination directory exists.
14975a6cdb3SDavid E. O'Brien#  this part is taken from Noah Friedman's mkinstalldirs script
15075a6cdb3SDavid E. O'Brien
15175a6cdb3SDavid E. O'Brien# Skip lots of stat calls in the usual case.
15275a6cdb3SDavid E. O'Brienif [ ! -d "$dstdir" ]; then
15375a6cdb3SDavid E. O'BriendefaultIFS='
15475a6cdb3SDavid E. O'Brien'
15575a6cdb3SDavid E. O'BrienIFS="${IFS-${defaultIFS}}"
15675a6cdb3SDavid E. O'Brien
15775a6cdb3SDavid E. O'BrienoIFS="${IFS}"
15875a6cdb3SDavid E. O'Brien# Some sh's can't handle IFS=/ for some reason.
15975a6cdb3SDavid E. O'BrienIFS='%'
16075a6cdb3SDavid E. O'Brienset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
16175a6cdb3SDavid E. O'BrienIFS="${oIFS}"
16275a6cdb3SDavid E. O'Brien
16375a6cdb3SDavid E. O'Brienpathcomp=''
16475a6cdb3SDavid E. O'Brien
16575a6cdb3SDavid E. O'Brienwhile [ $# -ne 0 ] ; do
16675a6cdb3SDavid E. O'Brien	pathcomp="${pathcomp}${1}"
16775a6cdb3SDavid E. O'Brien	shift
16875a6cdb3SDavid E. O'Brien
16975a6cdb3SDavid E. O'Brien	if [ ! -d "${pathcomp}" ] ;
17075a6cdb3SDavid E. O'Brien        then
17175a6cdb3SDavid E. O'Brien		$mkdirprog "${pathcomp}"
17275a6cdb3SDavid E. O'Brien	else
17375a6cdb3SDavid E. O'Brien		true
17475a6cdb3SDavid E. O'Brien	fi
17575a6cdb3SDavid E. O'Brien
17675a6cdb3SDavid E. O'Brien	pathcomp="${pathcomp}/"
17775a6cdb3SDavid E. O'Briendone
17875a6cdb3SDavid E. O'Brienfi
17975a6cdb3SDavid E. O'Brien
18075a6cdb3SDavid E. O'Brienif [ x"$dir_arg" != x ]
18175a6cdb3SDavid E. O'Brienthen
18275a6cdb3SDavid E. O'Brien	$doit $instcmd $dst &&
18375a6cdb3SDavid E. O'Brien
18475a6cdb3SDavid E. O'Brien	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
18575a6cdb3SDavid E. O'Brien	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
18675a6cdb3SDavid E. O'Brien	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
18775a6cdb3SDavid E. O'Brien	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
18875a6cdb3SDavid E. O'Brienelse
18975a6cdb3SDavid E. O'Brien
19075a6cdb3SDavid E. O'Brien# If we're going to rename the final executable, determine the name now.
19175a6cdb3SDavid E. O'Brien
19275a6cdb3SDavid E. O'Brien	if [ x"$transformarg" = x ]
19375a6cdb3SDavid E. O'Brien	then
19475a6cdb3SDavid E. O'Brien		dstfile=`basename $dst`
19575a6cdb3SDavid E. O'Brien	else
19675a6cdb3SDavid E. O'Brien		dstfile=`basename $dst $transformbasename |
19775a6cdb3SDavid E. O'Brien			sed $transformarg`$transformbasename
19875a6cdb3SDavid E. O'Brien	fi
19975a6cdb3SDavid E. O'Brien
20075a6cdb3SDavid E. O'Brien# don't allow the sed command to completely eliminate the filename
20175a6cdb3SDavid E. O'Brien
20275a6cdb3SDavid E. O'Brien	if [ x"$dstfile" = x ]
20375a6cdb3SDavid E. O'Brien	then
20475a6cdb3SDavid E. O'Brien		dstfile=`basename $dst`
20575a6cdb3SDavid E. O'Brien	else
20675a6cdb3SDavid E. O'Brien		true
20775a6cdb3SDavid E. O'Brien	fi
20875a6cdb3SDavid E. O'Brien
20975a6cdb3SDavid E. O'Brien# Make a temp file name in the proper directory.
21075a6cdb3SDavid E. O'Brien
21175a6cdb3SDavid E. O'Brien	dsttmp=$dstdir/#inst.$$#
21275a6cdb3SDavid E. O'Brien
21375a6cdb3SDavid E. O'Brien# Move or copy the file name to the temp name
21475a6cdb3SDavid E. O'Brien
21575a6cdb3SDavid E. O'Brien	$doit $instcmd $src $dsttmp &&
21675a6cdb3SDavid E. O'Brien
21775a6cdb3SDavid E. O'Brien	trap "rm -f ${dsttmp}" 0 &&
21875a6cdb3SDavid E. O'Brien
21975a6cdb3SDavid E. O'Brien# and set any options; do chmod last to preserve setuid bits
22075a6cdb3SDavid E. O'Brien
22175a6cdb3SDavid E. O'Brien# If any of these fail, we abort the whole thing.  If we want to
22275a6cdb3SDavid E. O'Brien# ignore errors from any of these, just make sure not to ignore
22375a6cdb3SDavid E. O'Brien# errors from the above "$doit $instcmd $src $dsttmp" command.
22475a6cdb3SDavid E. O'Brien
22575a6cdb3SDavid E. O'Brien	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
22675a6cdb3SDavid E. O'Brien	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
22775a6cdb3SDavid E. O'Brien	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
22875a6cdb3SDavid E. O'Brien	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
22975a6cdb3SDavid E. O'Brien
23075a6cdb3SDavid E. O'Brien# Now rename the file to the real destination.
23175a6cdb3SDavid E. O'Brien
23275a6cdb3SDavid E. O'Brien	$doit $rmcmd -f $dstdir/$dstfile &&
23375a6cdb3SDavid E. O'Brien	$doit $mvcmd $dsttmp $dstdir/$dstfile
23475a6cdb3SDavid E. O'Brien
23575a6cdb3SDavid E. O'Brienfi &&
23675a6cdb3SDavid E. O'Brien
23775a6cdb3SDavid E. O'Brien
23875a6cdb3SDavid E. O'Brienexit 0
239