install-sh revision dc407927
13eed67faSmbalmer#!/bin/sh 23eed67faSmbalmer# install - install a program, script, or datafile 33eed67faSmbalmer 4dc407927Smrgscriptversion=2009-04-28.21; # UTC 53eed67faSmbalmer 63eed67faSmbalmer# This originates from X11R5 (mit/util/scripts/install.sh), which was 73eed67faSmbalmer# later released in X11R6 (xc/config/util/install.sh) with the 83eed67faSmbalmer# following copyright and license. 93eed67faSmbalmer# 103eed67faSmbalmer# Copyright (C) 1994 X Consortium 113eed67faSmbalmer# 123eed67faSmbalmer# Permission is hereby granted, free of charge, to any person obtaining a copy 133eed67faSmbalmer# of this software and associated documentation files (the "Software"), to 143eed67faSmbalmer# deal in the Software without restriction, including without limitation the 153eed67faSmbalmer# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 163eed67faSmbalmer# sell copies of the Software, and to permit persons to whom the Software is 173eed67faSmbalmer# furnished to do so, subject to the following conditions: 183eed67faSmbalmer# 193eed67faSmbalmer# The above copyright notice and this permission notice shall be included in 203eed67faSmbalmer# all copies or substantial portions of the Software. 213eed67faSmbalmer# 223eed67faSmbalmer# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 233eed67faSmbalmer# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 243eed67faSmbalmer# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 253eed67faSmbalmer# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 263eed67faSmbalmer# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 273eed67faSmbalmer# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 283eed67faSmbalmer# 293eed67faSmbalmer# Except as contained in this notice, the name of the X Consortium shall not 303eed67faSmbalmer# be used in advertising or otherwise to promote the sale, use or other deal- 313eed67faSmbalmer# ings in this Software without prior written authorization from the X Consor- 323eed67faSmbalmer# tium. 333eed67faSmbalmer# 343eed67faSmbalmer# 353eed67faSmbalmer# FSF changes to this file are in the public domain. 363eed67faSmbalmer# 373eed67faSmbalmer# Calling this script install-sh is preferred over install.sh, to prevent 383eed67faSmbalmer# `make' implicit rules from creating a file called install from it 393eed67faSmbalmer# when there is no Makefile. 403eed67faSmbalmer# 413eed67faSmbalmer# This script is compatible with the BSD install script, but was written 42dc407927Smrg# from scratch. 43dc407927Smrg 44dc407927Smrgnl=' 45dc407927Smrg' 46dc407927SmrgIFS=" "" $nl" 473eed67faSmbalmer 483eed67faSmbalmer# set DOITPROG to echo to test this script 493eed67faSmbalmer 503eed67faSmbalmer# Don't use :- since 4.3BSD and earlier shells don't like it. 51dc407927Smrgdoit=${DOITPROG-} 52dc407927Smrgif test -z "$doit"; then 53dc407927Smrg doit_exec=exec 54dc407927Smrgelse 55dc407927Smrg doit_exec=$doit 56dc407927Smrgfi 573eed67faSmbalmer 58dc407927Smrg# Put in absolute file names if you don't have them in your path; 59dc407927Smrg# or use environment vars. 60dc407927Smrg 61dc407927Smrgchgrpprog=${CHGRPPROG-chgrp} 62dc407927Smrgchmodprog=${CHMODPROG-chmod} 63dc407927Smrgchownprog=${CHOWNPROG-chown} 64dc407927Smrgcmpprog=${CMPPROG-cmp} 65dc407927Smrgcpprog=${CPPROG-cp} 66dc407927Smrgmkdirprog=${MKDIRPROG-mkdir} 67dc407927Smrgmvprog=${MVPROG-mv} 68dc407927Smrgrmprog=${RMPROG-rm} 69dc407927Smrgstripprog=${STRIPPROG-strip} 70dc407927Smrg 71dc407927Smrgposix_glob='?' 72dc407927Smrginitialize_posix_glob=' 73dc407927Smrg test "$posix_glob" != "?" || { 74dc407927Smrg if (set -f) 2>/dev/null; then 75dc407927Smrg posix_glob= 76dc407927Smrg else 77dc407927Smrg posix_glob=: 78dc407927Smrg fi 79dc407927Smrg } 80dc407927Smrg' 813eed67faSmbalmer 82dc407927Smrgposix_mkdir= 83dc407927Smrg 84dc407927Smrg# Desired mode of installed file. 85dc407927Smrgmode=0755 863eed67faSmbalmer 873eed67faSmbalmerchgrpcmd= 88dc407927Smrgchmodcmd=$chmodprog 89dc407927Smrgchowncmd= 90dc407927Smrgmvcmd=$mvprog 913eed67faSmbalmerrmcmd="$rmprog -f" 92dc407927Smrgstripcmd= 93dc407927Smrg 943eed67faSmbalmersrc= 953eed67faSmbalmerdst= 963eed67faSmbalmerdir_arg= 97dc407927Smrgdst_arg= 98dc407927Smrg 99dc407927Smrgcopy_on_change=false 1003eed67faSmbalmerno_target_directory= 1013eed67faSmbalmer 102dc407927Smrgusage="\ 103dc407927SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 1043eed67faSmbalmer or: $0 [OPTION]... SRCFILES... DIRECTORY 1053eed67faSmbalmer or: $0 [OPTION]... -t DIRECTORY SRCFILES... 1063eed67faSmbalmer or: $0 [OPTION]... -d DIRECTORIES... 1073eed67faSmbalmer 1083eed67faSmbalmerIn the 1st form, copy SRCFILE to DSTFILE. 1093eed67faSmbalmerIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1103eed67faSmbalmerIn the 4th, create DIRECTORIES. 1113eed67faSmbalmer 1123eed67faSmbalmerOptions: 113dc407927Smrg --help display this help and exit. 114dc407927Smrg --version display version info and exit. 115dc407927Smrg 116dc407927Smrg -c (ignored) 117dc407927Smrg -C install only if different (preserve the last data modification time) 118dc407927Smrg -d create directories instead of installing files. 119dc407927Smrg -g GROUP $chgrpprog installed files to GROUP. 120dc407927Smrg -m MODE $chmodprog installed files to MODE. 121dc407927Smrg -o USER $chownprog installed files to USER. 122dc407927Smrg -s $stripprog installed files. 123dc407927Smrg -t DIRECTORY install into DIRECTORY. 124dc407927Smrg -T report an error if DSTFILE is a directory. 1253eed67faSmbalmer 1263eed67faSmbalmerEnvironment variables override the default commands: 127dc407927Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 128dc407927Smrg RMPROG STRIPPROG 1293eed67faSmbalmer" 1303eed67faSmbalmer 131dc407927Smrgwhile test $# -ne 0; do 1323eed67faSmbalmer case $1 in 133dc407927Smrg -c) ;; 134dc407927Smrg 135dc407927Smrg -C) copy_on_change=true;; 1363eed67faSmbalmer 137dc407927Smrg -d) dir_arg=true;; 1383eed67faSmbalmer 1393eed67faSmbalmer -g) chgrpcmd="$chgrpprog $2" 140dc407927Smrg shift;; 1413eed67faSmbalmer 1423eed67faSmbalmer --help) echo "$usage"; exit $?;; 1433eed67faSmbalmer 144dc407927Smrg -m) mode=$2 145dc407927Smrg case $mode in 146dc407927Smrg *' '* | *' '* | *' 147dc407927Smrg'* | *'*'* | *'?'* | *'['*) 148dc407927Smrg echo "$0: invalid mode: $mode" >&2 149dc407927Smrg exit 1;; 150dc407927Smrg esac 151dc407927Smrg shift;; 1523eed67faSmbalmer 1533eed67faSmbalmer -o) chowncmd="$chownprog $2" 154dc407927Smrg shift;; 1553eed67faSmbalmer 156dc407927Smrg -s) stripcmd=$stripprog;; 1573eed67faSmbalmer 158dc407927Smrg -t) dst_arg=$2 159dc407927Smrg shift;; 1603eed67faSmbalmer 161dc407927Smrg -T) no_target_directory=true;; 1623eed67faSmbalmer 1633eed67faSmbalmer --version) echo "$0 $scriptversion"; exit $?;; 1643eed67faSmbalmer 165dc407927Smrg --) shift 1663eed67faSmbalmer break;; 167dc407927Smrg 168dc407927Smrg -*) echo "$0: invalid option: $1" >&2 169dc407927Smrg exit 1;; 170dc407927Smrg 171dc407927Smrg *) break;; 1723eed67faSmbalmer esac 173dc407927Smrg shift 1743eed67faSmbalmerdone 1753eed67faSmbalmer 176dc407927Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177dc407927Smrg # When -d is used, all remaining arguments are directories to create. 178dc407927Smrg # When -t is used, the destination is already specified. 179dc407927Smrg # Otherwise, the last argument is the destination. Remove it from $@. 180dc407927Smrg for arg 181dc407927Smrg do 182dc407927Smrg if test -n "$dst_arg"; then 183dc407927Smrg # $@ is not empty: it contains at least $arg. 184dc407927Smrg set fnord "$@" "$dst_arg" 185dc407927Smrg shift # fnord 186dc407927Smrg fi 187dc407927Smrg shift # arg 188dc407927Smrg dst_arg=$arg 189dc407927Smrg done 190dc407927Smrgfi 191dc407927Smrg 192dc407927Smrgif test $# -eq 0; then 1933eed67faSmbalmer if test -z "$dir_arg"; then 1943eed67faSmbalmer echo "$0: no input file specified." >&2 1953eed67faSmbalmer exit 1 1963eed67faSmbalmer fi 1973eed67faSmbalmer # It's OK to call `install-sh -d' without argument. 1983eed67faSmbalmer # This can happen when creating conditional directories. 1993eed67faSmbalmer exit 0 2003eed67faSmbalmerfi 2013eed67faSmbalmer 202dc407927Smrgif test -z "$dir_arg"; then 203dc407927Smrg trap '(exit $?); exit' 1 2 13 15 204dc407927Smrg 205dc407927Smrg # Set umask so as not to create temps with too-generous modes. 206dc407927Smrg # However, 'strip' requires both read and write access to temps. 207dc407927Smrg case $mode in 208dc407927Smrg # Optimize common cases. 209dc407927Smrg *644) cp_umask=133;; 210dc407927Smrg *755) cp_umask=22;; 211dc407927Smrg 212dc407927Smrg *[0-7]) 213dc407927Smrg if test -z "$stripcmd"; then 214dc407927Smrg u_plus_rw= 215dc407927Smrg else 216dc407927Smrg u_plus_rw='% 200' 217dc407927Smrg fi 218dc407927Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 219dc407927Smrg *) 220dc407927Smrg if test -z "$stripcmd"; then 221dc407927Smrg u_plus_rw= 222dc407927Smrg else 223dc407927Smrg u_plus_rw=,u+rw 224dc407927Smrg fi 225dc407927Smrg cp_umask=$mode$u_plus_rw;; 226dc407927Smrg esac 227dc407927Smrgfi 228dc407927Smrg 2293eed67faSmbalmerfor src 2303eed67faSmbalmerdo 2313eed67faSmbalmer # Protect names starting with `-'. 2323eed67faSmbalmer case $src in 233dc407927Smrg -*) src=./$src;; 2343eed67faSmbalmer esac 2353eed67faSmbalmer 2363eed67faSmbalmer if test -n "$dir_arg"; then 2373eed67faSmbalmer dst=$src 238dc407927Smrg dstdir=$dst 239dc407927Smrg test -d "$dstdir" 240dc407927Smrg dstdir_status=$? 2413eed67faSmbalmer else 242dc407927Smrg 2433eed67faSmbalmer # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2443eed67faSmbalmer # might cause directories to be created, which would be especially bad 2453eed67faSmbalmer # if $src (and thus $dsttmp) contains '*'. 2463eed67faSmbalmer if test ! -f "$src" && test ! -d "$src"; then 2473eed67faSmbalmer echo "$0: $src does not exist." >&2 2483eed67faSmbalmer exit 1 2493eed67faSmbalmer fi 2503eed67faSmbalmer 251dc407927Smrg if test -z "$dst_arg"; then 2523eed67faSmbalmer echo "$0: no destination specified." >&2 2533eed67faSmbalmer exit 1 2543eed67faSmbalmer fi 2553eed67faSmbalmer 256dc407927Smrg dst=$dst_arg 2573eed67faSmbalmer # Protect names starting with `-'. 2583eed67faSmbalmer case $dst in 259dc407927Smrg -*) dst=./$dst;; 2603eed67faSmbalmer esac 2613eed67faSmbalmer 2623eed67faSmbalmer # If destination is a directory, append the input filename; won't work 2633eed67faSmbalmer # if double slashes aren't ignored. 2643eed67faSmbalmer if test -d "$dst"; then 2653eed67faSmbalmer if test -n "$no_target_directory"; then 266dc407927Smrg echo "$0: $dst_arg: Is a directory" >&2 2673eed67faSmbalmer exit 1 2683eed67faSmbalmer fi 269dc407927Smrg dstdir=$dst 270dc407927Smrg dst=$dstdir/`basename "$src"` 271dc407927Smrg dstdir_status=0 272dc407927Smrg else 273dc407927Smrg # Prefer dirname, but fall back on a substitute if dirname fails. 274dc407927Smrg dstdir=` 275dc407927Smrg (dirname "$dst") 2>/dev/null || 276dc407927Smrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 277dc407927Smrg X"$dst" : 'X\(//\)[^/]' \| \ 278dc407927Smrg X"$dst" : 'X\(//\)$' \| \ 279dc407927Smrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 280dc407927Smrg echo X"$dst" | 281dc407927Smrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 282dc407927Smrg s//\1/ 283dc407927Smrg q 284dc407927Smrg } 285dc407927Smrg /^X\(\/\/\)[^/].*/{ 286dc407927Smrg s//\1/ 287dc407927Smrg q 288dc407927Smrg } 289dc407927Smrg /^X\(\/\/\)$/{ 290dc407927Smrg s//\1/ 291dc407927Smrg q 292dc407927Smrg } 293dc407927Smrg /^X\(\/\).*/{ 294dc407927Smrg s//\1/ 295dc407927Smrg q 296dc407927Smrg } 297dc407927Smrg s/.*/./; q' 298dc407927Smrg ` 299dc407927Smrg 300dc407927Smrg test -d "$dstdir" 301dc407927Smrg dstdir_status=$? 3023eed67faSmbalmer fi 3033eed67faSmbalmer fi 3043eed67faSmbalmer 305dc407927Smrg obsolete_mkdir_used=false 306dc407927Smrg 307dc407927Smrg if test $dstdir_status != 0; then 308dc407927Smrg case $posix_mkdir in 309dc407927Smrg '') 310dc407927Smrg # Create intermediate dirs using mode 755 as modified by the umask. 311dc407927Smrg # This is like FreeBSD 'install' as of 1997-10-28. 312dc407927Smrg umask=`umask` 313dc407927Smrg case $stripcmd.$umask in 314dc407927Smrg # Optimize common cases. 315dc407927Smrg *[2367][2367]) mkdir_umask=$umask;; 316dc407927Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 317dc407927Smrg 318dc407927Smrg *[0-7]) 319dc407927Smrg mkdir_umask=`expr $umask + 22 \ 320dc407927Smrg - $umask % 100 % 40 + $umask % 20 \ 321dc407927Smrg - $umask % 10 % 4 + $umask % 2 322dc407927Smrg `;; 323dc407927Smrg *) mkdir_umask=$umask,go-w;; 324dc407927Smrg esac 325dc407927Smrg 326dc407927Smrg # With -d, create the new directory with the user-specified mode. 327dc407927Smrg # Otherwise, rely on $mkdir_umask. 328dc407927Smrg if test -n "$dir_arg"; then 329dc407927Smrg mkdir_mode=-m$mode 330dc407927Smrg else 331dc407927Smrg mkdir_mode= 332dc407927Smrg fi 333dc407927Smrg 334dc407927Smrg posix_mkdir=false 335dc407927Smrg case $umask in 336dc407927Smrg *[123567][0-7][0-7]) 337dc407927Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 338dc407927Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 339dc407927Smrg ;; 340dc407927Smrg *) 341dc407927Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 342dc407927Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 343dc407927Smrg 344dc407927Smrg if (umask $mkdir_umask && 345dc407927Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 346dc407927Smrg then 347dc407927Smrg if test -z "$dir_arg" || { 348dc407927Smrg # Check for POSIX incompatibilities with -m. 349dc407927Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 350dc407927Smrg # other-writeable bit of parent directory when it shouldn't. 351dc407927Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 352dc407927Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 353dc407927Smrg case $ls_ld_tmpdir in 354dc407927Smrg d????-?r-*) different_mode=700;; 355dc407927Smrg d????-?--*) different_mode=755;; 356dc407927Smrg *) false;; 357dc407927Smrg esac && 358dc407927Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 359dc407927Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 360dc407927Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 361dc407927Smrg } 362dc407927Smrg } 363dc407927Smrg then posix_mkdir=: 364dc407927Smrg fi 365dc407927Smrg rmdir "$tmpdir/d" "$tmpdir" 366dc407927Smrg else 367dc407927Smrg # Remove any dirs left behind by ancient mkdir implementations. 368dc407927Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 369dc407927Smrg fi 370dc407927Smrg trap '' 0;; 371dc407927Smrg esac;; 372dc407927Smrg esac 3733eed67faSmbalmer 374dc407927Smrg if 375dc407927Smrg $posix_mkdir && ( 376dc407927Smrg umask $mkdir_umask && 377dc407927Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 378dc407927Smrg ) 379dc407927Smrg then : 380dc407927Smrg else 3813eed67faSmbalmer 382dc407927Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 383dc407927Smrg # or it failed possibly due to a race condition. Create the 384dc407927Smrg # directory the slow way, step by step, checking for races as we go. 3853eed67faSmbalmer 386dc407927Smrg case $dstdir in 387dc407927Smrg /*) prefix='/';; 388dc407927Smrg -*) prefix='./';; 389dc407927Smrg *) prefix='';; 390dc407927Smrg esac 3913eed67faSmbalmer 392dc407927Smrg eval "$initialize_posix_glob" 3933eed67faSmbalmer 394dc407927Smrg oIFS=$IFS 395dc407927Smrg IFS=/ 396dc407927Smrg $posix_glob set -f 397dc407927Smrg set fnord $dstdir 3983eed67faSmbalmer shift 399dc407927Smrg $posix_glob set +f 400dc407927Smrg IFS=$oIFS 401dc407927Smrg 402dc407927Smrg prefixes= 403dc407927Smrg 404dc407927Smrg for d 405dc407927Smrg do 406dc407927Smrg test -z "$d" && continue 407dc407927Smrg 408dc407927Smrg prefix=$prefix$d 409dc407927Smrg if test -d "$prefix"; then 410dc407927Smrg prefixes= 411dc407927Smrg else 412dc407927Smrg if $posix_mkdir; then 413dc407927Smrg (umask=$mkdir_umask && 414dc407927Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 415dc407927Smrg # Don't fail if two instances are running concurrently. 416dc407927Smrg test -d "$prefix" || exit 1 417dc407927Smrg else 418dc407927Smrg case $prefix in 419dc407927Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 420dc407927Smrg *) qprefix=$prefix;; 421dc407927Smrg esac 422dc407927Smrg prefixes="$prefixes '$qprefix'" 423dc407927Smrg fi 424dc407927Smrg fi 425dc407927Smrg prefix=$prefix/ 426dc407927Smrg done 427dc407927Smrg 428dc407927Smrg if test -n "$prefixes"; then 429dc407927Smrg # Don't fail if two instances are running concurrently. 430dc407927Smrg (umask $mkdir_umask && 431dc407927Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 432dc407927Smrg test -d "$dstdir" || exit 1 433dc407927Smrg obsolete_mkdir_used=true 4343eed67faSmbalmer fi 435dc407927Smrg fi 4363eed67faSmbalmer fi 4373eed67faSmbalmer 4383eed67faSmbalmer if test -n "$dir_arg"; then 439dc407927Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 440dc407927Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 441dc407927Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 442dc407927Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4433eed67faSmbalmer else 4443eed67faSmbalmer 4453eed67faSmbalmer # Make a couple of temp file names in the proper directory. 4463eed67faSmbalmer dsttmp=$dstdir/_inst.$$_ 4473eed67faSmbalmer rmtmp=$dstdir/_rm.$$_ 4483eed67faSmbalmer 4493eed67faSmbalmer # Trap to clean up those temp files at exit. 4503eed67faSmbalmer trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4513eed67faSmbalmer 4523eed67faSmbalmer # Copy the file name to the temp name. 453dc407927Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4543eed67faSmbalmer 4553eed67faSmbalmer # and set any options; do chmod last to preserve setuid bits. 4563eed67faSmbalmer # 4573eed67faSmbalmer # If any of these fail, we abort the whole thing. If we want to 4583eed67faSmbalmer # ignore errors from any of these, just make sure not to ignore 4593eed67faSmbalmer # errors from the above "$doit $cpprog $src $dsttmp" command. 4603eed67faSmbalmer # 461dc407927Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 462dc407927Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 463dc407927Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 464dc407927Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 465dc407927Smrg 466dc407927Smrg # If -C, don't bother to copy if it wouldn't change the file. 467dc407927Smrg if $copy_on_change && 468dc407927Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 469dc407927Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 470dc407927Smrg 471dc407927Smrg eval "$initialize_posix_glob" && 472dc407927Smrg $posix_glob set -f && 473dc407927Smrg set X $old && old=:$2:$4:$5:$6 && 474dc407927Smrg set X $new && new=:$2:$4:$5:$6 && 475dc407927Smrg $posix_glob set +f && 476dc407927Smrg 477dc407927Smrg test "$old" = "$new" && 478dc407927Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 479dc407927Smrg then 480dc407927Smrg rm -f "$dsttmp" 481dc407927Smrg else 482dc407927Smrg # Rename the file to the real destination. 483dc407927Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 484dc407927Smrg 485dc407927Smrg # The rename failed, perhaps because mv can't rename something else 486dc407927Smrg # to itself, or perhaps because mv is so ancient that it does not 487dc407927Smrg # support -f. 488dc407927Smrg { 489dc407927Smrg # Now remove or move aside any old file at destination location. 490dc407927Smrg # We try this two ways since rm can't unlink itself on some 491dc407927Smrg # systems and the destination file might be busy for other 492dc407927Smrg # reasons. In this case, the final cleanup might fail but the new 493dc407927Smrg # file should still install successfully. 494dc407927Smrg { 495dc407927Smrg test ! -f "$dst" || 496dc407927Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 497dc407927Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 498dc407927Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 499dc407927Smrg } || 500dc407927Smrg { echo "$0: cannot unlink or rename $dst" >&2 501dc407927Smrg (exit 1); exit 1 502dc407927Smrg } 503dc407927Smrg } && 504dc407927Smrg 505dc407927Smrg # Now rename the file to the real destination. 506dc407927Smrg $doit $mvcmd "$dsttmp" "$dst" 507dc407927Smrg } 508dc407927Smrg fi || exit 1 509dc407927Smrg 510dc407927Smrg trap '' 0 511dc407927Smrg fi 5123eed67faSmbalmerdone 5133eed67faSmbalmer 5143eed67faSmbalmer# Local variables: 5153eed67faSmbalmer# eval: (add-hook 'write-file-hooks 'time-stamp) 5163eed67faSmbalmer# time-stamp-start: "scriptversion=" 5173eed67faSmbalmer# time-stamp-format: "%:y-%02m-%02d.%02H" 518dc407927Smrg# time-stamp-time-zone: "UTC" 519dc407927Smrg# time-stamp-end: "; # UTC" 5203eed67faSmbalmer# End: 521