install-sh revision e90eff46
167f05d30Smrg#!/bin/sh 267f05d30Smrg# install - install a program, script, or datafile 3fffe5102Smrg 4e90eff46Smrgscriptversion=2013-12-25.23; # UTC 5fffe5102Smrg 667f05d30Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 767f05d30Smrg# later released in X11R6 (xc/config/util/install.sh) with the 867f05d30Smrg# following copyright and license. 967f05d30Smrg# 1067f05d30Smrg# Copyright (C) 1994 X Consortium 1167f05d30Smrg# 1267f05d30Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 1367f05d30Smrg# of this software and associated documentation files (the "Software"), to 1467f05d30Smrg# deal in the Software without restriction, including without limitation the 1567f05d30Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1667f05d30Smrg# sell copies of the Software, and to permit persons to whom the Software is 1767f05d30Smrg# furnished to do so, subject to the following conditions: 1867f05d30Smrg# 1967f05d30Smrg# The above copyright notice and this permission notice shall be included in 2067f05d30Smrg# all copies or substantial portions of the Software. 2167f05d30Smrg# 2267f05d30Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2367f05d30Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2467f05d30Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2567f05d30Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2667f05d30Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2767f05d30Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2867f05d30Smrg# 2967f05d30Smrg# Except as contained in this notice, the name of the X Consortium shall not 3067f05d30Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 3167f05d30Smrg# ings in this Software without prior written authorization from the X Consor- 3267f05d30Smrg# tium. 3367f05d30Smrg# 3467f05d30Smrg# 3567f05d30Smrg# FSF changes to this file are in the public domain. 3667f05d30Smrg# 3767f05d30Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38e90eff46Smrg# 'make' implicit rules from creating a file called install from it 3967f05d30Smrg# when there is no Makefile. 4067f05d30Smrg# 4167f05d30Smrg# This script is compatible with the BSD install script, but was written 42fffe5102Smrg# from scratch. 4367f05d30Smrg 44e90eff46Smrgtab=' ' 45fffe5102Smrgnl=' 46fffe5102Smrg' 47e90eff46SmrgIFS=" $tab$nl" 4867f05d30Smrg 49e90eff46Smrg# Set DOITPROG to "echo" to test this script. 5067f05d30Smrg 51fffe5102Smrgdoit=${DOITPROG-} 52e90eff46Smrgdoit_exec=${doit:-exec} 5367f05d30Smrg 54fffe5102Smrg# Put in absolute file names if you don't have them in your path; 55fffe5102Smrg# or use environment vars. 56fffe5102Smrg 57fffe5102Smrgchgrpprog=${CHGRPPROG-chgrp} 58fffe5102Smrgchmodprog=${CHMODPROG-chmod} 59fffe5102Smrgchownprog=${CHOWNPROG-chown} 60fffe5102Smrgcmpprog=${CMPPROG-cmp} 61fffe5102Smrgcpprog=${CPPROG-cp} 62fffe5102Smrgmkdirprog=${MKDIRPROG-mkdir} 63fffe5102Smrgmvprog=${MVPROG-mv} 64fffe5102Smrgrmprog=${RMPROG-rm} 65fffe5102Smrgstripprog=${STRIPPROG-strip} 66fffe5102Smrg 67fffe5102Smrgposix_mkdir= 68fffe5102Smrg 69fffe5102Smrg# Desired mode of installed file. 70fffe5102Smrgmode=0755 71fffe5102Smrg 72fffe5102Smrgchgrpcmd= 73fffe5102Smrgchmodcmd=$chmodprog 74fffe5102Smrgchowncmd= 75fffe5102Smrgmvcmd=$mvprog 76fffe5102Smrgrmcmd="$rmprog -f" 77fffe5102Smrgstripcmd= 7867f05d30Smrg 79fffe5102Smrgsrc= 80fffe5102Smrgdst= 81fffe5102Smrgdir_arg= 82fffe5102Smrgdst_arg= 8367f05d30Smrg 84fffe5102Smrgcopy_on_change=false 85e90eff46Smrgis_target_a_directory=possibly 8667f05d30Smrg 87fffe5102Smrgusage="\ 88fffe5102SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89fffe5102Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 90fffe5102Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91fffe5102Smrg or: $0 [OPTION]... -d DIRECTORIES... 9267f05d30Smrg 93fffe5102SmrgIn the 1st form, copy SRCFILE to DSTFILE. 94fffe5102SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95fffe5102SmrgIn the 4th, create DIRECTORIES. 9667f05d30Smrg 97fffe5102SmrgOptions: 98fffe5102Smrg --help display this help and exit. 99fffe5102Smrg --version display version info and exit. 10067f05d30Smrg 101fffe5102Smrg -c (ignored) 102fffe5102Smrg -C install only if different (preserve the last data modification time) 103fffe5102Smrg -d create directories instead of installing files. 104fffe5102Smrg -g GROUP $chgrpprog installed files to GROUP. 105fffe5102Smrg -m MODE $chmodprog installed files to MODE. 106fffe5102Smrg -o USER $chownprog installed files to USER. 107fffe5102Smrg -s $stripprog installed files. 108fffe5102Smrg -t DIRECTORY install into DIRECTORY. 109fffe5102Smrg -T report an error if DSTFILE is a directory. 11067f05d30Smrg 111fffe5102SmrgEnvironment variables override the default commands: 112fffe5102Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113fffe5102Smrg RMPROG STRIPPROG 114fffe5102Smrg" 11567f05d30Smrg 116fffe5102Smrgwhile test $# -ne 0; do 117fffe5102Smrg case $1 in 118fffe5102Smrg -c) ;; 11967f05d30Smrg 120fffe5102Smrg -C) copy_on_change=true;; 12167f05d30Smrg 122fffe5102Smrg -d) dir_arg=true;; 12367f05d30Smrg 124fffe5102Smrg -g) chgrpcmd="$chgrpprog $2" 125e90eff46Smrg shift;; 12667f05d30Smrg 127fffe5102Smrg --help) echo "$usage"; exit $?;; 12867f05d30Smrg 129fffe5102Smrg -m) mode=$2 130e90eff46Smrg case $mode in 131e90eff46Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132e90eff46Smrg echo "$0: invalid mode: $mode" >&2 133e90eff46Smrg exit 1;; 134e90eff46Smrg esac 135e90eff46Smrg shift;; 13667f05d30Smrg 137fffe5102Smrg -o) chowncmd="$chownprog $2" 138e90eff46Smrg shift;; 13967f05d30Smrg 140fffe5102Smrg -s) stripcmd=$stripprog;; 14167f05d30Smrg 142e90eff46Smrg -t) 143e90eff46Smrg is_target_a_directory=always 144e90eff46Smrg dst_arg=$2 145e90eff46Smrg # Protect names problematic for 'test' and other utilities. 146e90eff46Smrg case $dst_arg in 147e90eff46Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 148e90eff46Smrg esac 149e90eff46Smrg shift;; 15067f05d30Smrg 151e90eff46Smrg -T) is_target_a_directory=never;; 15267f05d30Smrg 153fffe5102Smrg --version) echo "$0 $scriptversion"; exit $?;; 15467f05d30Smrg 155e90eff46Smrg --) shift 156e90eff46Smrg break;; 15767f05d30Smrg 158e90eff46Smrg -*) echo "$0: invalid option: $1" >&2 159e90eff46Smrg exit 1;; 16067f05d30Smrg 161fffe5102Smrg *) break;; 162fffe5102Smrg esac 163fffe5102Smrg shift 164fffe5102Smrgdone 16567f05d30Smrg 166e90eff46Smrg# We allow the use of options -d and -T together, by making -d 167e90eff46Smrg# take the precedence; this is for compatibility with GNU install. 168e90eff46Smrg 169e90eff46Smrgif test -n "$dir_arg"; then 170e90eff46Smrg if test -n "$dst_arg"; then 171e90eff46Smrg echo "$0: target directory not allowed when installing a directory." >&2 172e90eff46Smrg exit 1 173e90eff46Smrg fi 174e90eff46Smrgfi 175e90eff46Smrg 176fffe5102Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177fffe5102Smrg # When -d is used, all remaining arguments are directories to create. 178fffe5102Smrg # When -t is used, the destination is already specified. 179fffe5102Smrg # Otherwise, the last argument is the destination. Remove it from $@. 180fffe5102Smrg for arg 181fffe5102Smrg do 182fffe5102Smrg if test -n "$dst_arg"; then 183fffe5102Smrg # $@ is not empty: it contains at least $arg. 184fffe5102Smrg set fnord "$@" "$dst_arg" 185fffe5102Smrg shift # fnord 186fffe5102Smrg fi 187fffe5102Smrg shift # arg 188fffe5102Smrg dst_arg=$arg 189e90eff46Smrg # Protect names problematic for 'test' and other utilities. 1906dbd43aaSmrg case $dst_arg in 1916dbd43aaSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1926dbd43aaSmrg esac 193fffe5102Smrg done 194fffe5102Smrgfi 19567f05d30Smrg 196fffe5102Smrgif test $# -eq 0; then 197fffe5102Smrg if test -z "$dir_arg"; then 198fffe5102Smrg echo "$0: no input file specified." >&2 199fffe5102Smrg exit 1 200fffe5102Smrg fi 201e90eff46Smrg # It's OK to call 'install-sh -d' without argument. 202fffe5102Smrg # This can happen when creating conditional directories. 203fffe5102Smrg exit 0 204fffe5102Smrgfi 20567f05d30Smrg 206e90eff46Smrgif test -z "$dir_arg"; then 207e90eff46Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 208e90eff46Smrg if test ! -d "$dst_arg"; then 209e90eff46Smrg echo "$0: $dst_arg: Is not a directory." >&2 210e90eff46Smrg exit 1 211e90eff46Smrg fi 212e90eff46Smrg fi 213e90eff46Smrgfi 214e90eff46Smrg 215fffe5102Smrgif test -z "$dir_arg"; then 2166dbd43aaSmrg do_exit='(exit $ret); exit $ret' 2176dbd43aaSmrg trap "ret=129; $do_exit" 1 2186dbd43aaSmrg trap "ret=130; $do_exit" 2 2196dbd43aaSmrg trap "ret=141; $do_exit" 13 2206dbd43aaSmrg trap "ret=143; $do_exit" 15 221fffe5102Smrg 222fffe5102Smrg # Set umask so as not to create temps with too-generous modes. 223fffe5102Smrg # However, 'strip' requires both read and write access to temps. 224fffe5102Smrg case $mode in 225fffe5102Smrg # Optimize common cases. 226fffe5102Smrg *644) cp_umask=133;; 227fffe5102Smrg *755) cp_umask=22;; 228fffe5102Smrg 229fffe5102Smrg *[0-7]) 230fffe5102Smrg if test -z "$stripcmd"; then 231e90eff46Smrg u_plus_rw= 232fffe5102Smrg else 233e90eff46Smrg u_plus_rw='% 200' 234fffe5102Smrg fi 235fffe5102Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236fffe5102Smrg *) 237fffe5102Smrg if test -z "$stripcmd"; then 238e90eff46Smrg u_plus_rw= 239fffe5102Smrg else 240e90eff46Smrg u_plus_rw=,u+rw 241fffe5102Smrg fi 242fffe5102Smrg cp_umask=$mode$u_plus_rw;; 243fffe5102Smrg esac 244fffe5102Smrgfi 24567f05d30Smrg 246fffe5102Smrgfor src 247fffe5102Smrgdo 248e90eff46Smrg # Protect names problematic for 'test' and other utilities. 249fffe5102Smrg case $src in 2506dbd43aaSmrg -* | [=\(\)!]) src=./$src;; 251fffe5102Smrg esac 252fffe5102Smrg 253fffe5102Smrg if test -n "$dir_arg"; then 254fffe5102Smrg dst=$src 255fffe5102Smrg dstdir=$dst 256fffe5102Smrg test -d "$dstdir" 257fffe5102Smrg dstdir_status=$? 258fffe5102Smrg else 259fffe5102Smrg 260fffe5102Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261fffe5102Smrg # might cause directories to be created, which would be especially bad 262fffe5102Smrg # if $src (and thus $dsttmp) contains '*'. 263fffe5102Smrg if test ! -f "$src" && test ! -d "$src"; then 264fffe5102Smrg echo "$0: $src does not exist." >&2 265fffe5102Smrg exit 1 266fffe5102Smrg fi 267fffe5102Smrg 268fffe5102Smrg if test -z "$dst_arg"; then 269fffe5102Smrg echo "$0: no destination specified." >&2 270fffe5102Smrg exit 1 271fffe5102Smrg fi 272fffe5102Smrg dst=$dst_arg 27367f05d30Smrg 274fffe5102Smrg # If destination is a directory, append the input filename; won't work 275fffe5102Smrg # if double slashes aren't ignored. 276fffe5102Smrg if test -d "$dst"; then 277e90eff46Smrg if test "$is_target_a_directory" = never; then 278e90eff46Smrg echo "$0: $dst_arg: Is a directory" >&2 279e90eff46Smrg exit 1 280fffe5102Smrg fi 281fffe5102Smrg dstdir=$dst 282fffe5102Smrg dst=$dstdir/`basename "$src"` 283fffe5102Smrg dstdir_status=0 284fffe5102Smrg else 285e90eff46Smrg dstdir=`dirname "$dst"` 286fffe5102Smrg test -d "$dstdir" 287fffe5102Smrg dstdir_status=$? 288fffe5102Smrg fi 289fffe5102Smrg fi 290fffe5102Smrg 291fffe5102Smrg obsolete_mkdir_used=false 292fffe5102Smrg 293fffe5102Smrg if test $dstdir_status != 0; then 294fffe5102Smrg case $posix_mkdir in 295fffe5102Smrg '') 296e90eff46Smrg # Create intermediate dirs using mode 755 as modified by the umask. 297e90eff46Smrg # This is like FreeBSD 'install' as of 1997-10-28. 298e90eff46Smrg umask=`umask` 299e90eff46Smrg case $stripcmd.$umask in 300e90eff46Smrg # Optimize common cases. 301e90eff46Smrg *[2367][2367]) mkdir_umask=$umask;; 302e90eff46Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303e90eff46Smrg 304e90eff46Smrg *[0-7]) 305e90eff46Smrg mkdir_umask=`expr $umask + 22 \ 306e90eff46Smrg - $umask % 100 % 40 + $umask % 20 \ 307e90eff46Smrg - $umask % 10 % 4 + $umask % 2 308e90eff46Smrg `;; 309e90eff46Smrg *) mkdir_umask=$umask,go-w;; 310e90eff46Smrg esac 311e90eff46Smrg 312e90eff46Smrg # With -d, create the new directory with the user-specified mode. 313e90eff46Smrg # Otherwise, rely on $mkdir_umask. 314e90eff46Smrg if test -n "$dir_arg"; then 315e90eff46Smrg mkdir_mode=-m$mode 316e90eff46Smrg else 317e90eff46Smrg mkdir_mode= 318e90eff46Smrg fi 319e90eff46Smrg 320e90eff46Smrg posix_mkdir=false 321e90eff46Smrg case $umask in 322e90eff46Smrg *[123567][0-7][0-7]) 323e90eff46Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 324e90eff46Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325e90eff46Smrg ;; 326e90eff46Smrg *) 327e90eff46Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 328e90eff46Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 329e90eff46Smrg 330e90eff46Smrg if (umask $mkdir_umask && 331e90eff46Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 332e90eff46Smrg then 333e90eff46Smrg if test -z "$dir_arg" || { 334e90eff46Smrg # Check for POSIX incompatibilities with -m. 335e90eff46Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 336e90eff46Smrg # other-writable bit of parent directory when it shouldn't. 337e90eff46Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 338e90eff46Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 339e90eff46Smrg case $ls_ld_tmpdir in 340e90eff46Smrg d????-?r-*) different_mode=700;; 341e90eff46Smrg d????-?--*) different_mode=755;; 342e90eff46Smrg *) false;; 343e90eff46Smrg esac && 344e90eff46Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 345e90eff46Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 346e90eff46Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 347e90eff46Smrg } 348e90eff46Smrg } 349e90eff46Smrg then posix_mkdir=: 350e90eff46Smrg fi 351e90eff46Smrg rmdir "$tmpdir/d" "$tmpdir" 352e90eff46Smrg else 353e90eff46Smrg # Remove any dirs left behind by ancient mkdir implementations. 354e90eff46Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 355e90eff46Smrg fi 356e90eff46Smrg trap '' 0;; 357e90eff46Smrg esac;; 358fffe5102Smrg esac 35967f05d30Smrg 360fffe5102Smrg if 361fffe5102Smrg $posix_mkdir && ( 362e90eff46Smrg umask $mkdir_umask && 363e90eff46Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 364fffe5102Smrg ) 365fffe5102Smrg then : 366fffe5102Smrg else 367fffe5102Smrg 368fffe5102Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 369fffe5102Smrg # or it failed possibly due to a race condition. Create the 370fffe5102Smrg # directory the slow way, step by step, checking for races as we go. 371fffe5102Smrg 372fffe5102Smrg case $dstdir in 373e90eff46Smrg /*) prefix='/';; 374e90eff46Smrg [-=\(\)!]*) prefix='./';; 375e90eff46Smrg *) prefix='';; 376fffe5102Smrg esac 377fffe5102Smrg 378fffe5102Smrg oIFS=$IFS 379fffe5102Smrg IFS=/ 380e90eff46Smrg set -f 381fffe5102Smrg set fnord $dstdir 382fffe5102Smrg shift 383e90eff46Smrg set +f 384fffe5102Smrg IFS=$oIFS 385fffe5102Smrg 386fffe5102Smrg prefixes= 387fffe5102Smrg 388fffe5102Smrg for d 389fffe5102Smrg do 390e90eff46Smrg test X"$d" = X && continue 391e90eff46Smrg 392e90eff46Smrg prefix=$prefix$d 393e90eff46Smrg if test -d "$prefix"; then 394e90eff46Smrg prefixes= 395e90eff46Smrg else 396e90eff46Smrg if $posix_mkdir; then 397e90eff46Smrg (umask=$mkdir_umask && 398e90eff46Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 399e90eff46Smrg # Don't fail if two instances are running concurrently. 400e90eff46Smrg test -d "$prefix" || exit 1 401e90eff46Smrg else 402e90eff46Smrg case $prefix in 403e90eff46Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 404e90eff46Smrg *) qprefix=$prefix;; 405e90eff46Smrg esac 406e90eff46Smrg prefixes="$prefixes '$qprefix'" 407e90eff46Smrg fi 408e90eff46Smrg fi 409e90eff46Smrg prefix=$prefix/ 410fffe5102Smrg done 411fffe5102Smrg 412fffe5102Smrg if test -n "$prefixes"; then 413e90eff46Smrg # Don't fail if two instances are running concurrently. 414e90eff46Smrg (umask $mkdir_umask && 415e90eff46Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 416e90eff46Smrg test -d "$dstdir" || exit 1 417e90eff46Smrg obsolete_mkdir_used=true 418fffe5102Smrg fi 419fffe5102Smrg fi 420fffe5102Smrg fi 421fffe5102Smrg 422fffe5102Smrg if test -n "$dir_arg"; then 423fffe5102Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 424fffe5102Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 425fffe5102Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 426fffe5102Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 427fffe5102Smrg else 428fffe5102Smrg 429fffe5102Smrg # Make a couple of temp file names in the proper directory. 430fffe5102Smrg dsttmp=$dstdir/_inst.$$_ 431fffe5102Smrg rmtmp=$dstdir/_rm.$$_ 432fffe5102Smrg 433fffe5102Smrg # Trap to clean up those temp files at exit. 434fffe5102Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 435fffe5102Smrg 436fffe5102Smrg # Copy the file name to the temp name. 437fffe5102Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 438fffe5102Smrg 439fffe5102Smrg # and set any options; do chmod last to preserve setuid bits. 440fffe5102Smrg # 441fffe5102Smrg # If any of these fail, we abort the whole thing. If we want to 442fffe5102Smrg # ignore errors from any of these, just make sure not to ignore 443fffe5102Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 444fffe5102Smrg # 445fffe5102Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 446fffe5102Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 447fffe5102Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 448fffe5102Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 449fffe5102Smrg 450fffe5102Smrg # If -C, don't bother to copy if it wouldn't change the file. 451fffe5102Smrg if $copy_on_change && 452e90eff46Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 453e90eff46Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 454e90eff46Smrg set -f && 455fffe5102Smrg set X $old && old=:$2:$4:$5:$6 && 456fffe5102Smrg set X $new && new=:$2:$4:$5:$6 && 457e90eff46Smrg set +f && 458fffe5102Smrg test "$old" = "$new" && 459fffe5102Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 460fffe5102Smrg then 461fffe5102Smrg rm -f "$dsttmp" 462fffe5102Smrg else 463fffe5102Smrg # Rename the file to the real destination. 464fffe5102Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 465fffe5102Smrg 466fffe5102Smrg # The rename failed, perhaps because mv can't rename something else 467fffe5102Smrg # to itself, or perhaps because mv is so ancient that it does not 468fffe5102Smrg # support -f. 469fffe5102Smrg { 470e90eff46Smrg # Now remove or move aside any old file at destination location. 471e90eff46Smrg # We try this two ways since rm can't unlink itself on some 472e90eff46Smrg # systems and the destination file might be busy for other 473e90eff46Smrg # reasons. In this case, the final cleanup might fail but the new 474e90eff46Smrg # file should still install successfully. 475e90eff46Smrg { 476e90eff46Smrg test ! -f "$dst" || 477e90eff46Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 478e90eff46Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 479e90eff46Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 480e90eff46Smrg } || 481e90eff46Smrg { echo "$0: cannot unlink or rename $dst" >&2 482e90eff46Smrg (exit 1); exit 1 483e90eff46Smrg } 484e90eff46Smrg } && 485e90eff46Smrg 486e90eff46Smrg # Now rename the file to the real destination. 487e90eff46Smrg $doit $mvcmd "$dsttmp" "$dst" 488fffe5102Smrg } 489fffe5102Smrg fi || exit 1 490fffe5102Smrg 491fffe5102Smrg trap '' 0 492fffe5102Smrg fi 493fffe5102Smrgdone 49467f05d30Smrg 495fffe5102Smrg# Local variables: 496fffe5102Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 497fffe5102Smrg# time-stamp-start: "scriptversion=" 498fffe5102Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 499fffe5102Smrg# time-stamp-time-zone: "UTC" 500fffe5102Smrg# time-stamp-end: "; # UTC" 501fffe5102Smrg# End: 502