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