install-sh revision b8414663
17d5e3a19Smrg#!/bin/sh 27d5e3a19Smrg# install - install a program, script, or datafile 37d5e3a19Smrg 4b8414663Smrgscriptversion=2013-12-25.23; # UTC 57d5e3a19Smrg 67d5e3a19Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 77d5e3a19Smrg# later released in X11R6 (xc/config/util/install.sh) with the 87d5e3a19Smrg# following copyright and license. 97d5e3a19Smrg# 107d5e3a19Smrg# Copyright (C) 1994 X Consortium 117d5e3a19Smrg# 127d5e3a19Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 137d5e3a19Smrg# of this software and associated documentation files (the "Software"), to 147d5e3a19Smrg# deal in the Software without restriction, including without limitation the 157d5e3a19Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 167d5e3a19Smrg# sell copies of the Software, and to permit persons to whom the Software is 177d5e3a19Smrg# furnished to do so, subject to the following conditions: 187d5e3a19Smrg# 197d5e3a19Smrg# The above copyright notice and this permission notice shall be included in 207d5e3a19Smrg# all copies or substantial portions of the Software. 217d5e3a19Smrg# 227d5e3a19Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 237d5e3a19Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 247d5e3a19Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 257d5e3a19Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 267d5e3a19Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 277d5e3a19Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 287d5e3a19Smrg# 297d5e3a19Smrg# Except as contained in this notice, the name of the X Consortium shall not 307d5e3a19Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 317d5e3a19Smrg# ings in this Software without prior written authorization from the X Consor- 327d5e3a19Smrg# tium. 337d5e3a19Smrg# 347d5e3a19Smrg# 357d5e3a19Smrg# FSF changes to this file are in the public domain. 367d5e3a19Smrg# 377d5e3a19Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38b8414663Smrg# 'make' implicit rules from creating a file called install from it 397d5e3a19Smrg# when there is no Makefile. 407d5e3a19Smrg# 417d5e3a19Smrg# This script is compatible with the BSD install script, but was written 427d5e3a19Smrg# from scratch. 437d5e3a19Smrg 44b8414663Smrgtab=' ' 457d5e3a19Smrgnl=' 467d5e3a19Smrg' 47b8414663SmrgIFS=" $tab$nl" 487d5e3a19Smrg 49b8414663Smrg# Set DOITPROG to "echo" to test this script. 507d5e3a19Smrg 511568b75bSmrgdoit=${DOITPROG-} 52b8414663Smrgdoit_exec=${doit:-exec} 537d5e3a19Smrg 547d5e3a19Smrg# Put in absolute file names if you don't have them in your path; 557d5e3a19Smrg# or use environment vars. 567d5e3a19Smrg 571568b75bSmrgchgrpprog=${CHGRPPROG-chgrp} 581568b75bSmrgchmodprog=${CHMODPROG-chmod} 591568b75bSmrgchownprog=${CHOWNPROG-chown} 601568b75bSmrgcmpprog=${CMPPROG-cmp} 611568b75bSmrgcpprog=${CPPROG-cp} 621568b75bSmrgmkdirprog=${MKDIRPROG-mkdir} 631568b75bSmrgmvprog=${MVPROG-mv} 641568b75bSmrgrmprog=${RMPROG-rm} 651568b75bSmrgstripprog=${STRIPPROG-strip} 661568b75bSmrg 677d5e3a19Smrgposix_mkdir= 687d5e3a19Smrg 697d5e3a19Smrg# Desired mode of installed file. 707d5e3a19Smrgmode=0755 717d5e3a19Smrg 721568b75bSmrgchgrpcmd= 737d5e3a19Smrgchmodcmd=$chmodprog 747d5e3a19Smrgchowncmd= 751568b75bSmrgmvcmd=$mvprog 767d5e3a19Smrgrmcmd="$rmprog -f" 771568b75bSmrgstripcmd= 781568b75bSmrg 797d5e3a19Smrgsrc= 807d5e3a19Smrgdst= 817d5e3a19Smrgdir_arg= 821568b75bSmrgdst_arg= 831568b75bSmrg 841568b75bSmrgcopy_on_change=false 85b8414663Smrgis_target_a_directory=possibly 867d5e3a19Smrg 871568b75bSmrgusage="\ 881568b75bSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 897d5e3a19Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 907d5e3a19Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 917d5e3a19Smrg or: $0 [OPTION]... -d DIRECTORIES... 927d5e3a19Smrg 937d5e3a19SmrgIn the 1st form, copy SRCFILE to DSTFILE. 947d5e3a19SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 957d5e3a19SmrgIn the 4th, create DIRECTORIES. 967d5e3a19Smrg 977d5e3a19SmrgOptions: 981568b75bSmrg --help display this help and exit. 991568b75bSmrg --version display version info and exit. 1001568b75bSmrg 1011568b75bSmrg -c (ignored) 1021568b75bSmrg -C install only if different (preserve the last data modification time) 1031568b75bSmrg -d create directories instead of installing files. 1041568b75bSmrg -g GROUP $chgrpprog installed files to GROUP. 1051568b75bSmrg -m MODE $chmodprog installed files to MODE. 1061568b75bSmrg -o USER $chownprog installed files to USER. 1071568b75bSmrg -s $stripprog installed files. 1081568b75bSmrg -t DIRECTORY install into DIRECTORY. 1091568b75bSmrg -T report an error if DSTFILE is a directory. 1107d5e3a19Smrg 1117d5e3a19SmrgEnvironment variables override the default commands: 1121568b75bSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1131568b75bSmrg RMPROG STRIPPROG 1147d5e3a19Smrg" 1157d5e3a19Smrg 1167d5e3a19Smrgwhile test $# -ne 0; do 1177d5e3a19Smrg case $1 in 1181568b75bSmrg -c) ;; 1191568b75bSmrg 1201568b75bSmrg -C) copy_on_change=true;; 1217d5e3a19Smrg 1221568b75bSmrg -d) dir_arg=true;; 1237d5e3a19Smrg 1247d5e3a19Smrg -g) chgrpcmd="$chgrpprog $2" 125b8414663Smrg shift;; 1267d5e3a19Smrg 1277d5e3a19Smrg --help) echo "$usage"; exit $?;; 1287d5e3a19Smrg 1297d5e3a19Smrg -m) mode=$2 130b8414663Smrg case $mode in 131b8414663Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132b8414663Smrg echo "$0: invalid mode: $mode" >&2 133b8414663Smrg exit 1;; 134b8414663Smrg esac 135b8414663Smrg shift;; 1367d5e3a19Smrg 1377d5e3a19Smrg -o) chowncmd="$chownprog $2" 138b8414663Smrg shift;; 1397d5e3a19Smrg 1401568b75bSmrg -s) stripcmd=$stripprog;; 1417d5e3a19Smrg 142b8414663Smrg -t) 143b8414663Smrg is_target_a_directory=always 144b8414663Smrg dst_arg=$2 145b8414663Smrg # Protect names problematic for 'test' and other utilities. 146b8414663Smrg case $dst_arg in 147b8414663Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 148b8414663Smrg esac 149b8414663Smrg shift;; 1507d5e3a19Smrg 151b8414663Smrg -T) is_target_a_directory=never;; 1527d5e3a19Smrg 1537d5e3a19Smrg --version) echo "$0 $scriptversion"; exit $?;; 1547d5e3a19Smrg 155b8414663Smrg --) shift 156b8414663Smrg break;; 1577d5e3a19Smrg 158b8414663Smrg -*) echo "$0: invalid option: $1" >&2 159b8414663Smrg exit 1;; 1607d5e3a19Smrg 1617d5e3a19Smrg *) break;; 1627d5e3a19Smrg esac 1631568b75bSmrg shift 1647d5e3a19Smrgdone 1657d5e3a19Smrg 166b8414663Smrg# We allow the use of options -d and -T together, by making -d 167b8414663Smrg# take the precedence; this is for compatibility with GNU install. 168b8414663Smrg 169b8414663Smrgif test -n "$dir_arg"; then 170b8414663Smrg if test -n "$dst_arg"; then 171b8414663Smrg echo "$0: target directory not allowed when installing a directory." >&2 172b8414663Smrg exit 1 173b8414663Smrg fi 174b8414663Smrgfi 175b8414663Smrg 1761568b75bSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1777d5e3a19Smrg # When -d is used, all remaining arguments are directories to create. 1787d5e3a19Smrg # When -t is used, the destination is already specified. 1797d5e3a19Smrg # Otherwise, the last argument is the destination. Remove it from $@. 1807d5e3a19Smrg for arg 1817d5e3a19Smrg do 1821568b75bSmrg if test -n "$dst_arg"; then 1837d5e3a19Smrg # $@ is not empty: it contains at least $arg. 1841568b75bSmrg set fnord "$@" "$dst_arg" 1857d5e3a19Smrg shift # fnord 1867d5e3a19Smrg fi 1877d5e3a19Smrg shift # arg 1881568b75bSmrg dst_arg=$arg 189b8414663Smrg # Protect names problematic for 'test' and other utilities. 190b8414663Smrg case $dst_arg in 191b8414663Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 192b8414663Smrg esac 1937d5e3a19Smrg done 1947d5e3a19Smrgfi 1957d5e3a19Smrg 1967d5e3a19Smrgif test $# -eq 0; then 1977d5e3a19Smrg if test -z "$dir_arg"; then 1987d5e3a19Smrg echo "$0: no input file specified." >&2 1997d5e3a19Smrg exit 1 2007d5e3a19Smrg fi 201b8414663Smrg # It's OK to call 'install-sh -d' without argument. 2027d5e3a19Smrg # This can happen when creating conditional directories. 2037d5e3a19Smrg exit 0 2047d5e3a19Smrgfi 2057d5e3a19Smrg 2067d5e3a19Smrgif test -z "$dir_arg"; then 207b8414663Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 208b8414663Smrg if test ! -d "$dst_arg"; then 209b8414663Smrg echo "$0: $dst_arg: Is not a directory." >&2 210b8414663Smrg exit 1 211b8414663Smrg fi 212b8414663Smrg fi 213b8414663Smrgfi 214b8414663Smrg 215b8414663Smrgif test -z "$dir_arg"; then 216b8414663Smrg do_exit='(exit $ret); exit $ret' 217b8414663Smrg trap "ret=129; $do_exit" 1 218b8414663Smrg trap "ret=130; $do_exit" 2 219b8414663Smrg trap "ret=141; $do_exit" 13 220b8414663Smrg trap "ret=143; $do_exit" 15 2217d5e3a19Smrg 2227d5e3a19Smrg # Set umask so as not to create temps with too-generous modes. 2237d5e3a19Smrg # However, 'strip' requires both read and write access to temps. 2247d5e3a19Smrg case $mode in 2257d5e3a19Smrg # Optimize common cases. 2267d5e3a19Smrg *644) cp_umask=133;; 2277d5e3a19Smrg *755) cp_umask=22;; 2287d5e3a19Smrg 2297d5e3a19Smrg *[0-7]) 2307d5e3a19Smrg if test -z "$stripcmd"; then 231b8414663Smrg u_plus_rw= 2327d5e3a19Smrg else 233b8414663Smrg u_plus_rw='% 200' 2347d5e3a19Smrg fi 2357d5e3a19Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2367d5e3a19Smrg *) 2377d5e3a19Smrg if test -z "$stripcmd"; then 238b8414663Smrg u_plus_rw= 2397d5e3a19Smrg else 240b8414663Smrg u_plus_rw=,u+rw 2417d5e3a19Smrg fi 2427d5e3a19Smrg cp_umask=$mode$u_plus_rw;; 2437d5e3a19Smrg esac 2447d5e3a19Smrgfi 2457d5e3a19Smrg 2467d5e3a19Smrgfor src 2477d5e3a19Smrgdo 248b8414663Smrg # Protect names problematic for 'test' and other utilities. 2497d5e3a19Smrg case $src in 250b8414663Smrg -* | [=\(\)!]) src=./$src;; 2517d5e3a19Smrg esac 2527d5e3a19Smrg 2537d5e3a19Smrg if test -n "$dir_arg"; then 2547d5e3a19Smrg dst=$src 2557d5e3a19Smrg dstdir=$dst 2567d5e3a19Smrg test -d "$dstdir" 2577d5e3a19Smrg dstdir_status=$? 2587d5e3a19Smrg else 2597d5e3a19Smrg 2607d5e3a19Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2617d5e3a19Smrg # might cause directories to be created, which would be especially bad 2627d5e3a19Smrg # if $src (and thus $dsttmp) contains '*'. 2637d5e3a19Smrg if test ! -f "$src" && test ! -d "$src"; then 2647d5e3a19Smrg echo "$0: $src does not exist." >&2 2657d5e3a19Smrg exit 1 2667d5e3a19Smrg fi 2677d5e3a19Smrg 2681568b75bSmrg if test -z "$dst_arg"; then 2697d5e3a19Smrg echo "$0: no destination specified." >&2 2707d5e3a19Smrg exit 1 2717d5e3a19Smrg fi 2721568b75bSmrg dst=$dst_arg 2737d5e3a19Smrg 2747d5e3a19Smrg # If destination is a directory, append the input filename; won't work 2757d5e3a19Smrg # if double slashes aren't ignored. 2767d5e3a19Smrg if test -d "$dst"; then 277b8414663Smrg if test "$is_target_a_directory" = never; then 278b8414663Smrg echo "$0: $dst_arg: Is a directory" >&2 279b8414663Smrg exit 1 2807d5e3a19Smrg fi 2817d5e3a19Smrg dstdir=$dst 2827d5e3a19Smrg dst=$dstdir/`basename "$src"` 2837d5e3a19Smrg dstdir_status=0 2847d5e3a19Smrg else 285b8414663Smrg dstdir=`dirname "$dst"` 2867d5e3a19Smrg test -d "$dstdir" 2877d5e3a19Smrg dstdir_status=$? 2887d5e3a19Smrg fi 2897d5e3a19Smrg fi 2907d5e3a19Smrg 2917d5e3a19Smrg obsolete_mkdir_used=false 2927d5e3a19Smrg 2937d5e3a19Smrg if test $dstdir_status != 0; then 2947d5e3a19Smrg case $posix_mkdir in 2957d5e3a19Smrg '') 296b8414663Smrg # Create intermediate dirs using mode 755 as modified by the umask. 297b8414663Smrg # This is like FreeBSD 'install' as of 1997-10-28. 298b8414663Smrg umask=`umask` 299b8414663Smrg case $stripcmd.$umask in 300b8414663Smrg # Optimize common cases. 301b8414663Smrg *[2367][2367]) mkdir_umask=$umask;; 302b8414663Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303b8414663Smrg 304b8414663Smrg *[0-7]) 305b8414663Smrg mkdir_umask=`expr $umask + 22 \ 306b8414663Smrg - $umask % 100 % 40 + $umask % 20 \ 307b8414663Smrg - $umask % 10 % 4 + $umask % 2 308b8414663Smrg `;; 309b8414663Smrg *) mkdir_umask=$umask,go-w;; 310b8414663Smrg esac 311b8414663Smrg 312b8414663Smrg # With -d, create the new directory with the user-specified mode. 313b8414663Smrg # Otherwise, rely on $mkdir_umask. 314b8414663Smrg if test -n "$dir_arg"; then 315b8414663Smrg mkdir_mode=-m$mode 316b8414663Smrg else 317b8414663Smrg mkdir_mode= 318b8414663Smrg fi 319b8414663Smrg 320b8414663Smrg posix_mkdir=false 321b8414663Smrg case $umask in 322b8414663Smrg *[123567][0-7][0-7]) 323b8414663Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 324b8414663Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325b8414663Smrg ;; 326b8414663Smrg *) 327b8414663Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 328b8414663Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 329b8414663Smrg 330b8414663Smrg if (umask $mkdir_umask && 331b8414663Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 332b8414663Smrg then 333b8414663Smrg if test -z "$dir_arg" || { 334b8414663Smrg # Check for POSIX incompatibilities with -m. 335b8414663Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 336b8414663Smrg # other-writable bit of parent directory when it shouldn't. 337b8414663Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 338b8414663Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 339b8414663Smrg case $ls_ld_tmpdir in 340b8414663Smrg d????-?r-*) different_mode=700;; 341b8414663Smrg d????-?--*) different_mode=755;; 342b8414663Smrg *) false;; 343b8414663Smrg esac && 344b8414663Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 345b8414663Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 346b8414663Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 347b8414663Smrg } 348b8414663Smrg } 349b8414663Smrg then posix_mkdir=: 350b8414663Smrg fi 351b8414663Smrg rmdir "$tmpdir/d" "$tmpdir" 352b8414663Smrg else 353b8414663Smrg # Remove any dirs left behind by ancient mkdir implementations. 354b8414663Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 355b8414663Smrg fi 356b8414663Smrg trap '' 0;; 357b8414663Smrg esac;; 3587d5e3a19Smrg esac 3597d5e3a19Smrg 3607d5e3a19Smrg if 3617d5e3a19Smrg $posix_mkdir && ( 362b8414663Smrg umask $mkdir_umask && 363b8414663Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3647d5e3a19Smrg ) 3657d5e3a19Smrg then : 3667d5e3a19Smrg else 3677d5e3a19Smrg 3687d5e3a19Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3697d5e3a19Smrg # or it failed possibly due to a race condition. Create the 3707d5e3a19Smrg # directory the slow way, step by step, checking for races as we go. 3717d5e3a19Smrg 3727d5e3a19Smrg case $dstdir in 373b8414663Smrg /*) prefix='/';; 374b8414663Smrg [-=\(\)!]*) prefix='./';; 375b8414663Smrg *) prefix='';; 3767d5e3a19Smrg esac 3777d5e3a19Smrg 3787d5e3a19Smrg oIFS=$IFS 3797d5e3a19Smrg IFS=/ 380b8414663Smrg set -f 3817d5e3a19Smrg set fnord $dstdir 3827d5e3a19Smrg shift 383b8414663Smrg set +f 3847d5e3a19Smrg IFS=$oIFS 3857d5e3a19Smrg 3867d5e3a19Smrg prefixes= 3877d5e3a19Smrg 3887d5e3a19Smrg for d 3897d5e3a19Smrg do 390b8414663Smrg test X"$d" = X && continue 391b8414663Smrg 392b8414663Smrg prefix=$prefix$d 393b8414663Smrg if test -d "$prefix"; then 394b8414663Smrg prefixes= 395b8414663Smrg else 396b8414663Smrg if $posix_mkdir; then 397b8414663Smrg (umask=$mkdir_umask && 398b8414663Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 399b8414663Smrg # Don't fail if two instances are running concurrently. 400b8414663Smrg test -d "$prefix" || exit 1 401b8414663Smrg else 402b8414663Smrg case $prefix in 403b8414663Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 404b8414663Smrg *) qprefix=$prefix;; 405b8414663Smrg esac 406b8414663Smrg prefixes="$prefixes '$qprefix'" 407b8414663Smrg fi 408b8414663Smrg fi 409b8414663Smrg prefix=$prefix/ 4107d5e3a19Smrg done 4117d5e3a19Smrg 4127d5e3a19Smrg if test -n "$prefixes"; then 413b8414663Smrg # Don't fail if two instances are running concurrently. 414b8414663Smrg (umask $mkdir_umask && 415b8414663Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 416b8414663Smrg test -d "$dstdir" || exit 1 417b8414663Smrg obsolete_mkdir_used=true 4187d5e3a19Smrg fi 4197d5e3a19Smrg fi 4207d5e3a19Smrg fi 4217d5e3a19Smrg 4227d5e3a19Smrg if test -n "$dir_arg"; then 4237d5e3a19Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4247d5e3a19Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4257d5e3a19Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4267d5e3a19Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4277d5e3a19Smrg else 4287d5e3a19Smrg 4297d5e3a19Smrg # Make a couple of temp file names in the proper directory. 4307d5e3a19Smrg dsttmp=$dstdir/_inst.$$_ 4317d5e3a19Smrg rmtmp=$dstdir/_rm.$$_ 4327d5e3a19Smrg 4337d5e3a19Smrg # Trap to clean up those temp files at exit. 4347d5e3a19Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4357d5e3a19Smrg 4367d5e3a19Smrg # Copy the file name to the temp name. 4377d5e3a19Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4387d5e3a19Smrg 4397d5e3a19Smrg # and set any options; do chmod last to preserve setuid bits. 4407d5e3a19Smrg # 4417d5e3a19Smrg # If any of these fail, we abort the whole thing. If we want to 4427d5e3a19Smrg # ignore errors from any of these, just make sure not to ignore 4437d5e3a19Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4447d5e3a19Smrg # 4451568b75bSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4461568b75bSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4471568b75bSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4481568b75bSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4491568b75bSmrg 4501568b75bSmrg # If -C, don't bother to copy if it wouldn't change the file. 4511568b75bSmrg if $copy_on_change && 452b8414663Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 453b8414663Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 454b8414663Smrg set -f && 4551568b75bSmrg set X $old && old=:$2:$4:$5:$6 && 4561568b75bSmrg set X $new && new=:$2:$4:$5:$6 && 457b8414663Smrg set +f && 4581568b75bSmrg test "$old" = "$new" && 4591568b75bSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4601568b75bSmrg then 4611568b75bSmrg rm -f "$dsttmp" 4621568b75bSmrg else 4631568b75bSmrg # Rename the file to the real destination. 4641568b75bSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 4651568b75bSmrg 4661568b75bSmrg # The rename failed, perhaps because mv can't rename something else 4671568b75bSmrg # to itself, or perhaps because mv is so ancient that it does not 4681568b75bSmrg # support -f. 4691568b75bSmrg { 470b8414663Smrg # Now remove or move aside any old file at destination location. 471b8414663Smrg # We try this two ways since rm can't unlink itself on some 472b8414663Smrg # systems and the destination file might be busy for other 473b8414663Smrg # reasons. In this case, the final cleanup might fail but the new 474b8414663Smrg # file should still install successfully. 475b8414663Smrg { 476b8414663Smrg test ! -f "$dst" || 477b8414663Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 478b8414663Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 479b8414663Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 480b8414663Smrg } || 481b8414663Smrg { echo "$0: cannot unlink or rename $dst" >&2 482b8414663Smrg (exit 1); exit 1 483b8414663Smrg } 484b8414663Smrg } && 485b8414663Smrg 486b8414663Smrg # Now rename the file to the real destination. 487b8414663Smrg $doit $mvcmd "$dsttmp" "$dst" 4881568b75bSmrg } 4891568b75bSmrg fi || exit 1 4907d5e3a19Smrg 4917d5e3a19Smrg trap '' 0 4927d5e3a19Smrg fi 4937d5e3a19Smrgdone 4947d5e3a19Smrg 4957d5e3a19Smrg# Local variables: 4967d5e3a19Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 4977d5e3a19Smrg# time-stamp-start: "scriptversion=" 4987d5e3a19Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 499765486e8Smrg# time-stamp-time-zone: "UTC" 500765486e8Smrg# time-stamp-end: "; # UTC" 5017d5e3a19Smrg# End: 502