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

KDiff3-0.9.92
author joachim99
date Mon, 16 Apr 2007 21:26:08 +0000
parents 8febbfb1148c
children
rev   line source
joachim99@2 1 #!/bin/sh
joachim99@69 2 # install - install a program, script, or datafile
joachim99@69 3
joachim99@77 4 scriptversion=2005-11-07.23
joachim99@69 5
joachim99@69 6 # This originates from X11R5 (mit/util/scripts/install.sh), which was
joachim99@69 7 # later released in X11R6 (xc/config/util/install.sh) with the
joachim99@69 8 # following copyright and license.
joachim99@2 9 #
joachim99@69 10 # Copyright (C) 1994 X Consortium
joachim99@2 11 #
joachim99@69 12 # Permission is hereby granted, free of charge, to any person obtaining a copy
joachim99@69 13 # of this software and associated documentation files (the "Software"), to
joachim99@69 14 # deal in the Software without restriction, including without limitation the
joachim99@69 15 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
joachim99@69 16 # sell copies of the Software, and to permit persons to whom the Software is
joachim99@69 17 # furnished to do so, subject to the following conditions:
joachim99@2 18 #
joachim99@69 19 # The above copyright notice and this permission notice shall be included in
joachim99@69 20 # all copies or substantial portions of the Software.
joachim99@69 21 #
joachim99@69 22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
joachim99@69 23 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
joachim99@69 24 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
joachim99@69 25 # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
joachim99@69 26 # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
joachim99@69 27 # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
joachim99@69 28 #
joachim99@69 29 # Except as contained in this notice, the name of the X Consortium shall not
joachim99@69 30 # be used in advertising or otherwise to promote the sale, use or other deal-
joachim99@69 31 # ings in this Software without prior written authorization from the X Consor-
joachim99@69 32 # tium.
joachim99@69 33 #
joachim99@69 34 #
joachim99@69 35 # FSF changes to this file are in the public domain.
joachim99@2 36 #
joachim99@2 37 # Calling this script install-sh is preferred over install.sh, to prevent
joachim99@2 38 # `make' implicit rules from creating a file called install from it
joachim99@2 39 # when there is no Makefile.
joachim99@2 40 #
joachim99@2 41 # This script is compatible with the BSD install script, but was written
joachim99@2 42 # from scratch. It can only install one file at a time, a restriction
joachim99@2 43 # shared with many OS's install programs.
joachim99@2 44
joachim99@2 45 # set DOITPROG to echo to test this script
joachim99@2 46
joachim99@2 47 # Don't use :- since 4.3BSD and earlier shells don't like it.
joachim99@2 48 doit="${DOITPROG-}"
joachim99@2 49
joachim99@2 50 # put in absolute paths if you don't have them in your path; or use env. vars.
joachim99@2 51
joachim99@2 52 mvprog="${MVPROG-mv}"
joachim99@2 53 cpprog="${CPPROG-cp}"
joachim99@2 54 chmodprog="${CHMODPROG-chmod}"
joachim99@2 55 chownprog="${CHOWNPROG-chown}"
joachim99@2 56 chgrpprog="${CHGRPPROG-chgrp}"
joachim99@2 57 stripprog="${STRIPPROG-strip}"
joachim99@2 58 rmprog="${RMPROG-rm}"
joachim99@2 59 mkdirprog="${MKDIRPROG-mkdir}"
joachim99@2 60
joachim99@77 61 posix_glob=
joachim99@77 62 posix_mkdir=
joachim99@77 63
joachim99@77 64 # Symbolic mode for testing mkdir with directories.
joachim99@77 65 # It is the same as 755, but also tests that "u+" works.
joachim99@77 66 test_mode=u=rwx,g=rx,o=rx,u+wx
joachim99@77 67
joachim99@77 68 # Desired mode of installed file.
joachim99@77 69 mode=0755
joachim99@77 70
joachim99@77 71 # Desired mode of newly created intermediate directories.
joachim99@77 72 # It is empty if not known yet.
joachim99@77 73 intermediate_mode=
joachim99@77 74
joachim99@77 75 chmodcmd=$chmodprog
joachim99@69 76 chowncmd=
joachim99@69 77 chgrpcmd=
joachim99@69 78 stripcmd=
joachim99@2 79 rmcmd="$rmprog -f"
joachim99@2 80 mvcmd="$mvprog"
joachim99@69 81 src=
joachim99@69 82 dst=
joachim99@69 83 dir_arg=
joachim99@69 84 dstarg=
joachim99@69 85 no_target_directory=
joachim99@2 86
joachim99@69 87 usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
joachim99@69 88 or: $0 [OPTION]... SRCFILES... DIRECTORY
joachim99@69 89 or: $0 [OPTION]... -t DIRECTORY SRCFILES...
joachim99@69 90 or: $0 [OPTION]... -d DIRECTORIES...
joachim99@2 91
joachim99@69 92 In the 1st form, copy SRCFILE to DSTFILE.
joachim99@69 93 In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
joachim99@69 94 In the 4th, create DIRECTORIES.
joachim99@2 95
joachim99@69 96 Options:
joachim99@69 97 -c (ignored)
joachim99@69 98 -d create directories instead of installing files.
joachim99@69 99 -g GROUP $chgrpprog installed files to GROUP.
joachim99@69 100 -m MODE $chmodprog installed files to MODE.
joachim99@69 101 -o USER $chownprog installed files to USER.
joachim99@69 102 -s $stripprog installed files.
joachim99@69 103 -t DIRECTORY install into DIRECTORY.
joachim99@69 104 -T report an error if DSTFILE is a directory.
joachim99@69 105 --help display this help and exit.
joachim99@69 106 --version display version info and exit.
joachim99@2 107
joachim99@69 108 Environment variables override the default commands:
joachim99@69 109 CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
joachim99@69 110 "
joachim99@2 111
joachim99@69 112 while test -n "$1"; do
joachim99@69 113 case $1 in
joachim99@69 114 -c) shift
joachim99@69 115 continue;;
joachim99@2 116
joachim99@69 117 -d) dir_arg=true
joachim99@69 118 shift
joachim99@69 119 continue;;
joachim99@2 120
joachim99@69 121 -g) chgrpcmd="$chgrpprog $2"
joachim99@69 122 shift
joachim99@69 123 shift
joachim99@69 124 continue;;
joachim99@2 125
joachim99@69 126 --help) echo "$usage"; exit $?;;
joachim99@2 127
joachim99@77 128 -m) mode=$2
joachim99@69 129 shift
joachim99@69 130 shift
joachim99@69 131 continue;;
joachim99@69 132
joachim99@69 133 -o) chowncmd="$chownprog $2"
joachim99@69 134 shift
joachim99@69 135 shift
joachim99@69 136 continue;;
joachim99@69 137
joachim99@69 138 -s) stripcmd=$stripprog
joachim99@69 139 shift
joachim99@69 140 continue;;
joachim99@69 141
joachim99@69 142 -t) dstarg=$2
joachim99@69 143 shift
joachim99@69 144 shift
joachim99@69 145 continue;;
joachim99@69 146
joachim99@69 147 -T) no_target_directory=true
joachim99@69 148 shift
joachim99@69 149 continue;;
joachim99@69 150
joachim99@69 151 --version) echo "$0 $scriptversion"; exit $?;;
joachim99@69 152
joachim99@69 153 *) # When -d is used, all remaining arguments are directories to create.
joachim99@69 154 # When -t is used, the destination is already specified.
joachim99@69 155 test -n "$dir_arg$dstarg" && break
joachim99@69 156 # Otherwise, the last argument is the destination. Remove it from $@.
joachim99@69 157 for arg
joachim99@69 158 do
joachim99@69 159 if test -n "$dstarg"; then
joachim99@69 160 # $@ is not empty: it contains at least $arg.
joachim99@69 161 set fnord "$@" "$dstarg"
joachim99@69 162 shift # fnord
joachim99@69 163 fi
joachim99@69 164 shift # arg
joachim99@69 165 dstarg=$arg
joachim99@69 166 done
joachim99@69 167 break;;
joachim99@69 168 esac
joachim99@2 169 done
joachim99@2 170
joachim99@69 171 if test -z "$1"; then
joachim99@69 172 if test -z "$dir_arg"; then
joachim99@69 173 echo "$0: no input file specified." >&2
joachim99@69 174 exit 1
joachim99@69 175 fi
joachim99@69 176 # It's OK to call `install-sh -d' without argument.
joachim99@69 177 # This can happen when creating conditional directories.
joachim99@69 178 exit 0
joachim99@2 179 fi
joachim99@2 180
joachim99@77 181 test -n "$dir_arg" || trap '(exit $?); exit' 1 2 13 15
joachim99@77 182
joachim99@69 183 for src
joachim99@69 184 do
joachim99@69 185 # Protect names starting with `-'.
joachim99@69 186 case $src in
joachim99@69 187 -*) src=./$src ;;
joachim99@69 188 esac
joachim99@66 189
joachim99@69 190 if test -n "$dir_arg"; then
joachim99@69 191 dst=$src
joachim99@77 192 dstdir=$dst
joachim99@77 193 test -d "$dstdir"
joachim99@77 194 dstdir_status=$?
joachim99@77 195 else
joachim99@2 196
joachim99@69 197 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
joachim99@69 198 # might cause directories to be created, which would be especially bad
joachim99@69 199 # if $src (and thus $dsttmp) contains '*'.
joachim99@69 200 if test ! -f "$src" && test ! -d "$src"; then
joachim99@69 201 echo "$0: $src does not exist." >&2
joachim99@69 202 exit 1
joachim99@69 203 fi
joachim99@2 204
joachim99@69 205 if test -z "$dstarg"; then
joachim99@69 206 echo "$0: no destination specified." >&2
joachim99@69 207 exit 1
joachim99@69 208 fi
joachim99@66 209
joachim99@69 210 dst=$dstarg
joachim99@69 211 # Protect names starting with `-'.
joachim99@69 212 case $dst in
joachim99@69 213 -*) dst=./$dst ;;
joachim99@69 214 esac
joachim99@2 215
joachim99@69 216 # If destination is a directory, append the input filename; won't work
joachim99@69 217 # if double slashes aren't ignored.
joachim99@69 218 if test -d "$dst"; then
joachim99@69 219 if test -n "$no_target_directory"; then
joachim99@69 220 echo "$0: $dstarg: Is a directory" >&2
joachim99@69 221 exit 1
joachim99@69 222 fi
joachim99@77 223 dstdir=$dst
joachim99@77 224 dst=$dstdir/`basename "$src"`
joachim99@77 225 dstdir_status=0
joachim99@77 226 else
joachim99@77 227 # Prefer dirname, but fall back on a substitute if dirname fails.
joachim99@77 228 dstdir=`
joachim99@77 229 (dirname "$dst") 2>/dev/null ||
joachim99@77 230 expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
joachim99@77 231 X"$dst" : 'X\(//\)[^/]' \| \
joachim99@77 232 X"$dst" : 'X\(//\)$' \| \
joachim99@77 233 X"$dst" : 'X\(/\)' \| \
joachim99@77 234 . : '\(.\)' 2>/dev/null ||
joachim99@77 235 echo X"$dst" |
joachim99@77 236 sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
joachim99@77 237 /^X\(\/\/\)[^/].*/{ s//\1/; q; }
joachim99@77 238 /^X\(\/\/\)$/{ s//\1/; q; }
joachim99@77 239 /^X\(\/\).*/{ s//\1/; q; }
joachim99@77 240 s/.*/./; q'
joachim99@77 241 `
joachim99@77 242
joachim99@77 243 test -d "$dstdir"
joachim99@77 244 dstdir_status=$?
joachim99@69 245 fi
joachim99@69 246 fi
joachim99@2 247
joachim99@77 248 obsolete_mkdir_used=false
joachim99@2 249
joachim99@77 250 if test $dstdir_status != 0; then
joachim99@77 251 case $posix_mkdir in
joachim99@77 252 '')
joachim99@77 253 posix_mkdir=false
joachim99@77 254 if $mkdirprog -m $test_mode -p -- / >/dev/null 2>&1; then
joachim99@77 255 posix_mkdir=true
joachim99@77 256 else
joachim99@77 257 # Remove any dirs left behind by ancient mkdir implementations.
joachim99@77 258 rmdir ./-m "$test_mode" ./-p ./-- 2>/dev/null
joachim99@77 259 fi ;;
joachim99@77 260 esac
joachim99@2 261
joachim99@77 262 if
joachim99@77 263 $posix_mkdir && {
joachim99@2 264
joachim99@77 265 # With -d, create the new directory with the user-specified mode.
joachim99@77 266 # Otherwise, create it using the same intermediate mode that
joachim99@77 267 # mkdir -p would use when creating intermediate directories.
joachim99@77 268 # POSIX says that this mode is "$(umask -S),u+wx", so use that
joachim99@77 269 # if umask -S works.
joachim99@2 270
joachim99@77 271 if test -n "$dir_arg"; then
joachim99@77 272 mkdir_mode=$mode
joachim99@77 273 else
joachim99@77 274 case $intermediate_mode in
joachim99@77 275 '')
joachim99@77 276 if umask_S=`(umask -S) 2>/dev/null`; then
joachim99@77 277 intermediate_mode=$umask_S,u+wx
joachim99@77 278 else
joachim99@77 279 intermediate_mode=$test_mode
joachim99@77 280 fi ;;
joachim99@77 281 esac
joachim99@77 282 mkdir_mode=$intermediate_mode
joachim99@77 283 fi
joachim99@2 284
joachim99@77 285 $mkdirprog -m "$mkdir_mode" -p -- "$dstdir"
joachim99@77 286 }
joachim99@77 287 then :
joachim99@77 288 else
joachim99@77 289
joachim99@77 290 # mkdir does not conform to POSIX, or it failed possibly due to
joachim99@77 291 # a race condition. Create the directory the slow way, step by
joachim99@77 292 # step, checking for races as we go.
joachim99@77 293
joachim99@77 294 case $dstdir in
joachim99@77 295 /*) pathcomp=/ ;;
joachim99@77 296 -*) pathcomp=./ ;;
joachim99@77 297 *) pathcomp= ;;
joachim99@77 298 esac
joachim99@77 299
joachim99@77 300 case $posix_glob in
joachim99@77 301 '')
joachim99@77 302 if (set -f) 2>/dev/null; then
joachim99@77 303 posix_glob=true
joachim99@77 304 else
joachim99@77 305 posix_glob=false
joachim99@77 306 fi ;;
joachim99@77 307 esac
joachim99@77 308
joachim99@77 309 oIFS=$IFS
joachim99@77 310 IFS=/
joachim99@77 311 $posix_glob && set -f
joachim99@77 312 set fnord $dstdir
joachim99@69 313 shift
joachim99@77 314 $posix_glob && set +f
joachim99@77 315 IFS=$oIFS
joachim99@77 316
joachim99@77 317 for d
joachim99@77 318 do
joachim99@77 319 test "x$d" = x && continue
joachim99@77 320
joachim99@77 321 pathcomp=$pathcomp$d
joachim99@77 322 if test ! -d "$pathcomp"; then
joachim99@77 323 $mkdirprog "$pathcomp"
joachim99@77 324 # Don't fail if two instances are running concurrently.
joachim99@77 325 test -d "$pathcomp" || exit 1
joachim99@77 326 fi
joachim99@77 327 pathcomp=$pathcomp/
joachim99@77 328 done
joachim99@77 329 obsolete_mkdir_used=true
joachim99@77 330 fi
joachim99@69 331 fi
joachim99@2 332
joachim99@69 333 if test -n "$dir_arg"; then
joachim99@77 334 { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
joachim99@77 335 { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
joachim99@77 336 { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
joachim99@77 337 test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dst"; } || exit 1
joachim99@69 338 else
joachim99@2 339
joachim99@69 340 # Make a couple of temp file names in the proper directory.
joachim99@69 341 dsttmp=$dstdir/_inst.$$_
joachim99@69 342 rmtmp=$dstdir/_rm.$$_
joachim99@69 343
joachim99@69 344 # Trap to clean up those temp files at exit.
joachim99@69 345 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
joachim99@69 346
joachim99@69 347 # Copy the file name to the temp name.
joachim99@69 348 $doit $cpprog "$src" "$dsttmp" &&
joachim99@69 349
joachim99@69 350 # and set any options; do chmod last to preserve setuid bits.
joachim99@69 351 #
joachim99@69 352 # If any of these fail, we abort the whole thing. If we want to
joachim99@69 353 # ignore errors from any of these, just make sure not to ignore
joachim99@69 354 # errors from the above "$doit $cpprog $src $dsttmp" command.
joachim99@69 355 #
joachim99@69 356 { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
joachim99@69 357 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
joachim99@69 358 && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
joachim99@77 359 && { test -z "$chmodcmd" || $doit $chmodcmd "$mode" "$dsttmp"; } &&
joachim99@69 360
joachim99@69 361 # Now rename the file to the real destination.
joachim99@77 362 { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
joachim99@69 363 || {
joachim99@69 364 # The rename failed, perhaps because mv can't rename something else
joachim99@69 365 # to itself, or perhaps because mv is so ancient that it does not
joachim99@69 366 # support -f.
joachim99@69 367
joachim99@69 368 # Now remove or move aside any old file at destination location.
joachim99@69 369 # We try this two ways since rm can't unlink itself on some
joachim99@69 370 # systems and the destination file might be busy for other
joachim99@69 371 # reasons. In this case, the final cleanup might fail but the new
joachim99@69 372 # file should still install successfully.
joachim99@69 373 {
joachim99@77 374 if test -f "$dst"; then
joachim99@77 375 $doit $rmcmd -f "$dst" 2>/dev/null \
joachim99@77 376 || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
joachim99@77 377 && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
joachim99@69 378 || {
joachim99@77 379 echo "$0: cannot unlink or rename $dst" >&2
joachim99@69 380 (exit 1); exit 1
joachim99@69 381 }
joachim99@69 382 else
joachim99@69 383 :
joachim99@69 384 fi
joachim99@69 385 } &&
joachim99@69 386
joachim99@69 387 # Now rename the file to the real destination.
joachim99@77 388 $doit $mvcmd "$dsttmp" "$dst"
joachim99@69 389 }
joachim99@77 390 } || exit 1
joachim99@77 391
joachim99@77 392 trap '' 0
joachim99@77 393 fi
joachim99@2 394 done
joachim99@2 395
joachim99@69 396 # Local variables:
joachim99@69 397 # eval: (add-hook 'write-file-hooks 'time-stamp)
joachim99@69 398 # time-stamp-start: "scriptversion="
joachim99@69 399 # time-stamp-format: "%:y-%02m-%02d.%02H"
joachim99@69 400 # time-stamp-end: "$"
joachim99@69 401 # End: