xref: /freebsd/crypto/heimdal/install-sh (revision 1c43270ada91f3473174c2bf81fba64963b7e4ac)
1b528cefcSMark Murray#!/bin/sh
2b528cefcSMark Murray#
3b528cefcSMark Murray# install - install a program, script, or datafile
48373020dSJacques Vidrine#
51c43270aSJacques Vidrine# This originates from X11R5 (mit/util/scripts/install.sh), which was
61c43270aSJacques Vidrine# later released in X11R6 (xc/config/util/install.sh) with the
71c43270aSJacques Vidrine# following copyright and license.
88373020dSJacques Vidrine#
91c43270aSJacques Vidrine# Copyright (C) 1994 X Consortium
101c43270aSJacques Vidrine#
111c43270aSJacques Vidrine# Permission is hereby granted, free of charge, to any person obtaining a copy
121c43270aSJacques Vidrine# of this software and associated documentation files (the "Software"), to
131c43270aSJacques Vidrine# deal in the Software without restriction, including without limitation the
141c43270aSJacques Vidrine# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
151c43270aSJacques Vidrine# sell copies of the Software, and to permit persons to whom the Software is
161c43270aSJacques Vidrine# furnished to do so, subject to the following conditions:
171c43270aSJacques Vidrine#
181c43270aSJacques Vidrine# The above copyright notice and this permission notice shall be included in
191c43270aSJacques Vidrine# all copies or substantial portions of the Software.
201c43270aSJacques Vidrine#
211c43270aSJacques Vidrine# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
221c43270aSJacques Vidrine# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
231c43270aSJacques Vidrine# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
241c43270aSJacques Vidrine# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
251c43270aSJacques Vidrine# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
261c43270aSJacques Vidrine# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
271c43270aSJacques Vidrine#
281c43270aSJacques Vidrine# Except as contained in this notice, the name of the X Consortium shall not
291c43270aSJacques Vidrine# be used in advertising or otherwise to promote the sale, use or other deal-
301c43270aSJacques Vidrine# ings in this Software without prior written authorization from the X Consor-
311c43270aSJacques Vidrine# tium.
321c43270aSJacques Vidrine#
331c43270aSJacques Vidrine#
341c43270aSJacques Vidrine# FSF changes to this file are in the public domain.
35b528cefcSMark Murray#
36b528cefcSMark Murray# Calling this script install-sh is preferred over install.sh, to prevent
37b528cefcSMark Murray# `make' implicit rules from creating a file called install from it
38b528cefcSMark Murray# when there is no Makefile.
39b528cefcSMark Murray#
40b528cefcSMark Murray# This script is compatible with the BSD install script, but was written
418373020dSJacques Vidrine# from scratch.  It can only install one file at a time, a restriction
428373020dSJacques Vidrine# shared with many OS's install programs.
43b528cefcSMark Murray
44b528cefcSMark Murray
45b528cefcSMark Murray# set DOITPROG to echo to test this script
46b528cefcSMark Murray
47b528cefcSMark Murray# Don't use :- since 4.3BSD and earlier shells don't like it.
48b528cefcSMark Murraydoit="${DOITPROG-}"
49b528cefcSMark Murray
50b528cefcSMark Murray
51b528cefcSMark Murray# put in absolute paths if you don't have them in your path; or use env. vars.
52b528cefcSMark Murray
53b528cefcSMark Murraymvprog="${MVPROG-mv}"
54b528cefcSMark Murraycpprog="${CPPROG-cp}"
55b528cefcSMark Murraychmodprog="${CHMODPROG-chmod}"
56b528cefcSMark Murraychownprog="${CHOWNPROG-chown}"
57b528cefcSMark Murraychgrpprog="${CHGRPPROG-chgrp}"
58b528cefcSMark Murraystripprog="${STRIPPROG-strip}"
59b528cefcSMark Murrayrmprog="${RMPROG-rm}"
60b528cefcSMark Murraymkdirprog="${MKDIRPROG-mkdir}"
61b528cefcSMark Murray
628373020dSJacques Vidrinetransformbasename=""
63b528cefcSMark Murraytransform_arg=""
64b528cefcSMark Murrayinstcmd="$mvprog"
65b528cefcSMark Murraychmodcmd="$chmodprog 0755"
66b528cefcSMark Murraychowncmd=""
67b528cefcSMark Murraychgrpcmd=""
68b528cefcSMark Murraystripcmd=""
69b528cefcSMark Murrayrmcmd="$rmprog -f"
70b528cefcSMark Murraymvcmd="$mvprog"
71b528cefcSMark Murraysrc=""
72b528cefcSMark Murraydst=""
73b528cefcSMark Murraydir_arg=""
74b528cefcSMark Murray
75b528cefcSMark Murraywhile [ x"$1" != x ]; do
76b528cefcSMark Murray    case $1 in
771c43270aSJacques Vidrine	-c) instcmd=$cpprog
78b528cefcSMark Murray	    shift
79b528cefcSMark Murray	    continue;;
80b528cefcSMark Murray
81b528cefcSMark Murray	-d) dir_arg=true
82b528cefcSMark Murray	    shift
83b528cefcSMark Murray	    continue;;
84b528cefcSMark Murray
85b528cefcSMark Murray	-m) chmodcmd="$chmodprog $2"
86b528cefcSMark Murray	    shift
87b528cefcSMark Murray	    shift
88b528cefcSMark Murray	    continue;;
89b528cefcSMark Murray
90b528cefcSMark Murray	-o) chowncmd="$chownprog $2"
91b528cefcSMark Murray	    shift
92b528cefcSMark Murray	    shift
93b528cefcSMark Murray	    continue;;
94b528cefcSMark Murray
95b528cefcSMark Murray	-g) chgrpcmd="$chgrpprog $2"
96b528cefcSMark Murray	    shift
97b528cefcSMark Murray	    shift
98b528cefcSMark Murray	    continue;;
99b528cefcSMark Murray
1001c43270aSJacques Vidrine	-s) stripcmd=$stripprog
101b528cefcSMark Murray	    shift
102b528cefcSMark Murray	    continue;;
103b528cefcSMark Murray
104b528cefcSMark Murray	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
105b528cefcSMark Murray	    shift
106b528cefcSMark Murray	    continue;;
107b528cefcSMark Murray
108b528cefcSMark Murray	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
109b528cefcSMark Murray	    shift
110b528cefcSMark Murray	    continue;;
111b528cefcSMark Murray
112b528cefcSMark Murray	*)  if [ x"$src" = x ]
113b528cefcSMark Murray	    then
114b528cefcSMark Murray		src=$1
115b528cefcSMark Murray	    else
116b528cefcSMark Murray		# this colon is to work around a 386BSD /bin/sh bug
117b528cefcSMark Murray		:
118b528cefcSMark Murray		dst=$1
119b528cefcSMark Murray	    fi
120b528cefcSMark Murray	    shift
121b528cefcSMark Murray	    continue;;
122b528cefcSMark Murray    esac
123b528cefcSMark Murraydone
124b528cefcSMark Murray
125b528cefcSMark Murrayif [ x"$src" = x ]
126b528cefcSMark Murraythen
1271c43270aSJacques Vidrine	echo "$0: no input file specified" >&2
128b528cefcSMark Murray	exit 1
129b528cefcSMark Murrayelse
1308373020dSJacques Vidrine	:
131b528cefcSMark Murrayfi
132b528cefcSMark Murray
133b528cefcSMark Murrayif [ x"$dir_arg" != x ]; then
134b528cefcSMark Murray	dst=$src
135b528cefcSMark Murray	src=""
136b528cefcSMark Murray
1371c43270aSJacques Vidrine	if [ -d "$dst" ]; then
138b528cefcSMark Murray		instcmd=:
1398373020dSJacques Vidrine		chmodcmd=""
140b528cefcSMark Murray	else
1418373020dSJacques Vidrine		instcmd=$mkdirprog
142b528cefcSMark Murray	fi
143b528cefcSMark Murrayelse
144b528cefcSMark Murray
145b528cefcSMark Murray# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
146b528cefcSMark Murray# might cause directories to be created, which would be especially bad
147b528cefcSMark Murray# if $src (and thus $dsttmp) contains '*'.
148b528cefcSMark Murray
1491c43270aSJacques Vidrine	if [ -f "$src" ] || [ -d "$src" ]
150b528cefcSMark Murray	then
1518373020dSJacques Vidrine		:
152b528cefcSMark Murray	else
1531c43270aSJacques Vidrine		echo "$0: $src does not exist" >&2
154b528cefcSMark Murray		exit 1
155b528cefcSMark Murray	fi
156b528cefcSMark Murray
157b528cefcSMark Murray	if [ x"$dst" = x ]
158b528cefcSMark Murray	then
1591c43270aSJacques Vidrine		echo "$0: no destination specified" >&2
160b528cefcSMark Murray		exit 1
161b528cefcSMark Murray	else
1628373020dSJacques Vidrine		:
163b528cefcSMark Murray	fi
164b528cefcSMark Murray
165b528cefcSMark Murray# If destination is a directory, append the input filename; if your system
166b528cefcSMark Murray# does not like double slashes in filenames, you may need to add some logic
167b528cefcSMark Murray
1681c43270aSJacques Vidrine	if [ -d "$dst" ]
169b528cefcSMark Murray	then
1701c43270aSJacques Vidrine		dst=$dst/`basename "$src"`
171b528cefcSMark Murray	else
1728373020dSJacques Vidrine		:
173b528cefcSMark Murray	fi
174b528cefcSMark Murrayfi
175b528cefcSMark Murray
176b528cefcSMark Murray## this sed command emulates the dirname command
1771c43270aSJacques Vidrinedstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
178b528cefcSMark Murray
179b528cefcSMark Murray# Make sure that the destination directory exists.
180b528cefcSMark Murray#  this part is taken from Noah Friedman's mkinstalldirs script
181b528cefcSMark Murray
182b528cefcSMark Murray# Skip lots of stat calls in the usual case.
183b528cefcSMark Murrayif [ ! -d "$dstdir" ]; then
184b528cefcSMark MurraydefaultIFS='
185b528cefcSMark Murray	'
1861c43270aSJacques VidrineIFS="${IFS-$defaultIFS}"
187b528cefcSMark Murray
1881c43270aSJacques VidrineoIFS=$IFS
189b528cefcSMark Murray# Some sh's can't handle IFS=/ for some reason.
190b528cefcSMark MurrayIFS='%'
1911c43270aSJacques Vidrineset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
1921c43270aSJacques VidrineIFS=$oIFS
193b528cefcSMark Murray
194b528cefcSMark Murraypathcomp=''
195b528cefcSMark Murray
196b528cefcSMark Murraywhile [ $# -ne 0 ] ; do
1971c43270aSJacques Vidrine	pathcomp=$pathcomp$1
198b528cefcSMark Murray	shift
199b528cefcSMark Murray
2001c43270aSJacques Vidrine	if [ ! -d "$pathcomp" ] ;
201b528cefcSMark Murray        then
2021c43270aSJacques Vidrine		$mkdirprog "$pathcomp"
203b528cefcSMark Murray	else
2048373020dSJacques Vidrine		:
205b528cefcSMark Murray	fi
206b528cefcSMark Murray
2071c43270aSJacques Vidrine	pathcomp=$pathcomp/
208b528cefcSMark Murraydone
209b528cefcSMark Murrayfi
210b528cefcSMark Murray
211b528cefcSMark Murrayif [ x"$dir_arg" != x ]
212b528cefcSMark Murraythen
2131c43270aSJacques Vidrine	$doit $instcmd "$dst" &&
214b528cefcSMark Murray
2151c43270aSJacques Vidrine	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
2161c43270aSJacques Vidrine	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
2171c43270aSJacques Vidrine	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
2181c43270aSJacques Vidrine	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
219b528cefcSMark Murrayelse
220b528cefcSMark Murray
221b528cefcSMark Murray# If we're going to rename the final executable, determine the name now.
222b528cefcSMark Murray
223b528cefcSMark Murray	if [ x"$transformarg" = x ]
224b528cefcSMark Murray	then
2251c43270aSJacques Vidrine		dstfile=`basename "$dst"`
226b528cefcSMark Murray	else
2271c43270aSJacques Vidrine		dstfile=`basename "$dst" $transformbasename |
228b528cefcSMark Murray			sed $transformarg`$transformbasename
229b528cefcSMark Murray	fi
230b528cefcSMark Murray
231b528cefcSMark Murray# don't allow the sed command to completely eliminate the filename
232b528cefcSMark Murray
233b528cefcSMark Murray	if [ x"$dstfile" = x ]
234b528cefcSMark Murray	then
2351c43270aSJacques Vidrine		dstfile=`basename "$dst"`
236b528cefcSMark Murray	else
2378373020dSJacques Vidrine		:
238b528cefcSMark Murray	fi
239b528cefcSMark Murray
2401c43270aSJacques Vidrine# Make a couple of temp file names in the proper directory.
241b528cefcSMark Murray
2421c43270aSJacques Vidrine	dsttmp=$dstdir/_inst.$$_
2431c43270aSJacques Vidrine	rmtmp=$dstdir/_rm.$$_
2441c43270aSJacques Vidrine
2451c43270aSJacques Vidrine# Trap to clean up temp files at exit.
2461c43270aSJacques Vidrine
2471c43270aSJacques Vidrine	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
2481c43270aSJacques Vidrine	trap '(exit $?); exit' 1 2 13 15
249b528cefcSMark Murray
250b528cefcSMark Murray# Move or copy the file name to the temp name
251b528cefcSMark Murray
2521c43270aSJacques Vidrine	$doit $instcmd "$src" "$dsttmp" &&
253b528cefcSMark Murray
254b528cefcSMark Murray# and set any options; do chmod last to preserve setuid bits
255b528cefcSMark Murray
256b528cefcSMark Murray# If any of these fail, we abort the whole thing.  If we want to
257b528cefcSMark Murray# ignore errors from any of these, just make sure not to ignore
258b528cefcSMark Murray# errors from the above "$doit $instcmd $src $dsttmp" command.
259b528cefcSMark Murray
2601c43270aSJacques Vidrine	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
2611c43270aSJacques Vidrine	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
2621c43270aSJacques Vidrine	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
2631c43270aSJacques Vidrine	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
2641c43270aSJacques Vidrine
2651c43270aSJacques Vidrine# Now remove or move aside any old file at destination location.  We try this
2661c43270aSJacques Vidrine# two ways since rm can't unlink itself on some systems and the destination
2671c43270aSJacques Vidrine# file might be busy for other reasons.  In this case, the final cleanup
2681c43270aSJacques Vidrine# might fail but the new file should still install successfully.
2691c43270aSJacques Vidrine
2701c43270aSJacques Vidrine{
2711c43270aSJacques Vidrine	if [ -f "$dstdir/$dstfile" ]
2721c43270aSJacques Vidrine	then
2731c43270aSJacques Vidrine		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
2741c43270aSJacques Vidrine		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
2751c43270aSJacques Vidrine		{
2761c43270aSJacques Vidrine		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
2771c43270aSJacques Vidrine		  (exit 1); exit
2781c43270aSJacques Vidrine		}
2791c43270aSJacques Vidrine	else
2801c43270aSJacques Vidrine		:
2811c43270aSJacques Vidrine	fi
2821c43270aSJacques Vidrine} &&
283b528cefcSMark Murray
284b528cefcSMark Murray# Now rename the file to the real destination.
285b528cefcSMark Murray
2861c43270aSJacques Vidrine	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
287b528cefcSMark Murray
288b528cefcSMark Murrayfi &&
289b528cefcSMark Murray
2901c43270aSJacques Vidrine# The final little trick to "correctly" pass the exit status to the exit trap.
291b528cefcSMark Murray
2921c43270aSJacques Vidrine{
2931c43270aSJacques Vidrine	(exit 0); exit
2941c43270aSJacques Vidrine}
295