1 1.1 mrg #!/bin/sh 2 1.1 mrg # install - install a program, script, or datafile 3 1.1 mrg 4 1.1 mrg scriptversion=2020-11-14.01; # UTC 5 1.1 mrg 6 1.1 mrg # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 1.1 mrg # later released in X11R6 (xc/config/util/install.sh) with the 8 1.1 mrg # following copyright and license. 9 1.1 mrg # 10 1.1 mrg # Copyright (C) 1994 X Consortium 11 1.1 mrg # 12 1.1 mrg # Permission is hereby granted, free of charge, to any person obtaining a copy 13 1.1 mrg # of this software and associated documentation files (the "Software"), to 14 1.1 mrg # deal in the Software without restriction, including without limitation the 15 1.1 mrg # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 1.1 mrg # sell copies of the Software, and to permit persons to whom the Software is 17 1.1 mrg # furnished to do so, subject to the following conditions: 18 1.1 mrg # 19 1.1 mrg # The above copyright notice and this permission notice shall be included in 20 1.1 mrg # all copies or substantial portions of the Software. 21 1.1 mrg # 22 1.1 mrg # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 1.1 mrg # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 1.1 mrg # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 1.1 mrg # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 1.1 mrg # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 1.1 mrg # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 1.1 mrg # 29 1.1 mrg # Except as contained in this notice, the name of the X Consortium shall not 30 1.1 mrg # be used in advertising or otherwise to promote the sale, use or other deal- 31 1.1 mrg # ings in this Software without prior written authorization from the X Consor- 32 1.1 mrg # tium. 33 1.1 mrg # 34 1.1 mrg # 35 1.1 mrg # FSF changes to this file are in the public domain. 36 1.1 mrg # 37 1.1 mrg # Calling this script install-sh is preferred over install.sh, to prevent 38 1.1 mrg # 'make' implicit rules from creating a file called install from it 39 1.1 mrg # when there is no Makefile. 40 1.1 mrg # 41 1.1 mrg # This script is compatible with the BSD install script, but was written 42 1.1 mrg # from scratch. 43 1.1 mrg 44 1.1 mrg tab=' ' 45 1.1 mrg nl=' 46 1.1 mrg ' 47 1.1 mrg IFS=" $tab$nl" 48 1.1 mrg 49 1.1 mrg # Set DOITPROG to "echo" to test this script. 50 1.1 mrg 51 1.1 mrg doit=${DOITPROG-} 52 1.1 mrg doit_exec=${doit:-exec} 53 1.1 mrg 54 1.1 mrg # Put in absolute file names if you don't have them in your path; 55 1.1 mrg # or use environment vars. 56 1.1 mrg 57 1.1 mrg chgrpprog=${CHGRPPROG-chgrp} 58 1.1 mrg chmodprog=${CHMODPROG-chmod} 59 1.1 mrg chownprog=${CHOWNPROG-chown} 60 1.1 mrg cmpprog=${CMPPROG-cmp} 61 1.1 mrg cpprog=${CPPROG-cp} 62 1.1 mrg mkdirprog=${MKDIRPROG-mkdir} 63 1.1 mrg mvprog=${MVPROG-mv} 64 1.1 mrg rmprog=${RMPROG-rm} 65 1.1 mrg stripprog=${STRIPPROG-strip} 66 1.1 mrg 67 1.1 mrg posix_mkdir= 68 1.1 mrg 69 1.1 mrg # Desired mode of installed file. 70 1.1 mrg mode=0755 71 1.1 mrg 72 1.1 mrg # Create dirs (including intermediate dirs) using mode 755. 73 1.1 mrg # This is like GNU 'install' as of coreutils 8.32 (2020). 74 1.1 mrg mkdir_umask=22 75 1.1 mrg 76 1.1 mrg backupsuffix= 77 1.1 mrg chgrpcmd= 78 1.1 mrg chmodcmd=$chmodprog 79 1.1 mrg chowncmd= 80 1.1 mrg mvcmd=$mvprog 81 1.1 mrg rmcmd="$rmprog -f" 82 1.1 mrg stripcmd= 83 1.1 mrg 84 1.1 mrg src= 85 1.1 mrg dst= 86 1.1 mrg dir_arg= 87 1.1 mrg dst_arg= 88 1.1 mrg 89 1.1 mrg copy_on_change=false 90 1.1 mrg is_target_a_directory=possibly 91 1.1 mrg 92 1.1 mrg usage="\ 93 1.1 mrg Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94 1.1 mrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95 1.1 mrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96 1.1 mrg or: $0 [OPTION]... -d DIRECTORIES... 97 1.1 mrg 98 1.1 mrg In the 1st form, copy SRCFILE to DSTFILE. 99 1.1 mrg In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100 1.1 mrg In the 4th, create DIRECTORIES. 101 1.1 mrg 102 1.1 mrg Options: 103 1.1 mrg --help display this help and exit. 104 1.1 mrg --version display version info and exit. 105 1.1 mrg 106 1.1 mrg -c (ignored) 107 1.1 mrg -C install only if different (preserve data modification time) 108 1.1 mrg -d create directories instead of installing files. 109 1.1 mrg -g GROUP $chgrpprog installed files to GROUP. 110 1.1 mrg -m MODE $chmodprog installed files to MODE. 111 1.1 mrg -o USER $chownprog installed files to USER. 112 1.1 mrg -p pass -p to $cpprog. 113 1.1 mrg -s $stripprog installed files. 114 1.1 mrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115 1.1 mrg -t DIRECTORY install into DIRECTORY. 116 1.1 mrg -T report an error if DSTFILE is a directory. 117 1.1 mrg 118 1.1 mrg Environment variables override the default commands: 119 1.1 mrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120 1.1 mrg RMPROG STRIPPROG 121 1.1 mrg 122 1.1 mrg By default, rm is invoked with -f; when overridden with RMPROG, 123 1.1 mrg it's up to you to specify -f if you want it. 124 1.1 mrg 125 1.1 mrg If -S is not specified, no backups are attempted. 126 1.1 mrg 127 1.1 mrg Email bug reports to bug-automake (at] gnu.org. 128 1.1 mrg Automake home page: https://www.gnu.org/software/automake/ 129 1.1 mrg " 130 1.1 mrg 131 1.1 mrg while test $# -ne 0; do 132 1.1 mrg case $1 in 133 1.1 mrg -c) ;; 134 1.1 mrg 135 1.1 mrg -C) copy_on_change=true;; 136 1.1 mrg 137 1.1 mrg -d) dir_arg=true;; 138 1.1 mrg 139 1.1 mrg -g) chgrpcmd="$chgrpprog $2" 140 1.1 mrg shift;; 141 1.1 mrg 142 1.1 mrg --help) echo "$usage"; exit $?;; 143 1.1 mrg 144 1.1 mrg -m) mode=$2 145 1.1 mrg case $mode in 146 1.1 mrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147 1.1 mrg echo "$0: invalid mode: $mode" >&2 148 1.1 mrg exit 1;; 149 1.1 mrg esac 150 1.1 mrg shift;; 151 1.1 mrg 152 1.1 mrg -o) chowncmd="$chownprog $2" 153 1.1 mrg shift;; 154 1.1 mrg 155 1.1 mrg -p) cpprog="$cpprog -p";; 156 1.1 mrg 157 1.1 mrg -s) stripcmd=$stripprog;; 158 1.1 mrg 159 1.1 mrg -S) backupsuffix="$2" 160 1.1 mrg shift;; 161 1.1 mrg 162 1.1 mrg -t) 163 1.1 mrg is_target_a_directory=always 164 1.1 mrg dst_arg=$2 165 1.1 mrg # Protect names problematic for 'test' and other utilities. 166 1.1 mrg case $dst_arg in 167 1.1 mrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168 1.1 mrg esac 169 1.1 mrg shift;; 170 1.1 mrg 171 1.1 mrg -T) is_target_a_directory=never;; 172 1.1 mrg 173 1.1 mrg --version) echo "$0 $scriptversion"; exit $?;; 174 1.1 mrg 175 1.1 mrg --) shift 176 1.1 mrg break;; 177 1.1 mrg 178 1.1 mrg -*) echo "$0: invalid option: $1" >&2 179 1.1 mrg exit 1;; 180 1.1 mrg 181 1.1 mrg *) break;; 182 1.1 mrg esac 183 1.1 mrg shift 184 1.1 mrg done 185 1.1 mrg 186 1.1 mrg # We allow the use of options -d and -T together, by making -d 187 1.1 mrg # take the precedence; this is for compatibility with GNU install. 188 1.1 mrg 189 1.1 mrg if test -n "$dir_arg"; then 190 1.1 mrg if test -n "$dst_arg"; then 191 1.1 mrg echo "$0: target directory not allowed when installing a directory." >&2 192 1.1 mrg exit 1 193 1.1 mrg fi 194 1.1 mrg fi 195 1.1 mrg 196 1.1 mrg if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197 1.1 mrg # When -d is used, all remaining arguments are directories to create. 198 1.1 mrg # When -t is used, the destination is already specified. 199 1.1 mrg # Otherwise, the last argument is the destination. Remove it from $@. 200 1.1 mrg for arg 201 1.1 mrg do 202 1.1 mrg if test -n "$dst_arg"; then 203 1.1 mrg # $@ is not empty: it contains at least $arg. 204 1.1 mrg set fnord "$@" "$dst_arg" 205 1.1 mrg shift # fnord 206 1.1 mrg fi 207 1.1 mrg shift # arg 208 1.1 mrg dst_arg=$arg 209 1.1 mrg # Protect names problematic for 'test' and other utilities. 210 1.1 mrg case $dst_arg in 211 1.1 mrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212 1.1 mrg esac 213 1.1 mrg done 214 1.1 mrg fi 215 1.1 mrg 216 1.1 mrg if test $# -eq 0; then 217 1.1 mrg if test -z "$dir_arg"; then 218 1.1 mrg echo "$0: no input file specified." >&2 219 1.1 mrg exit 1 220 1.1 mrg fi 221 1.1 mrg # It's OK to call 'install-sh -d' without argument. 222 1.1 mrg # This can happen when creating conditional directories. 223 1.1 mrg exit 0 224 1.1 mrg fi 225 1.1 mrg 226 1.1 mrg if test -z "$dir_arg"; then 227 1.1 mrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228 1.1 mrg if test ! -d "$dst_arg"; then 229 1.1 mrg echo "$0: $dst_arg: Is not a directory." >&2 230 1.1 mrg exit 1 231 1.1 mrg fi 232 1.1 mrg fi 233 1.1 mrg fi 234 1.1 mrg 235 1.1 mrg if test -z "$dir_arg"; then 236 1.1 mrg do_exit='(exit $ret); exit $ret' 237 1.1 mrg trap "ret=129; $do_exit" 1 238 1.1 mrg trap "ret=130; $do_exit" 2 239 1.1 mrg trap "ret=141; $do_exit" 13 240 1.1 mrg trap "ret=143; $do_exit" 15 241 1.1 mrg 242 1.1 mrg # Set umask so as not to create temps with too-generous modes. 243 1.1 mrg # However, 'strip' requires both read and write access to temps. 244 1.1 mrg case $mode in 245 1.1 mrg # Optimize common cases. 246 1.1 mrg *644) cp_umask=133;; 247 1.1 mrg *755) cp_umask=22;; 248 1.1 mrg 249 1.1 mrg *[0-7]) 250 1.1 mrg if test -z "$stripcmd"; then 251 1.1 mrg u_plus_rw= 252 1.1 mrg else 253 1.1 mrg u_plus_rw='% 200' 254 1.1 mrg fi 255 1.1 mrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256 1.1 mrg *) 257 1.1 mrg if test -z "$stripcmd"; then 258 1.1 mrg u_plus_rw= 259 1.1 mrg else 260 1.1 mrg u_plus_rw=,u+rw 261 1.1 mrg fi 262 1.1 mrg cp_umask=$mode$u_plus_rw;; 263 1.1 mrg esac 264 1.1 mrg fi 265 1.1 mrg 266 1.1 mrg for src 267 1.1 mrg do 268 1.1 mrg # Protect names problematic for 'test' and other utilities. 269 1.1 mrg case $src in 270 1.1 mrg -* | [=\(\)!]) src=./$src;; 271 1.1 mrg esac 272 1.1 mrg 273 1.1 mrg if test -n "$dir_arg"; then 274 1.1 mrg dst=$src 275 1.1 mrg dstdir=$dst 276 1.1 mrg test -d "$dstdir" 277 1.1 mrg dstdir_status=$? 278 1.1 mrg # Don't chown directories that already exist. 279 1.1 mrg if test $dstdir_status = 0; then 280 1.1 mrg chowncmd="" 281 1.1 mrg fi 282 1.1 mrg else 283 1.1 mrg 284 1.1 mrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285 1.1 mrg # might cause directories to be created, which would be especially bad 286 1.1 mrg # if $src (and thus $dsttmp) contains '*'. 287 1.1 mrg if test ! -f "$src" && test ! -d "$src"; then 288 1.1 mrg echo "$0: $src does not exist." >&2 289 1.1 mrg exit 1 290 1.1 mrg fi 291 1.1 mrg 292 1.1 mrg if test -z "$dst_arg"; then 293 1.1 mrg echo "$0: no destination specified." >&2 294 1.1 mrg exit 1 295 1.1 mrg fi 296 1.1 mrg dst=$dst_arg 297 1.1 mrg 298 1.1 mrg # If destination is a directory, append the input filename. 299 1.1 mrg if test -d "$dst"; then 300 1.1 mrg if test "$is_target_a_directory" = never; then 301 1.1 mrg echo "$0: $dst_arg: Is a directory" >&2 302 1.1 mrg exit 1 303 1.1 mrg fi 304 1.1 mrg dstdir=$dst 305 1.1 mrg dstbase=`basename "$src"` 306 1.1 mrg case $dst in 307 1.1 mrg */) dst=$dst$dstbase;; 308 1.1 mrg *) dst=$dst/$dstbase;; 309 1.1 mrg esac 310 1.1 mrg dstdir_status=0 311 1.1 mrg else 312 1.1 mrg dstdir=`dirname "$dst"` 313 1.1 mrg test -d "$dstdir" 314 1.1 mrg dstdir_status=$? 315 1.1 mrg fi 316 1.1 mrg fi 317 1.1 mrg 318 1.1 mrg case $dstdir in 319 1.1 mrg */) dstdirslash=$dstdir;; 320 1.1 mrg *) dstdirslash=$dstdir/;; 321 1.1 mrg esac 322 1.1 mrg 323 1.1 mrg obsolete_mkdir_used=false 324 1.1 mrg 325 1.1 mrg if test $dstdir_status != 0; then 326 1.1 mrg case $posix_mkdir in 327 1.1 mrg '') 328 1.1 mrg # With -d, create the new directory with the user-specified mode. 329 1.1 mrg # Otherwise, rely on $mkdir_umask. 330 1.1 mrg if test -n "$dir_arg"; then 331 1.1 mrg mkdir_mode=-m$mode 332 1.1 mrg else 333 1.1 mrg mkdir_mode= 334 1.1 mrg fi 335 1.1 mrg 336 1.1 mrg posix_mkdir=false 337 1.1 mrg # The $RANDOM variable is not portable (e.g., dash). Use it 338 1.1 mrg # here however when possible just to lower collision chance. 339 1.1 mrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340 1.1 mrg 341 1.1 mrg trap ' 342 1.1 mrg ret=$? 343 1.1 mrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344 1.1 mrg exit $ret 345 1.1 mrg ' 0 346 1.1 mrg 347 1.1 mrg # Because "mkdir -p" follows existing symlinks and we likely work 348 1.1 mrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349 1.1 mrg # directory is successfully created first before we actually test 350 1.1 mrg # 'mkdir -p'. 351 1.1 mrg if (umask $mkdir_umask && 352 1.1 mrg $mkdirprog $mkdir_mode "$tmpdir" && 353 1.1 mrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354 1.1 mrg then 355 1.1 mrg if test -z "$dir_arg" || { 356 1.1 mrg # Check for POSIX incompatibilities with -m. 357 1.1 mrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358 1.1 mrg # other-writable bit of parent directory when it shouldn't. 359 1.1 mrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360 1.1 mrg test_tmpdir="$tmpdir/a" 361 1.1 mrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362 1.1 mrg case $ls_ld_tmpdir in 363 1.1 mrg d????-?r-*) different_mode=700;; 364 1.1 mrg d????-?--*) different_mode=755;; 365 1.1 mrg *) false;; 366 1.1 mrg esac && 367 1.1 mrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368 1.1 mrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369 1.1 mrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370 1.1 mrg } 371 1.1 mrg } 372 1.1 mrg then posix_mkdir=: 373 1.1 mrg fi 374 1.1 mrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375 1.1 mrg else 376 1.1 mrg # Remove any dirs left behind by ancient mkdir implementations. 377 1.1 mrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378 1.1 mrg fi 379 1.1 mrg trap '' 0;; 380 1.1 mrg esac 381 1.1 mrg 382 1.1 mrg if 383 1.1 mrg $posix_mkdir && ( 384 1.1 mrg umask $mkdir_umask && 385 1.1 mrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386 1.1 mrg ) 387 1.1 mrg then : 388 1.1 mrg else 389 1.1 mrg 390 1.1 mrg # mkdir does not conform to POSIX, 391 1.1 mrg # or it failed possibly due to a race condition. Create the 392 1.1 mrg # directory the slow way, step by step, checking for races as we go. 393 1.1 mrg 394 1.1 mrg case $dstdir in 395 1.1 mrg /*) prefix='/';; 396 1.1 mrg [-=\(\)!]*) prefix='./';; 397 1.1 mrg *) prefix='';; 398 1.1 mrg esac 399 1.1 mrg 400 1.1 mrg oIFS=$IFS 401 1.1 mrg IFS=/ 402 1.1 mrg set -f 403 1.1 mrg set fnord $dstdir 404 1.1 mrg shift 405 1.1 mrg set +f 406 1.1 mrg IFS=$oIFS 407 1.1 mrg 408 1.1 mrg prefixes= 409 1.1 mrg 410 1.1 mrg for d 411 1.1 mrg do 412 1.1 mrg test X"$d" = X && continue 413 1.1 mrg 414 1.1 mrg prefix=$prefix$d 415 1.1 mrg if test -d "$prefix"; then 416 1.1 mrg prefixes= 417 1.1 mrg else 418 1.1 mrg if $posix_mkdir; then 419 1.1 mrg (umask $mkdir_umask && 420 1.1 mrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421 1.1 mrg # Don't fail if two instances are running concurrently. 422 1.1 mrg test -d "$prefix" || exit 1 423 1.1 mrg else 424 1.1 mrg case $prefix in 425 1.1 mrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426 1.1 mrg *) qprefix=$prefix;; 427 1.1 mrg esac 428 1.1 mrg prefixes="$prefixes '$qprefix'" 429 1.1 mrg fi 430 1.1 mrg fi 431 1.1 mrg prefix=$prefix/ 432 1.1 mrg done 433 1.1 mrg 434 1.1 mrg if test -n "$prefixes"; then 435 1.1 mrg # Don't fail if two instances are running concurrently. 436 1.1 mrg (umask $mkdir_umask && 437 1.1 mrg eval "\$doit_exec \$mkdirprog $prefixes") || 438 1.1 mrg test -d "$dstdir" || exit 1 439 1.1 mrg obsolete_mkdir_used=true 440 1.1 mrg fi 441 1.1 mrg fi 442 1.1 mrg fi 443 1.1 mrg 444 1.1 mrg if test -n "$dir_arg"; then 445 1.1 mrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446 1.1 mrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447 1.1 mrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448 1.1 mrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449 1.1 mrg else 450 1.1 mrg 451 1.1 mrg # Make a couple of temp file names in the proper directory. 452 1.1 mrg dsttmp=${dstdirslash}_inst.$$_ 453 1.1 mrg rmtmp=${dstdirslash}_rm.$$_ 454 1.1 mrg 455 1.1 mrg # Trap to clean up those temp files at exit. 456 1.1 mrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457 1.1 mrg 458 1.1 mrg # Copy the file name to the temp name. 459 1.1 mrg (umask $cp_umask && 460 1.1 mrg { test -z "$stripcmd" || { 461 1.1 mrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462 1.1 mrg # which would cause strip to fail. 463 1.1 mrg if test -z "$doit"; then 464 1.1 mrg : >"$dsttmp" # No need to fork-exec 'touch'. 465 1.1 mrg else 466 1.1 mrg $doit touch "$dsttmp" 467 1.1 mrg fi 468 1.1 mrg } 469 1.1 mrg } && 470 1.1 mrg $doit_exec $cpprog "$src" "$dsttmp") && 471 1.1 mrg 472 1.1 mrg # and set any options; do chmod last to preserve setuid bits. 473 1.1 mrg # 474 1.1 mrg # If any of these fail, we abort the whole thing. If we want to 475 1.1 mrg # ignore errors from any of these, just make sure not to ignore 476 1.1 mrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477 1.1 mrg # 478 1.1 mrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479 1.1 mrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480 1.1 mrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481 1.1 mrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482 1.1 mrg 483 1.1 mrg # If -C, don't bother to copy if it wouldn't change the file. 484 1.1 mrg if $copy_on_change && 485 1.1 mrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486 1.1 mrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487 1.1 mrg set -f && 488 1.1 mrg set X $old && old=:$2:$4:$5:$6 && 489 1.1 mrg set X $new && new=:$2:$4:$5:$6 && 490 1.1 mrg set +f && 491 1.1 mrg test "$old" = "$new" && 492 1.1 mrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493 1.1 mrg then 494 1.1 mrg rm -f "$dsttmp" 495 1.1 mrg else 496 1.1 mrg # If $backupsuffix is set, and the file being installed 497 1.1 mrg # already exists, attempt a backup. Don't worry if it fails, 498 1.1 mrg # e.g., if mv doesn't support -f. 499 1.1 mrg if test -n "$backupsuffix" && test -f "$dst"; then 500 1.1 mrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501 1.1 mrg fi 502 1.1 mrg 503 1.1 mrg # Rename the file to the real destination. 504 1.1 mrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505 1.1 mrg 506 1.1 mrg # The rename failed, perhaps because mv can't rename something else 507 1.1 mrg # to itself, or perhaps because mv is so ancient that it does not 508 1.1 mrg # support -f. 509 1.1 mrg { 510 1.1 mrg # Now remove or move aside any old file at destination location. 511 1.1 mrg # We try this two ways since rm can't unlink itself on some 512 1.1 mrg # systems and the destination file might be busy for other 513 1.1 mrg # reasons. In this case, the final cleanup might fail but the new 514 1.1 mrg # file should still install successfully. 515 1.1 mrg { 516 1.1 mrg test ! -f "$dst" || 517 1.1 mrg $doit $rmcmd "$dst" 2>/dev/null || 518 1.1 mrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519 1.1 mrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520 1.1 mrg } || 521 1.1 mrg { echo "$0: cannot unlink or rename $dst" >&2 522 1.1 mrg (exit 1); exit 1 523 1.1 mrg } 524 1.1 mrg } && 525 1.1 mrg 526 1.1 mrg # Now rename the file to the real destination. 527 1.1 mrg $doit $mvcmd "$dsttmp" "$dst" 528 1.1 mrg } 529 1.1 mrg fi || exit 1 530 1.1 mrg 531 1.1 mrg trap '' 0 532 1.1 mrg fi 533 1.1 mrg done 534 1.1 mrg 535 1.1 mrg # Local variables: 536 1.1 mrg # eval: (add-hook 'before-save-hook 'time-stamp) 537 1.1 mrg # time-stamp-start: "scriptversion=" 538 1.1 mrg # time-stamp-format: "%:y-%02m-%02d.%02H" 539 1.1 mrg # time-stamp-time-zone: "UTC0" 540 1.1 mrg # time-stamp-end: "; # UTC" 541 1.1 mrg # End: 542