1dbbd9e4bSmacallan#!/bin/sh 2dbbd9e4bSmacallan# install - install a program, script, or datafile 3dbbd9e4bSmacallan 4cfa76ccdSmrgscriptversion=2020-11-14.01; # 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 38e96acad6Smrg# '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 44cfa76ccdSmrgtab=' ' 45dbbd9e4bSmacallannl=' 46dbbd9e4bSmacallan' 47cfa76ccdSmrgIFS=" $tab$nl" 48dbbd9e4bSmacallan 49cfa76ccdSmrg# Set DOITPROG to "echo" to test this script. 50dbbd9e4bSmacallan 51dbbd9e4bSmacallandoit=${DOITPROG-} 52cfa76ccdSmrgdoit_exec=${doit:-exec} 53dbbd9e4bSmacallan 54dbbd9e4bSmacallan# Put in absolute file names if you don't have them in your path; 55dbbd9e4bSmacallan# or use environment vars. 56dbbd9e4bSmacallan 57dbbd9e4bSmacallanchgrpprog=${CHGRPPROG-chgrp} 58dbbd9e4bSmacallanchmodprog=${CHMODPROG-chmod} 59dbbd9e4bSmacallanchownprog=${CHOWNPROG-chown} 60dbbd9e4bSmacallancmpprog=${CMPPROG-cmp} 61dbbd9e4bSmacallancpprog=${CPPROG-cp} 62dbbd9e4bSmacallanmkdirprog=${MKDIRPROG-mkdir} 63dbbd9e4bSmacallanmvprog=${MVPROG-mv} 64dbbd9e4bSmacallanrmprog=${RMPROG-rm} 65dbbd9e4bSmacallanstripprog=${STRIPPROG-strip} 66dbbd9e4bSmacallan 67dbbd9e4bSmacallanposix_mkdir= 68dbbd9e4bSmacallan 69dbbd9e4bSmacallan# Desired mode of installed file. 70dbbd9e4bSmacallanmode=0755 71dbbd9e4bSmacallan 72cfa76ccdSmrg# Create dirs (including intermediate dirs) using mode 755. 73cfa76ccdSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 74cfa76ccdSmrgmkdir_umask=22 75cfa76ccdSmrg 76cfa76ccdSmrgbackupsuffix= 77dbbd9e4bSmacallanchgrpcmd= 78dbbd9e4bSmacallanchmodcmd=$chmodprog 79dbbd9e4bSmacallanchowncmd= 80dbbd9e4bSmacallanmvcmd=$mvprog 81dbbd9e4bSmacallanrmcmd="$rmprog -f" 82dbbd9e4bSmacallanstripcmd= 83dbbd9e4bSmacallan 84dbbd9e4bSmacallansrc= 85dbbd9e4bSmacallandst= 86dbbd9e4bSmacallandir_arg= 87dbbd9e4bSmacallandst_arg= 88dbbd9e4bSmacallan 89dbbd9e4bSmacallancopy_on_change=false 90cfa76ccdSmrgis_target_a_directory=possibly 91dbbd9e4bSmacallan 92dbbd9e4bSmacallanusage="\ 93dbbd9e4bSmacallanUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94dbbd9e4bSmacallan or: $0 [OPTION]... SRCFILES... DIRECTORY 95dbbd9e4bSmacallan or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96dbbd9e4bSmacallan or: $0 [OPTION]... -d DIRECTORIES... 97dbbd9e4bSmacallan 98dbbd9e4bSmacallanIn the 1st form, copy SRCFILE to DSTFILE. 99dbbd9e4bSmacallanIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100dbbd9e4bSmacallanIn the 4th, create DIRECTORIES. 101dbbd9e4bSmacallan 102dbbd9e4bSmacallanOptions: 103dbbd9e4bSmacallan --help display this help and exit. 104dbbd9e4bSmacallan --version display version info and exit. 105dbbd9e4bSmacallan 106dbbd9e4bSmacallan -c (ignored) 107cfa76ccdSmrg -C install only if different (preserve data modification time) 108dbbd9e4bSmacallan -d create directories instead of installing files. 109dbbd9e4bSmacallan -g GROUP $chgrpprog installed files to GROUP. 110dbbd9e4bSmacallan -m MODE $chmodprog installed files to MODE. 111dbbd9e4bSmacallan -o USER $chownprog installed files to USER. 112cfa76ccdSmrg -p pass -p to $cpprog. 113dbbd9e4bSmacallan -s $stripprog installed files. 114cfa76ccdSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115dbbd9e4bSmacallan -t DIRECTORY install into DIRECTORY. 116dbbd9e4bSmacallan -T report an error if DSTFILE is a directory. 117dbbd9e4bSmacallan 118dbbd9e4bSmacallanEnvironment variables override the default commands: 119dbbd9e4bSmacallan CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120dbbd9e4bSmacallan RMPROG STRIPPROG 121cfa76ccdSmrg 122cfa76ccdSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 123cfa76ccdSmrgit's up to you to specify -f if you want it. 124cfa76ccdSmrg 125cfa76ccdSmrgIf -S is not specified, no backups are attempted. 126cfa76ccdSmrg 127cfa76ccdSmrgEmail bug reports to bug-automake@gnu.org. 128cfa76ccdSmrgAutomake home page: https://www.gnu.org/software/automake/ 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" 140cfa76ccdSmrg shift;; 141dbbd9e4bSmacallan 142dbbd9e4bSmacallan --help) echo "$usage"; exit $?;; 143dbbd9e4bSmacallan 144dbbd9e4bSmacallan -m) mode=$2 145cfa76ccdSmrg case $mode in 146cfa76ccdSmrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147cfa76ccdSmrg echo "$0: invalid mode: $mode" >&2 148cfa76ccdSmrg exit 1;; 149cfa76ccdSmrg esac 150cfa76ccdSmrg shift;; 151dbbd9e4bSmacallan 152dbbd9e4bSmacallan -o) chowncmd="$chownprog $2" 153cfa76ccdSmrg shift;; 154cfa76ccdSmrg 155cfa76ccdSmrg -p) cpprog="$cpprog -p";; 156dbbd9e4bSmacallan 157dbbd9e4bSmacallan -s) stripcmd=$stripprog;; 158dbbd9e4bSmacallan 159cfa76ccdSmrg -S) backupsuffix="$2" 160cfa76ccdSmrg shift;; 161dbbd9e4bSmacallan 162cfa76ccdSmrg -t) 163cfa76ccdSmrg is_target_a_directory=always 164cfa76ccdSmrg dst_arg=$2 165cfa76ccdSmrg # Protect names problematic for 'test' and other utilities. 166cfa76ccdSmrg case $dst_arg in 167cfa76ccdSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168cfa76ccdSmrg esac 169cfa76ccdSmrg shift;; 170cfa76ccdSmrg 171cfa76ccdSmrg -T) is_target_a_directory=never;; 172dbbd9e4bSmacallan 173dbbd9e4bSmacallan --version) echo "$0 $scriptversion"; exit $?;; 174dbbd9e4bSmacallan 175cfa76ccdSmrg --) shift 176cfa76ccdSmrg break;; 177dbbd9e4bSmacallan 178cfa76ccdSmrg -*) echo "$0: invalid option: $1" >&2 179cfa76ccdSmrg exit 1;; 180dbbd9e4bSmacallan 181dbbd9e4bSmacallan *) break;; 182dbbd9e4bSmacallan esac 183dbbd9e4bSmacallan shift 184dbbd9e4bSmacallandone 185dbbd9e4bSmacallan 186cfa76ccdSmrg# We allow the use of options -d and -T together, by making -d 187cfa76ccdSmrg# take the precedence; this is for compatibility with GNU install. 188cfa76ccdSmrg 189cfa76ccdSmrgif test -n "$dir_arg"; then 190cfa76ccdSmrg if test -n "$dst_arg"; then 191cfa76ccdSmrg echo "$0: target directory not allowed when installing a directory." >&2 192cfa76ccdSmrg exit 1 193cfa76ccdSmrg fi 194cfa76ccdSmrgfi 195cfa76ccdSmrg 196dbbd9e4bSmacallanif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197dbbd9e4bSmacallan # When -d is used, all remaining arguments are directories to create. 198dbbd9e4bSmacallan # When -t is used, the destination is already specified. 199dbbd9e4bSmacallan # Otherwise, the last argument is the destination. Remove it from $@. 200dbbd9e4bSmacallan for arg 201dbbd9e4bSmacallan do 202dbbd9e4bSmacallan if test -n "$dst_arg"; then 203dbbd9e4bSmacallan # $@ is not empty: it contains at least $arg. 204dbbd9e4bSmacallan set fnord "$@" "$dst_arg" 205dbbd9e4bSmacallan shift # fnord 206dbbd9e4bSmacallan fi 207dbbd9e4bSmacallan shift # arg 208dbbd9e4bSmacallan dst_arg=$arg 209e96acad6Smrg # Protect names problematic for 'test' and other utilities. 210e96acad6Smrg case $dst_arg in 211e96acad6Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 212e96acad6Smrg esac 213dbbd9e4bSmacallan done 214dbbd9e4bSmacallanfi 215dbbd9e4bSmacallan 216dbbd9e4bSmacallanif test $# -eq 0; then 217dbbd9e4bSmacallan if test -z "$dir_arg"; then 218dbbd9e4bSmacallan echo "$0: no input file specified." >&2 219dbbd9e4bSmacallan exit 1 220dbbd9e4bSmacallan fi 221e96acad6Smrg # It's OK to call 'install-sh -d' without argument. 222dbbd9e4bSmacallan # This can happen when creating conditional directories. 223dbbd9e4bSmacallan exit 0 224dbbd9e4bSmacallanfi 225dbbd9e4bSmacallan 226cfa76ccdSmrgif test -z "$dir_arg"; then 227cfa76ccdSmrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228cfa76ccdSmrg if test ! -d "$dst_arg"; then 229cfa76ccdSmrg echo "$0: $dst_arg: Is not a directory." >&2 230cfa76ccdSmrg exit 1 231cfa76ccdSmrg fi 232cfa76ccdSmrg fi 233cfa76ccdSmrgfi 234cfa76ccdSmrg 235dbbd9e4bSmacallanif test -z "$dir_arg"; then 236e96acad6Smrg do_exit='(exit $ret); exit $ret' 237e96acad6Smrg trap "ret=129; $do_exit" 1 238e96acad6Smrg trap "ret=130; $do_exit" 2 239e96acad6Smrg trap "ret=141; $do_exit" 13 240e96acad6Smrg trap "ret=143; $do_exit" 15 241dbbd9e4bSmacallan 242dbbd9e4bSmacallan # Set umask so as not to create temps with too-generous modes. 243dbbd9e4bSmacallan # However, 'strip' requires both read and write access to temps. 244dbbd9e4bSmacallan case $mode in 245dbbd9e4bSmacallan # Optimize common cases. 246dbbd9e4bSmacallan *644) cp_umask=133;; 247dbbd9e4bSmacallan *755) cp_umask=22;; 248dbbd9e4bSmacallan 249dbbd9e4bSmacallan *[0-7]) 250dbbd9e4bSmacallan if test -z "$stripcmd"; then 251cfa76ccdSmrg u_plus_rw= 252dbbd9e4bSmacallan else 253cfa76ccdSmrg u_plus_rw='% 200' 254dbbd9e4bSmacallan fi 255dbbd9e4bSmacallan cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256dbbd9e4bSmacallan *) 257dbbd9e4bSmacallan if test -z "$stripcmd"; then 258cfa76ccdSmrg u_plus_rw= 259dbbd9e4bSmacallan else 260cfa76ccdSmrg u_plus_rw=,u+rw 261dbbd9e4bSmacallan fi 262dbbd9e4bSmacallan cp_umask=$mode$u_plus_rw;; 263dbbd9e4bSmacallan esac 264dbbd9e4bSmacallanfi 265dbbd9e4bSmacallan 266dbbd9e4bSmacallanfor src 267dbbd9e4bSmacallando 268e96acad6Smrg # Protect names problematic for 'test' and other utilities. 269dbbd9e4bSmacallan case $src in 270e96acad6Smrg -* | [=\(\)!]) src=./$src;; 271dbbd9e4bSmacallan esac 272dbbd9e4bSmacallan 273dbbd9e4bSmacallan if test -n "$dir_arg"; then 274dbbd9e4bSmacallan dst=$src 275dbbd9e4bSmacallan dstdir=$dst 276dbbd9e4bSmacallan test -d "$dstdir" 277dbbd9e4bSmacallan dstdir_status=$? 278cfa76ccdSmrg # Don't chown directories that already exist. 279cfa76ccdSmrg if test $dstdir_status = 0; then 280cfa76ccdSmrg chowncmd="" 281cfa76ccdSmrg fi 282dbbd9e4bSmacallan else 283dbbd9e4bSmacallan 284dbbd9e4bSmacallan # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285dbbd9e4bSmacallan # might cause directories to be created, which would be especially bad 286dbbd9e4bSmacallan # if $src (and thus $dsttmp) contains '*'. 287dbbd9e4bSmacallan if test ! -f "$src" && test ! -d "$src"; then 288dbbd9e4bSmacallan echo "$0: $src does not exist." >&2 289dbbd9e4bSmacallan exit 1 290dbbd9e4bSmacallan fi 291dbbd9e4bSmacallan 292dbbd9e4bSmacallan if test -z "$dst_arg"; then 293dbbd9e4bSmacallan echo "$0: no destination specified." >&2 294dbbd9e4bSmacallan exit 1 295dbbd9e4bSmacallan fi 296dbbd9e4bSmacallan dst=$dst_arg 297dbbd9e4bSmacallan 298cfa76ccdSmrg # If destination is a directory, append the input filename. 299dbbd9e4bSmacallan if test -d "$dst"; then 300cfa76ccdSmrg if test "$is_target_a_directory" = never; then 301cfa76ccdSmrg echo "$0: $dst_arg: Is a directory" >&2 302cfa76ccdSmrg exit 1 303dbbd9e4bSmacallan fi 304dbbd9e4bSmacallan dstdir=$dst 305cfa76ccdSmrg dstbase=`basename "$src"` 306cfa76ccdSmrg case $dst in 307cfa76ccdSmrg */) dst=$dst$dstbase;; 308cfa76ccdSmrg *) dst=$dst/$dstbase;; 309cfa76ccdSmrg esac 310dbbd9e4bSmacallan dstdir_status=0 311dbbd9e4bSmacallan else 312cfa76ccdSmrg dstdir=`dirname "$dst"` 313dbbd9e4bSmacallan test -d "$dstdir" 314dbbd9e4bSmacallan dstdir_status=$? 315dbbd9e4bSmacallan fi 316dbbd9e4bSmacallan fi 317dbbd9e4bSmacallan 318cfa76ccdSmrg case $dstdir in 319cfa76ccdSmrg */) dstdirslash=$dstdir;; 320cfa76ccdSmrg *) dstdirslash=$dstdir/;; 321cfa76ccdSmrg esac 322cfa76ccdSmrg 323dbbd9e4bSmacallan obsolete_mkdir_used=false 324dbbd9e4bSmacallan 325dbbd9e4bSmacallan if test $dstdir_status != 0; then 326dbbd9e4bSmacallan case $posix_mkdir in 327dbbd9e4bSmacallan '') 328cfa76ccdSmrg # With -d, create the new directory with the user-specified mode. 329cfa76ccdSmrg # Otherwise, rely on $mkdir_umask. 330cfa76ccdSmrg if test -n "$dir_arg"; then 331cfa76ccdSmrg mkdir_mode=-m$mode 332cfa76ccdSmrg else 333cfa76ccdSmrg mkdir_mode= 334cfa76ccdSmrg fi 335cfa76ccdSmrg 336cfa76ccdSmrg posix_mkdir=false 337cfa76ccdSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 338cfa76ccdSmrg # here however when possible just to lower collision chance. 339cfa76ccdSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340cfa76ccdSmrg 341cfa76ccdSmrg trap ' 342cfa76ccdSmrg ret=$? 343cfa76ccdSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344cfa76ccdSmrg exit $ret 345cfa76ccdSmrg ' 0 346cfa76ccdSmrg 347cfa76ccdSmrg # Because "mkdir -p" follows existing symlinks and we likely work 348cfa76ccdSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 349cfa76ccdSmrg # directory is successfully created first before we actually test 350cfa76ccdSmrg # 'mkdir -p'. 351cfa76ccdSmrg if (umask $mkdir_umask && 352cfa76ccdSmrg $mkdirprog $mkdir_mode "$tmpdir" && 353cfa76ccdSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354cfa76ccdSmrg then 355cfa76ccdSmrg if test -z "$dir_arg" || { 356cfa76ccdSmrg # Check for POSIX incompatibilities with -m. 357cfa76ccdSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358cfa76ccdSmrg # other-writable bit of parent directory when it shouldn't. 359cfa76ccdSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360cfa76ccdSmrg test_tmpdir="$tmpdir/a" 361cfa76ccdSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362cfa76ccdSmrg case $ls_ld_tmpdir in 363cfa76ccdSmrg d????-?r-*) different_mode=700;; 364cfa76ccdSmrg d????-?--*) different_mode=755;; 365cfa76ccdSmrg *) false;; 366cfa76ccdSmrg esac && 367cfa76ccdSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368cfa76ccdSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369cfa76ccdSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370cfa76ccdSmrg } 371cfa76ccdSmrg } 372cfa76ccdSmrg then posix_mkdir=: 373cfa76ccdSmrg fi 374cfa76ccdSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375dbbd9e4bSmacallan else 376cfa76ccdSmrg # Remove any dirs left behind by ancient mkdir implementations. 377cfa76ccdSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378dbbd9e4bSmacallan fi 379cfa76ccdSmrg trap '' 0;; 380dbbd9e4bSmacallan esac 381dbbd9e4bSmacallan 382dbbd9e4bSmacallan if 383dbbd9e4bSmacallan $posix_mkdir && ( 384cfa76ccdSmrg umask $mkdir_umask && 385cfa76ccdSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386dbbd9e4bSmacallan ) 387dbbd9e4bSmacallan then : 388dbbd9e4bSmacallan else 389dbbd9e4bSmacallan 390cfa76ccdSmrg # mkdir does not conform to POSIX, 391dbbd9e4bSmacallan # or it failed possibly due to a race condition. Create the 392dbbd9e4bSmacallan # directory the slow way, step by step, checking for races as we go. 393dbbd9e4bSmacallan 394dbbd9e4bSmacallan case $dstdir in 395cfa76ccdSmrg /*) prefix='/';; 396cfa76ccdSmrg [-=\(\)!]*) prefix='./';; 397cfa76ccdSmrg *) prefix='';; 398dbbd9e4bSmacallan esac 399dbbd9e4bSmacallan 400dbbd9e4bSmacallan oIFS=$IFS 401dbbd9e4bSmacallan IFS=/ 402cfa76ccdSmrg set -f 403dbbd9e4bSmacallan set fnord $dstdir 404dbbd9e4bSmacallan shift 405cfa76ccdSmrg set +f 406dbbd9e4bSmacallan IFS=$oIFS 407dbbd9e4bSmacallan 408dbbd9e4bSmacallan prefixes= 409dbbd9e4bSmacallan 410dbbd9e4bSmacallan for d 411dbbd9e4bSmacallan do 412cfa76ccdSmrg test X"$d" = X && continue 413cfa76ccdSmrg 414cfa76ccdSmrg prefix=$prefix$d 415cfa76ccdSmrg if test -d "$prefix"; then 416cfa76ccdSmrg prefixes= 417cfa76ccdSmrg else 418cfa76ccdSmrg if $posix_mkdir; then 419cfa76ccdSmrg (umask $mkdir_umask && 420cfa76ccdSmrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421cfa76ccdSmrg # Don't fail if two instances are running concurrently. 422cfa76ccdSmrg test -d "$prefix" || exit 1 423cfa76ccdSmrg else 424cfa76ccdSmrg case $prefix in 425cfa76ccdSmrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426cfa76ccdSmrg *) qprefix=$prefix;; 427cfa76ccdSmrg esac 428cfa76ccdSmrg prefixes="$prefixes '$qprefix'" 429cfa76ccdSmrg fi 430cfa76ccdSmrg fi 431cfa76ccdSmrg prefix=$prefix/ 432dbbd9e4bSmacallan done 433dbbd9e4bSmacallan 434dbbd9e4bSmacallan if test -n "$prefixes"; then 435cfa76ccdSmrg # Don't fail if two instances are running concurrently. 436cfa76ccdSmrg (umask $mkdir_umask && 437cfa76ccdSmrg eval "\$doit_exec \$mkdirprog $prefixes") || 438cfa76ccdSmrg test -d "$dstdir" || exit 1 439cfa76ccdSmrg obsolete_mkdir_used=true 440dbbd9e4bSmacallan fi 441dbbd9e4bSmacallan fi 442dbbd9e4bSmacallan fi 443dbbd9e4bSmacallan 444dbbd9e4bSmacallan if test -n "$dir_arg"; then 445dbbd9e4bSmacallan { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446dbbd9e4bSmacallan { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447dbbd9e4bSmacallan { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448dbbd9e4bSmacallan test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449dbbd9e4bSmacallan else 450dbbd9e4bSmacallan 451dbbd9e4bSmacallan # Make a couple of temp file names in the proper directory. 452cfa76ccdSmrg dsttmp=${dstdirslash}_inst.$$_ 453cfa76ccdSmrg rmtmp=${dstdirslash}_rm.$$_ 454dbbd9e4bSmacallan 455dbbd9e4bSmacallan # Trap to clean up those temp files at exit. 456dbbd9e4bSmacallan trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457dbbd9e4bSmacallan 458dbbd9e4bSmacallan # Copy the file name to the temp name. 459cfa76ccdSmrg (umask $cp_umask && 460cfa76ccdSmrg { test -z "$stripcmd" || { 461cfa76ccdSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 462cfa76ccdSmrg # which would cause strip to fail. 463cfa76ccdSmrg if test -z "$doit"; then 464cfa76ccdSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 465cfa76ccdSmrg else 466cfa76ccdSmrg $doit touch "$dsttmp" 467cfa76ccdSmrg fi 468cfa76ccdSmrg } 469cfa76ccdSmrg } && 470cfa76ccdSmrg $doit_exec $cpprog "$src" "$dsttmp") && 471dbbd9e4bSmacallan 472dbbd9e4bSmacallan # and set any options; do chmod last to preserve setuid bits. 473dbbd9e4bSmacallan # 474dbbd9e4bSmacallan # If any of these fail, we abort the whole thing. If we want to 475dbbd9e4bSmacallan # ignore errors from any of these, just make sure not to ignore 476dbbd9e4bSmacallan # errors from the above "$doit $cpprog $src $dsttmp" command. 477dbbd9e4bSmacallan # 478dbbd9e4bSmacallan { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479dbbd9e4bSmacallan { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480dbbd9e4bSmacallan { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481dbbd9e4bSmacallan { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482dbbd9e4bSmacallan 483dbbd9e4bSmacallan # If -C, don't bother to copy if it wouldn't change the file. 484dbbd9e4bSmacallan if $copy_on_change && 485cfa76ccdSmrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486cfa76ccdSmrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487cfa76ccdSmrg set -f && 488dbbd9e4bSmacallan set X $old && old=:$2:$4:$5:$6 && 489dbbd9e4bSmacallan set X $new && new=:$2:$4:$5:$6 && 490cfa76ccdSmrg set +f && 491dbbd9e4bSmacallan test "$old" = "$new" && 492dbbd9e4bSmacallan $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493dbbd9e4bSmacallan then 494dbbd9e4bSmacallan rm -f "$dsttmp" 495dbbd9e4bSmacallan else 496cfa76ccdSmrg # If $backupsuffix is set, and the file being installed 497cfa76ccdSmrg # already exists, attempt a backup. Don't worry if it fails, 498cfa76ccdSmrg # e.g., if mv doesn't support -f. 499cfa76ccdSmrg if test -n "$backupsuffix" && test -f "$dst"; then 500cfa76ccdSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501cfa76ccdSmrg fi 502cfa76ccdSmrg 503dbbd9e4bSmacallan # Rename the file to the real destination. 504dbbd9e4bSmacallan $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505dbbd9e4bSmacallan 506dbbd9e4bSmacallan # The rename failed, perhaps because mv can't rename something else 507dbbd9e4bSmacallan # to itself, or perhaps because mv is so ancient that it does not 508dbbd9e4bSmacallan # support -f. 509dbbd9e4bSmacallan { 510cfa76ccdSmrg # Now remove or move aside any old file at destination location. 511cfa76ccdSmrg # We try this two ways since rm can't unlink itself on some 512cfa76ccdSmrg # systems and the destination file might be busy for other 513cfa76ccdSmrg # reasons. In this case, the final cleanup might fail but the new 514cfa76ccdSmrg # file should still install successfully. 515cfa76ccdSmrg { 516cfa76ccdSmrg test ! -f "$dst" || 517cfa76ccdSmrg $doit $rmcmd "$dst" 2>/dev/null || 518cfa76ccdSmrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519cfa76ccdSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520cfa76ccdSmrg } || 521cfa76ccdSmrg { echo "$0: cannot unlink or rename $dst" >&2 522cfa76ccdSmrg (exit 1); exit 1 523cfa76ccdSmrg } 524cfa76ccdSmrg } && 525cfa76ccdSmrg 526cfa76ccdSmrg # Now rename the file to the real destination. 527cfa76ccdSmrg $doit $mvcmd "$dsttmp" "$dst" 528dbbd9e4bSmacallan } 529dbbd9e4bSmacallan fi || exit 1 530dbbd9e4bSmacallan 531dbbd9e4bSmacallan trap '' 0 532dbbd9e4bSmacallan fi 533dbbd9e4bSmacallandone 534dbbd9e4bSmacallan 535dbbd9e4bSmacallan# Local variables: 536cfa76ccdSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 537dbbd9e4bSmacallan# time-stamp-start: "scriptversion=" 538dbbd9e4bSmacallan# time-stamp-format: "%:y-%02m-%02d.%02H" 539cfa76ccdSmrg# time-stamp-time-zone: "UTC0" 5401c397cbaSmrg# time-stamp-end: "; # UTC" 541dbbd9e4bSmacallan# End: 542