xref: /freebsd/crypto/heimdal/install-sh (revision 8d4ba808a53020900c275b6f1cf21fc6e9f3bf36)
1b528cefcSMark Murray#!/bin/sh
2b528cefcSMark Murray# install - install a program, script, or datafile
38d4ba808SJacques Vidrine
48d4ba808SJacques Vidrinescriptversion=2004-02-15.20
58d4ba808SJacques Vidrine
61c43270aSJacques Vidrine# This originates from X11R5 (mit/util/scripts/install.sh), which was
71c43270aSJacques Vidrine# later released in X11R6 (xc/config/util/install.sh) with the
81c43270aSJacques Vidrine# following copyright and license.
98373020dSJacques Vidrine#
101c43270aSJacques Vidrine# Copyright (C) 1994 X Consortium
111c43270aSJacques Vidrine#
121c43270aSJacques Vidrine# Permission is hereby granted, free of charge, to any person obtaining a copy
131c43270aSJacques Vidrine# of this software and associated documentation files (the "Software"), to
141c43270aSJacques Vidrine# deal in the Software without restriction, including without limitation the
151c43270aSJacques Vidrine# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
161c43270aSJacques Vidrine# sell copies of the Software, and to permit persons to whom the Software is
171c43270aSJacques Vidrine# furnished to do so, subject to the following conditions:
181c43270aSJacques Vidrine#
191c43270aSJacques Vidrine# The above copyright notice and this permission notice shall be included in
201c43270aSJacques Vidrine# all copies or substantial portions of the Software.
211c43270aSJacques Vidrine#
221c43270aSJacques Vidrine# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
231c43270aSJacques Vidrine# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
241c43270aSJacques Vidrine# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
251c43270aSJacques Vidrine# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
261c43270aSJacques Vidrine# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
271c43270aSJacques Vidrine# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
281c43270aSJacques Vidrine#
291c43270aSJacques Vidrine# Except as contained in this notice, the name of the X Consortium shall not
301c43270aSJacques Vidrine# be used in advertising or otherwise to promote the sale, use or other deal-
311c43270aSJacques Vidrine# ings in this Software without prior written authorization from the X Consor-
321c43270aSJacques Vidrine# tium.
331c43270aSJacques Vidrine#
341c43270aSJacques Vidrine#
351c43270aSJacques Vidrine# FSF changes to this file are in the public domain.
36b528cefcSMark Murray#
37b528cefcSMark Murray# Calling this script install-sh is preferred over install.sh, to prevent
38b528cefcSMark Murray# `make' implicit rules from creating a file called install from it
39b528cefcSMark Murray# when there is no Makefile.
40b528cefcSMark Murray#
41b528cefcSMark Murray# This script is compatible with the BSD install script, but was written
428373020dSJacques Vidrine# from scratch.  It can only install one file at a time, a restriction
438373020dSJacques Vidrine# shared with many OS's install programs.
44b528cefcSMark Murray
45b528cefcSMark Murray# set DOITPROG to echo to test this script
46b528cefcSMark Murray
47b528cefcSMark Murray# Don't use :- since 4.3BSD and earlier shells don't like it.
48b528cefcSMark Murraydoit="${DOITPROG-}"
49b528cefcSMark Murray
50b528cefcSMark Murray# put in absolute paths if you don't have them in your path; or use env. vars.
51b528cefcSMark Murray
52b528cefcSMark Murraymvprog="${MVPROG-mv}"
53b528cefcSMark Murraycpprog="${CPPROG-cp}"
54b528cefcSMark Murraychmodprog="${CHMODPROG-chmod}"
55b528cefcSMark Murraychownprog="${CHOWNPROG-chown}"
56b528cefcSMark Murraychgrpprog="${CHGRPPROG-chgrp}"
57b528cefcSMark Murraystripprog="${STRIPPROG-strip}"
58b528cefcSMark Murrayrmprog="${RMPROG-rm}"
59b528cefcSMark Murraymkdirprog="${MKDIRPROG-mkdir}"
60b528cefcSMark Murray
618d4ba808SJacques Vidrinetransformbasename=
628d4ba808SJacques Vidrinetransform_arg=
63b528cefcSMark Murrayinstcmd="$mvprog"
64b528cefcSMark Murraychmodcmd="$chmodprog 0755"
658d4ba808SJacques Vidrinechowncmd=
668d4ba808SJacques Vidrinechgrpcmd=
678d4ba808SJacques Vidrinestripcmd=
68b528cefcSMark Murrayrmcmd="$rmprog -f"
69b528cefcSMark Murraymvcmd="$mvprog"
708d4ba808SJacques Vidrinesrc=
718d4ba808SJacques Vidrinedst=
728d4ba808SJacques Vidrinedir_arg=
73b528cefcSMark Murray
748d4ba808SJacques Vidrineusage="Usage: $0 [OPTION]... SRCFILE DSTFILE
758d4ba808SJacques Vidrine   or: $0 [OPTION]... SRCFILES... DIRECTORY
768d4ba808SJacques Vidrine   or: $0 -d DIRECTORIES...
778d4ba808SJacques Vidrine
788d4ba808SJacques VidrineIn the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
798d4ba808SJacques VidrineIn the second, create the directory path DIR.
808d4ba808SJacques Vidrine
818d4ba808SJacques VidrineOptions:
828d4ba808SJacques Vidrine-b=TRANSFORMBASENAME
838d4ba808SJacques Vidrine-c         copy source (using $cpprog) instead of moving (using $mvprog).
848d4ba808SJacques Vidrine-d         create directories instead of installing files.
858d4ba808SJacques Vidrine-g GROUP   $chgrp installed files to GROUP.
868d4ba808SJacques Vidrine-m MODE    $chmod installed files to MODE.
878d4ba808SJacques Vidrine-o USER    $chown installed files to USER.
888d4ba808SJacques Vidrine-s         strip installed files (using $stripprog).
898d4ba808SJacques Vidrine-t=TRANSFORM
908d4ba808SJacques Vidrine--help     display this help and exit.
918d4ba808SJacques Vidrine--version  display version info and exit.
928d4ba808SJacques Vidrine
938d4ba808SJacques VidrineEnvironment variables override the default commands:
948d4ba808SJacques Vidrine  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
958d4ba808SJacques Vidrine"
968d4ba808SJacques Vidrine
978d4ba808SJacques Vidrinewhile test -n "$1"; do
98b528cefcSMark Murray  case $1 in
998d4ba808SJacques Vidrine    -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
1008d4ba808SJacques Vidrine        shift
1018d4ba808SJacques Vidrine        continue;;
1028d4ba808SJacques Vidrine
1031c43270aSJacques Vidrine    -c) instcmd=$cpprog
104b528cefcSMark Murray        shift
105b528cefcSMark Murray        continue;;
106b528cefcSMark Murray
107b528cefcSMark Murray    -d) dir_arg=true
108b528cefcSMark Murray        shift
109b528cefcSMark Murray        continue;;
110b528cefcSMark Murray
1118d4ba808SJacques Vidrine    -g) chgrpcmd="$chgrpprog $2"
1128d4ba808SJacques Vidrine        shift
1138d4ba808SJacques Vidrine        shift
1148d4ba808SJacques Vidrine        continue;;
1158d4ba808SJacques Vidrine
1168d4ba808SJacques Vidrine    --help) echo "$usage"; exit 0;;
1178d4ba808SJacques Vidrine
118b528cefcSMark Murray    -m) chmodcmd="$chmodprog $2"
119b528cefcSMark Murray        shift
120b528cefcSMark Murray        shift
121b528cefcSMark Murray        continue;;
122b528cefcSMark Murray
123b528cefcSMark Murray    -o) chowncmd="$chownprog $2"
124b528cefcSMark Murray        shift
125b528cefcSMark Murray        shift
126b528cefcSMark Murray        continue;;
127b528cefcSMark Murray
1281c43270aSJacques Vidrine    -s) stripcmd=$stripprog
129b528cefcSMark Murray        shift
130b528cefcSMark Murray        continue;;
131b528cefcSMark Murray
132b528cefcSMark Murray    -t=*) transformarg=`echo $1 | sed 's/-t=//'`
133b528cefcSMark Murray        shift
134b528cefcSMark Murray        continue;;
135b528cefcSMark Murray
1368d4ba808SJacques Vidrine    --version) echo "$0 $scriptversion"; exit 0;;
137b528cefcSMark Murray
1388d4ba808SJacques Vidrine    *)  # When -d is used, all remaining arguments are directories to create.
1398d4ba808SJacques Vidrine	test -n "$dir_arg" && break
1408d4ba808SJacques Vidrine        # Otherwise, the last argument is the destination.  Remove it from $@.
1418d4ba808SJacques Vidrine	for arg
1428d4ba808SJacques Vidrine	do
1438d4ba808SJacques Vidrine          if test -n "$dstarg"; then
1448d4ba808SJacques Vidrine	    # $@ is not empty: it contains at least $arg.
1458d4ba808SJacques Vidrine	    set fnord "$@" "$dstarg"
1468d4ba808SJacques Vidrine	    shift # fnord
147b528cefcSMark Murray	  fi
1488d4ba808SJacques Vidrine	  shift # arg
1498d4ba808SJacques Vidrine	  dstarg=$arg
1508d4ba808SJacques Vidrine	done
1518d4ba808SJacques Vidrine	break;;
152b528cefcSMark Murray  esac
153b528cefcSMark Murraydone
154b528cefcSMark Murray
1558d4ba808SJacques Vidrineif test -z "$1"; then
1568d4ba808SJacques Vidrine  if test -z "$dir_arg"; then
1578d4ba808SJacques Vidrine    echo "$0: no input file specified." >&2
158b528cefcSMark Murray    exit 1
1598d4ba808SJacques Vidrine  fi
1608d4ba808SJacques Vidrine  # It's OK to call `install-sh -d' without argument.
1618d4ba808SJacques Vidrine  # This can happen when creating conditional directories.
1628d4ba808SJacques Vidrine  exit 0
163b528cefcSMark Murrayfi
164b528cefcSMark Murray
1658d4ba808SJacques Vidrinefor src
1668d4ba808SJacques Vidrinedo
1678d4ba808SJacques Vidrine  # Protect names starting with `-'.
1688d4ba808SJacques Vidrine  case $src in
1698d4ba808SJacques Vidrine    -*) src=./$src ;;
1708d4ba808SJacques Vidrine  esac
171b528cefcSMark Murray
1728d4ba808SJacques Vidrine  if test -n "$dir_arg"; then
1738d4ba808SJacques Vidrine    dst=$src
1748d4ba808SJacques Vidrine    src=
1758d4ba808SJacques Vidrine
1768d4ba808SJacques Vidrine    if test -d "$dst"; then
177b528cefcSMark Murray      instcmd=:
1788d4ba808SJacques Vidrine      chmodcmd=
179b528cefcSMark Murray    else
1808373020dSJacques Vidrine      instcmd=$mkdirprog
181b528cefcSMark Murray    fi
182b528cefcSMark Murray  else
183b528cefcSMark Murray    # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
184b528cefcSMark Murray    # might cause directories to be created, which would be especially bad
185b528cefcSMark Murray    # if $src (and thus $dsttmp) contains '*'.
1868d4ba808SJacques Vidrine    if test ! -f "$src" && test ! -d "$src"; then
1878d4ba808SJacques Vidrine      echo "$0: $src does not exist." >&2
188b528cefcSMark Murray      exit 1
189b528cefcSMark Murray    fi
190b528cefcSMark Murray
1918d4ba808SJacques Vidrine    if test -z "$dstarg"; then
1928d4ba808SJacques Vidrine      echo "$0: no destination specified." >&2
193b528cefcSMark Murray      exit 1
194b528cefcSMark Murray    fi
195b528cefcSMark Murray
1968d4ba808SJacques Vidrine    dst=$dstarg
1978d4ba808SJacques Vidrine    # Protect names starting with `-'.
1988d4ba808SJacques Vidrine    case $dst in
1998d4ba808SJacques Vidrine      -*) dst=./$dst ;;
2008d4ba808SJacques Vidrine    esac
201b528cefcSMark Murray
2028d4ba808SJacques Vidrine    # If destination is a directory, append the input filename; won't work
2038d4ba808SJacques Vidrine    # if double slashes aren't ignored.
2048d4ba808SJacques Vidrine    if test -d "$dst"; then
2051c43270aSJacques Vidrine      dst=$dst/`basename "$src"`
206b528cefcSMark Murray    fi
207b528cefcSMark Murray  fi
208b528cefcSMark Murray
2098d4ba808SJacques Vidrine  # This sed command emulates the dirname command.
2101c43270aSJacques Vidrine  dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
211b528cefcSMark Murray
212b528cefcSMark Murray  # Make sure that the destination directory exists.
213b528cefcSMark Murray
214b528cefcSMark Murray  # Skip lots of stat calls in the usual case.
2158d4ba808SJacques Vidrine  if test ! -d "$dstdir"; then
216b528cefcSMark Murray    defaultIFS='
217b528cefcSMark Murray	 '
2181c43270aSJacques Vidrine    IFS="${IFS-$defaultIFS}"
219b528cefcSMark Murray
2201c43270aSJacques Vidrine    oIFS=$IFS
221b528cefcSMark Murray    # Some sh's can't handle IFS=/ for some reason.
222b528cefcSMark Murray    IFS='%'
2231c43270aSJacques Vidrine    set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
2241c43270aSJacques Vidrine    IFS=$oIFS
225b528cefcSMark Murray
2268d4ba808SJacques Vidrine    pathcomp=
227b528cefcSMark Murray
2288d4ba808SJacques Vidrine    while test $# -ne 0 ; do
2291c43270aSJacques Vidrine      pathcomp=$pathcomp$1
230b528cefcSMark Murray      shift
2318d4ba808SJacques Vidrine      if test ! -d "$pathcomp"; then
2328d4ba808SJacques Vidrine        $mkdirprog "$pathcomp" || lasterr=$?
2338d4ba808SJacques Vidrine	# mkdir can fail with a `File exist' error in case several
2348d4ba808SJacques Vidrine	# install-sh are creating the directory concurrently.  This
2358d4ba808SJacques Vidrine	# is OK.
2368d4ba808SJacques Vidrine	test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; }
237b528cefcSMark Murray      fi
2381c43270aSJacques Vidrine      pathcomp=$pathcomp/
239b528cefcSMark Murray    done
240b528cefcSMark Murray  fi
241b528cefcSMark Murray
2428d4ba808SJacques Vidrine  if test -n "$dir_arg"; then
2438d4ba808SJacques Vidrine    $doit $instcmd "$dst" \
2448d4ba808SJacques Vidrine      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
2458d4ba808SJacques Vidrine      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
2468d4ba808SJacques Vidrine      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
2478d4ba808SJacques Vidrine      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
248b528cefcSMark Murray
249b528cefcSMark Murray  else
250b528cefcSMark Murray    # If we're going to rename the final executable, determine the name now.
2518d4ba808SJacques Vidrine    if test -z "$transformarg"; then
2521c43270aSJacques Vidrine      dstfile=`basename "$dst"`
253b528cefcSMark Murray    else
2548d4ba808SJacques Vidrine      dstfile=`basename "$dst" $transformbasename \
2558d4ba808SJacques Vidrine               | sed $transformarg`$transformbasename
256b528cefcSMark Murray    fi
257b528cefcSMark Murray
2588d4ba808SJacques Vidrine    # don't allow the sed command to completely eliminate the filename.
2598d4ba808SJacques Vidrine    test -z "$dstfile" && dstfile=`basename "$dst"`
260b528cefcSMark Murray
2611c43270aSJacques Vidrine    # Make a couple of temp file names in the proper directory.
2621c43270aSJacques Vidrine    dsttmp=$dstdir/_inst.$$_
2631c43270aSJacques Vidrine    rmtmp=$dstdir/_rm.$$_
2641c43270aSJacques Vidrine
2658d4ba808SJacques Vidrine    # Trap to clean up those temp files at exit.
2661c43270aSJacques Vidrine    trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
2671c43270aSJacques Vidrine    trap '(exit $?); exit' 1 2 13 15
268b528cefcSMark Murray
269b528cefcSMark Murray    # Move or copy the file name to the temp name
2701c43270aSJacques Vidrine    $doit $instcmd "$src" "$dsttmp" &&
271b528cefcSMark Murray
2728d4ba808SJacques Vidrine    # and set any options; do chmod last to preserve setuid bits.
2738d4ba808SJacques Vidrine    #
274b528cefcSMark Murray    # If any of these fail, we abort the whole thing.  If we want to
275b528cefcSMark Murray    # ignore errors from any of these, just make sure not to ignore
276b528cefcSMark Murray    # errors from the above "$doit $instcmd $src $dsttmp" command.
2778d4ba808SJacques Vidrine    #
2788d4ba808SJacques Vidrine    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
2798d4ba808SJacques Vidrine      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
2808d4ba808SJacques Vidrine      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
2818d4ba808SJacques Vidrine      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
282b528cefcSMark Murray
2838d4ba808SJacques Vidrine    # Now remove or move aside any old file at destination location.  We
2848d4ba808SJacques Vidrine    # try this two ways since rm can't unlink itself on some systems and
2858d4ba808SJacques Vidrine    # the destination file might be busy for other reasons.  In this case,
2868d4ba808SJacques Vidrine    # the final cleanup might fail but the new file should still install
2878d4ba808SJacques Vidrine    # successfully.
2881c43270aSJacques Vidrine    {
2898d4ba808SJacques Vidrine      if test -f "$dstdir/$dstfile"; then
2908d4ba808SJacques Vidrine        $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
2918d4ba808SJacques Vidrine        || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
2928d4ba808SJacques Vidrine        || {
2931c43270aSJacques Vidrine	  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
2941c43270aSJacques Vidrine	  (exit 1); exit
2951c43270aSJacques Vidrine        }
2961c43270aSJacques Vidrine      else
2971c43270aSJacques Vidrine        :
2981c43270aSJacques Vidrine      fi
2991c43270aSJacques Vidrine    } &&
300b528cefcSMark Murray
301b528cefcSMark Murray    # Now rename the file to the real destination.
3021c43270aSJacques Vidrine    $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
3038d4ba808SJacques Vidrine  fi || { (exit 1); exit; }
3048d4ba808SJacques Vidrinedone
305b528cefcSMark Murray
3061c43270aSJacques Vidrine# The final little trick to "correctly" pass the exit status to the exit trap.
3071c43270aSJacques Vidrine{
3081c43270aSJacques Vidrine  (exit 0); exit
3091c43270aSJacques Vidrine}
3108d4ba808SJacques Vidrine
3118d4ba808SJacques Vidrine# Local variables:
3128d4ba808SJacques Vidrine# eval: (add-hook 'write-file-hooks 'time-stamp)
3138d4ba808SJacques Vidrine# time-stamp-start: "scriptversion="
3148d4ba808SJacques Vidrine# time-stamp-format: "%:y-%02m-%02d.%02H"
3158d4ba808SJacques Vidrine# time-stamp-end: "$"
3168d4ba808SJacques Vidrine# End:
317