Home | History | Annotate | Download | only in build-scripts
      1 #!/bin/sh
      2 # install - install a program, script, or datafile
      3 
      4 scriptversion=2005-02-02.21
      5 
      6 # This originates from X11R5 (mit/util/scripts/install.sh), which was
      7 # later released in X11R6 (xc/config/util/install.sh) with the
      8 # following copyright and license.
      9 #
     10 # Copyright (C) 1994 X Consortium
     11 #
     12 # Permission is hereby granted, free of charge, to any person obtaining a copy
     13 # of this software and associated documentation files (the "Software"), to
     14 # deal in the Software without restriction, including without limitation the
     15 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     16 # sell copies of the Software, and to permit persons to whom the Software is
     17 # furnished to do so, subject to the following conditions:
     18 #
     19 # The above copyright notice and this permission notice shall be included in
     20 # all copies or substantial portions of the Software.
     21 #
     22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     23 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     24 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     25 # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     26 # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
     27 # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     28 #
     29 # Except as contained in this notice, the name of the X Consortium shall not
     30 # be used in advertising or otherwise to promote the sale, use or other deal-
     31 # ings in this Software without prior written authorization from the X Consor-
     32 # tium.
     33 #
     34 #
     35 # FSF changes to this file are in the public domain.
     36 #
     37 # Calling this script install-sh is preferred over install.sh, to prevent
     38 # `make' implicit rules from creating a file called install from it
     39 # when there is no Makefile.
     40 #
     41 # This script is compatible with the BSD install script, but was written
     42 # from scratch.  It can only install one file at a time, a restriction
     43 # shared with many OS's install programs.
     44 
     45 # set DOITPROG to echo to test this script
     46 
     47 # Don't use :- since 4.3BSD and earlier shells don't like it.
     48 doit="${DOITPROG-}"
     49 
     50 # put in absolute paths if you don't have them in your path; or use env. vars.
     51 
     52 mvprog="${MVPROG-mv}"
     53 cpprog="${CPPROG-cp}"
     54 chmodprog="${CHMODPROG-chmod}"
     55 chownprog="${CHOWNPROG-chown}"
     56 chgrpprog="${CHGRPPROG-chgrp}"
     57 stripprog="${STRIPPROG-strip}"
     58 rmprog="${RMPROG-rm}"
     59 mkdirprog="${MKDIRPROG-mkdir}"
     60 
     61 chmodcmd="$chmodprog 0755"
     62 chowncmd=
     63 chgrpcmd=
     64 stripcmd=
     65 rmcmd="$rmprog -f"
     66 mvcmd="$mvprog"
     67 src=
     68 dst=
     69 dir_arg=
     70 dstarg=
     71 no_target_directory=
     72 
     73 usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
     74    or: $0 [OPTION]... SRCFILES... DIRECTORY
     75    or: $0 [OPTION]... -t DIRECTORY SRCFILES...
     76    or: $0 [OPTION]... -d DIRECTORIES...
     77 
     78 In the 1st form, copy SRCFILE to DSTFILE.
     79 In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
     80 In the 4th, create DIRECTORIES.
     81 
     82 Options:
     83 -c         (ignored)
     84 -d         create directories instead of installing files.
     85 -g GROUP   $chgrpprog installed files to GROUP.
     86 -m MODE    $chmodprog installed files to MODE.
     87 -o USER    $chownprog installed files to USER.
     88 -s         $stripprog installed files.
     89 -t DIRECTORY  install into DIRECTORY.
     90 -T         report an error if DSTFILE is a directory.
     91 --help     display this help and exit.
     92 --version  display version info and exit.
     93 
     94 Environment variables override the default commands:
     95   CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
     96 "
     97 
     98 while test -n "$1"; do
     99   case $1 in
    100     -c) shift
    101         continue;;
    102 
    103     -d) dir_arg=true
    104         shift
    105         continue;;
    106 
    107     -g) chgrpcmd="$chgrpprog $2"
    108         shift
    109         shift
    110         continue;;
    111 
    112     --help) echo "$usage"; exit $?;;
    113 
    114     -m) chmodcmd="$chmodprog $2"
    115         shift
    116         shift
    117         continue;;
    118 
    119     -o) chowncmd="$chownprog $2"
    120         shift
    121         shift
    122         continue;;
    123 
    124     -s) stripcmd=$stripprog
    125         shift
    126         continue;;
    127 
    128     -t) dstarg=$2
    129 	shift
    130 	shift
    131 	continue;;
    132 
    133     -T) no_target_directory=true
    134 	shift
    135 	continue;;
    136 
    137     --version) echo "$0 $scriptversion"; exit $?;;
    138 
    139     *)  # When -d is used, all remaining arguments are directories to create.
    140 	# When -t is used, the destination is already specified.
    141 	test -n "$dir_arg$dstarg" && break
    142         # Otherwise, the last argument is the destination.  Remove it from $@.
    143 	for arg
    144 	do
    145           if test -n "$dstarg"; then
    146 	    # $@ is not empty: it contains at least $arg.
    147 	    set fnord "$@" "$dstarg"
    148 	    shift # fnord
    149 	  fi
    150 	  shift # arg
    151 	  dstarg=$arg
    152 	done
    153 	break;;
    154   esac
    155 done
    156 
    157 if test -z "$1"; then
    158   if test -z "$dir_arg"; then
    159     echo "$0: no input file specified." >&2
    160     exit 1
    161   fi
    162   # It's OK to call `install-sh -d' without argument.
    163   # This can happen when creating conditional directories.
    164   exit 0
    165 fi
    166 
    167 for src
    168 do
    169   # Protect names starting with `-'.
    170   case $src in
    171     -*) src=./$src ;;
    172   esac
    173 
    174   if test -n "$dir_arg"; then
    175     dst=$src
    176     src=
    177 
    178     if test -d "$dst"; then
    179       mkdircmd=:
    180       chmodcmd=
    181     else
    182       mkdircmd=$mkdirprog
    183     fi
    184   else
    185     # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    186     # might cause directories to be created, which would be especially bad
    187     # if $src (and thus $dsttmp) contains '*'.
    188     if test ! -f "$src" && test ! -d "$src"; then
    189       echo "$0: $src does not exist." >&2
    190       exit 1
    191     fi
    192 
    193     if test -z "$dstarg"; then
    194       echo "$0: no destination specified." >&2
    195       exit 1
    196     fi
    197 
    198     dst=$dstarg
    199     # Protect names starting with `-'.
    200     case $dst in
    201       -*) dst=./$dst ;;
    202     esac
    203 
    204     # If destination is a directory, append the input filename; won't work
    205     # if double slashes aren't ignored.
    206     if test -d "$dst"; then
    207       if test -n "$no_target_directory"; then
    208 	echo "$0: $dstarg: Is a directory" >&2
    209 	exit 1
    210       fi
    211       dst=$dst/`basename "$src"`
    212     fi
    213   fi
    214 
    215   # This sed command emulates the dirname command.
    216   dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
    217 
    218   # Make sure that the destination directory exists.
    219 
    220   # Skip lots of stat calls in the usual case.
    221   if test ! -d "$dstdir"; then
    222     defaultIFS='
    223 	 '
    224     IFS="${IFS-$defaultIFS}"
    225 
    226     oIFS=$IFS
    227     # Some sh's can't handle IFS=/ for some reason.
    228     IFS='%'
    229     set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
    230     shift
    231     IFS=$oIFS
    232 
    233     pathcomp=
    234 
    235     while test $# -ne 0 ; do
    236       pathcomp=$pathcomp$1
    237       shift
    238       if test ! -d "$pathcomp"; then
    239         $mkdirprog "$pathcomp"
    240 	# mkdir can fail with a `File exist' error in case several
    241 	# install-sh are creating the directory concurrently.  This
    242 	# is OK.
    243 	test -d "$pathcomp" || exit
    244       fi
    245       pathcomp=$pathcomp/
    246     done
    247   fi
    248 
    249   if test -n "$dir_arg"; then
    250     $doit $mkdircmd "$dst" \
    251       && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
    252       && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
    253       && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
    254       && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
    255 
    256   else
    257     dstfile=`basename "$dst"`
    258 
    259     # Make a couple of temp file names in the proper directory.
    260     dsttmp=$dstdir/_inst.$$_
    261     rmtmp=$dstdir/_rm.$$_
    262 
    263     # Trap to clean up those temp files at exit.
    264     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
    265     trap '(exit $?); exit' 1 2 13 15
    266 
    267     # Copy the file name to the temp name.
    268     $doit $cpprog "$src" "$dsttmp" &&
    269 
    270     # and set any options; do chmod last to preserve setuid bits.
    271     #
    272     # If any of these fail, we abort the whole thing.  If we want to
    273     # ignore errors from any of these, just make sure not to ignore
    274     # errors from the above "$doit $cpprog $src $dsttmp" command.
    275     #
    276     { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
    277       && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
    278       && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
    279       && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
    280 
    281     # Now rename the file to the real destination.
    282     { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
    283       || {
    284 	   # The rename failed, perhaps because mv can't rename something else
    285 	   # to itself, or perhaps because mv is so ancient that it does not
    286 	   # support -f.
    287 
    288 	   # Now remove or move aside any old file at destination location.
    289 	   # We try this two ways since rm can't unlink itself on some
    290 	   # systems and the destination file might be busy for other
    291 	   # reasons.  In this case, the final cleanup might fail but the new
    292 	   # file should still install successfully.
    293 	   {
    294 	     if test -f "$dstdir/$dstfile"; then
    295 	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
    296 	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
    297 	       || {
    298 		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
    299 		 (exit 1); exit 1
    300 	       }
    301 	     else
    302 	       :
    303 	     fi
    304 	   } &&
    305 
    306 	   # Now rename the file to the real destination.
    307 	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
    308 	 }
    309     }
    310   fi || { (exit 1); exit 1; }
    311 done
    312 
    313 # The final little trick to "correctly" pass the exit status to the exit trap.
    314 {
    315   (exit 0); exit 0
    316 }
    317 
    318 # Local variables:
    319 # eval: (add-hook 'write-file-hooks 'time-stamp)
    320 # time-stamp-start: "scriptversion="
    321 # time-stamp-format: "%:y-%02m-%02d.%02H"
    322 # time-stamp-end: "$"
    323 # End:
    324