install-sh revision dc99b369
15eefee25Smacallan#!/bin/sh 25eefee25Smacallan# install - install a program, script, or datafile 35eefee25Smacallan 4dc99b369Smrgscriptversion=2011-11-20.07; # UTC 55eefee25Smacallan 65eefee25Smacallan# This originates from X11R5 (mit/util/scripts/install.sh), which was 75eefee25Smacallan# later released in X11R6 (xc/config/util/install.sh) with the 85eefee25Smacallan# following copyright and license. 95eefee25Smacallan# 105eefee25Smacallan# Copyright (C) 1994 X Consortium 115eefee25Smacallan# 125eefee25Smacallan# Permission is hereby granted, free of charge, to any person obtaining a copy 135eefee25Smacallan# of this software and associated documentation files (the "Software"), to 145eefee25Smacallan# deal in the Software without restriction, including without limitation the 155eefee25Smacallan# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 165eefee25Smacallan# sell copies of the Software, and to permit persons to whom the Software is 175eefee25Smacallan# furnished to do so, subject to the following conditions: 185eefee25Smacallan# 195eefee25Smacallan# The above copyright notice and this permission notice shall be included in 205eefee25Smacallan# all copies or substantial portions of the Software. 215eefee25Smacallan# 225eefee25Smacallan# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 235eefee25Smacallan# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 245eefee25Smacallan# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 255eefee25Smacallan# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 265eefee25Smacallan# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 275eefee25Smacallan# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 285eefee25Smacallan# 295eefee25Smacallan# Except as contained in this notice, the name of the X Consortium shall not 305eefee25Smacallan# be used in advertising or otherwise to promote the sale, use or other deal- 315eefee25Smacallan# ings in this Software without prior written authorization from the X Consor- 325eefee25Smacallan# tium. 335eefee25Smacallan# 345eefee25Smacallan# 355eefee25Smacallan# FSF changes to this file are in the public domain. 365eefee25Smacallan# 375eefee25Smacallan# Calling this script install-sh is preferred over install.sh, to prevent 38dc99b369Smrg# 'make' implicit rules from creating a file called install from it 395eefee25Smacallan# when there is no Makefile. 405eefee25Smacallan# 415eefee25Smacallan# This script is compatible with the BSD install script, but was written 4262ab96baSmrg# from scratch. 4362ab96baSmrg 4462ab96baSmrgnl=' 4562ab96baSmrg' 4662ab96baSmrgIFS=" "" $nl" 475eefee25Smacallan 485eefee25Smacallan# set DOITPROG to echo to test this script 495eefee25Smacallan 505eefee25Smacallan# Don't use :- since 4.3BSD and earlier shells don't like it. 5162ab96baSmrgdoit=${DOITPROG-} 5262ab96baSmrgif test -z "$doit"; then 5362ab96baSmrg doit_exec=exec 5462ab96baSmrgelse 5562ab96baSmrg doit_exec=$doit 5662ab96baSmrgfi 575eefee25Smacallan 5862ab96baSmrg# Put in absolute file names if you don't have them in your path; 5962ab96baSmrg# or use environment vars. 6062ab96baSmrg 6162ab96baSmrgchgrpprog=${CHGRPPROG-chgrp} 6262ab96baSmrgchmodprog=${CHMODPROG-chmod} 6362ab96baSmrgchownprog=${CHOWNPROG-chown} 6462ab96baSmrgcmpprog=${CMPPROG-cmp} 6562ab96baSmrgcpprog=${CPPROG-cp} 6662ab96baSmrgmkdirprog=${MKDIRPROG-mkdir} 6762ab96baSmrgmvprog=${MVPROG-mv} 6862ab96baSmrgrmprog=${RMPROG-rm} 6962ab96baSmrgstripprog=${STRIPPROG-strip} 7062ab96baSmrg 7162ab96baSmrgposix_glob='?' 7262ab96baSmrginitialize_posix_glob=' 7362ab96baSmrg test "$posix_glob" != "?" || { 7462ab96baSmrg if (set -f) 2>/dev/null; then 7562ab96baSmrg posix_glob= 7662ab96baSmrg else 7762ab96baSmrg posix_glob=: 7862ab96baSmrg fi 7962ab96baSmrg } 8062ab96baSmrg' 815eefee25Smacallan 8262ab96baSmrgposix_mkdir= 8362ab96baSmrg 8462ab96baSmrg# Desired mode of installed file. 8562ab96baSmrgmode=0755 865eefee25Smacallan 875eefee25Smacallanchgrpcmd= 8862ab96baSmrgchmodcmd=$chmodprog 8962ab96baSmrgchowncmd= 9062ab96baSmrgmvcmd=$mvprog 915eefee25Smacallanrmcmd="$rmprog -f" 9262ab96baSmrgstripcmd= 9362ab96baSmrg 945eefee25Smacallansrc= 955eefee25Smacallandst= 965eefee25Smacallandir_arg= 9762ab96baSmrgdst_arg= 9862ab96baSmrg 9962ab96baSmrgcopy_on_change=false 1005eefee25Smacallanno_target_directory= 1015eefee25Smacallan 10262ab96baSmrgusage="\ 10362ab96baSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 1045eefee25Smacallan or: $0 [OPTION]... SRCFILES... DIRECTORY 1055eefee25Smacallan or: $0 [OPTION]... -t DIRECTORY SRCFILES... 1065eefee25Smacallan or: $0 [OPTION]... -d DIRECTORIES... 1075eefee25Smacallan 1085eefee25SmacallanIn the 1st form, copy SRCFILE to DSTFILE. 1095eefee25SmacallanIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1105eefee25SmacallanIn the 4th, create DIRECTORIES. 1115eefee25Smacallan 1125eefee25SmacallanOptions: 11362ab96baSmrg --help display this help and exit. 11462ab96baSmrg --version display version info and exit. 11562ab96baSmrg 11662ab96baSmrg -c (ignored) 11762ab96baSmrg -C install only if different (preserve the last data modification time) 11862ab96baSmrg -d create directories instead of installing files. 11962ab96baSmrg -g GROUP $chgrpprog installed files to GROUP. 12062ab96baSmrg -m MODE $chmodprog installed files to MODE. 12162ab96baSmrg -o USER $chownprog installed files to USER. 12262ab96baSmrg -s $stripprog installed files. 12362ab96baSmrg -t DIRECTORY install into DIRECTORY. 12462ab96baSmrg -T report an error if DSTFILE is a directory. 1255eefee25Smacallan 1265eefee25SmacallanEnvironment variables override the default commands: 12762ab96baSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 12862ab96baSmrg RMPROG STRIPPROG 1295eefee25Smacallan" 1305eefee25Smacallan 13162ab96baSmrgwhile test $# -ne 0; do 1325eefee25Smacallan case $1 in 13362ab96baSmrg -c) ;; 13462ab96baSmrg 13562ab96baSmrg -C) copy_on_change=true;; 1365eefee25Smacallan 13762ab96baSmrg -d) dir_arg=true;; 1385eefee25Smacallan 1395eefee25Smacallan -g) chgrpcmd="$chgrpprog $2" 14062ab96baSmrg shift;; 1415eefee25Smacallan 1425eefee25Smacallan --help) echo "$usage"; exit $?;; 1435eefee25Smacallan 14462ab96baSmrg -m) mode=$2 14562ab96baSmrg case $mode in 14662ab96baSmrg *' '* | *' '* | *' 14762ab96baSmrg'* | *'*'* | *'?'* | *'['*) 14862ab96baSmrg echo "$0: invalid mode: $mode" >&2 14962ab96baSmrg exit 1;; 15062ab96baSmrg esac 15162ab96baSmrg shift;; 1525eefee25Smacallan 1535eefee25Smacallan -o) chowncmd="$chownprog $2" 15462ab96baSmrg shift;; 1555eefee25Smacallan 15662ab96baSmrg -s) stripcmd=$stripprog;; 1575eefee25Smacallan 15862ab96baSmrg -t) dst_arg=$2 159dc99b369Smrg # Protect names problematic for 'test' and other utilities. 160dc99b369Smrg case $dst_arg in 161dc99b369Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 162dc99b369Smrg esac 16362ab96baSmrg shift;; 1645eefee25Smacallan 16562ab96baSmrg -T) no_target_directory=true;; 1665eefee25Smacallan 1675eefee25Smacallan --version) echo "$0 $scriptversion"; exit $?;; 1685eefee25Smacallan 16962ab96baSmrg --) shift 1705eefee25Smacallan break;; 17162ab96baSmrg 17262ab96baSmrg -*) echo "$0: invalid option: $1" >&2 17362ab96baSmrg exit 1;; 17462ab96baSmrg 17562ab96baSmrg *) break;; 1765eefee25Smacallan esac 17762ab96baSmrg shift 1785eefee25Smacallandone 1795eefee25Smacallan 18062ab96baSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 18162ab96baSmrg # When -d is used, all remaining arguments are directories to create. 18262ab96baSmrg # When -t is used, the destination is already specified. 18362ab96baSmrg # Otherwise, the last argument is the destination. Remove it from $@. 18462ab96baSmrg for arg 18562ab96baSmrg do 18662ab96baSmrg if test -n "$dst_arg"; then 18762ab96baSmrg # $@ is not empty: it contains at least $arg. 18862ab96baSmrg set fnord "$@" "$dst_arg" 18962ab96baSmrg shift # fnord 19062ab96baSmrg fi 19162ab96baSmrg shift # arg 19262ab96baSmrg dst_arg=$arg 193dc99b369Smrg # Protect names problematic for 'test' and other utilities. 194dc99b369Smrg case $dst_arg in 195dc99b369Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 196dc99b369Smrg esac 19762ab96baSmrg done 19862ab96baSmrgfi 19962ab96baSmrg 20062ab96baSmrgif test $# -eq 0; then 2015eefee25Smacallan if test -z "$dir_arg"; then 2025eefee25Smacallan echo "$0: no input file specified." >&2 2035eefee25Smacallan exit 1 2045eefee25Smacallan fi 205dc99b369Smrg # It's OK to call 'install-sh -d' without argument. 2065eefee25Smacallan # This can happen when creating conditional directories. 2075eefee25Smacallan exit 0 2085eefee25Smacallanfi 2095eefee25Smacallan 21062ab96baSmrgif test -z "$dir_arg"; then 211dc99b369Smrg do_exit='(exit $ret); exit $ret' 212dc99b369Smrg trap "ret=129; $do_exit" 1 213dc99b369Smrg trap "ret=130; $do_exit" 2 214dc99b369Smrg trap "ret=141; $do_exit" 13 215dc99b369Smrg trap "ret=143; $do_exit" 15 21662ab96baSmrg 21762ab96baSmrg # Set umask so as not to create temps with too-generous modes. 21862ab96baSmrg # However, 'strip' requires both read and write access to temps. 21962ab96baSmrg case $mode in 22062ab96baSmrg # Optimize common cases. 22162ab96baSmrg *644) cp_umask=133;; 22262ab96baSmrg *755) cp_umask=22;; 22362ab96baSmrg 22462ab96baSmrg *[0-7]) 22562ab96baSmrg if test -z "$stripcmd"; then 22662ab96baSmrg u_plus_rw= 22762ab96baSmrg else 22862ab96baSmrg u_plus_rw='% 200' 22962ab96baSmrg fi 23062ab96baSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23162ab96baSmrg *) 23262ab96baSmrg if test -z "$stripcmd"; then 23362ab96baSmrg u_plus_rw= 23462ab96baSmrg else 23562ab96baSmrg u_plus_rw=,u+rw 23662ab96baSmrg fi 23762ab96baSmrg cp_umask=$mode$u_plus_rw;; 23862ab96baSmrg esac 23962ab96baSmrgfi 24062ab96baSmrg 2415eefee25Smacallanfor src 2425eefee25Smacallando 243dc99b369Smrg # Protect names problematic for 'test' and other utilities. 2445eefee25Smacallan case $src in 245dc99b369Smrg -* | [=\(\)!]) src=./$src;; 2465eefee25Smacallan esac 2475eefee25Smacallan 2485eefee25Smacallan if test -n "$dir_arg"; then 2495eefee25Smacallan dst=$src 25062ab96baSmrg dstdir=$dst 25162ab96baSmrg test -d "$dstdir" 25262ab96baSmrg dstdir_status=$? 2535eefee25Smacallan else 25462ab96baSmrg 2555eefee25Smacallan # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2565eefee25Smacallan # might cause directories to be created, which would be especially bad 2575eefee25Smacallan # if $src (and thus $dsttmp) contains '*'. 2585eefee25Smacallan if test ! -f "$src" && test ! -d "$src"; then 2595eefee25Smacallan echo "$0: $src does not exist." >&2 2605eefee25Smacallan exit 1 2615eefee25Smacallan fi 2625eefee25Smacallan 26362ab96baSmrg if test -z "$dst_arg"; then 2645eefee25Smacallan echo "$0: no destination specified." >&2 2655eefee25Smacallan exit 1 2665eefee25Smacallan fi 26762ab96baSmrg dst=$dst_arg 2685eefee25Smacallan 2695eefee25Smacallan # If destination is a directory, append the input filename; won't work 2705eefee25Smacallan # if double slashes aren't ignored. 2715eefee25Smacallan if test -d "$dst"; then 2725eefee25Smacallan if test -n "$no_target_directory"; then 27362ab96baSmrg echo "$0: $dst_arg: Is a directory" >&2 2745eefee25Smacallan exit 1 2755eefee25Smacallan fi 27662ab96baSmrg dstdir=$dst 27762ab96baSmrg dst=$dstdir/`basename "$src"` 27862ab96baSmrg dstdir_status=0 27962ab96baSmrg else 28062ab96baSmrg # Prefer dirname, but fall back on a substitute if dirname fails. 28162ab96baSmrg dstdir=` 28262ab96baSmrg (dirname "$dst") 2>/dev/null || 28362ab96baSmrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 28462ab96baSmrg X"$dst" : 'X\(//\)[^/]' \| \ 28562ab96baSmrg X"$dst" : 'X\(//\)$' \| \ 28662ab96baSmrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 28762ab96baSmrg echo X"$dst" | 28862ab96baSmrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 28962ab96baSmrg s//\1/ 29062ab96baSmrg q 29162ab96baSmrg } 29262ab96baSmrg /^X\(\/\/\)[^/].*/{ 29362ab96baSmrg s//\1/ 29462ab96baSmrg q 29562ab96baSmrg } 29662ab96baSmrg /^X\(\/\/\)$/{ 29762ab96baSmrg s//\1/ 29862ab96baSmrg q 29962ab96baSmrg } 30062ab96baSmrg /^X\(\/\).*/{ 30162ab96baSmrg s//\1/ 30262ab96baSmrg q 30362ab96baSmrg } 30462ab96baSmrg s/.*/./; q' 30562ab96baSmrg ` 30662ab96baSmrg 30762ab96baSmrg test -d "$dstdir" 30862ab96baSmrg dstdir_status=$? 3095eefee25Smacallan fi 3105eefee25Smacallan fi 3115eefee25Smacallan 31262ab96baSmrg obsolete_mkdir_used=false 31362ab96baSmrg 31462ab96baSmrg if test $dstdir_status != 0; then 31562ab96baSmrg case $posix_mkdir in 31662ab96baSmrg '') 31762ab96baSmrg # Create intermediate dirs using mode 755 as modified by the umask. 31862ab96baSmrg # This is like FreeBSD 'install' as of 1997-10-28. 31962ab96baSmrg umask=`umask` 32062ab96baSmrg case $stripcmd.$umask in 32162ab96baSmrg # Optimize common cases. 32262ab96baSmrg *[2367][2367]) mkdir_umask=$umask;; 32362ab96baSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 32462ab96baSmrg 32562ab96baSmrg *[0-7]) 32662ab96baSmrg mkdir_umask=`expr $umask + 22 \ 32762ab96baSmrg - $umask % 100 % 40 + $umask % 20 \ 32862ab96baSmrg - $umask % 10 % 4 + $umask % 2 32962ab96baSmrg `;; 33062ab96baSmrg *) mkdir_umask=$umask,go-w;; 33162ab96baSmrg esac 33262ab96baSmrg 33362ab96baSmrg # With -d, create the new directory with the user-specified mode. 33462ab96baSmrg # Otherwise, rely on $mkdir_umask. 33562ab96baSmrg if test -n "$dir_arg"; then 33662ab96baSmrg mkdir_mode=-m$mode 33762ab96baSmrg else 33862ab96baSmrg mkdir_mode= 33962ab96baSmrg fi 34062ab96baSmrg 34162ab96baSmrg posix_mkdir=false 34262ab96baSmrg case $umask in 34362ab96baSmrg *[123567][0-7][0-7]) 34462ab96baSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 34562ab96baSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 34662ab96baSmrg ;; 34762ab96baSmrg *) 34862ab96baSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 34962ab96baSmrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 35062ab96baSmrg 35162ab96baSmrg if (umask $mkdir_umask && 35262ab96baSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 35362ab96baSmrg then 35462ab96baSmrg if test -z "$dir_arg" || { 35562ab96baSmrg # Check for POSIX incompatibilities with -m. 35662ab96baSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 357dc99b369Smrg # other-writable bit of parent directory when it shouldn't. 35862ab96baSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 35962ab96baSmrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 36062ab96baSmrg case $ls_ld_tmpdir in 36162ab96baSmrg d????-?r-*) different_mode=700;; 36262ab96baSmrg d????-?--*) different_mode=755;; 36362ab96baSmrg *) false;; 36462ab96baSmrg esac && 36562ab96baSmrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 36662ab96baSmrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 36762ab96baSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 36862ab96baSmrg } 36962ab96baSmrg } 37062ab96baSmrg then posix_mkdir=: 37162ab96baSmrg fi 37262ab96baSmrg rmdir "$tmpdir/d" "$tmpdir" 37362ab96baSmrg else 37462ab96baSmrg # Remove any dirs left behind by ancient mkdir implementations. 37562ab96baSmrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 37662ab96baSmrg fi 37762ab96baSmrg trap '' 0;; 37862ab96baSmrg esac;; 37962ab96baSmrg esac 3805eefee25Smacallan 38162ab96baSmrg if 38262ab96baSmrg $posix_mkdir && ( 38362ab96baSmrg umask $mkdir_umask && 38462ab96baSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 38562ab96baSmrg ) 38662ab96baSmrg then : 38762ab96baSmrg else 3885eefee25Smacallan 38962ab96baSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 39062ab96baSmrg # or it failed possibly due to a race condition. Create the 39162ab96baSmrg # directory the slow way, step by step, checking for races as we go. 3925eefee25Smacallan 39362ab96baSmrg case $dstdir in 39462ab96baSmrg /*) prefix='/';; 395dc99b369Smrg [-=\(\)!]*) prefix='./';; 39662ab96baSmrg *) prefix='';; 39762ab96baSmrg esac 3985eefee25Smacallan 39962ab96baSmrg eval "$initialize_posix_glob" 4005eefee25Smacallan 40162ab96baSmrg oIFS=$IFS 40262ab96baSmrg IFS=/ 40362ab96baSmrg $posix_glob set -f 40462ab96baSmrg set fnord $dstdir 4055eefee25Smacallan shift 40662ab96baSmrg $posix_glob set +f 40762ab96baSmrg IFS=$oIFS 40862ab96baSmrg 40962ab96baSmrg prefixes= 41062ab96baSmrg 41162ab96baSmrg for d 41262ab96baSmrg do 413dc99b369Smrg test X"$d" = X && continue 41462ab96baSmrg 41562ab96baSmrg prefix=$prefix$d 41662ab96baSmrg if test -d "$prefix"; then 41762ab96baSmrg prefixes= 41862ab96baSmrg else 41962ab96baSmrg if $posix_mkdir; then 42062ab96baSmrg (umask=$mkdir_umask && 42162ab96baSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42262ab96baSmrg # Don't fail if two instances are running concurrently. 42362ab96baSmrg test -d "$prefix" || exit 1 42462ab96baSmrg else 42562ab96baSmrg case $prefix in 42662ab96baSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42762ab96baSmrg *) qprefix=$prefix;; 42862ab96baSmrg esac 42962ab96baSmrg prefixes="$prefixes '$qprefix'" 43062ab96baSmrg fi 43162ab96baSmrg fi 43262ab96baSmrg prefix=$prefix/ 43362ab96baSmrg done 43462ab96baSmrg 43562ab96baSmrg if test -n "$prefixes"; then 43662ab96baSmrg # Don't fail if two instances are running concurrently. 43762ab96baSmrg (umask $mkdir_umask && 43862ab96baSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 43962ab96baSmrg test -d "$dstdir" || exit 1 44062ab96baSmrg obsolete_mkdir_used=true 4415eefee25Smacallan fi 44262ab96baSmrg fi 4435eefee25Smacallan fi 4445eefee25Smacallan 4455eefee25Smacallan if test -n "$dir_arg"; then 44662ab96baSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 44762ab96baSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 44862ab96baSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 44962ab96baSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4505eefee25Smacallan else 4515eefee25Smacallan 4525eefee25Smacallan # Make a couple of temp file names in the proper directory. 4535eefee25Smacallan dsttmp=$dstdir/_inst.$$_ 4545eefee25Smacallan rmtmp=$dstdir/_rm.$$_ 4555eefee25Smacallan 4565eefee25Smacallan # Trap to clean up those temp files at exit. 4575eefee25Smacallan trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4585eefee25Smacallan 4595eefee25Smacallan # Copy the file name to the temp name. 46062ab96baSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4615eefee25Smacallan 4625eefee25Smacallan # and set any options; do chmod last to preserve setuid bits. 4635eefee25Smacallan # 4645eefee25Smacallan # If any of these fail, we abort the whole thing. If we want to 4655eefee25Smacallan # ignore errors from any of these, just make sure not to ignore 4665eefee25Smacallan # errors from the above "$doit $cpprog $src $dsttmp" command. 4675eefee25Smacallan # 46862ab96baSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 46962ab96baSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 47062ab96baSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 47162ab96baSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 47262ab96baSmrg 47362ab96baSmrg # If -C, don't bother to copy if it wouldn't change the file. 47462ab96baSmrg if $copy_on_change && 47562ab96baSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 47662ab96baSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 47762ab96baSmrg 47862ab96baSmrg eval "$initialize_posix_glob" && 47962ab96baSmrg $posix_glob set -f && 48062ab96baSmrg set X $old && old=:$2:$4:$5:$6 && 48162ab96baSmrg set X $new && new=:$2:$4:$5:$6 && 48262ab96baSmrg $posix_glob set +f && 48362ab96baSmrg 48462ab96baSmrg test "$old" = "$new" && 48562ab96baSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 48662ab96baSmrg then 48762ab96baSmrg rm -f "$dsttmp" 48862ab96baSmrg else 48962ab96baSmrg # Rename the file to the real destination. 49062ab96baSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 49162ab96baSmrg 49262ab96baSmrg # The rename failed, perhaps because mv can't rename something else 49362ab96baSmrg # to itself, or perhaps because mv is so ancient that it does not 49462ab96baSmrg # support -f. 49562ab96baSmrg { 49662ab96baSmrg # Now remove or move aside any old file at destination location. 49762ab96baSmrg # We try this two ways since rm can't unlink itself on some 49862ab96baSmrg # systems and the destination file might be busy for other 49962ab96baSmrg # reasons. In this case, the final cleanup might fail but the new 50062ab96baSmrg # file should still install successfully. 50162ab96baSmrg { 50262ab96baSmrg test ! -f "$dst" || 50362ab96baSmrg $doit $rmcmd -f "$dst" 2>/dev/null || 50462ab96baSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 50562ab96baSmrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 50662ab96baSmrg } || 50762ab96baSmrg { echo "$0: cannot unlink or rename $dst" >&2 50862ab96baSmrg (exit 1); exit 1 50962ab96baSmrg } 51062ab96baSmrg } && 51162ab96baSmrg 51262ab96baSmrg # Now rename the file to the real destination. 51362ab96baSmrg $doit $mvcmd "$dsttmp" "$dst" 51462ab96baSmrg } 51562ab96baSmrg fi || exit 1 51662ab96baSmrg 51762ab96baSmrg trap '' 0 51862ab96baSmrg fi 5195eefee25Smacallandone 5205eefee25Smacallan 5215eefee25Smacallan# Local variables: 5225eefee25Smacallan# eval: (add-hook 'write-file-hooks 'time-stamp) 5235eefee25Smacallan# time-stamp-start: "scriptversion=" 5245eefee25Smacallan# time-stamp-format: "%:y-%02m-%02d.%02H" 525dc99b369Smrg# time-stamp-time-zone: "UTC" 526dc99b369Smrg# time-stamp-end: "; # UTC" 5275eefee25Smacallan# End: 528