install-sh revision 127808
1168054Sflz#!/bin/sh
2168054Sflz#
3168266Sgabor# install - install a program, script, or datafile
4168266Sgabor#
5168266Sgabor# This originates from X11R5 (mit/util/scripts/install.sh), which was
6168266Sgabor# later released in X11R6 (xc/config/util/install.sh) with the
7168266Sgabor# following copyright and license.
8168266Sgabor#
9168266Sgabor# Copyright (C) 1994 X Consortium
10168266Sgabor#
11168054Sflz# Permission is hereby granted, free of charge, to any person obtaining a copy
12168054Sflz# of this software and associated documentation files (the "Software"), to
13168064Sflz# deal in the Software without restriction, including without limitation the
14168064Sflz# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
15168064Sflz# sell copies of the Software, and to permit persons to whom the Software is
16168064Sflz# furnished to do so, subject to the following conditions:
17168064Sflz#
18168064Sflz# The above copyright notice and this permission notice shall be included in
19168064Sflz# all copies or substantial portions of the Software.
20168064Sflz#
21168064Sflz# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22168064Sflz# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23168064Sflz# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
24168064Sflz# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
25168064Sflz# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
26168064Sflz# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27168054Sflz#
28168054Sflz# Except as contained in this notice, the name of the X Consortium shall not
29168064Sflz# be used in advertising or otherwise to promote the sale, use or other deal-
30168054Sflz# ings in this Software without prior written authorization from the X Consor-
31168064Sflz# tium.
32168939Stmclaugh#
33168131Sbmah#
34168113Smarcus# FSF changes to this file are in the public domain.
35168123Snetchild#
36168939Stmclaugh# Calling this script install-sh is preferred over install.sh, to prevent
37168064Sflz# `make' implicit rules from creating a file called install from it
38168054Sflz# when there is no Makefile.
39168054Sflz#
40168054Sflz# This script is compatible with the BSD install script, but was written
41168054Sflz# from scratch.  It can only install one file at a time, a restriction
42168261Sache# shared with many OS's install programs.
43168077Sflz
44168077Sflz
45168126Sale# set DOITPROG to echo to test this script
46168069Sgarga
47168472Snovel# Don't use :- since 4.3BSD and earlier shells don't like it.
48168274Ssemdoit="${DOITPROG-}"
49168667Sstefan
50168274Ssem
51168113Smarcus# put in absolute paths if you don't have them in your path; or use env. vars.
52168098Skrion
53168123Snetchildmvprog="${MVPROG-mv}"
54168082Sgargacpprog="${CPPROG-cp}"
55168116Sclsungchmodprog="${CHMODPROG-chmod}"
56168937Scpercivachownprog="${CHOWNPROG-chown}"
57168177Sgaborchgrpprog="${CHGRPPROG-chgrp}"
58168354Sdanfestripprog="${STRIPPROG-strip}"
59168072Sehauptrmprog="${RMPROG-rm}"
60168108Srafanmkdirprog="${MKDIRPROG-mkdir}"
61168186Smat
62168210Sitetcutransformbasename=""
63168068Serwintransform_arg=""
64168072Sehauptinstcmd="$mvprog"
65168113Smarcuschmodcmd="$chmodprog 0755"
66168059Sgaborchowncmd=""
67168542Smiwichgrpcmd=""
68168098Skrionstripcmd=""
69168054Sflzrmcmd="$rmprog -f"
70168059Sgabormvcmd="$mvprog"
71168054Sflzsrc=""
72168256Sijliaodst=""
73168209Sitetcudir_arg=""
74168076Sjmelo
75168123Snetchildwhile [ x"$1" != x ]; do
76168054Sflz    case $1 in
77168055Spav	-c) instcmd=$cpprog
78168055Spav	    shift
79168536Skevlo	    continue;;
80168177Sgabor
81168098Skrion	-d) dir_arg=true
82168055Spav	    shift
83168161Sphilip	    continue;;
84168054Sflz
85168208Sitetcu	-m) chmodcmd="$chmodprog $2"
86168295Sleeym	    shift
87168295Sleeym	    shift
88168939Stmclaugh	    continue;;
89168068Serwin
90168337Slwhsu	-o) chowncmd="$chownprog $2"
91168177Sgabor	    shift
92168113Smarcus	    shift
93168918Sbrueffer	    continue;;
94168186Smat
95168055Spav	-g) chgrpcmd="$chgrpprog $2"
96168098Skrion	    shift
97168359Smm	    shift
98168100Smnag	    continue;;
99168123Snetchild
100168177Sgabor	-s) stripcmd=$stripprog
101168134Snork	    shift
102168084Sehaupt	    continue;;
103168542Smiwi
104168939Stmclaugh	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
105168054Sflz	    shift
106168098Skrion	    continue;;
107168108Srafan
108168098Skrion	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
109168098Skrion	    shift
110168098Skrion	    continue;;
111168055Spav
112168068Serwin	*)  if [ x"$src" = x ]
113168939Stmclaugh	    then
114168290Ssem		src=$1
115168667Sstefan	    else
116168125Stdb		# this colon is to work around a 386BSD /bin/sh bug
117169018Strasz		:
118168225Strhodes		dst=$1
119168186Smat	    fi
120168061Sahze	    shift
121168069Sgarga	    continue;;
122168935Stmclaugh    esac
123168054Sflzdone
124168054Sflz
125168064Sflzif [ x"$src" = x ]
126168064Sflzthen
127168054Sflz	echo "$0: no input file specified" >&2
128168055Spav	exit 1
129168055Spavelse
130168055Spav	:
131168055Spavfi
132168055Spav
133168055Spavif [ x"$dir_arg" != x ]; then
134168057Sahze	dst=$src
135168055Spav	src=""
136168919Sbrueffer
137168667Sstefan	if [ -d "$dst" ]; then
138168667Sstefan		instcmd=:
139168939Stmclaugh		chmodcmd=""
140168939Stmclaugh	else
141168939Stmclaugh		instcmd=$mkdirprog
142168125Stdb	fi
143168208Sitetcuelse
144168125Stdb
145168337Slwhsu# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
146168337Slwhsu# might cause directories to be created, which would be especially bad
147168108Srafan# if $src (and thus $dsttmp) contains '*'.
148168108Srafan
149168186Smat	if [ -f "$src" ] || [ -d "$src" ]
150168186Smat	then
151168938Scperciva		:
152168068Serwin	else
153168068Serwin		echo "$0: $src does not exist" >&2
154168072Sehaupt		exit 1
155168072Sehaupt	fi
156168274Ssem
157168225Strhodes	if [ x"$dst" = x ]
158168225Strhodes	then
159168068Serwin		echo "$0: no destination specified" >&2
160168059Sgabor		exit 1
161168068Serwin	else
162168068Serwin		:
163168068Serwin	fi
164168059Sgabor
165168354Sdanfe# If destination is a directory, append the input filename; if your system
166168098Skrion# does not like double slashes in filenames, you may need to add some logic
167168098Skrion
168168054Sflz	if [ -d "$dst" ]
169168054Sflz	then
170168054Sflz		dst=$dst/`basename "$src"`
171168054Sflz	else
172168069Sgarga		:
173168069Sgarga	fi
174168359Smmfi
175168069Sgarga
176168935Stmclaugh## this sed command emulates the dirname command
177168069Sgargadstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
178168295Sleeym
179168295Sleeym# Make sure that the destination directory exists.
180168210Sitetcu#  this part is taken from Noah Friedman's mkinstalldirs script
181168210Sitetcu
182168123Snetchild# Skip lots of stat calls in the usual case.
183168123Snetchildif [ ! -d "$dstdir" ]; then
184168134SnorkdefaultIFS='
185168134Snork	'
186168134SnorkIFS="${IFS-$defaultIFS}"
187168134Snork
188168134SnorkoIFS=$IFS
189168098Skrion# Some sh's can't handle IFS=/ for some reason.
190168098SkrionIFS='%'
191168098Skrionset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
192168098SkrionIFS=$oIFS
193168098Skrion
194168098Skrionpathcomp=''
195168098Skrion
196168098Skrionwhile [ $# -ne 0 ] ; do
197168209Sitetcu	pathcomp=$pathcomp$1
198168209Sitetcu	shift
199168295Sleeym
200168295Sleeym	if [ ! -d "$pathcomp" ] ;
201168939Stmclaugh        then
202168939Stmclaugh		$mkdirprog "$pathcomp"
203168687Sahze	else
204168113Smarcus		:
205168113Smarcus	fi
206168113Smarcus
207168113Smarcus	pathcomp=$pathcomp/
208168186Smatdone
209168186Smatfi
210168936Stmclaugh
211168936Stmclaughif [ x"$dir_arg" != x ]
212168542Smiwithen
213168542Smiwi	$doit $instcmd "$dst" &&
214169018Strasz
215168542Smiwi	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
216168076Sjmelo	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
217168076Sjmelo	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
218168123Snetchild	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
219168123Snetchildelse
220168126Sale
221168126Sale# If we're going to rename the final executable, determine the name now.
222168472Snovel
223168084Sehaupt	if [ x"$transformarg" = x ]
224168084Sehaupt	then
225168939Stmclaugh		dstfile=`basename "$dst"`
226168939Stmclaugh	else
227168687Sahze		dstfile=`basename "$dst" $transformbasename |
228168054Sflz			sed $transformarg`$transformbasename
229168055Spav	fi
230168055Spav
231168055Spav# don't allow the sed command to completely eliminate the filename
232168054Sflz
233168161Sphilip	if [ x"$dstfile" = x ]
234168161Sphilip	then
235168274Ssem		dstfile=`basename "$dst"`
236168274Ssem	else
237168108Srafan		:
238168274Ssem	fi
239168108Srafan
240168939Stmclaugh# Make a couple of temp file names in the proper directory.
241168939Stmclaugh
242168123Snetchild	dsttmp=$dstdir/_inst.$$_
243168123Snetchild	rmtmp=$dstdir/_rm.$$_
244168209Sitetcu
245168935Stmclaugh# Trap to clean up temp files at exit.
246168209Sitetcu
247168939Stmclaugh	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
248168939Stmclaugh	trap '(exit $?); exit' 1 2 13 15
249168054Sflz
250# Move or copy the file name to the temp name
251
252	$doit $instcmd "$src" "$dsttmp" &&
253
254# and set any options; do chmod last to preserve setuid bits
255
256# If any of these fail, we abort the whole thing.  If we want to
257# ignore errors from any of these, just make sure not to ignore
258# errors from the above "$doit $instcmd $src $dsttmp" command.
259
260	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
261	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
262	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
263	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
264
265# Now remove or move aside any old file at destination location.  We try this
266# two ways since rm can't unlink itself on some systems and the destination
267# file might be busy for other reasons.  In this case, the final cleanup
268# might fail but the new file should still install successfully.
269
270{
271	if [ -f "$dstdir/$dstfile" ]
272	then
273		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
274		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
275		{
276		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
277		  (exit 1); exit
278		}
279	else
280		:
281	fi
282} &&
283
284# Now rename the file to the real destination.
285
286	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
287
288fi &&
289
290# The final little trick to "correctly" pass the exit status to the exit trap.
291
292{
293	(exit 0); exit
294}
295