comparison kdiff3/admin/install-sh @ 77:1184fc843210

KDiff3-0.9.92
author joachim99
date Mon, 16 Apr 2007 21:26:08 +0000
parents 8febbfb1148c
children
comparison
equal deleted inserted replaced
76:257ccb866dc3 77:1184fc843210
1 #!/bin/sh 1 #!/bin/sh
2 # install - install a program, script, or datafile 2 # install - install a program, script, or datafile
3 3
4 scriptversion=2005-05-14.22 4 scriptversion=2005-11-07.23
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 #
56 chgrpprog="${CHGRPPROG-chgrp}" 56 chgrpprog="${CHGRPPROG-chgrp}"
57 stripprog="${STRIPPROG-strip}" 57 stripprog="${STRIPPROG-strip}"
58 rmprog="${RMPROG-rm}" 58 rmprog="${RMPROG-rm}"
59 mkdirprog="${MKDIRPROG-mkdir}" 59 mkdirprog="${MKDIRPROG-mkdir}"
60 60
61 chmodcmd="$chmodprog 0755" 61 posix_glob=
62 posix_mkdir=
63
64 # Symbolic mode for testing mkdir with directories.
65 # It is the same as 755, but also tests that "u+" works.
66 test_mode=u=rwx,g=rx,o=rx,u+wx
67
68 # Desired mode of installed file.
69 mode=0755
70
71 # Desired mode of newly created intermediate directories.
72 # It is empty if not known yet.
73 intermediate_mode=
74
75 chmodcmd=$chmodprog
62 chowncmd= 76 chowncmd=
63 chgrpcmd= 77 chgrpcmd=
64 stripcmd= 78 stripcmd=
65 rmcmd="$rmprog -f" 79 rmcmd="$rmprog -f"
66 mvcmd="$mvprog" 80 mvcmd="$mvprog"
109 shift 123 shift
110 continue;; 124 continue;;
111 125
112 --help) echo "$usage"; exit $?;; 126 --help) echo "$usage"; exit $?;;
113 127
114 -m) chmodcmd="$chmodprog $2" 128 -m) mode=$2
115 shift 129 shift
116 shift 130 shift
117 continue;; 131 continue;;
118 132
119 -o) chowncmd="$chownprog $2" 133 -o) chowncmd="$chownprog $2"
162 # It's OK to call `install-sh -d' without argument. 176 # It's OK to call `install-sh -d' without argument.
163 # This can happen when creating conditional directories. 177 # This can happen when creating conditional directories.
164 exit 0 178 exit 0
165 fi 179 fi
166 180
181 test -n "$dir_arg" || trap '(exit $?); exit' 1 2 13 15
182
167 for src 183 for src
168 do 184 do
169 # Protect names starting with `-'. 185 # Protect names starting with `-'.
170 case $src in 186 case $src in
171 -*) src=./$src ;; 187 -*) src=./$src ;;
172 esac 188 esac
173 189
174 if test -n "$dir_arg"; then 190 if test -n "$dir_arg"; then
175 dst=$src 191 dst=$src
176 src= 192 dstdir=$dst
177 193 test -d "$dstdir"
178 if test -d "$dst"; then 194 dstdir_status=$?
179 mkdircmd=:
180 chmodcmd=
181 else
182 mkdircmd=$mkdirprog
183 fi
184 else 195 else
196
185 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 197 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
186 # might cause directories to be created, which would be especially bad 198 # might cause directories to be created, which would be especially bad
187 # if $src (and thus $dsttmp) contains '*'. 199 # if $src (and thus $dsttmp) contains '*'.
188 if test ! -f "$src" && test ! -d "$src"; then 200 if test ! -f "$src" && test ! -d "$src"; then
189 echo "$0: $src does not exist." >&2 201 echo "$0: $src does not exist." >&2
206 if test -d "$dst"; then 218 if test -d "$dst"; then
207 if test -n "$no_target_directory"; then 219 if test -n "$no_target_directory"; then
208 echo "$0: $dstarg: Is a directory" >&2 220 echo "$0: $dstarg: Is a directory" >&2
209 exit 1 221 exit 1
210 fi 222 fi
211 dst=$dst/`basename "$src"` 223 dstdir=$dst
224 dst=$dstdir/`basename "$src"`
225 dstdir_status=0
226 else
227 # Prefer dirname, but fall back on a substitute if dirname fails.
228 dstdir=`
229 (dirname "$dst") 2>/dev/null ||
230 expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
231 X"$dst" : 'X\(//\)[^/]' \| \
232 X"$dst" : 'X\(//\)$' \| \
233 X"$dst" : 'X\(/\)' \| \
234 . : '\(.\)' 2>/dev/null ||
235 echo X"$dst" |
236 sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
237 /^X\(\/\/\)[^/].*/{ s//\1/; q; }
238 /^X\(\/\/\)$/{ s//\1/; q; }
239 /^X\(\/\).*/{ s//\1/; q; }
240 s/.*/./; q'
241 `
242
243 test -d "$dstdir"
244 dstdir_status=$?
212 fi 245 fi
213 fi 246 fi
214 247
215 # This sed command emulates the dirname command. 248 obsolete_mkdir_used=false
216 dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 249
217 250 if test $dstdir_status != 0; then
218 # Make sure that the destination directory exists. 251 case $posix_mkdir in
219 252 '')
220 # Skip lots of stat calls in the usual case. 253 posix_mkdir=false
221 if test ! -d "$dstdir"; then 254 if $mkdirprog -m $test_mode -p -- / >/dev/null 2>&1; then
222 defaultIFS=' 255 posix_mkdir=true
223 ' 256 else
224 IFS="${IFS-$defaultIFS}" 257 # Remove any dirs left behind by ancient mkdir implementations.
225 258 rmdir ./-m "$test_mode" ./-p ./-- 2>/dev/null
226 oIFS=$IFS 259 fi ;;
227 # Some sh's can't handle IFS=/ for some reason. 260 esac
228 IFS='%' 261
229 set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 262 if
230 shift 263 $posix_mkdir && {
231 IFS=$oIFS 264
232 265 # With -d, create the new directory with the user-specified mode.
233 pathcomp= 266 # Otherwise, create it using the same intermediate mode that
234 267 # mkdir -p would use when creating intermediate directories.
235 while test $# -ne 0 ; do 268 # POSIX says that this mode is "$(umask -S),u+wx", so use that
236 pathcomp=$pathcomp$1 269 # if umask -S works.
270
271 if test -n "$dir_arg"; then
272 mkdir_mode=$mode
273 else
274 case $intermediate_mode in
275 '')
276 if umask_S=`(umask -S) 2>/dev/null`; then
277 intermediate_mode=$umask_S,u+wx
278 else
279 intermediate_mode=$test_mode
280 fi ;;
281 esac
282 mkdir_mode=$intermediate_mode
283 fi
284
285 $mkdirprog -m "$mkdir_mode" -p -- "$dstdir"
286 }
287 then :
288 else
289
290 # mkdir does not conform to POSIX, or it failed possibly due to
291 # a race condition. Create the directory the slow way, step by
292 # step, checking for races as we go.
293
294 case $dstdir in
295 /*) pathcomp=/ ;;
296 -*) pathcomp=./ ;;
297 *) pathcomp= ;;
298 esac
299
300 case $posix_glob in
301 '')
302 if (set -f) 2>/dev/null; then
303 posix_glob=true
304 else
305 posix_glob=false
306 fi ;;
307 esac
308
309 oIFS=$IFS
310 IFS=/
311 $posix_glob && set -f
312 set fnord $dstdir
237 shift 313 shift
238 if test ! -d "$pathcomp"; then 314 $posix_glob && set +f
239 $mkdirprog "$pathcomp" 315 IFS=$oIFS
240 # mkdir can fail with a `File exist' error in case several 316
241 # install-sh are creating the directory concurrently. This 317 for d
242 # is OK. 318 do
243 test -d "$pathcomp" || exit 319 test "x$d" = x && continue
244 fi 320
245 pathcomp=$pathcomp/ 321 pathcomp=$pathcomp$d
246 done 322 if test ! -d "$pathcomp"; then
323 $mkdirprog "$pathcomp"
324 # Don't fail if two instances are running concurrently.
325 test -d "$pathcomp" || exit 1
326 fi
327 pathcomp=$pathcomp/
328 done
329 obsolete_mkdir_used=true
330 fi
247 fi 331 fi
248 332
249 if test -n "$dir_arg"; then 333 if test -n "$dir_arg"; then
250 $doit $mkdircmd "$dst" \ 334 { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
251 && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 335 { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
252 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 336 { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
253 && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 337 test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dst"; } || exit 1
254 && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
255
256 else 338 else
257 dstfile=`basename "$dst"`
258 339
259 # Make a couple of temp file names in the proper directory. 340 # Make a couple of temp file names in the proper directory.
260 dsttmp=$dstdir/_inst.$$_ 341 dsttmp=$dstdir/_inst.$$_
261 rmtmp=$dstdir/_rm.$$_ 342 rmtmp=$dstdir/_rm.$$_
262 343
263 # Trap to clean up those temp files at exit. 344 # Trap to clean up those temp files at exit.
264 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 345 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
265 trap '(exit $?); exit' 1 2 13 15
266 346
267 # Copy the file name to the temp name. 347 # Copy the file name to the temp name.
268 $doit $cpprog "$src" "$dsttmp" && 348 $doit $cpprog "$src" "$dsttmp" &&
269 349
270 # and set any options; do chmod last to preserve setuid bits. 350 # and set any options; do chmod last to preserve setuid bits.
274 # errors from the above "$doit $cpprog $src $dsttmp" command. 354 # errors from the above "$doit $cpprog $src $dsttmp" command.
275 # 355 #
276 { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 356 { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
277 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 357 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
278 && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 358 && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
279 && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 359 && { test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dsttmp"; } &&
280 360
281 # Now rename the file to the real destination. 361 # Now rename the file to the real destination.
282 { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 362 { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
283 || { 363 || {
284 # The rename failed, perhaps because mv can't rename something else 364 # 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 365 # to itself, or perhaps because mv is so ancient that it does not
286 # support -f. 366 # support -f.
287 367
289 # We try this two ways since rm can't unlink itself on some 369 # We try this two ways since rm can't unlink itself on some
290 # systems and the destination file might be busy for other 370 # systems and the destination file might be busy for other
291 # reasons. In this case, the final cleanup might fail but the new 371 # reasons. In this case, the final cleanup might fail but the new
292 # file should still install successfully. 372 # file should still install successfully.
293 { 373 {
294 if test -f "$dstdir/$dstfile"; then 374 if test -f "$dst"; then
295 $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 375 $doit $rmcmd -f "$dst" 2>/dev/null \
296 || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 376 || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
377 && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
297 || { 378 || {
298 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 379 echo "$0: cannot unlink or rename $dst" >&2
299 (exit 1); exit 1 380 (exit 1); exit 1
300 } 381 }
301 else 382 else
302 : 383 :
303 fi 384 fi
304 } && 385 } &&
305 386
306 # Now rename the file to the real destination. 387 # Now rename the file to the real destination.
307 $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 388 $doit $mvcmd "$dsttmp" "$dst"
308 } 389 }
309 } 390 } || exit 1
310 fi || { (exit 1); exit 1; } 391
392 trap '' 0
393 fi
311 done 394 done
312
313 # The final little trick to "correctly" pass the exit status to the exit trap.
314 {
315 (exit 0); exit 0
316 }
317 395
318 # Local variables: 396 # Local variables:
319 # eval: (add-hook 'write-file-hooks 'time-stamp) 397 # eval: (add-hook 'write-file-hooks 'time-stamp)
320 # time-stamp-start: "scriptversion=" 398 # time-stamp-start: "scriptversion="
321 # time-stamp-format: "%:y-%02m-%02d.%02H" 399 # time-stamp-format: "%:y-%02m-%02d.%02H"