175a6cdb3SDavid E. O'Brien#!/bin/sh 275a6cdb3SDavid E. O'Brien# install - install a program, script, or datafile 3d1d50c78SDavid E. O'Brien 4974b70c4SDavid E. O'Brienscriptversion=2006-10-14.15 5d1d50c78SDavid E. O'Brien 6d1d50c78SDavid E. O'Brien# This originates from X11R5 (mit/util/scripts/install.sh), which was 7d1d50c78SDavid E. O'Brien# later released in X11R6 (xc/config/util/install.sh) with the 8d1d50c78SDavid E. O'Brien# following copyright and license. 9a2e8fb4cSDavid E. O'Brien# 10d1d50c78SDavid E. O'Brien# Copyright (C) 1994 X Consortium 11a2e8fb4cSDavid E. O'Brien# 12d1d50c78SDavid E. O'Brien# Permission is hereby granted, free of charge, to any person obtaining a copy 13d1d50c78SDavid E. O'Brien# of this software and associated documentation files (the "Software"), to 14d1d50c78SDavid E. O'Brien# deal in the Software without restriction, including without limitation the 15d1d50c78SDavid E. O'Brien# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16d1d50c78SDavid E. O'Brien# sell copies of the Software, and to permit persons to whom the Software is 17d1d50c78SDavid E. O'Brien# furnished to do so, subject to the following conditions: 18d1d50c78SDavid E. O'Brien# 19d1d50c78SDavid E. O'Brien# The above copyright notice and this permission notice shall be included in 20d1d50c78SDavid E. O'Brien# all copies or substantial portions of the Software. 21d1d50c78SDavid E. O'Brien# 22d1d50c78SDavid E. O'Brien# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23d1d50c78SDavid E. O'Brien# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24d1d50c78SDavid E. O'Brien# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25d1d50c78SDavid E. O'Brien# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26d1d50c78SDavid E. O'Brien# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27d1d50c78SDavid E. O'Brien# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28d1d50c78SDavid E. O'Brien# 29d1d50c78SDavid E. O'Brien# Except as contained in this notice, the name of the X Consortium shall not 30d1d50c78SDavid E. O'Brien# be used in advertising or otherwise to promote the sale, use or other deal- 31d1d50c78SDavid E. O'Brien# ings in this Software without prior written authorization from the X Consor- 32d1d50c78SDavid E. O'Brien# tium. 33d1d50c78SDavid E. O'Brien# 34d1d50c78SDavid E. O'Brien# 35d1d50c78SDavid E. O'Brien# FSF changes to this file are in the public domain. 3675a6cdb3SDavid E. O'Brien# 3775a6cdb3SDavid E. O'Brien# Calling this script install-sh is preferred over install.sh, to prevent 3875a6cdb3SDavid E. O'Brien# `make' implicit rules from creating a file called install from it 3975a6cdb3SDavid E. O'Brien# when there is no Makefile. 4075a6cdb3SDavid E. O'Brien# 4175a6cdb3SDavid E. O'Brien# This script is compatible with the BSD install script, but was written 42974b70c4SDavid E. O'Brien# from scratch. 43974b70c4SDavid E. O'Brien 44974b70c4SDavid E. O'Briennl=' 45974b70c4SDavid E. O'Brien' 46974b70c4SDavid E. O'BrienIFS=" "" $nl" 4775a6cdb3SDavid E. O'Brien 4875a6cdb3SDavid E. O'Brien# set DOITPROG to echo to test this script 4975a6cdb3SDavid E. O'Brien 5075a6cdb3SDavid E. O'Brien# Don't use :- since 4.3BSD and earlier shells don't like it. 5175a6cdb3SDavid E. O'Briendoit="${DOITPROG-}" 52974b70c4SDavid E. O'Brienif test -z "$doit"; then 53974b70c4SDavid E. O'Brien doit_exec=exec 54974b70c4SDavid E. O'Brienelse 55974b70c4SDavid E. O'Brien doit_exec=$doit 56974b70c4SDavid E. O'Brienfi 5775a6cdb3SDavid E. O'Brien 58974b70c4SDavid E. O'Brien# Put in absolute file names if you don't have them in your path; 59974b70c4SDavid E. O'Brien# or use environment vars. 6075a6cdb3SDavid E. O'Brien 6175a6cdb3SDavid E. O'Brienmvprog="${MVPROG-mv}" 6275a6cdb3SDavid E. O'Briencpprog="${CPPROG-cp}" 6375a6cdb3SDavid E. O'Brienchmodprog="${CHMODPROG-chmod}" 6475a6cdb3SDavid E. O'Brienchownprog="${CHOWNPROG-chown}" 6575a6cdb3SDavid E. O'Brienchgrpprog="${CHGRPPROG-chgrp}" 6675a6cdb3SDavid E. O'Brienstripprog="${STRIPPROG-strip}" 6775a6cdb3SDavid E. O'Brienrmprog="${RMPROG-rm}" 6875a6cdb3SDavid E. O'Brienmkdirprog="${MKDIRPROG-mkdir}" 6975a6cdb3SDavid E. O'Brien 70974b70c4SDavid E. O'Brienposix_glob= 71974b70c4SDavid E. O'Brienposix_mkdir= 72974b70c4SDavid E. O'Brien 73974b70c4SDavid E. O'Brien# Desired mode of installed file. 74974b70c4SDavid E. O'Brienmode=0755 75974b70c4SDavid E. O'Brien 76974b70c4SDavid E. O'Brienchmodcmd=$chmodprog 77d1d50c78SDavid E. O'Brienchowncmd= 78d1d50c78SDavid E. O'Brienchgrpcmd= 79d1d50c78SDavid E. O'Brienstripcmd= 8075a6cdb3SDavid E. O'Brienrmcmd="$rmprog -f" 8175a6cdb3SDavid E. O'Brienmvcmd="$mvprog" 82d1d50c78SDavid E. O'Briensrc= 83d1d50c78SDavid E. O'Briendst= 84d1d50c78SDavid E. O'Briendir_arg= 85d1d50c78SDavid E. O'Briendstarg= 86d1d50c78SDavid E. O'Brienno_target_directory= 8775a6cdb3SDavid E. O'Brien 88d1d50c78SDavid E. O'Brienusage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89d1d50c78SDavid E. O'Brien or: $0 [OPTION]... SRCFILES... DIRECTORY 90d1d50c78SDavid E. O'Brien or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91d1d50c78SDavid E. O'Brien or: $0 [OPTION]... -d DIRECTORIES... 92d1d50c78SDavid E. O'Brien 93d1d50c78SDavid E. O'BrienIn the 1st form, copy SRCFILE to DSTFILE. 94d1d50c78SDavid E. O'BrienIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95d1d50c78SDavid E. O'BrienIn the 4th, create DIRECTORIES. 96d1d50c78SDavid E. O'Brien 97d1d50c78SDavid E. O'BrienOptions: 98d1d50c78SDavid E. O'Brien-c (ignored) 99d1d50c78SDavid E. O'Brien-d create directories instead of installing files. 100d1d50c78SDavid E. O'Brien-g GROUP $chgrpprog installed files to GROUP. 101d1d50c78SDavid E. O'Brien-m MODE $chmodprog installed files to MODE. 102d1d50c78SDavid E. O'Brien-o USER $chownprog installed files to USER. 103d1d50c78SDavid E. O'Brien-s $stripprog installed files. 104d1d50c78SDavid E. O'Brien-t DIRECTORY install into DIRECTORY. 105d1d50c78SDavid E. O'Brien-T report an error if DSTFILE is a directory. 106d1d50c78SDavid E. O'Brien--help display this help and exit. 107d1d50c78SDavid E. O'Brien--version display version info and exit. 108d1d50c78SDavid E. O'Brien 109d1d50c78SDavid E. O'BrienEnvironment variables override the default commands: 110d1d50c78SDavid E. O'Brien CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 111d1d50c78SDavid E. O'Brien" 112d1d50c78SDavid E. O'Brien 113974b70c4SDavid E. O'Brienwhile test $# -ne 0; do 11475a6cdb3SDavid E. O'Brien case $1 in 115d1d50c78SDavid E. O'Brien -c) shift 11675a6cdb3SDavid E. O'Brien continue;; 11775a6cdb3SDavid E. O'Brien 11875a6cdb3SDavid E. O'Brien -d) dir_arg=true 11975a6cdb3SDavid E. O'Brien shift 12075a6cdb3SDavid E. O'Brien continue;; 12175a6cdb3SDavid E. O'Brien 122d1d50c78SDavid E. O'Brien -g) chgrpcmd="$chgrpprog $2" 123d1d50c78SDavid E. O'Brien shift 124d1d50c78SDavid E. O'Brien shift 125d1d50c78SDavid E. O'Brien continue;; 126d1d50c78SDavid E. O'Brien 127d1d50c78SDavid E. O'Brien --help) echo "$usage"; exit $?;; 128d1d50c78SDavid E. O'Brien 129974b70c4SDavid E. O'Brien -m) mode=$2 13075a6cdb3SDavid E. O'Brien shift 13175a6cdb3SDavid E. O'Brien shift 132974b70c4SDavid E. O'Brien case $mode in 133974b70c4SDavid E. O'Brien *' '* | *' '* | *' 134974b70c4SDavid E. O'Brien'* | *'*'* | *'?'* | *'['*) 135974b70c4SDavid E. O'Brien echo "$0: invalid mode: $mode" >&2 136974b70c4SDavid E. O'Brien exit 1;; 137974b70c4SDavid E. O'Brien esac 13875a6cdb3SDavid E. O'Brien continue;; 13975a6cdb3SDavid E. O'Brien 14075a6cdb3SDavid E. O'Brien -o) chowncmd="$chownprog $2" 14175a6cdb3SDavid E. O'Brien shift 14275a6cdb3SDavid E. O'Brien shift 14375a6cdb3SDavid E. O'Brien continue;; 14475a6cdb3SDavid E. O'Brien 145d1d50c78SDavid E. O'Brien -s) stripcmd=$stripprog 146d1d50c78SDavid E. O'Brien shift 147d1d50c78SDavid E. O'Brien continue;; 148d1d50c78SDavid E. O'Brien 149d1d50c78SDavid E. O'Brien -t) dstarg=$2 15075a6cdb3SDavid E. O'Brien shift 15175a6cdb3SDavid E. O'Brien shift 15275a6cdb3SDavid E. O'Brien continue;; 15375a6cdb3SDavid E. O'Brien 154d1d50c78SDavid E. O'Brien -T) no_target_directory=true 15575a6cdb3SDavid E. O'Brien shift 15675a6cdb3SDavid E. O'Brien continue;; 15775a6cdb3SDavid E. O'Brien 158d1d50c78SDavid E. O'Brien --version) echo "$0 $scriptversion"; exit $?;; 15975a6cdb3SDavid E. O'Brien 160974b70c4SDavid E. O'Brien --) shift 161974b70c4SDavid E. O'Brien break;; 162974b70c4SDavid E. O'Brien 163974b70c4SDavid E. O'Brien -*) echo "$0: invalid option: $1" >&2 164974b70c4SDavid E. O'Brien exit 1;; 165974b70c4SDavid E. O'Brien 166974b70c4SDavid E. O'Brien *) break;; 167974b70c4SDavid E. O'Brien esac 168974b70c4SDavid E. O'Briendone 169974b70c4SDavid E. O'Brien 170974b70c4SDavid E. O'Brienif test $# -ne 0 && test -z "$dir_arg$dstarg"; then 171974b70c4SDavid E. O'Brien # When -d is used, all remaining arguments are directories to create. 172d1d50c78SDavid E. O'Brien # When -t is used, the destination is already specified. 173d1d50c78SDavid E. O'Brien # Otherwise, the last argument is the destination. Remove it from $@. 174d1d50c78SDavid E. O'Brien for arg 175d1d50c78SDavid E. O'Brien do 176d1d50c78SDavid E. O'Brien if test -n "$dstarg"; then 177d1d50c78SDavid E. O'Brien # $@ is not empty: it contains at least $arg. 178d1d50c78SDavid E. O'Brien set fnord "$@" "$dstarg" 179d1d50c78SDavid E. O'Brien shift # fnord 18075a6cdb3SDavid E. O'Brien fi 181d1d50c78SDavid E. O'Brien shift # arg 182d1d50c78SDavid E. O'Brien dstarg=$arg 183d1d50c78SDavid E. O'Brien done 184974b70c4SDavid E. O'Brienfi 18575a6cdb3SDavid E. O'Brien 186974b70c4SDavid E. O'Brienif test $# -eq 0; then 187d1d50c78SDavid E. O'Brien if test -z "$dir_arg"; then 188d1d50c78SDavid E. O'Brien echo "$0: no input file specified." >&2 18975a6cdb3SDavid E. O'Brien exit 1 190d1d50c78SDavid E. O'Brien fi 191d1d50c78SDavid E. O'Brien # It's OK to call `install-sh -d' without argument. 192d1d50c78SDavid E. O'Brien # This can happen when creating conditional directories. 193d1d50c78SDavid E. O'Brien exit 0 19475a6cdb3SDavid E. O'Brienfi 19575a6cdb3SDavid E. O'Brien 196974b70c4SDavid E. O'Brienif test -z "$dir_arg"; then 197974b70c4SDavid E. O'Brien trap '(exit $?); exit' 1 2 13 15 198974b70c4SDavid E. O'Brien 199974b70c4SDavid E. O'Brien # Set umask so as not to create temps with too-generous modes. 200974b70c4SDavid E. O'Brien # However, 'strip' requires both read and write access to temps. 201974b70c4SDavid E. O'Brien case $mode in 202974b70c4SDavid E. O'Brien # Optimize common cases. 203974b70c4SDavid E. O'Brien *644) cp_umask=133;; 204974b70c4SDavid E. O'Brien *755) cp_umask=22;; 205974b70c4SDavid E. O'Brien 206974b70c4SDavid E. O'Brien *[0-7]) 207974b70c4SDavid E. O'Brien if test -z "$stripcmd"; then 208974b70c4SDavid E. O'Brien u_plus_rw= 209974b70c4SDavid E. O'Brien else 210974b70c4SDavid E. O'Brien u_plus_rw='% 200' 211974b70c4SDavid E. O'Brien fi 212974b70c4SDavid E. O'Brien cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 213974b70c4SDavid E. O'Brien *) 214974b70c4SDavid E. O'Brien if test -z "$stripcmd"; then 215974b70c4SDavid E. O'Brien u_plus_rw= 216974b70c4SDavid E. O'Brien else 217974b70c4SDavid E. O'Brien u_plus_rw=,u+rw 218974b70c4SDavid E. O'Brien fi 219974b70c4SDavid E. O'Brien cp_umask=$mode$u_plus_rw;; 220974b70c4SDavid E. O'Brien esac 221974b70c4SDavid E. O'Brienfi 222974b70c4SDavid E. O'Brien 223d1d50c78SDavid E. O'Brienfor src 224d1d50c78SDavid E. O'Briendo 225d1d50c78SDavid E. O'Brien # Protect names starting with `-'. 226d1d50c78SDavid E. O'Brien case $src in 227d1d50c78SDavid E. O'Brien -*) src=./$src ;; 228d1d50c78SDavid E. O'Brien esac 229d1d50c78SDavid E. O'Brien 230d1d50c78SDavid E. O'Brien if test -n "$dir_arg"; then 23175a6cdb3SDavid E. O'Brien dst=$src 232974b70c4SDavid E. O'Brien dstdir=$dst 233974b70c4SDavid E. O'Brien test -d "$dstdir" 234974b70c4SDavid E. O'Brien dstdir_status=$? 235974b70c4SDavid E. O'Brien else 23675a6cdb3SDavid E. O'Brien 237d1d50c78SDavid E. O'Brien # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 23875a6cdb3SDavid E. O'Brien # might cause directories to be created, which would be especially bad 23975a6cdb3SDavid E. O'Brien # if $src (and thus $dsttmp) contains '*'. 240d1d50c78SDavid E. O'Brien if test ! -f "$src" && test ! -d "$src"; then 241d1d50c78SDavid E. O'Brien echo "$0: $src does not exist." >&2 24275a6cdb3SDavid E. O'Brien exit 1 24375a6cdb3SDavid E. O'Brien fi 24475a6cdb3SDavid E. O'Brien 245d1d50c78SDavid E. O'Brien if test -z "$dstarg"; then 246d1d50c78SDavid E. O'Brien echo "$0: no destination specified." >&2 24775a6cdb3SDavid E. O'Brien exit 1 24875a6cdb3SDavid E. O'Brien fi 24975a6cdb3SDavid E. O'Brien 250d1d50c78SDavid E. O'Brien dst=$dstarg 251d1d50c78SDavid E. O'Brien # Protect names starting with `-'. 252d1d50c78SDavid E. O'Brien case $dst in 253d1d50c78SDavid E. O'Brien -*) dst=./$dst ;; 254d1d50c78SDavid E. O'Brien esac 25575a6cdb3SDavid E. O'Brien 256d1d50c78SDavid E. O'Brien # If destination is a directory, append the input filename; won't work 257d1d50c78SDavid E. O'Brien # if double slashes aren't ignored. 258d1d50c78SDavid E. O'Brien if test -d "$dst"; then 259d1d50c78SDavid E. O'Brien if test -n "$no_target_directory"; then 260d1d50c78SDavid E. O'Brien echo "$0: $dstarg: Is a directory" >&2 261d1d50c78SDavid E. O'Brien exit 1 262d1d50c78SDavid E. O'Brien fi 263974b70c4SDavid E. O'Brien dstdir=$dst 264974b70c4SDavid E. O'Brien dst=$dstdir/`basename "$src"` 265974b70c4SDavid E. O'Brien dstdir_status=0 266974b70c4SDavid E. O'Brien else 267974b70c4SDavid E. O'Brien # Prefer dirname, but fall back on a substitute if dirname fails. 268974b70c4SDavid E. O'Brien dstdir=` 269974b70c4SDavid E. O'Brien (dirname "$dst") 2>/dev/null || 270974b70c4SDavid E. O'Brien expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 271974b70c4SDavid E. O'Brien X"$dst" : 'X\(//\)[^/]' \| \ 272974b70c4SDavid E. O'Brien X"$dst" : 'X\(//\)$' \| \ 273974b70c4SDavid E. O'Brien X"$dst" : 'X\(/\)' \| . 2>/dev/null || 274974b70c4SDavid E. O'Brien echo X"$dst" | 275974b70c4SDavid E. O'Brien sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 276974b70c4SDavid E. O'Brien s//\1/ 277974b70c4SDavid E. O'Brien q 278974b70c4SDavid E. O'Brien } 279974b70c4SDavid E. O'Brien /^X\(\/\/\)[^/].*/{ 280974b70c4SDavid E. O'Brien s//\1/ 281974b70c4SDavid E. O'Brien q 282974b70c4SDavid E. O'Brien } 283974b70c4SDavid E. O'Brien /^X\(\/\/\)$/{ 284974b70c4SDavid E. O'Brien s//\1/ 285974b70c4SDavid E. O'Brien q 286974b70c4SDavid E. O'Brien } 287974b70c4SDavid E. O'Brien /^X\(\/\).*/{ 288974b70c4SDavid E. O'Brien s//\1/ 289974b70c4SDavid E. O'Brien q 290974b70c4SDavid E. O'Brien } 291974b70c4SDavid E. O'Brien s/.*/./; q' 292974b70c4SDavid E. O'Brien ` 293974b70c4SDavid E. O'Brien 294974b70c4SDavid E. O'Brien test -d "$dstdir" 295974b70c4SDavid E. O'Brien dstdir_status=$? 29675a6cdb3SDavid E. O'Brien fi 29775a6cdb3SDavid E. O'Brien fi 29875a6cdb3SDavid E. O'Brien 299974b70c4SDavid E. O'Brien obsolete_mkdir_used=false 30075a6cdb3SDavid E. O'Brien 301974b70c4SDavid E. O'Brien if test $dstdir_status != 0; then 302974b70c4SDavid E. O'Brien case $posix_mkdir in 303974b70c4SDavid E. O'Brien '') 304974b70c4SDavid E. O'Brien # Create intermediate dirs using mode 755 as modified by the umask. 305974b70c4SDavid E. O'Brien # This is like FreeBSD 'install' as of 1997-10-28. 306974b70c4SDavid E. O'Brien umask=`umask` 307974b70c4SDavid E. O'Brien case $stripcmd.$umask in 308974b70c4SDavid E. O'Brien # Optimize common cases. 309974b70c4SDavid E. O'Brien *[2367][2367]) mkdir_umask=$umask;; 310974b70c4SDavid E. O'Brien .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 31175a6cdb3SDavid E. O'Brien 312974b70c4SDavid E. O'Brien *[0-7]) 313974b70c4SDavid E. O'Brien mkdir_umask=`expr $umask + 22 \ 314974b70c4SDavid E. O'Brien - $umask % 100 % 40 + $umask % 20 \ 315974b70c4SDavid E. O'Brien - $umask % 10 % 4 + $umask % 2 316974b70c4SDavid E. O'Brien `;; 317974b70c4SDavid E. O'Brien *) mkdir_umask=$umask,go-w;; 318974b70c4SDavid E. O'Brien esac 319974b70c4SDavid E. O'Brien 320974b70c4SDavid E. O'Brien # With -d, create the new directory with the user-specified mode. 321974b70c4SDavid E. O'Brien # Otherwise, rely on $mkdir_umask. 322974b70c4SDavid E. O'Brien if test -n "$dir_arg"; then 323974b70c4SDavid E. O'Brien mkdir_mode=-m$mode 324974b70c4SDavid E. O'Brien else 325974b70c4SDavid E. O'Brien mkdir_mode= 326974b70c4SDavid E. O'Brien fi 327974b70c4SDavid E. O'Brien 328974b70c4SDavid E. O'Brien posix_mkdir=false 329974b70c4SDavid E. O'Brien case $umask in 330974b70c4SDavid E. O'Brien *[123567][0-7][0-7]) 331974b70c4SDavid E. O'Brien # POSIX mkdir -p sets u+wx bits regardless of umask, which 332974b70c4SDavid E. O'Brien # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 333974b70c4SDavid E. O'Brien ;; 334974b70c4SDavid E. O'Brien *) 335974b70c4SDavid E. O'Brien tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 336974b70c4SDavid E. O'Brien trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 337974b70c4SDavid E. O'Brien 338974b70c4SDavid E. O'Brien if (umask $mkdir_umask && 339974b70c4SDavid E. O'Brien exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 340974b70c4SDavid E. O'Brien then 341974b70c4SDavid E. O'Brien if test -z "$dir_arg" || { 342974b70c4SDavid E. O'Brien # Check for POSIX incompatibilities with -m. 343974b70c4SDavid E. O'Brien # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 344974b70c4SDavid E. O'Brien # other-writeable bit of parent directory when it shouldn't. 345974b70c4SDavid E. O'Brien # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 346974b70c4SDavid E. O'Brien ls_ld_tmpdir=`ls -ld "$tmpdir"` 347974b70c4SDavid E. O'Brien case $ls_ld_tmpdir in 348974b70c4SDavid E. O'Brien d????-?r-*) different_mode=700;; 349974b70c4SDavid E. O'Brien d????-?--*) different_mode=755;; 350974b70c4SDavid E. O'Brien *) false;; 351974b70c4SDavid E. O'Brien esac && 352974b70c4SDavid E. O'Brien $mkdirprog -m$different_mode -p -- "$tmpdir" && { 353974b70c4SDavid E. O'Brien ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 354974b70c4SDavid E. O'Brien test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 355974b70c4SDavid E. O'Brien } 356974b70c4SDavid E. O'Brien } 357974b70c4SDavid E. O'Brien then posix_mkdir=: 358974b70c4SDavid E. O'Brien fi 359974b70c4SDavid E. O'Brien rmdir "$tmpdir/d" "$tmpdir" 360974b70c4SDavid E. O'Brien else 361974b70c4SDavid E. O'Brien # Remove any dirs left behind by ancient mkdir implementations. 362974b70c4SDavid E. O'Brien rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 363974b70c4SDavid E. O'Brien fi 364974b70c4SDavid E. O'Brien trap '' 0;; 365974b70c4SDavid E. O'Brien esac;; 366974b70c4SDavid E. O'Brien esac 367974b70c4SDavid E. O'Brien 368974b70c4SDavid E. O'Brien if 369974b70c4SDavid E. O'Brien $posix_mkdir && ( 370974b70c4SDavid E. O'Brien umask $mkdir_umask && 371974b70c4SDavid E. O'Brien $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 372974b70c4SDavid E. O'Brien ) 373974b70c4SDavid E. O'Brien then : 374974b70c4SDavid E. O'Brien else 375974b70c4SDavid E. O'Brien 376974b70c4SDavid E. O'Brien # The umask is ridiculous, or mkdir does not conform to POSIX, 377974b70c4SDavid E. O'Brien # or it failed possibly due to a race condition. Create the 378974b70c4SDavid E. O'Brien # directory the slow way, step by step, checking for races as we go. 379974b70c4SDavid E. O'Brien 380974b70c4SDavid E. O'Brien case $dstdir in 381974b70c4SDavid E. O'Brien /*) prefix=/ ;; 382974b70c4SDavid E. O'Brien -*) prefix=./ ;; 383974b70c4SDavid E. O'Brien *) prefix= ;; 384974b70c4SDavid E. O'Brien esac 385974b70c4SDavid E. O'Brien 386974b70c4SDavid E. O'Brien case $posix_glob in 387974b70c4SDavid E. O'Brien '') 388974b70c4SDavid E. O'Brien if (set -f) 2>/dev/null; then 389974b70c4SDavid E. O'Brien posix_glob=true 390974b70c4SDavid E. O'Brien else 391974b70c4SDavid E. O'Brien posix_glob=false 392974b70c4SDavid E. O'Brien fi ;; 393974b70c4SDavid E. O'Brien esac 39475a6cdb3SDavid E. O'Brien 395d1d50c78SDavid E. O'Brien oIFS=$IFS 396974b70c4SDavid E. O'Brien IFS=/ 397974b70c4SDavid E. O'Brien $posix_glob && set -f 398974b70c4SDavid E. O'Brien set fnord $dstdir 39975a6cdb3SDavid E. O'Brien shift 400974b70c4SDavid E. O'Brien $posix_glob && set +f 401d1d50c78SDavid E. O'Brien IFS=$oIFS 40275a6cdb3SDavid E. O'Brien 403974b70c4SDavid E. O'Brien prefixes= 404d1d50c78SDavid E. O'Brien 405974b70c4SDavid E. O'Brien for d 406974b70c4SDavid E. O'Brien do 407974b70c4SDavid E. O'Brien test -z "$d" && continue 408974b70c4SDavid E. O'Brien 409974b70c4SDavid E. O'Brien prefix=$prefix$d 410974b70c4SDavid E. O'Brien if test -d "$prefix"; then 411974b70c4SDavid E. O'Brien prefixes= 412974b70c4SDavid E. O'Brien else 413974b70c4SDavid E. O'Brien if $posix_mkdir; then 414974b70c4SDavid E. O'Brien (umask=$mkdir_umask && 415974b70c4SDavid E. O'Brien $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 416974b70c4SDavid E. O'Brien # Don't fail if two instances are running concurrently. 417974b70c4SDavid E. O'Brien test -d "$prefix" || exit 1 418974b70c4SDavid E. O'Brien else 419974b70c4SDavid E. O'Brien case $prefix in 420974b70c4SDavid E. O'Brien *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 421974b70c4SDavid E. O'Brien *) qprefix=$prefix;; 422974b70c4SDavid E. O'Brien esac 423974b70c4SDavid E. O'Brien prefixes="$prefixes '$qprefix'" 42475a6cdb3SDavid E. O'Brien fi 425974b70c4SDavid E. O'Brien fi 426974b70c4SDavid E. O'Brien prefix=$prefix/ 42775a6cdb3SDavid E. O'Brien done 428974b70c4SDavid E. O'Brien 429974b70c4SDavid E. O'Brien if test -n "$prefixes"; then 430974b70c4SDavid E. O'Brien # Don't fail if two instances are running concurrently. 431974b70c4SDavid E. O'Brien (umask $mkdir_umask && 432974b70c4SDavid E. O'Brien eval "\$doit_exec \$mkdirprog $prefixes") || 433974b70c4SDavid E. O'Brien test -d "$dstdir" || exit 1 434974b70c4SDavid E. O'Brien obsolete_mkdir_used=true 435974b70c4SDavid E. O'Brien fi 436974b70c4SDavid E. O'Brien fi 43775a6cdb3SDavid E. O'Brien fi 43875a6cdb3SDavid E. O'Brien 439d1d50c78SDavid E. O'Brien if test -n "$dir_arg"; then 440974b70c4SDavid E. O'Brien { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 441974b70c4SDavid E. O'Brien { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 442974b70c4SDavid E. O'Brien { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 443974b70c4SDavid E. O'Brien test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 44475a6cdb3SDavid E. O'Brien else 44575a6cdb3SDavid E. O'Brien 446d1d50c78SDavid E. O'Brien # Make a couple of temp file names in the proper directory. 447d1d50c78SDavid E. O'Brien dsttmp=$dstdir/_inst.$$_ 448d1d50c78SDavid E. O'Brien rmtmp=$dstdir/_rm.$$_ 44975a6cdb3SDavid E. O'Brien 450d1d50c78SDavid E. O'Brien # Trap to clean up those temp files at exit. 451d1d50c78SDavid E. O'Brien trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 45275a6cdb3SDavid E. O'Brien 453d1d50c78SDavid E. O'Brien # Copy the file name to the temp name. 454974b70c4SDavid E. O'Brien (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 45575a6cdb3SDavid E. O'Brien 456d1d50c78SDavid E. O'Brien # and set any options; do chmod last to preserve setuid bits. 457d1d50c78SDavid E. O'Brien # 458d1d50c78SDavid E. O'Brien # If any of these fail, we abort the whole thing. If we want to 459d1d50c78SDavid E. O'Brien # ignore errors from any of these, just make sure not to ignore 460d1d50c78SDavid E. O'Brien # errors from the above "$doit $cpprog $src $dsttmp" command. 461d1d50c78SDavid E. O'Brien # 462d1d50c78SDavid E. O'Brien { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 463d1d50c78SDavid E. O'Brien && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 464d1d50c78SDavid E. O'Brien && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 465974b70c4SDavid E. O'Brien && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 466d1d50c78SDavid E. O'Brien 467d1d50c78SDavid E. O'Brien # Now rename the file to the real destination. 468974b70c4SDavid E. O'Brien { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ 469d1d50c78SDavid E. O'Brien || { 470d1d50c78SDavid E. O'Brien # The rename failed, perhaps because mv can't rename something else 471d1d50c78SDavid E. O'Brien # to itself, or perhaps because mv is so ancient that it does not 472d1d50c78SDavid E. O'Brien # support -f. 473d1d50c78SDavid E. O'Brien 474d1d50c78SDavid E. O'Brien # Now remove or move aside any old file at destination location. 475d1d50c78SDavid E. O'Brien # We try this two ways since rm can't unlink itself on some 476d1d50c78SDavid E. O'Brien # systems and the destination file might be busy for other 477d1d50c78SDavid E. O'Brien # reasons. In this case, the final cleanup might fail but the new 478d1d50c78SDavid E. O'Brien # file should still install successfully. 479d1d50c78SDavid E. O'Brien { 480974b70c4SDavid E. O'Brien if test -f "$dst"; then 481974b70c4SDavid E. O'Brien $doit $rmcmd -f "$dst" 2>/dev/null \ 482974b70c4SDavid E. O'Brien || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ 483974b70c4SDavid E. O'Brien && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ 484d1d50c78SDavid E. O'Brien || { 485974b70c4SDavid E. O'Brien echo "$0: cannot unlink or rename $dst" >&2 486d1d50c78SDavid E. O'Brien (exit 1); exit 1 487d1d50c78SDavid E. O'Brien } 48875a6cdb3SDavid E. O'Brien else 489a2e8fb4cSDavid E. O'Brien : 49075a6cdb3SDavid E. O'Brien fi 491d1d50c78SDavid E. O'Brien } && 49275a6cdb3SDavid E. O'Brien 49375a6cdb3SDavid E. O'Brien # Now rename the file to the real destination. 494974b70c4SDavid E. O'Brien $doit $mvcmd "$dsttmp" "$dst" 495d1d50c78SDavid E. O'Brien } 496974b70c4SDavid E. O'Brien } || exit 1 49775a6cdb3SDavid E. O'Brien 498974b70c4SDavid E. O'Brien trap '' 0 499974b70c4SDavid E. O'Brien fi 500974b70c4SDavid E. O'Briendone 50175a6cdb3SDavid E. O'Brien 502d1d50c78SDavid E. O'Brien# Local variables: 503d1d50c78SDavid E. O'Brien# eval: (add-hook 'write-file-hooks 'time-stamp) 504d1d50c78SDavid E. O'Brien# time-stamp-start: "scriptversion=" 505d1d50c78SDavid E. O'Brien# time-stamp-format: "%:y-%02m-%02d.%02H" 506d1d50c78SDavid E. O'Brien# time-stamp-end: "$" 507d1d50c78SDavid E. O'Brien# End: 508