install-sh 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #!/bin/sh
  2. # install - install a program, script, or datafile
  3. scriptversion=2005-05-14.22
  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. It can only install one file at a time, a restriction
  41. # shared with many OS's install programs.
  42. # set DOITPROG to echo to test this script
  43. # Don't use :- since 4.3BSD and earlier shells don't like it.
  44. doit="${DOITPROG-}"
  45. # put in absolute paths if you don't have them in your path; or use env. vars.
  46. mvprog="${MVPROG-mv}"
  47. cpprog="${CPPROG-cp}"
  48. chmodprog="${CHMODPROG-chmod}"
  49. chownprog="${CHOWNPROG-chown}"
  50. chgrpprog="${CHGRPPROG-chgrp}"
  51. stripprog="${STRIPPROG-strip}"
  52. rmprog="${RMPROG-rm}"
  53. mkdirprog="${MKDIRPROG-mkdir}"
  54. chmodcmd="$chmodprog 0755"
  55. chowncmd=
  56. chgrpcmd=
  57. stripcmd=
  58. rmcmd="$rmprog -f"
  59. mvcmd="$mvprog"
  60. src=
  61. dst=
  62. dir_arg=
  63. dstarg=
  64. no_target_directory=
  65. usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
  66. or: $0 [OPTION]... SRCFILES... DIRECTORY
  67. or: $0 [OPTION]... -t DIRECTORY SRCFILES...
  68. or: $0 [OPTION]... -d DIRECTORIES...
  69. In the 1st form, copy SRCFILE to DSTFILE.
  70. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
  71. In the 4th, create DIRECTORIES.
  72. Options:
  73. -c (ignored)
  74. -d create directories instead of installing files.
  75. -g GROUP $chgrpprog installed files to GROUP.
  76. -m MODE $chmodprog installed files to MODE.
  77. -o USER $chownprog installed files to USER.
  78. -s $stripprog installed files.
  79. -t DIRECTORY install into DIRECTORY.
  80. -T report an error if DSTFILE is a directory.
  81. --help display this help and exit.
  82. --version display version info and exit.
  83. Environment variables override the default commands:
  84. CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
  85. "
  86. while test -n "$1"; do
  87. case $1 in
  88. -c) shift
  89. continue;;
  90. -d) dir_arg=true
  91. shift
  92. continue;;
  93. -g) chgrpcmd="$chgrpprog $2"
  94. shift
  95. shift
  96. continue;;
  97. --help) echo "$usage"; exit $?;;
  98. -m) chmodcmd="$chmodprog $2"
  99. shift
  100. shift
  101. continue;;
  102. -o) chowncmd="$chownprog $2"
  103. shift
  104. shift
  105. continue;;
  106. -s) stripcmd=$stripprog
  107. shift
  108. continue;;
  109. -t) dstarg=$2
  110. shift
  111. shift
  112. continue;;
  113. -T) no_target_directory=true
  114. shift
  115. continue;;
  116. --version) echo "$0 $scriptversion"; exit $?;;
  117. *) # When -d is used, all remaining arguments are directories to create.
  118. # When -t is used, the destination is already specified.
  119. test -n "$dir_arg$dstarg" && break
  120. # Otherwise, the last argument is the destination. Remove it from $@.
  121. for arg
  122. do
  123. if test -n "$dstarg"; then
  124. # $@ is not empty: it contains at least $arg.
  125. set fnord "$@" "$dstarg"
  126. shift # fnord
  127. fi
  128. shift # arg
  129. dstarg=$arg
  130. done
  131. break;;
  132. esac
  133. done
  134. if test -z "$1"; then
  135. if test -z "$dir_arg"; then
  136. echo "$0: no input file specified." >&2
  137. exit 1
  138. fi
  139. # It's OK to call `install-sh -d' without argument.
  140. # This can happen when creating conditional directories.
  141. exit 0
  142. fi
  143. for src
  144. do
  145. # Protect names starting with `-'.
  146. case $src in
  147. -*) src=./$src ;;
  148. esac
  149. if test -n "$dir_arg"; then
  150. dst=$src
  151. src=
  152. if test -d "$dst"; then
  153. mkdircmd=:
  154. chmodcmd=
  155. else
  156. mkdircmd=$mkdirprog
  157. fi
  158. else
  159. # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
  160. # might cause directories to be created, which would be especially bad
  161. # if $src (and thus $dsttmp) contains '*'.
  162. if test ! -f "$src" && test ! -d "$src"; then
  163. echo "$0: $src does not exist." >&2
  164. exit 1
  165. fi
  166. if test -z "$dstarg"; then
  167. echo "$0: no destination specified." >&2
  168. exit 1
  169. fi
  170. dst=$dstarg
  171. # Protect names starting with `-'.
  172. case $dst in
  173. -*) dst=./$dst ;;
  174. esac
  175. # If destination is a directory, append the input filename; won't work
  176. # if double slashes aren't ignored.
  177. if test -d "$dst"; then
  178. if test -n "$no_target_directory"; then
  179. echo "$0: $dstarg: Is a directory" >&2
  180. exit 1
  181. fi
  182. dst=$dst/`basename "$src"`
  183. fi
  184. fi
  185. # This sed command emulates the dirname command.
  186. dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
  187. # Make sure that the destination directory exists.
  188. # Skip lots of stat calls in the usual case.
  189. if test ! -d "$dstdir"; then
  190. defaultIFS='
  191. '
  192. IFS="${IFS-$defaultIFS}"
  193. oIFS=$IFS
  194. # Some sh's can't handle IFS=/ for some reason.
  195. IFS='%'
  196. set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
  197. shift
  198. IFS=$oIFS
  199. pathcomp=
  200. while test $# -ne 0 ; do
  201. pathcomp=$pathcomp$1
  202. shift
  203. if test ! -d "$pathcomp"; then
  204. $mkdirprog "$pathcomp"
  205. # mkdir can fail with a `File exist' error in case several
  206. # install-sh are creating the directory concurrently. This
  207. # is OK.
  208. test -d "$pathcomp" || exit
  209. fi
  210. pathcomp=$pathcomp/
  211. done
  212. fi
  213. if test -n "$dir_arg"; then
  214. $doit $mkdircmd "$dst" \
  215. && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
  216. && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
  217. && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
  218. && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
  219. else
  220. dstfile=`basename "$dst"`
  221. # Make a couple of temp file names in the proper directory.
  222. dsttmp=$dstdir/_inst.$$_
  223. rmtmp=$dstdir/_rm.$$_
  224. # Trap to clean up those temp files at exit.
  225. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
  226. trap '(exit $?); exit' 1 2 13 15
  227. # Copy the file name to the temp name.
  228. $doit $cpprog "$src" "$dsttmp" &&
  229. # and set any options; do chmod last to preserve setuid bits.
  230. #
  231. # If any of these fail, we abort the whole thing. If we want to
  232. # ignore errors from any of these, just make sure not to ignore
  233. # errors from the above "$doit $cpprog $src $dsttmp" command.
  234. #
  235. { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
  236. && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
  237. && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
  238. && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
  239. # Now rename the file to the real destination.
  240. { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
  241. || {
  242. # The rename failed, perhaps because mv can't rename something else
  243. # to itself, or perhaps because mv is so ancient that it does not
  244. # support -f.
  245. # Now remove or move aside any old file at destination location.
  246. # We try this two ways since rm can't unlink itself on some
  247. # systems and the destination file might be busy for other
  248. # reasons. In this case, the final cleanup might fail but the new
  249. # file should still install successfully.
  250. {
  251. if test -f "$dstdir/$dstfile"; then
  252. $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
  253. || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
  254. || {
  255. echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
  256. (exit 1); exit 1
  257. }
  258. else
  259. :
  260. fi
  261. } &&
  262. # Now rename the file to the real destination.
  263. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
  264. }
  265. }
  266. fi || { (exit 1); exit 1; }
  267. done
  268. # The final little trick to "correctly" pass the exit status to the exit trap.
  269. {
  270. (exit 0); exit 0
  271. }
  272. # Local variables:
  273. # eval: (add-hook 'write-file-hooks 'time-stamp)
  274. # time-stamp-start: "scriptversion="
  275. # time-stamp-format: "%:y-%02m-%02d.%02H"
  276. # time-stamp-end: "$"
  277. # End: