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