ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/Search/trunk/install-sh
Revision: 387
Committed: 2011-12-30T16:21:06-08:00 (10 years, 11 months ago) by douglas
File size: 13663 byte(s)
Log Message:
Fixes for clang.


File Contents

# User Rev Content
1 Douglas Thrift 361 #!/bin/sh
2     # install - install a program, script, or datafile
3    
4 douglas 387 scriptversion=2009-04-28.21; # UTC
5 Douglas Thrift 361
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.
9     #
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.
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
42 douglas 387 # from scratch.
43 Douglas Thrift 361
44 douglas 387 nl='
45     '
46     IFS=" "" $nl"
47    
48 Douglas Thrift 361 # set DOITPROG to echo to test this script
49    
50     # Don't use :- since 4.3BSD and earlier shells don't like it.
51 douglas 387 doit=${DOITPROG-}
52     if test -z "$doit"; then
53     doit_exec=exec
54     else
55     doit_exec=$doit
56     fi
57 Douglas Thrift 361
58 douglas 387 # Put in absolute file names if you don't have them in your path;
59     # or use environment vars.
60 Douglas Thrift 361
61 douglas 387 chgrpprog=${CHGRPPROG-chgrp}
62     chmodprog=${CHMODPROG-chmod}
63     chownprog=${CHOWNPROG-chown}
64     cmpprog=${CMPPROG-cmp}
65     cpprog=${CPPROG-cp}
66     mkdirprog=${MKDIRPROG-mkdir}
67     mvprog=${MVPROG-mv}
68     rmprog=${RMPROG-rm}
69     stripprog=${STRIPPROG-strip}
70 Douglas Thrift 361
71 douglas 387 posix_glob='?'
72     initialize_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     '
81    
82     posix_mkdir=
83    
84     # Desired mode of installed file.
85     mode=0755
86    
87     chgrpcmd=
88     chmodcmd=$chmodprog
89 Douglas Thrift 361 chowncmd=
90 douglas 387 mvcmd=$mvprog
91     rmcmd="$rmprog -f"
92 Douglas Thrift 361 stripcmd=
93 douglas 387
94 Douglas Thrift 361 src=
95     dst=
96     dir_arg=
97 douglas 387 dst_arg=
98 Douglas Thrift 361
99 douglas 387 copy_on_change=false
100     no_target_directory=
101    
102     usage="\
103     Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
104 Douglas Thrift 361 or: $0 [OPTION]... SRCFILES... DIRECTORY
105 douglas 387 or: $0 [OPTION]... -t DIRECTORY SRCFILES...
106     or: $0 [OPTION]... -d DIRECTORIES...
107 Douglas Thrift 361
108 douglas 387 In the 1st form, copy SRCFILE to DSTFILE.
109     In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
110     In the 4th, create DIRECTORIES.
111 Douglas Thrift 361
112     Options:
113 douglas 387 --help display this help and exit.
114     --version display version info and exit.
115 Douglas Thrift 361
116 douglas 387 -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.
125    
126 Douglas Thrift 361 Environment variables override the default commands:
127 douglas 387 CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
128     RMPROG STRIPPROG
129 Douglas Thrift 361 "
130    
131 douglas 387 while test $# -ne 0; do
132 Douglas Thrift 361 case $1 in
133 douglas 387 -c) ;;
134 Douglas Thrift 361
135 douglas 387 -C) copy_on_change=true;;
136 Douglas Thrift 361
137 douglas 387 -d) dir_arg=true;;
138 Douglas Thrift 361
139     -g) chgrpcmd="$chgrpprog $2"
140 douglas 387 shift;;
141 Douglas Thrift 361
142 douglas 387 --help) echo "$usage"; exit $?;;
143 Douglas Thrift 361
144 douglas 387 -m) mode=$2
145     case $mode in
146     *' '* | *' '* | *'
147     '* | *'*'* | *'?'* | *'['*)
148     echo "$0: invalid mode: $mode" >&2
149     exit 1;;
150     esac
151     shift;;
152 Douglas Thrift 361
153     -o) chowncmd="$chownprog $2"
154 douglas 387 shift;;
155 Douglas Thrift 361
156 douglas 387 -s) stripcmd=$stripprog;;
157 Douglas Thrift 361
158 douglas 387 -t) dst_arg=$2
159     shift;;
160 Douglas Thrift 361
161 douglas 387 -T) no_target_directory=true;;
162 Douglas Thrift 361
163 douglas 387 --version) echo "$0 $scriptversion"; exit $?;;
164    
165     --) shift
166 Douglas Thrift 361 break;;
167 douglas 387
168     -*) echo "$0: invalid option: $1" >&2
169     exit 1;;
170    
171     *) break;;
172 Douglas Thrift 361 esac
173 douglas 387 shift
174 Douglas Thrift 361 done
175    
176 douglas 387 if 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
190     fi
191    
192     if test $# -eq 0; then
193 Douglas Thrift 361 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
200     fi
201    
202 douglas 387 if 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
227     fi
228    
229 Douglas Thrift 361 for src
230     do
231     # Protect names starting with `-'.
232     case $src in
233 douglas 387 -*) src=./$src;;
234 Douglas Thrift 361 esac
235    
236     if test -n "$dir_arg"; then
237     dst=$src
238 douglas 387 dstdir=$dst
239     test -d "$dstdir"
240     dstdir_status=$?
241     else
242 Douglas Thrift 361
243 douglas 387 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
244 Douglas Thrift 361 # 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    
251 douglas 387 if test -z "$dst_arg"; then
252 Douglas Thrift 361 echo "$0: no destination specified." >&2
253     exit 1
254     fi
255    
256 douglas 387 dst=$dst_arg
257 Douglas Thrift 361 # Protect names starting with `-'.
258     case $dst in
259 douglas 387 -*) dst=./$dst;;
260 Douglas Thrift 361 esac
261    
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
265 douglas 387 if test -n "$no_target_directory"; then
266     echo "$0: $dst_arg: Is a directory" >&2
267     exit 1
268     fi
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=$?
302 Douglas Thrift 361 fi
303     fi
304    
305 douglas 387 obsolete_mkdir_used=false
306 Douglas Thrift 361
307 douglas 387 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 Douglas Thrift 361
318 douglas 387 *[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 Douglas Thrift 361
326 douglas 387 # 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 Douglas Thrift 361
334 douglas 387 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 Douglas Thrift 361
344 douglas 387 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
373    
374     if
375     $posix_mkdir && (
376     umask $mkdir_umask &&
377     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
378     )
379     then :
380     else
381    
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.
385    
386     case $dstdir in
387     /*) prefix='/';;
388     -*) prefix='./';;
389     *) prefix='';;
390     esac
391    
392     eval "$initialize_posix_glob"
393    
394     oIFS=$IFS
395     IFS=/
396     $posix_glob set -f
397     set fnord $dstdir
398 Douglas Thrift 361 shift
399 douglas 387 $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
434 Douglas Thrift 361 fi
435 douglas 387 fi
436 Douglas Thrift 361 fi
437    
438     if test -n "$dir_arg"; then
439 douglas 387 { 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
443 Douglas Thrift 361 else
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.
450 douglas 387 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
451 Douglas Thrift 361
452 douglas 387 # Copy the file name to the temp name.
453     (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
454 Douglas Thrift 361
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
459 douglas 387 # errors from the above "$doit $cpprog $src $dsttmp" command.
460 Douglas Thrift 361 #
461 douglas 387 { 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 Douglas Thrift 361
466 douglas 387 # 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 Douglas Thrift 361
471 douglas 387 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 Douglas Thrift 361
477 douglas 387 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
512 Douglas Thrift 361 done
513    
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"
518 douglas 387 # time-stamp-time-zone: "UTC"
519     # time-stamp-end: "; # UTC"
520 Douglas Thrift 361 # End:

Properties

Name Value
svn:executable *