install-sh 9.3 KB

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