1382ff0afSmrg#!/bin/sh
2382ff0afSmrg# install - install a program, script, or datafile
3382ff0afSmrg
4382ff0afSmrgscriptversion=2005-05-14.22
5382ff0afSmrg
6382ff0afSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
7382ff0afSmrg# later released in X11R6 (xc/config/util/install.sh) with the
8382ff0afSmrg# following copyright and license.
9382ff0afSmrg#
10382ff0afSmrg# Copyright (C) 1994 X Consortium
11382ff0afSmrg#
12382ff0afSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy
13382ff0afSmrg# of this software and associated documentation files (the "Software"), to
14382ff0afSmrg# deal in the Software without restriction, including without limitation the
15382ff0afSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16382ff0afSmrg# sell copies of the Software, and to permit persons to whom the Software is
17382ff0afSmrg# furnished to do so, subject to the following conditions:
18382ff0afSmrg#
19382ff0afSmrg# The above copyright notice and this permission notice shall be included in
20382ff0afSmrg# all copies or substantial portions of the Software.
21382ff0afSmrg#
22382ff0afSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23382ff0afSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24382ff0afSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25382ff0afSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26382ff0afSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27382ff0afSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28382ff0afSmrg#
29382ff0afSmrg# Except as contained in this notice, the name of the X Consortium shall not
30382ff0afSmrg# be used in advertising or otherwise to promote the sale, use or other deal-
31382ff0afSmrg# ings in this Software without prior written authorization from the X Consor-
32382ff0afSmrg# tium.
33382ff0afSmrg#
34382ff0afSmrg#
35382ff0afSmrg# FSF changes to this file are in the public domain.
36382ff0afSmrg#
37382ff0afSmrg# Calling this script install-sh is preferred over install.sh, to prevent
38382ff0afSmrg# `make' implicit rules from creating a file called install from it
39382ff0afSmrg# when there is no Makefile.
40382ff0afSmrg#
41382ff0afSmrg# This script is compatible with the BSD install script, but was written
42382ff0afSmrg# from scratch.  It can only install one file at a time, a restriction
43382ff0afSmrg# shared with many OS's install programs.
44382ff0afSmrg
45382ff0afSmrg# set DOITPROG to echo to test this script
46382ff0afSmrg
47382ff0afSmrg# Don't use :- since 4.3BSD and earlier shells don't like it.
48382ff0afSmrgdoit="${DOITPROG-}"
49382ff0afSmrg
50382ff0afSmrg# put in absolute paths if you don't have them in your path; or use env. vars.
51382ff0afSmrg
52382ff0afSmrgmvprog="${MVPROG-mv}"
53382ff0afSmrgcpprog="${CPPROG-cp}"
54382ff0afSmrgchmodprog="${CHMODPROG-chmod}"
55382ff0afSmrgchownprog="${CHOWNPROG-chown}"
56382ff0afSmrgchgrpprog="${CHGRPPROG-chgrp}"
57382ff0afSmrgstripprog="${STRIPPROG-strip}"
58382ff0afSmrgrmprog="${RMPROG-rm}"
59382ff0afSmrgmkdirprog="${MKDIRPROG-mkdir}"
60382ff0afSmrg
61382ff0afSmrgchmodcmd="$chmodprog 0755"
62382ff0afSmrgchowncmd=
63382ff0afSmrgchgrpcmd=
64382ff0afSmrgstripcmd=
65382ff0afSmrgrmcmd="$rmprog -f"
66382ff0afSmrgmvcmd="$mvprog"
67382ff0afSmrgsrc=
68382ff0afSmrgdst=
69382ff0afSmrgdir_arg=
70382ff0afSmrgdstarg=
71382ff0afSmrgno_target_directory=
72382ff0afSmrg
73382ff0afSmrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
74382ff0afSmrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
75382ff0afSmrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
76382ff0afSmrg   or: $0 [OPTION]... -d DIRECTORIES...
77382ff0afSmrg
78382ff0afSmrgIn the 1st form, copy SRCFILE to DSTFILE.
79382ff0afSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
80382ff0afSmrgIn the 4th, create DIRECTORIES.
81382ff0afSmrg
82382ff0afSmrgOptions:
83382ff0afSmrg-c         (ignored)
84382ff0afSmrg-d         create directories instead of installing files.
85382ff0afSmrg-g GROUP   $chgrpprog installed files to GROUP.
86382ff0afSmrg-m MODE    $chmodprog installed files to MODE.
87382ff0afSmrg-o USER    $chownprog installed files to USER.
88382ff0afSmrg-s         $stripprog installed files.
89382ff0afSmrg-t DIRECTORY  install into DIRECTORY.
90382ff0afSmrg-T         report an error if DSTFILE is a directory.
91382ff0afSmrg--help     display this help and exit.
92382ff0afSmrg--version  display version info and exit.
93382ff0afSmrg
94382ff0afSmrgEnvironment variables override the default commands:
95382ff0afSmrg  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
96382ff0afSmrg"
97382ff0afSmrg
98382ff0afSmrgwhile test -n "$1"; do
99382ff0afSmrg  case $1 in
100382ff0afSmrg    -c) shift
101382ff0afSmrg        continue;;
102382ff0afSmrg
103382ff0afSmrg    -d) dir_arg=true
104382ff0afSmrg        shift
105382ff0afSmrg        continue;;
106382ff0afSmrg
107382ff0afSmrg    -g) chgrpcmd="$chgrpprog $2"
108382ff0afSmrg        shift
109382ff0afSmrg        shift
110382ff0afSmrg        continue;;
111382ff0afSmrg
112382ff0afSmrg    --help) echo "$usage"; exit $?;;
113382ff0afSmrg
114382ff0afSmrg    -m) chmodcmd="$chmodprog $2"
115382ff0afSmrg        shift
116382ff0afSmrg        shift
117382ff0afSmrg        continue;;
118382ff0afSmrg
119382ff0afSmrg    -o) chowncmd="$chownprog $2"
120382ff0afSmrg        shift
121382ff0afSmrg        shift
122382ff0afSmrg        continue;;
123382ff0afSmrg
124382ff0afSmrg    -s) stripcmd=$stripprog
125382ff0afSmrg        shift
126382ff0afSmrg        continue;;
127382ff0afSmrg
128382ff0afSmrg    -t) dstarg=$2
129382ff0afSmrg	shift
130382ff0afSmrg	shift
131382ff0afSmrg	continue;;
132382ff0afSmrg
133382ff0afSmrg    -T) no_target_directory=true
134382ff0afSmrg	shift
135382ff0afSmrg	continue;;
136382ff0afSmrg
137382ff0afSmrg    --version) echo "$0 $scriptversion"; exit $?;;
138382ff0afSmrg
139382ff0afSmrg    *)  # When -d is used, all remaining arguments are directories to create.
140382ff0afSmrg	# When -t is used, the destination is already specified.
141382ff0afSmrg	test -n "$dir_arg$dstarg" && break
142382ff0afSmrg        # Otherwise, the last argument is the destination.  Remove it from $@.
143382ff0afSmrg	for arg
144382ff0afSmrg	do
145382ff0afSmrg          if test -n "$dstarg"; then
146382ff0afSmrg	    # $@ is not empty: it contains at least $arg.
147382ff0afSmrg	    set fnord "$@" "$dstarg"
148382ff0afSmrg	    shift # fnord
149382ff0afSmrg	  fi
150382ff0afSmrg	  shift # arg
151382ff0afSmrg	  dstarg=$arg
152382ff0afSmrg	done
153382ff0afSmrg	break;;
154382ff0afSmrg  esac
155382ff0afSmrgdone
156382ff0afSmrg
157382ff0afSmrgif test -z "$1"; then
158382ff0afSmrg  if test -z "$dir_arg"; then
159382ff0afSmrg    echo "$0: no input file specified." >&2
160382ff0afSmrg    exit 1
161382ff0afSmrg  fi
162382ff0afSmrg  # It's OK to call `install-sh -d' without argument.
163382ff0afSmrg  # This can happen when creating conditional directories.
164382ff0afSmrg  exit 0
165382ff0afSmrgfi
166382ff0afSmrg
167382ff0afSmrgfor src
168382ff0afSmrgdo
169382ff0afSmrg  # Protect names starting with `-'.
170382ff0afSmrg  case $src in
171382ff0afSmrg    -*) src=./$src ;;
172382ff0afSmrg  esac
173382ff0afSmrg
174382ff0afSmrg  if test -n "$dir_arg"; then
175382ff0afSmrg    dst=$src
176382ff0afSmrg    src=
177382ff0afSmrg
178382ff0afSmrg    if test -d "$dst"; then
179382ff0afSmrg      mkdircmd=:
180382ff0afSmrg      chmodcmd=
181382ff0afSmrg    else
182382ff0afSmrg      mkdircmd=$mkdirprog
183382ff0afSmrg    fi
184382ff0afSmrg  else
185382ff0afSmrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
186382ff0afSmrg    # might cause directories to be created, which would be especially bad
187382ff0afSmrg    # if $src (and thus $dsttmp) contains '*'.
188382ff0afSmrg    if test ! -f "$src" && test ! -d "$src"; then
189382ff0afSmrg      echo "$0: $src does not exist." >&2
190382ff0afSmrg      exit 1
191382ff0afSmrg    fi
192382ff0afSmrg
193382ff0afSmrg    if test -z "$dstarg"; then
194382ff0afSmrg      echo "$0: no destination specified." >&2
195382ff0afSmrg      exit 1
196382ff0afSmrg    fi
197382ff0afSmrg
198382ff0afSmrg    dst=$dstarg
199382ff0afSmrg    # Protect names starting with `-'.
200382ff0afSmrg    case $dst in
201382ff0afSmrg      -*) dst=./$dst ;;
202382ff0afSmrg    esac
203382ff0afSmrg
204382ff0afSmrg    # If destination is a directory, append the input filename; won't work
205382ff0afSmrg    # if double slashes aren't ignored.
206382ff0afSmrg    if test -d "$dst"; then
207382ff0afSmrg      if test -n "$no_target_directory"; then
208382ff0afSmrg	echo "$0: $dstarg: Is a directory" >&2
209382ff0afSmrg	exit 1
210382ff0afSmrg      fi
211382ff0afSmrg      dst=$dst/`basename "$src"`
212382ff0afSmrg    fi
213382ff0afSmrg  fi
214382ff0afSmrg
215382ff0afSmrg  # This sed command emulates the dirname command.
216382ff0afSmrg  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
217382ff0afSmrg
218382ff0afSmrg  # Make sure that the destination directory exists.
219382ff0afSmrg
220382ff0afSmrg  # Skip lots of stat calls in the usual case.
221382ff0afSmrg  if test ! -d "$dstdir"; then
222382ff0afSmrg    defaultIFS='
223382ff0afSmrg	 '
224382ff0afSmrg    IFS="${IFS-$defaultIFS}"
225382ff0afSmrg
226382ff0afSmrg    oIFS=$IFS
227382ff0afSmrg    # Some sh's can't handle IFS=/ for some reason.
228382ff0afSmrg    IFS='%'
229382ff0afSmrg    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
230382ff0afSmrg    shift
231382ff0afSmrg    IFS=$oIFS
232382ff0afSmrg
233382ff0afSmrg    pathcomp=
234382ff0afSmrg
235382ff0afSmrg    while test $# -ne 0 ; do
236382ff0afSmrg      pathcomp=$pathcomp$1
237382ff0afSmrg      shift
238382ff0afSmrg      if test ! -d "$pathcomp"; then
239382ff0afSmrg        $mkdirprog "$pathcomp"
240382ff0afSmrg	# mkdir can fail with a `File exist' error in case several
241382ff0afSmrg	# install-sh are creating the directory concurrently.  This
242382ff0afSmrg	# is OK.
243382ff0afSmrg	test -d "$pathcomp" || exit
244382ff0afSmrg      fi
245382ff0afSmrg      pathcomp=$pathcomp/
246382ff0afSmrg    done
247382ff0afSmrg  fi
248382ff0afSmrg
249382ff0afSmrg  if test -n "$dir_arg"; then
250382ff0afSmrg    $doit $mkdircmd "$dst" \
251382ff0afSmrg      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
252382ff0afSmrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
253382ff0afSmrg      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
254382ff0afSmrg      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
255382ff0afSmrg
256382ff0afSmrg  else
257382ff0afSmrg    dstfile=`basename "$dst"`
258382ff0afSmrg
259382ff0afSmrg    # Make a couple of temp file names in the proper directory.
260382ff0afSmrg    dsttmp=$dstdir/_inst.$$_
261382ff0afSmrg    rmtmp=$dstdir/_rm.$$_
262382ff0afSmrg
263382ff0afSmrg    # Trap to clean up those temp files at exit.
264382ff0afSmrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
265382ff0afSmrg    trap '(exit $?); exit' 1 2 13 15
266382ff0afSmrg
267382ff0afSmrg    # Copy the file name to the temp name.
268382ff0afSmrg    $doit $cpprog "$src" "$dsttmp" &&
269382ff0afSmrg
270382ff0afSmrg    # and set any options; do chmod last to preserve setuid bits.
271382ff0afSmrg    #
272382ff0afSmrg    # If any of these fail, we abort the whole thing.  If we want to
273382ff0afSmrg    # ignore errors from any of these, just make sure not to ignore
274382ff0afSmrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
275382ff0afSmrg    #
276382ff0afSmrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
277382ff0afSmrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
278382ff0afSmrg      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
279382ff0afSmrg      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
280382ff0afSmrg
281382ff0afSmrg    # Now rename the file to the real destination.
282382ff0afSmrg    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
283382ff0afSmrg      || {
284382ff0afSmrg	   # The rename failed, perhaps because mv can't rename something else
285382ff0afSmrg	   # to itself, or perhaps because mv is so ancient that it does not
286382ff0afSmrg	   # support -f.
287382ff0afSmrg
288382ff0afSmrg	   # Now remove or move aside any old file at destination location.
289382ff0afSmrg	   # We try this two ways since rm can't unlink itself on some
290382ff0afSmrg	   # systems and the destination file might be busy for other
291382ff0afSmrg	   # reasons.  In this case, the final cleanup might fail but the new
292382ff0afSmrg	   # file should still install successfully.
293382ff0afSmrg	   {
294382ff0afSmrg	     if test -f "$dstdir/$dstfile"; then
295382ff0afSmrg	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
296382ff0afSmrg	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
297382ff0afSmrg	       || {
298382ff0afSmrg		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
299382ff0afSmrg		 (exit 1); exit 1
300382ff0afSmrg	       }
301382ff0afSmrg	     else
302382ff0afSmrg	       :
303382ff0afSmrg	     fi
304382ff0afSmrg	   } &&
305382ff0afSmrg
306382ff0afSmrg	   # Now rename the file to the real destination.
307382ff0afSmrg	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
308382ff0afSmrg	 }
309382ff0afSmrg    }
310382ff0afSmrg  fi || { (exit 1); exit 1; }
311382ff0afSmrgdone
312382ff0afSmrg
313382ff0afSmrg# The final little trick to "correctly" pass the exit status to the exit trap.
314382ff0afSmrg{
315382ff0afSmrg  (exit 0); exit 0
316382ff0afSmrg}
317382ff0afSmrg
318382ff0afSmrg# Local variables:
319382ff0afSmrg# eval: (add-hook 'write-file-hooks 'time-stamp)
320382ff0afSmrg# time-stamp-start: "scriptversion="
321382ff0afSmrg# time-stamp-format: "%:y-%02m-%02d.%02H"
322382ff0afSmrg# time-stamp-end: "$"
323382ff0afSmrg# End:
324