install-sh revision 485f0483
1caade7ccSmrg#!/bin/sh 2caade7ccSmrg# install - install a program, script, or datafile 3caade7ccSmrg 4485f0483Smrgscriptversion=2009-04-28.21; # UTC 5caade7ccSmrg 6caade7ccSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7caade7ccSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8caade7ccSmrg# following copyright and license. 9caade7ccSmrg# 10caade7ccSmrg# Copyright (C) 1994 X Consortium 11caade7ccSmrg# 12caade7ccSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13caade7ccSmrg# of this software and associated documentation files (the "Software"), to 14caade7ccSmrg# deal in the Software without restriction, including without limitation the 15caade7ccSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16caade7ccSmrg# sell copies of the Software, and to permit persons to whom the Software is 17caade7ccSmrg# furnished to do so, subject to the following conditions: 18caade7ccSmrg# 19caade7ccSmrg# The above copyright notice and this permission notice shall be included in 20caade7ccSmrg# all copies or substantial portions of the Software. 21caade7ccSmrg# 22caade7ccSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23caade7ccSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24caade7ccSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25caade7ccSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26caade7ccSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27caade7ccSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28caade7ccSmrg# 29caade7ccSmrg# Except as contained in this notice, the name of the X Consortium shall not 30caade7ccSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31caade7ccSmrg# ings in this Software without prior written authorization from the X Consor- 32caade7ccSmrg# tium. 33caade7ccSmrg# 34caade7ccSmrg# 35caade7ccSmrg# FSF changes to this file are in the public domain. 36caade7ccSmrg# 37caade7ccSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38caade7ccSmrg# `make' implicit rules from creating a file called install from it 39caade7ccSmrg# when there is no Makefile. 40caade7ccSmrg# 41caade7ccSmrg# This script is compatible with the BSD install script, but was written 42caade7ccSmrg# from scratch. 43caade7ccSmrg 44caade7ccSmrgnl=' 45caade7ccSmrg' 46caade7ccSmrgIFS=" "" $nl" 47caade7ccSmrg 48caade7ccSmrg# set DOITPROG to echo to test this script 49caade7ccSmrg 50caade7ccSmrg# Don't use :- since 4.3BSD and earlier shells don't like it. 51485f0483Smrgdoit=${DOITPROG-} 52caade7ccSmrgif test -z "$doit"; then 53caade7ccSmrg doit_exec=exec 54caade7ccSmrgelse 55caade7ccSmrg doit_exec=$doit 56caade7ccSmrgfi 57caade7ccSmrg 58caade7ccSmrg# Put in absolute file names if you don't have them in your path; 59caade7ccSmrg# or use environment vars. 60caade7ccSmrg 61485f0483Smrgchgrpprog=${CHGRPPROG-chgrp} 62485f0483Smrgchmodprog=${CHMODPROG-chmod} 63485f0483Smrgchownprog=${CHOWNPROG-chown} 64485f0483Smrgcmpprog=${CMPPROG-cmp} 65485f0483Smrgcpprog=${CPPROG-cp} 66485f0483Smrgmkdirprog=${MKDIRPROG-mkdir} 67485f0483Smrgmvprog=${MVPROG-mv} 68485f0483Smrgrmprog=${RMPROG-rm} 69485f0483Smrgstripprog=${STRIPPROG-strip} 70485f0483Smrg 71485f0483Smrgposix_glob='?' 72485f0483Smrginitialize_posix_glob=' 73485f0483Smrg test "$posix_glob" != "?" || { 74485f0483Smrg if (set -f) 2>/dev/null; then 75485f0483Smrg posix_glob= 76485f0483Smrg else 77485f0483Smrg posix_glob=: 78485f0483Smrg fi 79485f0483Smrg } 80485f0483Smrg' 81caade7ccSmrg 82caade7ccSmrgposix_mkdir= 83caade7ccSmrg 84caade7ccSmrg# Desired mode of installed file. 85caade7ccSmrgmode=0755 86caade7ccSmrg 87485f0483Smrgchgrpcmd= 88caade7ccSmrgchmodcmd=$chmodprog 89caade7ccSmrgchowncmd= 90485f0483Smrgmvcmd=$mvprog 91caade7ccSmrgrmcmd="$rmprog -f" 92485f0483Smrgstripcmd= 93485f0483Smrg 94caade7ccSmrgsrc= 95caade7ccSmrgdst= 96caade7ccSmrgdir_arg= 97485f0483Smrgdst_arg= 98485f0483Smrg 99485f0483Smrgcopy_on_change=false 100caade7ccSmrgno_target_directory= 101caade7ccSmrg 102485f0483Smrgusage="\ 103485f0483SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 104caade7ccSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 105caade7ccSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 106caade7ccSmrg or: $0 [OPTION]... -d DIRECTORIES... 107caade7ccSmrg 108caade7ccSmrgIn the 1st form, copy SRCFILE to DSTFILE. 109caade7ccSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 110caade7ccSmrgIn the 4th, create DIRECTORIES. 111caade7ccSmrg 112caade7ccSmrgOptions: 113485f0483Smrg --help display this help and exit. 114485f0483Smrg --version display version info and exit. 115485f0483Smrg 116485f0483Smrg -c (ignored) 117485f0483Smrg -C install only if different (preserve the last data modification time) 118485f0483Smrg -d create directories instead of installing files. 119485f0483Smrg -g GROUP $chgrpprog installed files to GROUP. 120485f0483Smrg -m MODE $chmodprog installed files to MODE. 121485f0483Smrg -o USER $chownprog installed files to USER. 122485f0483Smrg -s $stripprog installed files. 123485f0483Smrg -t DIRECTORY install into DIRECTORY. 124485f0483Smrg -T report an error if DSTFILE is a directory. 125caade7ccSmrg 126caade7ccSmrgEnvironment variables override the default commands: 127485f0483Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 128485f0483Smrg RMPROG STRIPPROG 129caade7ccSmrg" 130caade7ccSmrg 131caade7ccSmrgwhile test $# -ne 0; do 132caade7ccSmrg case $1 in 133485f0483Smrg -c) ;; 134485f0483Smrg 135485f0483Smrg -C) copy_on_change=true;; 136caade7ccSmrg 137485f0483Smrg -d) dir_arg=true;; 138caade7ccSmrg 139caade7ccSmrg -g) chgrpcmd="$chgrpprog $2" 140485f0483Smrg shift;; 141caade7ccSmrg 142caade7ccSmrg --help) echo "$usage"; exit $?;; 143caade7ccSmrg 144caade7ccSmrg -m) mode=$2 145caade7ccSmrg case $mode in 146caade7ccSmrg *' '* | *' '* | *' 147caade7ccSmrg'* | *'*'* | *'?'* | *'['*) 148caade7ccSmrg echo "$0: invalid mode: $mode" >&2 149caade7ccSmrg exit 1;; 150caade7ccSmrg esac 151485f0483Smrg shift;; 152caade7ccSmrg 153caade7ccSmrg -o) chowncmd="$chownprog $2" 154485f0483Smrg shift;; 155caade7ccSmrg 156485f0483Smrg -s) stripcmd=$stripprog;; 157caade7ccSmrg 158485f0483Smrg -t) dst_arg=$2 159485f0483Smrg shift;; 160caade7ccSmrg 161485f0483Smrg -T) no_target_directory=true;; 162caade7ccSmrg 163caade7ccSmrg --version) echo "$0 $scriptversion"; exit $?;; 164caade7ccSmrg 165caade7ccSmrg --) shift 166caade7ccSmrg break;; 167caade7ccSmrg 168caade7ccSmrg -*) echo "$0: invalid option: $1" >&2 169caade7ccSmrg exit 1;; 170caade7ccSmrg 171caade7ccSmrg *) break;; 172caade7ccSmrg esac 173485f0483Smrg shift 174caade7ccSmrgdone 175caade7ccSmrg 176485f0483Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177caade7ccSmrg # When -d is used, all remaining arguments are directories to create. 178caade7ccSmrg # When -t is used, the destination is already specified. 179caade7ccSmrg # Otherwise, the last argument is the destination. Remove it from $@. 180caade7ccSmrg for arg 181caade7ccSmrg do 182485f0483Smrg if test -n "$dst_arg"; then 183caade7ccSmrg # $@ is not empty: it contains at least $arg. 184485f0483Smrg set fnord "$@" "$dst_arg" 185caade7ccSmrg shift # fnord 186caade7ccSmrg fi 187caade7ccSmrg shift # arg 188485f0483Smrg dst_arg=$arg 189caade7ccSmrg done 190caade7ccSmrgfi 191caade7ccSmrg 192caade7ccSmrgif test $# -eq 0; then 193caade7ccSmrg if test -z "$dir_arg"; then 194caade7ccSmrg echo "$0: no input file specified." >&2 195caade7ccSmrg exit 1 196caade7ccSmrg fi 197caade7ccSmrg # It's OK to call `install-sh -d' without argument. 198caade7ccSmrg # This can happen when creating conditional directories. 199caade7ccSmrg exit 0 200caade7ccSmrgfi 201caade7ccSmrg 202caade7ccSmrgif test -z "$dir_arg"; then 203caade7ccSmrg trap '(exit $?); exit' 1 2 13 15 204caade7ccSmrg 205caade7ccSmrg # Set umask so as not to create temps with too-generous modes. 206caade7ccSmrg # However, 'strip' requires both read and write access to temps. 207caade7ccSmrg case $mode in 208caade7ccSmrg # Optimize common cases. 209caade7ccSmrg *644) cp_umask=133;; 210caade7ccSmrg *755) cp_umask=22;; 211caade7ccSmrg 212caade7ccSmrg *[0-7]) 213caade7ccSmrg if test -z "$stripcmd"; then 214caade7ccSmrg u_plus_rw= 215caade7ccSmrg else 216caade7ccSmrg u_plus_rw='% 200' 217caade7ccSmrg fi 218caade7ccSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 219caade7ccSmrg *) 220caade7ccSmrg if test -z "$stripcmd"; then 221caade7ccSmrg u_plus_rw= 222caade7ccSmrg else 223caade7ccSmrg u_plus_rw=,u+rw 224caade7ccSmrg fi 225caade7ccSmrg cp_umask=$mode$u_plus_rw;; 226caade7ccSmrg esac 227caade7ccSmrgfi 228caade7ccSmrg 229caade7ccSmrgfor src 230caade7ccSmrgdo 231caade7ccSmrg # Protect names starting with `-'. 232caade7ccSmrg case $src in 233485f0483Smrg -*) src=./$src;; 234caade7ccSmrg esac 235caade7ccSmrg 236caade7ccSmrg if test -n "$dir_arg"; then 237caade7ccSmrg dst=$src 238caade7ccSmrg dstdir=$dst 239caade7ccSmrg test -d "$dstdir" 240caade7ccSmrg dstdir_status=$? 241caade7ccSmrg else 242caade7ccSmrg 243caade7ccSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 244caade7ccSmrg # might cause directories to be created, which would be especially bad 245caade7ccSmrg # if $src (and thus $dsttmp) contains '*'. 246caade7ccSmrg if test ! -f "$src" && test ! -d "$src"; then 247caade7ccSmrg echo "$0: $src does not exist." >&2 248caade7ccSmrg exit 1 249caade7ccSmrg fi 250caade7ccSmrg 251485f0483Smrg if test -z "$dst_arg"; then 252caade7ccSmrg echo "$0: no destination specified." >&2 253caade7ccSmrg exit 1 254caade7ccSmrg fi 255caade7ccSmrg 256485f0483Smrg dst=$dst_arg 257caade7ccSmrg # Protect names starting with `-'. 258caade7ccSmrg case $dst in 259485f0483Smrg -*) dst=./$dst;; 260caade7ccSmrg esac 261caade7ccSmrg 262caade7ccSmrg # If destination is a directory, append the input filename; won't work 263caade7ccSmrg # if double slashes aren't ignored. 264caade7ccSmrg if test -d "$dst"; then 265caade7ccSmrg if test -n "$no_target_directory"; then 266485f0483Smrg echo "$0: $dst_arg: Is a directory" >&2 267caade7ccSmrg exit 1 268caade7ccSmrg fi 269caade7ccSmrg dstdir=$dst 270caade7ccSmrg dst=$dstdir/`basename "$src"` 271caade7ccSmrg dstdir_status=0 272caade7ccSmrg else 273caade7ccSmrg # Prefer dirname, but fall back on a substitute if dirname fails. 274caade7ccSmrg dstdir=` 275caade7ccSmrg (dirname "$dst") 2>/dev/null || 276caade7ccSmrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 277caade7ccSmrg X"$dst" : 'X\(//\)[^/]' \| \ 278caade7ccSmrg X"$dst" : 'X\(//\)$' \| \ 279caade7ccSmrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 280caade7ccSmrg echo X"$dst" | 281caade7ccSmrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 282caade7ccSmrg s//\1/ 283caade7ccSmrg q 284caade7ccSmrg } 285caade7ccSmrg /^X\(\/\/\)[^/].*/{ 286caade7ccSmrg s//\1/ 287caade7ccSmrg q 288caade7ccSmrg } 289caade7ccSmrg /^X\(\/\/\)$/{ 290caade7ccSmrg s//\1/ 291caade7ccSmrg q 292caade7ccSmrg } 293caade7ccSmrg /^X\(\/\).*/{ 294caade7ccSmrg s//\1/ 295caade7ccSmrg q 296caade7ccSmrg } 297caade7ccSmrg s/.*/./; q' 298caade7ccSmrg ` 299caade7ccSmrg 300caade7ccSmrg test -d "$dstdir" 301caade7ccSmrg dstdir_status=$? 302caade7ccSmrg fi 303caade7ccSmrg fi 304caade7ccSmrg 305caade7ccSmrg obsolete_mkdir_used=false 306caade7ccSmrg 307caade7ccSmrg if test $dstdir_status != 0; then 308caade7ccSmrg case $posix_mkdir in 309caade7ccSmrg '') 310caade7ccSmrg # Create intermediate dirs using mode 755 as modified by the umask. 311caade7ccSmrg # This is like FreeBSD 'install' as of 1997-10-28. 312caade7ccSmrg umask=`umask` 313caade7ccSmrg case $stripcmd.$umask in 314caade7ccSmrg # Optimize common cases. 315caade7ccSmrg *[2367][2367]) mkdir_umask=$umask;; 316caade7ccSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 317caade7ccSmrg 318caade7ccSmrg *[0-7]) 319caade7ccSmrg mkdir_umask=`expr $umask + 22 \ 320caade7ccSmrg - $umask % 100 % 40 + $umask % 20 \ 321caade7ccSmrg - $umask % 10 % 4 + $umask % 2 322caade7ccSmrg `;; 323caade7ccSmrg *) mkdir_umask=$umask,go-w;; 324caade7ccSmrg esac 325caade7ccSmrg 326caade7ccSmrg # With -d, create the new directory with the user-specified mode. 327caade7ccSmrg # Otherwise, rely on $mkdir_umask. 328caade7ccSmrg if test -n "$dir_arg"; then 329caade7ccSmrg mkdir_mode=-m$mode 330caade7ccSmrg else 331caade7ccSmrg mkdir_mode= 332caade7ccSmrg fi 333caade7ccSmrg 334caade7ccSmrg posix_mkdir=false 335caade7ccSmrg case $umask in 336caade7ccSmrg *[123567][0-7][0-7]) 337caade7ccSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 338caade7ccSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 339caade7ccSmrg ;; 340caade7ccSmrg *) 341caade7ccSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 342caade7ccSmrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 343caade7ccSmrg 344caade7ccSmrg if (umask $mkdir_umask && 345caade7ccSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 346caade7ccSmrg then 347caade7ccSmrg if test -z "$dir_arg" || { 348caade7ccSmrg # Check for POSIX incompatibilities with -m. 349caade7ccSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 350caade7ccSmrg # other-writeable bit of parent directory when it shouldn't. 351caade7ccSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 352caade7ccSmrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 353caade7ccSmrg case $ls_ld_tmpdir in 354caade7ccSmrg d????-?r-*) different_mode=700;; 355caade7ccSmrg d????-?--*) different_mode=755;; 356caade7ccSmrg *) false;; 357caade7ccSmrg esac && 358caade7ccSmrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 359caade7ccSmrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 360caade7ccSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 361caade7ccSmrg } 362caade7ccSmrg } 363caade7ccSmrg then posix_mkdir=: 364caade7ccSmrg fi 365caade7ccSmrg rmdir "$tmpdir/d" "$tmpdir" 366caade7ccSmrg else 367caade7ccSmrg # Remove any dirs left behind by ancient mkdir implementations. 368caade7ccSmrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 369caade7ccSmrg fi 370caade7ccSmrg trap '' 0;; 371caade7ccSmrg esac;; 372caade7ccSmrg esac 373caade7ccSmrg 374caade7ccSmrg if 375caade7ccSmrg $posix_mkdir && ( 376caade7ccSmrg umask $mkdir_umask && 377caade7ccSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 378caade7ccSmrg ) 379caade7ccSmrg then : 380caade7ccSmrg else 381caade7ccSmrg 382caade7ccSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 383caade7ccSmrg # or it failed possibly due to a race condition. Create the 384caade7ccSmrg # directory the slow way, step by step, checking for races as we go. 385caade7ccSmrg 386caade7ccSmrg case $dstdir in 387485f0483Smrg /*) prefix='/';; 388485f0483Smrg -*) prefix='./';; 389485f0483Smrg *) prefix='';; 390caade7ccSmrg esac 391caade7ccSmrg 392485f0483Smrg eval "$initialize_posix_glob" 393caade7ccSmrg 394caade7ccSmrg oIFS=$IFS 395caade7ccSmrg IFS=/ 396485f0483Smrg $posix_glob set -f 397caade7ccSmrg set fnord $dstdir 398caade7ccSmrg shift 399485f0483Smrg $posix_glob set +f 400caade7ccSmrg IFS=$oIFS 401caade7ccSmrg 402caade7ccSmrg prefixes= 403caade7ccSmrg 404caade7ccSmrg for d 405caade7ccSmrg do 406caade7ccSmrg test -z "$d" && continue 407caade7ccSmrg 408caade7ccSmrg prefix=$prefix$d 409caade7ccSmrg if test -d "$prefix"; then 410caade7ccSmrg prefixes= 411caade7ccSmrg else 412caade7ccSmrg if $posix_mkdir; then 413caade7ccSmrg (umask=$mkdir_umask && 414caade7ccSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 415caade7ccSmrg # Don't fail if two instances are running concurrently. 416caade7ccSmrg test -d "$prefix" || exit 1 417caade7ccSmrg else 418caade7ccSmrg case $prefix in 419caade7ccSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 420caade7ccSmrg *) qprefix=$prefix;; 421caade7ccSmrg esac 422caade7ccSmrg prefixes="$prefixes '$qprefix'" 423caade7ccSmrg fi 424caade7ccSmrg fi 425caade7ccSmrg prefix=$prefix/ 426caade7ccSmrg done 427caade7ccSmrg 428caade7ccSmrg if test -n "$prefixes"; then 429caade7ccSmrg # Don't fail if two instances are running concurrently. 430caade7ccSmrg (umask $mkdir_umask && 431caade7ccSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 432caade7ccSmrg test -d "$dstdir" || exit 1 433caade7ccSmrg obsolete_mkdir_used=true 434caade7ccSmrg fi 435caade7ccSmrg fi 436caade7ccSmrg fi 437caade7ccSmrg 438caade7ccSmrg if test -n "$dir_arg"; then 439caade7ccSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 440caade7ccSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 441caade7ccSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 442caade7ccSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 443caade7ccSmrg else 444caade7ccSmrg 445caade7ccSmrg # Make a couple of temp file names in the proper directory. 446caade7ccSmrg dsttmp=$dstdir/_inst.$$_ 447caade7ccSmrg rmtmp=$dstdir/_rm.$$_ 448caade7ccSmrg 449caade7ccSmrg # Trap to clean up those temp files at exit. 450caade7ccSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 451caade7ccSmrg 452caade7ccSmrg # Copy the file name to the temp name. 453caade7ccSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 454caade7ccSmrg 455caade7ccSmrg # and set any options; do chmod last to preserve setuid bits. 456caade7ccSmrg # 457caade7ccSmrg # If any of these fail, we abort the whole thing. If we want to 458caade7ccSmrg # ignore errors from any of these, just make sure not to ignore 459caade7ccSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 460caade7ccSmrg # 461485f0483Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 462485f0483Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 463485f0483Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 464485f0483Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 465485f0483Smrg 466485f0483Smrg # If -C, don't bother to copy if it wouldn't change the file. 467485f0483Smrg if $copy_on_change && 468485f0483Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 469485f0483Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 470485f0483Smrg 471485f0483Smrg eval "$initialize_posix_glob" && 472485f0483Smrg $posix_glob set -f && 473485f0483Smrg set X $old && old=:$2:$4:$5:$6 && 474485f0483Smrg set X $new && new=:$2:$4:$5:$6 && 475485f0483Smrg $posix_glob set +f && 476485f0483Smrg 477485f0483Smrg test "$old" = "$new" && 478485f0483Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 479485f0483Smrg then 480485f0483Smrg rm -f "$dsttmp" 481485f0483Smrg else 482485f0483Smrg # Rename the file to the real destination. 483485f0483Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 484485f0483Smrg 485485f0483Smrg # The rename failed, perhaps because mv can't rename something else 486485f0483Smrg # to itself, or perhaps because mv is so ancient that it does not 487485f0483Smrg # support -f. 488485f0483Smrg { 489485f0483Smrg # Now remove or move aside any old file at destination location. 490485f0483Smrg # We try this two ways since rm can't unlink itself on some 491485f0483Smrg # systems and the destination file might be busy for other 492485f0483Smrg # reasons. In this case, the final cleanup might fail but the new 493485f0483Smrg # file should still install successfully. 494485f0483Smrg { 495485f0483Smrg test ! -f "$dst" || 496485f0483Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 497485f0483Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 498485f0483Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 499485f0483Smrg } || 500485f0483Smrg { echo "$0: cannot unlink or rename $dst" >&2 501485f0483Smrg (exit 1); exit 1 502485f0483Smrg } 503485f0483Smrg } && 504485f0483Smrg 505485f0483Smrg # Now rename the file to the real destination. 506485f0483Smrg $doit $mvcmd "$dsttmp" "$dst" 507485f0483Smrg } 508485f0483Smrg fi || exit 1 509caade7ccSmrg 510caade7ccSmrg trap '' 0 511caade7ccSmrg fi 512caade7ccSmrgdone 513caade7ccSmrg 514caade7ccSmrg# Local variables: 515caade7ccSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 516caade7ccSmrg# time-stamp-start: "scriptversion=" 517caade7ccSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 518485f0483Smrg# time-stamp-time-zone: "UTC" 519485f0483Smrg# time-stamp-end: "; # UTC" 520caade7ccSmrg# End: 521