1fa225cbcSrjs#!/bin/sh 2fa225cbcSrjs# install - install a program, script, or datafile 3fa225cbcSrjs 4fa225cbcSrjsscriptversion=2006-12-25.00 5fa225cbcSrjs 6fa225cbcSrjs# This originates from X11R5 (mit/util/scripts/install.sh), which was 7fa225cbcSrjs# later released in X11R6 (xc/config/util/install.sh) with the 8fa225cbcSrjs# following copyright and license. 9fa225cbcSrjs# 10fa225cbcSrjs# Copyright (C) 1994 X Consortium 11fa225cbcSrjs# 12fa225cbcSrjs# Permission is hereby granted, free of charge, to any person obtaining a copy 13fa225cbcSrjs# of this software and associated documentation files (the "Software"), to 14fa225cbcSrjs# deal in the Software without restriction, including without limitation the 15fa225cbcSrjs# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16fa225cbcSrjs# sell copies of the Software, and to permit persons to whom the Software is 17fa225cbcSrjs# furnished to do so, subject to the following conditions: 18fa225cbcSrjs# 19fa225cbcSrjs# The above copyright notice and this permission notice shall be included in 20fa225cbcSrjs# all copies or substantial portions of the Software. 21fa225cbcSrjs# 22fa225cbcSrjs# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23fa225cbcSrjs# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24fa225cbcSrjs# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25fa225cbcSrjs# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26fa225cbcSrjs# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27fa225cbcSrjs# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28fa225cbcSrjs# 29fa225cbcSrjs# Except as contained in this notice, the name of the X Consortium shall not 30fa225cbcSrjs# be used in advertising or otherwise to promote the sale, use or other deal- 31fa225cbcSrjs# ings in this Software without prior written authorization from the X Consor- 32fa225cbcSrjs# tium. 33fa225cbcSrjs# 34fa225cbcSrjs# 35fa225cbcSrjs# FSF changes to this file are in the public domain. 36fa225cbcSrjs# 37fa225cbcSrjs# Calling this script install-sh is preferred over install.sh, to prevent 38fa225cbcSrjs# `make' implicit rules from creating a file called install from it 39fa225cbcSrjs# when there is no Makefile. 40fa225cbcSrjs# 41fa225cbcSrjs# This script is compatible with the BSD install script, but was written 42fa225cbcSrjs# from scratch. 43fa225cbcSrjs 44fa225cbcSrjsnl=' 45fa225cbcSrjs' 46fa225cbcSrjsIFS=" "" $nl" 47fa225cbcSrjs 48fa225cbcSrjs# set DOITPROG to echo to test this script 49fa225cbcSrjs 50fa225cbcSrjs# Don't use :- since 4.3BSD and earlier shells don't like it. 51fa225cbcSrjsdoit=${DOITPROG-} 52fa225cbcSrjsif test -z "$doit"; then 53fa225cbcSrjs doit_exec=exec 54fa225cbcSrjselse 55fa225cbcSrjs doit_exec=$doit 56fa225cbcSrjsfi 57fa225cbcSrjs 58fa225cbcSrjs# Put in absolute file names if you don't have them in your path; 59fa225cbcSrjs# or use environment vars. 60fa225cbcSrjs 61fa225cbcSrjschgrpprog=${CHGRPPROG-chgrp} 62fa225cbcSrjschmodprog=${CHMODPROG-chmod} 63fa225cbcSrjschownprog=${CHOWNPROG-chown} 64fa225cbcSrjscmpprog=${CMPPROG-cmp} 65fa225cbcSrjscpprog=${CPPROG-cp} 66fa225cbcSrjsmkdirprog=${MKDIRPROG-mkdir} 67fa225cbcSrjsmvprog=${MVPROG-mv} 68fa225cbcSrjsrmprog=${RMPROG-rm} 69fa225cbcSrjsstripprog=${STRIPPROG-strip} 70fa225cbcSrjs 71fa225cbcSrjsposix_glob='?' 72fa225cbcSrjsinitialize_posix_glob=' 73fa225cbcSrjs test "$posix_glob" != "?" || { 74fa225cbcSrjs if (set -f) 2>/dev/null; then 75fa225cbcSrjs posix_glob= 76fa225cbcSrjs else 77fa225cbcSrjs posix_glob=: 78fa225cbcSrjs fi 79fa225cbcSrjs } 80fa225cbcSrjs' 81fa225cbcSrjs 82fa225cbcSrjsposix_mkdir= 83fa225cbcSrjs 84fa225cbcSrjs# Desired mode of installed file. 85fa225cbcSrjsmode=0755 86fa225cbcSrjs 87fa225cbcSrjschgrpcmd= 88fa225cbcSrjschmodcmd=$chmodprog 89fa225cbcSrjschowncmd= 90fa225cbcSrjsmvcmd=$mvprog 91fa225cbcSrjsrmcmd="$rmprog -f" 92fa225cbcSrjsstripcmd= 93fa225cbcSrjs 94fa225cbcSrjssrc= 95fa225cbcSrjsdst= 96fa225cbcSrjsdir_arg= 97fa225cbcSrjsdst_arg= 98fa225cbcSrjs 99fa225cbcSrjscopy_on_change=false 100fa225cbcSrjsno_target_directory= 101fa225cbcSrjs 102fa225cbcSrjsusage="\ 103fa225cbcSrjsUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 104fa225cbcSrjs or: $0 [OPTION]... SRCFILES... DIRECTORY 105fa225cbcSrjs or: $0 [OPTION]... -t DIRECTORY SRCFILES... 106fa225cbcSrjs or: $0 [OPTION]... -d DIRECTORIES... 107fa225cbcSrjs 108fa225cbcSrjsIn the 1st form, copy SRCFILE to DSTFILE. 109fa225cbcSrjsIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 110fa225cbcSrjsIn the 4th, create DIRECTORIES. 111fa225cbcSrjs 112fa225cbcSrjsOptions: 113fa225cbcSrjs --help display this help and exit. 114fa225cbcSrjs --version display version info and exit. 115fa225cbcSrjs 116fa225cbcSrjs -c (ignored) 117fa225cbcSrjs -C install only if different (preserve the last data modification time) 118fa225cbcSrjs -d create directories instead of installing files. 119fa225cbcSrjs -g GROUP $chgrpprog installed files to GROUP. 120fa225cbcSrjs -m MODE $chmodprog installed files to MODE. 121fa225cbcSrjs -o USER $chownprog installed files to USER. 122fa225cbcSrjs -s $stripprog installed files. 123fa225cbcSrjs -t DIRECTORY install into DIRECTORY. 124fa225cbcSrjs -T report an error if DSTFILE is a directory. 125fa225cbcSrjs 126fa225cbcSrjsEnvironment variables override the default commands: 127fa225cbcSrjs CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 128fa225cbcSrjs RMPROG STRIPPROG 129fa225cbcSrjs" 130fa225cbcSrjs 131fa225cbcSrjswhile test $# -ne 0; do 132fa225cbcSrjs case $1 in 133fa225cbcSrjs -c) ;; 134fa225cbcSrjs 135fa225cbcSrjs -C) copy_on_change=true;; 136fa225cbcSrjs 137fa225cbcSrjs -d) dir_arg=true;; 138fa225cbcSrjs 139fa225cbcSrjs -g) chgrpcmd="$chgrpprog $2" 140fa225cbcSrjs shift;; 141fa225cbcSrjs 142fa225cbcSrjs --help) echo "$usage"; exit $?;; 143fa225cbcSrjs 144fa225cbcSrjs -m) mode=$2 145fa225cbcSrjs case $mode in 146fa225cbcSrjs *' '* | *' '* | *' 147fa225cbcSrjs'* | *'*'* | *'?'* | *'['*) 148fa225cbcSrjs echo "$0: invalid mode: $mode" >&2 149fa225cbcSrjs exit 1;; 150fa225cbcSrjs esac 151fa225cbcSrjs shift;; 152fa225cbcSrjs 153fa225cbcSrjs -o) chowncmd="$chownprog $2" 154fa225cbcSrjs shift;; 155fa225cbcSrjs 156fa225cbcSrjs -s) stripcmd=$stripprog;; 157fa225cbcSrjs 158fa225cbcSrjs -t) dst_arg=$2 159fa225cbcSrjs shift;; 160fa225cbcSrjs 161fa225cbcSrjs -T) no_target_directory=true;; 162fa225cbcSrjs 163fa225cbcSrjs --version) echo "$0 $scriptversion"; exit $?;; 164fa225cbcSrjs 165fa225cbcSrjs --) shift 166fa225cbcSrjs break;; 167fa225cbcSrjs 168fa225cbcSrjs -*) echo "$0: invalid option: $1" >&2 169fa225cbcSrjs exit 1;; 170fa225cbcSrjs 171fa225cbcSrjs *) break;; 172fa225cbcSrjs esac 173fa225cbcSrjs shift 174fa225cbcSrjsdone 175fa225cbcSrjs 176fa225cbcSrjsif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177fa225cbcSrjs # When -d is used, all remaining arguments are directories to create. 178fa225cbcSrjs # When -t is used, the destination is already specified. 179fa225cbcSrjs # Otherwise, the last argument is the destination. Remove it from $@. 180fa225cbcSrjs for arg 181fa225cbcSrjs do 182fa225cbcSrjs if test -n "$dst_arg"; then 183fa225cbcSrjs # $@ is not empty: it contains at least $arg. 184fa225cbcSrjs set fnord "$@" "$dst_arg" 185fa225cbcSrjs shift # fnord 186fa225cbcSrjs fi 187fa225cbcSrjs shift # arg 188fa225cbcSrjs dst_arg=$arg 189fa225cbcSrjs done 190fa225cbcSrjsfi 191fa225cbcSrjs 192fa225cbcSrjsif test $# -eq 0; then 193fa225cbcSrjs if test -z "$dir_arg"; then 194fa225cbcSrjs echo "$0: no input file specified." >&2 195fa225cbcSrjs exit 1 196fa225cbcSrjs fi 197fa225cbcSrjs # It's OK to call `install-sh -d' without argument. 198fa225cbcSrjs # This can happen when creating conditional directories. 199fa225cbcSrjs exit 0 200fa225cbcSrjsfi 201fa225cbcSrjs 202fa225cbcSrjsif test -z "$dir_arg"; then 203fa225cbcSrjs trap '(exit $?); exit' 1 2 13 15 204fa225cbcSrjs 205fa225cbcSrjs # Set umask so as not to create temps with too-generous modes. 206fa225cbcSrjs # However, 'strip' requires both read and write access to temps. 207fa225cbcSrjs case $mode in 208fa225cbcSrjs # Optimize common cases. 209fa225cbcSrjs *644) cp_umask=133;; 210fa225cbcSrjs *755) cp_umask=22;; 211fa225cbcSrjs 212fa225cbcSrjs *[0-7]) 213fa225cbcSrjs if test -z "$stripcmd"; then 214fa225cbcSrjs u_plus_rw= 215fa225cbcSrjs else 216fa225cbcSrjs u_plus_rw='% 200' 217fa225cbcSrjs fi 218fa225cbcSrjs cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 219fa225cbcSrjs *) 220fa225cbcSrjs if test -z "$stripcmd"; then 221fa225cbcSrjs u_plus_rw= 222fa225cbcSrjs else 223fa225cbcSrjs u_plus_rw=,u+rw 224fa225cbcSrjs fi 225fa225cbcSrjs cp_umask=$mode$u_plus_rw;; 226fa225cbcSrjs esac 227fa225cbcSrjsfi 228fa225cbcSrjs 229fa225cbcSrjsfor src 230fa225cbcSrjsdo 231fa225cbcSrjs # Protect names starting with `-'. 232fa225cbcSrjs case $src in 233fa225cbcSrjs -*) src=./$src;; 234fa225cbcSrjs esac 235fa225cbcSrjs 236fa225cbcSrjs if test -n "$dir_arg"; then 237fa225cbcSrjs dst=$src 238fa225cbcSrjs dstdir=$dst 239fa225cbcSrjs test -d "$dstdir" 240fa225cbcSrjs dstdir_status=$? 241fa225cbcSrjs else 242fa225cbcSrjs 243fa225cbcSrjs # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 244fa225cbcSrjs # might cause directories to be created, which would be especially bad 245fa225cbcSrjs # if $src (and thus $dsttmp) contains '*'. 246fa225cbcSrjs if test ! -f "$src" && test ! -d "$src"; then 247fa225cbcSrjs echo "$0: $src does not exist." >&2 248fa225cbcSrjs exit 1 249fa225cbcSrjs fi 250fa225cbcSrjs 251fa225cbcSrjs if test -z "$dst_arg"; then 252fa225cbcSrjs echo "$0: no destination specified." >&2 253fa225cbcSrjs exit 1 254fa225cbcSrjs fi 255fa225cbcSrjs 256fa225cbcSrjs dst=$dst_arg 257fa225cbcSrjs # Protect names starting with `-'. 258fa225cbcSrjs case $dst in 259fa225cbcSrjs -*) dst=./$dst;; 260fa225cbcSrjs esac 261fa225cbcSrjs 262fa225cbcSrjs # If destination is a directory, append the input filename; won't work 263fa225cbcSrjs # if double slashes aren't ignored. 264fa225cbcSrjs if test -d "$dst"; then 265fa225cbcSrjs if test -n "$no_target_directory"; then 266fa225cbcSrjs echo "$0: $dst_arg: Is a directory" >&2 267fa225cbcSrjs exit 1 268fa225cbcSrjs fi 269fa225cbcSrjs dstdir=$dst 270fa225cbcSrjs dst=$dstdir/`basename "$src"` 271fa225cbcSrjs dstdir_status=0 272fa225cbcSrjs else 273fa225cbcSrjs # Prefer dirname, but fall back on a substitute if dirname fails. 274fa225cbcSrjs dstdir=` 275fa225cbcSrjs (dirname "$dst") 2>/dev/null || 276fa225cbcSrjs expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 277fa225cbcSrjs X"$dst" : 'X\(//\)[^/]' \| \ 278fa225cbcSrjs X"$dst" : 'X\(//\)$' \| \ 279fa225cbcSrjs X"$dst" : 'X\(/\)' \| . 2>/dev/null || 280fa225cbcSrjs echo X"$dst" | 281fa225cbcSrjs sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 282fa225cbcSrjs s//\1/ 283fa225cbcSrjs q 284fa225cbcSrjs } 285fa225cbcSrjs /^X\(\/\/\)[^/].*/{ 286fa225cbcSrjs s//\1/ 287fa225cbcSrjs q 288fa225cbcSrjs } 289fa225cbcSrjs /^X\(\/\/\)$/{ 290fa225cbcSrjs s//\1/ 291fa225cbcSrjs q 292fa225cbcSrjs } 293fa225cbcSrjs /^X\(\/\).*/{ 294fa225cbcSrjs s//\1/ 295fa225cbcSrjs q 296fa225cbcSrjs } 297fa225cbcSrjs s/.*/./; q' 298fa225cbcSrjs ` 299fa225cbcSrjs 300fa225cbcSrjs test -d "$dstdir" 301fa225cbcSrjs dstdir_status=$? 302fa225cbcSrjs fi 303fa225cbcSrjs fi 304fa225cbcSrjs 305fa225cbcSrjs obsolete_mkdir_used=false 306fa225cbcSrjs 307fa225cbcSrjs if test $dstdir_status != 0; then 308fa225cbcSrjs case $posix_mkdir in 309fa225cbcSrjs '') 310fa225cbcSrjs # Create intermediate dirs using mode 755 as modified by the umask. 311fa225cbcSrjs # This is like FreeBSD 'install' as of 1997-10-28. 312fa225cbcSrjs umask=`umask` 313fa225cbcSrjs case $stripcmd.$umask in 314fa225cbcSrjs # Optimize common cases. 315fa225cbcSrjs *[2367][2367]) mkdir_umask=$umask;; 316fa225cbcSrjs .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 317fa225cbcSrjs 318fa225cbcSrjs *[0-7]) 319fa225cbcSrjs mkdir_umask=`expr $umask + 22 \ 320fa225cbcSrjs - $umask % 100 % 40 + $umask % 20 \ 321fa225cbcSrjs - $umask % 10 % 4 + $umask % 2 322fa225cbcSrjs `;; 323fa225cbcSrjs *) mkdir_umask=$umask,go-w;; 324fa225cbcSrjs esac 325fa225cbcSrjs 326fa225cbcSrjs # With -d, create the new directory with the user-specified mode. 327fa225cbcSrjs # Otherwise, rely on $mkdir_umask. 328fa225cbcSrjs if test -n "$dir_arg"; then 329fa225cbcSrjs mkdir_mode=-m$mode 330fa225cbcSrjs else 331fa225cbcSrjs mkdir_mode= 332fa225cbcSrjs fi 333fa225cbcSrjs 334fa225cbcSrjs posix_mkdir=false 335fa225cbcSrjs case $umask in 336fa225cbcSrjs *[123567][0-7][0-7]) 337fa225cbcSrjs # POSIX mkdir -p sets u+wx bits regardless of umask, which 338fa225cbcSrjs # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 339fa225cbcSrjs ;; 340fa225cbcSrjs *) 341fa225cbcSrjs tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 342fa225cbcSrjs trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 343fa225cbcSrjs 344fa225cbcSrjs if (umask $mkdir_umask && 345fa225cbcSrjs exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 346fa225cbcSrjs then 347fa225cbcSrjs if test -z "$dir_arg" || { 348fa225cbcSrjs # Check for POSIX incompatibilities with -m. 349fa225cbcSrjs # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 350fa225cbcSrjs # other-writeable bit of parent directory when it shouldn't. 351fa225cbcSrjs # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 352fa225cbcSrjs ls_ld_tmpdir=`ls -ld "$tmpdir"` 353fa225cbcSrjs case $ls_ld_tmpdir in 354fa225cbcSrjs d????-?r-*) different_mode=700;; 355fa225cbcSrjs d????-?--*) different_mode=755;; 356fa225cbcSrjs *) false;; 357fa225cbcSrjs esac && 358fa225cbcSrjs $mkdirprog -m$different_mode -p -- "$tmpdir" && { 359fa225cbcSrjs ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 360fa225cbcSrjs test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 361fa225cbcSrjs } 362fa225cbcSrjs } 363fa225cbcSrjs then posix_mkdir=: 364fa225cbcSrjs fi 365fa225cbcSrjs rmdir "$tmpdir/d" "$tmpdir" 366fa225cbcSrjs else 367fa225cbcSrjs # Remove any dirs left behind by ancient mkdir implementations. 368fa225cbcSrjs rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 369fa225cbcSrjs fi 370fa225cbcSrjs trap '' 0;; 371fa225cbcSrjs esac;; 372fa225cbcSrjs esac 373fa225cbcSrjs 374fa225cbcSrjs if 375fa225cbcSrjs $posix_mkdir && ( 376fa225cbcSrjs umask $mkdir_umask && 377fa225cbcSrjs $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 378fa225cbcSrjs ) 379fa225cbcSrjs then : 380fa225cbcSrjs else 381fa225cbcSrjs 382fa225cbcSrjs # The umask is ridiculous, or mkdir does not conform to POSIX, 383fa225cbcSrjs # or it failed possibly due to a race condition. Create the 384fa225cbcSrjs # directory the slow way, step by step, checking for races as we go. 385fa225cbcSrjs 386fa225cbcSrjs case $dstdir in 387fa225cbcSrjs /*) prefix='/';; 388fa225cbcSrjs -*) prefix='./';; 389fa225cbcSrjs *) prefix='';; 390fa225cbcSrjs esac 391fa225cbcSrjs 392fa225cbcSrjs eval "$initialize_posix_glob" 393fa225cbcSrjs 394fa225cbcSrjs oIFS=$IFS 395fa225cbcSrjs IFS=/ 396fa225cbcSrjs $posix_glob set -f 397fa225cbcSrjs set fnord $dstdir 398fa225cbcSrjs shift 399fa225cbcSrjs $posix_glob set +f 400fa225cbcSrjs IFS=$oIFS 401fa225cbcSrjs 402fa225cbcSrjs prefixes= 403fa225cbcSrjs 404fa225cbcSrjs for d 405fa225cbcSrjs do 406fa225cbcSrjs test -z "$d" && continue 407fa225cbcSrjs 408fa225cbcSrjs prefix=$prefix$d 409fa225cbcSrjs if test -d "$prefix"; then 410fa225cbcSrjs prefixes= 411fa225cbcSrjs else 412fa225cbcSrjs if $posix_mkdir; then 413fa225cbcSrjs (umask=$mkdir_umask && 414fa225cbcSrjs $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 415fa225cbcSrjs # Don't fail if two instances are running concurrently. 416fa225cbcSrjs test -d "$prefix" || exit 1 417fa225cbcSrjs else 418fa225cbcSrjs case $prefix in 419fa225cbcSrjs *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 420fa225cbcSrjs *) qprefix=$prefix;; 421fa225cbcSrjs esac 422fa225cbcSrjs prefixes="$prefixes '$qprefix'" 423fa225cbcSrjs fi 424fa225cbcSrjs fi 425fa225cbcSrjs prefix=$prefix/ 426fa225cbcSrjs done 427fa225cbcSrjs 428fa225cbcSrjs if test -n "$prefixes"; then 429fa225cbcSrjs # Don't fail if two instances are running concurrently. 430fa225cbcSrjs (umask $mkdir_umask && 431fa225cbcSrjs eval "\$doit_exec \$mkdirprog $prefixes") || 432fa225cbcSrjs test -d "$dstdir" || exit 1 433fa225cbcSrjs obsolete_mkdir_used=true 434fa225cbcSrjs fi 435fa225cbcSrjs fi 436fa225cbcSrjs fi 437fa225cbcSrjs 438fa225cbcSrjs if test -n "$dir_arg"; then 439fa225cbcSrjs { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 440fa225cbcSrjs { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 441fa225cbcSrjs { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 442fa225cbcSrjs test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 443fa225cbcSrjs else 444fa225cbcSrjs 445fa225cbcSrjs # Make a couple of temp file names in the proper directory. 446fa225cbcSrjs dsttmp=$dstdir/_inst.$$_ 447fa225cbcSrjs rmtmp=$dstdir/_rm.$$_ 448fa225cbcSrjs 449fa225cbcSrjs # Trap to clean up those temp files at exit. 450fa225cbcSrjs trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 451fa225cbcSrjs 452fa225cbcSrjs # Copy the file name to the temp name. 453fa225cbcSrjs (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 454fa225cbcSrjs 455fa225cbcSrjs # and set any options; do chmod last to preserve setuid bits. 456fa225cbcSrjs # 457fa225cbcSrjs # If any of these fail, we abort the whole thing. If we want to 458fa225cbcSrjs # ignore errors from any of these, just make sure not to ignore 459fa225cbcSrjs # errors from the above "$doit $cpprog $src $dsttmp" command. 460fa225cbcSrjs # 461fa225cbcSrjs { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 462fa225cbcSrjs { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 463fa225cbcSrjs { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 464fa225cbcSrjs { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 465fa225cbcSrjs 466fa225cbcSrjs # If -C, don't bother to copy if it wouldn't change the file. 467fa225cbcSrjs if $copy_on_change && 468fa225cbcSrjs old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 469fa225cbcSrjs new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 470fa225cbcSrjs 471fa225cbcSrjs eval "$initialize_posix_glob" && 472fa225cbcSrjs $posix_glob set -f && 473fa225cbcSrjs set X $old && old=:$2:$4:$5:$6 && 474fa225cbcSrjs set X $new && new=:$2:$4:$5:$6 && 475fa225cbcSrjs $posix_glob set +f && 476fa225cbcSrjs 477fa225cbcSrjs test "$old" = "$new" && 478fa225cbcSrjs $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 479fa225cbcSrjs then 480fa225cbcSrjs rm -f "$dsttmp" 481fa225cbcSrjs else 482fa225cbcSrjs # Rename the file to the real destination. 483fa225cbcSrjs $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 484fa225cbcSrjs 485fa225cbcSrjs # The rename failed, perhaps because mv can't rename something else 486fa225cbcSrjs # to itself, or perhaps because mv is so ancient that it does not 487fa225cbcSrjs # support -f. 488fa225cbcSrjs { 489fa225cbcSrjs # Now remove or move aside any old file at destination location. 490fa225cbcSrjs # We try this two ways since rm can't unlink itself on some 491fa225cbcSrjs # systems and the destination file might be busy for other 492fa225cbcSrjs # reasons. In this case, the final cleanup might fail but the new 493fa225cbcSrjs # file should still install successfully. 494fa225cbcSrjs { 495fa225cbcSrjs test ! -f "$dst" || 496fa225cbcSrjs $doit $rmcmd -f "$dst" 2>/dev/null || 497fa225cbcSrjs { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 498fa225cbcSrjs { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 499fa225cbcSrjs } || 500fa225cbcSrjs { echo "$0: cannot unlink or rename $dst" >&2 501fa225cbcSrjs (exit 1); exit 1 502fa225cbcSrjs } 503fa225cbcSrjs } && 504fa225cbcSrjs 505fa225cbcSrjs # Now rename the file to the real destination. 506fa225cbcSrjs $doit $mvcmd "$dsttmp" "$dst" 507fa225cbcSrjs } 508fa225cbcSrjs fi || exit 1 509fa225cbcSrjs 510fa225cbcSrjs trap '' 0 511fa225cbcSrjs fi 512fa225cbcSrjsdone 513fa225cbcSrjs 514fa225cbcSrjs# Local variables: 515fa225cbcSrjs# eval: (add-hook 'write-file-hooks 'time-stamp) 516fa225cbcSrjs# time-stamp-start: "scriptversion=" 517fa225cbcSrjs# time-stamp-format: "%:y-%02m-%02d.%02H" 518fa225cbcSrjs# time-stamp-end: "$" 519fa225cbcSrjs# End: 520