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