191a17321Smrg#!/bin/sh
291a17321Smrg# install - install a program, script, or datafile
391a17321Smrg
491a17321Smrgscriptversion=2005-05-14.22
591a17321Smrg
691a17321Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
791a17321Smrg# later released in X11R6 (xc/config/util/install.sh) with the
891a17321Smrg# following copyright and license.
991a17321Smrg#
1091a17321Smrg# Copyright (C) 1994 X Consortium
1191a17321Smrg#
1291a17321Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1391a17321Smrg# of this software and associated documentation files (the "Software"), to
1491a17321Smrg# deal in the Software without restriction, including without limitation the
1591a17321Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1691a17321Smrg# sell copies of the Software, and to permit persons to whom the Software is
1791a17321Smrg# furnished to do so, subject to the following conditions:
1891a17321Smrg#
1991a17321Smrg# The above copyright notice and this permission notice shall be included in
2091a17321Smrg# all copies or substantial portions of the Software.
2191a17321Smrg#
2291a17321Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2391a17321Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2491a17321Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2591a17321Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2691a17321Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2791a17321Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2891a17321Smrg#
2991a17321Smrg# Except as contained in this notice, the name of the X Consortium shall not
3091a17321Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3191a17321Smrg# ings in this Software without prior written authorization from the X Consor-
3291a17321Smrg# tium.
3391a17321Smrg#
3491a17321Smrg#
3591a17321Smrg# FSF changes to this file are in the public domain.
3691a17321Smrg#
3791a17321Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3891a17321Smrg# `make' implicit rules from creating a file called install from it
3991a17321Smrg# when there is no Makefile.
4091a17321Smrg#
4191a17321Smrg# This script is compatible with the BSD install script, but was written
4291a17321Smrg# from scratch.  It can only install one file at a time, a restriction
4391a17321Smrg# shared with many OS's install programs.
4491a17321Smrg
4591a17321Smrg# set DOITPROG to echo to test this script
4691a17321Smrg
4791a17321Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
4891a17321Smrgdoit="${DOITPROG-}"
4991a17321Smrg
5091a17321Smrg# put in absolute paths if you don't have them in your path; or use env. vars.
5191a17321Smrg
5291a17321Smrgmvprog="${MVPROG-mv}"
5391a17321Smrgcpprog="${CPPROG-cp}"
5491a17321Smrgchmodprog="${CHMODPROG-chmod}"
5591a17321Smrgchownprog="${CHOWNPROG-chown}"
5691a17321Smrgchgrpprog="${CHGRPPROG-chgrp}"
5791a17321Smrgstripprog="${STRIPPROG-strip}"
5891a17321Smrgrmprog="${RMPROG-rm}"
5991a17321Smrgmkdirprog="${MKDIRPROG-mkdir}"
6091a17321Smrg
6191a17321Smrgchmodcmd="$chmodprog 0755"
6291a17321Smrgchowncmd=
6391a17321Smrgchgrpcmd=
6491a17321Smrgstripcmd=
6591a17321Smrgrmcmd="$rmprog -f"
6691a17321Smrgmvcmd="$mvprog"
6791a17321Smrgsrc=
6891a17321Smrgdst=
6991a17321Smrgdir_arg=
7091a17321Smrgdstarg=
7191a17321Smrgno_target_directory=
7291a17321Smrg
7391a17321Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
7491a17321Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
7591a17321Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
7691a17321Smrg   or: $0 [OPTION]... -d DIRECTORIES...
7791a17321Smrg
7891a17321SmrgIn the 1st form, copy SRCFILE to DSTFILE.
7991a17321SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
8091a17321SmrgIn the 4th, create DIRECTORIES.
8191a17321Smrg
8291a17321SmrgOptions:
8391a17321Smrg-c         (ignored)
8491a17321Smrg-d         create directories instead of installing files.
8591a17321Smrg-g GROUP   $chgrpprog installed files to GROUP.
8691a17321Smrg-m MODE    $chmodprog installed files to MODE.
8791a17321Smrg-o USER    $chownprog installed files to USER.
8891a17321Smrg-s         $stripprog installed files.
8991a17321Smrg-t DIRECTORY  install into DIRECTORY.
9091a17321Smrg-T         report an error if DSTFILE is a directory.
9191a17321Smrg--help     display this help and exit.
9291a17321Smrg--version  display version info and exit.
9391a17321Smrg
9491a17321SmrgEnvironment variables override the default commands:
9591a17321Smrg  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
9691a17321Smrg"
9791a17321Smrg
9891a17321Smrgwhile test -n "$1"; do
9991a17321Smrg  case $1 in
10091a17321Smrg    -c) shift
10191a17321Smrg        continue;;
10291a17321Smrg
10391a17321Smrg    -d) dir_arg=true
10491a17321Smrg        shift
10591a17321Smrg        continue;;
10691a17321Smrg
10791a17321Smrg    -g) chgrpcmd="$chgrpprog $2"
10891a17321Smrg        shift
10991a17321Smrg        shift
11091a17321Smrg        continue;;
11191a17321Smrg
11291a17321Smrg    --help) echo "$usage"; exit $?;;
11391a17321Smrg
11491a17321Smrg    -m) chmodcmd="$chmodprog $2"
11591a17321Smrg        shift
11691a17321Smrg        shift
11791a17321Smrg        continue;;
11891a17321Smrg
11991a17321Smrg    -o) chowncmd="$chownprog $2"
12091a17321Smrg        shift
12191a17321Smrg        shift
12291a17321Smrg        continue;;
12391a17321Smrg
12491a17321Smrg    -s) stripcmd=$stripprog
12591a17321Smrg        shift
12691a17321Smrg        continue;;
12791a17321Smrg
12891a17321Smrg    -t) dstarg=$2
12991a17321Smrg	shift
13091a17321Smrg	shift
13191a17321Smrg	continue;;
13291a17321Smrg
13391a17321Smrg    -T) no_target_directory=true
13491a17321Smrg	shift
13591a17321Smrg	continue;;
13691a17321Smrg
13791a17321Smrg    --version) echo "$0 $scriptversion"; exit $?;;
13891a17321Smrg
13991a17321Smrg    *)  # When -d is used, all remaining arguments are directories to create.
14091a17321Smrg	# When -t is used, the destination is already specified.
14191a17321Smrg	test -n "$dir_arg$dstarg" && break
14291a17321Smrg        # Otherwise, the last argument is the destination.  Remove it from $@.
14391a17321Smrg	for arg
14491a17321Smrg	do
14591a17321Smrg          if test -n "$dstarg"; then
14691a17321Smrg	    # $@ is not empty: it contains at least $arg.
14791a17321Smrg	    set fnord "$@" "$dstarg"
14891a17321Smrg	    shift # fnord
14991a17321Smrg	  fi
15091a17321Smrg	  shift # arg
15191a17321Smrg	  dstarg=$arg
15291a17321Smrg	done
15391a17321Smrg	break;;
15491a17321Smrg  esac
15591a17321Smrgdone
15691a17321Smrg
15791a17321Smrgif test -z "$1"; then
15891a17321Smrg  if test -z "$dir_arg"; then
15991a17321Smrg    echo "$0: no input file specified." >&2
16091a17321Smrg    exit 1
16191a17321Smrg  fi
16291a17321Smrg  # It's OK to call `install-sh -d' without argument.
16391a17321Smrg  # This can happen when creating conditional directories.
16491a17321Smrg  exit 0
16591a17321Smrgfi
16691a17321Smrg
16791a17321Smrgfor src
16891a17321Smrgdo
16991a17321Smrg  # Protect names starting with `-'.
17091a17321Smrg  case $src in
17191a17321Smrg    -*) src=./$src ;;
17291a17321Smrg  esac
17391a17321Smrg
17491a17321Smrg  if test -n "$dir_arg"; then
17591a17321Smrg    dst=$src
17691a17321Smrg    src=
17791a17321Smrg
17891a17321Smrg    if test -d "$dst"; then
17991a17321Smrg      mkdircmd=:
18091a17321Smrg      chmodcmd=
18191a17321Smrg    else
18291a17321Smrg      mkdircmd=$mkdirprog
18391a17321Smrg    fi
18491a17321Smrg  else
18591a17321Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
18691a17321Smrg    # might cause directories to be created, which would be especially bad
18791a17321Smrg    # if $src (and thus $dsttmp) contains '*'.
18891a17321Smrg    if test ! -f "$src" && test ! -d "$src"; then
18991a17321Smrg      echo "$0: $src does not exist." >&2
19091a17321Smrg      exit 1
19191a17321Smrg    fi
19291a17321Smrg
19391a17321Smrg    if test -z "$dstarg"; then
19491a17321Smrg      echo "$0: no destination specified." >&2
19591a17321Smrg      exit 1
19691a17321Smrg    fi
19791a17321Smrg
19891a17321Smrg    dst=$dstarg
19991a17321Smrg    # Protect names starting with `-'.
20091a17321Smrg    case $dst in
20191a17321Smrg      -*) dst=./$dst ;;
20291a17321Smrg    esac
20391a17321Smrg
20491a17321Smrg    # If destination is a directory, append the input filename; won't work
20591a17321Smrg    # if double slashes aren't ignored.
20691a17321Smrg    if test -d "$dst"; then
20791a17321Smrg      if test -n "$no_target_directory"; then
20891a17321Smrg	echo "$0: $dstarg: Is a directory" >&2
20991a17321Smrg	exit 1
21091a17321Smrg      fi
21191a17321Smrg      dst=$dst/`basename "$src"`
21291a17321Smrg    fi
21391a17321Smrg  fi
21491a17321Smrg
21591a17321Smrg  # This sed command emulates the dirname command.
21691a17321Smrg  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
21791a17321Smrg
21891a17321Smrg  # Make sure that the destination directory exists.
21991a17321Smrg
22091a17321Smrg  # Skip lots of stat calls in the usual case.
22191a17321Smrg  if test ! -d "$dstdir"; then
22291a17321Smrg    defaultIFS='
22391a17321Smrg	 '
22491a17321Smrg    IFS="${IFS-$defaultIFS}"
22591a17321Smrg
22691a17321Smrg    oIFS=$IFS
22791a17321Smrg    # Some sh's can't handle IFS=/ for some reason.
22891a17321Smrg    IFS='%'
22991a17321Smrg    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
23091a17321Smrg    shift
23191a17321Smrg    IFS=$oIFS
23291a17321Smrg
23391a17321Smrg    pathcomp=
23491a17321Smrg
23591a17321Smrg    while test $# -ne 0 ; do
23691a17321Smrg      pathcomp=$pathcomp$1
23791a17321Smrg      shift
23891a17321Smrg      if test ! -d "$pathcomp"; then
23991a17321Smrg        $mkdirprog "$pathcomp"
24091a17321Smrg	# mkdir can fail with a `File exist' error in case several
24191a17321Smrg	# install-sh are creating the directory concurrently.  This
24291a17321Smrg	# is OK.
24391a17321Smrg	test -d "$pathcomp" || exit
24491a17321Smrg      fi
24591a17321Smrg      pathcomp=$pathcomp/
24691a17321Smrg    done
24791a17321Smrg  fi
24891a17321Smrg
24991a17321Smrg  if test -n "$dir_arg"; then
25091a17321Smrg    $doit $mkdircmd "$dst" \
25191a17321Smrg      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
25291a17321Smrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
25391a17321Smrg      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
25491a17321Smrg      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
25591a17321Smrg
25691a17321Smrg  else
25791a17321Smrg    dstfile=`basename "$dst"`
25891a17321Smrg
25991a17321Smrg    # Make a couple of temp file names in the proper directory.
26091a17321Smrg    dsttmp=$dstdir/_inst.$$_
26191a17321Smrg    rmtmp=$dstdir/_rm.$$_
26291a17321Smrg
26391a17321Smrg    # Trap to clean up those temp files at exit.
26491a17321Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
26591a17321Smrg    trap '(exit $?); exit' 1 2 13 15
26691a17321Smrg
26791a17321Smrg    # Copy the file name to the temp name.
26891a17321Smrg    $doit $cpprog "$src" "$dsttmp" &&
26991a17321Smrg
27091a17321Smrg    # and set any options; do chmod last to preserve setuid bits.
27191a17321Smrg    #
27291a17321Smrg    # If any of these fail, we abort the whole thing.  If we want to
27391a17321Smrg    # ignore errors from any of these, just make sure not to ignore
27491a17321Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
27591a17321Smrg    #
27691a17321Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
27791a17321Smrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
27891a17321Smrg      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
27991a17321Smrg      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
28091a17321Smrg
28191a17321Smrg    # Now rename the file to the real destination.
28291a17321Smrg    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
28391a17321Smrg      || {
28491a17321Smrg	   # The rename failed, perhaps because mv can't rename something else
28591a17321Smrg	   # to itself, or perhaps because mv is so ancient that it does not
28691a17321Smrg	   # support -f.
28791a17321Smrg
28891a17321Smrg	   # Now remove or move aside any old file at destination location.
28991a17321Smrg	   # We try this two ways since rm can't unlink itself on some
29091a17321Smrg	   # systems and the destination file might be busy for other
29191a17321Smrg	   # reasons.  In this case, the final cleanup might fail but the new
29291a17321Smrg	   # file should still install successfully.
29391a17321Smrg	   {
29491a17321Smrg	     if test -f "$dstdir/$dstfile"; then
29591a17321Smrg	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
29691a17321Smrg	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
29791a17321Smrg	       || {
29891a17321Smrg		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
29991a17321Smrg		 (exit 1); exit 1
30091a17321Smrg	       }
30191a17321Smrg	     else
30291a17321Smrg	       :
30391a17321Smrg	     fi
30491a17321Smrg	   } &&
30591a17321Smrg
30691a17321Smrg	   # Now rename the file to the real destination.
30791a17321Smrg	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
30891a17321Smrg	 }
30991a17321Smrg    }
31091a17321Smrg  fi || { (exit 1); exit 1; }
31191a17321Smrgdone
31291a17321Smrg
31391a17321Smrg# The final little trick to "correctly" pass the exit status to the exit trap.
31491a17321Smrg{
31591a17321Smrg  (exit 0); exit 0
31691a17321Smrg}
31791a17321Smrg
31891a17321Smrg# Local variables:
31991a17321Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
32091a17321Smrg# time-stamp-start: "scriptversion="
32191a17321Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
32291a17321Smrg# time-stamp-end: "$"
32391a17321Smrg# End:
324