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