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