install-sh revision caade7cc
1caade7ccSmrg#!/bin/sh 2caade7ccSmrg# install - install a program, script, or datafile 3caade7ccSmrg 4caade7ccSmrgscriptversion=2006-10-14.15 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. 51caade7ccSmrgdoit="${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 61caade7ccSmrgmvprog="${MVPROG-mv}" 62caade7ccSmrgcpprog="${CPPROG-cp}" 63caade7ccSmrgchmodprog="${CHMODPROG-chmod}" 64caade7ccSmrgchownprog="${CHOWNPROG-chown}" 65caade7ccSmrgchgrpprog="${CHGRPPROG-chgrp}" 66caade7ccSmrgstripprog="${STRIPPROG-strip}" 67caade7ccSmrgrmprog="${RMPROG-rm}" 68caade7ccSmrgmkdirprog="${MKDIRPROG-mkdir}" 69caade7ccSmrg 70caade7ccSmrgposix_glob= 71caade7ccSmrgposix_mkdir= 72caade7ccSmrg 73caade7ccSmrg# Desired mode of installed file. 74caade7ccSmrgmode=0755 75caade7ccSmrg 76caade7ccSmrgchmodcmd=$chmodprog 77caade7ccSmrgchowncmd= 78caade7ccSmrgchgrpcmd= 79caade7ccSmrgstripcmd= 80caade7ccSmrgrmcmd="$rmprog -f" 81caade7ccSmrgmvcmd="$mvprog" 82caade7ccSmrgsrc= 83caade7ccSmrgdst= 84caade7ccSmrgdir_arg= 85caade7ccSmrgdstarg= 86caade7ccSmrgno_target_directory= 87caade7ccSmrg 88caade7ccSmrgusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89caade7ccSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 90caade7ccSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91caade7ccSmrg or: $0 [OPTION]... -d DIRECTORIES... 92caade7ccSmrg 93caade7ccSmrgIn the 1st form, copy SRCFILE to DSTFILE. 94caade7ccSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95caade7ccSmrgIn the 4th, create DIRECTORIES. 96caade7ccSmrg 97caade7ccSmrgOptions: 98caade7ccSmrg-c (ignored) 99caade7ccSmrg-d create directories instead of installing files. 100caade7ccSmrg-g GROUP $chgrpprog installed files to GROUP. 101caade7ccSmrg-m MODE $chmodprog installed files to MODE. 102caade7ccSmrg-o USER $chownprog installed files to USER. 103caade7ccSmrg-s $stripprog installed files. 104caade7ccSmrg-t DIRECTORY install into DIRECTORY. 105caade7ccSmrg-T report an error if DSTFILE is a directory. 106caade7ccSmrg--help display this help and exit. 107caade7ccSmrg--version display version info and exit. 108caade7ccSmrg 109caade7ccSmrgEnvironment variables override the default commands: 110caade7ccSmrg CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 111caade7ccSmrg" 112caade7ccSmrg 113caade7ccSmrgwhile test $# -ne 0; do 114caade7ccSmrg case $1 in 115caade7ccSmrg -c) shift 116caade7ccSmrg continue;; 117caade7ccSmrg 118caade7ccSmrg -d) dir_arg=true 119caade7ccSmrg shift 120caade7ccSmrg continue;; 121caade7ccSmrg 122caade7ccSmrg -g) chgrpcmd="$chgrpprog $2" 123caade7ccSmrg shift 124caade7ccSmrg shift 125caade7ccSmrg continue;; 126caade7ccSmrg 127caade7ccSmrg --help) echo "$usage"; exit $?;; 128caade7ccSmrg 129caade7ccSmrg -m) mode=$2 130caade7ccSmrg shift 131caade7ccSmrg shift 132caade7ccSmrg case $mode in 133caade7ccSmrg *' '* | *' '* | *' 134caade7ccSmrg'* | *'*'* | *'?'* | *'['*) 135caade7ccSmrg echo "$0: invalid mode: $mode" >&2 136caade7ccSmrg exit 1;; 137caade7ccSmrg esac 138caade7ccSmrg continue;; 139caade7ccSmrg 140caade7ccSmrg -o) chowncmd="$chownprog $2" 141caade7ccSmrg shift 142caade7ccSmrg shift 143caade7ccSmrg continue;; 144caade7ccSmrg 145caade7ccSmrg -s) stripcmd=$stripprog 146caade7ccSmrg shift 147caade7ccSmrg continue;; 148caade7ccSmrg 149caade7ccSmrg -t) dstarg=$2 150caade7ccSmrg shift 151caade7ccSmrg shift 152caade7ccSmrg continue;; 153caade7ccSmrg 154caade7ccSmrg -T) no_target_directory=true 155caade7ccSmrg shift 156caade7ccSmrg continue;; 157caade7ccSmrg 158caade7ccSmrg --version) echo "$0 $scriptversion"; exit $?;; 159caade7ccSmrg 160caade7ccSmrg --) shift 161caade7ccSmrg break;; 162caade7ccSmrg 163caade7ccSmrg -*) echo "$0: invalid option: $1" >&2 164caade7ccSmrg exit 1;; 165caade7ccSmrg 166caade7ccSmrg *) break;; 167caade7ccSmrg esac 168caade7ccSmrgdone 169caade7ccSmrg 170caade7ccSmrgif test $# -ne 0 && test -z "$dir_arg$dstarg"; then 171caade7ccSmrg # When -d is used, all remaining arguments are directories to create. 172caade7ccSmrg # When -t is used, the destination is already specified. 173caade7ccSmrg # Otherwise, the last argument is the destination. Remove it from $@. 174caade7ccSmrg for arg 175caade7ccSmrg do 176caade7ccSmrg if test -n "$dstarg"; then 177caade7ccSmrg # $@ is not empty: it contains at least $arg. 178caade7ccSmrg set fnord "$@" "$dstarg" 179caade7ccSmrg shift # fnord 180caade7ccSmrg fi 181caade7ccSmrg shift # arg 182caade7ccSmrg dstarg=$arg 183caade7ccSmrg done 184caade7ccSmrgfi 185caade7ccSmrg 186caade7ccSmrgif test $# -eq 0; then 187caade7ccSmrg if test -z "$dir_arg"; then 188caade7ccSmrg echo "$0: no input file specified." >&2 189caade7ccSmrg exit 1 190caade7ccSmrg fi 191caade7ccSmrg # It's OK to call `install-sh -d' without argument. 192caade7ccSmrg # This can happen when creating conditional directories. 193caade7ccSmrg exit 0 194caade7ccSmrgfi 195caade7ccSmrg 196caade7ccSmrgif test -z "$dir_arg"; then 197caade7ccSmrg trap '(exit $?); exit' 1 2 13 15 198caade7ccSmrg 199caade7ccSmrg # Set umask so as not to create temps with too-generous modes. 200caade7ccSmrg # However, 'strip' requires both read and write access to temps. 201caade7ccSmrg case $mode in 202caade7ccSmrg # Optimize common cases. 203caade7ccSmrg *644) cp_umask=133;; 204caade7ccSmrg *755) cp_umask=22;; 205caade7ccSmrg 206caade7ccSmrg *[0-7]) 207caade7ccSmrg if test -z "$stripcmd"; then 208caade7ccSmrg u_plus_rw= 209caade7ccSmrg else 210caade7ccSmrg u_plus_rw='% 200' 211caade7ccSmrg fi 212caade7ccSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 213caade7ccSmrg *) 214caade7ccSmrg if test -z "$stripcmd"; then 215caade7ccSmrg u_plus_rw= 216caade7ccSmrg else 217caade7ccSmrg u_plus_rw=,u+rw 218caade7ccSmrg fi 219caade7ccSmrg cp_umask=$mode$u_plus_rw;; 220caade7ccSmrg esac 221caade7ccSmrgfi 222caade7ccSmrg 223caade7ccSmrgfor src 224caade7ccSmrgdo 225caade7ccSmrg # Protect names starting with `-'. 226caade7ccSmrg case $src in 227caade7ccSmrg -*) src=./$src ;; 228caade7ccSmrg esac 229caade7ccSmrg 230caade7ccSmrg if test -n "$dir_arg"; then 231caade7ccSmrg dst=$src 232caade7ccSmrg dstdir=$dst 233caade7ccSmrg test -d "$dstdir" 234caade7ccSmrg dstdir_status=$? 235caade7ccSmrg else 236caade7ccSmrg 237caade7ccSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 238caade7ccSmrg # might cause directories to be created, which would be especially bad 239caade7ccSmrg # if $src (and thus $dsttmp) contains '*'. 240caade7ccSmrg if test ! -f "$src" && test ! -d "$src"; then 241caade7ccSmrg echo "$0: $src does not exist." >&2 242caade7ccSmrg exit 1 243caade7ccSmrg fi 244caade7ccSmrg 245caade7ccSmrg if test -z "$dstarg"; then 246caade7ccSmrg echo "$0: no destination specified." >&2 247caade7ccSmrg exit 1 248caade7ccSmrg fi 249caade7ccSmrg 250caade7ccSmrg dst=$dstarg 251caade7ccSmrg # Protect names starting with `-'. 252caade7ccSmrg case $dst in 253caade7ccSmrg -*) dst=./$dst ;; 254caade7ccSmrg esac 255caade7ccSmrg 256caade7ccSmrg # If destination is a directory, append the input filename; won't work 257caade7ccSmrg # if double slashes aren't ignored. 258caade7ccSmrg if test -d "$dst"; then 259caade7ccSmrg if test -n "$no_target_directory"; then 260caade7ccSmrg echo "$0: $dstarg: Is a directory" >&2 261caade7ccSmrg exit 1 262caade7ccSmrg fi 263caade7ccSmrg dstdir=$dst 264caade7ccSmrg dst=$dstdir/`basename "$src"` 265caade7ccSmrg dstdir_status=0 266caade7ccSmrg else 267caade7ccSmrg # Prefer dirname, but fall back on a substitute if dirname fails. 268caade7ccSmrg dstdir=` 269caade7ccSmrg (dirname "$dst") 2>/dev/null || 270caade7ccSmrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 271caade7ccSmrg X"$dst" : 'X\(//\)[^/]' \| \ 272caade7ccSmrg X"$dst" : 'X\(//\)$' \| \ 273caade7ccSmrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 274caade7ccSmrg echo X"$dst" | 275caade7ccSmrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 276caade7ccSmrg s//\1/ 277caade7ccSmrg q 278caade7ccSmrg } 279caade7ccSmrg /^X\(\/\/\)[^/].*/{ 280caade7ccSmrg s//\1/ 281caade7ccSmrg q 282caade7ccSmrg } 283caade7ccSmrg /^X\(\/\/\)$/{ 284caade7ccSmrg s//\1/ 285caade7ccSmrg q 286caade7ccSmrg } 287caade7ccSmrg /^X\(\/\).*/{ 288caade7ccSmrg s//\1/ 289caade7ccSmrg q 290caade7ccSmrg } 291caade7ccSmrg s/.*/./; q' 292caade7ccSmrg ` 293caade7ccSmrg 294caade7ccSmrg test -d "$dstdir" 295caade7ccSmrg dstdir_status=$? 296caade7ccSmrg fi 297caade7ccSmrg fi 298caade7ccSmrg 299caade7ccSmrg obsolete_mkdir_used=false 300caade7ccSmrg 301caade7ccSmrg if test $dstdir_status != 0; then 302caade7ccSmrg case $posix_mkdir in 303caade7ccSmrg '') 304caade7ccSmrg # Create intermediate dirs using mode 755 as modified by the umask. 305caade7ccSmrg # This is like FreeBSD 'install' as of 1997-10-28. 306caade7ccSmrg umask=`umask` 307caade7ccSmrg case $stripcmd.$umask in 308caade7ccSmrg # Optimize common cases. 309caade7ccSmrg *[2367][2367]) mkdir_umask=$umask;; 310caade7ccSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 311caade7ccSmrg 312caade7ccSmrg *[0-7]) 313caade7ccSmrg mkdir_umask=`expr $umask + 22 \ 314caade7ccSmrg - $umask % 100 % 40 + $umask % 20 \ 315caade7ccSmrg - $umask % 10 % 4 + $umask % 2 316caade7ccSmrg `;; 317caade7ccSmrg *) mkdir_umask=$umask,go-w;; 318caade7ccSmrg esac 319caade7ccSmrg 320caade7ccSmrg # With -d, create the new directory with the user-specified mode. 321caade7ccSmrg # Otherwise, rely on $mkdir_umask. 322caade7ccSmrg if test -n "$dir_arg"; then 323caade7ccSmrg mkdir_mode=-m$mode 324caade7ccSmrg else 325caade7ccSmrg mkdir_mode= 326caade7ccSmrg fi 327caade7ccSmrg 328caade7ccSmrg posix_mkdir=false 329caade7ccSmrg case $umask in 330caade7ccSmrg *[123567][0-7][0-7]) 331caade7ccSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 332caade7ccSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 333caade7ccSmrg ;; 334caade7ccSmrg *) 335caade7ccSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 336caade7ccSmrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 337caade7ccSmrg 338caade7ccSmrg if (umask $mkdir_umask && 339caade7ccSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 340caade7ccSmrg then 341caade7ccSmrg if test -z "$dir_arg" || { 342caade7ccSmrg # Check for POSIX incompatibilities with -m. 343caade7ccSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 344caade7ccSmrg # other-writeable bit of parent directory when it shouldn't. 345caade7ccSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 346caade7ccSmrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 347caade7ccSmrg case $ls_ld_tmpdir in 348caade7ccSmrg d????-?r-*) different_mode=700;; 349caade7ccSmrg d????-?--*) different_mode=755;; 350caade7ccSmrg *) false;; 351caade7ccSmrg esac && 352caade7ccSmrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 353caade7ccSmrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 354caade7ccSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 355caade7ccSmrg } 356caade7ccSmrg } 357caade7ccSmrg then posix_mkdir=: 358caade7ccSmrg fi 359caade7ccSmrg rmdir "$tmpdir/d" "$tmpdir" 360caade7ccSmrg else 361caade7ccSmrg # Remove any dirs left behind by ancient mkdir implementations. 362caade7ccSmrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 363caade7ccSmrg fi 364caade7ccSmrg trap '' 0;; 365caade7ccSmrg esac;; 366caade7ccSmrg esac 367caade7ccSmrg 368caade7ccSmrg if 369caade7ccSmrg $posix_mkdir && ( 370caade7ccSmrg umask $mkdir_umask && 371caade7ccSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 372caade7ccSmrg ) 373caade7ccSmrg then : 374caade7ccSmrg else 375caade7ccSmrg 376caade7ccSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 377caade7ccSmrg # or it failed possibly due to a race condition. Create the 378caade7ccSmrg # directory the slow way, step by step, checking for races as we go. 379caade7ccSmrg 380caade7ccSmrg case $dstdir in 381caade7ccSmrg /*) prefix=/ ;; 382caade7ccSmrg -*) prefix=./ ;; 383caade7ccSmrg *) prefix= ;; 384caade7ccSmrg esac 385caade7ccSmrg 386caade7ccSmrg case $posix_glob in 387caade7ccSmrg '') 388caade7ccSmrg if (set -f) 2>/dev/null; then 389caade7ccSmrg posix_glob=true 390caade7ccSmrg else 391caade7ccSmrg posix_glob=false 392caade7ccSmrg fi ;; 393caade7ccSmrg esac 394caade7ccSmrg 395caade7ccSmrg oIFS=$IFS 396caade7ccSmrg IFS=/ 397caade7ccSmrg $posix_glob && set -f 398caade7ccSmrg set fnord $dstdir 399caade7ccSmrg shift 400caade7ccSmrg $posix_glob && set +f 401caade7ccSmrg IFS=$oIFS 402caade7ccSmrg 403caade7ccSmrg prefixes= 404caade7ccSmrg 405caade7ccSmrg for d 406caade7ccSmrg do 407caade7ccSmrg test -z "$d" && continue 408caade7ccSmrg 409caade7ccSmrg prefix=$prefix$d 410caade7ccSmrg if test -d "$prefix"; then 411caade7ccSmrg prefixes= 412caade7ccSmrg else 413caade7ccSmrg if $posix_mkdir; then 414caade7ccSmrg (umask=$mkdir_umask && 415caade7ccSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 416caade7ccSmrg # Don't fail if two instances are running concurrently. 417caade7ccSmrg test -d "$prefix" || exit 1 418caade7ccSmrg else 419caade7ccSmrg case $prefix in 420caade7ccSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 421caade7ccSmrg *) qprefix=$prefix;; 422caade7ccSmrg esac 423caade7ccSmrg prefixes="$prefixes '$qprefix'" 424caade7ccSmrg fi 425caade7ccSmrg fi 426caade7ccSmrg prefix=$prefix/ 427caade7ccSmrg done 428caade7ccSmrg 429caade7ccSmrg if test -n "$prefixes"; then 430caade7ccSmrg # Don't fail if two instances are running concurrently. 431caade7ccSmrg (umask $mkdir_umask && 432caade7ccSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 433caade7ccSmrg test -d "$dstdir" || exit 1 434caade7ccSmrg obsolete_mkdir_used=true 435caade7ccSmrg fi 436caade7ccSmrg fi 437caade7ccSmrg fi 438caade7ccSmrg 439caade7ccSmrg if test -n "$dir_arg"; then 440caade7ccSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 441caade7ccSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 442caade7ccSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 443caade7ccSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 444caade7ccSmrg else 445caade7ccSmrg 446caade7ccSmrg # Make a couple of temp file names in the proper directory. 447caade7ccSmrg dsttmp=$dstdir/_inst.$$_ 448caade7ccSmrg rmtmp=$dstdir/_rm.$$_ 449caade7ccSmrg 450caade7ccSmrg # Trap to clean up those temp files at exit. 451caade7ccSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 452caade7ccSmrg 453caade7ccSmrg # Copy the file name to the temp name. 454caade7ccSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 455caade7ccSmrg 456caade7ccSmrg # and set any options; do chmod last to preserve setuid bits. 457caade7ccSmrg # 458caade7ccSmrg # If any of these fail, we abort the whole thing. If we want to 459caade7ccSmrg # ignore errors from any of these, just make sure not to ignore 460caade7ccSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 461caade7ccSmrg # 462caade7ccSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 463caade7ccSmrg && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 464caade7ccSmrg && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 465caade7ccSmrg && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 466caade7ccSmrg 467caade7ccSmrg # Now rename the file to the real destination. 468caade7ccSmrg { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ 469caade7ccSmrg || { 470caade7ccSmrg # The rename failed, perhaps because mv can't rename something else 471caade7ccSmrg # to itself, or perhaps because mv is so ancient that it does not 472caade7ccSmrg # support -f. 473caade7ccSmrg 474caade7ccSmrg # Now remove or move aside any old file at destination location. 475caade7ccSmrg # We try this two ways since rm can't unlink itself on some 476caade7ccSmrg # systems and the destination file might be busy for other 477caade7ccSmrg # reasons. In this case, the final cleanup might fail but the new 478caade7ccSmrg # file should still install successfully. 479caade7ccSmrg { 480caade7ccSmrg if test -f "$dst"; then 481caade7ccSmrg $doit $rmcmd -f "$dst" 2>/dev/null \ 482caade7ccSmrg || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ 483caade7ccSmrg && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ 484caade7ccSmrg || { 485caade7ccSmrg echo "$0: cannot unlink or rename $dst" >&2 486caade7ccSmrg (exit 1); exit 1 487caade7ccSmrg } 488caade7ccSmrg else 489caade7ccSmrg : 490caade7ccSmrg fi 491caade7ccSmrg } && 492caade7ccSmrg 493caade7ccSmrg # Now rename the file to the real destination. 494caade7ccSmrg $doit $mvcmd "$dsttmp" "$dst" 495caade7ccSmrg } 496caade7ccSmrg } || exit 1 497caade7ccSmrg 498caade7ccSmrg trap '' 0 499caade7ccSmrg fi 500caade7ccSmrgdone 501caade7ccSmrg 502caade7ccSmrg# Local variables: 503caade7ccSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 504caade7ccSmrg# time-stamp-start: "scriptversion=" 505caade7ccSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 506caade7ccSmrg# time-stamp-end: "$" 507caade7ccSmrg# End: 508