xref: /netbsd-src/external/gpl2/gmake/dist/config/install-sh (revision 69606e3f5c9388e52aed8c120ad63c049ca45d8f)
1*69606e3fSchristos#!/bin/sh
2*69606e3fSchristos# install - install a program, script, or datafile
3*69606e3fSchristos
4*69606e3fSchristosscriptversion=2005-05-14.22
5*69606e3fSchristos
6*69606e3fSchristos# This originates from X11R5 (mit/util/scripts/install.sh), which was
7*69606e3fSchristos# later released in X11R6 (xc/config/util/install.sh) with the
8*69606e3fSchristos# following copyright and license.
9*69606e3fSchristos#
10*69606e3fSchristos# Copyright (C) 1994 X Consortium
11*69606e3fSchristos#
12*69606e3fSchristos# Permission is hereby granted, free of charge, to any person obtaining a copy
13*69606e3fSchristos# of this software and associated documentation files (the "Software"), to
14*69606e3fSchristos# deal in the Software without restriction, including without limitation the
15*69606e3fSchristos# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16*69606e3fSchristos# sell copies of the Software, and to permit persons to whom the Software is
17*69606e3fSchristos# furnished to do so, subject to the following conditions:
18*69606e3fSchristos#
19*69606e3fSchristos# The above copyright notice and this permission notice shall be included in
20*69606e3fSchristos# all copies or substantial portions of the Software.
21*69606e3fSchristos#
22*69606e3fSchristos# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23*69606e3fSchristos# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24*69606e3fSchristos# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25*69606e3fSchristos# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26*69606e3fSchristos# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27*69606e3fSchristos# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28*69606e3fSchristos#
29*69606e3fSchristos# Except as contained in this notice, the name of the X Consortium shall not
30*69606e3fSchristos# be used in advertising or otherwise to promote the sale, use or other deal-
31*69606e3fSchristos# ings in this Software without prior written authorization from the X Consor-
32*69606e3fSchristos# tium.
33*69606e3fSchristos#
34*69606e3fSchristos#
35*69606e3fSchristos# FSF changes to this file are in the public domain.
36*69606e3fSchristos#
37*69606e3fSchristos# Calling this script install-sh is preferred over install.sh, to prevent
38*69606e3fSchristos# `make' implicit rules from creating a file called install from it
39*69606e3fSchristos# when there is no Makefile.
40*69606e3fSchristos#
41*69606e3fSchristos# This script is compatible with the BSD install script, but was written
42*69606e3fSchristos# from scratch.  It can only install one file at a time, a restriction
43*69606e3fSchristos# shared with many OS's install programs.
44*69606e3fSchristos
45*69606e3fSchristos# set DOITPROG to echo to test this script
46*69606e3fSchristos
47*69606e3fSchristos# Don't use :- since 4.3BSD and earlier shells don't like it.
48*69606e3fSchristosdoit="${DOITPROG-}"
49*69606e3fSchristos
50*69606e3fSchristos# put in absolute paths if you don't have them in your path; or use env. vars.
51*69606e3fSchristos
52*69606e3fSchristosmvprog="${MVPROG-mv}"
53*69606e3fSchristoscpprog="${CPPROG-cp}"
54*69606e3fSchristoschmodprog="${CHMODPROG-chmod}"
55*69606e3fSchristoschownprog="${CHOWNPROG-chown}"
56*69606e3fSchristoschgrpprog="${CHGRPPROG-chgrp}"
57*69606e3fSchristosstripprog="${STRIPPROG-strip}"
58*69606e3fSchristosrmprog="${RMPROG-rm}"
59*69606e3fSchristosmkdirprog="${MKDIRPROG-mkdir}"
60*69606e3fSchristos
61*69606e3fSchristoschmodcmd="$chmodprog 0755"
62*69606e3fSchristoschowncmd=
63*69606e3fSchristoschgrpcmd=
64*69606e3fSchristosstripcmd=
65*69606e3fSchristosrmcmd="$rmprog -f"
66*69606e3fSchristosmvcmd="$mvprog"
67*69606e3fSchristossrc=
68*69606e3fSchristosdst=
69*69606e3fSchristosdir_arg=
70*69606e3fSchristosdstarg=
71*69606e3fSchristosno_target_directory=
72*69606e3fSchristos
73*69606e3fSchristosusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
74*69606e3fSchristos   or: $0 [OPTION]... SRCFILES... DIRECTORY
75*69606e3fSchristos   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
76*69606e3fSchristos   or: $0 [OPTION]... -d DIRECTORIES...
77*69606e3fSchristos
78*69606e3fSchristosIn the 1st form, copy SRCFILE to DSTFILE.
79*69606e3fSchristosIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
80*69606e3fSchristosIn the 4th, create DIRECTORIES.
81*69606e3fSchristos
82*69606e3fSchristosOptions:
83*69606e3fSchristos-c         (ignored)
84*69606e3fSchristos-d         create directories instead of installing files.
85*69606e3fSchristos-g GROUP   $chgrpprog installed files to GROUP.
86*69606e3fSchristos-m MODE    $chmodprog installed files to MODE.
87*69606e3fSchristos-o USER    $chownprog installed files to USER.
88*69606e3fSchristos-s         $stripprog installed files.
89*69606e3fSchristos-t DIRECTORY  install into DIRECTORY.
90*69606e3fSchristos-T         report an error if DSTFILE is a directory.
91*69606e3fSchristos--help     display this help and exit.
92*69606e3fSchristos--version  display version info and exit.
93*69606e3fSchristos
94*69606e3fSchristosEnvironment variables override the default commands:
95*69606e3fSchristos  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
96*69606e3fSchristos"
97*69606e3fSchristos
98*69606e3fSchristoswhile test -n "$1"; do
99*69606e3fSchristos  case $1 in
100*69606e3fSchristos    -c) shift
101*69606e3fSchristos        continue;;
102*69606e3fSchristos
103*69606e3fSchristos    -d) dir_arg=true
104*69606e3fSchristos        shift
105*69606e3fSchristos        continue;;
106*69606e3fSchristos
107*69606e3fSchristos    -g) chgrpcmd="$chgrpprog $2"
108*69606e3fSchristos        shift
109*69606e3fSchristos        shift
110*69606e3fSchristos        continue;;
111*69606e3fSchristos
112*69606e3fSchristos    --help) echo "$usage"; exit $?;;
113*69606e3fSchristos
114*69606e3fSchristos    -m) chmodcmd="$chmodprog $2"
115*69606e3fSchristos        shift
116*69606e3fSchristos        shift
117*69606e3fSchristos        continue;;
118*69606e3fSchristos
119*69606e3fSchristos    -o) chowncmd="$chownprog $2"
120*69606e3fSchristos        shift
121*69606e3fSchristos        shift
122*69606e3fSchristos        continue;;
123*69606e3fSchristos
124*69606e3fSchristos    -s) stripcmd=$stripprog
125*69606e3fSchristos        shift
126*69606e3fSchristos        continue;;
127*69606e3fSchristos
128*69606e3fSchristos    -t) dstarg=$2
129*69606e3fSchristos	shift
130*69606e3fSchristos	shift
131*69606e3fSchristos	continue;;
132*69606e3fSchristos
133*69606e3fSchristos    -T) no_target_directory=true
134*69606e3fSchristos	shift
135*69606e3fSchristos	continue;;
136*69606e3fSchristos
137*69606e3fSchristos    --version) echo "$0 $scriptversion"; exit $?;;
138*69606e3fSchristos
139*69606e3fSchristos    *)  # When -d is used, all remaining arguments are directories to create.
140*69606e3fSchristos	# When -t is used, the destination is already specified.
141*69606e3fSchristos	test -n "$dir_arg$dstarg" && break
142*69606e3fSchristos        # Otherwise, the last argument is the destination.  Remove it from $@.
143*69606e3fSchristos	for arg
144*69606e3fSchristos	do
145*69606e3fSchristos          if test -n "$dstarg"; then
146*69606e3fSchristos	    # $@ is not empty: it contains at least $arg.
147*69606e3fSchristos	    set fnord "$@" "$dstarg"
148*69606e3fSchristos	    shift # fnord
149*69606e3fSchristos	  fi
150*69606e3fSchristos	  shift # arg
151*69606e3fSchristos	  dstarg=$arg
152*69606e3fSchristos	done
153*69606e3fSchristos	break;;
154*69606e3fSchristos  esac
155*69606e3fSchristosdone
156*69606e3fSchristos
157*69606e3fSchristosif test -z "$1"; then
158*69606e3fSchristos  if test -z "$dir_arg"; then
159*69606e3fSchristos    echo "$0: no input file specified." >&2
160*69606e3fSchristos    exit 1
161*69606e3fSchristos  fi
162*69606e3fSchristos  # It's OK to call `install-sh -d' without argument.
163*69606e3fSchristos  # This can happen when creating conditional directories.
164*69606e3fSchristos  exit 0
165*69606e3fSchristosfi
166*69606e3fSchristos
167*69606e3fSchristosfor src
168*69606e3fSchristosdo
169*69606e3fSchristos  # Protect names starting with `-'.
170*69606e3fSchristos  case $src in
171*69606e3fSchristos    -*) src=./$src ;;
172*69606e3fSchristos  esac
173*69606e3fSchristos
174*69606e3fSchristos  if test -n "$dir_arg"; then
175*69606e3fSchristos    dst=$src
176*69606e3fSchristos    src=
177*69606e3fSchristos
178*69606e3fSchristos    if test -d "$dst"; then
179*69606e3fSchristos      mkdircmd=:
180*69606e3fSchristos      chmodcmd=
181*69606e3fSchristos    else
182*69606e3fSchristos      mkdircmd=$mkdirprog
183*69606e3fSchristos    fi
184*69606e3fSchristos  else
185*69606e3fSchristos    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
186*69606e3fSchristos    # might cause directories to be created, which would be especially bad
187*69606e3fSchristos    # if $src (and thus $dsttmp) contains '*'.
188*69606e3fSchristos    if test ! -f "$src" && test ! -d "$src"; then
189*69606e3fSchristos      echo "$0: $src does not exist." >&2
190*69606e3fSchristos      exit 1
191*69606e3fSchristos    fi
192*69606e3fSchristos
193*69606e3fSchristos    if test -z "$dstarg"; then
194*69606e3fSchristos      echo "$0: no destination specified." >&2
195*69606e3fSchristos      exit 1
196*69606e3fSchristos    fi
197*69606e3fSchristos
198*69606e3fSchristos    dst=$dstarg
199*69606e3fSchristos    # Protect names starting with `-'.
200*69606e3fSchristos    case $dst in
201*69606e3fSchristos      -*) dst=./$dst ;;
202*69606e3fSchristos    esac
203*69606e3fSchristos
204*69606e3fSchristos    # If destination is a directory, append the input filename; won't work
205*69606e3fSchristos    # if double slashes aren't ignored.
206*69606e3fSchristos    if test -d "$dst"; then
207*69606e3fSchristos      if test -n "$no_target_directory"; then
208*69606e3fSchristos	echo "$0: $dstarg: Is a directory" >&2
209*69606e3fSchristos	exit 1
210*69606e3fSchristos      fi
211*69606e3fSchristos      dst=$dst/`basename "$src"`
212*69606e3fSchristos    fi
213*69606e3fSchristos  fi
214*69606e3fSchristos
215*69606e3fSchristos  # This sed command emulates the dirname command.
216*69606e3fSchristos  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
217*69606e3fSchristos
218*69606e3fSchristos  # Make sure that the destination directory exists.
219*69606e3fSchristos
220*69606e3fSchristos  # Skip lots of stat calls in the usual case.
221*69606e3fSchristos  if test ! -d "$dstdir"; then
222*69606e3fSchristos    defaultIFS='
223*69606e3fSchristos	 '
224*69606e3fSchristos    IFS="${IFS-$defaultIFS}"
225*69606e3fSchristos
226*69606e3fSchristos    oIFS=$IFS
227*69606e3fSchristos    # Some sh's can't handle IFS=/ for some reason.
228*69606e3fSchristos    IFS='%'
229*69606e3fSchristos    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
230*69606e3fSchristos    shift
231*69606e3fSchristos    IFS=$oIFS
232*69606e3fSchristos
233*69606e3fSchristos    pathcomp=
234*69606e3fSchristos
235*69606e3fSchristos    while test $# -ne 0 ; do
236*69606e3fSchristos      pathcomp=$pathcomp$1
237*69606e3fSchristos      shift
238*69606e3fSchristos      if test ! -d "$pathcomp"; then
239*69606e3fSchristos        $mkdirprog "$pathcomp"
240*69606e3fSchristos	# mkdir can fail with a `File exist' error in case several
241*69606e3fSchristos	# install-sh are creating the directory concurrently.  This
242*69606e3fSchristos	# is OK.
243*69606e3fSchristos	test -d "$pathcomp" || exit
244*69606e3fSchristos      fi
245*69606e3fSchristos      pathcomp=$pathcomp/
246*69606e3fSchristos    done
247*69606e3fSchristos  fi
248*69606e3fSchristos
249*69606e3fSchristos  if test -n "$dir_arg"; then
250*69606e3fSchristos    $doit $mkdircmd "$dst" \
251*69606e3fSchristos      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
252*69606e3fSchristos      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
253*69606e3fSchristos      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
254*69606e3fSchristos      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
255*69606e3fSchristos
256*69606e3fSchristos  else
257*69606e3fSchristos    dstfile=`basename "$dst"`
258*69606e3fSchristos
259*69606e3fSchristos    # Make a couple of temp file names in the proper directory.
260*69606e3fSchristos    dsttmp=$dstdir/_inst.$$_
261*69606e3fSchristos    rmtmp=$dstdir/_rm.$$_
262*69606e3fSchristos
263*69606e3fSchristos    # Trap to clean up those temp files at exit.
264*69606e3fSchristos    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
265*69606e3fSchristos    trap '(exit $?); exit' 1 2 13 15
266*69606e3fSchristos
267*69606e3fSchristos    # Copy the file name to the temp name.
268*69606e3fSchristos    $doit $cpprog "$src" "$dsttmp" &&
269*69606e3fSchristos
270*69606e3fSchristos    # and set any options; do chmod last to preserve setuid bits.
271*69606e3fSchristos    #
272*69606e3fSchristos    # If any of these fail, we abort the whole thing.  If we want to
273*69606e3fSchristos    # ignore errors from any of these, just make sure not to ignore
274*69606e3fSchristos    # errors from the above "$doit $cpprog $src $dsttmp" command.
275*69606e3fSchristos    #
276*69606e3fSchristos    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
277*69606e3fSchristos      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
278*69606e3fSchristos      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
279*69606e3fSchristos      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
280*69606e3fSchristos
281*69606e3fSchristos    # Now rename the file to the real destination.
282*69606e3fSchristos    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
283*69606e3fSchristos      || {
284*69606e3fSchristos	   # The rename failed, perhaps because mv can't rename something else
285*69606e3fSchristos	   # to itself, or perhaps because mv is so ancient that it does not
286*69606e3fSchristos	   # support -f.
287*69606e3fSchristos
288*69606e3fSchristos	   # Now remove or move aside any old file at destination location.
289*69606e3fSchristos	   # We try this two ways since rm can't unlink itself on some
290*69606e3fSchristos	   # systems and the destination file might be busy for other
291*69606e3fSchristos	   # reasons.  In this case, the final cleanup might fail but the new
292*69606e3fSchristos	   # file should still install successfully.
293*69606e3fSchristos	   {
294*69606e3fSchristos	     if test -f "$dstdir/$dstfile"; then
295*69606e3fSchristos	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
296*69606e3fSchristos	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
297*69606e3fSchristos	       || {
298*69606e3fSchristos		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
299*69606e3fSchristos		 (exit 1); exit 1
300*69606e3fSchristos	       }
301*69606e3fSchristos	     else
302*69606e3fSchristos	       :
303*69606e3fSchristos	     fi
304*69606e3fSchristos	   } &&
305*69606e3fSchristos
306*69606e3fSchristos	   # Now rename the file to the real destination.
307*69606e3fSchristos	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
308*69606e3fSchristos	 }
309*69606e3fSchristos    }
310*69606e3fSchristos  fi || { (exit 1); exit 1; }
311*69606e3fSchristosdone
312*69606e3fSchristos
313*69606e3fSchristos# The final little trick to "correctly" pass the exit status to the exit trap.
314*69606e3fSchristos{
315*69606e3fSchristos  (exit 0); exit 0
316*69606e3fSchristos}
317*69606e3fSchristos
318*69606e3fSchristos# Local variables:
319*69606e3fSchristos# eval: (add-hook 'write-file-hooks 'time-stamp)
320*69606e3fSchristos# time-stamp-start: "scriptversion="
321*69606e3fSchristos# time-stamp-format: "%:y-%02m-%02d.%02H"
322*69606e3fSchristos# time-stamp-end: "$"
323*69606e3fSchristos# End:
324