153e90a53Smrg#!/bin/sh
253e90a53Smrg# install - install a program, script, or datafile
353e90a53Smrg
453e90a53Smrgscriptversion=2005-05-14.22
553e90a53Smrg
653e90a53Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
753e90a53Smrg# later released in X11R6 (xc/config/util/install.sh) with the
853e90a53Smrg# following copyright and license.
953e90a53Smrg#
1053e90a53Smrg# Copyright (C) 1994 X Consortium
1153e90a53Smrg#
1253e90a53Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1353e90a53Smrg# of this software and associated documentation files (the "Software"), to
1453e90a53Smrg# deal in the Software without restriction, including without limitation the
1553e90a53Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1653e90a53Smrg# sell copies of the Software, and to permit persons to whom the Software is
1753e90a53Smrg# furnished to do so, subject to the following conditions:
1853e90a53Smrg#
1953e90a53Smrg# The above copyright notice and this permission notice shall be included in
2053e90a53Smrg# all copies or substantial portions of the Software.
2153e90a53Smrg#
2253e90a53Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2353e90a53Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2453e90a53Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2553e90a53Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2653e90a53Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2753e90a53Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2853e90a53Smrg#
2953e90a53Smrg# Except as contained in this notice, the name of the X Consortium shall not
3053e90a53Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3153e90a53Smrg# ings in this Software without prior written authorization from the X Consor-
3253e90a53Smrg# tium.
3353e90a53Smrg#
3453e90a53Smrg#
3553e90a53Smrg# FSF changes to this file are in the public domain.
3653e90a53Smrg#
3753e90a53Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3853e90a53Smrg# `make' implicit rules from creating a file called install from it
3953e90a53Smrg# when there is no Makefile.
4053e90a53Smrg#
4153e90a53Smrg# This script is compatible with the BSD install script, but was written
4253e90a53Smrg# from scratch.  It can only install one file at a time, a restriction
4353e90a53Smrg# shared with many OS's install programs.
4453e90a53Smrg
4553e90a53Smrg# set DOITPROG to echo to test this script
4653e90a53Smrg
4753e90a53Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
4853e90a53Smrgdoit="${DOITPROG-}"
4953e90a53Smrg
5053e90a53Smrg# put in absolute paths if you don't have them in your path; or use env. vars.
5153e90a53Smrg
5253e90a53Smrgmvprog="${MVPROG-mv}"
5353e90a53Smrgcpprog="${CPPROG-cp}"
5453e90a53Smrgchmodprog="${CHMODPROG-chmod}"
5553e90a53Smrgchownprog="${CHOWNPROG-chown}"
5653e90a53Smrgchgrpprog="${CHGRPPROG-chgrp}"
5753e90a53Smrgstripprog="${STRIPPROG-strip}"
5853e90a53Smrgrmprog="${RMPROG-rm}"
5953e90a53Smrgmkdirprog="${MKDIRPROG-mkdir}"
6053e90a53Smrg
6153e90a53Smrgchmodcmd="$chmodprog 0755"
6253e90a53Smrgchowncmd=
6353e90a53Smrgchgrpcmd=
6453e90a53Smrgstripcmd=
6553e90a53Smrgrmcmd="$rmprog -f"
6653e90a53Smrgmvcmd="$mvprog"
6753e90a53Smrgsrc=
6853e90a53Smrgdst=
6953e90a53Smrgdir_arg=
7053e90a53Smrgdstarg=
7153e90a53Smrgno_target_directory=
7253e90a53Smrg
7353e90a53Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
7453e90a53Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
7553e90a53Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
7653e90a53Smrg   or: $0 [OPTION]... -d DIRECTORIES...
7753e90a53Smrg
7853e90a53SmrgIn the 1st form, copy SRCFILE to DSTFILE.
7953e90a53SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
8053e90a53SmrgIn the 4th, create DIRECTORIES.
8153e90a53Smrg
8253e90a53SmrgOptions:
8353e90a53Smrg-c         (ignored)
8453e90a53Smrg-d         create directories instead of installing files.
8553e90a53Smrg-g GROUP   $chgrpprog installed files to GROUP.
8653e90a53Smrg-m MODE    $chmodprog installed files to MODE.
8753e90a53Smrg-o USER    $chownprog installed files to USER.
8853e90a53Smrg-s         $stripprog installed files.
8953e90a53Smrg-t DIRECTORY  install into DIRECTORY.
9053e90a53Smrg-T         report an error if DSTFILE is a directory.
9153e90a53Smrg--help     display this help and exit.
9253e90a53Smrg--version  display version info and exit.
9353e90a53Smrg
9453e90a53SmrgEnvironment variables override the default commands:
9553e90a53Smrg  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
9653e90a53Smrg"
9753e90a53Smrg
9853e90a53Smrgwhile test -n "$1"; do
9953e90a53Smrg  case $1 in
10053e90a53Smrg    -c) shift
10153e90a53Smrg        continue;;
10253e90a53Smrg
10353e90a53Smrg    -d) dir_arg=true
10453e90a53Smrg        shift
10553e90a53Smrg        continue;;
10653e90a53Smrg
10753e90a53Smrg    -g) chgrpcmd="$chgrpprog $2"
10853e90a53Smrg        shift
10953e90a53Smrg        shift
11053e90a53Smrg        continue;;
11153e90a53Smrg
11253e90a53Smrg    --help) echo "$usage"; exit $?;;
11353e90a53Smrg
11453e90a53Smrg    -m) chmodcmd="$chmodprog $2"
11553e90a53Smrg        shift
11653e90a53Smrg        shift
11753e90a53Smrg        continue;;
11853e90a53Smrg
11953e90a53Smrg    -o) chowncmd="$chownprog $2"
12053e90a53Smrg        shift
12153e90a53Smrg        shift
12253e90a53Smrg        continue;;
12353e90a53Smrg
12453e90a53Smrg    -s) stripcmd=$stripprog
12553e90a53Smrg        shift
12653e90a53Smrg        continue;;
12753e90a53Smrg
12853e90a53Smrg    -t) dstarg=$2
12953e90a53Smrg	shift
13053e90a53Smrg	shift
13153e90a53Smrg	continue;;
13253e90a53Smrg
13353e90a53Smrg    -T) no_target_directory=true
13453e90a53Smrg	shift
13553e90a53Smrg	continue;;
13653e90a53Smrg
13753e90a53Smrg    --version) echo "$0 $scriptversion"; exit $?;;
13853e90a53Smrg
13953e90a53Smrg    *)  # When -d is used, all remaining arguments are directories to create.
14053e90a53Smrg	# When -t is used, the destination is already specified.
14153e90a53Smrg	test -n "$dir_arg$dstarg" && break
14253e90a53Smrg        # Otherwise, the last argument is the destination.  Remove it from $@.
14353e90a53Smrg	for arg
14453e90a53Smrg	do
14553e90a53Smrg          if test -n "$dstarg"; then
14653e90a53Smrg	    # $@ is not empty: it contains at least $arg.
14753e90a53Smrg	    set fnord "$@" "$dstarg"
14853e90a53Smrg	    shift # fnord
14953e90a53Smrg	  fi
15053e90a53Smrg	  shift # arg
15153e90a53Smrg	  dstarg=$arg
15253e90a53Smrg	done
15353e90a53Smrg	break;;
15453e90a53Smrg  esac
15553e90a53Smrgdone
15653e90a53Smrg
15753e90a53Smrgif test -z "$1"; then
15853e90a53Smrg  if test -z "$dir_arg"; then
15953e90a53Smrg    echo "$0: no input file specified." >&2
16053e90a53Smrg    exit 1
16153e90a53Smrg  fi
16253e90a53Smrg  # It's OK to call `install-sh -d' without argument.
16353e90a53Smrg  # This can happen when creating conditional directories.
16453e90a53Smrg  exit 0
16553e90a53Smrgfi
16653e90a53Smrg
16753e90a53Smrgfor src
16853e90a53Smrgdo
16953e90a53Smrg  # Protect names starting with `-'.
17053e90a53Smrg  case $src in
17153e90a53Smrg    -*) src=./$src ;;
17253e90a53Smrg  esac
17353e90a53Smrg
17453e90a53Smrg  if test -n "$dir_arg"; then
17553e90a53Smrg    dst=$src
17653e90a53Smrg    src=
17753e90a53Smrg
17853e90a53Smrg    if test -d "$dst"; then
17953e90a53Smrg      mkdircmd=:
18053e90a53Smrg      chmodcmd=
18153e90a53Smrg    else
18253e90a53Smrg      mkdircmd=$mkdirprog
18353e90a53Smrg    fi
18453e90a53Smrg  else
18553e90a53Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
18653e90a53Smrg    # might cause directories to be created, which would be especially bad
18753e90a53Smrg    # if $src (and thus $dsttmp) contains '*'.
18853e90a53Smrg    if test ! -f "$src" && test ! -d "$src"; then
18953e90a53Smrg      echo "$0: $src does not exist." >&2
19053e90a53Smrg      exit 1
19153e90a53Smrg    fi
19253e90a53Smrg
19353e90a53Smrg    if test -z "$dstarg"; then
19453e90a53Smrg      echo "$0: no destination specified." >&2
19553e90a53Smrg      exit 1
19653e90a53Smrg    fi
19753e90a53Smrg
19853e90a53Smrg    dst=$dstarg
19953e90a53Smrg    # Protect names starting with `-'.
20053e90a53Smrg    case $dst in
20153e90a53Smrg      -*) dst=./$dst ;;
20253e90a53Smrg    esac
20353e90a53Smrg
20453e90a53Smrg    # If destination is a directory, append the input filename; won't work
20553e90a53Smrg    # if double slashes aren't ignored.
20653e90a53Smrg    if test -d "$dst"; then
20753e90a53Smrg      if test -n "$no_target_directory"; then
20853e90a53Smrg	echo "$0: $dstarg: Is a directory" >&2
20953e90a53Smrg	exit 1
21053e90a53Smrg      fi
21153e90a53Smrg      dst=$dst/`basename "$src"`
21253e90a53Smrg    fi
21353e90a53Smrg  fi
21453e90a53Smrg
21553e90a53Smrg  # This sed command emulates the dirname command.
21653e90a53Smrg  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
21753e90a53Smrg
21853e90a53Smrg  # Make sure that the destination directory exists.
21953e90a53Smrg
22053e90a53Smrg  # Skip lots of stat calls in the usual case.
22153e90a53Smrg  if test ! -d "$dstdir"; then
22253e90a53Smrg    defaultIFS='
22353e90a53Smrg	 '
22453e90a53Smrg    IFS="${IFS-$defaultIFS}"
22553e90a53Smrg
22653e90a53Smrg    oIFS=$IFS
22753e90a53Smrg    # Some sh's can't handle IFS=/ for some reason.
22853e90a53Smrg    IFS='%'
22953e90a53Smrg    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
23053e90a53Smrg    shift
23153e90a53Smrg    IFS=$oIFS
23253e90a53Smrg
23353e90a53Smrg    pathcomp=
23453e90a53Smrg
23553e90a53Smrg    while test $# -ne 0 ; do
23653e90a53Smrg      pathcomp=$pathcomp$1
23753e90a53Smrg      shift
23853e90a53Smrg      if test ! -d "$pathcomp"; then
23953e90a53Smrg        $mkdirprog "$pathcomp"
24053e90a53Smrg	# mkdir can fail with a `File exist' error in case several
24153e90a53Smrg	# install-sh are creating the directory concurrently.  This
24253e90a53Smrg	# is OK.
24353e90a53Smrg	test -d "$pathcomp" || exit
24453e90a53Smrg      fi
24553e90a53Smrg      pathcomp=$pathcomp/
24653e90a53Smrg    done
24753e90a53Smrg  fi
24853e90a53Smrg
24953e90a53Smrg  if test -n "$dir_arg"; then
25053e90a53Smrg    $doit $mkdircmd "$dst" \
25153e90a53Smrg      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
25253e90a53Smrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
25353e90a53Smrg      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
25453e90a53Smrg      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
25553e90a53Smrg
25653e90a53Smrg  else
25753e90a53Smrg    dstfile=`basename "$dst"`
25853e90a53Smrg
25953e90a53Smrg    # Make a couple of temp file names in the proper directory.
26053e90a53Smrg    dsttmp=$dstdir/_inst.$$_
26153e90a53Smrg    rmtmp=$dstdir/_rm.$$_
26253e90a53Smrg
26353e90a53Smrg    # Trap to clean up those temp files at exit.
26453e90a53Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
26553e90a53Smrg    trap '(exit $?); exit' 1 2 13 15
26653e90a53Smrg
26753e90a53Smrg    # Copy the file name to the temp name.
26853e90a53Smrg    $doit $cpprog "$src" "$dsttmp" &&
26953e90a53Smrg
27053e90a53Smrg    # and set any options; do chmod last to preserve setuid bits.
27153e90a53Smrg    #
27253e90a53Smrg    # If any of these fail, we abort the whole thing.  If we want to
27353e90a53Smrg    # ignore errors from any of these, just make sure not to ignore
27453e90a53Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
27553e90a53Smrg    #
27653e90a53Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
27753e90a53Smrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
27853e90a53Smrg      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
27953e90a53Smrg      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
28053e90a53Smrg
28153e90a53Smrg    # Now rename the file to the real destination.
28253e90a53Smrg    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
28353e90a53Smrg      || {
28453e90a53Smrg	   # The rename failed, perhaps because mv can't rename something else
28553e90a53Smrg	   # to itself, or perhaps because mv is so ancient that it does not
28653e90a53Smrg	   # support -f.
28753e90a53Smrg
28853e90a53Smrg	   # Now remove or move aside any old file at destination location.
28953e90a53Smrg	   # We try this two ways since rm can't unlink itself on some
29053e90a53Smrg	   # systems and the destination file might be busy for other
29153e90a53Smrg	   # reasons.  In this case, the final cleanup might fail but the new
29253e90a53Smrg	   # file should still install successfully.
29353e90a53Smrg	   {
29453e90a53Smrg	     if test -f "$dstdir/$dstfile"; then
29553e90a53Smrg	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
29653e90a53Smrg	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
29753e90a53Smrg	       || {
29853e90a53Smrg		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
29953e90a53Smrg		 (exit 1); exit 1
30053e90a53Smrg	       }
30153e90a53Smrg	     else
30253e90a53Smrg	       :
30353e90a53Smrg	     fi
30453e90a53Smrg	   } &&
30553e90a53Smrg
30653e90a53Smrg	   # Now rename the file to the real destination.
30753e90a53Smrg	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
30853e90a53Smrg	 }
30953e90a53Smrg    }
31053e90a53Smrg  fi || { (exit 1); exit 1; }
31153e90a53Smrgdone
31253e90a53Smrg
31353e90a53Smrg# The final little trick to "correctly" pass the exit status to the exit trap.
31453e90a53Smrg{
31553e90a53Smrg  (exit 0); exit 0
31653e90a53Smrg}
31753e90a53Smrg
31853e90a53Smrg# Local variables:
31953e90a53Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
32053e90a53Smrg# time-stamp-start: "scriptversion="
32153e90a53Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
32253e90a53Smrg# time-stamp-end: "$"
32353e90a53Smrg# End:
324