1937a2000SPeter Wemm#!/bin/sh 2937a2000SPeter Wemm# install - install a program, script, or datafile 3937a2000SPeter Wemm 4*bca4681bSCy Schubertscriptversion=2014-09-12.12; # UTC 5937a2000SPeter Wemm 6937a2000SPeter Wemm# This originates from X11R5 (mit/util/scripts/install.sh), which was 7937a2000SPeter Wemm# later released in X11R6 (xc/config/util/install.sh) with the 8937a2000SPeter Wemm# following copyright and license. 9937a2000SPeter Wemm# 10937a2000SPeter Wemm# Copyright (C) 1994 X Consortium 11937a2000SPeter Wemm# 12937a2000SPeter Wemm# Permission is hereby granted, free of charge, to any person obtaining a copy 13937a2000SPeter Wemm# of this software and associated documentation files (the "Software"), to 14937a2000SPeter Wemm# deal in the Software without restriction, including without limitation the 15937a2000SPeter Wemm# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16937a2000SPeter Wemm# sell copies of the Software, and to permit persons to whom the Software is 17937a2000SPeter Wemm# furnished to do so, subject to the following conditions: 18937a2000SPeter Wemm# 19937a2000SPeter Wemm# The above copyright notice and this permission notice shall be included in 20937a2000SPeter Wemm# all copies or substantial portions of the Software. 21937a2000SPeter Wemm# 22937a2000SPeter Wemm# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23937a2000SPeter Wemm# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24937a2000SPeter Wemm# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25937a2000SPeter Wemm# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26937a2000SPeter Wemm# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27937a2000SPeter Wemm# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28937a2000SPeter Wemm# 29937a2000SPeter Wemm# Except as contained in this notice, the name of the X Consortium shall not 30937a2000SPeter Wemm# be used in advertising or otherwise to promote the sale, use or other deal- 31937a2000SPeter Wemm# ings in this Software without prior written authorization from the X Consor- 32937a2000SPeter Wemm# tium. 33937a2000SPeter Wemm# 34937a2000SPeter Wemm# 35937a2000SPeter Wemm# FSF changes to this file are in the public domain. 36937a2000SPeter Wemm# 37937a2000SPeter Wemm# Calling this script install-sh is preferred over install.sh, to prevent 38d915215eSBaptiste Daroussin# 'make' implicit rules from creating a file called install from it 39937a2000SPeter Wemm# when there is no Makefile. 40937a2000SPeter Wemm# 41937a2000SPeter Wemm# This script is compatible with the BSD install script, but was written 428bc5c7c0SPeter Wemm# from scratch. 438bc5c7c0SPeter Wemm 44d915215eSBaptiste Daroussintab=' ' 458bc5c7c0SPeter Wemmnl=' 468bc5c7c0SPeter Wemm' 47d915215eSBaptiste DaroussinIFS=" $tab$nl" 48937a2000SPeter Wemm 49d915215eSBaptiste Daroussin# Set DOITPROG to "echo" to test this script. 50937a2000SPeter Wemm 518bc5c7c0SPeter Wemmdoit=${DOITPROG-} 52d915215eSBaptiste Daroussindoit_exec=${doit:-exec} 53937a2000SPeter Wemm 548bc5c7c0SPeter Wemm# Put in absolute file names if you don't have them in your path; 558bc5c7c0SPeter Wemm# or use environment vars. 56937a2000SPeter Wemm 578bc5c7c0SPeter Wemmchgrpprog=${CHGRPPROG-chgrp} 588bc5c7c0SPeter Wemmchmodprog=${CHMODPROG-chmod} 598bc5c7c0SPeter Wemmchownprog=${CHOWNPROG-chown} 608bc5c7c0SPeter Wemmcmpprog=${CMPPROG-cmp} 618bc5c7c0SPeter Wemmcpprog=${CPPROG-cp} 628bc5c7c0SPeter Wemmmkdirprog=${MKDIRPROG-mkdir} 638bc5c7c0SPeter Wemmmvprog=${MVPROG-mv} 648bc5c7c0SPeter Wemmrmprog=${RMPROG-rm} 658bc5c7c0SPeter Wemmstripprog=${STRIPPROG-strip} 66937a2000SPeter Wemm 678bc5c7c0SPeter Wemmposix_mkdir= 688bc5c7c0SPeter Wemm 698bc5c7c0SPeter Wemm# Desired mode of installed file. 708bc5c7c0SPeter Wemmmode=0755 718bc5c7c0SPeter Wemm 72937a2000SPeter Wemmchgrpcmd= 738bc5c7c0SPeter Wemmchmodcmd=$chmodprog 748bc5c7c0SPeter Wemmchowncmd= 758bc5c7c0SPeter Wemmmvcmd=$mvprog 76937a2000SPeter Wemmrmcmd="$rmprog -f" 778bc5c7c0SPeter Wemmstripcmd= 788bc5c7c0SPeter Wemm 79937a2000SPeter Wemmsrc= 80937a2000SPeter Wemmdst= 81937a2000SPeter Wemmdir_arg= 828bc5c7c0SPeter Wemmdst_arg= 838bc5c7c0SPeter Wemm 848bc5c7c0SPeter Wemmcopy_on_change=false 85d915215eSBaptiste Daroussinis_target_a_directory=possibly 86937a2000SPeter Wemm 878bc5c7c0SPeter Wemmusage="\ 888bc5c7c0SPeter WemmUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89937a2000SPeter Wemm or: $0 [OPTION]... SRCFILES... DIRECTORY 90937a2000SPeter Wemm or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91937a2000SPeter Wemm or: $0 [OPTION]... -d DIRECTORIES... 92937a2000SPeter Wemm 93937a2000SPeter WemmIn the 1st form, copy SRCFILE to DSTFILE. 94937a2000SPeter WemmIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95937a2000SPeter WemmIn the 4th, create DIRECTORIES. 96937a2000SPeter Wemm 97937a2000SPeter WemmOptions: 988bc5c7c0SPeter Wemm --help display this help and exit. 998bc5c7c0SPeter Wemm --version display version info and exit. 1008bc5c7c0SPeter Wemm 101937a2000SPeter Wemm -c (ignored) 1028bc5c7c0SPeter Wemm -C install only if different (preserve the last data modification time) 103937a2000SPeter Wemm -d create directories instead of installing files. 104937a2000SPeter Wemm -g GROUP $chgrpprog installed files to GROUP. 105937a2000SPeter Wemm -m MODE $chmodprog installed files to MODE. 106937a2000SPeter Wemm -o USER $chownprog installed files to USER. 107937a2000SPeter Wemm -s $stripprog installed files. 108937a2000SPeter Wemm -t DIRECTORY install into DIRECTORY. 109937a2000SPeter Wemm -T report an error if DSTFILE is a directory. 110937a2000SPeter Wemm 111937a2000SPeter WemmEnvironment variables override the default commands: 1128bc5c7c0SPeter Wemm CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 1138bc5c7c0SPeter Wemm RMPROG STRIPPROG 114937a2000SPeter Wemm" 115937a2000SPeter Wemm 1168bc5c7c0SPeter Wemmwhile test $# -ne 0; do 117937a2000SPeter Wemm case $1 in 1188bc5c7c0SPeter Wemm -c) ;; 119937a2000SPeter Wemm 1208bc5c7c0SPeter Wemm -C) copy_on_change=true;; 1218bc5c7c0SPeter Wemm 1228bc5c7c0SPeter Wemm -d) dir_arg=true;; 123937a2000SPeter Wemm 124937a2000SPeter Wemm -g) chgrpcmd="$chgrpprog $2" 1258bc5c7c0SPeter Wemm shift;; 126937a2000SPeter Wemm 127937a2000SPeter Wemm --help) echo "$usage"; exit $?;; 128937a2000SPeter Wemm 1298bc5c7c0SPeter Wemm -m) mode=$2 1308bc5c7c0SPeter Wemm case $mode in 131d915215eSBaptiste Daroussin *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 1328bc5c7c0SPeter Wemm echo "$0: invalid mode: $mode" >&2 1338bc5c7c0SPeter Wemm exit 1;; 1348bc5c7c0SPeter Wemm esac 1358bc5c7c0SPeter Wemm shift;; 136937a2000SPeter Wemm 137937a2000SPeter Wemm -o) chowncmd="$chownprog $2" 1388bc5c7c0SPeter Wemm shift;; 139937a2000SPeter Wemm 1408bc5c7c0SPeter Wemm -s) stripcmd=$stripprog;; 141937a2000SPeter Wemm 142d915215eSBaptiste Daroussin -t) 143d915215eSBaptiste Daroussin is_target_a_directory=always 144d915215eSBaptiste Daroussin dst_arg=$2 145d915215eSBaptiste Daroussin # Protect names problematic for 'test' and other utilities. 1468bc5c7c0SPeter Wemm case $dst_arg in 1478bc5c7c0SPeter Wemm -* | [=\(\)!]) dst_arg=./$dst_arg;; 1488bc5c7c0SPeter Wemm esac 1498bc5c7c0SPeter Wemm shift;; 150937a2000SPeter Wemm 151d915215eSBaptiste Daroussin -T) is_target_a_directory=never;; 152937a2000SPeter Wemm 153937a2000SPeter Wemm --version) echo "$0 $scriptversion"; exit $?;; 154937a2000SPeter Wemm 1558bc5c7c0SPeter Wemm --) shift 1568bc5c7c0SPeter Wemm break;; 1578bc5c7c0SPeter Wemm 1588bc5c7c0SPeter Wemm -*) echo "$0: invalid option: $1" >&2 1598bc5c7c0SPeter Wemm exit 1;; 1608bc5c7c0SPeter Wemm 1618bc5c7c0SPeter Wemm *) break;; 1628bc5c7c0SPeter Wemm esac 1638bc5c7c0SPeter Wemm shift 1648bc5c7c0SPeter Wemmdone 1658bc5c7c0SPeter Wemm 166d915215eSBaptiste Daroussin# We allow the use of options -d and -T together, by making -d 167d915215eSBaptiste Daroussin# take the precedence; this is for compatibility with GNU install. 168d915215eSBaptiste Daroussin 169d915215eSBaptiste Daroussinif test -n "$dir_arg"; then 170d915215eSBaptiste Daroussin if test -n "$dst_arg"; then 171d915215eSBaptiste Daroussin echo "$0: target directory not allowed when installing a directory." >&2 172d915215eSBaptiste Daroussin exit 1 173d915215eSBaptiste Daroussin fi 174d915215eSBaptiste Daroussinfi 175d915215eSBaptiste Daroussin 1768bc5c7c0SPeter Wemmif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 1778bc5c7c0SPeter Wemm # When -d is used, all remaining arguments are directories to create. 178937a2000SPeter Wemm # When -t is used, the destination is already specified. 179937a2000SPeter Wemm # Otherwise, the last argument is the destination. Remove it from $@. 180937a2000SPeter Wemm for arg 181937a2000SPeter Wemm do 1828bc5c7c0SPeter Wemm if test -n "$dst_arg"; then 183937a2000SPeter Wemm # $@ is not empty: it contains at least $arg. 1848bc5c7c0SPeter Wemm set fnord "$@" "$dst_arg" 185937a2000SPeter Wemm shift # fnord 186937a2000SPeter Wemm fi 187937a2000SPeter Wemm shift # arg 1888bc5c7c0SPeter Wemm dst_arg=$arg 189d915215eSBaptiste Daroussin # Protect names problematic for 'test' and other utilities. 1908bc5c7c0SPeter Wemm case $dst_arg in 1918bc5c7c0SPeter Wemm -* | [=\(\)!]) dst_arg=./$dst_arg;; 192937a2000SPeter Wemm esac 193937a2000SPeter Wemm done 1948bc5c7c0SPeter Wemmfi 195937a2000SPeter Wemm 1968bc5c7c0SPeter Wemmif test $# -eq 0; then 197937a2000SPeter Wemm if test -z "$dir_arg"; then 198937a2000SPeter Wemm echo "$0: no input file specified." >&2 199937a2000SPeter Wemm exit 1 200937a2000SPeter Wemm fi 201d915215eSBaptiste Daroussin # It's OK to call 'install-sh -d' without argument. 202937a2000SPeter Wemm # This can happen when creating conditional directories. 203937a2000SPeter Wemm exit 0 204937a2000SPeter Wemmfi 205937a2000SPeter Wemm 2068bc5c7c0SPeter Wemmif test -z "$dir_arg"; then 207d915215eSBaptiste Daroussin if test $# -gt 1 || test "$is_target_a_directory" = always; then 208d915215eSBaptiste Daroussin if test ! -d "$dst_arg"; then 209d915215eSBaptiste Daroussin echo "$0: $dst_arg: Is not a directory." >&2 210d915215eSBaptiste Daroussin exit 1 211d915215eSBaptiste Daroussin fi 212d915215eSBaptiste Daroussin fi 213d915215eSBaptiste Daroussinfi 214d915215eSBaptiste Daroussin 215d915215eSBaptiste Daroussinif test -z "$dir_arg"; then 2168bc5c7c0SPeter Wemm do_exit='(exit $ret); exit $ret' 2178bc5c7c0SPeter Wemm trap "ret=129; $do_exit" 1 2188bc5c7c0SPeter Wemm trap "ret=130; $do_exit" 2 2198bc5c7c0SPeter Wemm trap "ret=141; $do_exit" 13 2208bc5c7c0SPeter Wemm trap "ret=143; $do_exit" 15 2218bc5c7c0SPeter Wemm 2228bc5c7c0SPeter Wemm # Set umask so as not to create temps with too-generous modes. 2238bc5c7c0SPeter Wemm # However, 'strip' requires both read and write access to temps. 2248bc5c7c0SPeter Wemm case $mode in 2258bc5c7c0SPeter Wemm # Optimize common cases. 2268bc5c7c0SPeter Wemm *644) cp_umask=133;; 2278bc5c7c0SPeter Wemm *755) cp_umask=22;; 2288bc5c7c0SPeter Wemm 2298bc5c7c0SPeter Wemm *[0-7]) 2308bc5c7c0SPeter Wemm if test -z "$stripcmd"; then 2318bc5c7c0SPeter Wemm u_plus_rw= 2328bc5c7c0SPeter Wemm else 2338bc5c7c0SPeter Wemm u_plus_rw='% 200' 2348bc5c7c0SPeter Wemm fi 2358bc5c7c0SPeter Wemm cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 2368bc5c7c0SPeter Wemm *) 2378bc5c7c0SPeter Wemm if test -z "$stripcmd"; then 2388bc5c7c0SPeter Wemm u_plus_rw= 2398bc5c7c0SPeter Wemm else 2408bc5c7c0SPeter Wemm u_plus_rw=,u+rw 2418bc5c7c0SPeter Wemm fi 2428bc5c7c0SPeter Wemm cp_umask=$mode$u_plus_rw;; 2438bc5c7c0SPeter Wemm esac 2448bc5c7c0SPeter Wemmfi 2458bc5c7c0SPeter Wemm 246937a2000SPeter Wemmfor src 247937a2000SPeter Wemmdo 248d915215eSBaptiste Daroussin # Protect names problematic for 'test' and other utilities. 249937a2000SPeter Wemm case $src in 2508bc5c7c0SPeter Wemm -* | [=\(\)!]) src=./$src;; 251937a2000SPeter Wemm esac 252937a2000SPeter Wemm 253937a2000SPeter Wemm if test -n "$dir_arg"; then 254937a2000SPeter Wemm dst=$src 2558bc5c7c0SPeter Wemm dstdir=$dst 2568bc5c7c0SPeter Wemm test -d "$dstdir" 2578bc5c7c0SPeter Wemm dstdir_status=$? 2588bc5c7c0SPeter Wemm else 259937a2000SPeter Wemm 260937a2000SPeter Wemm # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261937a2000SPeter Wemm # might cause directories to be created, which would be especially bad 262937a2000SPeter Wemm # if $src (and thus $dsttmp) contains '*'. 263937a2000SPeter Wemm if test ! -f "$src" && test ! -d "$src"; then 264937a2000SPeter Wemm echo "$0: $src does not exist." >&2 265937a2000SPeter Wemm exit 1 266937a2000SPeter Wemm fi 267937a2000SPeter Wemm 2688bc5c7c0SPeter Wemm if test -z "$dst_arg"; then 269937a2000SPeter Wemm echo "$0: no destination specified." >&2 270937a2000SPeter Wemm exit 1 271937a2000SPeter Wemm fi 2728bc5c7c0SPeter Wemm dst=$dst_arg 273937a2000SPeter Wemm 274937a2000SPeter Wemm # If destination is a directory, append the input filename; won't work 275937a2000SPeter Wemm # if double slashes aren't ignored. 276937a2000SPeter Wemm if test -d "$dst"; then 277d915215eSBaptiste Daroussin if test "$is_target_a_directory" = never; then 2788bc5c7c0SPeter Wemm echo "$0: $dst_arg: Is a directory" >&2 279937a2000SPeter Wemm exit 1 280937a2000SPeter Wemm fi 2818bc5c7c0SPeter Wemm dstdir=$dst 2828bc5c7c0SPeter Wemm dst=$dstdir/`basename "$src"` 2838bc5c7c0SPeter Wemm dstdir_status=0 2848bc5c7c0SPeter Wemm else 285d915215eSBaptiste Daroussin dstdir=`dirname "$dst"` 2868bc5c7c0SPeter Wemm test -d "$dstdir" 2878bc5c7c0SPeter Wemm dstdir_status=$? 288937a2000SPeter Wemm fi 289937a2000SPeter Wemm fi 290937a2000SPeter Wemm 2918bc5c7c0SPeter Wemm obsolete_mkdir_used=false 292937a2000SPeter Wemm 2938bc5c7c0SPeter Wemm if test $dstdir_status != 0; then 2948bc5c7c0SPeter Wemm case $posix_mkdir in 2958bc5c7c0SPeter Wemm '') 2968bc5c7c0SPeter Wemm # Create intermediate dirs using mode 755 as modified by the umask. 2978bc5c7c0SPeter Wemm # This is like FreeBSD 'install' as of 1997-10-28. 2988bc5c7c0SPeter Wemm umask=`umask` 2998bc5c7c0SPeter Wemm case $stripcmd.$umask in 3008bc5c7c0SPeter Wemm # Optimize common cases. 3018bc5c7c0SPeter Wemm *[2367][2367]) mkdir_umask=$umask;; 3028bc5c7c0SPeter Wemm .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303937a2000SPeter Wemm 3048bc5c7c0SPeter Wemm *[0-7]) 3058bc5c7c0SPeter Wemm mkdir_umask=`expr $umask + 22 \ 3068bc5c7c0SPeter Wemm - $umask % 100 % 40 + $umask % 20 \ 3078bc5c7c0SPeter Wemm - $umask % 10 % 4 + $umask % 2 3088bc5c7c0SPeter Wemm `;; 3098bc5c7c0SPeter Wemm *) mkdir_umask=$umask,go-w;; 3108bc5c7c0SPeter Wemm esac 3118bc5c7c0SPeter Wemm 3128bc5c7c0SPeter Wemm # With -d, create the new directory with the user-specified mode. 3138bc5c7c0SPeter Wemm # Otherwise, rely on $mkdir_umask. 3148bc5c7c0SPeter Wemm if test -n "$dir_arg"; then 3158bc5c7c0SPeter Wemm mkdir_mode=-m$mode 3168bc5c7c0SPeter Wemm else 3178bc5c7c0SPeter Wemm mkdir_mode= 3188bc5c7c0SPeter Wemm fi 3198bc5c7c0SPeter Wemm 3208bc5c7c0SPeter Wemm posix_mkdir=false 3218bc5c7c0SPeter Wemm case $umask in 3228bc5c7c0SPeter Wemm *[123567][0-7][0-7]) 3238bc5c7c0SPeter Wemm # POSIX mkdir -p sets u+wx bits regardless of umask, which 3248bc5c7c0SPeter Wemm # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 3258bc5c7c0SPeter Wemm ;; 3268bc5c7c0SPeter Wemm *) 327*bca4681bSCy Schubert # $RANDOM is not portable (e.g. dash); use it when possible to 328*bca4681bSCy Schubert # lower collision chance 3298bc5c7c0SPeter Wemm tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 330*bca4681bSCy Schubert trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 3318bc5c7c0SPeter Wemm 332*bca4681bSCy Schubert # As "mkdir -p" follows symlinks and we work in /tmp possibly; so 333*bca4681bSCy Schubert # create the $tmpdir first (and fail if unsuccessful) to make sure 334*bca4681bSCy Schubert # that nobody tries to guess the $tmpdir name. 3358bc5c7c0SPeter Wemm if (umask $mkdir_umask && 336*bca4681bSCy Schubert $mkdirprog $mkdir_mode "$tmpdir" && 337*bca4681bSCy Schubert exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 3388bc5c7c0SPeter Wemm then 3398bc5c7c0SPeter Wemm if test -z "$dir_arg" || { 3408bc5c7c0SPeter Wemm # Check for POSIX incompatibilities with -m. 3418bc5c7c0SPeter Wemm # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 342d915215eSBaptiste Daroussin # other-writable bit of parent directory when it shouldn't. 3438bc5c7c0SPeter Wemm # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 344*bca4681bSCy Schubert test_tmpdir="$tmpdir/a" 345*bca4681bSCy Schubert ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 3468bc5c7c0SPeter Wemm case $ls_ld_tmpdir in 3478bc5c7c0SPeter Wemm d????-?r-*) different_mode=700;; 3488bc5c7c0SPeter Wemm d????-?--*) different_mode=755;; 3498bc5c7c0SPeter Wemm *) false;; 3508bc5c7c0SPeter Wemm esac && 351*bca4681bSCy Schubert $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 352*bca4681bSCy Schubert ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 3538bc5c7c0SPeter Wemm test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3548bc5c7c0SPeter Wemm } 3558bc5c7c0SPeter Wemm } 3568bc5c7c0SPeter Wemm then posix_mkdir=: 3578bc5c7c0SPeter Wemm fi 358*bca4681bSCy Schubert rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 3598bc5c7c0SPeter Wemm else 3608bc5c7c0SPeter Wemm # Remove any dirs left behind by ancient mkdir implementations. 361*bca4681bSCy Schubert rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 3628bc5c7c0SPeter Wemm fi 3638bc5c7c0SPeter Wemm trap '' 0;; 3648bc5c7c0SPeter Wemm esac;; 3658bc5c7c0SPeter Wemm esac 3668bc5c7c0SPeter Wemm 3678bc5c7c0SPeter Wemm if 3688bc5c7c0SPeter Wemm $posix_mkdir && ( 3698bc5c7c0SPeter Wemm umask $mkdir_umask && 3708bc5c7c0SPeter Wemm $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 3718bc5c7c0SPeter Wemm ) 3728bc5c7c0SPeter Wemm then : 3738bc5c7c0SPeter Wemm else 3748bc5c7c0SPeter Wemm 3758bc5c7c0SPeter Wemm # The umask is ridiculous, or mkdir does not conform to POSIX, 3768bc5c7c0SPeter Wemm # or it failed possibly due to a race condition. Create the 3778bc5c7c0SPeter Wemm # directory the slow way, step by step, checking for races as we go. 3788bc5c7c0SPeter Wemm 3798bc5c7c0SPeter Wemm case $dstdir in 3808bc5c7c0SPeter Wemm /*) prefix='/';; 3818bc5c7c0SPeter Wemm [-=\(\)!]*) prefix='./';; 3828bc5c7c0SPeter Wemm *) prefix='';; 3838bc5c7c0SPeter Wemm esac 3848bc5c7c0SPeter Wemm 385937a2000SPeter Wemm oIFS=$IFS 3868bc5c7c0SPeter Wemm IFS=/ 387d915215eSBaptiste Daroussin set -f 3888bc5c7c0SPeter Wemm set fnord $dstdir 389937a2000SPeter Wemm shift 390d915215eSBaptiste Daroussin set +f 391937a2000SPeter Wemm IFS=$oIFS 392937a2000SPeter Wemm 3938bc5c7c0SPeter Wemm prefixes= 394937a2000SPeter Wemm 3958bc5c7c0SPeter Wemm for d 3968bc5c7c0SPeter Wemm do 3978bc5c7c0SPeter Wemm test X"$d" = X && continue 3988bc5c7c0SPeter Wemm 3998bc5c7c0SPeter Wemm prefix=$prefix$d 4008bc5c7c0SPeter Wemm if test -d "$prefix"; then 4018bc5c7c0SPeter Wemm prefixes= 4028bc5c7c0SPeter Wemm else 4038bc5c7c0SPeter Wemm if $posix_mkdir; then 4048bc5c7c0SPeter Wemm (umask=$mkdir_umask && 4058bc5c7c0SPeter Wemm $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 4068bc5c7c0SPeter Wemm # Don't fail if two instances are running concurrently. 4078bc5c7c0SPeter Wemm test -d "$prefix" || exit 1 4088bc5c7c0SPeter Wemm else 4098bc5c7c0SPeter Wemm case $prefix in 4108bc5c7c0SPeter Wemm *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 4118bc5c7c0SPeter Wemm *) qprefix=$prefix;; 4128bc5c7c0SPeter Wemm esac 4138bc5c7c0SPeter Wemm prefixes="$prefixes '$qprefix'" 414937a2000SPeter Wemm fi 4158bc5c7c0SPeter Wemm fi 4168bc5c7c0SPeter Wemm prefix=$prefix/ 417937a2000SPeter Wemm done 4188bc5c7c0SPeter Wemm 4198bc5c7c0SPeter Wemm if test -n "$prefixes"; then 4208bc5c7c0SPeter Wemm # Don't fail if two instances are running concurrently. 4218bc5c7c0SPeter Wemm (umask $mkdir_umask && 4228bc5c7c0SPeter Wemm eval "\$doit_exec \$mkdirprog $prefixes") || 4238bc5c7c0SPeter Wemm test -d "$dstdir" || exit 1 4248bc5c7c0SPeter Wemm obsolete_mkdir_used=true 4258bc5c7c0SPeter Wemm fi 4268bc5c7c0SPeter Wemm fi 427937a2000SPeter Wemm fi 428937a2000SPeter Wemm 429937a2000SPeter Wemm if test -n "$dir_arg"; then 4308bc5c7c0SPeter Wemm { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 4318bc5c7c0SPeter Wemm { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 4328bc5c7c0SPeter Wemm { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 4338bc5c7c0SPeter Wemm test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 434937a2000SPeter Wemm else 435937a2000SPeter Wemm 436937a2000SPeter Wemm # Make a couple of temp file names in the proper directory. 437937a2000SPeter Wemm dsttmp=$dstdir/_inst.$$_ 438937a2000SPeter Wemm rmtmp=$dstdir/_rm.$$_ 439937a2000SPeter Wemm 440937a2000SPeter Wemm # Trap to clean up those temp files at exit. 441937a2000SPeter Wemm trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 442937a2000SPeter Wemm 443937a2000SPeter Wemm # Copy the file name to the temp name. 4448bc5c7c0SPeter Wemm (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 445937a2000SPeter Wemm 446937a2000SPeter Wemm # and set any options; do chmod last to preserve setuid bits. 447937a2000SPeter Wemm # 448937a2000SPeter Wemm # If any of these fail, we abort the whole thing. If we want to 449937a2000SPeter Wemm # ignore errors from any of these, just make sure not to ignore 450937a2000SPeter Wemm # errors from the above "$doit $cpprog $src $dsttmp" command. 451937a2000SPeter Wemm # 4528bc5c7c0SPeter Wemm { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 4538bc5c7c0SPeter Wemm { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 4548bc5c7c0SPeter Wemm { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 4558bc5c7c0SPeter Wemm { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 456937a2000SPeter Wemm 4578bc5c7c0SPeter Wemm # If -C, don't bother to copy if it wouldn't change the file. 4588bc5c7c0SPeter Wemm if $copy_on_change && 4598bc5c7c0SPeter Wemm old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 4608bc5c7c0SPeter Wemm new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 461d915215eSBaptiste Daroussin set -f && 4628bc5c7c0SPeter Wemm set X $old && old=:$2:$4:$5:$6 && 4638bc5c7c0SPeter Wemm set X $new && new=:$2:$4:$5:$6 && 464d915215eSBaptiste Daroussin set +f && 4658bc5c7c0SPeter Wemm test "$old" = "$new" && 4668bc5c7c0SPeter Wemm $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 4678bc5c7c0SPeter Wemm then 4688bc5c7c0SPeter Wemm rm -f "$dsttmp" 4698bc5c7c0SPeter Wemm else 4708bc5c7c0SPeter Wemm # Rename the file to the real destination. 4718bc5c7c0SPeter Wemm $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 4728bc5c7c0SPeter Wemm 473937a2000SPeter Wemm # The rename failed, perhaps because mv can't rename something else 474937a2000SPeter Wemm # to itself, or perhaps because mv is so ancient that it does not 475937a2000SPeter Wemm # support -f. 4768bc5c7c0SPeter Wemm { 477937a2000SPeter Wemm # Now remove or move aside any old file at destination location. 478937a2000SPeter Wemm # We try this two ways since rm can't unlink itself on some 479937a2000SPeter Wemm # systems and the destination file might be busy for other 480937a2000SPeter Wemm # reasons. In this case, the final cleanup might fail but the new 481937a2000SPeter Wemm # file should still install successfully. 482937a2000SPeter Wemm { 4838bc5c7c0SPeter Wemm test ! -f "$dst" || 4848bc5c7c0SPeter Wemm $doit $rmcmd -f "$dst" 2>/dev/null || 4858bc5c7c0SPeter Wemm { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 4868bc5c7c0SPeter Wemm { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 4878bc5c7c0SPeter Wemm } || 4888bc5c7c0SPeter Wemm { echo "$0: cannot unlink or rename $dst" >&2 489937a2000SPeter Wemm (exit 1); exit 1 490937a2000SPeter Wemm } 491937a2000SPeter Wemm } && 492937a2000SPeter Wemm 493937a2000SPeter Wemm # Now rename the file to the real destination. 4948bc5c7c0SPeter Wemm $doit $mvcmd "$dsttmp" "$dst" 495937a2000SPeter Wemm } 4968bc5c7c0SPeter Wemm fi || exit 1 497937a2000SPeter Wemm 4988bc5c7c0SPeter Wemm trap '' 0 4998bc5c7c0SPeter Wemm fi 5008bc5c7c0SPeter Wemmdone 501937a2000SPeter Wemm 502937a2000SPeter Wemm# Local variables: 503937a2000SPeter Wemm# eval: (add-hook 'write-file-hooks 'time-stamp) 504937a2000SPeter Wemm# time-stamp-start: "scriptversion=" 505937a2000SPeter Wemm# time-stamp-format: "%:y-%02m-%02d.%02H" 5068bc5c7c0SPeter Wemm# time-stamp-time-zone: "UTC" 5078bc5c7c0SPeter Wemm# time-stamp-end: "; # UTC" 508937a2000SPeter Wemm# End: 509