install-sh revision 439fab64
1439fab64Smrg#!/bin/sh
2439fab64Smrg#
3439fab64Smrg# install - install a program, script, or datafile
4439fab64Smrg#
5439fab64Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
6439fab64Smrg# later released in X11R6 (xc/config/util/install.sh) with the
7439fab64Smrg# following copyright and license.
8439fab64Smrg#
9439fab64Smrg# Copyright (C) 1994 X Consortium
10439fab64Smrg#
11439fab64Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
12439fab64Smrg# of this software and associated documentation files (the "Software"), to
13439fab64Smrg# deal in the Software without restriction, including without limitation the
14439fab64Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
15439fab64Smrg# sell copies of the Software, and to permit persons to whom the Software is
16439fab64Smrg# furnished to do so, subject to the following conditions:
17439fab64Smrg#
18439fab64Smrg# The above copyright notice and this permission notice shall be included in
19439fab64Smrg# all copies or substantial portions of the Software.
20439fab64Smrg#
21439fab64Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22439fab64Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23439fab64Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
24439fab64Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
25439fab64Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
26439fab64Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27439fab64Smrg#
28439fab64Smrg# Except as contained in this notice, the name of the X Consortium shall not
29439fab64Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
30439fab64Smrg# ings in this Software without prior written authorization from the X Consor-
31439fab64Smrg# tium.
32439fab64Smrg#
33439fab64Smrg#
34439fab64Smrg# FSF changes to this file are in the public domain.
35439fab64Smrg#
36439fab64Smrg# Calling this script install-sh is preferred over install.sh, to prevent
37439fab64Smrg# `make' implicit rules from creating a file called install from it
38439fab64Smrg# when there is no Makefile.
39439fab64Smrg#
40439fab64Smrg# This script is compatible with the BSD install script, but was written
41439fab64Smrg# from scratch.  It can only install one file at a time, a restriction
42439fab64Smrg# shared with many OS's install programs.
43439fab64Smrg
44439fab64Smrg
45439fab64Smrg# set DOITPROG to echo to test this script
46439fab64Smrg
47439fab64Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
48439fab64Smrgdoit="${DOITPROG-}"
49439fab64Smrg
50439fab64Smrg
51439fab64Smrg# put in absolute paths if you don't have them in your path; or use env. vars.
52439fab64Smrg
53439fab64Smrgmvprog="${MVPROG-mv}"
54439fab64Smrgcpprog="${CPPROG-cp}"
55439fab64Smrgchmodprog="${CHMODPROG-chmod}"
56439fab64Smrgchownprog="${CHOWNPROG-chown}"
57439fab64Smrgchgrpprog="${CHGRPPROG-chgrp}"
58439fab64Smrgstripprog="${STRIPPROG-strip}"
59439fab64Smrgrmprog="${RMPROG-rm}"
60439fab64Smrgmkdirprog="${MKDIRPROG-mkdir}"
61439fab64Smrg
62439fab64Smrgtransformbasename=""
63439fab64Smrgtransform_arg=""
64439fab64Smrginstcmd="$mvprog"
65439fab64Smrgchmodcmd="$chmodprog 0755"
66439fab64Smrgchowncmd=""
67439fab64Smrgchgrpcmd=""
68439fab64Smrgstripcmd=""
69439fab64Smrgrmcmd="$rmprog -f"
70439fab64Smrgmvcmd="$mvprog"
71439fab64Smrgsrc=""
72439fab64Smrgdst=""
73439fab64Smrgdir_arg=""
74439fab64Smrg
75439fab64Smrgwhile [ x"$1" != x ]; do
76439fab64Smrg    case $1 in
77439fab64Smrg	-c) instcmd=$cpprog
78439fab64Smrg	    shift
79439fab64Smrg	    continue;;
80439fab64Smrg
81439fab64Smrg	-d) dir_arg=true
82439fab64Smrg	    shift
83439fab64Smrg	    continue;;
84439fab64Smrg
85439fab64Smrg	-m) chmodcmd="$chmodprog $2"
86439fab64Smrg	    shift
87439fab64Smrg	    shift
88439fab64Smrg	    continue;;
89439fab64Smrg
90439fab64Smrg	-o) chowncmd="$chownprog $2"
91439fab64Smrg	    shift
92439fab64Smrg	    shift
93439fab64Smrg	    continue;;
94439fab64Smrg
95439fab64Smrg	-g) chgrpcmd="$chgrpprog $2"
96439fab64Smrg	    shift
97439fab64Smrg	    shift
98439fab64Smrg	    continue;;
99439fab64Smrg
100439fab64Smrg	-s) stripcmd=$stripprog
101439fab64Smrg	    shift
102439fab64Smrg	    continue;;
103439fab64Smrg
104439fab64Smrg	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
105439fab64Smrg	    shift
106439fab64Smrg	    continue;;
107439fab64Smrg
108439fab64Smrg	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
109439fab64Smrg	    shift
110439fab64Smrg	    continue;;
111439fab64Smrg
112439fab64Smrg	*)  if [ x"$src" = x ]
113439fab64Smrg	    then
114439fab64Smrg		src=$1
115439fab64Smrg	    else
116439fab64Smrg		# this colon is to work around a 386BSD /bin/sh bug
117439fab64Smrg		:
118439fab64Smrg		dst=$1
119439fab64Smrg	    fi
120439fab64Smrg	    shift
121439fab64Smrg	    continue;;
122439fab64Smrg    esac
123439fab64Smrgdone
124439fab64Smrg
125439fab64Smrgif [ x"$src" = x ]
126439fab64Smrgthen
127439fab64Smrg	echo "$0: no input file specified" >&2
128439fab64Smrg	exit 1
129439fab64Smrgelse
130439fab64Smrg	:
131439fab64Smrgfi
132439fab64Smrg
133439fab64Smrgif [ x"$dir_arg" != x ]; then
134439fab64Smrg	dst=$src
135439fab64Smrg	src=""
136439fab64Smrg
137439fab64Smrg	if [ -d "$dst" ]; then
138439fab64Smrg		instcmd=:
139439fab64Smrg		chmodcmd=""
140439fab64Smrg	else
141439fab64Smrg		instcmd=$mkdirprog
142439fab64Smrg	fi
143439fab64Smrgelse
144439fab64Smrg
145439fab64Smrg# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
146439fab64Smrg# might cause directories to be created, which would be especially bad
147439fab64Smrg# if $src (and thus $dsttmp) contains '*'.
148439fab64Smrg
149439fab64Smrg	if [ -f "$src" ] || [ -d "$src" ]
150439fab64Smrg	then
151439fab64Smrg		:
152439fab64Smrg	else
153439fab64Smrg		echo "$0: $src does not exist" >&2
154439fab64Smrg		exit 1
155439fab64Smrg	fi
156439fab64Smrg
157439fab64Smrg	if [ x"$dst" = x ]
158439fab64Smrg	then
159439fab64Smrg		echo "$0: no destination specified" >&2
160439fab64Smrg		exit 1
161439fab64Smrg	else
162439fab64Smrg		:
163439fab64Smrg	fi
164439fab64Smrg
165439fab64Smrg# If destination is a directory, append the input filename; if your system
166439fab64Smrg# does not like double slashes in filenames, you may need to add some logic
167439fab64Smrg
168439fab64Smrg	if [ -d "$dst" ]
169439fab64Smrg	then
170439fab64Smrg		dst=$dst/`basename "$src"`
171439fab64Smrg	else
172439fab64Smrg		:
173439fab64Smrg	fi
174439fab64Smrgfi
175439fab64Smrg
176439fab64Smrg## this sed command emulates the dirname command
177439fab64Smrgdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
178439fab64Smrg
179439fab64Smrg# Make sure that the destination directory exists.
180439fab64Smrg#  this part is taken from Noah Friedman's mkinstalldirs script
181439fab64Smrg
182439fab64Smrg# Skip lots of stat calls in the usual case.
183439fab64Smrgif [ ! -d "$dstdir" ]; then
184439fab64SmrgdefaultIFS='
185439fab64Smrg	'
186439fab64SmrgIFS="${IFS-$defaultIFS}"
187439fab64Smrg
188439fab64SmrgoIFS=$IFS
189439fab64Smrg# Some sh's can't handle IFS=/ for some reason.
190439fab64SmrgIFS='%'
191439fab64Smrgset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
192439fab64SmrgIFS=$oIFS
193439fab64Smrg
194439fab64Smrgpathcomp=''
195439fab64Smrg
196439fab64Smrgwhile [ $# -ne 0 ] ; do
197439fab64Smrg	pathcomp=$pathcomp$1
198439fab64Smrg	shift
199439fab64Smrg
200439fab64Smrg	if [ ! -d "$pathcomp" ] ;
201439fab64Smrg        then
202439fab64Smrg		$mkdirprog "$pathcomp"
203439fab64Smrg	else
204439fab64Smrg		:
205439fab64Smrg	fi
206439fab64Smrg
207439fab64Smrg	pathcomp=$pathcomp/
208439fab64Smrgdone
209439fab64Smrgfi
210439fab64Smrg
211439fab64Smrgif [ x"$dir_arg" != x ]
212439fab64Smrgthen
213439fab64Smrg	$doit $instcmd "$dst" &&
214439fab64Smrg
215439fab64Smrg	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
216439fab64Smrg	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
217439fab64Smrg	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
218439fab64Smrg	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
219439fab64Smrgelse
220439fab64Smrg
221439fab64Smrg# If we're going to rename the final executable, determine the name now.
222439fab64Smrg
223439fab64Smrg	if [ x"$transformarg" = x ]
224439fab64Smrg	then
225439fab64Smrg		dstfile=`basename "$dst"`
226439fab64Smrg	else
227439fab64Smrg		dstfile=`basename "$dst" $transformbasename |
228439fab64Smrg			sed $transformarg`$transformbasename
229439fab64Smrg	fi
230439fab64Smrg
231439fab64Smrg# don't allow the sed command to completely eliminate the filename
232439fab64Smrg
233439fab64Smrg	if [ x"$dstfile" = x ]
234439fab64Smrg	then
235439fab64Smrg		dstfile=`basename "$dst"`
236439fab64Smrg	else
237439fab64Smrg		:
238439fab64Smrg	fi
239439fab64Smrg
240439fab64Smrg# Make a couple of temp file names in the proper directory.
241439fab64Smrg
242439fab64Smrg	dsttmp=$dstdir/_inst.$$_
243439fab64Smrg	rmtmp=$dstdir/_rm.$$_
244439fab64Smrg
245439fab64Smrg# Trap to clean up temp files at exit.
246439fab64Smrg
247439fab64Smrg	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
248439fab64Smrg	trap '(exit $?); exit' 1 2 13 15
249439fab64Smrg
250439fab64Smrg# Move or copy the file name to the temp name
251439fab64Smrg
252439fab64Smrg	$doit $instcmd "$src" "$dsttmp" &&
253439fab64Smrg
254439fab64Smrg# and set any options; do chmod last to preserve setuid bits
255439fab64Smrg
256439fab64Smrg# If any of these fail, we abort the whole thing.  If we want to
257439fab64Smrg# ignore errors from any of these, just make sure not to ignore
258439fab64Smrg# errors from the above "$doit $instcmd $src $dsttmp" command.
259439fab64Smrg
260439fab64Smrg	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
261439fab64Smrg	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
262439fab64Smrg	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
263439fab64Smrg	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
264439fab64Smrg
265439fab64Smrg# Now remove or move aside any old file at destination location.  We try this
266439fab64Smrg# two ways since rm can't unlink itself on some systems and the destination
267439fab64Smrg# file might be busy for other reasons.  In this case, the final cleanup
268439fab64Smrg# might fail but the new file should still install successfully.
269439fab64Smrg
270439fab64Smrg{
271439fab64Smrg	if [ -f "$dstdir/$dstfile" ]
272439fab64Smrg	then
273439fab64Smrg		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
274439fab64Smrg		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
275439fab64Smrg		{
276439fab64Smrg		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
277439fab64Smrg		  (exit 1); exit
278439fab64Smrg		}
279439fab64Smrg	else
280439fab64Smrg		:
281439fab64Smrg	fi
282439fab64Smrg} &&
283439fab64Smrg
284439fab64Smrg# Now rename the file to the real destination.
285439fab64Smrg
286439fab64Smrg	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
287439fab64Smrg
288439fab64Smrgfi &&
289439fab64Smrg
290439fab64Smrg# The final little trick to "correctly" pass the exit status to the exit trap.
291439fab64Smrg
292439fab64Smrg{
293439fab64Smrg	(exit 0); exit
294439fab64Smrg}
295