install-sh revision b0a0317a
14456fccdSmrg#!/bin/sh 24456fccdSmrg# install - install a program, script, or datafile 34456fccdSmrg 4b0a0317aSmrgscriptversion=2018-03-11.20; # UTC 54456fccdSmrg 64456fccdSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 74456fccdSmrg# later released in X11R6 (xc/config/util/install.sh) with the 84456fccdSmrg# following copyright and license. 94456fccdSmrg# 104456fccdSmrg# Copyright (C) 1994 X Consortium 114456fccdSmrg# 124456fccdSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 134456fccdSmrg# of this software and associated documentation files (the "Software"), to 144456fccdSmrg# deal in the Software without restriction, including without limitation the 154456fccdSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 164456fccdSmrg# sell copies of the Software, and to permit persons to whom the Software is 174456fccdSmrg# furnished to do so, subject to the following conditions: 184456fccdSmrg# 194456fccdSmrg# The above copyright notice and this permission notice shall be included in 204456fccdSmrg# all copies or substantial portions of the Software. 214456fccdSmrg# 224456fccdSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 234456fccdSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 244456fccdSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 254456fccdSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 264456fccdSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 274456fccdSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 284456fccdSmrg# 294456fccdSmrg# Except as contained in this notice, the name of the X Consortium shall not 304456fccdSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 314456fccdSmrg# ings in this Software without prior written authorization from the X Consor- 324456fccdSmrg# tium. 334456fccdSmrg# 344456fccdSmrg# 354456fccdSmrg# FSF changes to this file are in the public domain. 364456fccdSmrg# 374456fccdSmrg# Calling this script install-sh is preferred over install.sh, to prevent 383e6c936aSmrg# 'make' implicit rules from creating a file called install from it 394456fccdSmrg# when there is no Makefile. 404456fccdSmrg# 414456fccdSmrg# This script is compatible with the BSD install script, but was written 4242d69509Smrg# from scratch. 4342d69509Smrg 44b0a0317aSmrgtab=' ' 4542d69509Smrgnl=' 4642d69509Smrg' 47b0a0317aSmrgIFS=" $tab$nl" 484456fccdSmrg 49b0a0317aSmrg# Set DOITPROG to "echo" to test this script. 504456fccdSmrg 5142d69509Smrgdoit=${DOITPROG-} 52b0a0317aSmrgdoit_exec=${doit:-exec} 534456fccdSmrg 5442d69509Smrg# Put in absolute file names if you don't have them in your path; 5542d69509Smrg# or use environment vars. 5642d69509Smrg 5742d69509Smrgchgrpprog=${CHGRPPROG-chgrp} 5842d69509Smrgchmodprog=${CHMODPROG-chmod} 5942d69509Smrgchownprog=${CHOWNPROG-chown} 6042d69509Smrgcmpprog=${CMPPROG-cmp} 6142d69509Smrgcpprog=${CPPROG-cp} 6242d69509Smrgmkdirprog=${MKDIRPROG-mkdir} 6342d69509Smrgmvprog=${MVPROG-mv} 6442d69509Smrgrmprog=${RMPROG-rm} 6542d69509Smrgstripprog=${STRIPPROG-strip} 6642d69509Smrg 6742d69509Smrgposix_mkdir= 6842d69509Smrg 6942d69509Smrg# Desired mode of installed file. 7042d69509Smrgmode=0755 714456fccdSmrg 724456fccdSmrgchgrpcmd= 7342d69509Smrgchmodcmd=$chmodprog 7442d69509Smrgchowncmd= 7542d69509Smrgmvcmd=$mvprog 764456fccdSmrgrmcmd="$rmprog -f" 7742d69509Smrgstripcmd= 7842d69509Smrg 794456fccdSmrgsrc= 804456fccdSmrgdst= 814456fccdSmrgdir_arg= 8242d69509Smrgdst_arg= 8342d69509Smrg 8442d69509Smrgcopy_on_change=false 85b0a0317aSmrgis_target_a_directory=possibly 864456fccdSmrg 8742d69509Smrgusage="\ 8842d69509SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 894456fccdSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 904456fccdSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 914456fccdSmrg or: $0 [OPTION]... -d DIRECTORIES... 924456fccdSmrg 934456fccdSmrgIn the 1st form, copy SRCFILE to DSTFILE. 944456fccdSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 954456fccdSmrgIn the 4th, create DIRECTORIES. 964456fccdSmrg 974456fccdSmrgOptions: 9842d69509Smrg --help display this help and exit. 9942d69509Smrg --version display version info and exit. 10042d69509Smrg 10142d69509Smrg -c (ignored) 10242d69509Smrg -C install only if different (preserve the last data modification time) 10342d69509Smrg -d create directories instead of installing files. 10442d69509Smrg -g GROUP $chgrpprog installed files to GROUP. 10542d69509Smrg -m MODE $chmodprog installed files to MODE. 10642d69509Smrg -o USER $chownprog installed files to USER. 10742d69509Smrg -s $stripprog installed files. 10842d69509Smrg -t DIRECTORY install into DIRECTORY. 10942d69509Smrg -T report an error if DSTFILE is a directory. 1104456fccdSmrg 1114456fccdSmrgEnvironment variables override the default commands: 11242d69509Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 11342d69509Smrg RMPROG STRIPPROG 1144456fccdSmrg" 1154456fccdSmrg 11642d69509Smrgwhile test $# -ne 0; do 1174456fccdSmrg case $1 in 11842d69509Smrg -c) ;; 11942d69509Smrg 12042d69509Smrg -C) copy_on_change=true;; 1214456fccdSmrg 12242d69509Smrg -d) dir_arg=true;; 1234456fccdSmrg 1244456fccdSmrg -g) chgrpcmd="$chgrpprog $2" 125b0a0317aSmrg shift;; 1264456fccdSmrg 1274456fccdSmrg --help) echo "$usage"; exit $?;; 1284456fccdSmrg 12942d69509Smrg -m) mode=$2 130b0a0317aSmrg case $mode in 131b0a0317aSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132b0a0317aSmrg echo "$0: invalid mode: $mode" >&2 133b0a0317aSmrg exit 1;; 134b0a0317aSmrg esac 135b0a0317aSmrg shift;; 1364456fccdSmrg 1374456fccdSmrg -o) chowncmd="$chownprog $2" 138b0a0317aSmrg shift;; 1394456fccdSmrg 14042d69509Smrg -s) stripcmd=$stripprog;; 1414456fccdSmrg 142b0a0317aSmrg -t) 143b0a0317aSmrg is_target_a_directory=always 144b0a0317aSmrg dst_arg=$2 145b0a0317aSmrg # Protect names problematic for 'test' and other utilities. 146b0a0317aSmrg case $dst_arg in 147b0a0317aSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 148b0a0317aSmrg esac 149b0a0317aSmrg shift;; 1504456fccdSmrg 151b0a0317aSmrg -T) is_target_a_directory=never;; 1524456fccdSmrg 1534456fccdSmrg --version) echo "$0 $scriptversion"; exit $?;; 1544456fccdSmrg 155b0a0317aSmrg --) shift 156b0a0317aSmrg break;; 15742d69509Smrg 158b0a0317aSmrg -*) echo "$0: invalid option: $1" >&2 159b0a0317aSmrg exit 1;; 16042d69509Smrg 16142d69509Smrg *) break;; 1624456fccdSmrg esac 16342d69509Smrg shift 1644456fccdSmrgdone 1654456fccdSmrg 166b0a0317aSmrg# We allow the use of options -d and -T together, by making -d 167b0a0317aSmrg# take the precedence; this is for compatibility with GNU install. 168b0a0317aSmrg 169b0a0317aSmrgif test -n "$dir_arg"; then 170b0a0317aSmrg if test -n "$dst_arg"; then 171b0a0317aSmrg echo "$0: target directory not allowed when installing a directory." >&2 172b0a0317aSmrg exit 1 173b0a0317aSmrg fi 174b0a0317aSmrgfi 175b0a0317aSmrg 17642d69509Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 17742d69509Smrg # When -d is used, all remaining arguments are directories to create. 17842d69509Smrg # When -t is used, the destination is already specified. 17942d69509Smrg # Otherwise, the last argument is the destination. Remove it from $@. 18042d69509Smrg for arg 18142d69509Smrg do 18242d69509Smrg if test -n "$dst_arg"; then 18342d69509Smrg # $@ is not empty: it contains at least $arg. 18442d69509Smrg set fnord "$@" "$dst_arg" 18542d69509Smrg shift # fnord 18642d69509Smrg fi 18742d69509Smrg shift # arg 18842d69509Smrg dst_arg=$arg 1893e6c936aSmrg # Protect names problematic for 'test' and other utilities. 1903e6c936aSmrg case $dst_arg in 1913e6c936aSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1923e6c936aSmrg esac 19342d69509Smrg done 19442d69509Smrgfi 19542d69509Smrg 19642d69509Smrgif test $# -eq 0; then 1974456fccdSmrg if test -z "$dir_arg"; then 1984456fccdSmrg echo "$0: no input file specified." >&2 1994456fccdSmrg exit 1 2004456fccdSmrg fi 2013e6c936aSmrg # It's OK to call 'install-sh -d' without argument. 2024456fccdSmrg # This can happen when creating conditional directories. 2034456fccdSmrg exit 0 2044456fccdSmrgfi 2054456fccdSmrg 206b0a0317aSmrgif test -z "$dir_arg"; then 207b0a0317aSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 208b0a0317aSmrg if test ! -d "$dst_arg"; then 209b0a0317aSmrg echo "$0: $dst_arg: Is not a directory." >&2 210b0a0317aSmrg exit 1 211b0a0317aSmrg fi 212b0a0317aSmrg fi 213b0a0317aSmrgfi 214b0a0317aSmrg 21542d69509Smrgif test -z "$dir_arg"; then 2163e6c936aSmrg do_exit='(exit $ret); exit $ret' 2173e6c936aSmrg trap "ret=129; $do_exit" 1 2183e6c936aSmrg trap "ret=130; $do_exit" 2 2193e6c936aSmrg trap "ret=141; $do_exit" 13 2203e6c936aSmrg trap "ret=143; $do_exit" 15 22142d69509Smrg 22242d69509Smrg # Set umask so as not to create temps with too-generous modes. 22342d69509Smrg # However, 'strip' requires both read and write access to temps. 22442d69509Smrg case $mode in 22542d69509Smrg # Optimize common cases. 22642d69509Smrg *644) cp_umask=133;; 22742d69509Smrg *755) cp_umask=22;; 22842d69509Smrg 22942d69509Smrg *[0-7]) 23042d69509Smrg if test -z "$stripcmd"; then 231b0a0317aSmrg u_plus_rw= 23242d69509Smrg else 233b0a0317aSmrg u_plus_rw='% 200' 23442d69509Smrg fi 23542d69509Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23642d69509Smrg *) 23742d69509Smrg if test -z "$stripcmd"; then 238b0a0317aSmrg u_plus_rw= 23942d69509Smrg else 240b0a0317aSmrg u_plus_rw=,u+rw 24142d69509Smrg fi 24242d69509Smrg cp_umask=$mode$u_plus_rw;; 24342d69509Smrg esac 24442d69509Smrgfi 24542d69509Smrg 2464456fccdSmrgfor src 2474456fccdSmrgdo 2483e6c936aSmrg # Protect names problematic for 'test' and other utilities. 2494456fccdSmrg case $src in 2503e6c936aSmrg -* | [=\(\)!]) src=./$src;; 2514456fccdSmrg esac 2524456fccdSmrg 2534456fccdSmrg if test -n "$dir_arg"; then 2544456fccdSmrg dst=$src 25542d69509Smrg dstdir=$dst 25642d69509Smrg test -d "$dstdir" 25742d69509Smrg dstdir_status=$? 2584456fccdSmrg else 25942d69509Smrg 2604456fccdSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2614456fccdSmrg # might cause directories to be created, which would be especially bad 2624456fccdSmrg # if $src (and thus $dsttmp) contains '*'. 2634456fccdSmrg if test ! -f "$src" && test ! -d "$src"; then 2644456fccdSmrg echo "$0: $src does not exist." >&2 2654456fccdSmrg exit 1 2664456fccdSmrg fi 2674456fccdSmrg 26842d69509Smrg if test -z "$dst_arg"; then 2694456fccdSmrg echo "$0: no destination specified." >&2 2704456fccdSmrg exit 1 2714456fccdSmrg fi 27242d69509Smrg dst=$dst_arg 2734456fccdSmrg 274b0a0317aSmrg # If destination is a directory, append the input filename. 2754456fccdSmrg if test -d "$dst"; then 276b0a0317aSmrg if test "$is_target_a_directory" = never; then 277b0a0317aSmrg echo "$0: $dst_arg: Is a directory" >&2 278b0a0317aSmrg exit 1 2794456fccdSmrg fi 28042d69509Smrg dstdir=$dst 281b0a0317aSmrg dstbase=`basename "$src"` 282b0a0317aSmrg case $dst in 283b0a0317aSmrg */) dst=$dst$dstbase;; 284b0a0317aSmrg *) dst=$dst/$dstbase;; 285b0a0317aSmrg esac 28642d69509Smrg dstdir_status=0 28742d69509Smrg else 288b0a0317aSmrg dstdir=`dirname "$dst"` 28942d69509Smrg test -d "$dstdir" 29042d69509Smrg dstdir_status=$? 2914456fccdSmrg fi 2924456fccdSmrg fi 2934456fccdSmrg 294b0a0317aSmrg case $dstdir in 295b0a0317aSmrg */) dstdirslash=$dstdir;; 296b0a0317aSmrg *) dstdirslash=$dstdir/;; 297b0a0317aSmrg esac 298b0a0317aSmrg 29942d69509Smrg obsolete_mkdir_used=false 30042d69509Smrg 30142d69509Smrg if test $dstdir_status != 0; then 30242d69509Smrg case $posix_mkdir in 30342d69509Smrg '') 304b0a0317aSmrg # Create intermediate dirs using mode 755 as modified by the umask. 305b0a0317aSmrg # This is like FreeBSD 'install' as of 1997-10-28. 306b0a0317aSmrg umask=`umask` 307b0a0317aSmrg case $stripcmd.$umask in 308b0a0317aSmrg # Optimize common cases. 309b0a0317aSmrg *[2367][2367]) mkdir_umask=$umask;; 310b0a0317aSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 311b0a0317aSmrg 312b0a0317aSmrg *[0-7]) 313b0a0317aSmrg mkdir_umask=`expr $umask + 22 \ 314b0a0317aSmrg - $umask % 100 % 40 + $umask % 20 \ 315b0a0317aSmrg - $umask % 10 % 4 + $umask % 2 316b0a0317aSmrg `;; 317b0a0317aSmrg *) mkdir_umask=$umask,go-w;; 318b0a0317aSmrg esac 319b0a0317aSmrg 320b0a0317aSmrg # With -d, create the new directory with the user-specified mode. 321b0a0317aSmrg # Otherwise, rely on $mkdir_umask. 322b0a0317aSmrg if test -n "$dir_arg"; then 323b0a0317aSmrg mkdir_mode=-m$mode 324b0a0317aSmrg else 325b0a0317aSmrg mkdir_mode= 326b0a0317aSmrg fi 327b0a0317aSmrg 328b0a0317aSmrg posix_mkdir=false 329b0a0317aSmrg case $umask in 330b0a0317aSmrg *[123567][0-7][0-7]) 331b0a0317aSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 332b0a0317aSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 333b0a0317aSmrg ;; 334b0a0317aSmrg *) 335b0a0317aSmrg # Note that $RANDOM variable is not portable (e.g. dash); Use it 336b0a0317aSmrg # here however when possible just to lower collision chance. 337b0a0317aSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 338b0a0317aSmrg 339b0a0317aSmrg trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 340b0a0317aSmrg 341b0a0317aSmrg # Because "mkdir -p" follows existing symlinks and we likely work 342b0a0317aSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 343b0a0317aSmrg # directory is successfully created first before we actually test 344b0a0317aSmrg # 'mkdir -p' feature. 345b0a0317aSmrg if (umask $mkdir_umask && 346b0a0317aSmrg $mkdirprog $mkdir_mode "$tmpdir" && 347b0a0317aSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 348b0a0317aSmrg then 349b0a0317aSmrg if test -z "$dir_arg" || { 350b0a0317aSmrg # Check for POSIX incompatibilities with -m. 351b0a0317aSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 352b0a0317aSmrg # other-writable bit of parent directory when it shouldn't. 353b0a0317aSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 354b0a0317aSmrg test_tmpdir="$tmpdir/a" 355b0a0317aSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 356b0a0317aSmrg case $ls_ld_tmpdir in 357b0a0317aSmrg d????-?r-*) different_mode=700;; 358b0a0317aSmrg d????-?--*) different_mode=755;; 359b0a0317aSmrg *) false;; 360b0a0317aSmrg esac && 361b0a0317aSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 362b0a0317aSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 363b0a0317aSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 364b0a0317aSmrg } 365b0a0317aSmrg } 366b0a0317aSmrg then posix_mkdir=: 367b0a0317aSmrg fi 368b0a0317aSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 369b0a0317aSmrg else 370b0a0317aSmrg # Remove any dirs left behind by ancient mkdir implementations. 371b0a0317aSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 372b0a0317aSmrg fi 373b0a0317aSmrg trap '' 0;; 374b0a0317aSmrg esac;; 37542d69509Smrg esac 3764456fccdSmrg 37742d69509Smrg if 37842d69509Smrg $posix_mkdir && ( 379b0a0317aSmrg umask $mkdir_umask && 380b0a0317aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 38142d69509Smrg ) 38242d69509Smrg then : 38342d69509Smrg else 3844456fccdSmrg 38542d69509Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 38642d69509Smrg # or it failed possibly due to a race condition. Create the 38742d69509Smrg # directory the slow way, step by step, checking for races as we go. 3884456fccdSmrg 38942d69509Smrg case $dstdir in 390b0a0317aSmrg /*) prefix='/';; 391b0a0317aSmrg [-=\(\)!]*) prefix='./';; 392b0a0317aSmrg *) prefix='';; 39342d69509Smrg esac 3944456fccdSmrg 39542d69509Smrg oIFS=$IFS 39642d69509Smrg IFS=/ 397b0a0317aSmrg set -f 39842d69509Smrg set fnord $dstdir 3994456fccdSmrg shift 400b0a0317aSmrg set +f 40142d69509Smrg IFS=$oIFS 40242d69509Smrg 40342d69509Smrg prefixes= 40442d69509Smrg 40542d69509Smrg for d 40642d69509Smrg do 407b0a0317aSmrg test X"$d" = X && continue 408b0a0317aSmrg 409b0a0317aSmrg prefix=$prefix$d 410b0a0317aSmrg if test -d "$prefix"; then 411b0a0317aSmrg prefixes= 412b0a0317aSmrg else 413b0a0317aSmrg if $posix_mkdir; then 414b0a0317aSmrg (umask=$mkdir_umask && 415b0a0317aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 416b0a0317aSmrg # Don't fail if two instances are running concurrently. 417b0a0317aSmrg test -d "$prefix" || exit 1 418b0a0317aSmrg else 419b0a0317aSmrg case $prefix in 420b0a0317aSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 421b0a0317aSmrg *) qprefix=$prefix;; 422b0a0317aSmrg esac 423b0a0317aSmrg prefixes="$prefixes '$qprefix'" 424b0a0317aSmrg fi 425b0a0317aSmrg fi 426b0a0317aSmrg prefix=$prefix/ 42742d69509Smrg done 42842d69509Smrg 42942d69509Smrg if test -n "$prefixes"; then 430b0a0317aSmrg # Don't fail if two instances are running concurrently. 431b0a0317aSmrg (umask $mkdir_umask && 432b0a0317aSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 433b0a0317aSmrg test -d "$dstdir" || exit 1 434b0a0317aSmrg obsolete_mkdir_used=true 4354456fccdSmrg fi 43642d69509Smrg fi 4374456fccdSmrg fi 4384456fccdSmrg 4394456fccdSmrg if test -n "$dir_arg"; then 44042d69509Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 44142d69509Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 44242d69509Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 44342d69509Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4444456fccdSmrg else 4454456fccdSmrg 4464456fccdSmrg # Make a couple of temp file names in the proper directory. 447b0a0317aSmrg dsttmp=${dstdirslash}_inst.$$_ 448b0a0317aSmrg rmtmp=${dstdirslash}_rm.$$_ 4494456fccdSmrg 4504456fccdSmrg # Trap to clean up those temp files at exit. 4514456fccdSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4524456fccdSmrg 4534456fccdSmrg # Copy the file name to the temp name. 454b0a0317aSmrg (umask $cp_umask && 455b0a0317aSmrg { test -z "$stripcmd" || { 456b0a0317aSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 457b0a0317aSmrg # which would cause strip to fail. 458b0a0317aSmrg if test -z "$doit"; then 459b0a0317aSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 460b0a0317aSmrg else 461b0a0317aSmrg $doit touch "$dsttmp" 462b0a0317aSmrg fi 463b0a0317aSmrg } 464b0a0317aSmrg } && 465b0a0317aSmrg $doit_exec $cpprog "$src" "$dsttmp") && 4664456fccdSmrg 4674456fccdSmrg # and set any options; do chmod last to preserve setuid bits. 4684456fccdSmrg # 4694456fccdSmrg # If any of these fail, we abort the whole thing. If we want to 4704456fccdSmrg # ignore errors from any of these, just make sure not to ignore 4714456fccdSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4724456fccdSmrg # 47342d69509Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 47442d69509Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 47542d69509Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 47642d69509Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 47742d69509Smrg 47842d69509Smrg # If -C, don't bother to copy if it wouldn't change the file. 47942d69509Smrg if $copy_on_change && 480b0a0317aSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 481b0a0317aSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 482b0a0317aSmrg set -f && 48342d69509Smrg set X $old && old=:$2:$4:$5:$6 && 48442d69509Smrg set X $new && new=:$2:$4:$5:$6 && 485b0a0317aSmrg set +f && 48642d69509Smrg test "$old" = "$new" && 48742d69509Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 48842d69509Smrg then 48942d69509Smrg rm -f "$dsttmp" 49042d69509Smrg else 49142d69509Smrg # Rename the file to the real destination. 49242d69509Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 49342d69509Smrg 49442d69509Smrg # The rename failed, perhaps because mv can't rename something else 49542d69509Smrg # to itself, or perhaps because mv is so ancient that it does not 49642d69509Smrg # support -f. 49742d69509Smrg { 498b0a0317aSmrg # Now remove or move aside any old file at destination location. 499b0a0317aSmrg # We try this two ways since rm can't unlink itself on some 500b0a0317aSmrg # systems and the destination file might be busy for other 501b0a0317aSmrg # reasons. In this case, the final cleanup might fail but the new 502b0a0317aSmrg # file should still install successfully. 503b0a0317aSmrg { 504b0a0317aSmrg test ! -f "$dst" || 505b0a0317aSmrg $doit $rmcmd -f "$dst" 2>/dev/null || 506b0a0317aSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 507b0a0317aSmrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 508b0a0317aSmrg } || 509b0a0317aSmrg { echo "$0: cannot unlink or rename $dst" >&2 510b0a0317aSmrg (exit 1); exit 1 511b0a0317aSmrg } 512b0a0317aSmrg } && 513b0a0317aSmrg 514b0a0317aSmrg # Now rename the file to the real destination. 515b0a0317aSmrg $doit $mvcmd "$dsttmp" "$dst" 51642d69509Smrg } 51742d69509Smrg fi || exit 1 51842d69509Smrg 51942d69509Smrg trap '' 0 52042d69509Smrg fi 5214456fccdSmrgdone 5224456fccdSmrg 5234456fccdSmrg# Local variables: 524b0a0317aSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 5254456fccdSmrg# time-stamp-start: "scriptversion=" 5264456fccdSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 527b0a0317aSmrg# time-stamp-time-zone: "UTC0" 52842d69509Smrg# time-stamp-end: "; # UTC" 5294456fccdSmrg# End: 530