xref: /aosp_15_r20/external/mtools/install-sh (revision d5c9a868b113e0ec0db2f27bc2ce8a253e77c4b0)
1*d5c9a868SElliott Hughes#! /bin/sh
2*d5c9a868SElliott Hughes#
3*d5c9a868SElliott Hughes# install - install a program, script, or datafile
4*d5c9a868SElliott Hughes# This comes from X11R5.
5*d5c9a868SElliott Hughes#
6*d5c9a868SElliott Hughes# Calling this script install-sh is preferred over install.sh, to prevent
7*d5c9a868SElliott Hughes# `make' implicit rules from creating a file called install from it
8*d5c9a868SElliott Hughes# when there is no Makefile.
9*d5c9a868SElliott Hughes#
10*d5c9a868SElliott Hughes# This script is compatible with the BSD install script, but was written
11*d5c9a868SElliott Hughes# from scratch.
12*d5c9a868SElliott Hughes#
13*d5c9a868SElliott Hughes
14*d5c9a868SElliott Hughes
15*d5c9a868SElliott Hughes# set DOITPROG to echo to test this script
16*d5c9a868SElliott Hughes
17*d5c9a868SElliott Hughes# Don't use :- since 4.3BSD and earlier shells don't like it.
18*d5c9a868SElliott Hughesdoit="${DOITPROG-}"
19*d5c9a868SElliott Hughes
20*d5c9a868SElliott Hughes
21*d5c9a868SElliott Hughes# put in absolute paths if you don't have them in your path; or use env. vars.
22*d5c9a868SElliott Hughes
23*d5c9a868SElliott Hughesmvprog="${MVPROG-mv}"
24*d5c9a868SElliott Hughescpprog="${CPPROG-cp}"
25*d5c9a868SElliott Hugheschmodprog="${CHMODPROG-chmod}"
26*d5c9a868SElliott Hugheschownprog="${CHOWNPROG-chown}"
27*d5c9a868SElliott Hugheschgrpprog="${CHGRPPROG-chgrp}"
28*d5c9a868SElliott Hughesstripprog="${STRIPPROG-strip}"
29*d5c9a868SElliott Hughesrmprog="${RMPROG-rm}"
30*d5c9a868SElliott Hughesmkdirprog="${MKDIRPROG-mkdir}"
31*d5c9a868SElliott Hughes
32*d5c9a868SElliott Hughestranformbasename=""
33*d5c9a868SElliott Hughestransform_arg=""
34*d5c9a868SElliott Hughesinstcmd="$mvprog"
35*d5c9a868SElliott Hugheschmodcmd="$chmodprog 0755"
36*d5c9a868SElliott Hugheschowncmd=""
37*d5c9a868SElliott Hugheschgrpcmd=""
38*d5c9a868SElliott Hughesstripcmd=""
39*d5c9a868SElliott Hughesrmcmd="$rmprog -f"
40*d5c9a868SElliott Hughesmvcmd="$mvprog"
41*d5c9a868SElliott Hughessrc=""
42*d5c9a868SElliott Hughesdst=""
43*d5c9a868SElliott Hughesdir_arg=""
44*d5c9a868SElliott Hughes
45*d5c9a868SElliott Hugheswhile [ x"$1" != x ]; do
46*d5c9a868SElliott Hughes    case $1 in
47*d5c9a868SElliott Hughes	-c) instcmd="$cpprog"
48*d5c9a868SElliott Hughes	    shift
49*d5c9a868SElliott Hughes	    continue;;
50*d5c9a868SElliott Hughes
51*d5c9a868SElliott Hughes	-d) dir_arg=true
52*d5c9a868SElliott Hughes	    shift
53*d5c9a868SElliott Hughes	    continue;;
54*d5c9a868SElliott Hughes
55*d5c9a868SElliott Hughes	-m) chmodcmd="$chmodprog $2"
56*d5c9a868SElliott Hughes	    shift
57*d5c9a868SElliott Hughes	    shift
58*d5c9a868SElliott Hughes	    continue;;
59*d5c9a868SElliott Hughes
60*d5c9a868SElliott Hughes	-o) chowncmd="$chownprog $2"
61*d5c9a868SElliott Hughes	    shift
62*d5c9a868SElliott Hughes	    shift
63*d5c9a868SElliott Hughes	    continue;;
64*d5c9a868SElliott Hughes
65*d5c9a868SElliott Hughes	-g) chgrpcmd="$chgrpprog $2"
66*d5c9a868SElliott Hughes	    shift
67*d5c9a868SElliott Hughes	    shift
68*d5c9a868SElliott Hughes	    continue;;
69*d5c9a868SElliott Hughes
70*d5c9a868SElliott Hughes	-s) stripcmd="$stripprog"
71*d5c9a868SElliott Hughes	    shift
72*d5c9a868SElliott Hughes	    continue;;
73*d5c9a868SElliott Hughes
74*d5c9a868SElliott Hughes	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
75*d5c9a868SElliott Hughes	    shift
76*d5c9a868SElliott Hughes	    continue;;
77*d5c9a868SElliott Hughes
78*d5c9a868SElliott Hughes	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
79*d5c9a868SElliott Hughes	    shift
80*d5c9a868SElliott Hughes	    continue;;
81*d5c9a868SElliott Hughes
82*d5c9a868SElliott Hughes	*)  if [ x"$src" = x ]
83*d5c9a868SElliott Hughes	    then
84*d5c9a868SElliott Hughes		src=$1
85*d5c9a868SElliott Hughes	    else
86*d5c9a868SElliott Hughes		# this colon is to work around a 386BSD /bin/sh bug
87*d5c9a868SElliott Hughes		:
88*d5c9a868SElliott Hughes		dst=$1
89*d5c9a868SElliott Hughes	    fi
90*d5c9a868SElliott Hughes	    shift
91*d5c9a868SElliott Hughes	    continue;;
92*d5c9a868SElliott Hughes    esac
93*d5c9a868SElliott Hughesdone
94*d5c9a868SElliott Hughes
95*d5c9a868SElliott Hughesif [ x"$src" = x ]
96*d5c9a868SElliott Hughesthen
97*d5c9a868SElliott Hughes	echo "install:	no input file specified"
98*d5c9a868SElliott Hughes	exit 1
99*d5c9a868SElliott Hugheselse
100*d5c9a868SElliott Hughes	true
101*d5c9a868SElliott Hughesfi
102*d5c9a868SElliott Hughes
103*d5c9a868SElliott Hughesif [ x"$dir_arg" != x ]; then
104*d5c9a868SElliott Hughes	dst=$src
105*d5c9a868SElliott Hughes	src=""
106*d5c9a868SElliott Hughes
107*d5c9a868SElliott Hughes	if [ -d $dst ]; then
108*d5c9a868SElliott Hughes		instcmd=:
109*d5c9a868SElliott Hughes	else
110*d5c9a868SElliott Hughes		instcmd=mkdir
111*d5c9a868SElliott Hughes	fi
112*d5c9a868SElliott Hugheselse
113*d5c9a868SElliott Hughes
114*d5c9a868SElliott Hughes# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
115*d5c9a868SElliott Hughes# might cause directories to be created, which would be especially bad
116*d5c9a868SElliott Hughes# if $src (and thus $dsttmp) contains '*'.
117*d5c9a868SElliott Hughes
118*d5c9a868SElliott Hughes	if [ -f $src -o -d $src ]
119*d5c9a868SElliott Hughes	then
120*d5c9a868SElliott Hughes		true
121*d5c9a868SElliott Hughes	else
122*d5c9a868SElliott Hughes		echo "install:  $src does not exist"
123*d5c9a868SElliott Hughes		exit 1
124*d5c9a868SElliott Hughes	fi
125*d5c9a868SElliott Hughes
126*d5c9a868SElliott Hughes	if [ x"$dst" = x ]
127*d5c9a868SElliott Hughes	then
128*d5c9a868SElliott Hughes		echo "install:	no destination specified"
129*d5c9a868SElliott Hughes		exit 1
130*d5c9a868SElliott Hughes	else
131*d5c9a868SElliott Hughes		true
132*d5c9a868SElliott Hughes	fi
133*d5c9a868SElliott Hughes
134*d5c9a868SElliott Hughes# If destination is a directory, append the input filename; if your system
135*d5c9a868SElliott Hughes# does not like double slashes in filenames, you may need to add some logic
136*d5c9a868SElliott Hughes
137*d5c9a868SElliott Hughes	if [ -d $dst ]
138*d5c9a868SElliott Hughes	then
139*d5c9a868SElliott Hughes		dst="$dst"/`basename $src`
140*d5c9a868SElliott Hughes	else
141*d5c9a868SElliott Hughes		true
142*d5c9a868SElliott Hughes	fi
143*d5c9a868SElliott Hughesfi
144*d5c9a868SElliott Hughes
145*d5c9a868SElliott Hughes## this sed command emulates the dirname command
146*d5c9a868SElliott Hughesdstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
147*d5c9a868SElliott Hughes
148*d5c9a868SElliott Hughes# Make sure that the destination directory exists.
149*d5c9a868SElliott Hughes#  this part is taken from Noah Friedman's mkinstalldirs script
150*d5c9a868SElliott Hughes
151*d5c9a868SElliott Hughes# Skip lots of stat calls in the usual case.
152*d5c9a868SElliott Hughesif [ ! -d "$dstdir" ]; then
153*d5c9a868SElliott HughesdefaultIFS='
154*d5c9a868SElliott Hughes'
155*d5c9a868SElliott HughesIFS="${IFS-${defaultIFS}}"
156*d5c9a868SElliott Hughes
157*d5c9a868SElliott HughesoIFS="${IFS}"
158*d5c9a868SElliott Hughes# Some sh's can't handle IFS=/ for some reason.
159*d5c9a868SElliott HughesIFS='%'
160*d5c9a868SElliott Hughesset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
161*d5c9a868SElliott HughesIFS="${oIFS}"
162*d5c9a868SElliott Hughes
163*d5c9a868SElliott Hughespathcomp=''
164*d5c9a868SElliott Hughes
165*d5c9a868SElliott Hugheswhile [ $# -ne 0 ] ; do
166*d5c9a868SElliott Hughes	pathcomp="${pathcomp}${1}"
167*d5c9a868SElliott Hughes	shift
168*d5c9a868SElliott Hughes
169*d5c9a868SElliott Hughes	if [ ! -d "${pathcomp}" ] ;
170*d5c9a868SElliott Hughes        then
171*d5c9a868SElliott Hughes		$mkdirprog "${pathcomp}"
172*d5c9a868SElliott Hughes	else
173*d5c9a868SElliott Hughes		true
174*d5c9a868SElliott Hughes	fi
175*d5c9a868SElliott Hughes
176*d5c9a868SElliott Hughes	pathcomp="${pathcomp}/"
177*d5c9a868SElliott Hughesdone
178*d5c9a868SElliott Hughesfi
179*d5c9a868SElliott Hughes
180*d5c9a868SElliott Hughesif [ x"$dir_arg" != x ]
181*d5c9a868SElliott Hughesthen
182*d5c9a868SElliott Hughes	$doit $instcmd $dst &&
183*d5c9a868SElliott Hughes
184*d5c9a868SElliott Hughes	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
185*d5c9a868SElliott Hughes	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
186*d5c9a868SElliott Hughes	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
187*d5c9a868SElliott Hughes	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
188*d5c9a868SElliott Hugheselse
189*d5c9a868SElliott Hughes
190*d5c9a868SElliott Hughes# If we're going to rename the final executable, determine the name now.
191*d5c9a868SElliott Hughes
192*d5c9a868SElliott Hughes	if [ x"$transformarg" = x ]
193*d5c9a868SElliott Hughes	then
194*d5c9a868SElliott Hughes		dstfile=`basename $dst`
195*d5c9a868SElliott Hughes	else
196*d5c9a868SElliott Hughes		dstfile=`basename $dst $transformbasename |
197*d5c9a868SElliott Hughes			sed $transformarg`$transformbasename
198*d5c9a868SElliott Hughes	fi
199*d5c9a868SElliott Hughes
200*d5c9a868SElliott Hughes# don't allow the sed command to completely eliminate the filename
201*d5c9a868SElliott Hughes
202*d5c9a868SElliott Hughes	if [ x"$dstfile" = x ]
203*d5c9a868SElliott Hughes	then
204*d5c9a868SElliott Hughes		dstfile=`basename $dst`
205*d5c9a868SElliott Hughes	else
206*d5c9a868SElliott Hughes		true
207*d5c9a868SElliott Hughes	fi
208*d5c9a868SElliott Hughes
209*d5c9a868SElliott Hughes# Make a temp file name in the proper directory.
210*d5c9a868SElliott Hughes
211*d5c9a868SElliott Hughes	dsttmp=$dstdir/#inst.$$#
212*d5c9a868SElliott Hughes
213*d5c9a868SElliott Hughes# Move or copy the file name to the temp name
214*d5c9a868SElliott Hughes
215*d5c9a868SElliott Hughes	$doit $instcmd $src $dsttmp &&
216*d5c9a868SElliott Hughes
217*d5c9a868SElliott Hughes	trap "rm -f ${dsttmp}" 0 &&
218*d5c9a868SElliott Hughes
219*d5c9a868SElliott Hughes# and set any options; do chmod last to preserve setuid bits
220*d5c9a868SElliott Hughes
221*d5c9a868SElliott Hughes# If any of these fail, we abort the whole thing.  If we want to
222*d5c9a868SElliott Hughes# ignore errors from any of these, just make sure not to ignore
223*d5c9a868SElliott Hughes# errors from the above "$doit $instcmd $src $dsttmp" command.
224*d5c9a868SElliott Hughes
225*d5c9a868SElliott Hughes	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
226*d5c9a868SElliott Hughes	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
227*d5c9a868SElliott Hughes	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
228*d5c9a868SElliott Hughes	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
229*d5c9a868SElliott Hughes
230*d5c9a868SElliott Hughes# Now rename the file to the real destination.
231*d5c9a868SElliott Hughes
232*d5c9a868SElliott Hughes	$doit $rmcmd -f $dstdir/$dstfile &&
233*d5c9a868SElliott Hughes	$doit $mvcmd $dsttmp $dstdir/$dstfile
234*d5c9a868SElliott Hughes
235*d5c9a868SElliott Hughesfi &&
236*d5c9a868SElliott Hughes
237*d5c9a868SElliott Hughes
238*d5c9a868SElliott Hughesexit 0
239