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