xref: /aoo42x/main/install-sh (revision cdf0e10c)
1*cdf0e10cSrcweir#!/bin/sh
2*cdf0e10cSrcweir#
3*cdf0e10cSrcweir# install - install a program, script, or datafile
4*cdf0e10cSrcweir# This comes from X11R5 (mit/util/scripts/install.sh).
5*cdf0e10cSrcweir#
6*cdf0e10cSrcweir# Copyright 1991 by the Massachusetts Institute of Technology
7*cdf0e10cSrcweir#
8*cdf0e10cSrcweir# Permission to use, copy, modify, distribute, and sell this software and its
9*cdf0e10cSrcweir# documentation for any purpose is hereby granted without fee, provided that
10*cdf0e10cSrcweir# the above copyright notice appear in all copies and that both that
11*cdf0e10cSrcweir# copyright notice and this permission notice appear in supporting
12*cdf0e10cSrcweir# documentation, and that the name of M.I.T. not be used in advertising or
13*cdf0e10cSrcweir# publicity pertaining to distribution of the software without specific,
14*cdf0e10cSrcweir# written prior permission.  M.I.T. makes no representations about the
15*cdf0e10cSrcweir# suitability of this software for any purpose.  It is provided "as is"
16*cdf0e10cSrcweir# without express or implied warranty.
17*cdf0e10cSrcweir#
18*cdf0e10cSrcweir# Calling this script install-sh is preferred over install.sh, to prevent
19*cdf0e10cSrcweir# `make' implicit rules from creating a file called install from it
20*cdf0e10cSrcweir# when there is no Makefile.
21*cdf0e10cSrcweir#
22*cdf0e10cSrcweir# This script is compatible with the BSD install script, but was written
23*cdf0e10cSrcweir# from scratch.  It can only install one file at a time, a restriction
24*cdf0e10cSrcweir# shared with many OS's install programs.
25*cdf0e10cSrcweir
26*cdf0e10cSrcweir
27*cdf0e10cSrcweir# set DOITPROG to echo to test this script
28*cdf0e10cSrcweir
29*cdf0e10cSrcweir# Don't use :- since 4.3BSD and earlier shells don't like it.
30*cdf0e10cSrcweirdoit="${DOITPROG-}"
31*cdf0e10cSrcweir
32*cdf0e10cSrcweir
33*cdf0e10cSrcweir# put in absolute paths if you don't have them in your path; or use env. vars.
34*cdf0e10cSrcweir
35*cdf0e10cSrcweirmvprog="${MVPROG-mv}"
36*cdf0e10cSrcweircpprog="${CPPROG-cp}"
37*cdf0e10cSrcweirchmodprog="${CHMODPROG-chmod}"
38*cdf0e10cSrcweirchownprog="${CHOWNPROG-chown}"
39*cdf0e10cSrcweirchgrpprog="${CHGRPPROG-chgrp}"
40*cdf0e10cSrcweirstripprog="${STRIPPROG-strip}"
41*cdf0e10cSrcweirrmprog="${RMPROG-rm}"
42*cdf0e10cSrcweirmkdirprog="${MKDIRPROG-mkdir}"
43*cdf0e10cSrcweir
44*cdf0e10cSrcweirtransformbasename=""
45*cdf0e10cSrcweirtransform_arg=""
46*cdf0e10cSrcweirinstcmd="$mvprog"
47*cdf0e10cSrcweirchmodcmd="$chmodprog 0755"
48*cdf0e10cSrcweirchowncmd=""
49*cdf0e10cSrcweirchgrpcmd=""
50*cdf0e10cSrcweirstripcmd=""
51*cdf0e10cSrcweirrmcmd="$rmprog -f"
52*cdf0e10cSrcweirmvcmd="$mvprog"
53*cdf0e10cSrcweirsrc=""
54*cdf0e10cSrcweirdst=""
55*cdf0e10cSrcweirdir_arg=""
56*cdf0e10cSrcweir
57*cdf0e10cSrcweirwhile [ x"$1" != x ]; do
58*cdf0e10cSrcweir    case $1 in
59*cdf0e10cSrcweir	-c) instcmd=$cpprog
60*cdf0e10cSrcweir	    shift
61*cdf0e10cSrcweir	    continue;;
62*cdf0e10cSrcweir
63*cdf0e10cSrcweir	-d) dir_arg=true
64*cdf0e10cSrcweir	    shift
65*cdf0e10cSrcweir	    continue;;
66*cdf0e10cSrcweir
67*cdf0e10cSrcweir	-m) chmodcmd="$chmodprog $2"
68*cdf0e10cSrcweir	    shift
69*cdf0e10cSrcweir	    shift
70*cdf0e10cSrcweir	    continue;;
71*cdf0e10cSrcweir
72*cdf0e10cSrcweir	-o) chowncmd="$chownprog $2"
73*cdf0e10cSrcweir	    shift
74*cdf0e10cSrcweir	    shift
75*cdf0e10cSrcweir	    continue;;
76*cdf0e10cSrcweir
77*cdf0e10cSrcweir	-g) chgrpcmd="$chgrpprog $2"
78*cdf0e10cSrcweir	    shift
79*cdf0e10cSrcweir	    shift
80*cdf0e10cSrcweir	    continue;;
81*cdf0e10cSrcweir
82*cdf0e10cSrcweir	-s) stripcmd=$stripprog
83*cdf0e10cSrcweir	    shift
84*cdf0e10cSrcweir	    continue;;
85*cdf0e10cSrcweir
86*cdf0e10cSrcweir	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
87*cdf0e10cSrcweir	    shift
88*cdf0e10cSrcweir	    continue;;
89*cdf0e10cSrcweir
90*cdf0e10cSrcweir	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
91*cdf0e10cSrcweir	    shift
92*cdf0e10cSrcweir	    continue;;
93*cdf0e10cSrcweir
94*cdf0e10cSrcweir	*)  if [ x"$src" = x ]
95*cdf0e10cSrcweir	    then
96*cdf0e10cSrcweir		src=$1
97*cdf0e10cSrcweir	    else
98*cdf0e10cSrcweir		# this colon is to work around a 386BSD /bin/sh bug
99*cdf0e10cSrcweir		:
100*cdf0e10cSrcweir		dst=$1
101*cdf0e10cSrcweir	    fi
102*cdf0e10cSrcweir	    shift
103*cdf0e10cSrcweir	    continue;;
104*cdf0e10cSrcweir    esac
105*cdf0e10cSrcweirdone
106*cdf0e10cSrcweir
107*cdf0e10cSrcweirif [ x"$src" = x ]
108*cdf0e10cSrcweirthen
109*cdf0e10cSrcweir	echo "$0: no input file specified" >&2
110*cdf0e10cSrcweir	exit 1
111*cdf0e10cSrcweirelse
112*cdf0e10cSrcweir	:
113*cdf0e10cSrcweirfi
114*cdf0e10cSrcweir
115*cdf0e10cSrcweirif [ x"$dir_arg" != x ]; then
116*cdf0e10cSrcweir	dst=$src
117*cdf0e10cSrcweir	src=""
118*cdf0e10cSrcweir
119*cdf0e10cSrcweir	if [ -d "$dst" ]; then
120*cdf0e10cSrcweir		instcmd=:
121*cdf0e10cSrcweir		chmodcmd=""
122*cdf0e10cSrcweir	else
123*cdf0e10cSrcweir		instcmd=$mkdirprog
124*cdf0e10cSrcweir	fi
125*cdf0e10cSrcweirelse
126*cdf0e10cSrcweir
127*cdf0e10cSrcweir# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
128*cdf0e10cSrcweir# might cause directories to be created, which would be especially bad
129*cdf0e10cSrcweir# if $src (and thus $dsttmp) contains '*'.
130*cdf0e10cSrcweir
131*cdf0e10cSrcweir	if [ -f "$src" ] || [ -d "$src" ]
132*cdf0e10cSrcweir	then
133*cdf0e10cSrcweir		:
134*cdf0e10cSrcweir	else
135*cdf0e10cSrcweir		echo "$0: $src does not exist" >&2
136*cdf0e10cSrcweir		exit 1
137*cdf0e10cSrcweir	fi
138*cdf0e10cSrcweir
139*cdf0e10cSrcweir	if [ x"$dst" = x ]
140*cdf0e10cSrcweir	then
141*cdf0e10cSrcweir		echo "$0: no destination specified" >&2
142*cdf0e10cSrcweir		exit 1
143*cdf0e10cSrcweir	else
144*cdf0e10cSrcweir		:
145*cdf0e10cSrcweir	fi
146*cdf0e10cSrcweir
147*cdf0e10cSrcweir# If destination is a directory, append the input filename; if your system
148*cdf0e10cSrcweir# does not like double slashes in filenames, you may need to add some logic
149*cdf0e10cSrcweir
150*cdf0e10cSrcweir	if [ -d "$dst" ]
151*cdf0e10cSrcweir	then
152*cdf0e10cSrcweir		dst=$dst/`basename "$src"`
153*cdf0e10cSrcweir	else
154*cdf0e10cSrcweir		:
155*cdf0e10cSrcweir	fi
156*cdf0e10cSrcweirfi
157*cdf0e10cSrcweir
158*cdf0e10cSrcweir## this sed command emulates the dirname command
159*cdf0e10cSrcweirdstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
160*cdf0e10cSrcweir
161*cdf0e10cSrcweir# Make sure that the destination directory exists.
162*cdf0e10cSrcweir#  this part is taken from Noah Friedman's mkinstalldirs script
163*cdf0e10cSrcweir
164*cdf0e10cSrcweir# Skip lots of stat calls in the usual case.
165*cdf0e10cSrcweirif [ ! -d "$dstdir" ]; then
166*cdf0e10cSrcweirdefaultIFS='
167*cdf0e10cSrcweir	'
168*cdf0e10cSrcweirIFS="${IFS-$defaultIFS}"
169*cdf0e10cSrcweir
170*cdf0e10cSrcweiroIFS=$IFS
171*cdf0e10cSrcweir# Some sh's can't handle IFS=/ for some reason.
172*cdf0e10cSrcweirIFS='%'
173*cdf0e10cSrcweirset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
174*cdf0e10cSrcweirIFS=$oIFS
175*cdf0e10cSrcweir
176*cdf0e10cSrcweirpathcomp=''
177*cdf0e10cSrcweir
178*cdf0e10cSrcweirwhile [ $# -ne 0 ] ; do
179*cdf0e10cSrcweir	pathcomp=$pathcomp$1
180*cdf0e10cSrcweir	shift
181*cdf0e10cSrcweir
182*cdf0e10cSrcweir	if [ ! -d "$pathcomp" ] ;
183*cdf0e10cSrcweir        then
184*cdf0e10cSrcweir		$mkdirprog "$pathcomp"
185*cdf0e10cSrcweir	else
186*cdf0e10cSrcweir		:
187*cdf0e10cSrcweir	fi
188*cdf0e10cSrcweir
189*cdf0e10cSrcweir	pathcomp=$pathcomp/
190*cdf0e10cSrcweirdone
191*cdf0e10cSrcweirfi
192*cdf0e10cSrcweir
193*cdf0e10cSrcweirif [ x"$dir_arg" != x ]
194*cdf0e10cSrcweirthen
195*cdf0e10cSrcweir	$doit $instcmd "$dst" &&
196*cdf0e10cSrcweir
197*cdf0e10cSrcweir	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
198*cdf0e10cSrcweir	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
199*cdf0e10cSrcweir	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
200*cdf0e10cSrcweir	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
201*cdf0e10cSrcweirelse
202*cdf0e10cSrcweir
203*cdf0e10cSrcweir# If we're going to rename the final executable, determine the name now.
204*cdf0e10cSrcweir
205*cdf0e10cSrcweir	if [ x"$transformarg" = x ]
206*cdf0e10cSrcweir	then
207*cdf0e10cSrcweir		dstfile=`basename "$dst"`
208*cdf0e10cSrcweir	else
209*cdf0e10cSrcweir		dstfile=`basename "$dst" $transformbasename |
210*cdf0e10cSrcweir			sed $transformarg`$transformbasename
211*cdf0e10cSrcweir	fi
212*cdf0e10cSrcweir
213*cdf0e10cSrcweir# don't allow the sed command to completely eliminate the filename
214*cdf0e10cSrcweir
215*cdf0e10cSrcweir	if [ x"$dstfile" = x ]
216*cdf0e10cSrcweir	then
217*cdf0e10cSrcweir		dstfile=`basename "$dst"`
218*cdf0e10cSrcweir	else
219*cdf0e10cSrcweir		:
220*cdf0e10cSrcweir	fi
221*cdf0e10cSrcweir
222*cdf0e10cSrcweir# Make a couple of temp file names in the proper directory.
223*cdf0e10cSrcweir
224*cdf0e10cSrcweir	dsttmp=$dstdir/#inst.$$#
225*cdf0e10cSrcweir	rmtmp=$dstdir/#rm.$$#
226*cdf0e10cSrcweir
227*cdf0e10cSrcweir# Trap to clean up temp files at exit.
228*cdf0e10cSrcweir
229*cdf0e10cSrcweir	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
230*cdf0e10cSrcweir	trap '(exit $?); exit' 1 2 13 15
231*cdf0e10cSrcweir
232*cdf0e10cSrcweir# Move or copy the file name to the temp name
233*cdf0e10cSrcweir
234*cdf0e10cSrcweir	$doit $instcmd "$src" "$dsttmp" &&
235*cdf0e10cSrcweir
236*cdf0e10cSrcweir# and set any options; do chmod last to preserve setuid bits
237*cdf0e10cSrcweir
238*cdf0e10cSrcweir# If any of these fail, we abort the whole thing.  If we want to
239*cdf0e10cSrcweir# ignore errors from any of these, just make sure not to ignore
240*cdf0e10cSrcweir# errors from the above "$doit $instcmd $src $dsttmp" command.
241*cdf0e10cSrcweir
242*cdf0e10cSrcweir	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
243*cdf0e10cSrcweir	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
244*cdf0e10cSrcweir	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
245*cdf0e10cSrcweir	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
246*cdf0e10cSrcweir
247*cdf0e10cSrcweir# Now remove or move aside any old file at destination location.  We try this
248*cdf0e10cSrcweir# two ways since rm can't unlink itself on some systems and the destination
249*cdf0e10cSrcweir# file might be busy for other reasons.  In this case, the final cleanup
250*cdf0e10cSrcweir# might fail but the new file should still install successfully.
251*cdf0e10cSrcweir
252*cdf0e10cSrcweir{
253*cdf0e10cSrcweir	if [ -f "$dstdir/$dstfile" ]
254*cdf0e10cSrcweir	then
255*cdf0e10cSrcweir		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
256*cdf0e10cSrcweir		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
257*cdf0e10cSrcweir		{
258*cdf0e10cSrcweir		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
259*cdf0e10cSrcweir		  (exit 1); exit
260*cdf0e10cSrcweir		}
261*cdf0e10cSrcweir	else
262*cdf0e10cSrcweir		:
263*cdf0e10cSrcweir	fi
264*cdf0e10cSrcweir} &&
265*cdf0e10cSrcweir
266*cdf0e10cSrcweir# Now rename the file to the real destination.
267*cdf0e10cSrcweir
268*cdf0e10cSrcweir	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
269*cdf0e10cSrcweir
270*cdf0e10cSrcweirfi &&
271*cdf0e10cSrcweir
272*cdf0e10cSrcweir# The final little trick to "correctly" pass the exit status to the exit trap.
273*cdf0e10cSrcweir
274*cdf0e10cSrcweir{
275*cdf0e10cSrcweir	(exit 0); exit
276*cdf0e10cSrcweir}
277