ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/install-sh
(Generate patch)

Comparing rxvt-unicode/install-sh (file contents):
Revision 1.1 by ayin, Tue Jan 17 12:20:34 2006 UTC vs.
Revision 1.2 by ayin, Tue Jun 26 09:14:11 2007 UTC

1#!/bin/sh 1#!/bin/sh
2# install - install a program, script, or datafile 2# install - install a program, script, or datafile
3 3
4scriptversion=2005-05-14.22 4scriptversion=2006-10-14.15
5 5
6# This originates from X11R5 (mit/util/scripts/install.sh), which was 6# This originates from X11R5 (mit/util/scripts/install.sh), which was
7# later released in X11R6 (xc/config/util/install.sh) with the 7# later released in X11R6 (xc/config/util/install.sh) with the
8# following copyright and license. 8# following copyright and license.
9# 9#
37# Calling this script install-sh is preferred over install.sh, to prevent 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 38# `make' implicit rules from creating a file called install from it
39# when there is no Makefile. 39# when there is no Makefile.
40# 40#
41# This script is compatible with the BSD install script, but was written 41# This script is compatible with the BSD install script, but was written
42# from scratch. It can only install one file at a time, a restriction 42# from scratch.
43# shared with many OS's install programs. 43
44nl='
45'
46IFS=" "" $nl"
44 47
45# set DOITPROG to echo to test this script 48# set DOITPROG to echo to test this script
46 49
47# Don't use :- since 4.3BSD and earlier shells don't like it. 50# Don't use :- since 4.3BSD and earlier shells don't like it.
48doit="${DOITPROG-}" 51doit="${DOITPROG-}"
52if test -z "$doit"; then
53 doit_exec=exec
54else
55 doit_exec=$doit
56fi
49 57
50# put in absolute paths if you don't have them in your path; or use env. vars. 58# Put in absolute file names if you don't have them in your path;
59# or use environment vars.
51 60
52mvprog="${MVPROG-mv}" 61mvprog="${MVPROG-mv}"
53cpprog="${CPPROG-cp}" 62cpprog="${CPPROG-cp}"
54chmodprog="${CHMODPROG-chmod}" 63chmodprog="${CHMODPROG-chmod}"
55chownprog="${CHOWNPROG-chown}" 64chownprog="${CHOWNPROG-chown}"
56chgrpprog="${CHGRPPROG-chgrp}" 65chgrpprog="${CHGRPPROG-chgrp}"
57stripprog="${STRIPPROG-strip}" 66stripprog="${STRIPPROG-strip}"
58rmprog="${RMPROG-rm}" 67rmprog="${RMPROG-rm}"
59mkdirprog="${MKDIRPROG-mkdir}" 68mkdirprog="${MKDIRPROG-mkdir}"
60 69
70posix_glob=
71posix_mkdir=
72
73# Desired mode of installed file.
74mode=0755
75
61chmodcmd="$chmodprog 0755" 76chmodcmd=$chmodprog
62chowncmd= 77chowncmd=
63chgrpcmd= 78chgrpcmd=
64stripcmd= 79stripcmd=
65rmcmd="$rmprog -f" 80rmcmd="$rmprog -f"
66mvcmd="$mvprog" 81mvcmd="$mvprog"
93 108
94Environment variables override the default commands: 109Environment variables override the default commands:
95 CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 110 CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
96" 111"
97 112
98while test -n "$1"; do 113while test $# -ne 0; do
99 case $1 in 114 case $1 in
100 -c) shift 115 -c) shift
101 continue;; 116 continue;;
102 117
103 -d) dir_arg=true 118 -d) dir_arg=true
109 shift 124 shift
110 continue;; 125 continue;;
111 126
112 --help) echo "$usage"; exit $?;; 127 --help) echo "$usage"; exit $?;;
113 128
114 -m) chmodcmd="$chmodprog $2" 129 -m) mode=$2
115 shift 130 shift
116 shift 131 shift
132 case $mode in
133 *' '* | *' '* | *'
134'* | *'*'* | *'?'* | *'['*)
135 echo "$0: invalid mode: $mode" >&2
136 exit 1;;
137 esac
117 continue;; 138 continue;;
118 139
119 -o) chowncmd="$chownprog $2" 140 -o) chowncmd="$chownprog $2"
120 shift 141 shift
121 shift 142 shift
134 shift 155 shift
135 continue;; 156 continue;;
136 157
137 --version) echo "$0 $scriptversion"; exit $?;; 158 --version) echo "$0 $scriptversion"; exit $?;;
138 159
139 *) # When -d is used, all remaining arguments are directories to create. 160 --) shift
140 # When -t is used, the destination is already specified.
141 test -n "$dir_arg$dstarg" && break
142 # Otherwise, the last argument is the destination. Remove it from $@.
143 for arg
144 do
145 if test -n "$dstarg"; then
146 # $@ is not empty: it contains at least $arg.
147 set fnord "$@" "$dstarg"
148 shift # fnord
149 fi
150 shift # arg
151 dstarg=$arg
152 done
153 break;; 161 break;;
162
163 -*) echo "$0: invalid option: $1" >&2
164 exit 1;;
165
166 *) break;;
154 esac 167 esac
155done 168done
156 169
157if test -z "$1"; then 170if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
171 # When -d is used, all remaining arguments are directories to create.
172 # When -t is used, the destination is already specified.
173 # Otherwise, the last argument is the destination. Remove it from $@.
174 for arg
175 do
176 if test -n "$dstarg"; then
177 # $@ is not empty: it contains at least $arg.
178 set fnord "$@" "$dstarg"
179 shift # fnord
180 fi
181 shift # arg
182 dstarg=$arg
183 done
184fi
185
186if test $# -eq 0; then
158 if test -z "$dir_arg"; then 187 if test -z "$dir_arg"; then
159 echo "$0: no input file specified." >&2 188 echo "$0: no input file specified." >&2
160 exit 1 189 exit 1
161 fi 190 fi
162 # It's OK to call `install-sh -d' without argument. 191 # It's OK to call `install-sh -d' without argument.
163 # This can happen when creating conditional directories. 192 # This can happen when creating conditional directories.
164 exit 0 193 exit 0
165fi 194fi
166 195
196if test -z "$dir_arg"; then
197 trap '(exit $?); exit' 1 2 13 15
198
199 # Set umask so as not to create temps with too-generous modes.
200 # However, 'strip' requires both read and write access to temps.
201 case $mode in
202 # Optimize common cases.
203 *644) cp_umask=133;;
204 *755) cp_umask=22;;
205
206 *[0-7])
207 if test -z "$stripcmd"; then
208 u_plus_rw=
209 else
210 u_plus_rw='% 200'
211 fi
212 cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
213 *)
214 if test -z "$stripcmd"; then
215 u_plus_rw=
216 else
217 u_plus_rw=,u+rw
218 fi
219 cp_umask=$mode$u_plus_rw;;
220 esac
221fi
222
167for src 223for src
168do 224do
169 # Protect names starting with `-'. 225 # Protect names starting with `-'.
170 case $src in 226 case $src in
171 -*) src=./$src ;; 227 -*) src=./$src ;;
172 esac 228 esac
173 229
174 if test -n "$dir_arg"; then 230 if test -n "$dir_arg"; then
175 dst=$src 231 dst=$src
176 src= 232 dstdir=$dst
177
178 if test -d "$dst"; then 233 test -d "$dstdir"
179 mkdircmd=: 234 dstdir_status=$?
180 chmodcmd=
181 else
182 mkdircmd=$mkdirprog
183 fi
184 else 235 else
236
185 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 237 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
186 # might cause directories to be created, which would be especially bad 238 # might cause directories to be created, which would be especially bad
187 # if $src (and thus $dsttmp) contains '*'. 239 # if $src (and thus $dsttmp) contains '*'.
188 if test ! -f "$src" && test ! -d "$src"; then 240 if test ! -f "$src" && test ! -d "$src"; then
189 echo "$0: $src does not exist." >&2 241 echo "$0: $src does not exist." >&2
206 if test -d "$dst"; then 258 if test -d "$dst"; then
207 if test -n "$no_target_directory"; then 259 if test -n "$no_target_directory"; then
208 echo "$0: $dstarg: Is a directory" >&2 260 echo "$0: $dstarg: Is a directory" >&2
209 exit 1 261 exit 1
210 fi 262 fi
263 dstdir=$dst
211 dst=$dst/`basename "$src"` 264 dst=$dstdir/`basename "$src"`
265 dstdir_status=0
266 else
267 # Prefer dirname, but fall back on a substitute if dirname fails.
268 dstdir=`
269 (dirname "$dst") 2>/dev/null ||
270 expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
271 X"$dst" : 'X\(//\)[^/]' \| \
272 X"$dst" : 'X\(//\)$' \| \
273 X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
274 echo X"$dst" |
275 sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
276 s//\1/
277 q
278 }
279 /^X\(\/\/\)[^/].*/{
280 s//\1/
281 q
282 }
283 /^X\(\/\/\)$/{
284 s//\1/
285 q
286 }
287 /^X\(\/\).*/{
288 s//\1/
289 q
290 }
291 s/.*/./; q'
292 `
293
294 test -d "$dstdir"
295 dstdir_status=$?
212 fi 296 fi
213 fi 297 fi
214 298
215 # This sed command emulates the dirname command. 299 obsolete_mkdir_used=false
216 dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
217 300
218 # Make sure that the destination directory exists. 301 if test $dstdir_status != 0; then
302 case $posix_mkdir in
303 '')
304 # Create intermediate dirs using mode 755 as modified by the umask.
305 # This is like FreeBSD 'install' as of 1997-10-28.
306 umask=`umask`
307 case $stripcmd.$umask in
308 # Optimize common cases.
309 *[2367][2367]) mkdir_umask=$umask;;
310 .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
219 311
220 # Skip lots of stat calls in the usual case. 312 *[0-7])
313 mkdir_umask=`expr $umask + 22 \
314 - $umask % 100 % 40 + $umask % 20 \
315 - $umask % 10 % 4 + $umask % 2
316 `;;
317 *) mkdir_umask=$umask,go-w;;
318 esac
319
320 # With -d, create the new directory with the user-specified mode.
321 # Otherwise, rely on $mkdir_umask.
221 if test ! -d "$dstdir"; then 322 if test -n "$dir_arg"; then
222 defaultIFS=' 323 mkdir_mode=-m$mode
223 ' 324 else
224 IFS="${IFS-$defaultIFS}" 325 mkdir_mode=
326 fi
225 327
328 posix_mkdir=false
329 case $umask in
330 *[123567][0-7][0-7])
331 # POSIX mkdir -p sets u+wx bits regardless of umask, which
332 # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
333 ;;
334 *)
335 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
336 trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
337
338 if (umask $mkdir_umask &&
339 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
340 then
341 if test -z "$dir_arg" || {
342 # Check for POSIX incompatibilities with -m.
343 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
344 # other-writeable bit of parent directory when it shouldn't.
345 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
346 ls_ld_tmpdir=`ls -ld "$tmpdir"`
347 case $ls_ld_tmpdir in
348 d????-?r-*) different_mode=700;;
349 d????-?--*) different_mode=755;;
350 *) false;;
351 esac &&
352 $mkdirprog -m$different_mode -p -- "$tmpdir" && {
353 ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
354 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
355 }
356 }
357 then posix_mkdir=:
358 fi
359 rmdir "$tmpdir/d" "$tmpdir"
360 else
361 # Remove any dirs left behind by ancient mkdir implementations.
362 rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
363 fi
364 trap '' 0;;
365 esac;;
366 esac
367
368 if
369 $posix_mkdir && (
370 umask $mkdir_umask &&
371 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
372 )
373 then :
374 else
375
376 # The umask is ridiculous, or mkdir does not conform to POSIX,
377 # or it failed possibly due to a race condition. Create the
378 # directory the slow way, step by step, checking for races as we go.
379
380 case $dstdir in
381 /*) prefix=/ ;;
382 -*) prefix=./ ;;
383 *) prefix= ;;
384 esac
385
386 case $posix_glob in
387 '')
388 if (set -f) 2>/dev/null; then
389 posix_glob=true
390 else
391 posix_glob=false
392 fi ;;
393 esac
394
226 oIFS=$IFS 395 oIFS=$IFS
227 # Some sh's can't handle IFS=/ for some reason. 396 IFS=/
228 IFS='%' 397 $posix_glob && set -f
229 set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 398 set fnord $dstdir
230 shift
231 IFS=$oIFS
232
233 pathcomp=
234
235 while test $# -ne 0 ; do
236 pathcomp=$pathcomp$1
237 shift 399 shift
238 if test ! -d "$pathcomp"; then 400 $posix_glob && set +f
239 $mkdirprog "$pathcomp" 401 IFS=$oIFS
240 # mkdir can fail with a `File exist' error in case several 402
241 # install-sh are creating the directory concurrently. This 403 prefixes=
242 # is OK. 404
243 test -d "$pathcomp" || exit 405 for d
406 do
407 test -z "$d" && continue
408
409 prefix=$prefix$d
410 if test -d "$prefix"; then
411 prefixes=
412 else
413 if $posix_mkdir; then
414 (umask=$mkdir_umask &&
415 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
416 # Don't fail if two instances are running concurrently.
417 test -d "$prefix" || exit 1
418 else
419 case $prefix in
420 *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
421 *) qprefix=$prefix;;
422 esac
423 prefixes="$prefixes '$qprefix'"
424 fi
425 fi
426 prefix=$prefix/
427 done
428
429 if test -n "$prefixes"; then
430 # Don't fail if two instances are running concurrently.
431 (umask $mkdir_umask &&
432 eval "\$doit_exec \$mkdirprog $prefixes") ||
433 test -d "$dstdir" || exit 1
434 obsolete_mkdir_used=true
244 fi 435 fi
245 pathcomp=$pathcomp/ 436 fi
246 done
247 fi 437 fi
248 438
249 if test -n "$dir_arg"; then 439 if test -n "$dir_arg"; then
250 $doit $mkdircmd "$dst" \
251 && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 440 { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
252 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 441 { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
253 && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 442 { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
254 && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 443 test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
255
256 else 444 else
257 dstfile=`basename "$dst"`
258 445
259 # Make a couple of temp file names in the proper directory. 446 # Make a couple of temp file names in the proper directory.
260 dsttmp=$dstdir/_inst.$$_ 447 dsttmp=$dstdir/_inst.$$_
261 rmtmp=$dstdir/_rm.$$_ 448 rmtmp=$dstdir/_rm.$$_
262 449
263 # Trap to clean up those temp files at exit. 450 # Trap to clean up those temp files at exit.
264 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 451 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
265 trap '(exit $?); exit' 1 2 13 15
266 452
267 # Copy the file name to the temp name. 453 # Copy the file name to the temp name.
268 $doit $cpprog "$src" "$dsttmp" && 454 (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
269 455
270 # and set any options; do chmod last to preserve setuid bits. 456 # and set any options; do chmod last to preserve setuid bits.
271 # 457 #
272 # If any of these fail, we abort the whole thing. If we want to 458 # If any of these fail, we abort the whole thing. If we want to
273 # ignore errors from any of these, just make sure not to ignore 459 # ignore errors from any of these, just make sure not to ignore
274 # errors from the above "$doit $cpprog $src $dsttmp" command. 460 # errors from the above "$doit $cpprog $src $dsttmp" command.
275 # 461 #
276 { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 462 { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
277 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 463 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
278 && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 464 && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
279 && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 465 && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
280 466
281 # Now rename the file to the real destination. 467 # Now rename the file to the real destination.
282 { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 468 { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
283 || { 469 || {
284 # The rename failed, perhaps because mv can't rename something else 470 # The rename failed, perhaps because mv can't rename something else
285 # to itself, or perhaps because mv is so ancient that it does not 471 # to itself, or perhaps because mv is so ancient that it does not
286 # support -f. 472 # support -f.
287 473
289 # We try this two ways since rm can't unlink itself on some 475 # We try this two ways since rm can't unlink itself on some
290 # systems and the destination file might be busy for other 476 # systems and the destination file might be busy for other
291 # reasons. In this case, the final cleanup might fail but the new 477 # reasons. In this case, the final cleanup might fail but the new
292 # file should still install successfully. 478 # file should still install successfully.
293 { 479 {
294 if test -f "$dstdir/$dstfile"; then 480 if test -f "$dst"; then
295 $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 481 $doit $rmcmd -f "$dst" 2>/dev/null \
296 || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 482 || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
483 && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
297 || { 484 || {
298 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 485 echo "$0: cannot unlink or rename $dst" >&2
299 (exit 1); exit 1 486 (exit 1); exit 1
300 } 487 }
301 else 488 else
302 : 489 :
303 fi 490 fi
304 } && 491 } &&
305 492
306 # Now rename the file to the real destination. 493 # Now rename the file to the real destination.
307 $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 494 $doit $mvcmd "$dsttmp" "$dst"
308 } 495 }
309 } 496 } || exit 1
310 fi || { (exit 1); exit 1; } 497
498 trap '' 0
499 fi
311done 500done
312
313# The final little trick to "correctly" pass the exit status to the exit trap.
314{
315 (exit 0); exit 0
316}
317 501
318# Local variables: 502# Local variables:
319# eval: (add-hook 'write-file-hooks 'time-stamp) 503# eval: (add-hook 'write-file-hooks 'time-stamp)
320# time-stamp-start: "scriptversion=" 504# time-stamp-start: "scriptversion="
321# time-stamp-format: "%:y-%02m-%02d.%02H" 505# time-stamp-format: "%:y-%02m-%02d.%02H"

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines