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