1c95b42baSmrg#!/bin/sh 2c95b42baSmrg# install - install a program, script, or datafile 3c95b42baSmrg 40f595aedSmrgscriptversion=2020-11-14.01; # UTC 5c95b42baSmrg 6c95b42baSmrg# This originates from X11R5 (mit/util/scripts/install.sh), which was 7c95b42baSmrg# later released in X11R6 (xc/config/util/install.sh) with the 8c95b42baSmrg# following copyright and license. 9c95b42baSmrg# 10c95b42baSmrg# Copyright (C) 1994 X Consortium 11c95b42baSmrg# 12c95b42baSmrg# Permission is hereby granted, free of charge, to any person obtaining a copy 13c95b42baSmrg# of this software and associated documentation files (the "Software"), to 14c95b42baSmrg# deal in the Software without restriction, including without limitation the 15c95b42baSmrg# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16c95b42baSmrg# sell copies of the Software, and to permit persons to whom the Software is 17c95b42baSmrg# furnished to do so, subject to the following conditions: 18c95b42baSmrg# 19c95b42baSmrg# The above copyright notice and this permission notice shall be included in 20c95b42baSmrg# all copies or substantial portions of the Software. 21c95b42baSmrg# 22c95b42baSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23c95b42baSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24c95b42baSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25c95b42baSmrg# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26c95b42baSmrg# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27c95b42baSmrg# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28c95b42baSmrg# 29c95b42baSmrg# Except as contained in this notice, the name of the X Consortium shall not 30c95b42baSmrg# be used in advertising or otherwise to promote the sale, use or other deal- 31c95b42baSmrg# ings in this Software without prior written authorization from the X Consor- 32c95b42baSmrg# tium. 33c95b42baSmrg# 34c95b42baSmrg# 35c95b42baSmrg# FSF changes to this file are in the public domain. 36c95b42baSmrg# 37c95b42baSmrg# Calling this script install-sh is preferred over install.sh, to prevent 38b8f63ae3Smrg# 'make' implicit rules from creating a file called install from it 39c95b42baSmrg# when there is no Makefile. 40c95b42baSmrg# 41c95b42baSmrg# This script is compatible with the BSD install script, but was written 42f40e0d56Smrg# from scratch. 43f40e0d56Smrg 44b8f63ae3Smrgtab=' ' 45f40e0d56Smrgnl=' 46f40e0d56Smrg' 47b8f63ae3SmrgIFS=" $tab$nl" 48c95b42baSmrg 49b8f63ae3Smrg# Set DOITPROG to "echo" to test this script. 50c95b42baSmrg 51f40e0d56Smrgdoit=${DOITPROG-} 52b8f63ae3Smrgdoit_exec=${doit:-exec} 53c95b42baSmrg 54f40e0d56Smrg# Put in absolute file names if you don't have them in your path; 55f40e0d56Smrg# or use environment vars. 56f40e0d56Smrg 57f40e0d56Smrgchgrpprog=${CHGRPPROG-chgrp} 58f40e0d56Smrgchmodprog=${CHMODPROG-chmod} 59f40e0d56Smrgchownprog=${CHOWNPROG-chown} 60f40e0d56Smrgcmpprog=${CMPPROG-cmp} 61f40e0d56Smrgcpprog=${CPPROG-cp} 62f40e0d56Smrgmkdirprog=${MKDIRPROG-mkdir} 63f40e0d56Smrgmvprog=${MVPROG-mv} 64f40e0d56Smrgrmprog=${RMPROG-rm} 65f40e0d56Smrgstripprog=${STRIPPROG-strip} 66f40e0d56Smrg 67f40e0d56Smrgposix_mkdir= 68f40e0d56Smrg 69f40e0d56Smrg# Desired mode of installed file. 70f40e0d56Smrgmode=0755 71c95b42baSmrg 720f595aedSmrg# Create dirs (including intermediate dirs) using mode 755. 730f595aedSmrg# This is like GNU 'install' as of coreutils 8.32 (2020). 740f595aedSmrgmkdir_umask=22 750f595aedSmrg 760f595aedSmrgbackupsuffix= 77c95b42baSmrgchgrpcmd= 78f40e0d56Smrgchmodcmd=$chmodprog 79f40e0d56Smrgchowncmd= 80f40e0d56Smrgmvcmd=$mvprog 81c95b42baSmrgrmcmd="$rmprog -f" 82f40e0d56Smrgstripcmd= 83f40e0d56Smrg 84c95b42baSmrgsrc= 85c95b42baSmrgdst= 86c95b42baSmrgdir_arg= 87f40e0d56Smrgdst_arg= 88f40e0d56Smrg 89f40e0d56Smrgcopy_on_change=false 90b8f63ae3Smrgis_target_a_directory=possibly 91c95b42baSmrg 92f40e0d56Smrgusage="\ 93f40e0d56SmrgUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 94c95b42baSmrg or: $0 [OPTION]... SRCFILES... DIRECTORY 95c95b42baSmrg or: $0 [OPTION]... -t DIRECTORY SRCFILES... 96c95b42baSmrg or: $0 [OPTION]... -d DIRECTORIES... 97c95b42baSmrg 98c95b42baSmrgIn the 1st form, copy SRCFILE to DSTFILE. 99c95b42baSmrgIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 100c95b42baSmrgIn the 4th, create DIRECTORIES. 101c95b42baSmrg 102c95b42baSmrgOptions: 103f40e0d56Smrg --help display this help and exit. 104f40e0d56Smrg --version display version info and exit. 105f40e0d56Smrg 106f40e0d56Smrg -c (ignored) 1070f595aedSmrg -C install only if different (preserve data modification time) 108f40e0d56Smrg -d create directories instead of installing files. 109f40e0d56Smrg -g GROUP $chgrpprog installed files to GROUP. 110f40e0d56Smrg -m MODE $chmodprog installed files to MODE. 111f40e0d56Smrg -o USER $chownprog installed files to USER. 1120f595aedSmrg -p pass -p to $cpprog. 113f40e0d56Smrg -s $stripprog installed files. 1140f595aedSmrg -S SUFFIX attempt to back up existing files, with suffix SUFFIX. 115f40e0d56Smrg -t DIRECTORY install into DIRECTORY. 116f40e0d56Smrg -T report an error if DSTFILE is a directory. 117c95b42baSmrg 118c95b42baSmrgEnvironment variables override the default commands: 119f40e0d56Smrg CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 120f40e0d56Smrg RMPROG STRIPPROG 1210f595aedSmrg 1220f595aedSmrgBy default, rm is invoked with -f; when overridden with RMPROG, 1230f595aedSmrgit's up to you to specify -f if you want it. 1240f595aedSmrg 1250f595aedSmrgIf -S is not specified, no backups are attempted. 1260f595aedSmrg 1270f595aedSmrgEmail bug reports to bug-automake@gnu.org. 1280f595aedSmrgAutomake home page: https://www.gnu.org/software/automake/ 129c95b42baSmrg" 130c95b42baSmrg 131f40e0d56Smrgwhile test $# -ne 0; do 132c95b42baSmrg case $1 in 133f40e0d56Smrg -c) ;; 134f40e0d56Smrg 135f40e0d56Smrg -C) copy_on_change=true;; 136c95b42baSmrg 137f40e0d56Smrg -d) dir_arg=true;; 138c95b42baSmrg 139c95b42baSmrg -g) chgrpcmd="$chgrpprog $2" 140b8f63ae3Smrg shift;; 141c95b42baSmrg 142c95b42baSmrg --help) echo "$usage"; exit $?;; 143c95b42baSmrg 144f40e0d56Smrg -m) mode=$2 145b8f63ae3Smrg case $mode in 146b8f63ae3Smrg *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 147b8f63ae3Smrg echo "$0: invalid mode: $mode" >&2 148b8f63ae3Smrg exit 1;; 149b8f63ae3Smrg esac 150b8f63ae3Smrg shift;; 151c95b42baSmrg 152c95b42baSmrg -o) chowncmd="$chownprog $2" 153b8f63ae3Smrg shift;; 154c95b42baSmrg 1550f595aedSmrg -p) cpprog="$cpprog -p";; 1560f595aedSmrg 157f40e0d56Smrg -s) stripcmd=$stripprog;; 158c95b42baSmrg 1590f595aedSmrg -S) backupsuffix="$2" 1600f595aedSmrg shift;; 1610f595aedSmrg 162b8f63ae3Smrg -t) 163b8f63ae3Smrg is_target_a_directory=always 164b8f63ae3Smrg dst_arg=$2 165b8f63ae3Smrg # Protect names problematic for 'test' and other utilities. 166b8f63ae3Smrg case $dst_arg in 167b8f63ae3Smrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 168b8f63ae3Smrg esac 169b8f63ae3Smrg shift;; 170c95b42baSmrg 171b8f63ae3Smrg -T) is_target_a_directory=never;; 172c95b42baSmrg 173c95b42baSmrg --version) echo "$0 $scriptversion"; exit $?;; 174c95b42baSmrg 175b8f63ae3Smrg --) shift 176b8f63ae3Smrg break;; 177f40e0d56Smrg 178b8f63ae3Smrg -*) echo "$0: invalid option: $1" >&2 179b8f63ae3Smrg exit 1;; 180f40e0d56Smrg 181f40e0d56Smrg *) break;; 182c95b42baSmrg esac 183f40e0d56Smrg shift 184c95b42baSmrgdone 185c95b42baSmrg 186b8f63ae3Smrg# We allow the use of options -d and -T together, by making -d 187b8f63ae3Smrg# take the precedence; this is for compatibility with GNU install. 188b8f63ae3Smrg 189b8f63ae3Smrgif test -n "$dir_arg"; then 190b8f63ae3Smrg if test -n "$dst_arg"; then 191b8f63ae3Smrg echo "$0: target directory not allowed when installing a directory." >&2 192b8f63ae3Smrg exit 1 193b8f63ae3Smrg fi 194b8f63ae3Smrgfi 195b8f63ae3Smrg 196f40e0d56Smrgif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 197f40e0d56Smrg # When -d is used, all remaining arguments are directories to create. 198f40e0d56Smrg # When -t is used, the destination is already specified. 199f40e0d56Smrg # Otherwise, the last argument is the destination. Remove it from $@. 200f40e0d56Smrg for arg 201f40e0d56Smrg do 202f40e0d56Smrg if test -n "$dst_arg"; then 203f40e0d56Smrg # $@ is not empty: it contains at least $arg. 204f40e0d56Smrg set fnord "$@" "$dst_arg" 205f40e0d56Smrg shift # fnord 206f40e0d56Smrg fi 207f40e0d56Smrg shift # arg 208f40e0d56Smrg dst_arg=$arg 209b8f63ae3Smrg # Protect names problematic for 'test' and other utilities. 21062aeb71dSmrg case $dst_arg in 21162aeb71dSmrg -* | [=\(\)!]) dst_arg=./$dst_arg;; 21262aeb71dSmrg esac 213f40e0d56Smrg done 214f40e0d56Smrgfi 215f40e0d56Smrg 216f40e0d56Smrgif test $# -eq 0; then 217c95b42baSmrg if test -z "$dir_arg"; then 218c95b42baSmrg echo "$0: no input file specified." >&2 219c95b42baSmrg exit 1 220c95b42baSmrg fi 221b8f63ae3Smrg # It's OK to call 'install-sh -d' without argument. 222c95b42baSmrg # This can happen when creating conditional directories. 223c95b42baSmrg exit 0 224c95b42baSmrgfi 225c95b42baSmrg 226b8f63ae3Smrgif test -z "$dir_arg"; then 227b8f63ae3Smrg if test $# -gt 1 || test "$is_target_a_directory" = always; then 228b8f63ae3Smrg if test ! -d "$dst_arg"; then 229b8f63ae3Smrg echo "$0: $dst_arg: Is not a directory." >&2 230b8f63ae3Smrg exit 1 231b8f63ae3Smrg fi 232b8f63ae3Smrg fi 233b8f63ae3Smrgfi 234b8f63ae3Smrg 235f40e0d56Smrgif test -z "$dir_arg"; then 23662aeb71dSmrg do_exit='(exit $ret); exit $ret' 23762aeb71dSmrg trap "ret=129; $do_exit" 1 23862aeb71dSmrg trap "ret=130; $do_exit" 2 23962aeb71dSmrg trap "ret=141; $do_exit" 13 24062aeb71dSmrg trap "ret=143; $do_exit" 15 241f40e0d56Smrg 242f40e0d56Smrg # Set umask so as not to create temps with too-generous modes. 243f40e0d56Smrg # However, 'strip' requires both read and write access to temps. 244f40e0d56Smrg case $mode in 245f40e0d56Smrg # Optimize common cases. 246f40e0d56Smrg *644) cp_umask=133;; 247f40e0d56Smrg *755) cp_umask=22;; 248f40e0d56Smrg 249f40e0d56Smrg *[0-7]) 250f40e0d56Smrg if test -z "$stripcmd"; then 251b8f63ae3Smrg u_plus_rw= 252f40e0d56Smrg else 253b8f63ae3Smrg u_plus_rw='% 200' 254f40e0d56Smrg fi 255f40e0d56Smrg cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 256f40e0d56Smrg *) 257f40e0d56Smrg if test -z "$stripcmd"; then 258b8f63ae3Smrg u_plus_rw= 259f40e0d56Smrg else 260b8f63ae3Smrg u_plus_rw=,u+rw 261f40e0d56Smrg fi 262f40e0d56Smrg cp_umask=$mode$u_plus_rw;; 263f40e0d56Smrg esac 264f40e0d56Smrgfi 265f40e0d56Smrg 266c95b42baSmrgfor src 267c95b42baSmrgdo 268b8f63ae3Smrg # Protect names problematic for 'test' and other utilities. 269c95b42baSmrg case $src in 27062aeb71dSmrg -* | [=\(\)!]) src=./$src;; 271c95b42baSmrg esac 272c95b42baSmrg 273c95b42baSmrg if test -n "$dir_arg"; then 274c95b42baSmrg dst=$src 275f40e0d56Smrg dstdir=$dst 276f40e0d56Smrg test -d "$dstdir" 277f40e0d56Smrg dstdir_status=$? 2780f595aedSmrg # Don't chown directories that already exist. 2790f595aedSmrg if test $dstdir_status = 0; then 2800f595aedSmrg chowncmd="" 2810f595aedSmrg fi 282c95b42baSmrg else 283f40e0d56Smrg 284c95b42baSmrg # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 285c95b42baSmrg # might cause directories to be created, which would be especially bad 286c95b42baSmrg # if $src (and thus $dsttmp) contains '*'. 287c95b42baSmrg if test ! -f "$src" && test ! -d "$src"; then 288c95b42baSmrg echo "$0: $src does not exist." >&2 289c95b42baSmrg exit 1 290c95b42baSmrg fi 291c95b42baSmrg 292f40e0d56Smrg if test -z "$dst_arg"; then 293c95b42baSmrg echo "$0: no destination specified." >&2 294c95b42baSmrg exit 1 295c95b42baSmrg fi 296f40e0d56Smrg dst=$dst_arg 297c95b42baSmrg 2980f595aedSmrg # If destination is a directory, append the input filename. 299c95b42baSmrg if test -d "$dst"; then 300b8f63ae3Smrg if test "$is_target_a_directory" = never; then 301b8f63ae3Smrg echo "$0: $dst_arg: Is a directory" >&2 302b8f63ae3Smrg exit 1 303c95b42baSmrg fi 304f40e0d56Smrg dstdir=$dst 3050f595aedSmrg dstbase=`basename "$src"` 3060f595aedSmrg case $dst in 3070f595aedSmrg */) dst=$dst$dstbase;; 3080f595aedSmrg *) dst=$dst/$dstbase;; 3090f595aedSmrg esac 310f40e0d56Smrg dstdir_status=0 311f40e0d56Smrg else 312b8f63ae3Smrg dstdir=`dirname "$dst"` 313f40e0d56Smrg test -d "$dstdir" 314f40e0d56Smrg dstdir_status=$? 315c95b42baSmrg fi 316c95b42baSmrg fi 317c95b42baSmrg 3180f595aedSmrg case $dstdir in 3190f595aedSmrg */) dstdirslash=$dstdir;; 3200f595aedSmrg *) dstdirslash=$dstdir/;; 3210f595aedSmrg esac 3220f595aedSmrg 323f40e0d56Smrg obsolete_mkdir_used=false 324f40e0d56Smrg 325f40e0d56Smrg if test $dstdir_status != 0; then 326f40e0d56Smrg case $posix_mkdir in 327f40e0d56Smrg '') 328b8f63ae3Smrg # With -d, create the new directory with the user-specified mode. 329b8f63ae3Smrg # Otherwise, rely on $mkdir_umask. 330b8f63ae3Smrg if test -n "$dir_arg"; then 331b8f63ae3Smrg mkdir_mode=-m$mode 332b8f63ae3Smrg else 333b8f63ae3Smrg mkdir_mode= 334b8f63ae3Smrg fi 335b8f63ae3Smrg 336b8f63ae3Smrg posix_mkdir=false 3370f595aedSmrg # The $RANDOM variable is not portable (e.g., dash). Use it 3380f595aedSmrg # here however when possible just to lower collision chance. 3390f595aedSmrg tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 3400f595aedSmrg 3410f595aedSmrg trap ' 3420f595aedSmrg ret=$? 3430f595aedSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null 3440f595aedSmrg exit $ret 3450f595aedSmrg ' 0 3460f595aedSmrg 3470f595aedSmrg # Because "mkdir -p" follows existing symlinks and we likely work 3480f595aedSmrg # directly in world-writeable /tmp, make sure that the '$tmpdir' 3490f595aedSmrg # directory is successfully created first before we actually test 3500f595aedSmrg # 'mkdir -p'. 3510f595aedSmrg if (umask $mkdir_umask && 3520f595aedSmrg $mkdirprog $mkdir_mode "$tmpdir" && 3530f595aedSmrg exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 3540f595aedSmrg then 3550f595aedSmrg if test -z "$dir_arg" || { 3560f595aedSmrg # Check for POSIX incompatibilities with -m. 3570f595aedSmrg # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 3580f595aedSmrg # other-writable bit of parent directory when it shouldn't. 3590f595aedSmrg # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 3600f595aedSmrg test_tmpdir="$tmpdir/a" 3610f595aedSmrg ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 3620f595aedSmrg case $ls_ld_tmpdir in 3630f595aedSmrg d????-?r-*) different_mode=700;; 3640f595aedSmrg d????-?--*) different_mode=755;; 3650f595aedSmrg *) false;; 3660f595aedSmrg esac && 3670f595aedSmrg $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 3680f595aedSmrg ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 3690f595aedSmrg test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 3700f595aedSmrg } 3710f595aedSmrg } 3720f595aedSmrg then posix_mkdir=: 3730f595aedSmrg fi 3740f595aedSmrg rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 3750f595aedSmrg else 3760f595aedSmrg # Remove any dirs left behind by ancient mkdir implementations. 3770f595aedSmrg rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 3780f595aedSmrg fi 3790f595aedSmrg trap '' 0;; 380f40e0d56Smrg esac 381c95b42baSmrg 382f40e0d56Smrg if 383f40e0d56Smrg $posix_mkdir && ( 384b8f63ae3Smrg umask $mkdir_umask && 385b8f63ae3Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 386f40e0d56Smrg ) 387f40e0d56Smrg then : 388f40e0d56Smrg else 389c95b42baSmrg 3900f595aedSmrg # mkdir does not conform to POSIX, 391f40e0d56Smrg # or it failed possibly due to a race condition. Create the 392f40e0d56Smrg # directory the slow way, step by step, checking for races as we go. 393c95b42baSmrg 394f40e0d56Smrg case $dstdir in 395b8f63ae3Smrg /*) prefix='/';; 396b8f63ae3Smrg [-=\(\)!]*) prefix='./';; 397b8f63ae3Smrg *) prefix='';; 398f40e0d56Smrg esac 399c95b42baSmrg 400f40e0d56Smrg oIFS=$IFS 401f40e0d56Smrg IFS=/ 402b8f63ae3Smrg set -f 403f40e0d56Smrg set fnord $dstdir 404c95b42baSmrg shift 405b8f63ae3Smrg set +f 406f40e0d56Smrg IFS=$oIFS 407f40e0d56Smrg 408f40e0d56Smrg prefixes= 409f40e0d56Smrg 410f40e0d56Smrg for d 411f40e0d56Smrg do 412b8f63ae3Smrg test X"$d" = X && continue 413b8f63ae3Smrg 414b8f63ae3Smrg prefix=$prefix$d 415b8f63ae3Smrg if test -d "$prefix"; then 416b8f63ae3Smrg prefixes= 417b8f63ae3Smrg else 418b8f63ae3Smrg if $posix_mkdir; then 4190f595aedSmrg (umask $mkdir_umask && 420b8f63ae3Smrg $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 421b8f63ae3Smrg # Don't fail if two instances are running concurrently. 422b8f63ae3Smrg test -d "$prefix" || exit 1 423b8f63ae3Smrg else 424b8f63ae3Smrg case $prefix in 425b8f63ae3Smrg *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 426b8f63ae3Smrg *) qprefix=$prefix;; 427b8f63ae3Smrg esac 428b8f63ae3Smrg prefixes="$prefixes '$qprefix'" 429b8f63ae3Smrg fi 430b8f63ae3Smrg fi 431b8f63ae3Smrg prefix=$prefix/ 432f40e0d56Smrg done 433f40e0d56Smrg 434f40e0d56Smrg if test -n "$prefixes"; then 435b8f63ae3Smrg # Don't fail if two instances are running concurrently. 436b8f63ae3Smrg (umask $mkdir_umask && 437b8f63ae3Smrg eval "\$doit_exec \$mkdirprog $prefixes") || 438b8f63ae3Smrg test -d "$dstdir" || exit 1 439b8f63ae3Smrg obsolete_mkdir_used=true 440c95b42baSmrg fi 441f40e0d56Smrg fi 442c95b42baSmrg fi 443c95b42baSmrg 444c95b42baSmrg if test -n "$dir_arg"; then 445f40e0d56Smrg { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 446f40e0d56Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 447f40e0d56Smrg { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 448f40e0d56Smrg test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 449c95b42baSmrg else 450c95b42baSmrg 451c95b42baSmrg # Make a couple of temp file names in the proper directory. 4520f595aedSmrg dsttmp=${dstdirslash}_inst.$$_ 4530f595aedSmrg rmtmp=${dstdirslash}_rm.$$_ 454c95b42baSmrg 455c95b42baSmrg # Trap to clean up those temp files at exit. 456c95b42baSmrg trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 457c95b42baSmrg 458c95b42baSmrg # Copy the file name to the temp name. 4590f595aedSmrg (umask $cp_umask && 4600f595aedSmrg { test -z "$stripcmd" || { 4610f595aedSmrg # Create $dsttmp read-write so that cp doesn't create it read-only, 4620f595aedSmrg # which would cause strip to fail. 4630f595aedSmrg if test -z "$doit"; then 4640f595aedSmrg : >"$dsttmp" # No need to fork-exec 'touch'. 4650f595aedSmrg else 4660f595aedSmrg $doit touch "$dsttmp" 4670f595aedSmrg fi 4680f595aedSmrg } 4690f595aedSmrg } && 4700f595aedSmrg $doit_exec $cpprog "$src" "$dsttmp") && 471c95b42baSmrg 472c95b42baSmrg # and set any options; do chmod last to preserve setuid bits. 473c95b42baSmrg # 474c95b42baSmrg # If any of these fail, we abort the whole thing. If we want to 475c95b42baSmrg # ignore errors from any of these, just make sure not to ignore 476c95b42baSmrg # errors from the above "$doit $cpprog $src $dsttmp" command. 477c95b42baSmrg # 478f40e0d56Smrg { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 479f40e0d56Smrg { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 480f40e0d56Smrg { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 481f40e0d56Smrg { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 482f40e0d56Smrg 483f40e0d56Smrg # If -C, don't bother to copy if it wouldn't change the file. 484f40e0d56Smrg if $copy_on_change && 485b8f63ae3Smrg old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 486b8f63ae3Smrg new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 487b8f63ae3Smrg set -f && 488f40e0d56Smrg set X $old && old=:$2:$4:$5:$6 && 489f40e0d56Smrg set X $new && new=:$2:$4:$5:$6 && 490b8f63ae3Smrg set +f && 491f40e0d56Smrg test "$old" = "$new" && 492f40e0d56Smrg $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 493f40e0d56Smrg then 494f40e0d56Smrg rm -f "$dsttmp" 495f40e0d56Smrg else 4960f595aedSmrg # If $backupsuffix is set, and the file being installed 4970f595aedSmrg # already exists, attempt a backup. Don't worry if it fails, 4980f595aedSmrg # e.g., if mv doesn't support -f. 4990f595aedSmrg if test -n "$backupsuffix" && test -f "$dst"; then 5000f595aedSmrg $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null 5010f595aedSmrg fi 5020f595aedSmrg 503f40e0d56Smrg # Rename the file to the real destination. 504f40e0d56Smrg $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 505f40e0d56Smrg 506f40e0d56Smrg # The rename failed, perhaps because mv can't rename something else 507f40e0d56Smrg # to itself, or perhaps because mv is so ancient that it does not 508f40e0d56Smrg # support -f. 509f40e0d56Smrg { 510b8f63ae3Smrg # Now remove or move aside any old file at destination location. 511b8f63ae3Smrg # We try this two ways since rm can't unlink itself on some 512b8f63ae3Smrg # systems and the destination file might be busy for other 513b8f63ae3Smrg # reasons. In this case, the final cleanup might fail but the new 514b8f63ae3Smrg # file should still install successfully. 515b8f63ae3Smrg { 516b8f63ae3Smrg test ! -f "$dst" || 5170f595aedSmrg $doit $rmcmd "$dst" 2>/dev/null || 518b8f63ae3Smrg { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 5190f595aedSmrg { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } 520b8f63ae3Smrg } || 521b8f63ae3Smrg { echo "$0: cannot unlink or rename $dst" >&2 522b8f63ae3Smrg (exit 1); exit 1 523b8f63ae3Smrg } 524b8f63ae3Smrg } && 525b8f63ae3Smrg 526b8f63ae3Smrg # Now rename the file to the real destination. 527b8f63ae3Smrg $doit $mvcmd "$dsttmp" "$dst" 528f40e0d56Smrg } 529f40e0d56Smrg fi || exit 1 530f40e0d56Smrg 531f40e0d56Smrg trap '' 0 532f40e0d56Smrg fi 533c95b42baSmrgdone 534c95b42baSmrg 535c95b42baSmrg# Local variables: 5360f595aedSmrg# eval: (add-hook 'before-save-hook 'time-stamp) 537c95b42baSmrg# time-stamp-start: "scriptversion=" 538c95b42baSmrg# time-stamp-format: "%:y-%02m-%02d.%02H" 5390f595aedSmrg# time-stamp-time-zone: "UTC0" 540f40e0d56Smrg# time-stamp-end: "; # UTC" 541c95b42baSmrg# End: 542