cdrom.eclass 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. # Copyright 1999-2014 Gentoo Foundation
  2. # Distributed under the terms of the GNU General Public License v2
  3. # @ECLASS: cdrom.eclass
  4. # @MAINTAINER:
  5. # games@gentoo.org
  6. # @BLURB: Functions for CD-ROM handling
  7. # @DESCRIPTION:
  8. # Acquire cd(s) for those lovely cd-based emerges. Yes, this violates
  9. # the whole 'non-interactive' policy, but damnit I want CD support!
  10. #
  11. # With these cdrom functions we handle all the user interaction and
  12. # standardize everything. All you have to do is call cdrom_get_cds()
  13. # and when the function returns, you can assume that the cd has been
  14. # found at CDROM_ROOT.
  15. if [[ -z ${_CDROM_ECLASS} ]]; then
  16. _CDROM_ECLASS=1
  17. inherit portability
  18. # @ECLASS-VARIABLE: CDROM_OPTIONAL
  19. # @DEFAULT_UNSET
  20. # @DESCRIPTION:
  21. # By default, the eclass sets PROPERTIES="interactive" on the assumption
  22. # that people will be using these. If your package optionally supports
  23. # disc based installed, then set this to "yes", and we'll set things
  24. # conditionally based on USE=cdinstall.
  25. if [[ ${CDROM_OPTIONAL} == "yes" ]] ; then
  26. IUSE="cdinstall"
  27. PROPERTIES="cdinstall? ( interactive )"
  28. else
  29. PROPERTIES="interactive"
  30. fi
  31. # @FUNCTION: cdrom_get_cds
  32. # @USAGE: <file on cd1> [file on cd2] [file on cd3] [...]
  33. # @DESCRIPTION:
  34. # The function will attempt to locate a cd based upon a file that is on
  35. # the cd. The more files you give this function, the more cds the cdrom
  36. # functions will handle.
  37. #
  38. # Normally the cdrom functions will refer to the cds as 'cd #1', 'cd #2',
  39. # etc... If you want to give the cds better names, then just export
  40. # the appropriate CDROM_NAME variable before calling cdrom_get_cds().
  41. # Use CDROM_NAME for one cd, or CDROM_NAME_# for multiple cds. You can
  42. # also use the CDROM_NAME_SET bash array.
  43. #
  44. # For those multi cd ebuilds, see the cdrom_load_next_cd() function.
  45. cdrom_get_cds() {
  46. # first we figure out how many cds we're dealing with by
  47. # the # of files they gave us
  48. local cdcnt=0
  49. local f=
  50. for f in "$@" ; do
  51. ((++cdcnt))
  52. export CDROM_CHECK_${cdcnt}="$f"
  53. done
  54. export CDROM_TOTAL_CDS=${cdcnt}
  55. export CDROM_CURRENT_CD=1
  56. # now we see if the user gave use CD_ROOT ...
  57. # if they did, let's just believe them that it's correct
  58. if [[ -n ${CD_ROOT}${CD_ROOT_1} ]] ; then
  59. local var=
  60. cdcnt=0
  61. while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
  62. ((++cdcnt))
  63. var="CD_ROOT_${cdcnt}"
  64. [[ -z ${!var} ]] && var="CD_ROOT"
  65. if [[ -z ${!var} ]] ; then
  66. eerror "You must either use just the CD_ROOT"
  67. eerror "or specify ALL the CD_ROOT_X variables."
  68. eerror "In this case, you will need" \
  69. "${CDROM_TOTAL_CDS} CD_ROOT_X variables."
  70. die "could not locate CD_ROOT_${cdcnt}"
  71. fi
  72. done
  73. export CDROM_ROOT=${CD_ROOT_1:-${CD_ROOT}}
  74. einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
  75. export CDROM_SET=-1
  76. for f in ${CDROM_CHECK_1//:/ } ; do
  77. ((++CDROM_SET))
  78. [[ -e ${CDROM_ROOT}/${f} ]] && break
  79. done
  80. export CDROM_MATCH=${f}
  81. return
  82. fi
  83. # User didn't help us out so lets make sure they know they can
  84. # simplify the whole process ...
  85. if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
  86. einfo "This ebuild will need the ${CDROM_NAME:-cdrom for ${PN}}"
  87. echo
  88. einfo "If you do not have the CD, but have the data files"
  89. einfo "mounted somewhere on your filesystem, just export"
  90. einfo "the variable CD_ROOT so that it points to the"
  91. einfo "directory containing the files."
  92. echo
  93. einfo "For example:"
  94. einfo "export CD_ROOT=/mnt/cdrom"
  95. echo
  96. else
  97. if [[ -n ${CDROM_NAME_SET} ]] ; then
  98. # Translate the CDROM_NAME_SET array into CDROM_NAME_#
  99. cdcnt=0
  100. while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
  101. ((++cdcnt))
  102. export CDROM_NAME_${cdcnt}="${CDROM_NAME_SET[$((${cdcnt}-1))]}"
  103. done
  104. fi
  105. einfo "This package will need access to ${CDROM_TOTAL_CDS} cds."
  106. cdcnt=0
  107. while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
  108. ((++cdcnt))
  109. var="CDROM_NAME_${cdcnt}"
  110. [[ ! -z ${!var} ]] && einfo " CD ${cdcnt}: ${!var}"
  111. done
  112. echo
  113. einfo "If you do not have the CDs, but have the data files"
  114. einfo "mounted somewhere on your filesystem, just export"
  115. einfo "the following variables so they point to the right place:"
  116. einfon ""
  117. cdcnt=0
  118. while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
  119. ((++cdcnt))
  120. echo -n " CD_ROOT_${cdcnt}"
  121. done
  122. echo
  123. einfo "Or, if you have all the files in the same place, or"
  124. einfo "you only have one cdrom, you can export CD_ROOT"
  125. einfo "and that place will be used as the same data source"
  126. einfo "for all the CDs."
  127. echo
  128. einfo "For example:"
  129. einfo "export CD_ROOT_1=/mnt/cdrom"
  130. echo
  131. fi
  132. export CDROM_SET=""
  133. export CDROM_CURRENT_CD=0
  134. cdrom_load_next_cd
  135. }
  136. # @FUNCTION: cdrom_load_next_cd
  137. # @DESCRIPTION:
  138. # Some packages are so big they come on multiple CDs. When you're done
  139. # reading files off a CD and want access to the next one, just call this
  140. # function. Again, all the messy details of user interaction are taken
  141. # care of for you. Once this returns, just read the variable CDROM_ROOT
  142. # for the location of the mounted CD. Note that you can only go forward
  143. # in the CD list, so make sure you only call this function when you're
  144. # done using the current CD.
  145. cdrom_load_next_cd() {
  146. local var
  147. ((++CDROM_CURRENT_CD))
  148. unset CDROM_ROOT
  149. var=CD_ROOT_${CDROM_CURRENT_CD}
  150. [[ -z ${!var} ]] && var="CD_ROOT"
  151. if [[ -z ${!var} ]] ; then
  152. var="CDROM_CHECK_${CDROM_CURRENT_CD}"
  153. _cdrom_locate_file_on_cd ${!var}
  154. else
  155. export CDROM_ROOT=${!var}
  156. fi
  157. einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
  158. }
  159. # this is used internally by the cdrom_get_cds() and cdrom_load_next_cd()
  160. # functions. this should *never* be called from an ebuild.
  161. # all it does is try to locate a give file on a cd ... if the cd isn't
  162. # found, then a message asking for the user to insert the cdrom will be
  163. # displayed and we'll hang out here until:
  164. # (1) the file is found on a mounted cdrom
  165. # (2) the user hits CTRL+C
  166. _cdrom_locate_file_on_cd() {
  167. local mline=""
  168. local showedmsg=0 showjolietmsg=0
  169. while [[ -z ${CDROM_ROOT} ]] ; do
  170. local i=0
  171. local -a cdset=(${*//:/ })
  172. if [[ -n ${CDROM_SET} ]] ; then
  173. cdset=(${cdset[${CDROM_SET}]})
  174. fi
  175. while [[ -n ${cdset[${i}]} ]] ; do
  176. local dir=$(dirname ${cdset[${i}]})
  177. local file=$(basename ${cdset[${i}]})
  178. local point= node= fs= foo=
  179. while read point node fs foo ; do
  180. [[ " cd9660 iso9660 udf " != *" ${fs} "* ]] && \
  181. ! [[ ${fs} == "subfs" && ",${opts}," == *",fs=cdfss,"* ]] \
  182. && continue
  183. point=${point//\040/ }
  184. [[ ! -d ${point}/${dir} ]] && continue
  185. [[ -z $(find "${point}/${dir}" -maxdepth 1 -iname "${file}") ]] \
  186. && continue
  187. export CDROM_ROOT=${point}
  188. export CDROM_SET=${i}
  189. export CDROM_MATCH=${cdset[${i}]}
  190. return
  191. done <<< "$(get_mounts)"
  192. ((++i))
  193. done
  194. echo
  195. if [[ ${showedmsg} -eq 0 ]] ; then
  196. if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
  197. if [[ -z ${CDROM_NAME} ]] ; then
  198. einfo "Please insert+mount the cdrom for ${PN} now !"
  199. else
  200. einfo "Please insert+mount the ${CDROM_NAME} cdrom now !"
  201. fi
  202. else
  203. if [[ -z ${CDROM_NAME_1} ]] ; then
  204. einfo "Please insert+mount cd #${CDROM_CURRENT_CD}" \
  205. "for ${PN} now !"
  206. else
  207. local var="CDROM_NAME_${CDROM_CURRENT_CD}"
  208. einfo "Please insert+mount the ${!var} cdrom now !"
  209. fi
  210. fi
  211. showedmsg=1
  212. fi
  213. einfo "Press return to scan for the cd again"
  214. einfo "or hit CTRL+C to abort the emerge."
  215. echo
  216. if [[ ${showjolietmsg} -eq 0 ]] ; then
  217. showjolietmsg=1
  218. else
  219. ewarn "If you are having trouble with the detection"
  220. ewarn "of your CD, it is possible that you do not have"
  221. ewarn "Joliet support enabled in your kernel. Please"
  222. ewarn "check that CONFIG_JOLIET is enabled in your kernel."
  223. fi
  224. read || die "something is screwed with your system"
  225. done
  226. }
  227. fi