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