File indexing completed on 2024-12-22 04:04:18
0001 #!/bin/sh 0002 # install - install a program, script, or datafile 0003 0004 scriptversion=2018-03-11.20; # UTC 0005 0006 # This originates from X11R5 (mit/util/scripts/install.sh), which was 0007 # later released in X11R6 (xc/config/util/install.sh) with the 0008 # following copyright and license. 0009 # 0010 # Copyright (C) 1994 X Consortium 0011 # 0012 # Permission is hereby granted, free of charge, to any person obtaining a copy 0013 # of this software and associated documentation files (the "Software"), to 0014 # deal in the Software without restriction, including without limitation the 0015 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 0016 # sell copies of the Software, and to permit persons to whom the Software is 0017 # furnished to do so, subject to the following conditions: 0018 # 0019 # The above copyright notice and this permission notice shall be included in 0020 # all copies or substantial portions of the Software. 0021 # 0022 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0023 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0024 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0025 # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 0026 # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 0027 # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0028 # 0029 # Except as contained in this notice, the name of the X Consortium shall not 0030 # be used in advertising or otherwise to promote the sale, use or other deal- 0031 # ings in this Software without prior written authorization from the X Consor- 0032 # tium. 0033 # 0034 # 0035 # FSF changes to this file are in the public domain. 0036 # 0037 # Calling this script install-sh is preferred over install.sh, to prevent 0038 # 'make' implicit rules from creating a file called install from it 0039 # when there is no Makefile. 0040 # 0041 # This script is compatible with the BSD install script, but was written 0042 # from scratch. 0043 0044 tab=' ' 0045 nl=' 0046 ' 0047 IFS=" $tab$nl" 0048 0049 # Set DOITPROG to "echo" to test this script. 0050 0051 doit=${DOITPROG-} 0052 doit_exec=${doit:-exec} 0053 0054 # Put in absolute file names if you don't have them in your path; 0055 # or use environment vars. 0056 0057 chgrpprog=${CHGRPPROG-chgrp} 0058 chmodprog=${CHMODPROG-chmod} 0059 chownprog=${CHOWNPROG-chown} 0060 cmpprog=${CMPPROG-cmp} 0061 cpprog=${CPPROG-cp} 0062 mkdirprog=${MKDIRPROG-mkdir} 0063 mvprog=${MVPROG-mv} 0064 rmprog=${RMPROG-rm} 0065 stripprog=${STRIPPROG-strip} 0066 0067 posix_mkdir= 0068 0069 # Desired mode of installed file. 0070 mode=0755 0071 0072 chgrpcmd= 0073 chmodcmd=$chmodprog 0074 chowncmd= 0075 mvcmd=$mvprog 0076 rmcmd="$rmprog -f" 0077 stripcmd= 0078 0079 src= 0080 dst= 0081 dir_arg= 0082 dst_arg= 0083 0084 copy_on_change=false 0085 is_target_a_directory=possibly 0086 0087 usage="\ 0088 Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 0089 or: $0 [OPTION]... SRCFILES... DIRECTORY 0090 or: $0 [OPTION]... -t DIRECTORY SRCFILES... 0091 or: $0 [OPTION]... -d DIRECTORIES... 0092 0093 In the 1st form, copy SRCFILE to DSTFILE. 0094 In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 0095 In the 4th, create DIRECTORIES. 0096 0097 Options: 0098 --help display this help and exit. 0099 --version display version info and exit. 0100 0101 -c (ignored) 0102 -C install only if different (preserve the last data modification time) 0103 -d create directories instead of installing files. 0104 -g GROUP $chgrpprog installed files to GROUP. 0105 -m MODE $chmodprog installed files to MODE. 0106 -o USER $chownprog installed files to USER. 0107 -s $stripprog installed files. 0108 -t DIRECTORY install into DIRECTORY. 0109 -T report an error if DSTFILE is a directory. 0110 0111 Environment variables override the default commands: 0112 CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 0113 RMPROG STRIPPROG 0114 " 0115 0116 while test $# -ne 0; do 0117 case $1 in 0118 -c) ;; 0119 0120 -C) copy_on_change=true;; 0121 0122 -d) dir_arg=true;; 0123 0124 -g) chgrpcmd="$chgrpprog $2" 0125 shift;; 0126 0127 --help) echo "$usage"; exit $?;; 0128 0129 -m) mode=$2 0130 case $mode in 0131 *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 0132 echo "$0: invalid mode: $mode" >&2 0133 exit 1;; 0134 esac 0135 shift;; 0136 0137 -o) chowncmd="$chownprog $2" 0138 shift;; 0139 0140 -s) stripcmd=$stripprog;; 0141 0142 -t) 0143 is_target_a_directory=always 0144 dst_arg=$2 0145 # Protect names problematic for 'test' and other utilities. 0146 case $dst_arg in 0147 -* | [=\(\)!]) dst_arg=./$dst_arg;; 0148 esac 0149 shift;; 0150 0151 -T) is_target_a_directory=never;; 0152 0153 --version) echo "$0 $scriptversion"; exit $?;; 0154 0155 --) shift 0156 break;; 0157 0158 -*) echo "$0: invalid option: $1" >&2 0159 exit 1;; 0160 0161 *) break;; 0162 esac 0163 shift 0164 done 0165 0166 # We allow the use of options -d and -T together, by making -d 0167 # take the precedence; this is for compatibility with GNU install. 0168 0169 if test -n "$dir_arg"; then 0170 if test -n "$dst_arg"; then 0171 echo "$0: target directory not allowed when installing a directory." >&2 0172 exit 1 0173 fi 0174 fi 0175 0176 if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 0177 # When -d is used, all remaining arguments are directories to create. 0178 # When -t is used, the destination is already specified. 0179 # Otherwise, the last argument is the destination. Remove it from $@. 0180 for arg 0181 do 0182 if test -n "$dst_arg"; then 0183 # $@ is not empty: it contains at least $arg. 0184 set fnord "$@" "$dst_arg" 0185 shift # fnord 0186 fi 0187 shift # arg 0188 dst_arg=$arg 0189 # Protect names problematic for 'test' and other utilities. 0190 case $dst_arg in 0191 -* | [=\(\)!]) dst_arg=./$dst_arg;; 0192 esac 0193 done 0194 fi 0195 0196 if test $# -eq 0; then 0197 if test -z "$dir_arg"; then 0198 echo "$0: no input file specified." >&2 0199 exit 1 0200 fi 0201 # It's OK to call 'install-sh -d' without argument. 0202 # This can happen when creating conditional directories. 0203 exit 0 0204 fi 0205 0206 if test -z "$dir_arg"; then 0207 if test $# -gt 1 || test "$is_target_a_directory" = always; then 0208 if test ! -d "$dst_arg"; then 0209 echo "$0: $dst_arg: Is not a directory." >&2 0210 exit 1 0211 fi 0212 fi 0213 fi 0214 0215 if test -z "$dir_arg"; then 0216 do_exit='(exit $ret); exit $ret' 0217 trap "ret=129; $do_exit" 1 0218 trap "ret=130; $do_exit" 2 0219 trap "ret=141; $do_exit" 13 0220 trap "ret=143; $do_exit" 15 0221 0222 # Set umask so as not to create temps with too-generous modes. 0223 # However, 'strip' requires both read and write access to temps. 0224 case $mode in 0225 # Optimize common cases. 0226 *644) cp_umask=133;; 0227 *755) cp_umask=22;; 0228 0229 *[0-7]) 0230 if test -z "$stripcmd"; then 0231 u_plus_rw= 0232 else 0233 u_plus_rw='% 200' 0234 fi 0235 cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 0236 *) 0237 if test -z "$stripcmd"; then 0238 u_plus_rw= 0239 else 0240 u_plus_rw=,u+rw 0241 fi 0242 cp_umask=$mode$u_plus_rw;; 0243 esac 0244 fi 0245 0246 for src 0247 do 0248 # Protect names problematic for 'test' and other utilities. 0249 case $src in 0250 -* | [=\(\)!]) src=./$src;; 0251 esac 0252 0253 if test -n "$dir_arg"; then 0254 dst=$src 0255 dstdir=$dst 0256 test -d "$dstdir" 0257 dstdir_status=$? 0258 else 0259 0260 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 0261 # might cause directories to be created, which would be especially bad 0262 # if $src (and thus $dsttmp) contains '*'. 0263 if test ! -f "$src" && test ! -d "$src"; then 0264 echo "$0: $src does not exist." >&2 0265 exit 1 0266 fi 0267 0268 if test -z "$dst_arg"; then 0269 echo "$0: no destination specified." >&2 0270 exit 1 0271 fi 0272 dst=$dst_arg 0273 0274 # If destination is a directory, append the input filename. 0275 if test -d "$dst"; then 0276 if test "$is_target_a_directory" = never; then 0277 echo "$0: $dst_arg: Is a directory" >&2 0278 exit 1 0279 fi 0280 dstdir=$dst 0281 dstbase=`basename "$src"` 0282 case $dst in 0283 */) dst=$dst$dstbase;; 0284 *) dst=$dst/$dstbase;; 0285 esac 0286 dstdir_status=0 0287 else 0288 dstdir=`dirname "$dst"` 0289 test -d "$dstdir" 0290 dstdir_status=$? 0291 fi 0292 fi 0293 0294 case $dstdir in 0295 */) dstdirslash=$dstdir;; 0296 *) dstdirslash=$dstdir/;; 0297 esac 0298 0299 obsolete_mkdir_used=false 0300 0301 if test $dstdir_status != 0; then 0302 case $posix_mkdir in 0303 '') 0304 # Create intermediate dirs using mode 755 as modified by the umask. 0305 # This is like FreeBSD 'install' as of 1997-10-28. 0306 umask=`umask` 0307 case $stripcmd.$umask in 0308 # Optimize common cases. 0309 *[2367][2367]) mkdir_umask=$umask;; 0310 .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 0311 0312 *[0-7]) 0313 mkdir_umask=`expr $umask + 22 \ 0314 - $umask % 100 % 40 + $umask % 20 \ 0315 - $umask % 10 % 4 + $umask % 2 0316 `;; 0317 *) mkdir_umask=$umask,go-w;; 0318 esac 0319 0320 # With -d, create the new directory with the user-specified mode. 0321 # Otherwise, rely on $mkdir_umask. 0322 if test -n "$dir_arg"; then 0323 mkdir_mode=-m$mode 0324 else 0325 mkdir_mode= 0326 fi 0327 0328 posix_mkdir=false 0329 case $umask in 0330 *[123567][0-7][0-7]) 0331 # POSIX mkdir -p sets u+wx bits regardless of umask, which 0332 # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 0333 ;; 0334 *) 0335 # Note that $RANDOM variable is not portable (e.g. dash); Use it 0336 # here however when possible just to lower collision chance. 0337 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 0338 0339 trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 0340 0341 # Because "mkdir -p" follows existing symlinks and we likely work 0342 # directly in world-writeable /tmp, make sure that the '$tmpdir' 0343 # directory is successfully created first before we actually test 0344 # 'mkdir -p' feature. 0345 if (umask $mkdir_umask && 0346 $mkdirprog $mkdir_mode "$tmpdir" && 0347 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 0348 then 0349 if test -z "$dir_arg" || { 0350 # Check for POSIX incompatibilities with -m. 0351 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 0352 # other-writable bit of parent directory when it shouldn't. 0353 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 0354 test_tmpdir="$tmpdir/a" 0355 ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 0356 case $ls_ld_tmpdir in 0357 d????-?r-*) different_mode=700;; 0358 d????-?--*) different_mode=755;; 0359 *) false;; 0360 esac && 0361 $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 0362 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 0363 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 0364 } 0365 } 0366 then posix_mkdir=: 0367 fi 0368 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 0369 else 0370 # Remove any dirs left behind by ancient mkdir implementations. 0371 rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 0372 fi 0373 trap '' 0;; 0374 esac;; 0375 esac 0376 0377 if 0378 $posix_mkdir && ( 0379 umask $mkdir_umask && 0380 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 0381 ) 0382 then : 0383 else 0384 0385 # The umask is ridiculous, or mkdir does not conform to POSIX, 0386 # or it failed possibly due to a race condition. Create the 0387 # directory the slow way, step by step, checking for races as we go. 0388 0389 case $dstdir in 0390 /*) prefix='/';; 0391 [-=\(\)!]*) prefix='./';; 0392 *) prefix='';; 0393 esac 0394 0395 oIFS=$IFS 0396 IFS=/ 0397 set -f 0398 set fnord $dstdir 0399 shift 0400 set +f 0401 IFS=$oIFS 0402 0403 prefixes= 0404 0405 for d 0406 do 0407 test X"$d" = X && continue 0408 0409 prefix=$prefix$d 0410 if test -d "$prefix"; then 0411 prefixes= 0412 else 0413 if $posix_mkdir; then 0414 (umask=$mkdir_umask && 0415 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 0416 # Don't fail if two instances are running concurrently. 0417 test -d "$prefix" || exit 1 0418 else 0419 case $prefix in 0420 *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 0421 *) qprefix=$prefix;; 0422 esac 0423 prefixes="$prefixes '$qprefix'" 0424 fi 0425 fi 0426 prefix=$prefix/ 0427 done 0428 0429 if test -n "$prefixes"; then 0430 # Don't fail if two instances are running concurrently. 0431 (umask $mkdir_umask && 0432 eval "\$doit_exec \$mkdirprog $prefixes") || 0433 test -d "$dstdir" || exit 1 0434 obsolete_mkdir_used=true 0435 fi 0436 fi 0437 fi 0438 0439 if test -n "$dir_arg"; then 0440 { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 0441 { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 0442 { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 0443 test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 0444 else 0445 0446 # Make a couple of temp file names in the proper directory. 0447 dsttmp=${dstdirslash}_inst.$$_ 0448 rmtmp=${dstdirslash}_rm.$$_ 0449 0450 # Trap to clean up those temp files at exit. 0451 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 0452 0453 # Copy the file name to the temp name. 0454 (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 0455 0456 # and set any options; do chmod last to preserve setuid bits. 0457 # 0458 # If any of these fail, we abort the whole thing. If we want to 0459 # ignore errors from any of these, just make sure not to ignore 0460 # errors from the above "$doit $cpprog $src $dsttmp" command. 0461 # 0462 { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 0463 { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 0464 { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 0465 { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 0466 0467 # If -C, don't bother to copy if it wouldn't change the file. 0468 if $copy_on_change && 0469 old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 0470 new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 0471 set -f && 0472 set X $old && old=:$2:$4:$5:$6 && 0473 set X $new && new=:$2:$4:$5:$6 && 0474 set +f && 0475 test "$old" = "$new" && 0476 $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 0477 then 0478 rm -f "$dsttmp" 0479 else 0480 # Rename the file to the real destination. 0481 $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 0482 0483 # The rename failed, perhaps because mv can't rename something else 0484 # to itself, or perhaps because mv is so ancient that it does not 0485 # support -f. 0486 { 0487 # Now remove or move aside any old file at destination location. 0488 # We try this two ways since rm can't unlink itself on some 0489 # systems and the destination file might be busy for other 0490 # reasons. In this case, the final cleanup might fail but the new 0491 # file should still install successfully. 0492 { 0493 test ! -f "$dst" || 0494 $doit $rmcmd -f "$dst" 2>/dev/null || 0495 { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 0496 { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 0497 } || 0498 { echo "$0: cannot unlink or rename $dst" >&2 0499 (exit 1); exit 1 0500 } 0501 } && 0502 0503 # Now rename the file to the real destination. 0504 $doit $mvcmd "$dsttmp" "$dst" 0505 } 0506 fi || exit 1 0507 0508 trap '' 0 0509 fi 0510 done 0511 0512 # Local variables: 0513 # eval: (add-hook 'before-save-hook 'time-stamp) 0514 # time-stamp-start: "scriptversion=" 0515 # time-stamp-format: "%:y-%02m-%02d.%02H" 0516 # time-stamp-time-zone: "UTC0" 0517 # time-stamp-end: "; # UTC" 0518 # End: