xref: /freebsd/contrib/openbsm/config/install-sh (revision 3b97a967e1e992eaa2010e8a42f23f51760bc8cb)
13b97a967SRobert Watson#!/bin/sh
23b97a967SRobert Watson# install - install a program, script, or datafile
33b97a967SRobert Watson
43b97a967SRobert Watsonscriptversion=2005-05-14.22
53b97a967SRobert Watson
63b97a967SRobert Watson# This originates from X11R5 (mit/util/scripts/install.sh), which was
73b97a967SRobert Watson# later released in X11R6 (xc/config/util/install.sh) with the
83b97a967SRobert Watson# following copyright and license.
93b97a967SRobert Watson#
103b97a967SRobert Watson# Copyright (C) 1994 X Consortium
113b97a967SRobert Watson#
123b97a967SRobert Watson# Permission is hereby granted, free of charge, to any person obtaining a copy
133b97a967SRobert Watson# of this software and associated documentation files (the "Software"), to
143b97a967SRobert Watson# deal in the Software without restriction, including without limitation the
153b97a967SRobert Watson# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
163b97a967SRobert Watson# sell copies of the Software, and to permit persons to whom the Software is
173b97a967SRobert Watson# furnished to do so, subject to the following conditions:
183b97a967SRobert Watson#
193b97a967SRobert Watson# The above copyright notice and this permission notice shall be included in
203b97a967SRobert Watson# all copies or substantial portions of the Software.
213b97a967SRobert Watson#
223b97a967SRobert Watson# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
233b97a967SRobert Watson# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
243b97a967SRobert Watson# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
253b97a967SRobert Watson# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
263b97a967SRobert Watson# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
273b97a967SRobert Watson# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
283b97a967SRobert Watson#
293b97a967SRobert Watson# Except as contained in this notice, the name of the X Consortium shall not
303b97a967SRobert Watson# be used in advertising or otherwise to promote the sale, use or other deal-
313b97a967SRobert Watson# ings in this Software without prior written authorization from the X Consor-
323b97a967SRobert Watson# tium.
333b97a967SRobert Watson#
343b97a967SRobert Watson#
353b97a967SRobert Watson# FSF changes to this file are in the public domain.
363b97a967SRobert Watson#
373b97a967SRobert Watson# Calling this script install-sh is preferred over install.sh, to prevent
383b97a967SRobert Watson# `make' implicit rules from creating a file called install from it
393b97a967SRobert Watson# when there is no Makefile.
403b97a967SRobert Watson#
413b97a967SRobert Watson# This script is compatible with the BSD install script, but was written
423b97a967SRobert Watson# from scratch.  It can only install one file at a time, a restriction
433b97a967SRobert Watson# shared with many OS's install programs.
443b97a967SRobert Watson
453b97a967SRobert Watson# set DOITPROG to echo to test this script
463b97a967SRobert Watson
473b97a967SRobert Watson# Don't use :- since 4.3BSD and earlier shells don't like it.
483b97a967SRobert Watsondoit="${DOITPROG-}"
493b97a967SRobert Watson
503b97a967SRobert Watson# put in absolute paths if you don't have them in your path; or use env. vars.
513b97a967SRobert Watson
523b97a967SRobert Watsonmvprog="${MVPROG-mv}"
533b97a967SRobert Watsoncpprog="${CPPROG-cp}"
543b97a967SRobert Watsonchmodprog="${CHMODPROG-chmod}"
553b97a967SRobert Watsonchownprog="${CHOWNPROG-chown}"
563b97a967SRobert Watsonchgrpprog="${CHGRPPROG-chgrp}"
573b97a967SRobert Watsonstripprog="${STRIPPROG-strip}"
583b97a967SRobert Watsonrmprog="${RMPROG-rm}"
593b97a967SRobert Watsonmkdirprog="${MKDIRPROG-mkdir}"
603b97a967SRobert Watson
613b97a967SRobert Watsonchmodcmd="$chmodprog 0755"
623b97a967SRobert Watsonchowncmd=
633b97a967SRobert Watsonchgrpcmd=
643b97a967SRobert Watsonstripcmd=
653b97a967SRobert Watsonrmcmd="$rmprog -f"
663b97a967SRobert Watsonmvcmd="$mvprog"
673b97a967SRobert Watsonsrc=
683b97a967SRobert Watsondst=
693b97a967SRobert Watsondir_arg=
703b97a967SRobert Watsondstarg=
713b97a967SRobert Watsonno_target_directory=
723b97a967SRobert Watson
733b97a967SRobert Watsonusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
743b97a967SRobert Watson   or: $0 [OPTION]... SRCFILES... DIRECTORY
753b97a967SRobert Watson   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
763b97a967SRobert Watson   or: $0 [OPTION]... -d DIRECTORIES...
773b97a967SRobert Watson
783b97a967SRobert WatsonIn the 1st form, copy SRCFILE to DSTFILE.
793b97a967SRobert WatsonIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
803b97a967SRobert WatsonIn the 4th, create DIRECTORIES.
813b97a967SRobert Watson
823b97a967SRobert WatsonOptions:
833b97a967SRobert Watson-c         (ignored)
843b97a967SRobert Watson-d         create directories instead of installing files.
853b97a967SRobert Watson-g GROUP   $chgrpprog installed files to GROUP.
863b97a967SRobert Watson-m MODE    $chmodprog installed files to MODE.
873b97a967SRobert Watson-o USER    $chownprog installed files to USER.
883b97a967SRobert Watson-s         $stripprog installed files.
893b97a967SRobert Watson-t DIRECTORY  install into DIRECTORY.
903b97a967SRobert Watson-T         report an error if DSTFILE is a directory.
913b97a967SRobert Watson--help     display this help and exit.
923b97a967SRobert Watson--version  display version info and exit.
933b97a967SRobert Watson
943b97a967SRobert WatsonEnvironment variables override the default commands:
953b97a967SRobert Watson  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
963b97a967SRobert Watson"
973b97a967SRobert Watson
983b97a967SRobert Watsonwhile test -n "$1"; do
993b97a967SRobert Watson  case $1 in
1003b97a967SRobert Watson    -c) shift
1013b97a967SRobert Watson        continue;;
1023b97a967SRobert Watson
1033b97a967SRobert Watson    -d) dir_arg=true
1043b97a967SRobert Watson        shift
1053b97a967SRobert Watson        continue;;
1063b97a967SRobert Watson
1073b97a967SRobert Watson    -g) chgrpcmd="$chgrpprog $2"
1083b97a967SRobert Watson        shift
1093b97a967SRobert Watson        shift
1103b97a967SRobert Watson        continue;;
1113b97a967SRobert Watson
1123b97a967SRobert Watson    --help) echo "$usage"; exit $?;;
1133b97a967SRobert Watson
1143b97a967SRobert Watson    -m) chmodcmd="$chmodprog $2"
1153b97a967SRobert Watson        shift
1163b97a967SRobert Watson        shift
1173b97a967SRobert Watson        continue;;
1183b97a967SRobert Watson
1193b97a967SRobert Watson    -o) chowncmd="$chownprog $2"
1203b97a967SRobert Watson        shift
1213b97a967SRobert Watson        shift
1223b97a967SRobert Watson        continue;;
1233b97a967SRobert Watson
1243b97a967SRobert Watson    -s) stripcmd=$stripprog
1253b97a967SRobert Watson        shift
1263b97a967SRobert Watson        continue;;
1273b97a967SRobert Watson
1283b97a967SRobert Watson    -t) dstarg=$2
1293b97a967SRobert Watson	shift
1303b97a967SRobert Watson	shift
1313b97a967SRobert Watson	continue;;
1323b97a967SRobert Watson
1333b97a967SRobert Watson    -T) no_target_directory=true
1343b97a967SRobert Watson	shift
1353b97a967SRobert Watson	continue;;
1363b97a967SRobert Watson
1373b97a967SRobert Watson    --version) echo "$0 $scriptversion"; exit $?;;
1383b97a967SRobert Watson
1393b97a967SRobert Watson    *)  # When -d is used, all remaining arguments are directories to create.
1403b97a967SRobert Watson	# When -t is used, the destination is already specified.
1413b97a967SRobert Watson	test -n "$dir_arg$dstarg" && break
1423b97a967SRobert Watson        # Otherwise, the last argument is the destination.  Remove it from $@.
1433b97a967SRobert Watson	for arg
1443b97a967SRobert Watson	do
1453b97a967SRobert Watson          if test -n "$dstarg"; then
1463b97a967SRobert Watson	    # $@ is not empty: it contains at least $arg.
1473b97a967SRobert Watson	    set fnord "$@" "$dstarg"
1483b97a967SRobert Watson	    shift # fnord
1493b97a967SRobert Watson	  fi
1503b97a967SRobert Watson	  shift # arg
1513b97a967SRobert Watson	  dstarg=$arg
1523b97a967SRobert Watson	done
1533b97a967SRobert Watson	break;;
1543b97a967SRobert Watson  esac
1553b97a967SRobert Watsondone
1563b97a967SRobert Watson
1573b97a967SRobert Watsonif test -z "$1"; then
1583b97a967SRobert Watson  if test -z "$dir_arg"; then
1593b97a967SRobert Watson    echo "$0: no input file specified." >&2
1603b97a967SRobert Watson    exit 1
1613b97a967SRobert Watson  fi
1623b97a967SRobert Watson  # It's OK to call `install-sh -d' without argument.
1633b97a967SRobert Watson  # This can happen when creating conditional directories.
1643b97a967SRobert Watson  exit 0
1653b97a967SRobert Watsonfi
1663b97a967SRobert Watson
1673b97a967SRobert Watsonfor src
1683b97a967SRobert Watsondo
1693b97a967SRobert Watson  # Protect names starting with `-'.
1703b97a967SRobert Watson  case $src in
1713b97a967SRobert Watson    -*) src=./$src ;;
1723b97a967SRobert Watson  esac
1733b97a967SRobert Watson
1743b97a967SRobert Watson  if test -n "$dir_arg"; then
1753b97a967SRobert Watson    dst=$src
1763b97a967SRobert Watson    src=
1773b97a967SRobert Watson
1783b97a967SRobert Watson    if test -d "$dst"; then
1793b97a967SRobert Watson      mkdircmd=:
1803b97a967SRobert Watson      chmodcmd=
1813b97a967SRobert Watson    else
1823b97a967SRobert Watson      mkdircmd=$mkdirprog
1833b97a967SRobert Watson    fi
1843b97a967SRobert Watson  else
1853b97a967SRobert Watson    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
1863b97a967SRobert Watson    # might cause directories to be created, which would be especially bad
1873b97a967SRobert Watson    # if $src (and thus $dsttmp) contains '*'.
1883b97a967SRobert Watson    if test ! -f "$src" && test ! -d "$src"; then
1893b97a967SRobert Watson      echo "$0: $src does not exist." >&2
1903b97a967SRobert Watson      exit 1
1913b97a967SRobert Watson    fi
1923b97a967SRobert Watson
1933b97a967SRobert Watson    if test -z "$dstarg"; then
1943b97a967SRobert Watson      echo "$0: no destination specified." >&2
1953b97a967SRobert Watson      exit 1
1963b97a967SRobert Watson    fi
1973b97a967SRobert Watson
1983b97a967SRobert Watson    dst=$dstarg
1993b97a967SRobert Watson    # Protect names starting with `-'.
2003b97a967SRobert Watson    case $dst in
2013b97a967SRobert Watson      -*) dst=./$dst ;;
2023b97a967SRobert Watson    esac
2033b97a967SRobert Watson
2043b97a967SRobert Watson    # If destination is a directory, append the input filename; won't work
2053b97a967SRobert Watson    # if double slashes aren't ignored.
2063b97a967SRobert Watson    if test -d "$dst"; then
2073b97a967SRobert Watson      if test -n "$no_target_directory"; then
2083b97a967SRobert Watson	echo "$0: $dstarg: Is a directory" >&2
2093b97a967SRobert Watson	exit 1
2103b97a967SRobert Watson      fi
2113b97a967SRobert Watson      dst=$dst/`basename "$src"`
2123b97a967SRobert Watson    fi
2133b97a967SRobert Watson  fi
2143b97a967SRobert Watson
2153b97a967SRobert Watson  # This sed command emulates the dirname command.
2163b97a967SRobert Watson  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
2173b97a967SRobert Watson
2183b97a967SRobert Watson  # Make sure that the destination directory exists.
2193b97a967SRobert Watson
2203b97a967SRobert Watson  # Skip lots of stat calls in the usual case.
2213b97a967SRobert Watson  if test ! -d "$dstdir"; then
2223b97a967SRobert Watson    defaultIFS='
2233b97a967SRobert Watson	 '
2243b97a967SRobert Watson    IFS="${IFS-$defaultIFS}"
2253b97a967SRobert Watson
2263b97a967SRobert Watson    oIFS=$IFS
2273b97a967SRobert Watson    # Some sh's can't handle IFS=/ for some reason.
2283b97a967SRobert Watson    IFS='%'
2293b97a967SRobert Watson    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
2303b97a967SRobert Watson    shift
2313b97a967SRobert Watson    IFS=$oIFS
2323b97a967SRobert Watson
2333b97a967SRobert Watson    pathcomp=
2343b97a967SRobert Watson
2353b97a967SRobert Watson    while test $# -ne 0 ; do
2363b97a967SRobert Watson      pathcomp=$pathcomp$1
2373b97a967SRobert Watson      shift
2383b97a967SRobert Watson      if test ! -d "$pathcomp"; then
2393b97a967SRobert Watson        $mkdirprog "$pathcomp"
2403b97a967SRobert Watson	# mkdir can fail with a `File exist' error in case several
2413b97a967SRobert Watson	# install-sh are creating the directory concurrently.  This
2423b97a967SRobert Watson	# is OK.
2433b97a967SRobert Watson	test -d "$pathcomp" || exit
2443b97a967SRobert Watson      fi
2453b97a967SRobert Watson      pathcomp=$pathcomp/
2463b97a967SRobert Watson    done
2473b97a967SRobert Watson  fi
2483b97a967SRobert Watson
2493b97a967SRobert Watson  if test -n "$dir_arg"; then
2503b97a967SRobert Watson    $doit $mkdircmd "$dst" \
2513b97a967SRobert Watson      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
2523b97a967SRobert Watson      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
2533b97a967SRobert Watson      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
2543b97a967SRobert Watson      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
2553b97a967SRobert Watson
2563b97a967SRobert Watson  else
2573b97a967SRobert Watson    dstfile=`basename "$dst"`
2583b97a967SRobert Watson
2593b97a967SRobert Watson    # Make a couple of temp file names in the proper directory.
2603b97a967SRobert Watson    dsttmp=$dstdir/_inst.$$_
2613b97a967SRobert Watson    rmtmp=$dstdir/_rm.$$_
2623b97a967SRobert Watson
2633b97a967SRobert Watson    # Trap to clean up those temp files at exit.
2643b97a967SRobert Watson    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
2653b97a967SRobert Watson    trap '(exit $?); exit' 1 2 13 15
2663b97a967SRobert Watson
2673b97a967SRobert Watson    # Copy the file name to the temp name.
2683b97a967SRobert Watson    $doit $cpprog "$src" "$dsttmp" &&
2693b97a967SRobert Watson
2703b97a967SRobert Watson    # and set any options; do chmod last to preserve setuid bits.
2713b97a967SRobert Watson    #
2723b97a967SRobert Watson    # If any of these fail, we abort the whole thing.  If we want to
2733b97a967SRobert Watson    # ignore errors from any of these, just make sure not to ignore
2743b97a967SRobert Watson    # errors from the above "$doit $cpprog $src $dsttmp" command.
2753b97a967SRobert Watson    #
2763b97a967SRobert Watson    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
2773b97a967SRobert Watson      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
2783b97a967SRobert Watson      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
2793b97a967SRobert Watson      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
2803b97a967SRobert Watson
2813b97a967SRobert Watson    # Now rename the file to the real destination.
2823b97a967SRobert Watson    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
2833b97a967SRobert Watson      || {
2843b97a967SRobert Watson	   # The rename failed, perhaps because mv can't rename something else
2853b97a967SRobert Watson	   # to itself, or perhaps because mv is so ancient that it does not
2863b97a967SRobert Watson	   # support -f.
2873b97a967SRobert Watson
2883b97a967SRobert Watson	   # Now remove or move aside any old file at destination location.
2893b97a967SRobert Watson	   # We try this two ways since rm can't unlink itself on some
2903b97a967SRobert Watson	   # systems and the destination file might be busy for other
2913b97a967SRobert Watson	   # reasons.  In this case, the final cleanup might fail but the new
2923b97a967SRobert Watson	   # file should still install successfully.
2933b97a967SRobert Watson	   {
2943b97a967SRobert Watson	     if test -f "$dstdir/$dstfile"; then
2953b97a967SRobert Watson	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
2963b97a967SRobert Watson	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
2973b97a967SRobert Watson	       || {
2983b97a967SRobert Watson		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
2993b97a967SRobert Watson		 (exit 1); exit 1
3003b97a967SRobert Watson	       }
3013b97a967SRobert Watson	     else
3023b97a967SRobert Watson	       :
3033b97a967SRobert Watson	     fi
3043b97a967SRobert Watson	   } &&
3053b97a967SRobert Watson
3063b97a967SRobert Watson	   # Now rename the file to the real destination.
3073b97a967SRobert Watson	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
3083b97a967SRobert Watson	 }
3093b97a967SRobert Watson    }
3103b97a967SRobert Watson  fi || { (exit 1); exit 1; }
3113b97a967SRobert Watsondone
3123b97a967SRobert Watson
3133b97a967SRobert Watson# The final little trick to "correctly" pass the exit status to the exit trap.
3143b97a967SRobert Watson{
3153b97a967SRobert Watson  (exit 0); exit 0
3163b97a967SRobert Watson}
3173b97a967SRobert Watson
3183b97a967SRobert Watson# Local variables:
3193b97a967SRobert Watson# eval: (add-hook 'write-file-hooks 'time-stamp)
3203b97a967SRobert Watson# time-stamp-start: "scriptversion="
3213b97a967SRobert Watson# time-stamp-format: "%:y-%02m-%02d.%02H"
3223b97a967SRobert Watson# time-stamp-end: "$"
3233b97a967SRobert Watson# End:
324