xref: /freebsd/contrib/file/install-sh (revision a2e8fb4c99f2515c6c3d58637e0ae00e39b87c14)
175a6cdb3SDavid E. O'Brien#!/bin/sh
275a6cdb3SDavid E. O'Brien#
375a6cdb3SDavid E. O'Brien# install - install a program, script, or datafile
4a2e8fb4cSDavid E. O'Brien# This comes from X11R5 (mit/util/scripts/install.sh).
5a2e8fb4cSDavid E. O'Brien#
6a2e8fb4cSDavid E. O'Brien# Copyright 1991 by the Massachusetts Institute of Technology
7a2e8fb4cSDavid E. O'Brien#
8a2e8fb4cSDavid E. O'Brien# Permission to use, copy, modify, distribute, and sell this software and its
9a2e8fb4cSDavid E. O'Brien# documentation for any purpose is hereby granted without fee, provided that
10a2e8fb4cSDavid E. O'Brien# the above copyright notice appear in all copies and that both that
11a2e8fb4cSDavid E. O'Brien# copyright notice and this permission notice appear in supporting
12a2e8fb4cSDavid E. O'Brien# documentation, and that the name of M.I.T. not be used in advertising or
13a2e8fb4cSDavid E. O'Brien# publicity pertaining to distribution of the software without specific,
14a2e8fb4cSDavid E. O'Brien# written prior permission.  M.I.T. makes no representations about the
15a2e8fb4cSDavid E. O'Brien# suitability of this software for any purpose.  It is provided "as is"
16a2e8fb4cSDavid E. O'Brien# without express or implied warranty.
1775a6cdb3SDavid E. O'Brien#
1875a6cdb3SDavid E. O'Brien# Calling this script install-sh is preferred over install.sh, to prevent
1975a6cdb3SDavid E. O'Brien# `make' implicit rules from creating a file called install from it
2075a6cdb3SDavid E. O'Brien# when there is no Makefile.
2175a6cdb3SDavid E. O'Brien#
2275a6cdb3SDavid E. O'Brien# This script is compatible with the BSD install script, but was written
23a2e8fb4cSDavid E. O'Brien# from scratch.  It can only install one file at a time, a restriction
24a2e8fb4cSDavid E. O'Brien# shared with many OS's install programs.
2575a6cdb3SDavid E. O'Brien
2675a6cdb3SDavid E. O'Brien
2775a6cdb3SDavid E. O'Brien# set DOITPROG to echo to test this script
2875a6cdb3SDavid E. O'Brien
2975a6cdb3SDavid E. O'Brien# Don't use :- since 4.3BSD and earlier shells don't like it.
3075a6cdb3SDavid E. O'Briendoit="${DOITPROG-}"
3175a6cdb3SDavid E. O'Brien
3275a6cdb3SDavid E. O'Brien
3375a6cdb3SDavid E. O'Brien# put in absolute paths if you don't have them in your path; or use env. vars.
3475a6cdb3SDavid E. O'Brien
3575a6cdb3SDavid E. O'Brienmvprog="${MVPROG-mv}"
3675a6cdb3SDavid E. O'Briencpprog="${CPPROG-cp}"
3775a6cdb3SDavid E. O'Brienchmodprog="${CHMODPROG-chmod}"
3875a6cdb3SDavid E. O'Brienchownprog="${CHOWNPROG-chown}"
3975a6cdb3SDavid E. O'Brienchgrpprog="${CHGRPPROG-chgrp}"
4075a6cdb3SDavid E. O'Brienstripprog="${STRIPPROG-strip}"
4175a6cdb3SDavid E. O'Brienrmprog="${RMPROG-rm}"
4275a6cdb3SDavid E. O'Brienmkdirprog="${MKDIRPROG-mkdir}"
4375a6cdb3SDavid E. O'Brien
44a2e8fb4cSDavid E. O'Brientransformbasename=""
4575a6cdb3SDavid E. O'Brientransform_arg=""
4675a6cdb3SDavid E. O'Brieninstcmd="$mvprog"
4775a6cdb3SDavid E. O'Brienchmodcmd="$chmodprog 0755"
4875a6cdb3SDavid E. O'Brienchowncmd=""
4975a6cdb3SDavid E. O'Brienchgrpcmd=""
5075a6cdb3SDavid E. O'Brienstripcmd=""
5175a6cdb3SDavid E. O'Brienrmcmd="$rmprog -f"
5275a6cdb3SDavid E. O'Brienmvcmd="$mvprog"
5375a6cdb3SDavid E. O'Briensrc=""
5475a6cdb3SDavid E. O'Briendst=""
5575a6cdb3SDavid E. O'Briendir_arg=""
5675a6cdb3SDavid E. O'Brien
5775a6cdb3SDavid E. O'Brienwhile [ x"$1" != x ]; do
5875a6cdb3SDavid E. O'Brien    case $1 in
5975a6cdb3SDavid E. O'Brien	-c) instcmd="$cpprog"
6075a6cdb3SDavid E. O'Brien	    shift
6175a6cdb3SDavid E. O'Brien	    continue;;
6275a6cdb3SDavid E. O'Brien
6375a6cdb3SDavid E. O'Brien	-d) dir_arg=true
6475a6cdb3SDavid E. O'Brien	    shift
6575a6cdb3SDavid E. O'Brien	    continue;;
6675a6cdb3SDavid E. O'Brien
6775a6cdb3SDavid E. O'Brien	-m) chmodcmd="$chmodprog $2"
6875a6cdb3SDavid E. O'Brien	    shift
6975a6cdb3SDavid E. O'Brien	    shift
7075a6cdb3SDavid E. O'Brien	    continue;;
7175a6cdb3SDavid E. O'Brien
7275a6cdb3SDavid E. O'Brien	-o) chowncmd="$chownprog $2"
7375a6cdb3SDavid E. O'Brien	    shift
7475a6cdb3SDavid E. O'Brien	    shift
7575a6cdb3SDavid E. O'Brien	    continue;;
7675a6cdb3SDavid E. O'Brien
7775a6cdb3SDavid E. O'Brien	-g) chgrpcmd="$chgrpprog $2"
7875a6cdb3SDavid E. O'Brien	    shift
7975a6cdb3SDavid E. O'Brien	    shift
8075a6cdb3SDavid E. O'Brien	    continue;;
8175a6cdb3SDavid E. O'Brien
8275a6cdb3SDavid E. O'Brien	-s) stripcmd="$stripprog"
8375a6cdb3SDavid E. O'Brien	    shift
8475a6cdb3SDavid E. O'Brien	    continue;;
8575a6cdb3SDavid E. O'Brien
8675a6cdb3SDavid E. O'Brien	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
8775a6cdb3SDavid E. O'Brien	    shift
8875a6cdb3SDavid E. O'Brien	    continue;;
8975a6cdb3SDavid E. O'Brien
9075a6cdb3SDavid E. O'Brien	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
9175a6cdb3SDavid E. O'Brien	    shift
9275a6cdb3SDavid E. O'Brien	    continue;;
9375a6cdb3SDavid E. O'Brien
9475a6cdb3SDavid E. O'Brien	*)  if [ x"$src" = x ]
9575a6cdb3SDavid E. O'Brien	    then
9675a6cdb3SDavid E. O'Brien		src=$1
9775a6cdb3SDavid E. O'Brien	    else
9875a6cdb3SDavid E. O'Brien		# this colon is to work around a 386BSD /bin/sh bug
9975a6cdb3SDavid E. O'Brien		:
10075a6cdb3SDavid E. O'Brien		dst=$1
10175a6cdb3SDavid E. O'Brien	    fi
10275a6cdb3SDavid E. O'Brien	    shift
10375a6cdb3SDavid E. O'Brien	    continue;;
10475a6cdb3SDavid E. O'Brien    esac
10575a6cdb3SDavid E. O'Briendone
10675a6cdb3SDavid E. O'Brien
10775a6cdb3SDavid E. O'Brienif [ x"$src" = x ]
10875a6cdb3SDavid E. O'Brienthen
10975a6cdb3SDavid E. O'Brien	echo "install:	no input file specified"
11075a6cdb3SDavid E. O'Brien	exit 1
11175a6cdb3SDavid E. O'Brienelse
112a2e8fb4cSDavid E. O'Brien	:
11375a6cdb3SDavid E. O'Brienfi
11475a6cdb3SDavid E. O'Brien
11575a6cdb3SDavid E. O'Brienif [ x"$dir_arg" != x ]; then
11675a6cdb3SDavid E. O'Brien	dst=$src
11775a6cdb3SDavid E. O'Brien	src=""
11875a6cdb3SDavid E. O'Brien
11975a6cdb3SDavid E. O'Brien	if [ -d $dst ]; then
12075a6cdb3SDavid E. O'Brien		instcmd=:
121a2e8fb4cSDavid E. O'Brien		chmodcmd=""
12275a6cdb3SDavid E. O'Brien	else
123a2e8fb4cSDavid E. O'Brien		instcmd=$mkdirprog
12475a6cdb3SDavid E. O'Brien	fi
12575a6cdb3SDavid E. O'Brienelse
12675a6cdb3SDavid E. O'Brien
12775a6cdb3SDavid E. O'Brien# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
12875a6cdb3SDavid E. O'Brien# might cause directories to be created, which would be especially bad
12975a6cdb3SDavid E. O'Brien# if $src (and thus $dsttmp) contains '*'.
13075a6cdb3SDavid E. O'Brien
131a2e8fb4cSDavid E. O'Brien	if [ -f "$src" ] || [ -d "$src" ]
13275a6cdb3SDavid E. O'Brien	then
133a2e8fb4cSDavid E. O'Brien		:
13475a6cdb3SDavid E. O'Brien	else
13575a6cdb3SDavid E. O'Brien		echo "install:  $src does not exist"
13675a6cdb3SDavid E. O'Brien		exit 1
13775a6cdb3SDavid E. O'Brien	fi
13875a6cdb3SDavid E. O'Brien
13975a6cdb3SDavid E. O'Brien	if [ x"$dst" = x ]
14075a6cdb3SDavid E. O'Brien	then
14175a6cdb3SDavid E. O'Brien		echo "install:	no destination specified"
14275a6cdb3SDavid E. O'Brien		exit 1
14375a6cdb3SDavid E. O'Brien	else
144a2e8fb4cSDavid E. O'Brien		:
14575a6cdb3SDavid E. O'Brien	fi
14675a6cdb3SDavid E. O'Brien
14775a6cdb3SDavid E. O'Brien# If destination is a directory, append the input filename; if your system
14875a6cdb3SDavid E. O'Brien# does not like double slashes in filenames, you may need to add some logic
14975a6cdb3SDavid E. O'Brien
15075a6cdb3SDavid E. O'Brien	if [ -d $dst ]
15175a6cdb3SDavid E. O'Brien	then
15275a6cdb3SDavid E. O'Brien		dst="$dst"/`basename $src`
15375a6cdb3SDavid E. O'Brien	else
154a2e8fb4cSDavid E. O'Brien		:
15575a6cdb3SDavid E. O'Brien	fi
15675a6cdb3SDavid E. O'Brienfi
15775a6cdb3SDavid E. O'Brien
15875a6cdb3SDavid E. O'Brien## this sed command emulates the dirname command
15975a6cdb3SDavid E. O'Briendstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
16075a6cdb3SDavid E. O'Brien
16175a6cdb3SDavid E. O'Brien# Make sure that the destination directory exists.
16275a6cdb3SDavid E. O'Brien#  this part is taken from Noah Friedman's mkinstalldirs script
16375a6cdb3SDavid E. O'Brien
16475a6cdb3SDavid E. O'Brien# Skip lots of stat calls in the usual case.
16575a6cdb3SDavid E. O'Brienif [ ! -d "$dstdir" ]; then
16675a6cdb3SDavid E. O'BriendefaultIFS='
16775a6cdb3SDavid E. O'Brien	'
16875a6cdb3SDavid E. O'BrienIFS="${IFS-${defaultIFS}}"
16975a6cdb3SDavid E. O'Brien
17075a6cdb3SDavid E. O'BrienoIFS="${IFS}"
17175a6cdb3SDavid E. O'Brien# Some sh's can't handle IFS=/ for some reason.
17275a6cdb3SDavid E. O'BrienIFS='%'
17375a6cdb3SDavid E. O'Brienset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
17475a6cdb3SDavid E. O'BrienIFS="${oIFS}"
17575a6cdb3SDavid E. O'Brien
17675a6cdb3SDavid E. O'Brienpathcomp=''
17775a6cdb3SDavid E. O'Brien
17875a6cdb3SDavid E. O'Brienwhile [ $# -ne 0 ] ; do
17975a6cdb3SDavid E. O'Brien	pathcomp="${pathcomp}${1}"
18075a6cdb3SDavid E. O'Brien	shift
18175a6cdb3SDavid E. O'Brien
18275a6cdb3SDavid E. O'Brien	if [ ! -d "${pathcomp}" ] ;
18375a6cdb3SDavid E. O'Brien        then
18475a6cdb3SDavid E. O'Brien		$mkdirprog "${pathcomp}"
18575a6cdb3SDavid E. O'Brien	else
186a2e8fb4cSDavid E. O'Brien		:
18775a6cdb3SDavid E. O'Brien	fi
18875a6cdb3SDavid E. O'Brien
18975a6cdb3SDavid E. O'Brien	pathcomp="${pathcomp}/"
19075a6cdb3SDavid E. O'Briendone
19175a6cdb3SDavid E. O'Brienfi
19275a6cdb3SDavid E. O'Brien
19375a6cdb3SDavid E. O'Brienif [ x"$dir_arg" != x ]
19475a6cdb3SDavid E. O'Brienthen
19575a6cdb3SDavid E. O'Brien	$doit $instcmd $dst &&
19675a6cdb3SDavid E. O'Brien
197a2e8fb4cSDavid E. O'Brien	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
198a2e8fb4cSDavid E. O'Brien	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
199a2e8fb4cSDavid E. O'Brien	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
200a2e8fb4cSDavid E. O'Brien	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
20175a6cdb3SDavid E. O'Brienelse
20275a6cdb3SDavid E. O'Brien
20375a6cdb3SDavid E. O'Brien# If we're going to rename the final executable, determine the name now.
20475a6cdb3SDavid E. O'Brien
20575a6cdb3SDavid E. O'Brien	if [ x"$transformarg" = x ]
20675a6cdb3SDavid E. O'Brien	then
20775a6cdb3SDavid E. O'Brien		dstfile=`basename $dst`
20875a6cdb3SDavid E. O'Brien	else
20975a6cdb3SDavid E. O'Brien		dstfile=`basename $dst $transformbasename |
21075a6cdb3SDavid E. O'Brien			sed $transformarg`$transformbasename
21175a6cdb3SDavid E. O'Brien	fi
21275a6cdb3SDavid E. O'Brien
21375a6cdb3SDavid E. O'Brien# don't allow the sed command to completely eliminate the filename
21475a6cdb3SDavid E. O'Brien
21575a6cdb3SDavid E. O'Brien	if [ x"$dstfile" = x ]
21675a6cdb3SDavid E. O'Brien	then
21775a6cdb3SDavid E. O'Brien		dstfile=`basename $dst`
21875a6cdb3SDavid E. O'Brien	else
219a2e8fb4cSDavid E. O'Brien		:
22075a6cdb3SDavid E. O'Brien	fi
22175a6cdb3SDavid E. O'Brien
22275a6cdb3SDavid E. O'Brien# Make a temp file name in the proper directory.
22375a6cdb3SDavid E. O'Brien
22475a6cdb3SDavid E. O'Brien	dsttmp=$dstdir/#inst.$$#
22575a6cdb3SDavid E. O'Brien
22675a6cdb3SDavid E. O'Brien# Move or copy the file name to the temp name
22775a6cdb3SDavid E. O'Brien
22875a6cdb3SDavid E. O'Brien	$doit $instcmd $src $dsttmp &&
22975a6cdb3SDavid E. O'Brien
23075a6cdb3SDavid E. O'Brien	trap "rm -f ${dsttmp}" 0 &&
23175a6cdb3SDavid E. O'Brien
23275a6cdb3SDavid E. O'Brien# and set any options; do chmod last to preserve setuid bits
23375a6cdb3SDavid E. O'Brien
23475a6cdb3SDavid E. O'Brien# If any of these fail, we abort the whole thing.  If we want to
23575a6cdb3SDavid E. O'Brien# ignore errors from any of these, just make sure not to ignore
23675a6cdb3SDavid E. O'Brien# errors from the above "$doit $instcmd $src $dsttmp" command.
23775a6cdb3SDavid E. O'Brien
238a2e8fb4cSDavid E. O'Brien	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
239a2e8fb4cSDavid E. O'Brien	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
240a2e8fb4cSDavid E. O'Brien	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
241a2e8fb4cSDavid E. O'Brien	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
24275a6cdb3SDavid E. O'Brien
24375a6cdb3SDavid E. O'Brien# Now rename the file to the real destination.
24475a6cdb3SDavid E. O'Brien
24575a6cdb3SDavid E. O'Brien	$doit $rmcmd -f $dstdir/$dstfile &&
24675a6cdb3SDavid E. O'Brien	$doit $mvcmd $dsttmp $dstdir/$dstfile
24775a6cdb3SDavid E. O'Brien
24875a6cdb3SDavid E. O'Brienfi &&
24975a6cdb3SDavid E. O'Brien
25075a6cdb3SDavid E. O'Brien
25175a6cdb3SDavid E. O'Brienexit 0
252