1156283Srwatson#!/bin/sh
2156283Srwatson# install - install a program, script, or datafile
3156283Srwatson
4156283Srwatsonscriptversion=2005-05-14.22
5156283Srwatson
6156283Srwatson# This originates from X11R5 (mit/util/scripts/install.sh), which was
7156283Srwatson# later released in X11R6 (xc/config/util/install.sh) with the
8156283Srwatson# following copyright and license.
9156283Srwatson#
10156283Srwatson# Copyright (C) 1994 X Consortium
11156283Srwatson#
12156283Srwatson# Permission is hereby granted, free of charge, to any person obtaining a copy
13156283Srwatson# of this software and associated documentation files (the "Software"), to
14156283Srwatson# deal in the Software without restriction, including without limitation the
15156283Srwatson# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16156283Srwatson# sell copies of the Software, and to permit persons to whom the Software is
17156283Srwatson# furnished to do so, subject to the following conditions:
18156283Srwatson#
19156283Srwatson# The above copyright notice and this permission notice shall be included in
20156283Srwatson# all copies or substantial portions of the Software.
21156283Srwatson#
22156283Srwatson# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23156283Srwatson# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24156283Srwatson# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25156283Srwatson# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26156283Srwatson# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27156283Srwatson# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28156283Srwatson#
29156283Srwatson# Except as contained in this notice, the name of the X Consortium shall not
30156283Srwatson# be used in advertising or otherwise to promote the sale, use or other deal-
31156283Srwatson# ings in this Software without prior written authorization from the X Consor-
32156283Srwatson# tium.
33156283Srwatson#
34156283Srwatson#
35156283Srwatson# FSF changes to this file are in the public domain.
36156283Srwatson#
37156283Srwatson# Calling this script install-sh is preferred over install.sh, to prevent
38156283Srwatson# `make' implicit rules from creating a file called install from it
39156283Srwatson# when there is no Makefile.
40156283Srwatson#
41156283Srwatson# This script is compatible with the BSD install script, but was written
42156283Srwatson# from scratch.  It can only install one file at a time, a restriction
43156283Srwatson# shared with many OS's install programs.
44156283Srwatson
45156283Srwatson# set DOITPROG to echo to test this script
46156283Srwatson
47156283Srwatson# Don't use :- since 4.3BSD and earlier shells don't like it.
48156283Srwatsondoit="${DOITPROG-}"
49156283Srwatson
50156283Srwatson# put in absolute paths if you don't have them in your path; or use env. vars.
51156283Srwatson
52156283Srwatsonmvprog="${MVPROG-mv}"
53156283Srwatsoncpprog="${CPPROG-cp}"
54156283Srwatsonchmodprog="${CHMODPROG-chmod}"
55156283Srwatsonchownprog="${CHOWNPROG-chown}"
56156283Srwatsonchgrpprog="${CHGRPPROG-chgrp}"
57156283Srwatsonstripprog="${STRIPPROG-strip}"
58156283Srwatsonrmprog="${RMPROG-rm}"
59156283Srwatsonmkdirprog="${MKDIRPROG-mkdir}"
60156283Srwatson
61156283Srwatsonchmodcmd="$chmodprog 0755"
62156283Srwatsonchowncmd=
63156283Srwatsonchgrpcmd=
64156283Srwatsonstripcmd=
65156283Srwatsonrmcmd="$rmprog -f"
66156283Srwatsonmvcmd="$mvprog"
67156283Srwatsonsrc=
68156283Srwatsondst=
69156283Srwatsondir_arg=
70156283Srwatsondstarg=
71156283Srwatsonno_target_directory=
72156283Srwatson
73156283Srwatsonusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
74156283Srwatson   or: $0 [OPTION]... SRCFILES... DIRECTORY
75156283Srwatson   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
76156283Srwatson   or: $0 [OPTION]... -d DIRECTORIES...
77156283Srwatson
78156283SrwatsonIn the 1st form, copy SRCFILE to DSTFILE.
79156283SrwatsonIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
80156283SrwatsonIn the 4th, create DIRECTORIES.
81156283Srwatson
82156283SrwatsonOptions:
83156283Srwatson-c         (ignored)
84156283Srwatson-d         create directories instead of installing files.
85156283Srwatson-g GROUP   $chgrpprog installed files to GROUP.
86156283Srwatson-m MODE    $chmodprog installed files to MODE.
87156283Srwatson-o USER    $chownprog installed files to USER.
88156283Srwatson-s         $stripprog installed files.
89156283Srwatson-t DIRECTORY  install into DIRECTORY.
90156283Srwatson-T         report an error if DSTFILE is a directory.
91156283Srwatson--help     display this help and exit.
92156283Srwatson--version  display version info and exit.
93156283Srwatson
94156283SrwatsonEnvironment variables override the default commands:
95156283Srwatson  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
96156283Srwatson"
97156283Srwatson
98156283Srwatsonwhile test -n "$1"; do
99156283Srwatson  case $1 in
100156283Srwatson    -c) shift
101156283Srwatson        continue;;
102156283Srwatson
103156283Srwatson    -d) dir_arg=true
104156283Srwatson        shift
105156283Srwatson        continue;;
106156283Srwatson
107156283Srwatson    -g) chgrpcmd="$chgrpprog $2"
108156283Srwatson        shift
109156283Srwatson        shift
110156283Srwatson        continue;;
111156283Srwatson
112156283Srwatson    --help) echo "$usage"; exit $?;;
113156283Srwatson
114156283Srwatson    -m) chmodcmd="$chmodprog $2"
115156283Srwatson        shift
116156283Srwatson        shift
117156283Srwatson        continue;;
118156283Srwatson
119156283Srwatson    -o) chowncmd="$chownprog $2"
120156283Srwatson        shift
121156283Srwatson        shift
122156283Srwatson        continue;;
123156283Srwatson
124156283Srwatson    -s) stripcmd=$stripprog
125156283Srwatson        shift
126156283Srwatson        continue;;
127156283Srwatson
128156283Srwatson    -t) dstarg=$2
129156283Srwatson	shift
130156283Srwatson	shift
131156283Srwatson	continue;;
132156283Srwatson
133156283Srwatson    -T) no_target_directory=true
134156283Srwatson	shift
135156283Srwatson	continue;;
136156283Srwatson
137156283Srwatson    --version) echo "$0 $scriptversion"; exit $?;;
138156283Srwatson
139156283Srwatson    *)  # When -d is used, all remaining arguments are directories to create.
140156283Srwatson	# When -t is used, the destination is already specified.
141156283Srwatson	test -n "$dir_arg$dstarg" && break
142156283Srwatson        # Otherwise, the last argument is the destination.  Remove it from $@.
143156283Srwatson	for arg
144156283Srwatson	do
145156283Srwatson          if test -n "$dstarg"; then
146156283Srwatson	    # $@ is not empty: it contains at least $arg.
147156283Srwatson	    set fnord "$@" "$dstarg"
148156283Srwatson	    shift # fnord
149156283Srwatson	  fi
150156283Srwatson	  shift # arg
151156283Srwatson	  dstarg=$arg
152156283Srwatson	done
153156283Srwatson	break;;
154156283Srwatson  esac
155156283Srwatsondone
156156283Srwatson
157156283Srwatsonif test -z "$1"; then
158156283Srwatson  if test -z "$dir_arg"; then
159156283Srwatson    echo "$0: no input file specified." >&2
160156283Srwatson    exit 1
161156283Srwatson  fi
162156283Srwatson  # It's OK to call `install-sh -d' without argument.
163156283Srwatson  # This can happen when creating conditional directories.
164156283Srwatson  exit 0
165156283Srwatsonfi
166156283Srwatson
167156283Srwatsonfor src
168156283Srwatsondo
169156283Srwatson  # Protect names starting with `-'.
170156283Srwatson  case $src in
171156283Srwatson    -*) src=./$src ;;
172156283Srwatson  esac
173156283Srwatson
174156283Srwatson  if test -n "$dir_arg"; then
175156283Srwatson    dst=$src
176156283Srwatson    src=
177156283Srwatson
178156283Srwatson    if test -d "$dst"; then
179156283Srwatson      mkdircmd=:
180156283Srwatson      chmodcmd=
181156283Srwatson    else
182156283Srwatson      mkdircmd=$mkdirprog
183156283Srwatson    fi
184156283Srwatson  else
185156283Srwatson    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
186156283Srwatson    # might cause directories to be created, which would be especially bad
187156283Srwatson    # if $src (and thus $dsttmp) contains '*'.
188156283Srwatson    if test ! -f "$src" && test ! -d "$src"; then
189156283Srwatson      echo "$0: $src does not exist." >&2
190156283Srwatson      exit 1
191156283Srwatson    fi
192156283Srwatson
193156283Srwatson    if test -z "$dstarg"; then
194156283Srwatson      echo "$0: no destination specified." >&2
195156283Srwatson      exit 1
196156283Srwatson    fi
197156283Srwatson
198156283Srwatson    dst=$dstarg
199156283Srwatson    # Protect names starting with `-'.
200156283Srwatson    case $dst in
201156283Srwatson      -*) dst=./$dst ;;
202156283Srwatson    esac
203156283Srwatson
204156283Srwatson    # If destination is a directory, append the input filename; won't work
205156283Srwatson    # if double slashes aren't ignored.
206156283Srwatson    if test -d "$dst"; then
207156283Srwatson      if test -n "$no_target_directory"; then
208156283Srwatson	echo "$0: $dstarg: Is a directory" >&2
209156283Srwatson	exit 1
210156283Srwatson      fi
211156283Srwatson      dst=$dst/`basename "$src"`
212156283Srwatson    fi
213156283Srwatson  fi
214156283Srwatson
215156283Srwatson  # This sed command emulates the dirname command.
216156283Srwatson  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
217156283Srwatson
218156283Srwatson  # Make sure that the destination directory exists.
219156283Srwatson
220156283Srwatson  # Skip lots of stat calls in the usual case.
221156283Srwatson  if test ! -d "$dstdir"; then
222156283Srwatson    defaultIFS='
223156283Srwatson	 '
224156283Srwatson    IFS="${IFS-$defaultIFS}"
225156283Srwatson
226156283Srwatson    oIFS=$IFS
227156283Srwatson    # Some sh's can't handle IFS=/ for some reason.
228156283Srwatson    IFS='%'
229156283Srwatson    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
230156283Srwatson    shift
231156283Srwatson    IFS=$oIFS
232156283Srwatson
233156283Srwatson    pathcomp=
234156283Srwatson
235156283Srwatson    while test $# -ne 0 ; do
236156283Srwatson      pathcomp=$pathcomp$1
237156283Srwatson      shift
238156283Srwatson      if test ! -d "$pathcomp"; then
239156283Srwatson        $mkdirprog "$pathcomp"
240156283Srwatson	# mkdir can fail with a `File exist' error in case several
241156283Srwatson	# install-sh are creating the directory concurrently.  This
242156283Srwatson	# is OK.
243156283Srwatson	test -d "$pathcomp" || exit
244156283Srwatson      fi
245156283Srwatson      pathcomp=$pathcomp/
246156283Srwatson    done
247156283Srwatson  fi
248156283Srwatson
249156283Srwatson  if test -n "$dir_arg"; then
250156283Srwatson    $doit $mkdircmd "$dst" \
251156283Srwatson      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
252156283Srwatson      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
253156283Srwatson      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
254156283Srwatson      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
255156283Srwatson
256156283Srwatson  else
257156283Srwatson    dstfile=`basename "$dst"`
258156283Srwatson
259156283Srwatson    # Make a couple of temp file names in the proper directory.
260156283Srwatson    dsttmp=$dstdir/_inst.$$_
261156283Srwatson    rmtmp=$dstdir/_rm.$$_
262156283Srwatson
263156283Srwatson    # Trap to clean up those temp files at exit.
264156283Srwatson    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
265156283Srwatson    trap '(exit $?); exit' 1 2 13 15
266156283Srwatson
267156283Srwatson    # Copy the file name to the temp name.
268156283Srwatson    $doit $cpprog "$src" "$dsttmp" &&
269156283Srwatson
270156283Srwatson    # and set any options; do chmod last to preserve setuid bits.
271156283Srwatson    #
272156283Srwatson    # If any of these fail, we abort the whole thing.  If we want to
273156283Srwatson    # ignore errors from any of these, just make sure not to ignore
274156283Srwatson    # errors from the above "$doit $cpprog $src $dsttmp" command.
275156283Srwatson    #
276156283Srwatson    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
277156283Srwatson      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
278156283Srwatson      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
279156283Srwatson      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
280156283Srwatson
281156283Srwatson    # Now rename the file to the real destination.
282156283Srwatson    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
283156283Srwatson      || {
284156283Srwatson	   # The rename failed, perhaps because mv can't rename something else
285156283Srwatson	   # to itself, or perhaps because mv is so ancient that it does not
286156283Srwatson	   # support -f.
287156283Srwatson
288156283Srwatson	   # Now remove or move aside any old file at destination location.
289156283Srwatson	   # We try this two ways since rm can't unlink itself on some
290156283Srwatson	   # systems and the destination file might be busy for other
291156283Srwatson	   # reasons.  In this case, the final cleanup might fail but the new
292156283Srwatson	   # file should still install successfully.
293156283Srwatson	   {
294156283Srwatson	     if test -f "$dstdir/$dstfile"; then
295156283Srwatson	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
296156283Srwatson	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
297156283Srwatson	       || {
298156283Srwatson		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
299156283Srwatson		 (exit 1); exit 1
300156283Srwatson	       }
301156283Srwatson	     else
302156283Srwatson	       :
303156283Srwatson	     fi
304156283Srwatson	   } &&
305156283Srwatson
306156283Srwatson	   # Now rename the file to the real destination.
307156283Srwatson	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
308156283Srwatson	 }
309156283Srwatson    }
310156283Srwatson  fi || { (exit 1); exit 1; }
311156283Srwatsondone
312156283Srwatson
313156283Srwatson# The final little trick to "correctly" pass the exit status to the exit trap.
314156283Srwatson{
315156283Srwatson  (exit 0); exit 0
316156283Srwatson}
317156283Srwatson
318156283Srwatson# Local variables:
319156283Srwatson# eval: (add-hook 'write-file-hooks 'time-stamp)
320156283Srwatson# time-stamp-start: "scriptversion="
321156283Srwatson# time-stamp-format: "%:y-%02m-%02d.%02H"
322156283Srwatson# time-stamp-end: "$"
323156283Srwatson# End:
324