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