install-sh | install-sh | |||
---|---|---|---|---|
#!/bin/sh | #!/bin/sh | |||
# install - install a program, script, or datafile | # install - install a program, script, or datafile | |||
scriptversion=2020-11-14.01; # UTC | scriptversion=2014-09-12.12; # UTC | |||
# This originates from X11R5 (mit/util/scripts/install.sh), which was | # This originates from X11R5 (mit/util/scripts/install.sh), which was | |||
# later released in X11R6 (xc/config/util/install.sh) with the | # later released in X11R6 (xc/config/util/install.sh) with the | |||
# following copyright and license. | # following copyright and license. | |||
# | # | |||
# Copyright (C) 1994 X Consortium | # Copyright (C) 1994 X Consortium | |||
# | # | |||
# Permission is hereby granted, free of charge, to any person obtaining a c opy | # Permission is hereby granted, free of charge, to any person obtaining a c opy | |||
# of this software and associated documentation files (the "Software"), to | # of this software and associated documentation files (the "Software"), to | |||
# deal in the Software without restriction, including without limitation th e | # deal in the Software without restriction, including without limitation th e | |||
skipping to change at line 72 | skipping to change at line 72 | |||
mkdirprog=${MKDIRPROG-mkdir} | mkdirprog=${MKDIRPROG-mkdir} | |||
mvprog=${MVPROG-mv} | mvprog=${MVPROG-mv} | |||
rmprog=${RMPROG-rm} | rmprog=${RMPROG-rm} | |||
stripprog=${STRIPPROG-strip} | stripprog=${STRIPPROG-strip} | |||
posix_mkdir= | posix_mkdir= | |||
# Desired mode of installed file. | # Desired mode of installed file. | |||
mode=0755 | mode=0755 | |||
# Create dirs (including intermediate dirs) using mode 755. | ||||
# This is like GNU 'install' as of coreutils 8.32 (2020). | ||||
mkdir_umask=22 | ||||
backupsuffix= | ||||
chgrpcmd= | chgrpcmd= | |||
chmodcmd=$chmodprog | chmodcmd=$chmodprog | |||
chowncmd= | chowncmd= | |||
mvcmd=$mvprog | mvcmd=$mvprog | |||
rmcmd="$rmprog -f" | rmcmd="$rmprog -f" | |||
stripcmd= | stripcmd= | |||
src= | src= | |||
dst= | dst= | |||
dir_arg= | dir_arg= | |||
skipping to change at line 107 | skipping to change at line 102 | |||
In the 1st form, copy SRCFILE to DSTFILE. | In the 1st form, copy SRCFILE to DSTFILE. | |||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. | |||
In the 4th, create DIRECTORIES. | In the 4th, create DIRECTORIES. | |||
Options: | Options: | |||
--help display this help and exit. | --help display this help and exit. | |||
--version display version info and exit. | --version display version info and exit. | |||
-c (ignored) | -c (ignored) | |||
-C install only if different (preserve data modification time) | -C install only if different (preserve the last data modificat ion time) | |||
-d create directories instead of installing files. | -d create directories instead of installing files. | |||
-g GROUP $chgrpprog installed files to GROUP. | -g GROUP $chgrpprog installed files to GROUP. | |||
-m MODE $chmodprog installed files to MODE. | -m MODE $chmodprog installed files to MODE. | |||
-o USER $chownprog installed files to USER. | -o USER $chownprog installed files to USER. | |||
-p pass -p to $cpprog. | ||||
-s $stripprog installed files. | -s $stripprog installed files. | |||
-S SUFFIX attempt to back up existing files, with suffix SUFFIX. | ||||
-t DIRECTORY install into DIRECTORY. | -t DIRECTORY install into DIRECTORY. | |||
-T report an error if DSTFILE is a directory. | -T report an error if DSTFILE is a directory. | |||
Environment variables override the default commands: | Environment variables override the default commands: | |||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG | CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG | |||
RMPROG STRIPPROG | RMPROG STRIPPROG | |||
By default, rm is invoked with -f; when overridden with RMPROG, | ||||
it's up to you to specify -f if you want it. | ||||
If -S is not specified, no backups are attempted. | ||||
Email bug reports to bug-automake@gnu.org. | ||||
Automake home page: https://www.gnu.org/software/automake/ | ||||
" | " | |||
while test $# -ne 0; do | while test $# -ne 0; do | |||
case $1 in | case $1 in | |||
-c) ;; | -c) ;; | |||
-C) copy_on_change=true;; | -C) copy_on_change=true;; | |||
-d) dir_arg=true;; | -d) dir_arg=true;; | |||
skipping to change at line 155 | skipping to change at line 140 | |||
case $mode in | case $mode in | |||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) | *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) | |||
echo "$0: invalid mode: $mode" >&2 | echo "$0: invalid mode: $mode" >&2 | |||
exit 1;; | exit 1;; | |||
esac | esac | |||
shift;; | shift;; | |||
-o) chowncmd="$chownprog $2" | -o) chowncmd="$chownprog $2" | |||
shift;; | shift;; | |||
-p) cpprog="$cpprog -p";; | ||||
-s) stripcmd=$stripprog;; | -s) stripcmd=$stripprog;; | |||
-S) backupsuffix="$2" | ||||
shift;; | ||||
-t) | -t) | |||
is_target_a_directory=always | is_target_a_directory=always | |||
dst_arg=$2 | dst_arg=$2 | |||
# Protect names problematic for 'test' and other utilities. | # Protect names problematic for 'test' and other utilities. | |||
case $dst_arg in | case $dst_arg in | |||
-* | [=\(\)!]) dst_arg=./$dst_arg;; | -* | [=\(\)!]) dst_arg=./$dst_arg;; | |||
esac | esac | |||
shift;; | shift;; | |||
-T) is_target_a_directory=never;; | -T) is_target_a_directory=never;; | |||
skipping to change at line 278 | skipping to change at line 258 | |||
# Protect names problematic for 'test' and other utilities. | # Protect names problematic for 'test' and other utilities. | |||
case $src in | case $src in | |||
-* | [=\(\)!]) src=./$src;; | -* | [=\(\)!]) src=./$src;; | |||
esac | esac | |||
if test -n "$dir_arg"; then | if test -n "$dir_arg"; then | |||
dst=$src | dst=$src | |||
dstdir=$dst | dstdir=$dst | |||
test -d "$dstdir" | test -d "$dstdir" | |||
dstdir_status=$? | dstdir_status=$? | |||
# Don't chown directories that already exist. | ||||
if test $dstdir_status = 0; then | ||||
chowncmd="" | ||||
fi | ||||
else | else | |||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command | |||
# might cause directories to be created, which would be especially bad | # might cause directories to be created, which would be especially bad | |||
# if $src (and thus $dsttmp) contains '*'. | # if $src (and thus $dsttmp) contains '*'. | |||
if test ! -f "$src" && test ! -d "$src"; then | if test ! -f "$src" && test ! -d "$src"; then | |||
echo "$0: $src does not exist." >&2 | echo "$0: $src does not exist." >&2 | |||
exit 1 | exit 1 | |||
fi | fi | |||
if test -z "$dst_arg"; then | if test -z "$dst_arg"; then | |||
echo "$0: no destination specified." >&2 | echo "$0: no destination specified." >&2 | |||
exit 1 | exit 1 | |||
fi | fi | |||
dst=$dst_arg | dst=$dst_arg | |||
# If destination is a directory, append the input filename. | # If destination is a directory, append the input filename; won't work | |||
# if double slashes aren't ignored. | ||||
if test -d "$dst"; then | if test -d "$dst"; then | |||
if test "$is_target_a_directory" = never; then | if test "$is_target_a_directory" = never; then | |||
echo "$0: $dst_arg: Is a directory" >&2 | echo "$0: $dst_arg: Is a directory" >&2 | |||
exit 1 | exit 1 | |||
fi | fi | |||
dstdir=$dst | dstdir=$dst | |||
dstbase=`basename "$src"` | dst=$dstdir/`basename "$src"` | |||
case $dst in | ||||
*/) dst=$dst$dstbase;; | ||||
*) dst=$dst/$dstbase;; | ||||
esac | ||||
dstdir_status=0 | dstdir_status=0 | |||
else | else | |||
dstdir=`dirname "$dst"` | dstdir=`dirname "$dst"` | |||
test -d "$dstdir" | test -d "$dstdir" | |||
dstdir_status=$? | dstdir_status=$? | |||
fi | fi | |||
fi | fi | |||
case $dstdir in | ||||
*/) dstdirslash=$dstdir;; | ||||
*) dstdirslash=$dstdir/;; | ||||
esac | ||||
obsolete_mkdir_used=false | obsolete_mkdir_used=false | |||
if test $dstdir_status != 0; then | if test $dstdir_status != 0; then | |||
case $posix_mkdir in | case $posix_mkdir in | |||
'') | '') | |||
# Create intermediate dirs using mode 755 as modified by the umask. | ||||
# This is like FreeBSD 'install' as of 1997-10-28. | ||||
umask=`umask` | ||||
case $stripcmd.$umask in | ||||
# Optimize common cases. | ||||
*[2367][2367]) mkdir_umask=$umask;; | ||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; | ||||
*[0-7]) | ||||
mkdir_umask=`expr $umask + 22 \ | ||||
- $umask % 100 % 40 + $umask % 20 \ | ||||
- $umask % 10 % 4 + $umask % 2 | ||||
`;; | ||||
*) mkdir_umask=$umask,go-w;; | ||||
esac | ||||
# With -d, create the new directory with the user-specified mode. | # With -d, create the new directory with the user-specified mode. | |||
# Otherwise, rely on $mkdir_umask. | # Otherwise, rely on $mkdir_umask. | |||
if test -n "$dir_arg"; then | if test -n "$dir_arg"; then | |||
mkdir_mode=-m$mode | mkdir_mode=-m$mode | |||
else | else | |||
mkdir_mode= | mkdir_mode= | |||
fi | fi | |||
posix_mkdir=false | posix_mkdir=false | |||
# The $RANDOM variable is not portable (e.g., dash). Use it | case $umask in | |||
# here however when possible just to lower collision chance. | *[123567][0-7][0-7]) | |||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ | # POSIX mkdir -p sets u+wx bits regardless of umask, which | |||
# is incompatible with FreeBSD 'install' when (umask & 300) != | ||||
trap ' | 0. | |||
ret=$? | ;; | |||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null | *) | |||
exit $ret | # $RANDOM is not portable (e.g. dash); use it when possible to | |||
' 0 | # lower collision chance | |||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ | ||||
# Because "mkdir -p" follows existing symlinks and we likely work | trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/ | |||
# directly in world-writeable /tmp, make sure that the '$tmpdir' | null; exit $ret' 0 | |||
# directory is successfully created first before we actually test | ||||
# 'mkdir -p'. | # As "mkdir -p" follows symlinks and we work in /tmp possibly; | |||
if (umask $mkdir_umask && | so | |||
$mkdirprog $mkdir_mode "$tmpdir" && | # create the $tmpdir first (and fail if unsuccessful) to make s | |||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 | ure | |||
then | # that nobody tries to guess the $tmpdir name. | |||
if test -z "$dir_arg" || { | if (umask $mkdir_umask && | |||
# Check for POSIX incompatibilities with -m. | $mkdirprog $mkdir_mode "$tmpdir" && | |||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or | exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null | |||
# other-writable bit of parent directory when it shouldn't. | 2>&1 | |||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory. | then | |||
test_tmpdir="$tmpdir/a" | if test -z "$dir_arg" || { | |||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"` | # Check for POSIX incompatibilities with -m. | |||
case $ls_ld_tmpdir in | # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or | |||
d????-?r-*) different_mode=700;; | # other-writable bit of parent directory when it shouldn | |||
d????-?--*) different_mode=755;; | 't. | |||
*) false;; | # FreeBSD 6.1 mkdir -m -p sets mode of existing director | |||
esac && | y. | |||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && { | test_tmpdir="$tmpdir/a" | |||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` | ls_ld_tmpdir=`ls -ld "$test_tmpdir"` | |||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" | case $ls_ld_tmpdir in | |||
} | d????-?r-*) different_mode=700;; | |||
} | d????-?--*) different_mode=755;; | |||
then posix_mkdir=: | *) false;; | |||
fi | esac && | |||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" | $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { | |||
else | ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` | |||
# Remove any dirs left behind by ancient mkdir implementations. | test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" | |||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null | } | |||
fi | } | |||
trap '' 0;; | then posix_mkdir=: | |||
fi | ||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" | ||||
else | ||||
# Remove any dirs left behind by ancient mkdir implementation | ||||
s. | ||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null | ||||
fi | ||||
trap '' 0;; | ||||
esac;; | ||||
esac | esac | |||
if | if | |||
$posix_mkdir && ( | $posix_mkdir && ( | |||
umask $mkdir_umask && | umask $mkdir_umask && | |||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" | |||
) | ) | |||
then : | then : | |||
else | else | |||
# mkdir does not conform to POSIX, | # The umask is ridiculous, or mkdir does not conform to POSIX, | |||
# or it failed possibly due to a race condition. Create the | # or it failed possibly due to a race condition. Create the | |||
# directory the slow way, step by step, checking for races as we go. | # directory the slow way, step by step, checking for races as we go. | |||
case $dstdir in | case $dstdir in | |||
/*) prefix='/';; | /*) prefix='/';; | |||
[-=\(\)!]*) prefix='./';; | [-=\(\)!]*) prefix='./';; | |||
*) prefix='';; | *) prefix='';; | |||
esac | esac | |||
oIFS=$IFS | oIFS=$IFS | |||
skipping to change at line 419 | skipping to change at line 404 | |||
for d | for d | |||
do | do | |||
test X"$d" = X && continue | test X"$d" = X && continue | |||
prefix=$prefix$d | prefix=$prefix$d | |||
if test -d "$prefix"; then | if test -d "$prefix"; then | |||
prefixes= | prefixes= | |||
else | else | |||
if $posix_mkdir; then | if $posix_mkdir; then | |||
(umask $mkdir_umask && | (umask=$mkdir_umask && | |||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break | |||
# Don't fail if two instances are running concurrently. | # Don't fail if two instances are running concurrently. | |||
test -d "$prefix" || exit 1 | test -d "$prefix" || exit 1 | |||
else | else | |||
case $prefix in | case $prefix in | |||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; | *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; | |||
*) qprefix=$prefix;; | *) qprefix=$prefix;; | |||
esac | esac | |||
prefixes="$prefixes '$qprefix'" | prefixes="$prefixes '$qprefix'" | |||
fi | fi | |||
skipping to change at line 452 | skipping to change at line 437 | |||
fi | fi | |||
if test -n "$dir_arg"; then | if test -n "$dir_arg"; then | |||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } && | { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && | |||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && | |||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || | { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || | |||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 | test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 | |||
else | else | |||
# Make a couple of temp file names in the proper directory. | # Make a couple of temp file names in the proper directory. | |||
dsttmp=${dstdirslash}_inst.$$_ | dsttmp=$dstdir/_inst.$$_ | |||
rmtmp=${dstdirslash}_rm.$$_ | rmtmp=$dstdir/_rm.$$_ | |||
# Trap to clean up those temp files at exit. | # Trap to clean up those temp files at exit. | |||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 | |||
# Copy the file name to the temp name. | # Copy the file name to the temp name. | |||
(umask $cp_umask && | (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && | |||
{ test -z "$stripcmd" || { | ||||
# Create $dsttmp read-write so that cp doesn't create it read-only, | ||||
# which would cause strip to fail. | ||||
if test -z "$doit"; then | ||||
: >"$dsttmp" # No need to fork-exec 'touch'. | ||||
else | ||||
$doit touch "$dsttmp" | ||||
fi | ||||
} | ||||
} && | ||||
$doit_exec $cpprog "$src" "$dsttmp") && | ||||
# and set any options; do chmod last to preserve setuid bits. | # and set any options; do chmod last to preserve setuid bits. | |||
# | # | |||
# If any of these fail, we abort the whole thing. If we want to | # If any of these fail, we abort the whole thing. If we want to | |||
# ignore errors from any of these, just make sure not to ignore | # ignore errors from any of these, just make sure not to ignore | |||
# errors from the above "$doit $cpprog $src $dsttmp" command. | # errors from the above "$doit $cpprog $src $dsttmp" command. | |||
# | # | |||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && | |||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && | |||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && | { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && | |||
skipping to change at line 496 | skipping to change at line 470 | |||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && | new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && | |||
set -f && | set -f && | |||
set X $old && old=:$2:$4:$5:$6 && | set X $old && old=:$2:$4:$5:$6 && | |||
set X $new && new=:$2:$4:$5:$6 && | set X $new && new=:$2:$4:$5:$6 && | |||
set +f && | set +f && | |||
test "$old" = "$new" && | test "$old" = "$new" && | |||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 | $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 | |||
then | then | |||
rm -f "$dsttmp" | rm -f "$dsttmp" | |||
else | else | |||
# If $backupsuffix is set, and the file being installed | ||||
# already exists, attempt a backup. Don't worry if it fails, | ||||
# e.g., if mv doesn't support -f. | ||||
if test -n "$backupsuffix" && test -f "$dst"; then | ||||
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null | ||||
fi | ||||
# Rename the file to the real destination. | # Rename the file to the real destination. | |||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || | $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || | |||
# The rename failed, perhaps because mv can't rename something else | # The rename failed, perhaps because mv can't rename something else | |||
# to itself, or perhaps because mv is so ancient that it does not | # to itself, or perhaps because mv is so ancient that it does not | |||
# support -f. | # support -f. | |||
{ | { | |||
# Now remove or move aside any old file at destination location. | # Now remove or move aside any old file at destination location. | |||
# We try this two ways since rm can't unlink itself on some | # We try this two ways since rm can't unlink itself on some | |||
# systems and the destination file might be busy for other | # systems and the destination file might be busy for other | |||
# reasons. In this case, the final cleanup might fail but the new | # reasons. In this case, the final cleanup might fail but the new | |||
# file should still install successfully. | # file should still install successfully. | |||
{ | { | |||
test ! -f "$dst" || | test ! -f "$dst" || | |||
$doit $rmcmd "$dst" 2>/dev/null || | $doit $rmcmd -f "$dst" 2>/dev/null || | |||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && | { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && | |||
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; } | { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } | |||
} || | } || | |||
{ echo "$0: cannot unlink or rename $dst" >&2 | { echo "$0: cannot unlink or rename $dst" >&2 | |||
(exit 1); exit 1 | (exit 1); exit 1 | |||
} | } | |||
} && | } && | |||
# Now rename the file to the real destination. | # Now rename the file to the real destination. | |||
$doit $mvcmd "$dsttmp" "$dst" | $doit $mvcmd "$dsttmp" "$dst" | |||
} | } | |||
fi || exit 1 | fi || exit 1 | |||
trap '' 0 | trap '' 0 | |||
fi | fi | |||
done | done | |||
# Local variables: | # Local variables: | |||
# eval: (add-hook 'before-save-hook 'time-stamp) | # eval: (add-hook 'write-file-hooks 'time-stamp) | |||
# time-stamp-start: "scriptversion=" | # time-stamp-start: "scriptversion=" | |||
# time-stamp-format: "%:y-%02m-%02d.%02H" | # time-stamp-format: "%:y-%02m-%02d.%02H" | |||
# time-stamp-time-zone: "UTC0" | # time-stamp-time-zone: "UTC" | |||
# time-stamp-end: "; # UTC" | # time-stamp-end: "; # UTC" | |||
# End: | # End: | |||
End of changes. 23 change blocks. | ||||
107 lines changed or deleted | 82 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |