1*5ddc57e5SXin Li#!/bin/sh 2*5ddc57e5SXin Li# install - install a program, script, or datafile 3*5ddc57e5SXin Li 4*5ddc57e5SXin Liscriptversion=2014-09-12.12; # UTC 5*5ddc57e5SXin Li 6*5ddc57e5SXin Li# This originates from X11R5 (mit/util/scripts/install.sh), which was 7*5ddc57e5SXin Li# later released in X11R6 (xc/config/util/install.sh) with the 8*5ddc57e5SXin Li# following copyright and license. 9*5ddc57e5SXin Li# 10*5ddc57e5SXin Li# Copyright (C) 1994 X Consortium 11*5ddc57e5SXin Li# 12*5ddc57e5SXin Li# Permission is hereby granted, free of charge, to any person obtaining a copy 13*5ddc57e5SXin Li# of this software and associated documentation files (the "Software"), to 14*5ddc57e5SXin Li# deal in the Software without restriction, including without limitation the 15*5ddc57e5SXin Li# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16*5ddc57e5SXin Li# sell copies of the Software, and to permit persons to whom the Software is 17*5ddc57e5SXin Li# furnished to do so, subject to the following conditions: 18*5ddc57e5SXin Li# 19*5ddc57e5SXin Li# The above copyright notice and this permission notice shall be included in 20*5ddc57e5SXin Li# all copies or substantial portions of the Software. 21*5ddc57e5SXin Li# 22*5ddc57e5SXin Li# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23*5ddc57e5SXin Li# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24*5ddc57e5SXin Li# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25*5ddc57e5SXin Li# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26*5ddc57e5SXin Li# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27*5ddc57e5SXin Li# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28*5ddc57e5SXin Li# 29*5ddc57e5SXin Li# Except as contained in this notice, the name of the X Consortium shall not 30*5ddc57e5SXin Li# be used in advertising or otherwise to promote the sale, use or other deal- 31*5ddc57e5SXin Li# ings in this Software without prior written authorization from the X Consor- 32*5ddc57e5SXin Li# tium. 33*5ddc57e5SXin Li# 34*5ddc57e5SXin Li# 35*5ddc57e5SXin Li# FSF changes to this file are in the public domain. 36*5ddc57e5SXin Li# 37*5ddc57e5SXin Li# Calling this script install-sh is preferred over install.sh, to prevent 38*5ddc57e5SXin Li# 'make' implicit rules from creating a file called install from it 39*5ddc57e5SXin Li# when there is no Makefile. 40*5ddc57e5SXin Li# 41*5ddc57e5SXin Li# This script is compatible with the BSD install script, but was written 42*5ddc57e5SXin Li# from scratch. 43*5ddc57e5SXin Li 44*5ddc57e5SXin Litab=' ' 45*5ddc57e5SXin Linl=' 46*5ddc57e5SXin Li' 47*5ddc57e5SXin LiIFS=" $tab$nl" 48*5ddc57e5SXin Li 49*5ddc57e5SXin Li# Set DOITPROG to "echo" to test this script. 50*5ddc57e5SXin Li 51*5ddc57e5SXin Lidoit=${DOITPROG-} 52*5ddc57e5SXin Lidoit_exec=${doit:-exec} 53*5ddc57e5SXin Li 54*5ddc57e5SXin Li# Put in absolute file names if you don't have them in your path; 55*5ddc57e5SXin Li# or use environment vars. 56*5ddc57e5SXin Li 57*5ddc57e5SXin Lichgrpprog=${CHGRPPROG-chgrp} 58*5ddc57e5SXin Lichmodprog=${CHMODPROG-chmod} 59*5ddc57e5SXin Lichownprog=${CHOWNPROG-chown} 60*5ddc57e5SXin Licmpprog=${CMPPROG-cmp} 61*5ddc57e5SXin Licpprog=${CPPROG-cp} 62*5ddc57e5SXin Limkdirprog=${MKDIRPROG-mkdir} 63*5ddc57e5SXin Limvprog=${MVPROG-mv} 64*5ddc57e5SXin Lirmprog=${RMPROG-rm} 65*5ddc57e5SXin Listripprog=${STRIPPROG-strip} 66*5ddc57e5SXin Li 67*5ddc57e5SXin Liposix_mkdir= 68*5ddc57e5SXin Li 69*5ddc57e5SXin Li# Desired mode of installed file. 70*5ddc57e5SXin Limode=0755 71*5ddc57e5SXin Li 72*5ddc57e5SXin Lichgrpcmd= 73*5ddc57e5SXin Lichmodcmd=$chmodprog 74*5ddc57e5SXin Lichowncmd= 75*5ddc57e5SXin Limvcmd=$mvprog 76*5ddc57e5SXin Lirmcmd="$rmprog -f" 77*5ddc57e5SXin Listripcmd= 78*5ddc57e5SXin Li 79*5ddc57e5SXin Lisrc= 80*5ddc57e5SXin Lidst= 81*5ddc57e5SXin Lidir_arg= 82*5ddc57e5SXin Lidst_arg= 83*5ddc57e5SXin Li 84*5ddc57e5SXin Licopy_on_change=false 85*5ddc57e5SXin Liis_target_a_directory=possibly 86*5ddc57e5SXin Li 87*5ddc57e5SXin Liusage="\ 88*5ddc57e5SXin LiUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89*5ddc57e5SXin Li or: $0 [OPTION]... SRCFILES... DIRECTORY 90*5ddc57e5SXin Li or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91*5ddc57e5SXin Li or: $0 [OPTION]... -d DIRECTORIES... 92*5ddc57e5SXin Li 93*5ddc57e5SXin LiIn the 1st form, copy SRCFILE to DSTFILE. 94*5ddc57e5SXin LiIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95*5ddc57e5SXin LiIn the 4th, create DIRECTORIES. 96*5ddc57e5SXin Li 97*5ddc57e5SXin LiOptions: 98*5ddc57e5SXin Li --help display this help and exit. 99*5ddc57e5SXin Li --version display version info and exit. 100*5ddc57e5SXin Li 101*5ddc57e5SXin Li -c (ignored) 102*5ddc57e5SXin Li -C install only if different (preserve the last data modification time) 103*5ddc57e5SXin Li -d create directories instead of installing files. 104*5ddc57e5SXin Li -g GROUP $chgrpprog installed files to GROUP. 105*5ddc57e5SXin Li -m MODE $chmodprog installed files to MODE. 106*5ddc57e5SXin Li -o USER $chownprog installed files to USER. 107*5ddc57e5SXin Li -s $stripprog installed files. 108*5ddc57e5SXin Li -t DIRECTORY install into DIRECTORY. 109*5ddc57e5SXin Li -T report an error if DSTFILE is a directory. 110*5ddc57e5SXin Li 111*5ddc57e5SXin LiEnvironment variables override the default commands: 112*5ddc57e5SXin Li CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113*5ddc57e5SXin Li RMPROG STRIPPROG 114*5ddc57e5SXin Li" 115*5ddc57e5SXin Li 116*5ddc57e5SXin Liwhile test $# -ne 0; do 117*5ddc57e5SXin Li case $1 in 118*5ddc57e5SXin Li -c) ;; 119*5ddc57e5SXin Li 120*5ddc57e5SXin Li -C) copy_on_change=true;; 121*5ddc57e5SXin Li 122*5ddc57e5SXin Li -d) dir_arg=true;; 123*5ddc57e5SXin Li 124*5ddc57e5SXin Li -g) chgrpcmd="$chgrpprog $2" 125*5ddc57e5SXin Li shift;; 126*5ddc57e5SXin Li 127*5ddc57e5SXin Li --help) echo "$usage"; exit $?;; 128*5ddc57e5SXin Li 129*5ddc57e5SXin Li -m) mode=$2 130*5ddc57e5SXin Li case $mode in 131*5ddc57e5SXin Li *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132*5ddc57e5SXin Li echo "$0: invalid mode: $mode" >&2 133*5ddc57e5SXin Li exit 1;; 134*5ddc57e5SXin Li esac 135*5ddc57e5SXin Li shift;; 136*5ddc57e5SXin Li 137*5ddc57e5SXin Li -o) chowncmd="$chownprog $2" 138*5ddc57e5SXin Li shift;; 139*5ddc57e5SXin Li 140*5ddc57e5SXin Li -s) stripcmd=$stripprog;; 141*5ddc57e5SXin Li 142*5ddc57e5SXin Li -t) 143*5ddc57e5SXin Li is_target_a_directory=always 144*5ddc57e5SXin Li dst_arg=$2 145*5ddc57e5SXin Li # Protect names problematic for 'test' and other utilities. 146*5ddc57e5SXin Li case $dst_arg in 147*5ddc57e5SXin Li -* | [=\(\)!]) dst_arg=./$dst_arg;; 148*5ddc57e5SXin Li esac 149*5ddc57e5SXin Li shift;; 150*5ddc57e5SXin Li 151*5ddc57e5SXin Li -T) is_target_a_directory=never;; 152*5ddc57e5SXin Li 153*5ddc57e5SXin Li --version) echo "$0 $scriptversion"; exit $?;; 154*5ddc57e5SXin Li 155*5ddc57e5SXin Li --) shift 156*5ddc57e5SXin Li break;; 157*5ddc57e5SXin Li 158*5ddc57e5SXin Li -*) echo "$0: invalid option: $1" >&2 159*5ddc57e5SXin Li exit 1;; 160*5ddc57e5SXin Li 161*5ddc57e5SXin Li *) break;; 162*5ddc57e5SXin Li esac 163*5ddc57e5SXin Li shift 164*5ddc57e5SXin Lidone 165*5ddc57e5SXin Li 166*5ddc57e5SXin Li# We allow the use of options -d and -T together, by making -d 167*5ddc57e5SXin Li# take the precedence; this is for compatibility with GNU install. 168*5ddc57e5SXin Li 169*5ddc57e5SXin Liif test -n "$dir_arg"; then 170*5ddc57e5SXin Li if test -n "$dst_arg"; then 171*5ddc57e5SXin Li echo "$0: target directory not allowed when installing a directory." >&2 172*5ddc57e5SXin Li exit 1 173*5ddc57e5SXin Li fi 174*5ddc57e5SXin Lifi 175*5ddc57e5SXin Li 176*5ddc57e5SXin Liif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177*5ddc57e5SXin Li # When -d is used, all remaining arguments are directories to create. 178*5ddc57e5SXin Li # When -t is used, the destination is already specified. 179*5ddc57e5SXin Li # Otherwise, the last argument is the destination. Remove it from $@. 180*5ddc57e5SXin Li for arg 181*5ddc57e5SXin Li do 182*5ddc57e5SXin Li if test -n "$dst_arg"; then 183*5ddc57e5SXin Li # $@ is not empty: it contains at least $arg. 184*5ddc57e5SXin Li set fnord "$@" "$dst_arg" 185*5ddc57e5SXin Li shift # fnord 186*5ddc57e5SXin Li fi 187*5ddc57e5SXin Li shift # arg 188*5ddc57e5SXin Li dst_arg=$arg 189*5ddc57e5SXin Li # Protect names problematic for 'test' and other utilities. 190*5ddc57e5SXin Li case $dst_arg in 191*5ddc57e5SXin Li -* | [=\(\)!]) dst_arg=./$dst_arg;; 192*5ddc57e5SXin Li esac 193*5ddc57e5SXin Li done 194*5ddc57e5SXin Lifi 195*5ddc57e5SXin Li 196*5ddc57e5SXin Liif test $# -eq 0; then 197*5ddc57e5SXin Li if test -z "$dir_arg"; then 198*5ddc57e5SXin Li echo "$0: no input file specified." >&2 199*5ddc57e5SXin Li exit 1 200*5ddc57e5SXin Li fi 201*5ddc57e5SXin Li # It's OK to call 'install-sh -d' without argument. 202*5ddc57e5SXin Li # This can happen when creating conditional directories. 203*5ddc57e5SXin Li exit 0 204*5ddc57e5SXin Lifi 205*5ddc57e5SXin Li 206*5ddc57e5SXin Liif test -z "$dir_arg"; then 207*5ddc57e5SXin Li if test $# -gt 1 || test "$is_target_a_directory" = always; then 208*5ddc57e5SXin Li if test ! -d "$dst_arg"; then 209*5ddc57e5SXin Li echo "$0: $dst_arg: Is not a directory." >&2 210*5ddc57e5SXin Li exit 1 211*5ddc57e5SXin Li fi 212*5ddc57e5SXin Li fi 213*5ddc57e5SXin Lifi 214*5ddc57e5SXin Li 215*5ddc57e5SXin Liif test -z "$dir_arg"; then 216*5ddc57e5SXin Li do_exit='(exit $ret); exit $ret' 217*5ddc57e5SXin Li trap "ret=129; $do_exit" 1 218*5ddc57e5SXin Li trap "ret=130; $do_exit" 2 219*5ddc57e5SXin Li trap "ret=141; $do_exit" 13 220*5ddc57e5SXin Li trap "ret=143; $do_exit" 15 221*5ddc57e5SXin Li 222*5ddc57e5SXin Li # Set umask so as not to create temps with too-generous modes. 223*5ddc57e5SXin Li # However, 'strip' requires both read and write access to temps. 224*5ddc57e5SXin Li case $mode in 225*5ddc57e5SXin Li # Optimize common cases. 226*5ddc57e5SXin Li *644) cp_umask=133;; 227*5ddc57e5SXin Li *755) cp_umask=22;; 228*5ddc57e5SXin Li 229*5ddc57e5SXin Li *[0-7]) 230*5ddc57e5SXin Li if test -z "$stripcmd"; then 231*5ddc57e5SXin Li u_plus_rw= 232*5ddc57e5SXin Li else 233*5ddc57e5SXin Li u_plus_rw='% 200' 234*5ddc57e5SXin Li fi 235*5ddc57e5SXin Li cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236*5ddc57e5SXin Li *) 237*5ddc57e5SXin Li if test -z "$stripcmd"; then 238*5ddc57e5SXin Li u_plus_rw= 239*5ddc57e5SXin Li else 240*5ddc57e5SXin Li u_plus_rw=,u+rw 241*5ddc57e5SXin Li fi 242*5ddc57e5SXin Li cp_umask=$mode$u_plus_rw;; 243*5ddc57e5SXin Li esac 244*5ddc57e5SXin Lifi 245*5ddc57e5SXin Li 246*5ddc57e5SXin Lifor src 247*5ddc57e5SXin Lido 248*5ddc57e5SXin Li # Protect names problematic for 'test' and other utilities. 249*5ddc57e5SXin Li case $src in 250*5ddc57e5SXin Li -* | [=\(\)!]) src=./$src;; 251*5ddc57e5SXin Li esac 252*5ddc57e5SXin Li 253*5ddc57e5SXin Li if test -n "$dir_arg"; then 254*5ddc57e5SXin Li dst=$src 255*5ddc57e5SXin Li dstdir=$dst 256*5ddc57e5SXin Li test -d "$dstdir" 257*5ddc57e5SXin Li dstdir_status=$? 258*5ddc57e5SXin Li else 259*5ddc57e5SXin Li 260*5ddc57e5SXin Li # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261*5ddc57e5SXin Li # might cause directories to be created, which would be especially bad 262*5ddc57e5SXin Li # if $src (and thus $dsttmp) contains '*'. 263*5ddc57e5SXin Li if test ! -f "$src" && test ! -d "$src"; then 264*5ddc57e5SXin Li echo "$0: $src does not exist." >&2 265*5ddc57e5SXin Li exit 1 266*5ddc57e5SXin Li fi 267*5ddc57e5SXin Li 268*5ddc57e5SXin Li if test -z "$dst_arg"; then 269*5ddc57e5SXin Li echo "$0: no destination specified." >&2 270*5ddc57e5SXin Li exit 1 271*5ddc57e5SXin Li fi 272*5ddc57e5SXin Li dst=$dst_arg 273*5ddc57e5SXin Li 274*5ddc57e5SXin Li # If destination is a directory, append the input filename; won't work 275*5ddc57e5SXin Li # if double slashes aren't ignored. 276*5ddc57e5SXin Li if test -d "$dst"; then 277*5ddc57e5SXin Li if test "$is_target_a_directory" = never; then 278*5ddc57e5SXin Li echo "$0: $dst_arg: Is a directory" >&2 279*5ddc57e5SXin Li exit 1 280*5ddc57e5SXin Li fi 281*5ddc57e5SXin Li dstdir=$dst 282*5ddc57e5SXin Li dst=$dstdir/`basename "$src"` 283*5ddc57e5SXin Li dstdir_status=0 284*5ddc57e5SXin Li else 285*5ddc57e5SXin Li dstdir=`dirname "$dst"` 286*5ddc57e5SXin Li test -d "$dstdir" 287*5ddc57e5SXin Li dstdir_status=$? 288*5ddc57e5SXin Li fi 289*5ddc57e5SXin Li fi 290*5ddc57e5SXin Li 291*5ddc57e5SXin Li obsolete_mkdir_used=false 292*5ddc57e5SXin Li 293*5ddc57e5SXin Li if test $dstdir_status != 0; then 294*5ddc57e5SXin Li case $posix_mkdir in 295*5ddc57e5SXin Li '') 296*5ddc57e5SXin Li # Create intermediate dirs using mode 755 as modified by the umask. 297*5ddc57e5SXin Li # This is like FreeBSD 'install' as of 1997-10-28. 298*5ddc57e5SXin Li umask=`umask` 299*5ddc57e5SXin Li case $stripcmd.$umask in 300*5ddc57e5SXin Li # Optimize common cases. 301*5ddc57e5SXin Li *[2367][2367]) mkdir_umask=$umask;; 302*5ddc57e5SXin Li .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303*5ddc57e5SXin Li 304*5ddc57e5SXin Li *[0-7]) 305*5ddc57e5SXin Li mkdir_umask=`expr $umask + 22 \ 306*5ddc57e5SXin Li - $umask % 100 % 40 + $umask % 20 \ 307*5ddc57e5SXin Li - $umask % 10 % 4 + $umask % 2 308*5ddc57e5SXin Li `;; 309*5ddc57e5SXin Li *) mkdir_umask=$umask,go-w;; 310*5ddc57e5SXin Li esac 311*5ddc57e5SXin Li 312*5ddc57e5SXin Li # With -d, create the new directory with the user-specified mode. 313*5ddc57e5SXin Li # Otherwise, rely on $mkdir_umask. 314*5ddc57e5SXin Li if test -n "$dir_arg"; then 315*5ddc57e5SXin Li mkdir_mode=-m$mode 316*5ddc57e5SXin Li else 317*5ddc57e5SXin Li mkdir_mode= 318*5ddc57e5SXin Li fi 319*5ddc57e5SXin Li 320*5ddc57e5SXin Li posix_mkdir=false 321*5ddc57e5SXin Li case $umask in 322*5ddc57e5SXin Li *[123567][0-7][0-7]) 323*5ddc57e5SXin Li # POSIX mkdir -p sets u+wx bits regardless of umask, which 324*5ddc57e5SXin Li # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325*5ddc57e5SXin Li ;; 326*5ddc57e5SXin Li *) 327*5ddc57e5SXin Li # $RANDOM is not portable (e.g. dash); use it when possible to 328*5ddc57e5SXin Li # lower collision chance 329*5ddc57e5SXin Li tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 330*5ddc57e5SXin Li trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 331*5ddc57e5SXin Li 332*5ddc57e5SXin Li # As "mkdir -p" follows symlinks and we work in /tmp possibly; so 333*5ddc57e5SXin Li # create the $tmpdir first (and fail if unsuccessful) to make sure 334*5ddc57e5SXin Li # that nobody tries to guess the $tmpdir name. 335*5ddc57e5SXin Li if (umask $mkdir_umask && 336*5ddc57e5SXin Li $mkdirprog $mkdir_mode "$tmpdir" && 337*5ddc57e5SXin Li exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 338*5ddc57e5SXin Li then 339*5ddc57e5SXin Li if test -z "$dir_arg" || { 340*5ddc57e5SXin Li # Check for POSIX incompatibilities with -m. 341*5ddc57e5SXin Li # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 342*5ddc57e5SXin Li # other-writable bit of parent directory when it shouldn't. 343*5ddc57e5SXin Li # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 344*5ddc57e5SXin Li test_tmpdir="$tmpdir/a" 345*5ddc57e5SXin Li ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 346*5ddc57e5SXin Li case $ls_ld_tmpdir in 347*5ddc57e5SXin Li d????-?r-*) different_mode=700;; 348*5ddc57e5SXin Li d????-?--*) different_mode=755;; 349*5ddc57e5SXin Li *) false;; 350*5ddc57e5SXin Li esac && 351*5ddc57e5SXin Li $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 352*5ddc57e5SXin Li ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 353*5ddc57e5SXin Li test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 354*5ddc57e5SXin Li } 355*5ddc57e5SXin Li } 356*5ddc57e5SXin Li then posix_mkdir=: 357*5ddc57e5SXin Li fi 358*5ddc57e5SXin Li rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 359*5ddc57e5SXin Li else 360*5ddc57e5SXin Li # Remove any dirs left behind by ancient mkdir implementations. 361*5ddc57e5SXin Li rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 362*5ddc57e5SXin Li fi 363*5ddc57e5SXin Li trap '' 0;; 364*5ddc57e5SXin Li esac;; 365*5ddc57e5SXin Li esac 366*5ddc57e5SXin Li 367*5ddc57e5SXin Li if 368*5ddc57e5SXin Li $posix_mkdir && ( 369*5ddc57e5SXin Li umask $mkdir_umask && 370*5ddc57e5SXin Li $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 371*5ddc57e5SXin Li ) 372*5ddc57e5SXin Li then : 373*5ddc57e5SXin Li else 374*5ddc57e5SXin Li 375*5ddc57e5SXin Li # The umask is ridiculous, or mkdir does not conform to POSIX, 376*5ddc57e5SXin Li # or it failed possibly due to a race condition. Create the 377*5ddc57e5SXin Li # directory the slow way, step by step, checking for races as we go. 378*5ddc57e5SXin Li 379*5ddc57e5SXin Li case $dstdir in 380*5ddc57e5SXin Li /*) prefix='/';; 381*5ddc57e5SXin Li [-=\(\)!]*) prefix='./';; 382*5ddc57e5SXin Li *) prefix='';; 383*5ddc57e5SXin Li esac 384*5ddc57e5SXin Li 385*5ddc57e5SXin Li oIFS=$IFS 386*5ddc57e5SXin Li IFS=/ 387*5ddc57e5SXin Li set -f 388*5ddc57e5SXin Li set fnord $dstdir 389*5ddc57e5SXin Li shift 390*5ddc57e5SXin Li set +f 391*5ddc57e5SXin Li IFS=$oIFS 392*5ddc57e5SXin Li 393*5ddc57e5SXin Li prefixes= 394*5ddc57e5SXin Li 395*5ddc57e5SXin Li for d 396*5ddc57e5SXin Li do 397*5ddc57e5SXin Li test X"$d" = X && continue 398*5ddc57e5SXin Li 399*5ddc57e5SXin Li prefix=$prefix$d 400*5ddc57e5SXin Li if test -d "$prefix"; then 401*5ddc57e5SXin Li prefixes= 402*5ddc57e5SXin Li else 403*5ddc57e5SXin Li if $posix_mkdir; then 404*5ddc57e5SXin Li (umask=$mkdir_umask && 405*5ddc57e5SXin Li $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 406*5ddc57e5SXin Li # Don't fail if two instances are running concurrently. 407*5ddc57e5SXin Li test -d "$prefix" || exit 1 408*5ddc57e5SXin Li else 409*5ddc57e5SXin Li case $prefix in 410*5ddc57e5SXin Li *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 411*5ddc57e5SXin Li *) qprefix=$prefix;; 412*5ddc57e5SXin Li esac 413*5ddc57e5SXin Li prefixes="$prefixes '$qprefix'" 414*5ddc57e5SXin Li fi 415*5ddc57e5SXin Li fi 416*5ddc57e5SXin Li prefix=$prefix/ 417*5ddc57e5SXin Li done 418*5ddc57e5SXin Li 419*5ddc57e5SXin Li if test -n "$prefixes"; then 420*5ddc57e5SXin Li # Don't fail if two instances are running concurrently. 421*5ddc57e5SXin Li (umask $mkdir_umask && 422*5ddc57e5SXin Li eval "\$doit_exec \$mkdirprog $prefixes") || 423*5ddc57e5SXin Li test -d "$dstdir" || exit 1 424*5ddc57e5SXin Li obsolete_mkdir_used=true 425*5ddc57e5SXin Li fi 426*5ddc57e5SXin Li fi 427*5ddc57e5SXin Li fi 428*5ddc57e5SXin Li 429*5ddc57e5SXin Li if test -n "$dir_arg"; then 430*5ddc57e5SXin Li { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 431*5ddc57e5SXin Li { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 432*5ddc57e5SXin Li { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 433*5ddc57e5SXin Li test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 434*5ddc57e5SXin Li else 435*5ddc57e5SXin Li 436*5ddc57e5SXin Li # Make a couple of temp file names in the proper directory. 437*5ddc57e5SXin Li dsttmp=$dstdir/_inst.$$_ 438*5ddc57e5SXin Li rmtmp=$dstdir/_rm.$$_ 439*5ddc57e5SXin Li 440*5ddc57e5SXin Li # Trap to clean up those temp files at exit. 441*5ddc57e5SXin Li trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 442*5ddc57e5SXin Li 443*5ddc57e5SXin Li # Copy the file name to the temp name. 444*5ddc57e5SXin Li (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 445*5ddc57e5SXin Li 446*5ddc57e5SXin Li # and set any options; do chmod last to preserve setuid bits. 447*5ddc57e5SXin Li # 448*5ddc57e5SXin Li # If any of these fail, we abort the whole thing. If we want to 449*5ddc57e5SXin Li # ignore errors from any of these, just make sure not to ignore 450*5ddc57e5SXin Li # errors from the above "$doit $cpprog $src $dsttmp" command. 451*5ddc57e5SXin Li # 452*5ddc57e5SXin Li { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 453*5ddc57e5SXin Li { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 454*5ddc57e5SXin Li { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 455*5ddc57e5SXin Li { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 456*5ddc57e5SXin Li 457*5ddc57e5SXin Li # If -C, don't bother to copy if it wouldn't change the file. 458*5ddc57e5SXin Li if $copy_on_change && 459*5ddc57e5SXin Li old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 460*5ddc57e5SXin Li new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 461*5ddc57e5SXin Li set -f && 462*5ddc57e5SXin Li set X $old && old=:$2:$4:$5:$6 && 463*5ddc57e5SXin Li set X $new && new=:$2:$4:$5:$6 && 464*5ddc57e5SXin Li set +f && 465*5ddc57e5SXin Li test "$old" = "$new" && 466*5ddc57e5SXin Li $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 467*5ddc57e5SXin Li then 468*5ddc57e5SXin Li rm -f "$dsttmp" 469*5ddc57e5SXin Li else 470*5ddc57e5SXin Li # Rename the file to the real destination. 471*5ddc57e5SXin Li $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 472*5ddc57e5SXin Li 473*5ddc57e5SXin Li # The rename failed, perhaps because mv can't rename something else 474*5ddc57e5SXin Li # to itself, or perhaps because mv is so ancient that it does not 475*5ddc57e5SXin Li # support -f. 476*5ddc57e5SXin Li { 477*5ddc57e5SXin Li # Now remove or move aside any old file at destination location. 478*5ddc57e5SXin Li # We try this two ways since rm can't unlink itself on some 479*5ddc57e5SXin Li # systems and the destination file might be busy for other 480*5ddc57e5SXin Li # reasons. In this case, the final cleanup might fail but the new 481*5ddc57e5SXin Li # file should still install successfully. 482*5ddc57e5SXin Li { 483*5ddc57e5SXin Li test ! -f "$dst" || 484*5ddc57e5SXin Li $doit $rmcmd -f "$dst" 2>/dev/null || 485*5ddc57e5SXin Li { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 486*5ddc57e5SXin Li { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 487*5ddc57e5SXin Li } || 488*5ddc57e5SXin Li { echo "$0: cannot unlink or rename $dst" >&2 489*5ddc57e5SXin Li (exit 1); exit 1 490*5ddc57e5SXin Li } 491*5ddc57e5SXin Li } && 492*5ddc57e5SXin Li 493*5ddc57e5SXin Li # Now rename the file to the real destination. 494*5ddc57e5SXin Li $doit $mvcmd "$dsttmp" "$dst" 495*5ddc57e5SXin Li } 496*5ddc57e5SXin Li fi || exit 1 497*5ddc57e5SXin Li 498*5ddc57e5SXin Li trap '' 0 499*5ddc57e5SXin Li fi 500*5ddc57e5SXin Lidone 501*5ddc57e5SXin Li 502*5ddc57e5SXin Li# Local variables: 503*5ddc57e5SXin Li# eval: (add-hook 'write-file-hooks 'time-stamp) 504*5ddc57e5SXin Li# time-stamp-start: "scriptversion=" 505*5ddc57e5SXin Li# time-stamp-format: "%:y-%02m-%02d.%02H" 506*5ddc57e5SXin Li# time-stamp-time-zone: "UTC" 507*5ddc57e5SXin Li# time-stamp-end: "; # UTC" 508*5ddc57e5SXin Li# End: 509