xref: /netbsd-src/external/bsd/top/dist/install-sh (revision 10dd2532a5fc0a73e461275cb9fca28fc3013d32)
1*10dd2532Schristos#!/bin/sh
2*10dd2532Schristos#
3*10dd2532Schristos# install - install a program, script, or datafile
4*10dd2532Schristos# This comes from X11R5 (mit/util/scripts/install.sh).
5*10dd2532Schristos#
6*10dd2532Schristos# Copyright 1991 by the Massachusetts Institute of Technology
7*10dd2532Schristos#
8*10dd2532Schristos# Permission to use, copy, modify, distribute, and sell this software and its
9*10dd2532Schristos# documentation for any purpose is hereby granted without fee, provided that
10*10dd2532Schristos# the above copyright notice appear in all copies and that both that
11*10dd2532Schristos# copyright notice and this permission notice appear in supporting
12*10dd2532Schristos# documentation, and that the name of M.I.T. not be used in advertising or
13*10dd2532Schristos# publicity pertaining to distribution of the software without specific,
14*10dd2532Schristos# written prior permission.  M.I.T. makes no representations about the
15*10dd2532Schristos# suitability of this software for any purpose.  It is provided "as is"
16*10dd2532Schristos# without express or implied warranty.
17*10dd2532Schristos#
18*10dd2532Schristos# Calling this script install-sh is preferred over install.sh, to prevent
19*10dd2532Schristos# `make' implicit rules from creating a file called install from it
20*10dd2532Schristos# when there is no Makefile.
21*10dd2532Schristos#
22*10dd2532Schristos# This script is compatible with the BSD install script, but was written
23*10dd2532Schristos# from scratch.  It can only install one file at a time, a restriction
24*10dd2532Schristos# shared with many OS's install programs.
25*10dd2532Schristos
26*10dd2532Schristos
27*10dd2532Schristos# set DOITPROG to echo to test this script
28*10dd2532Schristos
29*10dd2532Schristos# Don't use :- since 4.3BSD and earlier shells don't like it.
30*10dd2532Schristosdoit="${DOITPROG-}"
31*10dd2532Schristos
32*10dd2532Schristos
33*10dd2532Schristos# put in absolute paths if you don't have them in your path; or use env. vars.
34*10dd2532Schristos
35*10dd2532Schristosmvprog="${MVPROG-mv}"
36*10dd2532Schristoscpprog="${CPPROG-cp}"
37*10dd2532Schristoschmodprog="${CHMODPROG-chmod}"
38*10dd2532Schristoschownprog="${CHOWNPROG-chown}"
39*10dd2532Schristoschgrpprog="${CHGRPPROG-chgrp}"
40*10dd2532Schristosstripprog="${STRIPPROG-strip}"
41*10dd2532Schristosrmprog="${RMPROG-rm}"
42*10dd2532Schristosmkdirprog="${MKDIRPROG-mkdir}"
43*10dd2532Schristos
44*10dd2532Schristostransformbasename=""
45*10dd2532Schristostransform_arg=""
46*10dd2532Schristosinstcmd="$mvprog"
47*10dd2532Schristoschmodcmd="$chmodprog 0755"
48*10dd2532Schristoschowncmd=""
49*10dd2532Schristoschgrpcmd=""
50*10dd2532Schristosstripcmd=""
51*10dd2532Schristosrmcmd="$rmprog -f"
52*10dd2532Schristosmvcmd="$mvprog"
53*10dd2532Schristossrc=""
54*10dd2532Schristosdst=""
55*10dd2532Schristosdir_arg=""
56*10dd2532Schristos
57*10dd2532Schristoswhile [ x"$1" != x ]; do
58*10dd2532Schristos    case $1 in
59*10dd2532Schristos	-c) instcmd="$cpprog"
60*10dd2532Schristos	    shift
61*10dd2532Schristos	    continue;;
62*10dd2532Schristos
63*10dd2532Schristos	-d) dir_arg=true
64*10dd2532Schristos	    shift
65*10dd2532Schristos	    continue;;
66*10dd2532Schristos
67*10dd2532Schristos	-m) chmodcmd="$chmodprog $2"
68*10dd2532Schristos	    shift
69*10dd2532Schristos	    shift
70*10dd2532Schristos	    continue;;
71*10dd2532Schristos
72*10dd2532Schristos	-o) chowncmd="$chownprog $2"
73*10dd2532Schristos	    shift
74*10dd2532Schristos	    shift
75*10dd2532Schristos	    continue;;
76*10dd2532Schristos
77*10dd2532Schristos	-g) chgrpcmd="$chgrpprog $2"
78*10dd2532Schristos	    shift
79*10dd2532Schristos	    shift
80*10dd2532Schristos	    continue;;
81*10dd2532Schristos
82*10dd2532Schristos	-s) stripcmd="$stripprog"
83*10dd2532Schristos	    shift
84*10dd2532Schristos	    continue;;
85*10dd2532Schristos
86*10dd2532Schristos	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
87*10dd2532Schristos	    shift
88*10dd2532Schristos	    continue;;
89*10dd2532Schristos
90*10dd2532Schristos	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
91*10dd2532Schristos	    shift
92*10dd2532Schristos	    continue;;
93*10dd2532Schristos
94*10dd2532Schristos	*)  if [ x"$src" = x ]
95*10dd2532Schristos	    then
96*10dd2532Schristos		src=$1
97*10dd2532Schristos	    else
98*10dd2532Schristos		# this colon is to work around a 386BSD /bin/sh bug
99*10dd2532Schristos		:
100*10dd2532Schristos		dst=$1
101*10dd2532Schristos	    fi
102*10dd2532Schristos	    shift
103*10dd2532Schristos	    continue;;
104*10dd2532Schristos    esac
105*10dd2532Schristosdone
106*10dd2532Schristos
107*10dd2532Schristosif [ x"$src" = x ]
108*10dd2532Schristosthen
109*10dd2532Schristos	echo "install:	no input file specified"
110*10dd2532Schristos	exit 1
111*10dd2532Schristoselse
112*10dd2532Schristos	:
113*10dd2532Schristosfi
114*10dd2532Schristos
115*10dd2532Schristosif [ x"$dir_arg" != x ]; then
116*10dd2532Schristos	dst=$src
117*10dd2532Schristos	src=""
118*10dd2532Schristos
119*10dd2532Schristos	if [ -d $dst ]; then
120*10dd2532Schristos		instcmd=:
121*10dd2532Schristos		chmodcmd=""
122*10dd2532Schristos	else
123*10dd2532Schristos		instcmd=$mkdirprog
124*10dd2532Schristos	fi
125*10dd2532Schristoselse
126*10dd2532Schristos
127*10dd2532Schristos# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
128*10dd2532Schristos# might cause directories to be created, which would be especially bad
129*10dd2532Schristos# if $src (and thus $dsttmp) contains '*'.
130*10dd2532Schristos
131*10dd2532Schristos	if [ -f $src -o -d $src ]
132*10dd2532Schristos	then
133*10dd2532Schristos		:
134*10dd2532Schristos	else
135*10dd2532Schristos		echo "install:  $src does not exist"
136*10dd2532Schristos		exit 1
137*10dd2532Schristos	fi
138*10dd2532Schristos
139*10dd2532Schristos	if [ x"$dst" = x ]
140*10dd2532Schristos	then
141*10dd2532Schristos		echo "install:	no destination specified"
142*10dd2532Schristos		exit 1
143*10dd2532Schristos	else
144*10dd2532Schristos		:
145*10dd2532Schristos	fi
146*10dd2532Schristos
147*10dd2532Schristos# If destination is a directory, append the input filename; if your system
148*10dd2532Schristos# does not like double slashes in filenames, you may need to add some logic
149*10dd2532Schristos
150*10dd2532Schristos	if [ -d $dst ]
151*10dd2532Schristos	then
152*10dd2532Schristos		dst="$dst"/`basename $src`
153*10dd2532Schristos	else
154*10dd2532Schristos		:
155*10dd2532Schristos	fi
156*10dd2532Schristosfi
157*10dd2532Schristos
158*10dd2532Schristos## this sed command emulates the dirname command
159*10dd2532Schristosdstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
160*10dd2532Schristos
161*10dd2532Schristos# Make sure that the destination directory exists.
162*10dd2532Schristos#  this part is taken from Noah Friedman's mkinstalldirs script
163*10dd2532Schristos
164*10dd2532Schristos# Skip lots of stat calls in the usual case.
165*10dd2532Schristosif [ ! -d "$dstdir" ]; then
166*10dd2532SchristosdefaultIFS='
167*10dd2532Schristos	'
168*10dd2532SchristosIFS="${IFS-${defaultIFS}}"
169*10dd2532Schristos
170*10dd2532SchristosoIFS="${IFS}"
171*10dd2532Schristos# Some sh's can't handle IFS=/ for some reason.
172*10dd2532SchristosIFS='%'
173*10dd2532Schristosset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
174*10dd2532SchristosIFS="${oIFS}"
175*10dd2532Schristos
176*10dd2532Schristospathcomp=''
177*10dd2532Schristos
178*10dd2532Schristoswhile [ $# -ne 0 ] ; do
179*10dd2532Schristos	pathcomp="${pathcomp}${1}"
180*10dd2532Schristos	shift
181*10dd2532Schristos
182*10dd2532Schristos	if [ ! -d "${pathcomp}" ] ;
183*10dd2532Schristos        then
184*10dd2532Schristos		$mkdirprog "${pathcomp}"
185*10dd2532Schristos	else
186*10dd2532Schristos		:
187*10dd2532Schristos	fi
188*10dd2532Schristos
189*10dd2532Schristos	pathcomp="${pathcomp}/"
190*10dd2532Schristosdone
191*10dd2532Schristosfi
192*10dd2532Schristos
193*10dd2532Schristosif [ x"$dir_arg" != x ]
194*10dd2532Schristosthen
195*10dd2532Schristos	$doit $instcmd $dst &&
196*10dd2532Schristos
197*10dd2532Schristos	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
198*10dd2532Schristos	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
199*10dd2532Schristos	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
200*10dd2532Schristos	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
201*10dd2532Schristoselse
202*10dd2532Schristos
203*10dd2532Schristos# If we're going to rename the final executable, determine the name now.
204*10dd2532Schristos
205*10dd2532Schristos	if [ x"$transformarg" = x ]
206*10dd2532Schristos	then
207*10dd2532Schristos		dstfile=`basename $dst`
208*10dd2532Schristos	else
209*10dd2532Schristos		dstfile=`basename $dst $transformbasename |
210*10dd2532Schristos			sed $transformarg`$transformbasename
211*10dd2532Schristos	fi
212*10dd2532Schristos
213*10dd2532Schristos# don't allow the sed command to completely eliminate the filename
214*10dd2532Schristos
215*10dd2532Schristos	if [ x"$dstfile" = x ]
216*10dd2532Schristos	then
217*10dd2532Schristos		dstfile=`basename $dst`
218*10dd2532Schristos	else
219*10dd2532Schristos		:
220*10dd2532Schristos	fi
221*10dd2532Schristos
222*10dd2532Schristos# Make a temp file name in the proper directory.
223*10dd2532Schristos
224*10dd2532Schristos	dsttmp=$dstdir/#inst.$$#
225*10dd2532Schristos
226*10dd2532Schristos# Move or copy the file name to the temp name
227*10dd2532Schristos
228*10dd2532Schristos	$doit $instcmd $src $dsttmp &&
229*10dd2532Schristos
230*10dd2532Schristos	trap "rm -f ${dsttmp}" 0 &&
231*10dd2532Schristos
232*10dd2532Schristos# and set any options; do chmod last to preserve setuid bits
233*10dd2532Schristos
234*10dd2532Schristos# If any of these fail, we abort the whole thing.  If we want to
235*10dd2532Schristos# ignore errors from any of these, just make sure not to ignore
236*10dd2532Schristos# errors from the above "$doit $instcmd $src $dsttmp" command.
237*10dd2532Schristos
238*10dd2532Schristos	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
239*10dd2532Schristos	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
240*10dd2532Schristos	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
241*10dd2532Schristos	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
242*10dd2532Schristos
243*10dd2532Schristos# Now rename the file to the real destination.
244*10dd2532Schristos
245*10dd2532Schristos	$doit $rmcmd -f $dstdir/$dstfile &&
246*10dd2532Schristos	$doit $mvcmd $dsttmp $dstdir/$dstfile
247*10dd2532Schristos
248*10dd2532Schristosfi &&
249*10dd2532Schristos
250*10dd2532Schristos
251*10dd2532Schristosexit 0
252