install-sh revision cbc4e2be
1eaef79e5Smrg#!/bin/sh 2eaef79e5Smrg# install - install a program, script, or datafile 3eaef79e5Smrg 4cbc4e2beSmrgscriptversion=2011-11-20.07; # UTC 5eaef79e5Smrg 6eaef79e5Smrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7eaef79e5Smrg# later released in X11R6 (xc/config/util/install.sh) with the 8eaef79e5Smrg# following copyright and license. 9eaef79e5Smrg# 10eaef79e5Smrg# Copyright (C) 1994 X Consortium 11eaef79e5Smrg# 12eaef79e5Smrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13eaef79e5Smrg# of this software and associated documentation files (the "Software"), to 14eaef79e5Smrg# deal in the Software without restriction, including without limitation the 15eaef79e5Smrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16eaef79e5Smrg# sell copies of the Software, and to permit persons to whom the Software is 17eaef79e5Smrg# furnished to do so, subject to the following conditions: 18eaef79e5Smrg# 19eaef79e5Smrg# The above copyright notice and this permission notice shall be included in 20eaef79e5Smrg# all copies or substantial portions of the Software. 21eaef79e5Smrg# 22eaef79e5Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23eaef79e5Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24eaef79e5Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25eaef79e5Smrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26eaef79e5Smrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27eaef79e5Smrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28eaef79e5Smrg# 29eaef79e5Smrg# Except as contained in this notice, the name of the X Consortium shall not 30eaef79e5Smrg# be used in advertising or otherwise to promote the sale, use or other deal- 31eaef79e5Smrg# ings in this Software without prior written authorization from the X Consor- 32eaef79e5Smrg# tium. 33eaef79e5Smrg# 34eaef79e5Smrg# 35eaef79e5Smrg# FSF changes to this file are in the public domain. 36eaef79e5Smrg# 37eaef79e5Smrg# Calling this script install-sh is preferred over install.sh, to prevent 38cbc4e2beSmrg# 'make' implicit rules from creating a file called install from it 39eaef79e5Smrg# when there is no Makefile. 40eaef79e5Smrg# 41eaef79e5Smrg# This script is compatible with the BSD install script, but was written 422b32c8f7Smrg# from scratch. 432b32c8f7Smrg 442b32c8f7Smrgnl=' 452b32c8f7Smrg' 462b32c8f7SmrgIFS=" "" $nl" 47eaef79e5Smrg 48eaef79e5Smrg# set DOITPROG to echo to test this script 49eaef79e5Smrg 50eaef79e5Smrg# Don't use :- since 4.3BSD and earlier shells don't like it. 512b32c8f7Smrgdoit=${DOITPROG-} 522b32c8f7Smrgif test -z "$doit"; then 532b32c8f7Smrg doit_exec=exec 542b32c8f7Smrgelse 552b32c8f7Smrg doit_exec=$doit 562b32c8f7Smrgfi 57eaef79e5Smrg 582b32c8f7Smrg# Put in absolute file names if you don't have them in your path; 592b32c8f7Smrg# or use environment vars. 602b32c8f7Smrg 612b32c8f7Smrgchgrpprog=${CHGRPPROG-chgrp} 622b32c8f7Smrgchmodprog=${CHMODPROG-chmod} 632b32c8f7Smrgchownprog=${CHOWNPROG-chown} 642b32c8f7Smrgcmpprog=${CMPPROG-cmp} 652b32c8f7Smrgcpprog=${CPPROG-cp} 662b32c8f7Smrgmkdirprog=${MKDIRPROG-mkdir} 672b32c8f7Smrgmvprog=${MVPROG-mv} 682b32c8f7Smrgrmprog=${RMPROG-rm} 692b32c8f7Smrgstripprog=${STRIPPROG-strip} 702b32c8f7Smrg 712b32c8f7Smrgposix_glob='?' 722b32c8f7Smrginitialize_posix_glob=' 732b32c8f7Smrg test "$posix_glob" != "?" || { 742b32c8f7Smrg if (set -f) 2>/dev/null; then 752b32c8f7Smrg posix_glob= 762b32c8f7Smrg else 772b32c8f7Smrg posix_glob=: 782b32c8f7Smrg fi 792b32c8f7Smrg } 802b32c8f7Smrg' 81eaef79e5Smrg 822b32c8f7Smrgposix_mkdir= 832b32c8f7Smrg 842b32c8f7Smrg# Desired mode of installed file. 852b32c8f7Smrgmode=0755 86eaef79e5Smrg 87eaef79e5Smrgchgrpcmd= 882b32c8f7Smrgchmodcmd=$chmodprog 892b32c8f7Smrgchowncmd= 902b32c8f7Smrgmvcmd=$mvprog 91eaef79e5Smrgrmcmd="$rmprog -f" 922b32c8f7Smrgstripcmd= 932b32c8f7Smrg 94eaef79e5Smrgsrc= 95eaef79e5Smrgdst= 96eaef79e5Smrgdir_arg= 972b32c8f7Smrgdst_arg= 982b32c8f7Smrg 992b32c8f7Smrgcopy_on_change=false 100eaef79e5Smrgno_target_directory= 101eaef79e5Smrg 1022b32c8f7Smrgusage="\ 1032b32c8f7SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 104eaef79e5Smrg or: $0 [OPTION]... SRCFILES... DIRECTORY 105eaef79e5Smrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 106eaef79e5Smrg or: $0 [OPTION]... -d DIRECTORIES... 107eaef79e5Smrg 108eaef79e5SmrgIn the 1st form, copy SRCFILE to DSTFILE. 109eaef79e5SmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 110eaef79e5SmrgIn the 4th, create DIRECTORIES. 111eaef79e5Smrg 112eaef79e5SmrgOptions: 1132b32c8f7Smrg --help display this help and exit. 1142b32c8f7Smrg --version display version info and exit. 1152b32c8f7Smrg 1162b32c8f7Smrg -c (ignored) 1172b32c8f7Smrg -C install only if different (preserve the last data modification time) 1182b32c8f7Smrg -d create directories instead of installing files. 1192b32c8f7Smrg -g GROUP $chgrpprog installed files to GROUP. 1202b32c8f7Smrg -m MODE $chmodprog installed files to MODE. 1212b32c8f7Smrg -o USER $chownprog installed files to USER. 1222b32c8f7Smrg -s $stripprog installed files. 1232b32c8f7Smrg -t DIRECTORY install into DIRECTORY. 1242b32c8f7Smrg -T report an error if DSTFILE is a directory. 125eaef79e5Smrg 126eaef79e5SmrgEnvironment variables override the default commands: 1272b32c8f7Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1282b32c8f7Smrg RMPROG STRIPPROG 129eaef79e5Smrg" 130eaef79e5Smrg 1312b32c8f7Smrgwhile test $# -ne 0; do 132eaef79e5Smrg case $1 in 1332b32c8f7Smrg -c) ;; 1342b32c8f7Smrg 1352b32c8f7Smrg -C) copy_on_change=true;; 136eaef79e5Smrg 1372b32c8f7Smrg -d) dir_arg=true;; 138eaef79e5Smrg 139eaef79e5Smrg -g) chgrpcmd="$chgrpprog $2" 1402b32c8f7Smrg shift;; 141eaef79e5Smrg 142eaef79e5Smrg --help) echo "$usage"; exit $?;; 143eaef79e5Smrg 1442b32c8f7Smrg -m) mode=$2 1452b32c8f7Smrg case $mode in 1462b32c8f7Smrg *' '* | *' '* | *' 1472b32c8f7Smrg'* | *'*'* | *'?'* | *'['*) 1482b32c8f7Smrg echo "$0: invalid mode: $mode" >&2 1492b32c8f7Smrg exit 1;; 1502b32c8f7Smrg esac 1512b32c8f7Smrg shift;; 152eaef79e5Smrg 153eaef79e5Smrg -o) chowncmd="$chownprog $2" 1542b32c8f7Smrg shift;; 155eaef79e5Smrg 1562b32c8f7Smrg -s) stripcmd=$stripprog;; 157eaef79e5Smrg 1582b32c8f7Smrg -t) dst_arg=$2 159cbc4e2beSmrg # Protect names problematic for 'test' and other utilities. 160cbc4e2beSmrg case $dst_arg in 161cbc4e2beSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 162cbc4e2beSmrg esac 1632b32c8f7Smrg shift;; 164eaef79e5Smrg 1652b32c8f7Smrg -T) no_target_directory=true;; 166eaef79e5Smrg 167eaef79e5Smrg --version) echo "$0 $scriptversion"; exit $?;; 168eaef79e5Smrg 1692b32c8f7Smrg --) shift 170eaef79e5Smrg break;; 1712b32c8f7Smrg 1722b32c8f7Smrg -*) echo "$0: invalid option: $1" >&2 1732b32c8f7Smrg exit 1;; 1742b32c8f7Smrg 1752b32c8f7Smrg *) break;; 176eaef79e5Smrg esac 1772b32c8f7Smrg shift 178eaef79e5Smrgdone 179eaef79e5Smrg 1802b32c8f7Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1812b32c8f7Smrg # When -d is used, all remaining arguments are directories to create. 1822b32c8f7Smrg # When -t is used, the destination is already specified. 1832b32c8f7Smrg # Otherwise, the last argument is the destination. Remove it from $@. 1842b32c8f7Smrg for arg 1852b32c8f7Smrg do 1862b32c8f7Smrg if test -n "$dst_arg"; then 1872b32c8f7Smrg # $@ is not empty: it contains at least $arg. 1882b32c8f7Smrg set fnord "$@" "$dst_arg" 1892b32c8f7Smrg shift # fnord 1902b32c8f7Smrg fi 1912b32c8f7Smrg shift # arg 1922b32c8f7Smrg dst_arg=$arg 193cbc4e2beSmrg # Protect names problematic for 'test' and other utilities. 194cbc4e2beSmrg case $dst_arg in 195cbc4e2beSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 196cbc4e2beSmrg esac 1972b32c8f7Smrg done 1982b32c8f7Smrgfi 1992b32c8f7Smrg 2002b32c8f7Smrgif test $# -eq 0; then 201eaef79e5Smrg if test -z "$dir_arg"; then 202eaef79e5Smrg echo "$0: no input file specified." >&2 203eaef79e5Smrg exit 1 204eaef79e5Smrg fi 205cbc4e2beSmrg # It's OK to call 'install-sh -d' without argument. 206eaef79e5Smrg # This can happen when creating conditional directories. 207eaef79e5Smrg exit 0 208eaef79e5Smrgfi 209eaef79e5Smrg 2102b32c8f7Smrgif test -z "$dir_arg"; then 211cbc4e2beSmrg do_exit='(exit $ret); exit $ret' 212cbc4e2beSmrg trap "ret=129; $do_exit" 1 213cbc4e2beSmrg trap "ret=130; $do_exit" 2 214cbc4e2beSmrg trap "ret=141; $do_exit" 13 215cbc4e2beSmrg trap "ret=143; $do_exit" 15 2162b32c8f7Smrg 2172b32c8f7Smrg # Set umask so as not to create temps with too-generous modes. 2182b32c8f7Smrg # However, 'strip' requires both read and write access to temps. 2192b32c8f7Smrg case $mode in 2202b32c8f7Smrg # Optimize common cases. 2212b32c8f7Smrg *644) cp_umask=133;; 2222b32c8f7Smrg *755) cp_umask=22;; 2232b32c8f7Smrg 2242b32c8f7Smrg *[0-7]) 2252b32c8f7Smrg if test -z "$stripcmd"; then 2262b32c8f7Smrg u_plus_rw= 2272b32c8f7Smrg else 2282b32c8f7Smrg u_plus_rw='% 200' 2292b32c8f7Smrg fi 2302b32c8f7Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2312b32c8f7Smrg *) 2322b32c8f7Smrg if test -z "$stripcmd"; then 2332b32c8f7Smrg u_plus_rw= 2342b32c8f7Smrg else 2352b32c8f7Smrg u_plus_rw=,u+rw 2362b32c8f7Smrg fi 2372b32c8f7Smrg cp_umask=$mode$u_plus_rw;; 2382b32c8f7Smrg esac 2392b32c8f7Smrgfi 2402b32c8f7Smrg 241eaef79e5Smrgfor src 242eaef79e5Smrgdo 243cbc4e2beSmrg # Protect names problematic for 'test' and other utilities. 244eaef79e5Smrg case $src in 245cbc4e2beSmrg -* | [=\(\)!]) src=./$src;; 246eaef79e5Smrg esac 247eaef79e5Smrg 248eaef79e5Smrg if test -n "$dir_arg"; then 249eaef79e5Smrg dst=$src 2502b32c8f7Smrg dstdir=$dst 2512b32c8f7Smrg test -d "$dstdir" 2522b32c8f7Smrg dstdir_status=$? 253eaef79e5Smrg else 2542b32c8f7Smrg 255eaef79e5Smrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 256eaef79e5Smrg # might cause directories to be created, which would be especially bad 257eaef79e5Smrg # if $src (and thus $dsttmp) contains '*'. 258eaef79e5Smrg if test ! -f "$src" && test ! -d "$src"; then 259eaef79e5Smrg echo "$0: $src does not exist." >&2 260eaef79e5Smrg exit 1 261eaef79e5Smrg fi 262eaef79e5Smrg 2632b32c8f7Smrg if test -z "$dst_arg"; then 264eaef79e5Smrg echo "$0: no destination specified." >&2 265eaef79e5Smrg exit 1 266eaef79e5Smrg fi 2672b32c8f7Smrg dst=$dst_arg 268eaef79e5Smrg 269eaef79e5Smrg # If destination is a directory, append the input filename; won't work 270eaef79e5Smrg # if double slashes aren't ignored. 271eaef79e5Smrg if test -d "$dst"; then 272eaef79e5Smrg if test -n "$no_target_directory"; then 2732b32c8f7Smrg echo "$0: $dst_arg: Is a directory" >&2 274eaef79e5Smrg exit 1 275eaef79e5Smrg fi 2762b32c8f7Smrg dstdir=$dst 2772b32c8f7Smrg dst=$dstdir/`basename "$src"` 2782b32c8f7Smrg dstdir_status=0 2792b32c8f7Smrg else 2802b32c8f7Smrg # Prefer dirname, but fall back on a substitute if dirname fails. 2812b32c8f7Smrg dstdir=` 2822b32c8f7Smrg (dirname "$dst") 2>/dev/null || 2832b32c8f7Smrg expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 2842b32c8f7Smrg X"$dst" : 'X\(//\)[^/]' \| \ 2852b32c8f7Smrg X"$dst" : 'X\(//\)$' \| \ 2862b32c8f7Smrg X"$dst" : 'X\(/\)' \| . 2>/dev/null || 2872b32c8f7Smrg echo X"$dst" | 2882b32c8f7Smrg sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 2892b32c8f7Smrg s//\1/ 2902b32c8f7Smrg q 2912b32c8f7Smrg } 2922b32c8f7Smrg /^X\(\/\/\)[^/].*/{ 2932b32c8f7Smrg s//\1/ 2942b32c8f7Smrg q 2952b32c8f7Smrg } 2962b32c8f7Smrg /^X\(\/\/\)$/{ 2972b32c8f7Smrg s//\1/ 2982b32c8f7Smrg q 2992b32c8f7Smrg } 3002b32c8f7Smrg /^X\(\/\).*/{ 3012b32c8f7Smrg s//\1/ 3022b32c8f7Smrg q 3032b32c8f7Smrg } 3042b32c8f7Smrg s/.*/./; q' 3052b32c8f7Smrg ` 3062b32c8f7Smrg 3072b32c8f7Smrg test -d "$dstdir" 3082b32c8f7Smrg dstdir_status=$? 309eaef79e5Smrg fi 310eaef79e5Smrg fi 311eaef79e5Smrg 3122b32c8f7Smrg obsolete_mkdir_used=false 3132b32c8f7Smrg 3142b32c8f7Smrg if test $dstdir_status != 0; then 3152b32c8f7Smrg case $posix_mkdir in 3162b32c8f7Smrg '') 3172b32c8f7Smrg # Create intermediate dirs using mode 755 as modified by the umask. 3182b32c8f7Smrg # This is like FreeBSD 'install' as of 1997-10-28. 3192b32c8f7Smrg umask=`umask` 3202b32c8f7Smrg case $stripcmd.$umask in 3212b32c8f7Smrg # Optimize common cases. 3222b32c8f7Smrg *[2367][2367]) mkdir_umask=$umask;; 3232b32c8f7Smrg .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 3242b32c8f7Smrg 3252b32c8f7Smrg *[0-7]) 3262b32c8f7Smrg mkdir_umask=`expr $umask + 22 \ 3272b32c8f7Smrg - $umask % 100 % 40 + $umask % 20 \ 3282b32c8f7Smrg - $umask % 10 % 4 + $umask % 2 3292b32c8f7Smrg `;; 3302b32c8f7Smrg *) mkdir_umask=$umask,go-w;; 3312b32c8f7Smrg esac 3322b32c8f7Smrg 3332b32c8f7Smrg # With -d, create the new directory with the user-specified mode. 3342b32c8f7Smrg # Otherwise, rely on $mkdir_umask. 3352b32c8f7Smrg if test -n "$dir_arg"; then 3362b32c8f7Smrg mkdir_mode=-m$mode 3372b32c8f7Smrg else 3382b32c8f7Smrg mkdir_mode= 3392b32c8f7Smrg fi 3402b32c8f7Smrg 3412b32c8f7Smrg posix_mkdir=false 3422b32c8f7Smrg case $umask in 3432b32c8f7Smrg *[123567][0-7][0-7]) 3442b32c8f7Smrg # POSIX mkdir -p sets u+wx bits regardless of umask, which 3452b32c8f7Smrg # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3462b32c8f7Smrg ;; 3472b32c8f7Smrg *) 3482b32c8f7Smrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3492b32c8f7Smrg trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 3502b32c8f7Smrg 3512b32c8f7Smrg if (umask $mkdir_umask && 3522b32c8f7Smrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 3532b32c8f7Smrg then 3542b32c8f7Smrg if test -z "$dir_arg" || { 3552b32c8f7Smrg # Check for POSIX incompatibilities with -m. 3562b32c8f7Smrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 357cbc4e2beSmrg # other-writable bit of parent directory when it shouldn't. 3582b32c8f7Smrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3592b32c8f7Smrg ls_ld_tmpdir=`ls -ld "$tmpdir"` 3602b32c8f7Smrg case $ls_ld_tmpdir in 3612b32c8f7Smrg d????-?r-*) different_mode=700;; 3622b32c8f7Smrg d????-?--*) different_mode=755;; 3632b32c8f7Smrg *) false;; 3642b32c8f7Smrg esac && 3652b32c8f7Smrg $mkdirprog -m$different_mode -p -- "$tmpdir" && { 3662b32c8f7Smrg ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 3672b32c8f7Smrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3682b32c8f7Smrg } 3692b32c8f7Smrg } 3702b32c8f7Smrg then posix_mkdir=: 3712b32c8f7Smrg fi 3722b32c8f7Smrg rmdir "$tmpdir/d" "$tmpdir" 3732b32c8f7Smrg else 3742b32c8f7Smrg # Remove any dirs left behind by ancient mkdir implementations. 3752b32c8f7Smrg rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 3762b32c8f7Smrg fi 3772b32c8f7Smrg trap '' 0;; 3782b32c8f7Smrg esac;; 3792b32c8f7Smrg esac 380eaef79e5Smrg 3812b32c8f7Smrg if 3822b32c8f7Smrg $posix_mkdir && ( 3832b32c8f7Smrg umask $mkdir_umask && 3842b32c8f7Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3852b32c8f7Smrg ) 3862b32c8f7Smrg then : 3872b32c8f7Smrg else 388eaef79e5Smrg 3892b32c8f7Smrg # The umask is ridiculous, or mkdir does not conform to POSIX, 3902b32c8f7Smrg # or it failed possibly due to a race condition. Create the 3912b32c8f7Smrg # directory the slow way, step by step, checking for races as we go. 392eaef79e5Smrg 3932b32c8f7Smrg case $dstdir in 3942b32c8f7Smrg /*) prefix='/';; 395cbc4e2beSmrg [-=\(\)!]*) prefix='./';; 3962b32c8f7Smrg *) prefix='';; 3972b32c8f7Smrg esac 398eaef79e5Smrg 3992b32c8f7Smrg eval "$initialize_posix_glob" 400eaef79e5Smrg 4012b32c8f7Smrg oIFS=$IFS 4022b32c8f7Smrg IFS=/ 4032b32c8f7Smrg $posix_glob set -f 4042b32c8f7Smrg set fnord $dstdir 405eaef79e5Smrg shift 4062b32c8f7Smrg $posix_glob set +f 4072b32c8f7Smrg IFS=$oIFS 4082b32c8f7Smrg 4092b32c8f7Smrg prefixes= 4102b32c8f7Smrg 4112b32c8f7Smrg for d 4122b32c8f7Smrg do 413cbc4e2beSmrg test X"$d" = X && continue 4142b32c8f7Smrg 4152b32c8f7Smrg prefix=$prefix$d 4162b32c8f7Smrg if test -d "$prefix"; then 4172b32c8f7Smrg prefixes= 4182b32c8f7Smrg else 4192b32c8f7Smrg if $posix_mkdir; then 4202b32c8f7Smrg (umask=$mkdir_umask && 4212b32c8f7Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4222b32c8f7Smrg # Don't fail if two instances are running concurrently. 4232b32c8f7Smrg test -d "$prefix" || exit 1 4242b32c8f7Smrg else 4252b32c8f7Smrg case $prefix in 4262b32c8f7Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4272b32c8f7Smrg *) qprefix=$prefix;; 4282b32c8f7Smrg esac 4292b32c8f7Smrg prefixes="$prefixes '$qprefix'" 4302b32c8f7Smrg fi 4312b32c8f7Smrg fi 4322b32c8f7Smrg prefix=$prefix/ 4332b32c8f7Smrg done 4342b32c8f7Smrg 4352b32c8f7Smrg if test -n "$prefixes"; then 4362b32c8f7Smrg # Don't fail if two instances are running concurrently. 4372b32c8f7Smrg (umask $mkdir_umask && 4382b32c8f7Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 4392b32c8f7Smrg test -d "$dstdir" || exit 1 4402b32c8f7Smrg obsolete_mkdir_used=true 441eaef79e5Smrg fi 4422b32c8f7Smrg fi 443eaef79e5Smrg fi 444eaef79e5Smrg 445eaef79e5Smrg if test -n "$dir_arg"; then 4462b32c8f7Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4472b32c8f7Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4482b32c8f7Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4492b32c8f7Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 450eaef79e5Smrg else 451eaef79e5Smrg 452eaef79e5Smrg # Make a couple of temp file names in the proper directory. 453eaef79e5Smrg dsttmp=$dstdir/_inst.$$_ 454eaef79e5Smrg rmtmp=$dstdir/_rm.$$_ 455eaef79e5Smrg 456eaef79e5Smrg # Trap to clean up those temp files at exit. 457eaef79e5Smrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 458eaef79e5Smrg 459eaef79e5Smrg # Copy the file name to the temp name. 4602b32c8f7Smrg (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 461eaef79e5Smrg 462eaef79e5Smrg # and set any options; do chmod last to preserve setuid bits. 463eaef79e5Smrg # 464eaef79e5Smrg # If any of these fail, we abort the whole thing. If we want to 465eaef79e5Smrg # ignore errors from any of these, just make sure not to ignore 466eaef79e5Smrg # errors from the above "$doit $cpprog $src $dsttmp" command. 467eaef79e5Smrg # 4682b32c8f7Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4692b32c8f7Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4702b32c8f7Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4712b32c8f7Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 4722b32c8f7Smrg 4732b32c8f7Smrg # If -C, don't bother to copy if it wouldn't change the file. 4742b32c8f7Smrg if $copy_on_change && 4752b32c8f7Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4762b32c8f7Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 4772b32c8f7Smrg 4782b32c8f7Smrg eval "$initialize_posix_glob" && 4792b32c8f7Smrg $posix_glob set -f && 4802b32c8f7Smrg set X $old && old=:$2:$4:$5:$6 && 4812b32c8f7Smrg set X $new && new=:$2:$4:$5:$6 && 4822b32c8f7Smrg $posix_glob set +f && 4832b32c8f7Smrg 4842b32c8f7Smrg test "$old" = "$new" && 4852b32c8f7Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4862b32c8f7Smrg then 4872b32c8f7Smrg rm -f "$dsttmp" 4882b32c8f7Smrg else 4892b32c8f7Smrg # Rename the file to the real destination. 4902b32c8f7Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 4912b32c8f7Smrg 4922b32c8f7Smrg # The rename failed, perhaps because mv can't rename something else 4932b32c8f7Smrg # to itself, or perhaps because mv is so ancient that it does not 4942b32c8f7Smrg # support -f. 4952b32c8f7Smrg { 4962b32c8f7Smrg # Now remove or move aside any old file at destination location. 4972b32c8f7Smrg # We try this two ways since rm can't unlink itself on some 4982b32c8f7Smrg # systems and the destination file might be busy for other 4992b32c8f7Smrg # reasons. In this case, the final cleanup might fail but the new 5002b32c8f7Smrg # file should still install successfully. 5012b32c8f7Smrg { 5022b32c8f7Smrg test ! -f "$dst" || 5032b32c8f7Smrg $doit $rmcmd -f "$dst" 2>/dev/null || 5042b32c8f7Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 5052b32c8f7Smrg { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 5062b32c8f7Smrg } || 5072b32c8f7Smrg { echo "$0: cannot unlink or rename $dst" >&2 5082b32c8f7Smrg (exit 1); exit 1 5092b32c8f7Smrg } 5102b32c8f7Smrg } && 5112b32c8f7Smrg 5122b32c8f7Smrg # Now rename the file to the real destination. 5132b32c8f7Smrg $doit $mvcmd "$dsttmp" "$dst" 5142b32c8f7Smrg } 5152b32c8f7Smrg fi || exit 1 5162b32c8f7Smrg 5172b32c8f7Smrg trap '' 0 5182b32c8f7Smrg fi 519eaef79e5Smrgdone 520eaef79e5Smrg 521eaef79e5Smrg# Local variables: 522eaef79e5Smrg# eval: (add-hook 'write-file-hooks 'time-stamp) 523eaef79e5Smrg# time-stamp-start: "scriptversion=" 524eaef79e5Smrg# time-stamp-format: "%:y-%02m-%02d.%02H" 5252b32c8f7Smrg# time-stamp-time-zone: "UTC" 5262b32c8f7Smrg# time-stamp-end: "; # UTC" 527eaef79e5Smrg# End: 528