install-sh revision 75cbef56
13eed67faSmbalmer#!/bin/sh 23eed67faSmbalmer# install - install a program, script, or datafile 33eed67faSmbalmer 475cbef56Smrgscriptversion=2011-01-19.21; # UTC 53eed67faSmbalmer 63eed67faSmbalmer# This originates from X11R5 (mit/util/scripts/install.sh), which was 73eed67faSmbalmer# later released in X11R6 (xc/config/util/install.sh) with the 83eed67faSmbalmer# following copyright and license. 93eed67faSmbalmer# 103eed67faSmbalmer# Copyright (C) 1994 X Consortium 113eed67faSmbalmer# 123eed67faSmbalmer# Permission is hereby granted, free of charge, to any person obtaining a copy 133eed67faSmbalmer# of this software and associated documentation files (the "Software"), to 143eed67faSmbalmer# deal in the Software without restriction, including without limitation the 153eed67faSmbalmer# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 163eed67faSmbalmer# sell copies of the Software, and to permit persons to whom the Software is 173eed67faSmbalmer# furnished to do so, subject to the following conditions: 183eed67faSmbalmer# 193eed67faSmbalmer# The above copyright notice and this permission notice shall be included in 203eed67faSmbalmer# all copies or substantial portions of the Software. 213eed67faSmbalmer# 223eed67faSmbalmer# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 233eed67faSmbalmer# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 243eed67faSmbalmer# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 253eed67faSmbalmer# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 263eed67faSmbalmer# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 273eed67faSmbalmer# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 283eed67faSmbalmer# 293eed67faSmbalmer# Except as contained in this notice, the name of the X Consortium shall not 303eed67faSmbalmer# be used in advertising or otherwise to promote the sale, use or other deal- 313eed67faSmbalmer# ings in this Software without prior written authorization from the X Consor- 323eed67faSmbalmer# tium. 333eed67faSmbalmer# 343eed67faSmbalmer# 353eed67faSmbalmer# FSF changes to this file are in the public domain. 363eed67faSmbalmer# 373eed67faSmbalmer# Calling this script install-sh is preferred over install.sh, to prevent 383eed67faSmbalmer# `make' implicit rules from creating a file called install from it 393eed67faSmbalmer# when there is no Makefile. 403eed67faSmbalmer# 413eed67faSmbalmer# This script is compatible with the BSD install script, but was written 42dc407927Smrg# from scratch. 43dc407927Smrg 44dc407927Smrgnl=' 45dc407927Smrg' 46dc407927SmrgIFS=" "" $nl" 473eed67faSmbalmer 483eed67faSmbalmer# set DOITPROG to echo to test this script 493eed67faSmbalmer 503eed67faSmbalmer# Don't use :- since 4.3BSD and earlier shells don't like it. 51dc407927Smrgdoit=${DOITPROG-} 52dc407927Smrgif test -z "$doit"; then 53dc407927Smrg doit_exec=exec 54dc407927Smrgelse 55dc407927Smrg doit_exec=$doit 56dc407927Smrgfi 573eed67faSmbalmer 58dc407927Smrg# Put in absolute file names if you don't have them in your path; 59dc407927Smrg# or use environment vars. 60dc407927Smrg 61dc407927Smrgchgrpprog=${CHGRPPROG-chgrp} 62dc407927Smrgchmodprog=${CHMODPROG-chmod} 63dc407927Smrgchownprog=${CHOWNPROG-chown} 64dc407927Smrgcmpprog=${CMPPROG-cmp} 65dc407927Smrgcpprog=${CPPROG-cp} 66dc407927Smrgmkdirprog=${MKDIRPROG-mkdir} 67dc407927Smrgmvprog=${MVPROG-mv} 68dc407927Smrgrmprog=${RMPROG-rm} 69dc407927Smrgstripprog=${STRIPPROG-strip} 70dc407927Smrg 71dc407927Smrgposix_glob='?' 72dc407927Smrginitialize_posix_glob=' 73dc407927Smrg test "$posix_glob" != "?" || { 74dc407927Smrg if (set -f) 2>/dev/null; then 75dc407927Smrg posix_glob= 76dc407927Smrg else 77dc407927Smrg posix_glob=: 78dc407927Smrg fi 79dc407927Smrg } 80dc407927Smrg' 813eed67faSmbalmer 82dc407927Smrgposix_mkdir= 83dc407927Smrg 84dc407927Smrg# Desired mode of installed file. 85dc407927Smrgmode=0755 863eed67faSmbalmer 873eed67faSmbalmerchgrpcmd= 88dc407927Smrgchmodcmd=$chmodprog 89dc407927Smrgchowncmd= 90dc407927Smrgmvcmd=$mvprog 913eed67faSmbalmerrmcmd="$rmprog -f" 92dc407927Smrgstripcmd= 93dc407927Smrg 943eed67faSmbalmersrc= 953eed67faSmbalmerdst= 963eed67faSmbalmerdir_arg= 97dc407927Smrgdst_arg= 98dc407927Smrg 99dc407927Smrgcopy_on_change=false 1003eed67faSmbalmerno_target_directory= 1013eed67faSmbalmer 102dc407927Smrgusage="\ 103dc407927SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 1043eed67faSmbalmer or: $0 [OPTION]... SRCFILES... DIRECTORY 1053eed67faSmbalmer or: $0 [OPTION]... -t DIRECTORY SRCFILES... 1063eed67faSmbalmer or: $0 [OPTION]... -d DIRECTORIES... 1073eed67faSmbalmer 1083eed67faSmbalmerIn the 1st form, copy SRCFILE to DSTFILE. 1093eed67faSmbalmerIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1103eed67faSmbalmerIn the 4th, create DIRECTORIES. 1113eed67faSmbalmer 1123eed67faSmbalmerOptions: 113dc407927Smrg --help display this help and exit. 114dc407927Smrg --version display version info and exit. 115dc407927Smrg 116dc407927Smrg -c (ignored) 117dc407927Smrg -C install only if different (preserve the last data modification time) 118dc407927Smrg -d create directories instead of installing files. 119dc407927Smrg -g GROUP $chgrpprog installed files to GROUP. 120dc407927Smrg -m MODE $chmodprog installed files to MODE. 121dc407927Smrg -o USER $chownprog installed files to USER. 122dc407927Smrg -s $stripprog installed files. 123dc407927Smrg -t DIRECTORY install into DIRECTORY. 124dc407927Smrg -T report an error if DSTFILE is a directory. 1253eed67faSmbalmer 1263eed67faSmbalmerEnvironment variables override the default commands: 127dc407927Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 128dc407927Smrg RMPROG STRIPPROG 1293eed67faSmbalmer" 1303eed67faSmbalmer 131dc407927Smrgwhile test $# -ne 0; do 1323eed67faSmbalmer case $1 in 133dc407927Smrg -c) ;; 134dc407927Smrg 135dc407927Smrg -C) copy_on_change=true;; 1363eed67faSmbalmer 137dc407927Smrg -d) dir_arg=true;; 1383eed67faSmbalmer 1393eed67faSmbalmer -g) chgrpcmd="$chgrpprog $2" 140dc407927Smrg shift;; 1413eed67faSmbalmer 1423eed67faSmbalmer --help) echo "$usage"; exit $?;; 1433eed67faSmbalmer 144dc407927Smrg -m) mode=$2 145dc407927Smrg case $mode in 146dc407927Smrg *' '* | *' '* | *' 147dc407927Smrg'* | *'*'* | *'?'* | *'['*) 148dc407927Smrg echo "$0: invalid mode: $mode" >&2 149dc407927Smrg exit 1;; 150dc407927Smrg esac 151dc407927Smrg shift;; 1523eed67faSmbalmer 1533eed67faSmbalmer -o) chowncmd="$chownprog $2" 154dc407927Smrg shift;; 1553eed67faSmbalmer 156dc407927Smrg -s) stripcmd=$stripprog;; 1573eed67faSmbalmer 158dc407927Smrg -t) dst_arg=$2 15975cbef56Smrg # Protect names problematic for `test' and other utilities. 16075cbef56Smrg case $dst_arg in 16175cbef56Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 16275cbef56Smrg esac 163dc407927Smrg shift;; 1643eed67faSmbalmer 165dc407927Smrg -T) no_target_directory=true;; 1663eed67faSmbalmer 1673eed67faSmbalmer --version) echo "$0 $scriptversion"; exit $?;; 1683eed67faSmbalmer 169dc407927Smrg --) shift 1703eed67faSmbalmer break;; 171dc407927Smrg 172dc407927Smrg -*) echo "$0: invalid option: $1" >&2 173dc407927Smrg exit 1;; 174dc407927Smrg 175dc407927Smrg *) break;; 1763eed67faSmbalmer esac 177dc407927Smrg shift 1783eed67faSmbalmerdone 1793eed67faSmbalmer 180dc407927Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 181dc407927Smrg # When -d is used, all remaining arguments are directories to create. 182dc407927Smrg # When -t is used, the destination is already specified. 183dc407927Smrg # Otherwise, the last argument is the destination. Remove it from $@. 184dc407927Smrg for arg 185dc407927Smrg do 186dc407927Smrg if test -n "$dst_arg"; then 187dc407927Smrg # $@ is not empty: it contains at least $arg. 188dc407927Smrg set fnord "$@" "$dst_arg" 189dc407927Smrg shift # fnord 190dc407927Smrg fi 191dc407927Smrg shift # arg 192dc407927Smrg dst_arg=$arg 19375cbef56Smrg # Protect names problematic for `test' and other utilities. 19475cbef56Smrg case $dst_arg in 19575cbef56Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 19675cbef56Smrg esac 197dc407927Smrg done 198dc407927Smrgfi 199dc407927Smrg 200dc407927Smrgif test $# -eq 0; then 2013eed67faSmbalmer if test -z "$dir_arg"; then 2023eed67faSmbalmer echo "$0: no input file specified." >&2 2033eed67faSmbalmer exit 1 2043eed67faSmbalmer fi 2053eed67faSmbalmer # It's OK to call `install-sh -d' without argument. 2063eed67faSmbalmer # This can happen when creating conditional directories. 2073eed67faSmbalmer exit 0 2083eed67faSmbalmerfi 2093eed67faSmbalmer 210dc407927Smrgif test -z "$dir_arg"; then 21175cbef56Smrg do_exit='(exit $ret); exit $ret' 21275cbef56Smrg trap "ret=129; $do_exit" 1 21375cbef56Smrg trap "ret=130; $do_exit" 2 21475cbef56Smrg trap "ret=141; $do_exit" 13 21575cbef56Smrg trap "ret=143; $do_exit" 15 216dc407927Smrg 217dc407927Smrg # Set umask so as not to create temps with too-generous modes. 218dc407927Smrg # However, 'strip' requires both read and write access to temps. 219dc407927Smrg case $mode in 220dc407927Smrg # Optimize common cases. 221dc407927Smrg *644) cp_umask=133;; 222dc407927Smrg *755) cp_umask=22;; 223dc407927Smrg 224dc407927Smrg *[0-7]) 225dc407927Smrg if test -z "$stripcmd"; then 226dc407927Smrg u_plus_rw= 227dc407927Smrg else 228dc407927Smrg u_plus_rw='% 200' 229dc407927Smrg fi 230dc407927Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 231dc407927Smrg *) 232dc407927Smrg if test -z "$stripcmd"; then 233dc407927Smrg u_plus_rw= 234dc407927Smrg else 235dc407927Smrg u_plus_rw=,u+rw 236dc407927Smrg fi 237dc407927Smrg cp_umask=$mode$u_plus_rw;; 238dc407927Smrg esac 239dc407927Smrgfi 240dc407927Smrg 2413eed67faSmbalmerfor src 2423eed67faSmbalmerdo 24375cbef56Smrg # Protect names problematic for `test' and other utilities. 2443eed67faSmbalmer case $src in 24575cbef56Smrg -* | [=\(\)!]) src=./$src;; 2463eed67faSmbalmer esac 2473eed67faSmbalmer 2483eed67faSmbalmer if test -n "$dir_arg"; then 2493eed67faSmbalmer dst=$src 250dc407927Smrg dstdir=$dst 251dc407927Smrg test -d "$dstdir" 252dc407927Smrg dstdir_status=$? 2533eed67faSmbalmer else 254dc407927Smrg 2553eed67faSmbalmer # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2563eed67faSmbalmer # might cause directories to be created, which would be especially bad 2573eed67faSmbalmer # if $src (and thus $dsttmp) contains '*'. 2583eed67faSmbalmer if test ! -f "$src" && test ! -d "$src"; then 2593eed67faSmbalmer echo "$0: $src does not exist." >&2 2603eed67faSmbalmer exit 1 2613eed67faSmbalmer fi 2623eed67faSmbalmer 263dc407927Smrg if test -z "$dst_arg"; then 2643eed67faSmbalmer echo "$0: no destination specified." >&2 2653eed67faSmbalmer exit 1 2663eed67faSmbalmer fi 267dc407927Smrg dst=$dst_arg 2683eed67faSmbalmer 2693eed67faSmbalmer # If destination is a directory, append the input filename; won't work 2703eed67faSmbalmer # if double slashes aren't ignored. 2713eed67faSmbalmer if test -d "$dst"; then 2723eed67faSmbalmer if test -n "$no_target_directory"; then 273dc407927Smrg echo "$0: $dst_arg: Is a directory" >&2 2743eed67faSmbalmer exit 1 2753eed67faSmbalmer fi 276dc407927Smrg dstdir=$dst 277dc407927Smrg dst=$dstdir/`basename "$src"` 278dc407927Smrg dstdir_status=0 279dc407927Smrg else 280dc407927Smrg # Prefer dirname, but fall back on a substitute if dirname fails. 281dc407927Smrg dstdir=` 282dc407927Smrg (dirname "$dst") 2>/dev/null || 283dc407927Smrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 284dc407927Smrg X"$dst" : 'X\(//\)[^/]' \| \ 285dc407927Smrg X"$dst" : 'X\(//\)$' \| \ 286dc407927Smrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 287dc407927Smrg echo X"$dst" | 288dc407927Smrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 289dc407927Smrg s//\1/ 290dc407927Smrg q 291dc407927Smrg } 292dc407927Smrg /^X\(\/\/\)[^/].*/{ 293dc407927Smrg s//\1/ 294dc407927Smrg q 295dc407927Smrg } 296dc407927Smrg /^X\(\/\/\)$/{ 297dc407927Smrg s//\1/ 298dc407927Smrg q 299dc407927Smrg } 300dc407927Smrg /^X\(\/\).*/{ 301dc407927Smrg s//\1/ 302dc407927Smrg q 303dc407927Smrg } 304dc407927Smrg s/.*/./; q' 305dc407927Smrg ` 306dc407927Smrg 307dc407927Smrg test -d "$dstdir" 308dc407927Smrg dstdir_status=$? 3093eed67faSmbalmer fi 3103eed67faSmbalmer fi 3113eed67faSmbalmer 312dc407927Smrg obsolete_mkdir_used=false 313dc407927Smrg 314dc407927Smrg if test $dstdir_status != 0; then 315dc407927Smrg case $posix_mkdir in 316dc407927Smrg '') 317dc407927Smrg # Create intermediate dirs using mode 755 as modified by the umask. 318dc407927Smrg # This is like FreeBSD 'install' as of 1997-10-28. 319dc407927Smrg umask=`umask` 320dc407927Smrg case $stripcmd.$umask in 321dc407927Smrg # Optimize common cases. 322dc407927Smrg *[2367][2367]) mkdir_umask=$umask;; 323dc407927Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 324dc407927Smrg 325dc407927Smrg *[0-7]) 326dc407927Smrg mkdir_umask=`expr $umask + 22 \ 327dc407927Smrg - $umask % 100 % 40 + $umask % 20 \ 328dc407927Smrg - $umask % 10 % 4 + $umask % 2 329dc407927Smrg `;; 330dc407927Smrg *) mkdir_umask=$umask,go-w;; 331dc407927Smrg esac 332dc407927Smrg 333dc407927Smrg # With -d, create the new directory with the user-specified mode. 334dc407927Smrg # Otherwise, rely on $mkdir_umask. 335dc407927Smrg if test -n "$dir_arg"; then 336dc407927Smrg mkdir_mode=-m$mode 337dc407927Smrg else 338dc407927Smrg mkdir_mode= 339dc407927Smrg fi 340dc407927Smrg 341dc407927Smrg posix_mkdir=false 342dc407927Smrg case $umask in 343dc407927Smrg *[123567][0-7][0-7]) 344dc407927Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 345dc407927Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 346dc407927Smrg ;; 347dc407927Smrg *) 348dc407927Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 349dc407927Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 350dc407927Smrg 351dc407927Smrg if (umask $mkdir_umask && 352dc407927Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 353dc407927Smrg then 354dc407927Smrg if test -z "$dir_arg" || { 355dc407927Smrg # Check for POSIX incompatibilities with -m. 356dc407927Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 357dc407927Smrg # other-writeable bit of parent directory when it shouldn't. 358dc407927Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 359dc407927Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 360dc407927Smrg case $ls_ld_tmpdir in 361dc407927Smrg d????-?r-*) different_mode=700;; 362dc407927Smrg d????-?--*) different_mode=755;; 363dc407927Smrg *) false;; 364dc407927Smrg esac && 365dc407927Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 366dc407927Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 367dc407927Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 368dc407927Smrg } 369dc407927Smrg } 370dc407927Smrg then posix_mkdir=: 371dc407927Smrg fi 372dc407927Smrg rmdir "$tmpdir/d" "$tmpdir" 373dc407927Smrg else 374dc407927Smrg # Remove any dirs left behind by ancient mkdir implementations. 375dc407927Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 376dc407927Smrg fi 377dc407927Smrg trap '' 0;; 378dc407927Smrg esac;; 379dc407927Smrg esac 3803eed67faSmbalmer 381dc407927Smrg if 382dc407927Smrg $posix_mkdir && ( 383dc407927Smrg umask $mkdir_umask && 384dc407927Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 385dc407927Smrg ) 386dc407927Smrg then : 387dc407927Smrg else 3883eed67faSmbalmer 389dc407927Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 390dc407927Smrg # or it failed possibly due to a race condition. Create the 391dc407927Smrg # directory the slow way, step by step, checking for races as we go. 3923eed67faSmbalmer 393dc407927Smrg case $dstdir in 394dc407927Smrg /*) prefix='/';; 39575cbef56Smrg [-=\(\)!]*) prefix='./';; 396dc407927Smrg *) prefix='';; 397dc407927Smrg esac 3983eed67faSmbalmer 399dc407927Smrg eval "$initialize_posix_glob" 4003eed67faSmbalmer 401dc407927Smrg oIFS=$IFS 402dc407927Smrg IFS=/ 403dc407927Smrg $posix_glob set -f 404dc407927Smrg set fnord $dstdir 4053eed67faSmbalmer shift 406dc407927Smrg $posix_glob set +f 407dc407927Smrg IFS=$oIFS 408dc407927Smrg 409dc407927Smrg prefixes= 410dc407927Smrg 411dc407927Smrg for d 412dc407927Smrg do 41375cbef56Smrg test X"$d" = X && continue 414dc407927Smrg 415dc407927Smrg prefix=$prefix$d 416dc407927Smrg if test -d "$prefix"; then 417dc407927Smrg prefixes= 418dc407927Smrg else 419dc407927Smrg if $posix_mkdir; then 420dc407927Smrg (umask=$mkdir_umask && 421dc407927Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 422dc407927Smrg # Don't fail if two instances are running concurrently. 423dc407927Smrg test -d "$prefix" || exit 1 424dc407927Smrg else 425dc407927Smrg case $prefix in 426dc407927Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 427dc407927Smrg *) qprefix=$prefix;; 428dc407927Smrg esac 429dc407927Smrg prefixes="$prefixes '$qprefix'" 430dc407927Smrg fi 431dc407927Smrg fi 432dc407927Smrg prefix=$prefix/ 433dc407927Smrg done 434dc407927Smrg 435dc407927Smrg if test -n "$prefixes"; then 436dc407927Smrg # Don't fail if two instances are running concurrently. 437dc407927Smrg (umask $mkdir_umask && 438dc407927Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 439dc407927Smrg test -d "$dstdir" || exit 1 440dc407927Smrg obsolete_mkdir_used=true 4413eed67faSmbalmer fi 442dc407927Smrg fi 4433eed67faSmbalmer fi 4443eed67faSmbalmer 4453eed67faSmbalmer if test -n "$dir_arg"; then 446dc407927Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 447dc407927Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 448dc407927Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 449dc407927Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4503eed67faSmbalmer else 4513eed67faSmbalmer 4523eed67faSmbalmer # Make a couple of temp file names in the proper directory. 4533eed67faSmbalmer dsttmp=$dstdir/_inst.$$_ 4543eed67faSmbalmer rmtmp=$dstdir/_rm.$$_ 4553eed67faSmbalmer 4563eed67faSmbalmer # Trap to clean up those temp files at exit. 4573eed67faSmbalmer trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4583eed67faSmbalmer 4593eed67faSmbalmer # Copy the file name to the temp name. 460dc407927Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4613eed67faSmbalmer 4623eed67faSmbalmer # and set any options; do chmod last to preserve setuid bits. 4633eed67faSmbalmer # 4643eed67faSmbalmer # If any of these fail, we abort the whole thing. If we want to 4653eed67faSmbalmer # ignore errors from any of these, just make sure not to ignore 4663eed67faSmbalmer # errors from the above "$doit $cpprog $src $dsttmp" command. 4673eed67faSmbalmer # 468dc407927Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 469dc407927Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 470dc407927Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 471dc407927Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 472dc407927Smrg 473dc407927Smrg # If -C, don't bother to copy if it wouldn't change the file. 474dc407927Smrg if $copy_on_change && 475dc407927Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 476dc407927Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 477dc407927Smrg 478dc407927Smrg eval "$initialize_posix_glob" && 479dc407927Smrg $posix_glob set -f && 480dc407927Smrg set X $old && old=:$2:$4:$5:$6 && 481dc407927Smrg set X $new && new=:$2:$4:$5:$6 && 482dc407927Smrg $posix_glob set +f && 483dc407927Smrg 484dc407927Smrg test "$old" = "$new" && 485dc407927Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 486dc407927Smrg then 487dc407927Smrg rm -f "$dsttmp" 488dc407927Smrg else 489dc407927Smrg # Rename the file to the real destination. 490dc407927Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 491dc407927Smrg 492dc407927Smrg # The rename failed, perhaps because mv can't rename something else 493dc407927Smrg # to itself, or perhaps because mv is so ancient that it does not 494dc407927Smrg # support -f. 495dc407927Smrg { 496dc407927Smrg # Now remove or move aside any old file at destination location. 497dc407927Smrg # We try this two ways since rm can't unlink itself on some 498dc407927Smrg # systems and the destination file might be busy for other 499dc407927Smrg # reasons. In this case, the final cleanup might fail but the new 500dc407927Smrg # file should still install successfully. 501dc407927Smrg { 502dc407927Smrg test ! -f "$dst" || 503dc407927Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 504dc407927Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 505dc407927Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 506dc407927Smrg } || 507dc407927Smrg { echo "$0: cannot unlink or rename $dst" >&2 508dc407927Smrg (exit 1); exit 1 509dc407927Smrg } 510dc407927Smrg } && 511dc407927Smrg 512dc407927Smrg # Now rename the file to the real destination. 513dc407927Smrg $doit $mvcmd "$dsttmp" "$dst" 514dc407927Smrg } 515dc407927Smrg fi || exit 1 516dc407927Smrg 517dc407927Smrg trap '' 0 518dc407927Smrg fi 5193eed67faSmbalmerdone 5203eed67faSmbalmer 5213eed67faSmbalmer# Local variables: 5223eed67faSmbalmer# eval: (add-hook 'write-file-hooks 'time-stamp) 5233eed67faSmbalmer# time-stamp-start: "scriptversion=" 5243eed67faSmbalmer# time-stamp-format: "%:y-%02m-%02d.%02H" 525dc407927Smrg# time-stamp-time-zone: "UTC" 526dc407927Smrg# time-stamp-end: "; # UTC" 5273eed67faSmbalmer# End: 528