xref: /freebsd/contrib/file/install-sh (revision 14b841d4a8e6c25d964f5e3bbda379a1541a27ec)
175a6cdb3SDavid E. O'Brien#!/bin/sh
2*2dc4dbb9SEitan Adler#
3*2dc4dbb9SEitan Adler# $NetBSD: install-sh.in,v 1.6 2012/01/11 13:07:31 hans Exp $
4*2dc4dbb9SEitan Adler# This script now also installs multiple files, but might choke on installing
5*2dc4dbb9SEitan Adler# multiple files with spaces in the file names.
6*2dc4dbb9SEitan Adler#
775a6cdb3SDavid E. O'Brien# install - install a program, script, or datafile
8*2dc4dbb9SEitan Adler# This comes from X11R5 (mit/util/scripts/install.sh).
9a2e8fb4cSDavid E. O'Brien#
10*2dc4dbb9SEitan Adler# Copyright 1991 by the Massachusetts Institute of Technology
11a2e8fb4cSDavid E. O'Brien#
12*2dc4dbb9SEitan Adler# Permission to use, copy, modify, distribute, and sell this software and its
13*2dc4dbb9SEitan Adler# documentation for any purpose is hereby granted without fee, provided that
14*2dc4dbb9SEitan Adler# the above copyright notice appear in all copies and that both that
15*2dc4dbb9SEitan Adler# copyright notice and this permission notice appear in supporting
16*2dc4dbb9SEitan Adler# documentation, and that the name of M.I.T. not be used in advertising or
17*2dc4dbb9SEitan Adler# publicity pertaining to distribution of the software without specific,
18*2dc4dbb9SEitan Adler# written prior permission.  M.I.T. makes no representations about the
19*2dc4dbb9SEitan Adler# suitability of this software for any purpose.  It is provided "as is"
20*2dc4dbb9SEitan Adler# without express or implied warranty.
2175a6cdb3SDavid E. O'Brien#
2275a6cdb3SDavid E. O'Brien# Calling this script install-sh is preferred over install.sh, to prevent
23*2dc4dbb9SEitan Adler# `make' implicit rules from creating a file called install from it
2475a6cdb3SDavid E. O'Brien# when there is no Makefile.
2575a6cdb3SDavid E. O'Brien#
2675a6cdb3SDavid E. O'Brien# This script is compatible with the BSD install script, but was written
27974b70c4SDavid E. O'Brien# from scratch.
28974b70c4SDavid E. O'Brien
2975a6cdb3SDavid E. O'Brien# set DOITPROG to echo to test this script
3075a6cdb3SDavid E. O'Brien
3175a6cdb3SDavid E. O'Brien# Don't use :- since 4.3BSD and earlier shells don't like it.
32*2dc4dbb9SEitan Adlerdoit="${DOITPROG-}"
3375a6cdb3SDavid E. O'Brien
3475a6cdb3SDavid E. O'Brien
35*2dc4dbb9SEitan Adler# put in absolute paths if you don't have them in your path; or use env. vars.
3680c86c36SDavid E. O'Brien
37*2dc4dbb9SEitan Adlerawkprog="${AWKPROG-awk}"
38*2dc4dbb9SEitan Adlermvprog="${MVPROG-mv}"
39*2dc4dbb9SEitan Adlercpprog="${CPPROG-cp}"
40*2dc4dbb9SEitan Adlerchmodprog="${CHMODPROG-chmod}"
41*2dc4dbb9SEitan Adlerchownprog="${CHOWNPROG-chown}"
42*2dc4dbb9SEitan Adlerchgrpprog="${CHGRPPROG-chgrp}"
43*2dc4dbb9SEitan Adlerstripprog="${STRIPPROG-strip}"
44*2dc4dbb9SEitan Adlerrmprog="${RMPROG-rm}"
45*2dc4dbb9SEitan Adlermkdirprog="${MKDIRPROG-mkdir}"
4675a6cdb3SDavid E. O'Brien
47*2dc4dbb9SEitan Adlerinstcmd="$cpprog"
48*2dc4dbb9SEitan Adlerinstflags=""
49*2dc4dbb9SEitan Adlerpathcompchmodcmd="$chmodprog 755"
50*2dc4dbb9SEitan Adlerchmodcmd="$chmodprog 755"
51*2dc4dbb9SEitan Adlerchowncmd=""
52*2dc4dbb9SEitan Adlerchgrpcmd=""
53*2dc4dbb9SEitan Adlerstripcmd=""
54*2dc4dbb9SEitan Adlerstripflags=""
5575a6cdb3SDavid E. O'Brienrmcmd="$rmprog -f"
56*2dc4dbb9SEitan Adlermvcmd="$mvprog"
57*2dc4dbb9SEitan Adlersrc=""
58*2dc4dbb9SEitan Adlermsrc=""
59*2dc4dbb9SEitan Adlerdst=""
60*2dc4dbb9SEitan Adlerdir_arg=""
61*2dc4dbb9SEitan Adlersuffix=""
62*2dc4dbb9SEitan Adlersuffixfmt=""
6375a6cdb3SDavid E. O'Brien
64*2dc4dbb9SEitan Adlerwhile [ x"$1" != x ]; do
6575a6cdb3SDavid E. O'Brien    case $1 in
66*2dc4dbb9SEitan Adler	-b) suffix=".old"
67*2dc4dbb9SEitan Adler	    shift
68*2dc4dbb9SEitan Adler	    continue;;
6980c86c36SDavid E. O'Brien
70*2dc4dbb9SEitan Adler	-B) suffixfmt="$2"
71*2dc4dbb9SEitan Adler	    shift
72*2dc4dbb9SEitan Adler	    shift
73*2dc4dbb9SEitan Adler	    continue;;
7480c86c36SDavid E. O'Brien
75*2dc4dbb9SEitan Adler	-c) instcmd="$cpprog"
76*2dc4dbb9SEitan Adler	    shift
77*2dc4dbb9SEitan Adler	    continue;;
7880c86c36SDavid E. O'Brien
79*2dc4dbb9SEitan Adler	-d) dir_arg=true
80*2dc4dbb9SEitan Adler	    shift
81*2dc4dbb9SEitan Adler	    continue;;
82d1d50c78SDavid E. O'Brien
83*2dc4dbb9SEitan Adler	-m) chmodcmd="$chmodprog $2"
84*2dc4dbb9SEitan Adler	    shift
85*2dc4dbb9SEitan Adler	    shift
86*2dc4dbb9SEitan Adler	    continue;;
8775a6cdb3SDavid E. O'Brien
88*2dc4dbb9SEitan Adler	-m*)
89*2dc4dbb9SEitan Adler	    chmodcmd="$chmodprog ${1#-m}"
90*2dc4dbb9SEitan Adler	    shift
91*2dc4dbb9SEitan Adler	    continue;;
9258a0f0d0SEitan Adler
9358a0f0d0SEitan Adler	-o) chowncmd="$chownprog $2"
9458a0f0d0SEitan Adler	    shift
95*2dc4dbb9SEitan Adler	    shift
96*2dc4dbb9SEitan Adler	    continue;;
97974b70c4SDavid E. O'Brien
98*2dc4dbb9SEitan Adler	-g) chgrpcmd="$chgrpprog $2"
99*2dc4dbb9SEitan Adler	    shift
100*2dc4dbb9SEitan Adler	    shift
101*2dc4dbb9SEitan Adler	    continue;;
102*2dc4dbb9SEitan Adler
103*2dc4dbb9SEitan Adler	-s) stripcmd="$stripprog"
104*2dc4dbb9SEitan Adler	    shift
105*2dc4dbb9SEitan Adler	    continue;;
106*2dc4dbb9SEitan Adler
107*2dc4dbb9SEitan Adler	-S) stripcmd="$stripprog"
108*2dc4dbb9SEitan Adler	    stripflags="-S $2 $stripflags"
109*2dc4dbb9SEitan Adler	    shift
110*2dc4dbb9SEitan Adler	    shift
111*2dc4dbb9SEitan Adler	    continue;;
112*2dc4dbb9SEitan Adler
113*2dc4dbb9SEitan Adler	-p) instflags="-p"
114*2dc4dbb9SEitan Adler	    shift
115*2dc4dbb9SEitan Adler	    continue;;
116*2dc4dbb9SEitan Adler
117*2dc4dbb9SEitan Adler	*)  if [ x"$msrc" = x ]
118*2dc4dbb9SEitan Adler	    then
119*2dc4dbb9SEitan Adler		msrc="$dst"
120*2dc4dbb9SEitan Adler	    else
121*2dc4dbb9SEitan Adler		msrc="$msrc $dst"
12258a0f0d0SEitan Adler	    fi
123*2dc4dbb9SEitan Adler	    src="$dst"
124*2dc4dbb9SEitan Adler	    dst="$1"
125*2dc4dbb9SEitan Adler	    shift
126*2dc4dbb9SEitan Adler	    continue;;
12758a0f0d0SEitan Adler    esac
12858a0f0d0SEitan Adlerdone
12958a0f0d0SEitan Adler
130*2dc4dbb9SEitan Adlerif [ x"$dir_arg" = x ]
131*2dc4dbb9SEitan Adlerthen
132*2dc4dbb9SEitan Adler	dstisfile=""
133*2dc4dbb9SEitan Adler	if [ ! -d "$dst" ]
134*2dc4dbb9SEitan Adler	then
135*2dc4dbb9SEitan Adler		if [ x"$msrc" = x"$src" ]
136*2dc4dbb9SEitan Adler		then
137*2dc4dbb9SEitan Adler			dstisfile=true
138*2dc4dbb9SEitan Adler		else
139*2dc4dbb9SEitan Adler			echo "install: destination is not a directory"
14075a6cdb3SDavid E. O'Brien			exit 1
141d1d50c78SDavid E. O'Brien		fi
14275a6cdb3SDavid E. O'Brien	fi
143974b70c4SDavid E. O'Brienelse
144*2dc4dbb9SEitan Adler	msrc="$msrc $dst"
145974b70c4SDavid E. O'Brienfi
146*2dc4dbb9SEitan Adler
147*2dc4dbb9SEitan Adlerif [ x"$msrc" = x ]
148*2dc4dbb9SEitan Adlerthen
149*2dc4dbb9SEitan Adler	echo "install: no destination specified"
150*2dc4dbb9SEitan Adler	exit 1
151*2dc4dbb9SEitan Adlerfi
152*2dc4dbb9SEitan Adler
153*2dc4dbb9SEitan Adlerfor srcarg in $msrc; do
154*2dc4dbb9SEitan Adler
155*2dc4dbb9SEitan Adlerif [ x"$dir_arg" != x ]; then
156*2dc4dbb9SEitan Adler
157*2dc4dbb9SEitan Adler	dstarg="$srcarg"
158974b70c4SDavid E. O'Brienelse
159*2dc4dbb9SEitan Adler	dstarg="$dst"
160974b70c4SDavid E. O'Brien
161*2dc4dbb9SEitan Adler# Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command
16275a6cdb3SDavid E. O'Brien# might cause directories to be created, which would be especially bad
16375a6cdb3SDavid E. O'Brien# if $src (and thus $dsttmp) contains '*'.
16480c86c36SDavid E. O'Brien
165*2dc4dbb9SEitan Adler	if [ -f "$srcarg" ]
16658a0f0d0SEitan Adler	then
167*2dc4dbb9SEitan Adler		doinst="$instcmd $instflags"
168*2dc4dbb9SEitan Adler	elif [ -d "$srcarg" ]
169*2dc4dbb9SEitan Adler	then
170*2dc4dbb9SEitan Adler		echo "install: $srcarg: not a regular file"
171*2dc4dbb9SEitan Adler		exit 1
172*2dc4dbb9SEitan Adler	elif [ "$srcarg" = "/dev/null" ]
173*2dc4dbb9SEitan Adler	then
174*2dc4dbb9SEitan Adler		doinst="$cpprog"
17558a0f0d0SEitan Adler	else
176*2dc4dbb9SEitan Adler		echo "install:  $srcarg does not exist"
177*2dc4dbb9SEitan Adler		exit 1
17858a0f0d0SEitan Adler	fi
17980c86c36SDavid E. O'Brien
180*2dc4dbb9SEitan Adler# If destination is a directory, append the input filename; if your system
181*2dc4dbb9SEitan Adler# does not like double slashes in filenames, you may need to add some logic
18280c86c36SDavid E. O'Brien
183*2dc4dbb9SEitan Adler	if [ -d "$dstarg" ]
184*2dc4dbb9SEitan Adler	then
185*2dc4dbb9SEitan Adler		dstarg="$dstarg"/`basename "$srcarg"`
186*2dc4dbb9SEitan Adler	fi
187*2dc4dbb9SEitan Adlerfi
18858a0f0d0SEitan Adler
189*2dc4dbb9SEitan Adler## this sed command emulates the dirname command
190*2dc4dbb9SEitan Adlerdstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
19158a0f0d0SEitan Adler
192*2dc4dbb9SEitan Adler# Make sure that the destination directory exists.
193*2dc4dbb9SEitan Adler#  this part is taken from Noah Friedman's mkinstalldirs script
19458a0f0d0SEitan Adler
195*2dc4dbb9SEitan Adler# Skip lots of stat calls in the usual case.
196*2dc4dbb9SEitan Adlerif [ ! -d "$dstdir" ]; then
197*2dc4dbb9SEitan AdlerdefaultIFS='
198*2dc4dbb9SEitan Adler'
199*2dc4dbb9SEitan AdlerIFS="${IFS-${defaultIFS}}"
200*2dc4dbb9SEitan Adler
201*2dc4dbb9SEitan AdleroIFS="${IFS}"
202*2dc4dbb9SEitan Adler# Some sh's can't handle IFS=/ for some reason.
203*2dc4dbb9SEitan AdlerIFS='%'
204*2dc4dbb9SEitan Adlerset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
205*2dc4dbb9SEitan AdlerIFS="${oIFS}"
206*2dc4dbb9SEitan Adler
207*2dc4dbb9SEitan Adlerpathcomp=''
208*2dc4dbb9SEitan Adler
209*2dc4dbb9SEitan Adlerwhile [ $# -ne 0 ] ; do
210*2dc4dbb9SEitan Adler	pathcomp="${pathcomp}${1}"
21158a0f0d0SEitan Adler	shift
21258a0f0d0SEitan Adler
213*2dc4dbb9SEitan Adler	if [ ! -d "${pathcomp}" ] ;
214*2dc4dbb9SEitan Adler        then
215*2dc4dbb9SEitan Adler		$doit $mkdirprog "${pathcomp}"
216*2dc4dbb9SEitan Adler        	if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi &&
217*2dc4dbb9SEitan Adler        	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi &&
218*2dc4dbb9SEitan Adler        	if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi
21958a0f0d0SEitan Adler
22058a0f0d0SEitan Adler	else
221*2dc4dbb9SEitan Adler		true
22258a0f0d0SEitan Adler	fi
223*2dc4dbb9SEitan Adler
224*2dc4dbb9SEitan Adler	pathcomp="${pathcomp}/"
22558a0f0d0SEitan Adlerdone
22658a0f0d0SEitan Adlerfi
22758a0f0d0SEitan Adler
228*2dc4dbb9SEitan Adler	if [ x"$dir_arg" != x ]
229*2dc4dbb9SEitan Adler	then
230*2dc4dbb9SEitan Adler		if [ -d "$dstarg" ]; then
231*2dc4dbb9SEitan Adler			true
232*2dc4dbb9SEitan Adler		else
233*2dc4dbb9SEitan Adler			$doit $mkdirprog "$dstarg" &&
234*2dc4dbb9SEitan Adler
235*2dc4dbb9SEitan Adler			if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi &&
236*2dc4dbb9SEitan Adler			if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi &&
237*2dc4dbb9SEitan Adler			if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi
238*2dc4dbb9SEitan Adler		fi
23958a0f0d0SEitan Adler	else
24058a0f0d0SEitan Adler
241*2dc4dbb9SEitan Adler		if [ x"$dstisfile" = x ]
242*2dc4dbb9SEitan Adler		then
243*2dc4dbb9SEitan Adler			file=$srcarg
244*2dc4dbb9SEitan Adler		else
245*2dc4dbb9SEitan Adler			file=$dst
246*2dc4dbb9SEitan Adler		fi
24758a0f0d0SEitan Adler
248*2dc4dbb9SEitan Adler		dstfile=`basename "$file"`
249*2dc4dbb9SEitan Adler		dstfinal="$dstdir/$dstfile"
25058a0f0d0SEitan Adler
251*2dc4dbb9SEitan Adler# Make a temp file name in the proper directory.
25258a0f0d0SEitan Adler
253*2dc4dbb9SEitan Adler		dsttmp=$dstdir/#inst.$$#
254*2dc4dbb9SEitan Adler
255*2dc4dbb9SEitan Adler# Make a backup file name in the proper directory.
256*2dc4dbb9SEitan Adler		case x$suffixfmt in
257*2dc4dbb9SEitan Adler		*%*)	suffix=`echo x |
258*2dc4dbb9SEitan Adler			$awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" '
259*2dc4dbb9SEitan Adler			{ cnt = 0;
260*2dc4dbb9SEitan Adler			  do {
261*2dc4dbb9SEitan Adler				sfx = sprintf(fmt, cnt++);
262*2dc4dbb9SEitan Adler				name = bname sfx;
263*2dc4dbb9SEitan Adler			  } while (system("test -f " name) == 0);
264*2dc4dbb9SEitan Adler			  print sfx; }' -`;;
265*2dc4dbb9SEitan Adler		x)	;;
266*2dc4dbb9SEitan Adler		*)	suffix="$suffixfmt";;
267*2dc4dbb9SEitan Adler		esac
268*2dc4dbb9SEitan Adler		dstbackup="$dstfinal$suffix"
269*2dc4dbb9SEitan Adler
270*2dc4dbb9SEitan Adler# Move or copy the file name to the temp name
271*2dc4dbb9SEitan Adler
272*2dc4dbb9SEitan Adler		$doit $doinst $srcarg "$dsttmp" &&
273*2dc4dbb9SEitan Adler
274*2dc4dbb9SEitan Adler		trap "rm -f ${dsttmp}" 0 &&
275*2dc4dbb9SEitan Adler
276*2dc4dbb9SEitan Adler# and set any options; do chmod last to preserve setuid bits
277*2dc4dbb9SEitan Adler
278d1d50c78SDavid E. O'Brien# If any of these fail, we abort the whole thing.  If we want to
279d1d50c78SDavid E. O'Brien# ignore errors from any of these, just make sure not to ignore
280*2dc4dbb9SEitan Adler# errors from the above "$doit $instcmd $src $dsttmp" command.
28180c86c36SDavid E. O'Brien
282*2dc4dbb9SEitan Adler		if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi &&
283*2dc4dbb9SEitan Adler		if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi &&
284*2dc4dbb9SEitan Adler		if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi &&
285*2dc4dbb9SEitan Adler		if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi &&
286d1d50c78SDavid E. O'Brien
287d1d50c78SDavid E. O'Brien# Now rename the file to the real destination.
288d1d50c78SDavid E. O'Brien
289*2dc4dbb9SEitan Adler		if [ x"$suffix" != x ] && [ -f "$dstfinal" ]
290*2dc4dbb9SEitan Adler		then
291*2dc4dbb9SEitan Adler			$doit $mvcmd "$dstfinal" "$dstbackup"
292*2dc4dbb9SEitan Adler		else
293*2dc4dbb9SEitan Adler			$doit $rmcmd -f "$dstfinal"
294*2dc4dbb9SEitan Adler		fi &&
295*2dc4dbb9SEitan Adler		$doit $mvcmd "$dsttmp" "$dstfinal"
29675a6cdb3SDavid E. O'Brien	fi
29775a6cdb3SDavid E. O'Brien
298*2dc4dbb9SEitan Adlerdone &&
299*2dc4dbb9SEitan Adler
300*2dc4dbb9SEitan Adler
301*2dc4dbb9SEitan Adlerexit 0
302