install-sh revision 27702724
127702724Smrg#!/bin/sh
227702724Smrg# install - install a program, script, or datafile
327702724Smrg
427702724Smrgscriptversion=2005-05-14.22
527702724Smrg
627702724Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was
727702724Smrg# later released in X11R6 (xc/config/util/install.sh) with the
827702724Smrg# following copyright and license.
927702724Smrg#
1027702724Smrg# Copyright (C) 1994 X Consortium
1127702724Smrg#
1227702724Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy
1327702724Smrg# of this software and associated documentation files (the "Software"), to
1427702724Smrg# deal in the Software without restriction, including without limitation the
1527702724Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1627702724Smrg# sell copies of the Software, and to permit persons to whom the Software is
1727702724Smrg# furnished to do so, subject to the following conditions:
1827702724Smrg#
1927702724Smrg# The above copyright notice and this permission notice shall be included in
2027702724Smrg# all copies or substantial portions of the Software.
2127702724Smrg#
2227702724Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2327702724Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2427702724Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2527702724Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2627702724Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
2727702724Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2827702724Smrg#
2927702724Smrg# Except as contained in this notice, the name of the X Consortium shall not
3027702724Smrg# be used in advertising or otherwise to promote the sale, use or other deal-
3127702724Smrg# ings in this Software without prior written authorization from the X Consor-
3227702724Smrg# tium.
3327702724Smrg#
3427702724Smrg#
3527702724Smrg# FSF changes to this file are in the public domain.
3627702724Smrg#
3727702724Smrg# Calling this script install-sh is preferred over install.sh, to prevent
3827702724Smrg# `make' implicit rules from creating a file called install from it
3927702724Smrg# when there is no Makefile.
4027702724Smrg#
4127702724Smrg# This script is compatible with the BSD install script, but was written
4227702724Smrg# from scratch.  It can only install one file at a time, a restriction
4327702724Smrg# shared with many OS's install programs.
4427702724Smrg
4527702724Smrg# set DOITPROG to echo to test this script
4627702724Smrg
4727702724Smrg# Don't use :- since 4.3BSD and earlier shells don't like it.
4827702724Smrgdoit="${DOITPROG-}"
4927702724Smrg
5027702724Smrg# put in absolute paths if you don't have them in your path; or use env. vars.
5127702724Smrg
5227702724Smrgmvprog="${MVPROG-mv}"
5327702724Smrgcpprog="${CPPROG-cp}"
5427702724Smrgchmodprog="${CHMODPROG-chmod}"
5527702724Smrgchownprog="${CHOWNPROG-chown}"
5627702724Smrgchgrpprog="${CHGRPPROG-chgrp}"
5727702724Smrgstripprog="${STRIPPROG-strip}"
5827702724Smrgrmprog="${RMPROG-rm}"
5927702724Smrgmkdirprog="${MKDIRPROG-mkdir}"
6027702724Smrg
6127702724Smrgchmodcmd="$chmodprog 0755"
6227702724Smrgchowncmd=
6327702724Smrgchgrpcmd=
6427702724Smrgstripcmd=
6527702724Smrgrmcmd="$rmprog -f"
6627702724Smrgmvcmd="$mvprog"
6727702724Smrgsrc=
6827702724Smrgdst=
6927702724Smrgdir_arg=
7027702724Smrgdstarg=
7127702724Smrgno_target_directory=
7227702724Smrg
7327702724Smrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
7427702724Smrg   or: $0 [OPTION]... SRCFILES... DIRECTORY
7527702724Smrg   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
7627702724Smrg   or: $0 [OPTION]... -d DIRECTORIES...
7727702724Smrg
7827702724SmrgIn the 1st form, copy SRCFILE to DSTFILE.
7927702724SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
8027702724SmrgIn the 4th, create DIRECTORIES.
8127702724Smrg
8227702724SmrgOptions:
8327702724Smrg-c         (ignored)
8427702724Smrg-d         create directories instead of installing files.
8527702724Smrg-g GROUP   $chgrpprog installed files to GROUP.
8627702724Smrg-m MODE    $chmodprog installed files to MODE.
8727702724Smrg-o USER    $chownprog installed files to USER.
8827702724Smrg-s         $stripprog installed files.
8927702724Smrg-t DIRECTORY  install into DIRECTORY.
9027702724Smrg-T         report an error if DSTFILE is a directory.
9127702724Smrg--help     display this help and exit.
9227702724Smrg--version  display version info and exit.
9327702724Smrg
9427702724SmrgEnvironment variables override the default commands:
9527702724Smrg  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
9627702724Smrg"
9727702724Smrg
9827702724Smrgwhile test -n "$1"; do
9927702724Smrg  case $1 in
10027702724Smrg    -c) shift
10127702724Smrg        continue;;
10227702724Smrg
10327702724Smrg    -d) dir_arg=true
10427702724Smrg        shift
10527702724Smrg        continue;;
10627702724Smrg
10727702724Smrg    -g) chgrpcmd="$chgrpprog $2"
10827702724Smrg        shift
10927702724Smrg        shift
11027702724Smrg        continue;;
11127702724Smrg
11227702724Smrg    --help) echo "$usage"; exit $?;;
11327702724Smrg
11427702724Smrg    -m) chmodcmd="$chmodprog $2"
11527702724Smrg        shift
11627702724Smrg        shift
11727702724Smrg        continue;;
11827702724Smrg
11927702724Smrg    -o) chowncmd="$chownprog $2"
12027702724Smrg        shift
12127702724Smrg        shift
12227702724Smrg        continue;;
12327702724Smrg
12427702724Smrg    -s) stripcmd=$stripprog
12527702724Smrg        shift
12627702724Smrg        continue;;
12727702724Smrg
12827702724Smrg    -t) dstarg=$2
12927702724Smrg	shift
13027702724Smrg	shift
13127702724Smrg	continue;;
13227702724Smrg
13327702724Smrg    -T) no_target_directory=true
13427702724Smrg	shift
13527702724Smrg	continue;;
13627702724Smrg
13727702724Smrg    --version) echo "$0 $scriptversion"; exit $?;;
13827702724Smrg
13927702724Smrg    *)  # When -d is used, all remaining arguments are directories to create.
14027702724Smrg	# When -t is used, the destination is already specified.
14127702724Smrg	test -n "$dir_arg$dstarg" && break
14227702724Smrg        # Otherwise, the last argument is the destination.  Remove it from $@.
14327702724Smrg	for arg
14427702724Smrg	do
14527702724Smrg          if test -n "$dstarg"; then
14627702724Smrg	    # $@ is not empty: it contains at least $arg.
14727702724Smrg	    set fnord "$@" "$dstarg"
14827702724Smrg	    shift # fnord
14927702724Smrg	  fi
15027702724Smrg	  shift # arg
15127702724Smrg	  dstarg=$arg
15227702724Smrg	done
15327702724Smrg	break;;
15427702724Smrg  esac
15527702724Smrgdone
15627702724Smrg
15727702724Smrgif test -z "$1"; then
15827702724Smrg  if test -z "$dir_arg"; then
15927702724Smrg    echo "$0: no input file specified." >&2
16027702724Smrg    exit 1
16127702724Smrg  fi
16227702724Smrg  # It's OK to call `install-sh -d' without argument.
16327702724Smrg  # This can happen when creating conditional directories.
16427702724Smrg  exit 0
16527702724Smrgfi
16627702724Smrg
16727702724Smrgfor src
16827702724Smrgdo
16927702724Smrg  # Protect names starting with `-'.
17027702724Smrg  case $src in
17127702724Smrg    -*) src=./$src ;;
17227702724Smrg  esac
17327702724Smrg
17427702724Smrg  if test -n "$dir_arg"; then
17527702724Smrg    dst=$src
17627702724Smrg    src=
17727702724Smrg
17827702724Smrg    if test -d "$dst"; then
17927702724Smrg      mkdircmd=:
18027702724Smrg      chmodcmd=
18127702724Smrg    else
18227702724Smrg      mkdircmd=$mkdirprog
18327702724Smrg    fi
18427702724Smrg  else
18527702724Smrg    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
18627702724Smrg    # might cause directories to be created, which would be especially bad
18727702724Smrg    # if $src (and thus $dsttmp) contains '*'.
18827702724Smrg    if test ! -f "$src" && test ! -d "$src"; then
18927702724Smrg      echo "$0: $src does not exist." >&2
19027702724Smrg      exit 1
19127702724Smrg    fi
19227702724Smrg
19327702724Smrg    if test -z "$dstarg"; then
19427702724Smrg      echo "$0: no destination specified." >&2
19527702724Smrg      exit 1
19627702724Smrg    fi
19727702724Smrg
19827702724Smrg    dst=$dstarg
19927702724Smrg    # Protect names starting with `-'.
20027702724Smrg    case $dst in
20127702724Smrg      -*) dst=./$dst ;;
20227702724Smrg    esac
20327702724Smrg
20427702724Smrg    # If destination is a directory, append the input filename; won't work
20527702724Smrg    # if double slashes aren't ignored.
20627702724Smrg    if test -d "$dst"; then
20727702724Smrg      if test -n "$no_target_directory"; then
20827702724Smrg	echo "$0: $dstarg: Is a directory" >&2
20927702724Smrg	exit 1
21027702724Smrg      fi
21127702724Smrg      dst=$dst/`basename "$src"`
21227702724Smrg    fi
21327702724Smrg  fi
21427702724Smrg
21527702724Smrg  # This sed command emulates the dirname command.
21627702724Smrg  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
21727702724Smrg
21827702724Smrg  # Make sure that the destination directory exists.
21927702724Smrg
22027702724Smrg  # Skip lots of stat calls in the usual case.
22127702724Smrg  if test ! -d "$dstdir"; then
22227702724Smrg    defaultIFS='
22327702724Smrg	 '
22427702724Smrg    IFS="${IFS-$defaultIFS}"
22527702724Smrg
22627702724Smrg    oIFS=$IFS
22727702724Smrg    # Some sh's can't handle IFS=/ for some reason.
22827702724Smrg    IFS='%'
22927702724Smrg    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
23027702724Smrg    shift
23127702724Smrg    IFS=$oIFS
23227702724Smrg
23327702724Smrg    pathcomp=
23427702724Smrg
23527702724Smrg    while test $# -ne 0 ; do
23627702724Smrg      pathcomp=$pathcomp$1
23727702724Smrg      shift
23827702724Smrg      if test ! -d "$pathcomp"; then
23927702724Smrg        $mkdirprog "$pathcomp"
24027702724Smrg	# mkdir can fail with a `File exist' error in case several
24127702724Smrg	# install-sh are creating the directory concurrently.  This
24227702724Smrg	# is OK.
24327702724Smrg	test -d "$pathcomp" || exit
24427702724Smrg      fi
24527702724Smrg      pathcomp=$pathcomp/
24627702724Smrg    done
24727702724Smrg  fi
24827702724Smrg
24927702724Smrg  if test -n "$dir_arg"; then
25027702724Smrg    $doit $mkdircmd "$dst" \
25127702724Smrg      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
25227702724Smrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
25327702724Smrg      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
25427702724Smrg      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
25527702724Smrg
25627702724Smrg  else
25727702724Smrg    dstfile=`basename "$dst"`
25827702724Smrg
25927702724Smrg    # Make a couple of temp file names in the proper directory.
26027702724Smrg    dsttmp=$dstdir/_inst.$$_
26127702724Smrg    rmtmp=$dstdir/_rm.$$_
26227702724Smrg
26327702724Smrg    # Trap to clean up those temp files at exit.
26427702724Smrg    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
26527702724Smrg    trap '(exit $?); exit' 1 2 13 15
26627702724Smrg
26727702724Smrg    # Copy the file name to the temp name.
26827702724Smrg    $doit $cpprog "$src" "$dsttmp" &&
26927702724Smrg
27027702724Smrg    # and set any options; do chmod last to preserve setuid bits.
27127702724Smrg    #
27227702724Smrg    # If any of these fail, we abort the whole thing.  If we want to
27327702724Smrg    # ignore errors from any of these, just make sure not to ignore
27427702724Smrg    # errors from the above "$doit $cpprog $src $dsttmp" command.
27527702724Smrg    #
27627702724Smrg    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
27727702724Smrg      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
27827702724Smrg      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
27927702724Smrg      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
28027702724Smrg
28127702724Smrg    # Now rename the file to the real destination.
28227702724Smrg    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
28327702724Smrg      || {
28427702724Smrg	   # The rename failed, perhaps because mv can't rename something else
28527702724Smrg	   # to itself, or perhaps because mv is so ancient that it does not
28627702724Smrg	   # support -f.
28727702724Smrg
28827702724Smrg	   # Now remove or move aside any old file at destination location.
28927702724Smrg	   # We try this two ways since rm can't unlink itself on some
29027702724Smrg	   # systems and the destination file might be busy for other
29127702724Smrg	   # reasons.  In this case, the final cleanup might fail but the new
29227702724Smrg	   # file should still install successfully.
29327702724Smrg	   {
29427702724Smrg	     if test -f "$dstdir/$dstfile"; then
29527702724Smrg	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
29627702724Smrg	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
29727702724Smrg	       || {
29827702724Smrg		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
29927702724Smrg		 (exit 1); exit 1
30027702724Smrg	       }
30127702724Smrg	     else
30227702724Smrg	       :
30327702724Smrg	     fi
30427702724Smrg	   } &&
30527702724Smrg
30627702724Smrg	   # Now rename the file to the real destination.
30727702724Smrg	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
30827702724Smrg	 }
30927702724Smrg    }
31027702724Smrg  fi || { (exit 1); exit 1; }
31127702724Smrgdone
31227702724Smrg
31327702724Smrg# The final little trick to "correctly" pass the exit status to the exit trap.
31427702724Smrg{
31527702724Smrg  (exit 0); exit 0
31627702724Smrg}
31727702724Smrg
31827702724Smrg# Local variables:
31927702724Smrg# eval: (add-hook 'write-file-hooks 'time-stamp)
32027702724Smrg# time-stamp-start: "scriptversion="
32127702724Smrg# time-stamp-format: "%:y-%02m-%02d.%02H"
32227702724Smrg# time-stamp-end: "$"
32327702724Smrg# End:
324