1e34c20c8SJon Dugan#!/bin/sh 2e34c20c8SJon Dugan# install - install a program, script, or datafile 3e34c20c8SJon Dugan 4*aa8a3f4fSBruce A. Mahscriptversion=2020-11-14.01; # UTC 5e34c20c8SJon Dugan 6e34c20c8SJon Dugan# This originates from X11R5 (mit/util/scripts/install.sh), which was 7e34c20c8SJon Dugan# later released in X11R6 (xc/config/util/install.sh) with the 8e34c20c8SJon Dugan# following copyright and license. 9e34c20c8SJon Dugan# 10e34c20c8SJon Dugan# Copyright (C) 1994 X Consortium 11e34c20c8SJon Dugan# 12e34c20c8SJon Dugan# Permission is hereby granted, free of charge, to any person obtaining a copy 13e34c20c8SJon Dugan# of this software and associated documentation files (the "Software"), to 14e34c20c8SJon Dugan# deal in the Software without restriction, including without limitation the 15e34c20c8SJon Dugan# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16e34c20c8SJon Dugan# sell copies of the Software, and to permit persons to whom the Software is 17e34c20c8SJon Dugan# furnished to do so, subject to the following conditions: 18e34c20c8SJon Dugan# 19e34c20c8SJon Dugan# The above copyright notice and this permission notice shall be included in 20e34c20c8SJon Dugan# all copies or substantial portions of the Software. 21e34c20c8SJon Dugan# 22e34c20c8SJon Dugan# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23e34c20c8SJon Dugan# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24e34c20c8SJon Dugan# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25e34c20c8SJon Dugan# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26e34c20c8SJon Dugan# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27e34c20c8SJon Dugan# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28e34c20c8SJon Dugan# 29e34c20c8SJon Dugan# Except as contained in this notice, the name of the X Consortium shall not 30e34c20c8SJon Dugan# be used in advertising or otherwise to promote the sale, use or other deal- 31e34c20c8SJon Dugan# ings in this Software without prior written authorization from the X Consor- 32e34c20c8SJon Dugan# tium. 33e34c20c8SJon Dugan# 34e34c20c8SJon Dugan# 35e34c20c8SJon Dugan# FSF changes to this file are in the public domain. 36e34c20c8SJon Dugan# 37e34c20c8SJon Dugan# Calling this script install-sh is preferred over install.sh, to prevent 38487ee810SBruce A. Mah# 'make' implicit rules from creating a file called install from it 39e34c20c8SJon Dugan# when there is no Makefile. 40e34c20c8SJon Dugan# 41e34c20c8SJon Dugan# This script is compatible with the BSD install script, but was written 42487ee810SBruce A. Mah# from scratch. 43487ee810SBruce A. Mah 44*aa8a3f4fSBruce A. Mahtab=' ' 45487ee810SBruce A. Mahnl=' 46487ee810SBruce A. Mah' 47*aa8a3f4fSBruce A. MahIFS=" $tab$nl" 48e34c20c8SJon Dugan 49*aa8a3f4fSBruce A. Mah# Set DOITPROG to "echo" to test this script. 50e34c20c8SJon Dugan 51487ee810SBruce A. Mahdoit=${DOITPROG-} 52*aa8a3f4fSBruce A. Mahdoit_exec=${doit:-exec} 53e34c20c8SJon Dugan 54487ee810SBruce A. Mah# Put in absolute file names if you don't have them in your path; 55487ee810SBruce A. Mah# or use environment vars. 56e34c20c8SJon Dugan 57487ee810SBruce A. Mahchgrpprog=${CHGRPPROG-chgrp} 58487ee810SBruce A. Mahchmodprog=${CHMODPROG-chmod} 59487ee810SBruce A. Mahchownprog=${CHOWNPROG-chown} 60487ee810SBruce A. Mahcmpprog=${CMPPROG-cmp} 61487ee810SBruce A. Mahcpprog=${CPPROG-cp} 62487ee810SBruce A. Mahmkdirprog=${MKDIRPROG-mkdir} 63487ee810SBruce A. Mahmvprog=${MVPROG-mv} 64487ee810SBruce A. Mahrmprog=${RMPROG-rm} 65487ee810SBruce A. Mahstripprog=${STRIPPROG-strip} 66e34c20c8SJon Dugan 67487ee810SBruce A. Mahposix_mkdir= 68487ee810SBruce A. Mah 69487ee810SBruce A. Mah# Desired mode of installed file. 70487ee810SBruce A. Mahmode=0755 71487ee810SBruce A. Mah 72*aa8a3f4fSBruce A. Mah# Create dirs (including intermediate dirs) using mode 755. 73*aa8a3f4fSBruce A. Mah# This is like GNU 'install' as of coreutils 8.32 (2020). 74*aa8a3f4fSBruce A. Mahmkdir_umask=22 75*aa8a3f4fSBruce A. Mah 76*aa8a3f4fSBruce A. Mahbackupsuffix= 7756a97f93Sjefchgrpcmd= 78487ee810SBruce A. Mahchmodcmd=$chmodprog 79487ee810SBruce A. Mahchowncmd= 80487ee810SBruce A. Mahmvcmd=$mvprog 8156a97f93Sjefrmcmd="$rmprog -f" 82487ee810SBruce A. Mahstripcmd= 83487ee810SBruce A. Mah 84e34c20c8SJon Dugansrc= 85e34c20c8SJon Dugandst= 86e34c20c8SJon Dugandir_arg= 87487ee810SBruce A. Mahdst_arg= 88487ee810SBruce A. Mah 89487ee810SBruce A. Mahcopy_on_change=false 90*aa8a3f4fSBruce A. Mahis_target_a_directory=possibly 91e34c20c8SJon Dugan 92487ee810SBruce A. Mahusage="\ 93487ee810SBruce A. MahUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94e34c20c8SJon Dugan or: $0 [OPTION]... SRCFILES... DIRECTORY 95e34c20c8SJon Dugan or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96e34c20c8SJon Dugan or: $0 [OPTION]... -d DIRECTORIES... 97e34c20c8SJon Dugan 98e34c20c8SJon DuganIn the 1st form, copy SRCFILE to DSTFILE. 99e34c20c8SJon DuganIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100e34c20c8SJon DuganIn the 4th, create DIRECTORIES. 101e34c20c8SJon Dugan 102e34c20c8SJon DuganOptions: 103487ee810SBruce A. Mah --help display this help and exit. 104487ee810SBruce A. Mah --version display version info and exit. 105487ee810SBruce A. Mah 106e34c20c8SJon Dugan -c (ignored) 107*aa8a3f4fSBruce A. Mah -C install only if different (preserve data modification time) 108e34c20c8SJon Dugan -d create directories instead of installing files. 109e34c20c8SJon Dugan -g GROUP $chgrpprog installed files to GROUP. 110e34c20c8SJon Dugan -m MODE $chmodprog installed files to MODE. 111e34c20c8SJon Dugan -o USER $chownprog installed files to USER. 112*aa8a3f4fSBruce A. Mah -p pass -p to $cpprog. 113e34c20c8SJon Dugan -s $stripprog installed files. 114*aa8a3f4fSBruce A. Mah -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115e34c20c8SJon Dugan -t DIRECTORY install into DIRECTORY. 116e34c20c8SJon Dugan -T report an error if DSTFILE is a directory. 117e34c20c8SJon Dugan 118e34c20c8SJon DuganEnvironment variables override the default commands: 119487ee810SBruce A. Mah CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120487ee810SBruce A. Mah RMPROG STRIPPROG 121*aa8a3f4fSBruce A. Mah 122*aa8a3f4fSBruce A. MahBy default, rm is invoked with -f; when overridden with RMPROG, 123*aa8a3f4fSBruce A. Mahit's up to you to specify -f if you want it. 124*aa8a3f4fSBruce A. Mah 125*aa8a3f4fSBruce A. MahIf -S is not specified, no backups are attempted. 126*aa8a3f4fSBruce A. Mah 127*aa8a3f4fSBruce A. MahEmail bug reports to [email protected]. 128*aa8a3f4fSBruce A. MahAutomake home page: https://www.gnu.org/software/automake/ 129e34c20c8SJon Dugan" 130e34c20c8SJon Dugan 131487ee810SBruce A. Mahwhile test $# -ne 0; do 132e34c20c8SJon Dugan case $1 in 133487ee810SBruce A. Mah -c) ;; 134e34c20c8SJon Dugan 135487ee810SBruce A. Mah -C) copy_on_change=true;; 136487ee810SBruce A. Mah 137487ee810SBruce A. Mah -d) dir_arg=true;; 138e34c20c8SJon Dugan 139e34c20c8SJon Dugan -g) chgrpcmd="$chgrpprog $2" 140487ee810SBruce A. Mah shift;; 141e34c20c8SJon Dugan 142e34c20c8SJon Dugan --help) echo "$usage"; exit $?;; 143e34c20c8SJon Dugan 144487ee810SBruce A. Mah -m) mode=$2 145487ee810SBruce A. Mah case $mode in 146*aa8a3f4fSBruce A. Mah *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147487ee810SBruce A. Mah echo "$0: invalid mode: $mode" >&2 148487ee810SBruce A. Mah exit 1;; 149487ee810SBruce A. Mah esac 150487ee810SBruce A. Mah shift;; 151e34c20c8SJon Dugan 152e34c20c8SJon Dugan -o) chowncmd="$chownprog $2" 153487ee810SBruce A. Mah shift;; 154e34c20c8SJon Dugan 155*aa8a3f4fSBruce A. Mah -p) cpprog="$cpprog -p";; 156*aa8a3f4fSBruce A. Mah 157487ee810SBruce A. Mah -s) stripcmd=$stripprog;; 158e34c20c8SJon Dugan 159*aa8a3f4fSBruce A. Mah -S) backupsuffix="$2" 160*aa8a3f4fSBruce A. Mah shift;; 161*aa8a3f4fSBruce A. Mah 162*aa8a3f4fSBruce A. Mah -t) 163*aa8a3f4fSBruce A. Mah is_target_a_directory=always 164*aa8a3f4fSBruce A. Mah dst_arg=$2 165487ee810SBruce A. Mah # Protect names problematic for 'test' and other utilities. 166487ee810SBruce A. Mah case $dst_arg in 167487ee810SBruce A. Mah -* | [=\(\)!]) dst_arg=./$dst_arg;; 168487ee810SBruce A. Mah esac 169487ee810SBruce A. Mah shift;; 170e34c20c8SJon Dugan 171*aa8a3f4fSBruce A. Mah -T) is_target_a_directory=never;; 172e34c20c8SJon Dugan 173e34c20c8SJon Dugan --version) echo "$0 $scriptversion"; exit $?;; 174e34c20c8SJon Dugan 175487ee810SBruce A. Mah --) shift 176487ee810SBruce A. Mah break;; 177487ee810SBruce A. Mah 178487ee810SBruce A. Mah -*) echo "$0: invalid option: $1" >&2 179487ee810SBruce A. Mah exit 1;; 180487ee810SBruce A. Mah 181487ee810SBruce A. Mah *) break;; 182487ee810SBruce A. Mah esac 183487ee810SBruce A. Mah shift 184487ee810SBruce A. Mahdone 185487ee810SBruce A. Mah 186*aa8a3f4fSBruce A. Mah# We allow the use of options -d and -T together, by making -d 187*aa8a3f4fSBruce A. Mah# take the precedence; this is for compatibility with GNU install. 188*aa8a3f4fSBruce A. Mah 189*aa8a3f4fSBruce A. Mahif test -n "$dir_arg"; then 190*aa8a3f4fSBruce A. Mah if test -n "$dst_arg"; then 191*aa8a3f4fSBruce A. Mah echo "$0: target directory not allowed when installing a directory." >&2 192*aa8a3f4fSBruce A. Mah exit 1 193*aa8a3f4fSBruce A. Mah fi 194*aa8a3f4fSBruce A. Mahfi 195*aa8a3f4fSBruce A. Mah 196487ee810SBruce A. Mahif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197487ee810SBruce A. Mah # When -d is used, all remaining arguments are directories to create. 198e34c20c8SJon Dugan # When -t is used, the destination is already specified. 199e34c20c8SJon Dugan # Otherwise, the last argument is the destination. Remove it from $@. 200e34c20c8SJon Dugan for arg 201e34c20c8SJon Dugan do 202487ee810SBruce A. Mah if test -n "$dst_arg"; then 203e34c20c8SJon Dugan # $@ is not empty: it contains at least $arg. 204487ee810SBruce A. Mah set fnord "$@" "$dst_arg" 205e34c20c8SJon Dugan shift # fnord 206e34c20c8SJon Dugan fi 207e34c20c8SJon Dugan shift # arg 208487ee810SBruce A. Mah dst_arg=$arg 209487ee810SBruce A. Mah # Protect names problematic for 'test' and other utilities. 210487ee810SBruce A. Mah case $dst_arg in 211487ee810SBruce A. Mah -* | [=\(\)!]) dst_arg=./$dst_arg;; 21256a97f93Sjef esac 21356a97f93Sjef done 214487ee810SBruce A. Mahfi 215e34c20c8SJon Dugan 216487ee810SBruce A. Mahif test $# -eq 0; then 217e34c20c8SJon Dugan if test -z "$dir_arg"; then 218e34c20c8SJon Dugan echo "$0: no input file specified." >&2 219e34c20c8SJon Dugan exit 1 220e34c20c8SJon Dugan fi 221487ee810SBruce A. Mah # It's OK to call 'install-sh -d' without argument. 222e34c20c8SJon Dugan # This can happen when creating conditional directories. 223e34c20c8SJon Dugan exit 0 224e34c20c8SJon Duganfi 225e34c20c8SJon Dugan 226487ee810SBruce A. Mahif test -z "$dir_arg"; then 227*aa8a3f4fSBruce A. Mah if test $# -gt 1 || test "$is_target_a_directory" = always; then 228*aa8a3f4fSBruce A. Mah if test ! -d "$dst_arg"; then 229*aa8a3f4fSBruce A. Mah echo "$0: $dst_arg: Is not a directory." >&2 230*aa8a3f4fSBruce A. Mah exit 1 231*aa8a3f4fSBruce A. Mah fi 232*aa8a3f4fSBruce A. Mah fi 233*aa8a3f4fSBruce A. Mahfi 234*aa8a3f4fSBruce A. Mah 235*aa8a3f4fSBruce A. Mahif test -z "$dir_arg"; then 236487ee810SBruce A. Mah do_exit='(exit $ret); exit $ret' 237487ee810SBruce A. Mah trap "ret=129; $do_exit" 1 238487ee810SBruce A. Mah trap "ret=130; $do_exit" 2 239487ee810SBruce A. Mah trap "ret=141; $do_exit" 13 240487ee810SBruce A. Mah trap "ret=143; $do_exit" 15 241487ee810SBruce A. Mah 242487ee810SBruce A. Mah # Set umask so as not to create temps with too-generous modes. 243487ee810SBruce A. Mah # However, 'strip' requires both read and write access to temps. 244487ee810SBruce A. Mah case $mode in 245487ee810SBruce A. Mah # Optimize common cases. 246487ee810SBruce A. Mah *644) cp_umask=133;; 247487ee810SBruce A. Mah *755) cp_umask=22;; 248487ee810SBruce A. Mah 249487ee810SBruce A. Mah *[0-7]) 250487ee810SBruce A. Mah if test -z "$stripcmd"; then 251487ee810SBruce A. Mah u_plus_rw= 252487ee810SBruce A. Mah else 253487ee810SBruce A. Mah u_plus_rw='% 200' 254487ee810SBruce A. Mah fi 255487ee810SBruce A. Mah cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256487ee810SBruce A. Mah *) 257487ee810SBruce A. Mah if test -z "$stripcmd"; then 258487ee810SBruce A. Mah u_plus_rw= 259487ee810SBruce A. Mah else 260487ee810SBruce A. Mah u_plus_rw=,u+rw 261487ee810SBruce A. Mah fi 262487ee810SBruce A. Mah cp_umask=$mode$u_plus_rw;; 263487ee810SBruce A. Mah esac 264487ee810SBruce A. Mahfi 265487ee810SBruce A. Mah 266e34c20c8SJon Duganfor src 267e34c20c8SJon Dugando 268487ee810SBruce A. Mah # Protect names problematic for 'test' and other utilities. 269e34c20c8SJon Dugan case $src in 270487ee810SBruce A. Mah -* | [=\(\)!]) src=./$src;; 271e34c20c8SJon Dugan esac 272e34c20c8SJon Dugan 273e34c20c8SJon Dugan if test -n "$dir_arg"; then 274e34c20c8SJon Dugan dst=$src 275487ee810SBruce A. Mah dstdir=$dst 276487ee810SBruce A. Mah test -d "$dstdir" 277487ee810SBruce A. Mah dstdir_status=$? 278*aa8a3f4fSBruce A. Mah # Don't chown directories that already exist. 279*aa8a3f4fSBruce A. Mah if test $dstdir_status = 0; then 280*aa8a3f4fSBruce A. Mah chowncmd="" 281*aa8a3f4fSBruce A. Mah fi 282487ee810SBruce A. Mah else 283e34c20c8SJon Dugan 284e34c20c8SJon Dugan # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285e34c20c8SJon Dugan # might cause directories to be created, which would be especially bad 286e34c20c8SJon Dugan # if $src (and thus $dsttmp) contains '*'. 287e34c20c8SJon Dugan if test ! -f "$src" && test ! -d "$src"; then 288e34c20c8SJon Dugan echo "$0: $src does not exist." >&2 289e34c20c8SJon Dugan exit 1 290e34c20c8SJon Dugan fi 291e34c20c8SJon Dugan 292487ee810SBruce A. Mah if test -z "$dst_arg"; then 293e34c20c8SJon Dugan echo "$0: no destination specified." >&2 294e34c20c8SJon Dugan exit 1 295e34c20c8SJon Dugan fi 296487ee810SBruce A. Mah dst=$dst_arg 297e34c20c8SJon Dugan 298*aa8a3f4fSBruce A. Mah # If destination is a directory, append the input filename. 299e34c20c8SJon Dugan if test -d "$dst"; then 300*aa8a3f4fSBruce A. Mah if test "$is_target_a_directory" = never; then 301487ee810SBruce A. Mah echo "$0: $dst_arg: Is a directory" >&2 302e34c20c8SJon Dugan exit 1 303e34c20c8SJon Dugan fi 304487ee810SBruce A. Mah dstdir=$dst 305*aa8a3f4fSBruce A. Mah dstbase=`basename "$src"` 306*aa8a3f4fSBruce A. Mah case $dst in 307*aa8a3f4fSBruce A. Mah */) dst=$dst$dstbase;; 308*aa8a3f4fSBruce A. Mah *) dst=$dst/$dstbase;; 309*aa8a3f4fSBruce A. Mah esac 310487ee810SBruce A. Mah dstdir_status=0 311487ee810SBruce A. Mah else 312*aa8a3f4fSBruce A. Mah dstdir=`dirname "$dst"` 313487ee810SBruce A. Mah test -d "$dstdir" 314487ee810SBruce A. Mah dstdir_status=$? 315e34c20c8SJon Dugan fi 316e34c20c8SJon Dugan fi 317e34c20c8SJon Dugan 318*aa8a3f4fSBruce A. Mah case $dstdir in 319*aa8a3f4fSBruce A. Mah */) dstdirslash=$dstdir;; 320*aa8a3f4fSBruce A. Mah *) dstdirslash=$dstdir/;; 321*aa8a3f4fSBruce A. Mah esac 322*aa8a3f4fSBruce A. Mah 323487ee810SBruce A. Mah obsolete_mkdir_used=false 324e34c20c8SJon Dugan 325487ee810SBruce A. Mah if test $dstdir_status != 0; then 326487ee810SBruce A. Mah case $posix_mkdir in 327487ee810SBruce A. Mah '') 328487ee810SBruce A. Mah # With -d, create the new directory with the user-specified mode. 329487ee810SBruce A. Mah # Otherwise, rely on $mkdir_umask. 330487ee810SBruce A. Mah if test -n "$dir_arg"; then 331487ee810SBruce A. Mah mkdir_mode=-m$mode 332487ee810SBruce A. Mah else 333487ee810SBruce A. Mah mkdir_mode= 334487ee810SBruce A. Mah fi 335487ee810SBruce A. Mah 336487ee810SBruce A. Mah posix_mkdir=false 337*aa8a3f4fSBruce A. Mah # The $RANDOM variable is not portable (e.g., dash). Use it 338*aa8a3f4fSBruce A. Mah # here however when possible just to lower collision chance. 339487ee810SBruce A. Mah tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 340487ee810SBruce A. Mah 341*aa8a3f4fSBruce A. Mah trap ' 342*aa8a3f4fSBruce A. Mah ret=$? 343*aa8a3f4fSBruce A. Mah rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 344*aa8a3f4fSBruce A. Mah exit $ret 345*aa8a3f4fSBruce A. Mah ' 0 346*aa8a3f4fSBruce A. Mah 347*aa8a3f4fSBruce A. Mah # Because "mkdir -p" follows existing symlinks and we likely work 348*aa8a3f4fSBruce A. Mah # directly in world-writeable /tmp, make sure that the '$tmpdir' 349*aa8a3f4fSBruce A. Mah # directory is successfully created first before we actually test 350*aa8a3f4fSBruce A. Mah # 'mkdir -p'. 351487ee810SBruce A. Mah if (umask $mkdir_umask && 352*aa8a3f4fSBruce A. Mah $mkdirprog $mkdir_mode "$tmpdir" && 353*aa8a3f4fSBruce A. Mah exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 354487ee810SBruce A. Mah then 355487ee810SBruce A. Mah if test -z "$dir_arg" || { 356487ee810SBruce A. Mah # Check for POSIX incompatibilities with -m. 357487ee810SBruce A. Mah # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 358487ee810SBruce A. Mah # other-writable bit of parent directory when it shouldn't. 359487ee810SBruce A. Mah # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 360*aa8a3f4fSBruce A. Mah test_tmpdir="$tmpdir/a" 361*aa8a3f4fSBruce A. Mah ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 362487ee810SBruce A. Mah case $ls_ld_tmpdir in 363487ee810SBruce A. Mah d????-?r-*) different_mode=700;; 364487ee810SBruce A. Mah d????-?--*) different_mode=755;; 365487ee810SBruce A. Mah *) false;; 366487ee810SBruce A. Mah esac && 367*aa8a3f4fSBruce A. Mah $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 368*aa8a3f4fSBruce A. Mah ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 369487ee810SBruce A. Mah test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 370487ee810SBruce A. Mah } 371487ee810SBruce A. Mah } 372487ee810SBruce A. Mah then posix_mkdir=: 373487ee810SBruce A. Mah fi 374*aa8a3f4fSBruce A. Mah rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 375487ee810SBruce A. Mah else 376487ee810SBruce A. Mah # Remove any dirs left behind by ancient mkdir implementations. 377*aa8a3f4fSBruce A. Mah rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 378487ee810SBruce A. Mah fi 379487ee810SBruce A. Mah trap '' 0;; 380487ee810SBruce A. Mah esac 381487ee810SBruce A. Mah 382487ee810SBruce A. Mah if 383487ee810SBruce A. Mah $posix_mkdir && ( 384487ee810SBruce A. Mah umask $mkdir_umask && 385487ee810SBruce A. Mah $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386487ee810SBruce A. Mah ) 387487ee810SBruce A. Mah then : 388487ee810SBruce A. Mah else 389487ee810SBruce A. Mah 390*aa8a3f4fSBruce A. Mah # mkdir does not conform to POSIX, 391487ee810SBruce A. Mah # or it failed possibly due to a race condition. Create the 392487ee810SBruce A. Mah # directory the slow way, step by step, checking for races as we go. 393487ee810SBruce A. Mah 394487ee810SBruce A. Mah case $dstdir in 395487ee810SBruce A. Mah /*) prefix='/';; 396487ee810SBruce A. Mah [-=\(\)!]*) prefix='./';; 397487ee810SBruce A. Mah *) prefix='';; 398487ee810SBruce A. Mah esac 399487ee810SBruce A. Mah 400e34c20c8SJon Dugan oIFS=$IFS 401487ee810SBruce A. Mah IFS=/ 402*aa8a3f4fSBruce A. Mah set -f 403487ee810SBruce A. Mah set fnord $dstdir 404e34c20c8SJon Dugan shift 405*aa8a3f4fSBruce A. Mah set +f 406e34c20c8SJon Dugan IFS=$oIFS 407e34c20c8SJon Dugan 408487ee810SBruce A. Mah prefixes= 409e34c20c8SJon Dugan 410487ee810SBruce A. Mah for d 411487ee810SBruce A. Mah do 412487ee810SBruce A. Mah test X"$d" = X && continue 413487ee810SBruce A. Mah 414487ee810SBruce A. Mah prefix=$prefix$d 415487ee810SBruce A. Mah if test -d "$prefix"; then 416487ee810SBruce A. Mah prefixes= 417487ee810SBruce A. Mah else 418487ee810SBruce A. Mah if $posix_mkdir; then 419*aa8a3f4fSBruce A. Mah (umask $mkdir_umask && 420487ee810SBruce A. Mah $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421487ee810SBruce A. Mah # Don't fail if two instances are running concurrently. 422487ee810SBruce A. Mah test -d "$prefix" || exit 1 423487ee810SBruce A. Mah else 424487ee810SBruce A. Mah case $prefix in 425487ee810SBruce A. Mah *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426487ee810SBruce A. Mah *) qprefix=$prefix;; 427487ee810SBruce A. Mah esac 428487ee810SBruce A. Mah prefixes="$prefixes '$qprefix'" 429e34c20c8SJon Dugan fi 430487ee810SBruce A. Mah fi 431487ee810SBruce A. Mah prefix=$prefix/ 432e34c20c8SJon Dugan done 433487ee810SBruce A. Mah 434487ee810SBruce A. Mah if test -n "$prefixes"; then 435487ee810SBruce A. Mah # Don't fail if two instances are running concurrently. 436487ee810SBruce A. Mah (umask $mkdir_umask && 437487ee810SBruce A. Mah eval "\$doit_exec \$mkdirprog $prefixes") || 438487ee810SBruce A. Mah test -d "$dstdir" || exit 1 439487ee810SBruce A. Mah obsolete_mkdir_used=true 440487ee810SBruce A. Mah fi 441487ee810SBruce A. Mah fi 442e34c20c8SJon Dugan fi 443e34c20c8SJon Dugan 444e34c20c8SJon Dugan if test -n "$dir_arg"; then 445487ee810SBruce A. Mah { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446487ee810SBruce A. Mah { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447487ee810SBruce A. Mah { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448487ee810SBruce A. Mah test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449e34c20c8SJon Dugan else 450e34c20c8SJon Dugan 451e34c20c8SJon Dugan # Make a couple of temp file names in the proper directory. 452*aa8a3f4fSBruce A. Mah dsttmp=${dstdirslash}_inst.$$_ 453*aa8a3f4fSBruce A. Mah rmtmp=${dstdirslash}_rm.$$_ 454e34c20c8SJon Dugan 455e34c20c8SJon Dugan # Trap to clean up those temp files at exit. 456e34c20c8SJon Dugan trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457e34c20c8SJon Dugan 458e34c20c8SJon Dugan # Copy the file name to the temp name. 459*aa8a3f4fSBruce A. Mah (umask $cp_umask && 460*aa8a3f4fSBruce A. Mah { test -z "$stripcmd" || { 461*aa8a3f4fSBruce A. Mah # Create $dsttmp read-write so that cp doesn't create it read-only, 462*aa8a3f4fSBruce A. Mah # which would cause strip to fail. 463*aa8a3f4fSBruce A. Mah if test -z "$doit"; then 464*aa8a3f4fSBruce A. Mah : >"$dsttmp" # No need to fork-exec 'touch'. 465*aa8a3f4fSBruce A. Mah else 466*aa8a3f4fSBruce A. Mah $doit touch "$dsttmp" 467*aa8a3f4fSBruce A. Mah fi 468*aa8a3f4fSBruce A. Mah } 469*aa8a3f4fSBruce A. Mah } && 470*aa8a3f4fSBruce A. Mah $doit_exec $cpprog "$src" "$dsttmp") && 471e34c20c8SJon Dugan 472e34c20c8SJon Dugan # and set any options; do chmod last to preserve setuid bits. 473e34c20c8SJon Dugan # 474e34c20c8SJon Dugan # If any of these fail, we abort the whole thing. If we want to 475e34c20c8SJon Dugan # ignore errors from any of these, just make sure not to ignore 476e34c20c8SJon Dugan # errors from the above "$doit $cpprog $src $dsttmp" command. 477e34c20c8SJon Dugan # 478487ee810SBruce A. Mah { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479487ee810SBruce A. Mah { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480487ee810SBruce A. Mah { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481487ee810SBruce A. Mah { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482e34c20c8SJon Dugan 483487ee810SBruce A. Mah # If -C, don't bother to copy if it wouldn't change the file. 484487ee810SBruce A. Mah if $copy_on_change && 485487ee810SBruce A. Mah old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486487ee810SBruce A. Mah new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487*aa8a3f4fSBruce A. Mah set -f && 488487ee810SBruce A. Mah set X $old && old=:$2:$4:$5:$6 && 489487ee810SBruce A. Mah set X $new && new=:$2:$4:$5:$6 && 490*aa8a3f4fSBruce A. Mah set +f && 491487ee810SBruce A. Mah test "$old" = "$new" && 492487ee810SBruce A. Mah $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493487ee810SBruce A. Mah then 494487ee810SBruce A. Mah rm -f "$dsttmp" 495487ee810SBruce A. Mah else 496*aa8a3f4fSBruce A. Mah # If $backupsuffix is set, and the file being installed 497*aa8a3f4fSBruce A. Mah # already exists, attempt a backup. Don't worry if it fails, 498*aa8a3f4fSBruce A. Mah # e.g., if mv doesn't support -f. 499*aa8a3f4fSBruce A. Mah if test -n "$backupsuffix" && test -f "$dst"; then 500*aa8a3f4fSBruce A. Mah $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 501*aa8a3f4fSBruce A. Mah fi 502*aa8a3f4fSBruce A. Mah 503487ee810SBruce A. Mah # Rename the file to the real destination. 504487ee810SBruce A. Mah $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505487ee810SBruce A. Mah 506e34c20c8SJon Dugan # The rename failed, perhaps because mv can't rename something else 507e34c20c8SJon Dugan # to itself, or perhaps because mv is so ancient that it does not 508e34c20c8SJon Dugan # support -f. 509487ee810SBruce A. Mah { 510e34c20c8SJon Dugan # Now remove or move aside any old file at destination location. 511e34c20c8SJon Dugan # We try this two ways since rm can't unlink itself on some 512e34c20c8SJon Dugan # systems and the destination file might be busy for other 513e34c20c8SJon Dugan # reasons. In this case, the final cleanup might fail but the new 514e34c20c8SJon Dugan # file should still install successfully. 515e34c20c8SJon Dugan { 516487ee810SBruce A. Mah test ! -f "$dst" || 517*aa8a3f4fSBruce A. Mah $doit $rmcmd "$dst" 2>/dev/null || 518487ee810SBruce A. Mah { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 519*aa8a3f4fSBruce A. Mah { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520487ee810SBruce A. Mah } || 521487ee810SBruce A. Mah { echo "$0: cannot unlink or rename $dst" >&2 522e34c20c8SJon Dugan (exit 1); exit 1 523e34c20c8SJon Dugan } 524e34c20c8SJon Dugan } && 525e34c20c8SJon Dugan 526e34c20c8SJon Dugan # Now rename the file to the real destination. 527487ee810SBruce A. Mah $doit $mvcmd "$dsttmp" "$dst" 528e34c20c8SJon Dugan } 529487ee810SBruce A. Mah fi || exit 1 530e34c20c8SJon Dugan 531487ee810SBruce A. Mah trap '' 0 532487ee810SBruce A. Mah fi 533487ee810SBruce A. Mahdone 53456a97f93Sjef 535e34c20c8SJon Dugan# Local variables: 536*aa8a3f4fSBruce A. Mah# eval: (add-hook 'before-save-hook 'time-stamp) 537e34c20c8SJon Dugan# time-stamp-start: "scriptversion=" 538e34c20c8SJon Dugan# time-stamp-format: "%:y-%02m-%02d.%02H" 539*aa8a3f4fSBruce A. Mah# time-stamp-time-zone: "UTC0" 540487ee810SBruce A. Mah# time-stamp-end: "; # UTC" 541e34c20c8SJon Dugan# End: 542