1603fc0a3Smrg#!/bin/sh
2603fc0a3Smrg#
3603fc0a3Smrg# $NetBSD: install-sh,v 1.3 2019/03/20 07:17:34 mrg Exp $
4603fc0a3Smrg# This script now also installs multiple files, but might choke on installing
5603fc0a3Smrg# multiple files with spaces in the file names.
6603fc0a3Smrg#
7603fc0a3Smrg# install - install a program, script, or datafile
8603fc0a3Smrg# This comes from X11R5 (mit/util/scripts/install.sh).
9603fc0a3Smrg#
10603fc0a3Smrg# Copyright 1991 by the Massachusetts Institute of Technology
11603fc0a3Smrg#
12603fc0a3Smrg# Permission to use, copy, modify, distribute, and sell this software and its
13603fc0a3Smrg# documentation for any purpose is hereby granted without fee, provided that
14603fc0a3Smrg# the above copyright notice appear in all copies and that both that
15603fc0a3Smrg# copyright notice and this permission notice appear in supporting
16603fc0a3Smrg# documentation, and that the name of M.I.T. not be used in advertising or
17603fc0a3Smrg# publicity pertaining to distribution of the software without specific,
18603fc0a3Smrg# written prior permission.  M.I.T. makes no representations about the
19603fc0a3Smrg# suitability of this software for any purpose.  It is provided "as is"
20603fc0a3Smrg# without express or implied warranty.
21603fc0a3Smrg#
22603fc0a3Smrg# Calling this script install-sh is preferred over install.sh, to prevent
23603fc0a3Smrg# `make' implicit rules from creating a file called install from it
24603fc0a3Smrg# when there is no Makefile.
25603fc0a3Smrg#
26603fc0a3Smrg# This script is compatible with the BSD install script, but was written
27603fc0a3Smrg# from scratch.
28603fc0a3Smrg
29603fc0a3Smrg# set DOITPROG to echo to test this script
30603fc0a3Smrg
31603fc0a3Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
32603fc0a3Smrgdoit="${DOITPROG-}"
33603fc0a3Smrg
34603fc0a3Smrg
35603fc0a3Smrg# put in absolute paths if you don't have them in your path; or use env. vars.
36603fc0a3Smrg
37603fc0a3Smrgawkprog="${AWKPROG-awk}"
38603fc0a3Smrgmvprog="${MVPROG-mv}"
39603fc0a3Smrgcpprog="${CPPROG-cp}"
40603fc0a3Smrgchmodprog="${CHMODPROG-chmod}"
41603fc0a3Smrgchownprog="${CHOWNPROG-chown}"
42603fc0a3Smrgchgrpprog="${CHGRPPROG-chgrp}"
43603fc0a3Smrgstripprog="${STRIPPROG-strip}"
44603fc0a3Smrgrmprog="${RMPROG-rm}"
45603fc0a3Smrgmkdirprog="${MKDIRPROG-mkdir}"
46603fc0a3Smrg
47603fc0a3Smrginstcmd="$cpprog"
48603fc0a3Smrginstflags=""
49603fc0a3Smrgpathcompchmodcmd="$chmodprog 755"
50603fc0a3Smrgchmodcmd="$chmodprog 755"
51603fc0a3Smrgchowncmd=""
52603fc0a3Smrgchgrpcmd=""
53603fc0a3Smrgstripcmd=""
54603fc0a3Smrgstripflags=""
55603fc0a3Smrgrmcmd="$rmprog -f"
56603fc0a3Smrgmvcmd="$mvprog"
57603fc0a3Smrgsrc=""
58603fc0a3Smrgmsrc=""
59603fc0a3Smrgdst=""
60603fc0a3Smrgdir_arg=""
61603fc0a3Smrgsuffix=""
62603fc0a3Smrgsuffixfmt=""
63603fc0a3Smrg
64603fc0a3Smrgwhile [ x"$1" != x ]; do
65603fc0a3Smrg    case $1 in
66603fc0a3Smrg	-b) suffix=".old"
67603fc0a3Smrg	    shift
68603fc0a3Smrg	    continue;;
69603fc0a3Smrg
70603fc0a3Smrg	-B) suffixfmt="$2"
71603fc0a3Smrg	    shift
72603fc0a3Smrg	    shift
73603fc0a3Smrg	    continue;;
74603fc0a3Smrg
75603fc0a3Smrg	-c) instcmd="$cpprog"
76603fc0a3Smrg	    shift
77603fc0a3Smrg	    continue;;
78603fc0a3Smrg
79603fc0a3Smrg	-d) dir_arg=true
80603fc0a3Smrg	    shift
81603fc0a3Smrg	    continue;;
82603fc0a3Smrg
83603fc0a3Smrg	-m) chmodcmd="$chmodprog $2"
84603fc0a3Smrg	    shift
85603fc0a3Smrg	    shift
86603fc0a3Smrg	    continue;;
87603fc0a3Smrg
88603fc0a3Smrg	-m*)
89603fc0a3Smrg	    chmodcmd="$chmodprog ${1#-m}"
90603fc0a3Smrg	    shift
91603fc0a3Smrg	    continue;;
92603fc0a3Smrg
93603fc0a3Smrg	-o) chowncmd="$chownprog $2"
94603fc0a3Smrg	    shift
95603fc0a3Smrg	    shift
96603fc0a3Smrg	    continue;;
97603fc0a3Smrg
98603fc0a3Smrg	-g) chgrpcmd="$chgrpprog $2"
99603fc0a3Smrg	    shift
100603fc0a3Smrg	    shift
101603fc0a3Smrg	    continue;;
102603fc0a3Smrg
103603fc0a3Smrg	-s) stripcmd="$stripprog"
104603fc0a3Smrg	    shift
105603fc0a3Smrg	    continue;;
106603fc0a3Smrg
107603fc0a3Smrg	-S) stripcmd="$stripprog"
108603fc0a3Smrg	    stripflags="-S $2 $stripflags"
109603fc0a3Smrg	    shift
110603fc0a3Smrg	    shift
111603fc0a3Smrg	    continue;;
112603fc0a3Smrg
113603fc0a3Smrg	-p) instflags="-p"
114603fc0a3Smrg	    shift
115603fc0a3Smrg	    continue;;
116603fc0a3Smrg
117603fc0a3Smrg	*)  if [ x"$msrc" = x ]
118603fc0a3Smrg	    then
119603fc0a3Smrg		msrc="$dst"
120603fc0a3Smrg	    else
121603fc0a3Smrg		msrc="$msrc $dst"
122603fc0a3Smrg	    fi
123603fc0a3Smrg	    src="$dst"
124603fc0a3Smrg	    dst="$1"
125603fc0a3Smrg	    shift
126603fc0a3Smrg	    continue;;
127603fc0a3Smrg    esac
128603fc0a3Smrgdone
129603fc0a3Smrg
130603fc0a3Smrgif [ x"$dir_arg" = x ]
131603fc0a3Smrgthen
132603fc0a3Smrg	dstisfile=""
133603fc0a3Smrg	if [ ! -d "$dst" ]
134603fc0a3Smrg	then
135603fc0a3Smrg		if [ x"$msrc" = x"$src" ]
136603fc0a3Smrg		then
137603fc0a3Smrg			dstisfile=true
138603fc0a3Smrg		else
139603fc0a3Smrg			echo "install: destination is not a directory"
140603fc0a3Smrg			exit 1
141603fc0a3Smrg		fi
142603fc0a3Smrg	fi
143603fc0a3Smrgelse
144603fc0a3Smrg	msrc="$msrc $dst"
145603fc0a3Smrgfi
146603fc0a3Smrg
147603fc0a3Smrgif [ x"$msrc" = x ]
148603fc0a3Smrgthen
149603fc0a3Smrg	echo "install: no destination specified"
150603fc0a3Smrg	exit 1
151603fc0a3Smrgfi      
152603fc0a3Smrg
153603fc0a3Smrgfor srcarg in $msrc; do
154603fc0a3Smrg
155603fc0a3Smrgif [ x"$dir_arg" != x ]; then
156603fc0a3Smrg
157603fc0a3Smrg	dstarg="$srcarg"
158603fc0a3Smrgelse
159603fc0a3Smrg	dstarg="$dst"
160603fc0a3Smrg
161603fc0a3Smrg# Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command
162603fc0a3Smrg# might cause directories to be created, which would be especially bad 
163603fc0a3Smrg# if $src (and thus $dsttmp) contains '*'.
164603fc0a3Smrg
165603fc0a3Smrg	if [ -f "$srcarg" ]
166603fc0a3Smrg	then
167603fc0a3Smrg		doinst="$instcmd $instflags"
168603fc0a3Smrg	elif [ -d "$srcarg" ]
169603fc0a3Smrg	then
170603fc0a3Smrg		echo "install: $srcarg: not a regular file"
171603fc0a3Smrg		exit 1
172603fc0a3Smrg	elif [ "$srcarg" = "/dev/null" ]
173603fc0a3Smrg	then
174603fc0a3Smrg		doinst="$cpprog"
175603fc0a3Smrg	else
176603fc0a3Smrg		echo "install:  $srcarg does not exist"
177603fc0a3Smrg		exit 1
178603fc0a3Smrg	fi
179603fc0a3Smrg	
180603fc0a3Smrg# If destination is a directory, append the input filename; if your system
181603fc0a3Smrg# does not like double slashes in filenames, you may need to add some logic
182603fc0a3Smrg
183603fc0a3Smrg	if [ -d "$dstarg" ]
184603fc0a3Smrg	then
185603fc0a3Smrg		dstarg="$dstarg"/`basename "$srcarg"`
186603fc0a3Smrg	fi
187603fc0a3Smrgfi
188603fc0a3Smrg
189603fc0a3Smrg## this sed command emulates the dirname command
190603fc0a3Smrgdstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
191603fc0a3Smrg
192603fc0a3Smrg# Make sure that the destination directory exists.
193603fc0a3Smrg#  this part is taken from Noah Friedman's mkinstalldirs script
194603fc0a3Smrg
195603fc0a3Smrg# Skip lots of stat calls in the usual case.
196603fc0a3Smrgif [ ! -d "$dstdir" ]; then
197603fc0a3SmrgdefaultIFS='	
198603fc0a3Smrg'
199603fc0a3SmrgIFS="${IFS-${defaultIFS}}"
200603fc0a3Smrg
201603fc0a3SmrgoIFS="${IFS}"
202603fc0a3Smrg# Some sh's can't handle IFS=/ for some reason.
203603fc0a3SmrgIFS='%'
204603fc0a3Smrgset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
205603fc0a3SmrgIFS="${oIFS}"
206603fc0a3Smrg
207603fc0a3Smrgpathcomp=''
208603fc0a3Smrg
209603fc0a3Smrgwhile [ $# -ne 0 ] ; do
210603fc0a3Smrg	pathcomp="${pathcomp}${1}"
211603fc0a3Smrg	shift
212603fc0a3Smrg
213603fc0a3Smrg	if [ ! -d "${pathcomp}" ] ;
214603fc0a3Smrg        then
215603fc0a3Smrg		$doit $mkdirprog "${pathcomp}"
216603fc0a3Smrg        	if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi &&
217603fc0a3Smrg        	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi &&
218603fc0a3Smrg        	if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi
219603fc0a3Smrg
220603fc0a3Smrg	else
221603fc0a3Smrg		true
222603fc0a3Smrg	fi
223603fc0a3Smrg
224603fc0a3Smrg	pathcomp="${pathcomp}/"
225603fc0a3Smrgdone
226603fc0a3Smrgfi
227603fc0a3Smrg
228603fc0a3Smrg	if [ x"$dir_arg" != x ]
229603fc0a3Smrg	then
230603fc0a3Smrg		if [ -d "$dstarg" ]; then
231603fc0a3Smrg			true
232603fc0a3Smrg		else
233603fc0a3Smrg			$doit $mkdirprog "$dstarg" &&
234603fc0a3Smrg
235603fc0a3Smrg			if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi &&
236603fc0a3Smrg			if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi &&
237603fc0a3Smrg			if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi
238603fc0a3Smrg		fi
239603fc0a3Smrg	else
240603fc0a3Smrg
241603fc0a3Smrg		if [ x"$dstisfile" = x ]
242603fc0a3Smrg		then
243603fc0a3Smrg			file=$srcarg
244603fc0a3Smrg		else
245603fc0a3Smrg			file=$dst
246603fc0a3Smrg		fi
247603fc0a3Smrg
248603fc0a3Smrg		dstfile=`basename "$file"`
249603fc0a3Smrg		dstfinal="$dstdir/$dstfile"
250603fc0a3Smrg
251603fc0a3Smrg# Make a temp file name in the proper directory.
252603fc0a3Smrg
253603fc0a3Smrg		dsttmp=$dstdir/#inst.$$#
254603fc0a3Smrg
255603fc0a3Smrg# Make a backup file name in the proper directory.
256603fc0a3Smrg		case x$suffixfmt in
257603fc0a3Smrg		*%*)	suffix=`echo x |
258603fc0a3Smrg			$awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" '
259603fc0a3Smrg			{ cnt = 0;
260603fc0a3Smrg			  do {
261603fc0a3Smrg				sfx = sprintf(fmt, cnt++);
262603fc0a3Smrg				name = bname sfx;
263603fc0a3Smrg			  } while (system("test -f " name) == 0);
264603fc0a3Smrg			  print sfx; }' -`;;
265603fc0a3Smrg		x)	;;
266603fc0a3Smrg		*)	suffix="$suffixfmt";;
267603fc0a3Smrg		esac
268603fc0a3Smrg		dstbackup="$dstfinal$suffix"
269603fc0a3Smrg
270603fc0a3Smrg# Move or copy the file name to the temp name
271603fc0a3Smrg
272603fc0a3Smrg		$doit $doinst $srcarg "$dsttmp" &&
273603fc0a3Smrg
274603fc0a3Smrg		trap "rm -f ${dsttmp}" 0 &&
275603fc0a3Smrg
276603fc0a3Smrg# and set any options; do chmod last to preserve setuid bits
277603fc0a3Smrg
278603fc0a3Smrg# If any of these fail, we abort the whole thing.  If we want to
279603fc0a3Smrg# ignore errors from any of these, just make sure not to ignore
280603fc0a3Smrg# errors from the above "$doit $instcmd $src $dsttmp" command.
281603fc0a3Smrg
282603fc0a3Smrg		if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi &&
283603fc0a3Smrg		if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi &&
284603fc0a3Smrg		if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi &&
285603fc0a3Smrg		if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi &&
286603fc0a3Smrg
287603fc0a3Smrg# Now rename the file to the real destination.
288603fc0a3Smrg
289603fc0a3Smrg		if [ x"$suffix" != x ] && [ -f "$dstfinal" ]
290603fc0a3Smrg		then
291603fc0a3Smrg			$doit $mvcmd "$dstfinal" "$dstbackup"
292603fc0a3Smrg		else
293603fc0a3Smrg			$doit $rmcmd -f "$dstfinal"
294603fc0a3Smrg		fi &&
295603fc0a3Smrg		$doit $mvcmd "$dsttmp" "$dstfinal"
296603fc0a3Smrg	fi
297603fc0a3Smrg
298603fc0a3Smrgdone &&
299603fc0a3Smrg
300603fc0a3Smrg
301603fc0a3Smrgexit 0
302