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