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