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