install-sh revision 7d575c90
1fdb3d228Smrg#!/bin/sh 2fdb3d228Smrg# install - install a program, script, or datafile 39b41ff1aSmrg 47d575c90Smrgscriptversion=2011-01-19.21; # UTC 59b41ff1aSmrg 6fdb3d228Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7fdb3d228Smrg# later released in X11R6 (xc/config/util/install.sh) with the 8fdb3d228Smrg# following copyright and license. 9fdb3d228Smrg# 10fdb3d228Smrg# Copyright (C) 1994 X Consortium 11fdb3d228Smrg# 12fdb3d228Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13fdb3d228Smrg# of this software and associated documentation files (the "Software"), to 14fdb3d228Smrg# deal in the Software without restriction, including without limitation the 15fdb3d228Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16fdb3d228Smrg# sell copies of the Software, and to permit persons to whom the Software is 17fdb3d228Smrg# furnished to do so, subject to the following conditions: 18fdb3d228Smrg# 19fdb3d228Smrg# The above copyright notice and this permission notice shall be included in 20fdb3d228Smrg# all copies or substantial portions of the Software. 21fdb3d228Smrg# 22fdb3d228Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23fdb3d228Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24fdb3d228Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25fdb3d228Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26fdb3d228Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27fdb3d228Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28fdb3d228Smrg# 29fdb3d228Smrg# Except as contained in this notice, the name of the X Consortium shall not 30fdb3d228Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 31fdb3d228Smrg# ings in this Software without prior written authorization from the X Consor- 32fdb3d228Smrg# tium. 33fdb3d228Smrg# 34fdb3d228Smrg# 35fdb3d228Smrg# FSF changes to this file are in the public domain. 36fdb3d228Smrg# 37fdb3d228Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38fdb3d228Smrg# `make' implicit rules from creating a file called install from it 39fdb3d228Smrg# when there is no Makefile. 40fdb3d228Smrg# 41fdb3d228Smrg# This script is compatible with the BSD install script, but was written 429b41ff1aSmrg# from scratch. 43fdb3d228Smrg 449b41ff1aSmrgnl=' 459b41ff1aSmrg' 469b41ff1aSmrgIFS=" "" $nl" 47fdb3d228Smrg 48fdb3d228Smrg# set DOITPROG to echo to test this script 49fdb3d228Smrg 50fdb3d228Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 519b41ff1aSmrgdoit=${DOITPROG-} 529b41ff1aSmrgif test -z "$doit"; then 539b41ff1aSmrg doit_exec=exec 54fdb3d228Smrgelse 559b41ff1aSmrg doit_exec=$doit 56fdb3d228Smrgfi 57fdb3d228Smrg 589b41ff1aSmrg# Put in absolute file names if you don't have them in your path; 599b41ff1aSmrg# or use environment vars. 609b41ff1aSmrg 619b41ff1aSmrgchgrpprog=${CHGRPPROG-chgrp} 629b41ff1aSmrgchmodprog=${CHMODPROG-chmod} 639b41ff1aSmrgchownprog=${CHOWNPROG-chown} 649b41ff1aSmrgcmpprog=${CMPPROG-cmp} 659b41ff1aSmrgcpprog=${CPPROG-cp} 669b41ff1aSmrgmkdirprog=${MKDIRPROG-mkdir} 679b41ff1aSmrgmvprog=${MVPROG-mv} 689b41ff1aSmrgrmprog=${RMPROG-rm} 699b41ff1aSmrgstripprog=${STRIPPROG-strip} 709b41ff1aSmrg 719b41ff1aSmrgposix_glob='?' 729b41ff1aSmrginitialize_posix_glob=' 739b41ff1aSmrg test "$posix_glob" != "?" || { 749b41ff1aSmrg if (set -f) 2>/dev/null; then 759b41ff1aSmrg posix_glob= 769b41ff1aSmrg else 779b41ff1aSmrg posix_glob=: 789b41ff1aSmrg fi 799b41ff1aSmrg } 809b41ff1aSmrg' 819b41ff1aSmrg 829b41ff1aSmrgposix_mkdir= 839b41ff1aSmrg 849b41ff1aSmrg# Desired mode of installed file. 859b41ff1aSmrgmode=0755 869b41ff1aSmrg 879b41ff1aSmrgchgrpcmd= 889b41ff1aSmrgchmodcmd=$chmodprog 899b41ff1aSmrgchowncmd= 909b41ff1aSmrgmvcmd=$mvprog 919b41ff1aSmrgrmcmd="$rmprog -f" 929b41ff1aSmrgstripcmd= 93fdb3d228Smrg 949b41ff1aSmrgsrc= 959b41ff1aSmrgdst= 969b41ff1aSmrgdir_arg= 979b41ff1aSmrgdst_arg= 98fdb3d228Smrg 999b41ff1aSmrgcopy_on_change=false 1009b41ff1aSmrgno_target_directory= 101fdb3d228Smrg 1029b41ff1aSmrgusage="\ 1039b41ff1aSmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 1049b41ff1aSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 1059b41ff1aSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 1069b41ff1aSmrg or: $0 [OPTION]... -d DIRECTORIES... 107fdb3d228Smrg 1089b41ff1aSmrgIn the 1st form, copy SRCFILE to DSTFILE. 1099b41ff1aSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 1109b41ff1aSmrgIn the 4th, create DIRECTORIES. 111fdb3d228Smrg 1129b41ff1aSmrgOptions: 1139b41ff1aSmrg --help display this help and exit. 1149b41ff1aSmrg --version display version info and exit. 115fdb3d228Smrg 1169b41ff1aSmrg -c (ignored) 1179b41ff1aSmrg -C install only if different (preserve the last data modification time) 1189b41ff1aSmrg -d create directories instead of installing files. 1199b41ff1aSmrg -g GROUP $chgrpprog installed files to GROUP. 1209b41ff1aSmrg -m MODE $chmodprog installed files to MODE. 1219b41ff1aSmrg -o USER $chownprog installed files to USER. 1229b41ff1aSmrg -s $stripprog installed files. 1239b41ff1aSmrg -t DIRECTORY install into DIRECTORY. 1249b41ff1aSmrg -T report an error if DSTFILE is a directory. 125fdb3d228Smrg 1269b41ff1aSmrgEnvironment variables override the default commands: 1279b41ff1aSmrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1289b41ff1aSmrg RMPROG STRIPPROG 1299b41ff1aSmrg" 130fdb3d228Smrg 1319b41ff1aSmrgwhile test $# -ne 0; do 1329b41ff1aSmrg case $1 in 1339b41ff1aSmrg -c) ;; 134fdb3d228Smrg 1359b41ff1aSmrg -C) copy_on_change=true;; 136fdb3d228Smrg 1379b41ff1aSmrg -d) dir_arg=true;; 138fdb3d228Smrg 1399b41ff1aSmrg -g) chgrpcmd="$chgrpprog $2" 1409b41ff1aSmrg shift;; 141fdb3d228Smrg 1429b41ff1aSmrg --help) echo "$usage"; exit $?;; 143fdb3d228Smrg 1449b41ff1aSmrg -m) mode=$2 1459b41ff1aSmrg case $mode in 1469b41ff1aSmrg *' '* | *' '* | *' 1479b41ff1aSmrg'* | *'*'* | *'?'* | *'['*) 1489b41ff1aSmrg echo "$0: invalid mode: $mode" >&2 1499b41ff1aSmrg exit 1;; 1509b41ff1aSmrg esac 1519b41ff1aSmrg shift;; 152fdb3d228Smrg 1539b41ff1aSmrg -o) chowncmd="$chownprog $2" 1549b41ff1aSmrg shift;; 155fdb3d228Smrg 1569b41ff1aSmrg -s) stripcmd=$stripprog;; 157fdb3d228Smrg 1589b41ff1aSmrg -t) dst_arg=$2 1597d575c90Smrg # Protect names problematic for `test' and other utilities. 1607d575c90Smrg case $dst_arg in 1617d575c90Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1627d575c90Smrg esac 1639b41ff1aSmrg shift;; 164fdb3d228Smrg 1659b41ff1aSmrg -T) no_target_directory=true;; 166fdb3d228Smrg 1679b41ff1aSmrg --version) echo "$0 $scriptversion"; exit $?;; 168fdb3d228Smrg 1699b41ff1aSmrg --) shift 1709b41ff1aSmrg break;; 171fdb3d228Smrg 1729b41ff1aSmrg -*) echo "$0: invalid option: $1" >&2 1739b41ff1aSmrg exit 1;; 174fdb3d228Smrg 1759b41ff1aSmrg *) break;; 1769b41ff1aSmrg esac 1779b41ff1aSmrg shift 1789b41ff1aSmrgdone 179fdb3d228Smrg 1809b41ff1aSmrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1819b41ff1aSmrg # When -d is used, all remaining arguments are directories to create. 1829b41ff1aSmrg # When -t is used, the destination is already specified. 1839b41ff1aSmrg # Otherwise, the last argument is the destination. Remove it from $@. 1849b41ff1aSmrg for arg 1859b41ff1aSmrg do 1869b41ff1aSmrg if test -n "$dst_arg"; then 1879b41ff1aSmrg # $@ is not empty: it contains at least $arg. 1889b41ff1aSmrg set fnord "$@" "$dst_arg" 1899b41ff1aSmrg shift # fnord 1909b41ff1aSmrg fi 1919b41ff1aSmrg shift # arg 1929b41ff1aSmrg dst_arg=$arg 1937d575c90Smrg # Protect names problematic for `test' and other utilities. 1947d575c90Smrg case $dst_arg in 1957d575c90Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 1967d575c90Smrg esac 1979b41ff1aSmrg done 1989b41ff1aSmrgfi 199fdb3d228Smrg 2009b41ff1aSmrgif test $# -eq 0; then 2019b41ff1aSmrg if test -z "$dir_arg"; then 2029b41ff1aSmrg echo "$0: no input file specified." >&2 2039b41ff1aSmrg exit 1 2049b41ff1aSmrg fi 2059b41ff1aSmrg # It's OK to call `install-sh -d' without argument. 2069b41ff1aSmrg # This can happen when creating conditional directories. 2079b41ff1aSmrg exit 0 2089b41ff1aSmrgfi 209fdb3d228Smrg 2109b41ff1aSmrgif test -z "$dir_arg"; then 2117d575c90Smrg do_exit='(exit $ret); exit $ret' 2127d575c90Smrg trap "ret=129; $do_exit" 1 2137d575c90Smrg trap "ret=130; $do_exit" 2 2147d575c90Smrg trap "ret=141; $do_exit" 13 2157d575c90Smrg trap "ret=143; $do_exit" 15 2169b41ff1aSmrg 2179b41ff1aSmrg # Set umask so as not to create temps with too-generous modes. 2189b41ff1aSmrg # However, 'strip' requires both read and write access to temps. 2199b41ff1aSmrg case $mode in 2209b41ff1aSmrg # Optimize common cases. 2219b41ff1aSmrg *644) cp_umask=133;; 2229b41ff1aSmrg *755) cp_umask=22;; 2239b41ff1aSmrg 2249b41ff1aSmrg *[0-7]) 2259b41ff1aSmrg if test -z "$stripcmd"; then 2269b41ff1aSmrg u_plus_rw= 2279b41ff1aSmrg else 2289b41ff1aSmrg u_plus_rw='% 200' 2299b41ff1aSmrg fi 2309b41ff1aSmrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2319b41ff1aSmrg *) 2329b41ff1aSmrg if test -z "$stripcmd"; then 2339b41ff1aSmrg u_plus_rw= 2349b41ff1aSmrg else 2359b41ff1aSmrg u_plus_rw=,u+rw 2369b41ff1aSmrg fi 2379b41ff1aSmrg cp_umask=$mode$u_plus_rw;; 2389b41ff1aSmrg esac 2399b41ff1aSmrgfi 240fdb3d228Smrg 2419b41ff1aSmrgfor src 2429b41ff1aSmrgdo 2437d575c90Smrg # Protect names problematic for `test' and other utilities. 2449b41ff1aSmrg case $src in 2457d575c90Smrg -* | [=\(\)!]) src=./$src;; 2469b41ff1aSmrg esac 2479b41ff1aSmrg 2489b41ff1aSmrg if test -n "$dir_arg"; then 2499b41ff1aSmrg dst=$src 2509b41ff1aSmrg dstdir=$dst 2519b41ff1aSmrg test -d "$dstdir" 2529b41ff1aSmrg dstdir_status=$? 2539b41ff1aSmrg else 2549b41ff1aSmrg 2559b41ff1aSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 2569b41ff1aSmrg # might cause directories to be created, which would be especially bad 2579b41ff1aSmrg # if $src (and thus $dsttmp) contains '*'. 2589b41ff1aSmrg if test ! -f "$src" && test ! -d "$src"; then 2599b41ff1aSmrg echo "$0: $src does not exist." >&2 2609b41ff1aSmrg exit 1 2619b41ff1aSmrg fi 2629b41ff1aSmrg 2639b41ff1aSmrg if test -z "$dst_arg"; then 2649b41ff1aSmrg echo "$0: no destination specified." >&2 2659b41ff1aSmrg exit 1 2669b41ff1aSmrg fi 2679b41ff1aSmrg dst=$dst_arg 268fdb3d228Smrg 2699b41ff1aSmrg # If destination is a directory, append the input filename; won't work 2709b41ff1aSmrg # if double slashes aren't ignored. 2719b41ff1aSmrg if test -d "$dst"; then 2729b41ff1aSmrg if test -n "$no_target_directory"; then 2739b41ff1aSmrg echo "$0: $dst_arg: Is a directory" >&2 2749b41ff1aSmrg exit 1 2759b41ff1aSmrg fi 2769b41ff1aSmrg dstdir=$dst 2779b41ff1aSmrg dst=$dstdir/`basename "$src"` 2789b41ff1aSmrg dstdir_status=0 2799b41ff1aSmrg else 2809b41ff1aSmrg # Prefer dirname, but fall back on a substitute if dirname fails. 2819b41ff1aSmrg dstdir=` 2829b41ff1aSmrg (dirname "$dst") 2>/dev/null || 2839b41ff1aSmrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 2849b41ff1aSmrg X"$dst" : 'X\(//\)[^/]' \| \ 2859b41ff1aSmrg X"$dst" : 'X\(//\)$' \| \ 2869b41ff1aSmrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 2879b41ff1aSmrg echo X"$dst" | 2889b41ff1aSmrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 2899b41ff1aSmrg s//\1/ 2909b41ff1aSmrg q 2919b41ff1aSmrg } 2929b41ff1aSmrg /^X\(\/\/\)[^/].*/{ 2939b41ff1aSmrg s//\1/ 2949b41ff1aSmrg q 2959b41ff1aSmrg } 2969b41ff1aSmrg /^X\(\/\/\)$/{ 2979b41ff1aSmrg s//\1/ 2989b41ff1aSmrg q 2999b41ff1aSmrg } 3009b41ff1aSmrg /^X\(\/\).*/{ 3019b41ff1aSmrg s//\1/ 3029b41ff1aSmrg q 3039b41ff1aSmrg } 3049b41ff1aSmrg s/.*/./; q' 3059b41ff1aSmrg ` 3069b41ff1aSmrg 3079b41ff1aSmrg test -d "$dstdir" 3089b41ff1aSmrg dstdir_status=$? 3099b41ff1aSmrg fi 3109b41ff1aSmrg fi 3119b41ff1aSmrg 3129b41ff1aSmrg obsolete_mkdir_used=false 3139b41ff1aSmrg 3149b41ff1aSmrg if test $dstdir_status != 0; then 3159b41ff1aSmrg case $posix_mkdir in 3169b41ff1aSmrg '') 3179b41ff1aSmrg # Create intermediate dirs using mode 755 as modified by the umask. 3189b41ff1aSmrg # This is like FreeBSD 'install' as of 1997-10-28. 3199b41ff1aSmrg umask=`umask` 3209b41ff1aSmrg case $stripcmd.$umask in 3219b41ff1aSmrg # Optimize common cases. 3229b41ff1aSmrg *[2367][2367]) mkdir_umask=$umask;; 3239b41ff1aSmrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3249b41ff1aSmrg 3259b41ff1aSmrg *[0-7]) 3269b41ff1aSmrg mkdir_umask=`expr $umask + 22 \ 3279b41ff1aSmrg - $umask % 100 % 40 + $umask % 20 \ 3289b41ff1aSmrg - $umask % 10 % 4 + $umask % 2 3299b41ff1aSmrg `;; 3309b41ff1aSmrg *) mkdir_umask=$umask,go-w;; 3319b41ff1aSmrg esac 3329b41ff1aSmrg 3339b41ff1aSmrg # With -d, create the new directory with the user-specified mode. 3349b41ff1aSmrg # Otherwise, rely on $mkdir_umask. 3359b41ff1aSmrg if test -n "$dir_arg"; then 3369b41ff1aSmrg mkdir_mode=-m$mode 337fdb3d228Smrg else 3389b41ff1aSmrg mkdir_mode= 339fdb3d228Smrg fi 340fdb3d228Smrg 3419b41ff1aSmrg posix_mkdir=false 3429b41ff1aSmrg case $umask in 3439b41ff1aSmrg *[123567][0-7][0-7]) 3449b41ff1aSmrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3459b41ff1aSmrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3469b41ff1aSmrg ;; 3479b41ff1aSmrg *) 3489b41ff1aSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3499b41ff1aSmrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 3509b41ff1aSmrg 3519b41ff1aSmrg if (umask $mkdir_umask && 3529b41ff1aSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 3539b41ff1aSmrg then 3549b41ff1aSmrg if test -z "$dir_arg" || { 3559b41ff1aSmrg # Check for POSIX incompatibilities with -m. 3569b41ff1aSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3579b41ff1aSmrg # other-writeable bit of parent directory when it shouldn't. 3589b41ff1aSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3599b41ff1aSmrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 3609b41ff1aSmrg case $ls_ld_tmpdir in 3619b41ff1aSmrg d????-?r-*) different_mode=700;; 3629b41ff1aSmrg d????-?--*) different_mode=755;; 3639b41ff1aSmrg *) false;; 3649b41ff1aSmrg esac && 3659b41ff1aSmrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 3669b41ff1aSmrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 3679b41ff1aSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3689b41ff1aSmrg } 3699b41ff1aSmrg } 3709b41ff1aSmrg then posix_mkdir=: 3719b41ff1aSmrg fi 3729b41ff1aSmrg rmdir "$tmpdir/d" "$tmpdir" 3739b41ff1aSmrg else 3749b41ff1aSmrg # Remove any dirs left behind by ancient mkdir implementations. 3759b41ff1aSmrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 3769b41ff1aSmrg fi 3779b41ff1aSmrg trap '' 0;; 3789b41ff1aSmrg esac;; 3799b41ff1aSmrg esac 380fdb3d228Smrg 3819b41ff1aSmrg if 3829b41ff1aSmrg $posix_mkdir && ( 3839b41ff1aSmrg umask $mkdir_umask && 3849b41ff1aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3859b41ff1aSmrg ) 3869b41ff1aSmrg then : 3879b41ff1aSmrg else 3889b41ff1aSmrg 3899b41ff1aSmrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3909b41ff1aSmrg # or it failed possibly due to a race condition. Create the 3919b41ff1aSmrg # directory the slow way, step by step, checking for races as we go. 3929b41ff1aSmrg 3939b41ff1aSmrg case $dstdir in 3949b41ff1aSmrg /*) prefix='/';; 3957d575c90Smrg [-=\(\)!]*) prefix='./';; 3969b41ff1aSmrg *) prefix='';; 3979b41ff1aSmrg esac 3989b41ff1aSmrg 3999b41ff1aSmrg eval "$initialize_posix_glob" 4009b41ff1aSmrg 4019b41ff1aSmrg oIFS=$IFS 4029b41ff1aSmrg IFS=/ 4039b41ff1aSmrg $posix_glob set -f 4049b41ff1aSmrg set fnord $dstdir 4059b41ff1aSmrg shift 4069b41ff1aSmrg $posix_glob set +f 4079b41ff1aSmrg IFS=$oIFS 4089b41ff1aSmrg 4099b41ff1aSmrg prefixes= 4109b41ff1aSmrg 4119b41ff1aSmrg for d 4129b41ff1aSmrg do 4137d575c90Smrg test X"$d" = X && continue 4149b41ff1aSmrg 4159b41ff1aSmrg prefix=$prefix$d 4169b41ff1aSmrg if test -d "$prefix"; then 4179b41ff1aSmrg prefixes= 4189b41ff1aSmrg else 4199b41ff1aSmrg if $posix_mkdir; then 4209b41ff1aSmrg (umask=$mkdir_umask && 4219b41ff1aSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4229b41ff1aSmrg # Don't fail if two instances are running concurrently. 4239b41ff1aSmrg test -d "$prefix" || exit 1 4249b41ff1aSmrg else 4259b41ff1aSmrg case $prefix in 4269b41ff1aSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4279b41ff1aSmrg *) qprefix=$prefix;; 4289b41ff1aSmrg esac 4299b41ff1aSmrg prefixes="$prefixes '$qprefix'" 4309b41ff1aSmrg fi 4319b41ff1aSmrg fi 4329b41ff1aSmrg prefix=$prefix/ 4339b41ff1aSmrg done 4349b41ff1aSmrg 4359b41ff1aSmrg if test -n "$prefixes"; then 4369b41ff1aSmrg # Don't fail if two instances are running concurrently. 4379b41ff1aSmrg (umask $mkdir_umask && 4389b41ff1aSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 4399b41ff1aSmrg test -d "$dstdir" || exit 1 4409b41ff1aSmrg obsolete_mkdir_used=true 4419b41ff1aSmrg fi 4429b41ff1aSmrg fi 4439b41ff1aSmrg fi 4449b41ff1aSmrg 4459b41ff1aSmrg if test -n "$dir_arg"; then 4469b41ff1aSmrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4479b41ff1aSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4489b41ff1aSmrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4499b41ff1aSmrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 4509b41ff1aSmrg else 4519b41ff1aSmrg 4529b41ff1aSmrg # Make a couple of temp file names in the proper directory. 4539b41ff1aSmrg dsttmp=$dstdir/_inst.$$_ 4549b41ff1aSmrg rmtmp=$dstdir/_rm.$$_ 4559b41ff1aSmrg 4569b41ff1aSmrg # Trap to clean up those temp files at exit. 4579b41ff1aSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 4589b41ff1aSmrg 4599b41ff1aSmrg # Copy the file name to the temp name. 4609b41ff1aSmrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 4619b41ff1aSmrg 4629b41ff1aSmrg # and set any options; do chmod last to preserve setuid bits. 4639b41ff1aSmrg # 4649b41ff1aSmrg # If any of these fail, we abort the whole thing. If we want to 4659b41ff1aSmrg # ignore errors from any of these, just make sure not to ignore 4669b41ff1aSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 4679b41ff1aSmrg # 4689b41ff1aSmrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4699b41ff1aSmrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4709b41ff1aSmrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4719b41ff1aSmrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4729b41ff1aSmrg 4739b41ff1aSmrg # If -C, don't bother to copy if it wouldn't change the file. 4749b41ff1aSmrg if $copy_on_change && 4759b41ff1aSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4769b41ff1aSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4779b41ff1aSmrg 4789b41ff1aSmrg eval "$initialize_posix_glob" && 4799b41ff1aSmrg $posix_glob set -f && 4809b41ff1aSmrg set X $old && old=:$2:$4:$5:$6 && 4819b41ff1aSmrg set X $new && new=:$2:$4:$5:$6 && 4829b41ff1aSmrg $posix_glob set +f && 4839b41ff1aSmrg 4849b41ff1aSmrg test "$old" = "$new" && 4859b41ff1aSmrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4869b41ff1aSmrg then 4879b41ff1aSmrg rm -f "$dsttmp" 4889b41ff1aSmrg else 4899b41ff1aSmrg # Rename the file to the real destination. 4909b41ff1aSmrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 4919b41ff1aSmrg 4929b41ff1aSmrg # The rename failed, perhaps because mv can't rename something else 4939b41ff1aSmrg # to itself, or perhaps because mv is so ancient that it does not 4949b41ff1aSmrg # support -f. 4959b41ff1aSmrg { 4969b41ff1aSmrg # Now remove or move aside any old file at destination location. 4979b41ff1aSmrg # We try this two ways since rm can't unlink itself on some 4989b41ff1aSmrg # systems and the destination file might be busy for other 4999b41ff1aSmrg # reasons. In this case, the final cleanup might fail but the new 5009b41ff1aSmrg # file should still install successfully. 5019b41ff1aSmrg { 5029b41ff1aSmrg test ! -f "$dst" || 5039b41ff1aSmrg $doit $rmcmd -f "$dst" 2>/dev/null || 5049b41ff1aSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 5059b41ff1aSmrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 5069b41ff1aSmrg } || 5079b41ff1aSmrg { echo "$0: cannot unlink or rename $dst" >&2 5089b41ff1aSmrg (exit 1); exit 1 5099b41ff1aSmrg } 5109b41ff1aSmrg } && 5119b41ff1aSmrg 5129b41ff1aSmrg # Now rename the file to the real destination. 5139b41ff1aSmrg $doit $mvcmd "$dsttmp" "$dst" 5149b41ff1aSmrg } 5159b41ff1aSmrg fi || exit 1 5169b41ff1aSmrg 5179b41ff1aSmrg trap '' 0 5189b41ff1aSmrg fi 5199b41ff1aSmrgdone 520fdb3d228Smrg 5219b41ff1aSmrg# Local variables: 5229b41ff1aSmrg# eval: (add-hook 'write-file-hooks 'time-stamp) 5239b41ff1aSmrg# time-stamp-start: "scriptversion=" 5249b41ff1aSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 5259b41ff1aSmrg# time-stamp-time-zone: "UTC" 5269b41ff1aSmrg# time-stamp-end: "; # UTC" 5279b41ff1aSmrg# End: 528