1304732Scy#!/bin/sh
2304732Scy# install - install a program, script, or datafile
3304732Scy
4304732Scyscriptversion=2011-04-20.01; # UTC
5304732Scy
6304732Scy# This originates from X11R5 (mit/util/scripts/install.sh), which was
7304732Scy# later released in X11R6 (xc/config/util/install.sh) with the
8304732Scy# following copyright and license.
9304732Scy#
10304732Scy# Copyright (C) 1994 X Consortium
11304732Scy#
12304732Scy# Permission is hereby granted, free of charge, to any person obtaining a copy
13304732Scy# of this software and associated documentation files (the "Software"), to
14304732Scy# deal in the Software without restriction, including without limitation the
15304732Scy# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16304732Scy# sell copies of the Software, and to permit persons to whom the Software is
17304732Scy# furnished to do so, subject to the following conditions:
18304732Scy#
19304732Scy# The above copyright notice and this permission notice shall be included in
20304732Scy# all copies or substantial portions of the Software.
21304732Scy#
22304732Scy# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23304732Scy# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24304732Scy# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25304732Scy# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26304732Scy# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27304732Scy# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28304732Scy#
29304732Scy# Except as contained in this notice, the name of the X Consortium shall not
30304732Scy# be used in advertising or otherwise to promote the sale, use or other deal-
31304732Scy# ings in this Software without prior written authorization from the X Consor-
32304732Scy# tium.
33304732Scy#
34304732Scy#
35304732Scy# FSF changes to this file are in the public domain.
36304732Scy#
37304732Scy# Calling this script install-sh is preferred over install.sh, to prevent
38304732Scy# `make' implicit rules from creating a file called install from it
39304732Scy# when there is no Makefile.
40304732Scy#
41304732Scy# This script is compatible with the BSD install script, but was written
42304732Scy# from scratch.
43304732Scy
44304732Scynl='
45304732Scy'
46304732ScyIFS=" ""	$nl"
47304732Scy
48304732Scy# set DOITPROG to echo to test this script
49304732Scy
50304732Scy# Don't use :- since 4.3BSD and earlier shells don't like it.
51304732Scydoit=${DOITPROG-}
52304732Scyif test -z "$doit"; then
53304732Scy  doit_exec=exec
54304732Scyelse
55304732Scy  doit_exec=$doit
56304732Scyfi
57304732Scy
58304732Scy# Put in absolute file names if you don't have them in your path;
59304732Scy# or use environment vars.
60304732Scy
61304732Scychgrpprog=${CHGRPPROG-chgrp}
62304732Scychmodprog=${CHMODPROG-chmod}
63304732Scychownprog=${CHOWNPROG-chown}
64304732Scycmpprog=${CMPPROG-cmp}
65304732Scycpprog=${CPPROG-cp}
66304732Scymkdirprog=${MKDIRPROG-mkdir}
67304732Scymvprog=${MVPROG-mv}
68304732Scyrmprog=${RMPROG-rm}
69304732Scystripprog=${STRIPPROG-strip}
70304732Scy
71304732Scyposix_glob='?'
72304732Scyinitialize_posix_glob='
73304732Scy  test "$posix_glob" != "?" || {
74304732Scy    if (set -f) 2>/dev/null; then
75304732Scy      posix_glob=
76304732Scy    else
77304732Scy      posix_glob=:
78304732Scy    fi
79304732Scy  }
80304732Scy'
81304732Scy
82304732Scyposix_mkdir=
83304732Scy
84304732Scy# Desired mode of installed file.
85304732Scymode=0755
86304732Scy
87304732Scychgrpcmd=
88304732Scychmodcmd=$chmodprog
89304732Scychowncmd=
90304732Scymvcmd=$mvprog
91304732Scyrmcmd="$rmprog -f"
92304732Scystripcmd=
93304732Scy
94304732Scysrc=
95304732Scydst=
96304732Scydir_arg=
97304732Scydst_arg=
98304732Scy
99304732Scycopy_on_change=false
100304732Scyno_target_directory=
101304732Scy
102304732Scyusage="\
103304732ScyUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
104304732Scy   or: $0 [OPTION]... SRCFILES... DIRECTORY
105304732Scy   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
106304732Scy   or: $0 [OPTION]... -d DIRECTORIES...
107304732Scy
108304732ScyIn the 1st form, copy SRCFILE to DSTFILE.
109304732ScyIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
110304732ScyIn the 4th, create DIRECTORIES.
111304732Scy
112304732ScyOptions:
113304732Scy     --help     display this help and exit.
114304732Scy     --version  display version info and exit.
115304732Scy
116304732Scy  -c            (ignored)
117304732Scy  -C            install only if different (preserve the last data modification time)
118304732Scy  -d            create directories instead of installing files.
119304732Scy  -g GROUP      $chgrpprog installed files to GROUP.
120304732Scy  -m MODE       $chmodprog installed files to MODE.
121304732Scy  -o USER       $chownprog installed files to USER.
122304732Scy  -s            $stripprog installed files.
123304732Scy  -S            $stripprog installed files.
124304732Scy  -t DIRECTORY  install into DIRECTORY.
125304732Scy  -T            report an error if DSTFILE is a directory.
126304732Scy
127304732ScyEnvironment variables override the default commands:
128304732Scy  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
129304732Scy  RMPROG STRIPPROG
130304732Scy"
131304732Scy
132304732Scywhile test $# -ne 0; do
133304732Scy  case $1 in
134304732Scy    -c) ;;
135304732Scy
136304732Scy    -C) copy_on_change=true;;
137304732Scy
138304732Scy    -d) dir_arg=true;;
139304732Scy
140304732Scy    -g) chgrpcmd="$chgrpprog $2"
141304732Scy	shift;;
142304732Scy
143304732Scy    --help) echo "$usage"; exit $?;;
144304732Scy
145304732Scy    -m) mode=$2
146304732Scy	case $mode in
147304732Scy	  *' '* | *'	'* | *'
148304732Scy'*	  | *'*'* | *'?'* | *'['*)
149304732Scy	    echo "$0: invalid mode: $mode" >&2
150304732Scy	    exit 1;;
151304732Scy	esac
152304732Scy	shift;;
153304732Scy
154304732Scy    -o) chowncmd="$chownprog $2"
155304732Scy	shift;;
156304732Scy
157304732Scy    -s) stripcmd=$stripprog;;
158304732Scy
159304732Scy    -S) stripcmd="$stripprog $2"
160304732Scy	shift;;
161304732Scy
162304732Scy    -t) dst_arg=$2
163304732Scy	shift;;
164304732Scy
165304732Scy    -T) no_target_directory=true;;
166304732Scy
167304732Scy    --version) echo "$0 $scriptversion"; exit $?;;
168304732Scy
169304732Scy    --)	shift
170304732Scy	break;;
171304732Scy
172304732Scy    -*)	echo "$0: invalid option: $1" >&2
173304732Scy	exit 1;;
174304732Scy
175304732Scy    *)  break;;
176304732Scy  esac
177304732Scy  shift
178304732Scydone
179304732Scy
180304732Scyif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
181304732Scy  # When -d is used, all remaining arguments are directories to create.
182304732Scy  # When -t is used, the destination is already specified.
183304732Scy  # Otherwise, the last argument is the destination.  Remove it from $@.
184304732Scy  for arg
185304732Scy  do
186304732Scy    if test -n "$dst_arg"; then
187304732Scy      # $@ is not empty: it contains at least $arg.
188304732Scy      set fnord "$@" "$dst_arg"
189304732Scy      shift # fnord
190304732Scy    fi
191304732Scy    shift # arg
192304732Scy    dst_arg=$arg
193304732Scy  done
194304732Scyfi
195304732Scy
196304732Scyif test $# -eq 0; then
197304732Scy  if test -z "$dir_arg"; then
198304732Scy    echo "$0: no input file specified." >&2
199304732Scy    exit 1
200304732Scy  fi
201304732Scy  # It's OK to call `install-sh -d' without argument.
202304732Scy  # This can happen when creating conditional directories.
203304732Scy  exit 0
204304732Scyfi
205304732Scy
206304732Scyif test -z "$dir_arg"; then
207304732Scy  do_exit='(exit $ret); exit $ret'
208304732Scy  trap "ret=129; $do_exit" 1
209304732Scy  trap "ret=130; $do_exit" 2
210304732Scy  trap "ret=141; $do_exit" 13
211304732Scy  trap "ret=143; $do_exit" 15
212304732Scy
213304732Scy  # Set umask so as not to create temps with too-generous modes.
214304732Scy  # However, 'strip' requires both read and write access to temps.
215304732Scy  case $mode in
216304732Scy    # Optimize common cases.
217304732Scy    *644) cp_umask=133;;
218304732Scy    *755) cp_umask=22;;
219304732Scy
220304732Scy    *[0-7])
221304732Scy      if test -z "$stripcmd"; then
222304732Scy	u_plus_rw=
223304732Scy      else
224304732Scy	u_plus_rw='% 200'
225304732Scy      fi
226304732Scy      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
227304732Scy    *)
228304732Scy      if test -z "$stripcmd"; then
229304732Scy	u_plus_rw=
230304732Scy      else
231304732Scy	u_plus_rw=,u+rw
232304732Scy      fi
233304732Scy      cp_umask=$mode$u_plus_rw;;
234304732Scy  esac
235304732Scyfi
236304732Scy
237304732Scyfor src
238304732Scydo
239304732Scy  # Protect names starting with `-'.
240304732Scy  case $src in
241304732Scy    -*) src=./$src;;
242304732Scy  esac
243304732Scy
244304732Scy  if test -n "$dir_arg"; then
245304732Scy    dst=$src
246304732Scy    dstdir=$dst
247304732Scy    test -d "$dstdir"
248304732Scy    dstdir_status=$?
249304732Scy  else
250304732Scy
251304732Scy    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
252304732Scy    # might cause directories to be created, which would be especially bad
253304732Scy    # if $src (and thus $dsttmp) contains '*'.
254304732Scy    if test ! -f "$src" && test ! -d "$src"; then
255304732Scy      echo "$0: $src does not exist." >&2
256304732Scy      exit 1
257304732Scy    fi
258304732Scy
259304732Scy    if test -z "$dst_arg"; then
260304732Scy      echo "$0: no destination specified." >&2
261304732Scy      exit 1
262304732Scy    fi
263304732Scy
264304732Scy    dst=$dst_arg
265304732Scy    # Protect names starting with `-'.
266304732Scy    case $dst in
267304732Scy      -*) dst=./$dst;;
268304732Scy    esac
269304732Scy
270304732Scy    # If destination is a directory, append the input filename; won't work
271304732Scy    # if double slashes aren't ignored.
272304732Scy    if test -d "$dst"; then
273304732Scy      if test -n "$no_target_directory"; then
274304732Scy	echo "$0: $dst_arg: Is a directory" >&2
275304732Scy	exit 1
276304732Scy      fi
277304732Scy      dstdir=$dst
278304732Scy      dst=$dstdir/`basename "$src"`
279304732Scy      dstdir_status=0
280304732Scy    else
281304732Scy      # Prefer dirname, but fall back on a substitute if dirname fails.
282304732Scy      dstdir=`
283304732Scy	(dirname "$dst") 2>/dev/null ||
284304732Scy	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
285304732Scy	     X"$dst" : 'X\(//\)[^/]' \| \
286304732Scy	     X"$dst" : 'X\(//\)$' \| \
287304732Scy	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
288304732Scy	echo X"$dst" |
289304732Scy	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
290304732Scy		   s//\1/
291304732Scy		   q
292304732Scy		 }
293304732Scy		 /^X\(\/\/\)[^/].*/{
294304732Scy		   s//\1/
295304732Scy		   q
296304732Scy		 }
297304732Scy		 /^X\(\/\/\)$/{
298304732Scy		   s//\1/
299304732Scy		   q
300304732Scy		 }
301304732Scy		 /^X\(\/\).*/{
302304732Scy		   s//\1/
303304732Scy		   q
304304732Scy		 }
305304732Scy		 s/.*/./; q'
306304732Scy      `
307304732Scy
308304732Scy      test -d "$dstdir"
309304732Scy      dstdir_status=$?
310304732Scy    fi
311304732Scy  fi
312304732Scy
313304732Scy  obsolete_mkdir_used=false
314304732Scy
315304732Scy  if test $dstdir_status != 0; then
316304732Scy    case $posix_mkdir in
317304732Scy      '')
318304732Scy	# Create intermediate dirs using mode 755 as modified by the umask.
319304732Scy	# This is like FreeBSD 'install' as of 1997-10-28.
320304732Scy	umask=`umask`
321304732Scy	case $stripcmd.$umask in
322304732Scy	  # Optimize common cases.
323304732Scy	  *[2367][2367]) mkdir_umask=$umask;;
324304732Scy	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
325304732Scy
326304732Scy	  *[0-7])
327304732Scy	    mkdir_umask=`expr $umask + 22 \
328304732Scy	      - $umask % 100 % 40 + $umask % 20 \
329304732Scy	      - $umask % 10 % 4 + $umask % 2
330304732Scy	    `;;
331304732Scy	  *) mkdir_umask=$umask,go-w;;
332304732Scy	esac
333304732Scy
334304732Scy	# With -d, create the new directory with the user-specified mode.
335304732Scy	# Otherwise, rely on $mkdir_umask.
336304732Scy	if test -n "$dir_arg"; then
337304732Scy	  mkdir_mode=-m$mode
338304732Scy	else
339304732Scy	  mkdir_mode=
340304732Scy	fi
341304732Scy
342304732Scy	posix_mkdir=false
343304732Scy	case $umask in
344304732Scy	  *[123567][0-7][0-7])
345304732Scy	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
346304732Scy	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
347304732Scy	    ;;
348304732Scy	  *)
349304732Scy	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
350304732Scy	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
351304732Scy
352304732Scy	    if (umask $mkdir_umask &&
353304732Scy		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
354304732Scy	    then
355304732Scy	      if test -z "$dir_arg" || {
356304732Scy		   # Check for POSIX incompatibilities with -m.
357304732Scy		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
358304732Scy		   # other-writeable bit of parent directory when it shouldn't.
359304732Scy		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
360304732Scy		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
361304732Scy		   case $ls_ld_tmpdir in
362304732Scy		     d????-?r-*) different_mode=700;;
363304732Scy		     d????-?--*) different_mode=755;;
364304732Scy		     *) false;;
365304732Scy		   esac &&
366304732Scy		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
367304732Scy		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
368304732Scy		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
369304732Scy		   }
370304732Scy		 }
371304732Scy	      then posix_mkdir=:
372304732Scy	      fi
373304732Scy	      rmdir "$tmpdir/d" "$tmpdir"
374304732Scy	    else
375304732Scy	      # Remove any dirs left behind by ancient mkdir implementations.
376304732Scy	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
377304732Scy	    fi
378304732Scy	    trap '' 0;;
379304732Scy	esac;;
380304732Scy    esac
381304732Scy
382304732Scy    if
383304732Scy      $posix_mkdir && (
384304732Scy	umask $mkdir_umask &&
385304732Scy	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
386304732Scy      )
387304732Scy    then :
388304732Scy    else
389304732Scy
390304732Scy      # The umask is ridiculous, or mkdir does not conform to POSIX,
391304732Scy      # or it failed possibly due to a race condition.  Create the
392304732Scy      # directory the slow way, step by step, checking for races as we go.
393304732Scy
394304732Scy      case $dstdir in
395304732Scy	/*) prefix='/';;
396304732Scy	-*) prefix='./';;
397304732Scy	*)  prefix='';;
398304732Scy      esac
399304732Scy
400304732Scy      eval "$initialize_posix_glob"
401304732Scy
402304732Scy      oIFS=$IFS
403304732Scy      IFS=/
404304732Scy      $posix_glob set -f
405304732Scy      set fnord $dstdir
406304732Scy      shift
407304732Scy      $posix_glob set +f
408304732Scy      IFS=$oIFS
409304732Scy
410304732Scy      prefixes=
411304732Scy
412304732Scy      for d
413304732Scy      do
414304732Scy	test -z "$d" && continue
415304732Scy
416304732Scy	prefix=$prefix$d
417304732Scy	if test -d "$prefix"; then
418304732Scy	  prefixes=
419304732Scy	else
420304732Scy	  if $posix_mkdir; then
421304732Scy	    (umask=$mkdir_umask &&
422304732Scy	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
423304732Scy	    # Don't fail if two instances are running concurrently.
424304732Scy	    test -d "$prefix" || exit 1
425304732Scy	  else
426304732Scy	    case $prefix in
427304732Scy	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
428304732Scy	      *) qprefix=$prefix;;
429304732Scy	    esac
430304732Scy	    prefixes="$prefixes '$qprefix'"
431304732Scy	  fi
432304732Scy	fi
433304732Scy	prefix=$prefix/
434304732Scy      done
435304732Scy
436304732Scy      if test -n "$prefixes"; then
437304732Scy	# Don't fail if two instances are running concurrently.
438304732Scy	(umask $mkdir_umask &&
439304732Scy	 eval "\$doit_exec \$mkdirprog $prefixes") ||
440304732Scy	  test -d "$dstdir" || exit 1
441304732Scy	obsolete_mkdir_used=true
442304732Scy      fi
443304732Scy    fi
444304732Scy  fi
445304732Scy
446304732Scy  if test -n "$dir_arg"; then
447304732Scy    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
448304732Scy    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
449304732Scy    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
450304732Scy      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
451304732Scy  else
452304732Scy
453304732Scy    # Make a couple of temp file names in the proper directory.
454304732Scy    dsttmp=$dstdir/_inst.$$_
455304732Scy    rmtmp=$dstdir/_rm.$$_
456304732Scy
457304732Scy    # Trap to clean up those temp files at exit.
458304732Scy    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
459304732Scy
460304732Scy    # Copy the file name to the temp name.
461304732Scy    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
462304732Scy
463304732Scy    # and set any options; do chmod last to preserve setuid bits.
464304732Scy    #
465304732Scy    # If any of these fail, we abort the whole thing.  If we want to
466304732Scy    # ignore errors from any of these, just make sure not to ignore
467304732Scy    # errors from the above "$doit $cpprog $src $dsttmp" command.
468304732Scy    #
469304732Scy    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
470304732Scy    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
471304732Scy    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
472304732Scy    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
473304732Scy
474304732Scy    # If -C, don't bother to copy if it wouldn't change the file.
475304732Scy    if $copy_on_change &&
476304732Scy       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
477304732Scy       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
478304732Scy
479304732Scy       eval "$initialize_posix_glob" &&
480304732Scy       $posix_glob set -f &&
481304732Scy       set X $old && old=:$2:$4:$5:$6 &&
482304732Scy       set X $new && new=:$2:$4:$5:$6 &&
483304732Scy       $posix_glob set +f &&
484304732Scy
485304732Scy       test "$old" = "$new" &&
486304732Scy       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
487304732Scy    then
488304732Scy      rm -f "$dsttmp"
489304732Scy    else
490304732Scy      # Rename the file to the real destination.
491304732Scy      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
492304732Scy
493304732Scy      # The rename failed, perhaps because mv can't rename something else
494304732Scy      # to itself, or perhaps because mv is so ancient that it does not
495304732Scy      # support -f.
496304732Scy      {
497304732Scy	# Now remove or move aside any old file at destination location.
498304732Scy	# We try this two ways since rm can't unlink itself on some
499304732Scy	# systems and the destination file might be busy for other
500304732Scy	# reasons.  In this case, the final cleanup might fail but the new
501304732Scy	# file should still install successfully.
502304732Scy	{
503304732Scy	  test ! -f "$dst" ||
504304732Scy	  $doit $rmcmd -f "$dst" 2>/dev/null ||
505304732Scy	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
506304732Scy	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
507304732Scy	  } ||
508304732Scy	  { echo "$0: cannot unlink or rename $dst" >&2
509304732Scy	    (exit 1); exit 1
510304732Scy	  }
511304732Scy	} &&
512304732Scy
513304732Scy	# Now rename the file to the real destination.
514304732Scy	$doit $mvcmd "$dsttmp" "$dst"
515304732Scy      }
516304732Scy    fi || exit 1
517304732Scy
518304732Scy    trap '' 0
519304732Scy  fi
520304732Scydone
521304732Scy
522304732Scy# Local variables:
523304732Scy# eval: (add-hook 'write-file-hooks 'time-stamp)
524304732Scy# time-stamp-start: "scriptversion="
525304732Scy# time-stamp-format: "%:y-%02m-%02d.%02H"
526304732Scy# time-stamp-time-zone: "UTC"
527304732Scy# time-stamp-end: "; # UTC"
528304732Scy# End:
529