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