install-sh revision 6dda92f9
1af7c02bdSmrg#!/bin/sh 2af7c02bdSmrg# install - install a program, script, or datafile 3af7c02bdSmrg 46dda92f9Smrgscriptversion=2011-01-19.21; # UTC 5af7c02bdSmrg 6af7c02bdSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7af7c02bdSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8af7c02bdSmrg# following copyright and license. 9af7c02bdSmrg# 10af7c02bdSmrg# Copyright (C) 1994 X Consortium 11af7c02bdSmrg# 12af7c02bdSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13af7c02bdSmrg# of this software and associated documentation files (the "Software"), to 14af7c02bdSmrg# deal in the Software without restriction, including without limitation the 15af7c02bdSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16af7c02bdSmrg# sell copies of the Software, and to permit persons to whom the Software is 17af7c02bdSmrg# furnished to do so, subject to the following conditions: 18af7c02bdSmrg# 19af7c02bdSmrg# The above copyright notice and this permission notice shall be included in 20af7c02bdSmrg# all copies or substantial portions of the Software. 21af7c02bdSmrg# 22af7c02bdSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23af7c02bdSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24af7c02bdSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25af7c02bdSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26af7c02bdSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27af7c02bdSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28af7c02bdSmrg# 29af7c02bdSmrg# Except as contained in this notice, the name of the X Consortium shall not 30af7c02bdSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31af7c02bdSmrg# ings in this Software without prior written authorization from the X Consor- 32af7c02bdSmrg# tium. 33af7c02bdSmrg# 34af7c02bdSmrg# 35af7c02bdSmrg# FSF changes to this file are in the public domain. 36af7c02bdSmrg# 37af7c02bdSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38af7c02bdSmrg# `make' implicit rules from creating a file called install from it 39af7c02bdSmrg# when there is no Makefile. 40af7c02bdSmrg# 41af7c02bdSmrg# This script is compatible with the BSD install script, but was written 4281c81b28Smrg# from scratch. 4381c81b28Smrg 4481c81b28Smrgnl=' 4581c81b28Smrg' 4681c81b28SmrgIFS=" "" $nl" 47af7c02bdSmrg 48af7c02bdSmrg# set DOITPROG to echo to test this script 49af7c02bdSmrg 50af7c02bdSmrg# Don't use :- since 4.3BSD and earlier shells don't like it. 5181c81b28Smrgdoit=${DOITPROG-} 5281c81b28Smrgif test -z "$doit"; then 5381c81b28Smrg doit_exec=exec 5481c81b28Smrgelse 5581c81b28Smrg doit_exec=$doit 5681c81b28Smrgfi 57af7c02bdSmrg 5881c81b28Smrg# Put in absolute file names if you don't have them in your path; 5981c81b28Smrg# or use environment vars. 6081c81b28Smrg 6181c81b28Smrgchgrpprog=${CHGRPPROG-chgrp} 6281c81b28Smrgchmodprog=${CHMODPROG-chmod} 6381c81b28Smrgchownprog=${CHOWNPROG-chown} 6481c81b28Smrgcmpprog=${CMPPROG-cmp} 6581c81b28Smrgcpprog=${CPPROG-cp} 6681c81b28Smrgmkdirprog=${MKDIRPROG-mkdir} 6781c81b28Smrgmvprog=${MVPROG-mv} 6881c81b28Smrgrmprog=${RMPROG-rm} 6981c81b28Smrgstripprog=${STRIPPROG-strip} 7081c81b28Smrg 7181c81b28Smrgposix_glob='?' 7281c81b28Smrginitialize_posix_glob=' 7381c81b28Smrg test "$posix_glob" != "?" || { 7481c81b28Smrg if (set -f) 2>/dev/null; then 7581c81b28Smrg posix_glob= 7681c81b28Smrg else 7781c81b28Smrg posix_glob=: 7881c81b28Smrg fi 7981c81b28Smrg } 8081c81b28Smrg' 81af7c02bdSmrg 8281c81b28Smrgposix_mkdir= 8381c81b28Smrg 8481c81b28Smrg# Desired mode of installed file. 8581c81b28Smrgmode=0755 86af7c02bdSmrg 87af7c02bdSmrgchgrpcmd= 8881c81b28Smrgchmodcmd=$chmodprog 8981c81b28Smrgchowncmd= 9081c81b28Smrgmvcmd=$mvprog 91af7c02bdSmrgrmcmd="$rmprog -f" 9281c81b28Smrgstripcmd= 9381c81b28Smrg 94af7c02bdSmrgsrc= 95af7c02bdSmrgdst= 96af7c02bdSmrgdir_arg= 9781c81b28Smrgdst_arg= 9881c81b28Smrg 9981c81b28Smrgcopy_on_change=false 100af7c02bdSmrgno_target_directory= 101af7c02bdSmrg 10281c81b28Smrgusage="\ 10381c81b28SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 104af7c02bdSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 105af7c02bdSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 106af7c02bdSmrg or: $0 [OPTION]... -d DIRECTORIES... 107af7c02bdSmrg 108af7c02bdSmrgIn the 1st form, copy SRCFILE to DSTFILE. 109af7c02bdSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 110af7c02bdSmrgIn the 4th, create DIRECTORIES. 111af7c02bdSmrg 112af7c02bdSmrgOptions: 11381c81b28Smrg --help display this help and exit. 11481c81b28Smrg --version display version info and exit. 11581c81b28Smrg 11681c81b28Smrg -c (ignored) 11781c81b28Smrg -C install only if different (preserve the last data modification time) 11881c81b28Smrg -d create directories instead of installing files. 11981c81b28Smrg -g GROUP $chgrpprog installed files to GROUP. 12081c81b28Smrg -m MODE $chmodprog installed files to MODE. 12181c81b28Smrg -o USER $chownprog installed files to USER. 12281c81b28Smrg -s $stripprog installed files. 12381c81b28Smrg -t DIRECTORY install into DIRECTORY. 12481c81b28Smrg -T report an error if DSTFILE is a directory. 125af7c02bdSmrg 126af7c02bdSmrgEnvironment variables override the default commands: 12781c81b28Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 12881c81b28Smrg RMPROG STRIPPROG 129af7c02bdSmrg" 130af7c02bdSmrg 13181c81b28Smrgwhile test $# -ne 0; do 132af7c02bdSmrg case $1 in 13381c81b28Smrg -c) ;; 13481c81b28Smrg 13581c81b28Smrg -C) copy_on_change=true;; 136af7c02bdSmrg 13781c81b28Smrg -d) dir_arg=true;; 138af7c02bdSmrg 139af7c02bdSmrg -g) chgrpcmd="$chgrpprog $2" 14081c81b28Smrg shift;; 141af7c02bdSmrg 142af7c02bdSmrg --help) echo "$usage"; exit $?;; 143af7c02bdSmrg 14481c81b28Smrg -m) mode=$2 14581c81b28Smrg case $mode in 14681c81b28Smrg *' '* | *' '* | *' 14781c81b28Smrg'* | *'*'* | *'?'* | *'['*) 14881c81b28Smrg echo "$0: invalid mode: $mode" >&2 14981c81b28Smrg exit 1;; 15081c81b28Smrg esac 15181c81b28Smrg shift;; 152af7c02bdSmrg 153af7c02bdSmrg -o) chowncmd="$chownprog $2" 15481c81b28Smrg shift;; 155af7c02bdSmrg 15681c81b28Smrg -s) stripcmd=$stripprog;; 157af7c02bdSmrg 15881c81b28Smrg -t) dst_arg=$2 1596dda92f9Smrg # Protect names problematic for `test' and other utilities. 1606dda92f9Smrg case $dst_arg in 1616dda92f9Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1626dda92f9Smrg esac 16381c81b28Smrg shift;; 164af7c02bdSmrg 16581c81b28Smrg -T) no_target_directory=true;; 166af7c02bdSmrg 167af7c02bdSmrg --version) echo "$0 $scriptversion"; exit $?;; 168af7c02bdSmrg 16981c81b28Smrg --) shift 170af7c02bdSmrg break;; 17181c81b28Smrg 17281c81b28Smrg -*) echo "$0: invalid option: $1" >&2 17381c81b28Smrg exit 1;; 17481c81b28Smrg 17581c81b28Smrg *) break;; 176af7c02bdSmrg esac 17781c81b28Smrg shift 178af7c02bdSmrgdone 179af7c02bdSmrg 18081c81b28Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 18181c81b28Smrg # When -d is used, all remaining arguments are directories to create. 18281c81b28Smrg # When -t is used, the destination is already specified. 18381c81b28Smrg # Otherwise, the last argument is the destination. Remove it from $@. 18481c81b28Smrg for arg 18581c81b28Smrg do 18681c81b28Smrg if test -n "$dst_arg"; then 18781c81b28Smrg # $@ is not empty: it contains at least $arg. 18881c81b28Smrg set fnord "$@" "$dst_arg" 18981c81b28Smrg shift # fnord 19081c81b28Smrg fi 19181c81b28Smrg shift # arg 19281c81b28Smrg dst_arg=$arg 1936dda92f9Smrg # Protect names problematic for `test' and other utilities. 1946dda92f9Smrg case $dst_arg in 1956dda92f9Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1966dda92f9Smrg esac 19781c81b28Smrg done 19881c81b28Smrgfi 19981c81b28Smrg 20081c81b28Smrgif test $# -eq 0; then 201af7c02bdSmrg if test -z "$dir_arg"; then 202af7c02bdSmrg echo "$0: no input file specified." >&2 203af7c02bdSmrg exit 1 204af7c02bdSmrg fi 205af7c02bdSmrg # It's OK to call `install-sh -d' without argument. 206af7c02bdSmrg # This can happen when creating conditional directories. 207af7c02bdSmrg exit 0 208af7c02bdSmrgfi 209af7c02bdSmrg 21081c81b28Smrgif test -z "$dir_arg"; then 2116dda92f9Smrg do_exit='(exit $ret); exit $ret' 2126dda92f9Smrg trap "ret=129; $do_exit" 1 2136dda92f9Smrg trap "ret=130; $do_exit" 2 2146dda92f9Smrg trap "ret=141; $do_exit" 13 2156dda92f9Smrg trap "ret=143; $do_exit" 15 21681c81b28Smrg 21781c81b28Smrg # Set umask so as not to create temps with too-generous modes. 21881c81b28Smrg # However, 'strip' requires both read and write access to temps. 21981c81b28Smrg case $mode in 22081c81b28Smrg # Optimize common cases. 22181c81b28Smrg *644) cp_umask=133;; 22281c81b28Smrg *755) cp_umask=22;; 22381c81b28Smrg 22481c81b28Smrg *[0-7]) 22581c81b28Smrg if test -z "$stripcmd"; then 22681c81b28Smrg u_plus_rw= 22781c81b28Smrg else 22881c81b28Smrg u_plus_rw='% 200' 22981c81b28Smrg fi 23081c81b28Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 23181c81b28Smrg *) 23281c81b28Smrg if test -z "$stripcmd"; then 23381c81b28Smrg u_plus_rw= 23481c81b28Smrg else 23581c81b28Smrg u_plus_rw=,u+rw 23681c81b28Smrg fi 23781c81b28Smrg cp_umask=$mode$u_plus_rw;; 23881c81b28Smrg esac 23981c81b28Smrgfi 24081c81b28Smrg 241af7c02bdSmrgfor src 242af7c02bdSmrgdo 2436dda92f9Smrg # Protect names problematic for `test' and other utilities. 244af7c02bdSmrg case $src in 2456dda92f9Smrg -* | [=\(\)!]) src=./$src;; 246af7c02bdSmrg esac 247af7c02bdSmrg 248af7c02bdSmrg if test -n "$dir_arg"; then 249af7c02bdSmrg dst=$src 25081c81b28Smrg dstdir=$dst 25181c81b28Smrg test -d "$dstdir" 25281c81b28Smrg dstdir_status=$? 253af7c02bdSmrg else 25481c81b28Smrg 255af7c02bdSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 256af7c02bdSmrg # might cause directories to be created, which would be especially bad 257af7c02bdSmrg # if $src (and thus $dsttmp) contains '*'. 258af7c02bdSmrg if test ! -f "$src" && test ! -d "$src"; then 259af7c02bdSmrg echo "$0: $src does not exist." >&2 260af7c02bdSmrg exit 1 261af7c02bdSmrg fi 262af7c02bdSmrg 26381c81b28Smrg if test -z "$dst_arg"; then 264af7c02bdSmrg echo "$0: no destination specified." >&2 265af7c02bdSmrg exit 1 266af7c02bdSmrg fi 26781c81b28Smrg dst=$dst_arg 268af7c02bdSmrg 269af7c02bdSmrg # If destination is a directory, append the input filename; won't work 270af7c02bdSmrg # if double slashes aren't ignored. 271af7c02bdSmrg if test -d "$dst"; then 272af7c02bdSmrg if test -n "$no_target_directory"; then 27381c81b28Smrg echo "$0: $dst_arg: Is a directory" >&2 274af7c02bdSmrg exit 1 275af7c02bdSmrg fi 27681c81b28Smrg dstdir=$dst 27781c81b28Smrg dst=$dstdir/`basename "$src"` 27881c81b28Smrg dstdir_status=0 27981c81b28Smrg else 28081c81b28Smrg # Prefer dirname, but fall back on a substitute if dirname fails. 28181c81b28Smrg dstdir=` 28281c81b28Smrg (dirname "$dst") 2>/dev/null || 28381c81b28Smrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 28481c81b28Smrg X"$dst" : 'X\(//\)[^/]' \| \ 28581c81b28Smrg X"$dst" : 'X\(//\)$' \| \ 28681c81b28Smrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 28781c81b28Smrg echo X"$dst" | 28881c81b28Smrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 28981c81b28Smrg s//\1/ 29081c81b28Smrg q 29181c81b28Smrg } 29281c81b28Smrg /^X\(\/\/\)[^/].*/{ 29381c81b28Smrg s//\1/ 29481c81b28Smrg q 29581c81b28Smrg } 29681c81b28Smrg /^X\(\/\/\)$/{ 29781c81b28Smrg s//\1/ 29881c81b28Smrg q 29981c81b28Smrg } 30081c81b28Smrg /^X\(\/\).*/{ 30181c81b28Smrg s//\1/ 30281c81b28Smrg q 30381c81b28Smrg } 30481c81b28Smrg s/.*/./; q' 30581c81b28Smrg ` 30681c81b28Smrg 30781c81b28Smrg test -d "$dstdir" 30881c81b28Smrg dstdir_status=$? 309af7c02bdSmrg fi 310af7c02bdSmrg fi 311af7c02bdSmrg 31281c81b28Smrg obsolete_mkdir_used=false 31381c81b28Smrg 31481c81b28Smrg if test $dstdir_status != 0; then 31581c81b28Smrg case $posix_mkdir in 31681c81b28Smrg '') 31781c81b28Smrg # Create intermediate dirs using mode 755 as modified by the umask. 31881c81b28Smrg # This is like FreeBSD 'install' as of 1997-10-28. 31981c81b28Smrg umask=`umask` 32081c81b28Smrg case $stripcmd.$umask in 32181c81b28Smrg # Optimize common cases. 32281c81b28Smrg *[2367][2367]) mkdir_umask=$umask;; 32381c81b28Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 32481c81b28Smrg 32581c81b28Smrg *[0-7]) 32681c81b28Smrg mkdir_umask=`expr $umask + 22 \ 32781c81b28Smrg - $umask % 100 % 40 + $umask % 20 \ 32881c81b28Smrg - $umask % 10 % 4 + $umask % 2 32981c81b28Smrg `;; 33081c81b28Smrg *) mkdir_umask=$umask,go-w;; 33181c81b28Smrg esac 33281c81b28Smrg 33381c81b28Smrg # With -d, create the new directory with the user-specified mode. 33481c81b28Smrg # Otherwise, rely on $mkdir_umask. 33581c81b28Smrg if test -n "$dir_arg"; then 33681c81b28Smrg mkdir_mode=-m$mode 33781c81b28Smrg else 33881c81b28Smrg mkdir_mode= 33981c81b28Smrg fi 34081c81b28Smrg 34181c81b28Smrg posix_mkdir=false 34281c81b28Smrg case $umask in 34381c81b28Smrg *[123567][0-7][0-7]) 34481c81b28Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 34581c81b28Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 34681c81b28Smrg ;; 34781c81b28Smrg *) 34881c81b28Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 34981c81b28Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 35081c81b28Smrg 35181c81b28Smrg if (umask $mkdir_umask && 35281c81b28Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 35381c81b28Smrg then 35481c81b28Smrg if test -z "$dir_arg" || { 35581c81b28Smrg # Check for POSIX incompatibilities with -m. 35681c81b28Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 35781c81b28Smrg # other-writeable bit of parent directory when it shouldn't. 35881c81b28Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 35981c81b28Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 36081c81b28Smrg case $ls_ld_tmpdir in 36181c81b28Smrg d????-?r-*) different_mode=700;; 36281c81b28Smrg d????-?--*) different_mode=755;; 36381c81b28Smrg *) false;; 36481c81b28Smrg esac && 36581c81b28Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 36681c81b28Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 36781c81b28Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 36881c81b28Smrg } 36981c81b28Smrg } 37081c81b28Smrg then posix_mkdir=: 37181c81b28Smrg fi 37281c81b28Smrg rmdir "$tmpdir/d" "$tmpdir" 37381c81b28Smrg else 37481c81b28Smrg # Remove any dirs left behind by ancient mkdir implementations. 37581c81b28Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 37681c81b28Smrg fi 37781c81b28Smrg trap '' 0;; 37881c81b28Smrg esac;; 37981c81b28Smrg esac 380af7c02bdSmrg 38181c81b28Smrg if 38281c81b28Smrg $posix_mkdir && ( 38381c81b28Smrg umask $mkdir_umask && 38481c81b28Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 38581c81b28Smrg ) 38681c81b28Smrg then : 38781c81b28Smrg else 388af7c02bdSmrg 38981c81b28Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 39081c81b28Smrg # or it failed possibly due to a race condition. Create the 39181c81b28Smrg # directory the slow way, step by step, checking for races as we go. 392af7c02bdSmrg 39381c81b28Smrg case $dstdir in 39481c81b28Smrg /*) prefix='/';; 3956dda92f9Smrg [-=\(\)!]*) prefix='./';; 39681c81b28Smrg *) prefix='';; 39781c81b28Smrg esac 398af7c02bdSmrg 39981c81b28Smrg eval "$initialize_posix_glob" 400af7c02bdSmrg 40181c81b28Smrg oIFS=$IFS 40281c81b28Smrg IFS=/ 40381c81b28Smrg $posix_glob set -f 40481c81b28Smrg set fnord $dstdir 405af7c02bdSmrg shift 40681c81b28Smrg $posix_glob set +f 40781c81b28Smrg IFS=$oIFS 40881c81b28Smrg 40981c81b28Smrg prefixes= 41081c81b28Smrg 41181c81b28Smrg for d 41281c81b28Smrg do 4136dda92f9Smrg test X"$d" = X && continue 41481c81b28Smrg 41581c81b28Smrg prefix=$prefix$d 41681c81b28Smrg if test -d "$prefix"; then 41781c81b28Smrg prefixes= 41881c81b28Smrg else 41981c81b28Smrg if $posix_mkdir; then 42081c81b28Smrg (umask=$mkdir_umask && 42181c81b28Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 42281c81b28Smrg # Don't fail if two instances are running concurrently. 42381c81b28Smrg test -d "$prefix" || exit 1 42481c81b28Smrg else 42581c81b28Smrg case $prefix in 42681c81b28Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 42781c81b28Smrg *) qprefix=$prefix;; 42881c81b28Smrg esac 42981c81b28Smrg prefixes="$prefixes '$qprefix'" 43081c81b28Smrg fi 43181c81b28Smrg fi 43281c81b28Smrg prefix=$prefix/ 43381c81b28Smrg done 43481c81b28Smrg 43581c81b28Smrg if test -n "$prefixes"; then 43681c81b28Smrg # Don't fail if two instances are running concurrently. 43781c81b28Smrg (umask $mkdir_umask && 43881c81b28Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 43981c81b28Smrg test -d "$dstdir" || exit 1 44081c81b28Smrg obsolete_mkdir_used=true 441af7c02bdSmrg fi 44281c81b28Smrg fi 443af7c02bdSmrg fi 444af7c02bdSmrg 445af7c02bdSmrg if test -n "$dir_arg"; then 44681c81b28Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 44781c81b28Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 44881c81b28Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 44981c81b28Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 450af7c02bdSmrg else 451af7c02bdSmrg 452af7c02bdSmrg # Make a couple of temp file names in the proper directory. 453af7c02bdSmrg dsttmp=$dstdir/_inst.$$_ 454af7c02bdSmrg rmtmp=$dstdir/_rm.$$_ 455af7c02bdSmrg 456af7c02bdSmrg # Trap to clean up those temp files at exit. 457af7c02bdSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 458af7c02bdSmrg 459af7c02bdSmrg # Copy the file name to the temp name. 46081c81b28Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 461af7c02bdSmrg 462af7c02bdSmrg # and set any options; do chmod last to preserve setuid bits. 463af7c02bdSmrg # 464af7c02bdSmrg # If any of these fail, we abort the whole thing. If we want to 465af7c02bdSmrg # ignore errors from any of these, just make sure not to ignore 466af7c02bdSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 467af7c02bdSmrg # 46881c81b28Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 46981c81b28Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 47081c81b28Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 47181c81b28Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 47281c81b28Smrg 47381c81b28Smrg # If -C, don't bother to copy if it wouldn't change the file. 47481c81b28Smrg if $copy_on_change && 47581c81b28Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 47681c81b28Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 47781c81b28Smrg 47881c81b28Smrg eval "$initialize_posix_glob" && 47981c81b28Smrg $posix_glob set -f && 48081c81b28Smrg set X $old && old=:$2:$4:$5:$6 && 48181c81b28Smrg set X $new && new=:$2:$4:$5:$6 && 48281c81b28Smrg $posix_glob set +f && 48381c81b28Smrg 48481c81b28Smrg test "$old" = "$new" && 48581c81b28Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 48681c81b28Smrg then 48781c81b28Smrg rm -f "$dsttmp" 48881c81b28Smrg else 48981c81b28Smrg # Rename the file to the real destination. 49081c81b28Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 49181c81b28Smrg 49281c81b28Smrg # The rename failed, perhaps because mv can't rename something else 49381c81b28Smrg # to itself, or perhaps because mv is so ancient that it does not 49481c81b28Smrg # support -f. 49581c81b28Smrg { 49681c81b28Smrg # Now remove or move aside any old file at destination location. 49781c81b28Smrg # We try this two ways since rm can't unlink itself on some 49881c81b28Smrg # systems and the destination file might be busy for other 49981c81b28Smrg # reasons. In this case, the final cleanup might fail but the new 50081c81b28Smrg # file should still install successfully. 50181c81b28Smrg { 50281c81b28Smrg test ! -f "$dst" || 50381c81b28Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 50481c81b28Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 50581c81b28Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 50681c81b28Smrg } || 50781c81b28Smrg { echo "$0: cannot unlink or rename $dst" >&2 50881c81b28Smrg (exit 1); exit 1 50981c81b28Smrg } 51081c81b28Smrg } && 51181c81b28Smrg 51281c81b28Smrg # Now rename the file to the real destination. 51381c81b28Smrg $doit $mvcmd "$dsttmp" "$dst" 51481c81b28Smrg } 51581c81b28Smrg fi || exit 1 51681c81b28Smrg 51781c81b28Smrg trap '' 0 51881c81b28Smrg fi 519af7c02bdSmrgdone 520af7c02bdSmrg 521af7c02bdSmrg# Local variables: 522af7c02bdSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 523af7c02bdSmrg# time-stamp-start: "scriptversion=" 524af7c02bdSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 52581c81b28Smrg# time-stamp-time-zone: "UTC" 52681c81b28Smrg# time-stamp-end: "; # UTC" 527af7c02bdSmrg# End: 528