install-sh 15 KB

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