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