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