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