Skip to content

Latest commit

 

History

History
executable file
·
509 lines (440 loc) · 14.5 KB

install-sh

File metadata and controls

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