games.eclass 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. # Copyright 1999-2015 Gentoo Foundation
  2. # Distributed under the terms of the GNU General Public License v2
  3. # @ECLASS: games.eclass
  4. # @MAINTAINER:
  5. # Games team <games@gentoo.org>
  6. # @BLURB: Standardizing the install of games.
  7. # @DESCRIPTION:
  8. # This eclass makes sure that games are consistently handled in gentoo.
  9. # It installs game files by default in FHS-compatible directories
  10. # like /usr/share/games and sets more restrictive permissions in order
  11. # to avoid some security bugs.
  12. #
  13. # The installation directories as well as the user and group files are
  14. # installed as can be controlled by the user. See the variables like
  15. # GAMES_BINDIR, GAMES_USER etc. below. These are NOT supposed to be set
  16. # by ebuilds!
  17. #
  18. # For a general guide on writing games ebuilds, see:
  19. # https://wiki.gentoo.org/wiki/Project:Games/Ebuild_howto
  20. #
  21. # WARNING: This eclass is DEPRECATED and must not be used by new games
  22. # ebuilds, bug #574082. When writing game ebuilds, no specific eclass
  23. # is needed. For more details, see the QA team policies page:
  24. # https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Policies#Games
  25. if [[ -z ${_GAMES_ECLASS} ]]; then
  26. _GAMES_ECLASS=1
  27. inherit base multilib toolchain-funcs eutils user
  28. case ${EAPI:-0} in
  29. 0|1) EXPORT_FUNCTIONS pkg_setup src_compile pkg_preinst pkg_postinst ;;
  30. 2|3|4|5) EXPORT_FUNCTIONS pkg_setup src_configure src_compile pkg_preinst pkg_postinst ;;
  31. *) die "games.eclass is banned in EAPI=${EAPI}, see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Policies#Games" ;;
  32. esac
  33. if [[ ${CATEGORY}/${PN} != "games-misc/games-envd" ]] ; then
  34. # environment file
  35. RDEPEND="games-misc/games-envd"
  36. fi
  37. # @ECLASS-VARIABLE: GAMES_PREFIX
  38. # @DESCRIPTION:
  39. # Prefix where to install games, mostly used by GAMES_BINDIR. Games data should
  40. # still go into GAMES_DATADIR. May be set by the user.
  41. GAMES_PREFIX=${GAMES_PREFIX:-/usr/games}
  42. # @ECLASS-VARIABLE: GAMES_PREFIX_OPT
  43. # @DESCRIPTION:
  44. # Prefix where to install precompiled/blob games, usually followed by
  45. # package name. May be set by the user.
  46. GAMES_PREFIX_OPT=${GAMES_PREFIX_OPT:-/opt}
  47. # @ECLASS-VARIABLE: GAMES_DATADIR
  48. # @DESCRIPTION:
  49. # Base directory where to install game data files, usually followed by
  50. # package name. May be set by the user.
  51. GAMES_DATADIR=${GAMES_DATADIR:-/usr/share/games}
  52. # @ECLASS-VARIABLE: GAMES_DATADIR_BASE
  53. # @DESCRIPTION:
  54. # Similar to GAMES_DATADIR, but only used when a package auto appends 'games'
  55. # to the path. May be set by the user.
  56. GAMES_DATADIR_BASE=${GAMES_DATADIR_BASE:-/usr/share}
  57. # @ECLASS-VARIABLE: GAMES_SYSCONFDIR
  58. # @DESCRIPTION:
  59. # Where to install global games configuration files, usually followed by
  60. # package name. May be set by the user.
  61. GAMES_SYSCONFDIR=${GAMES_SYSCONFDIR:-/etc/games}
  62. # @ECLASS-VARIABLE: GAMES_STATEDIR
  63. # @DESCRIPTION:
  64. # Where to install/store global variable game data, usually followed by
  65. # package name. May be set by the user.
  66. GAMES_STATEDIR=${GAMES_STATEDIR:-/var/games}
  67. # @ECLASS-VARIABLE: GAMES_LOGDIR
  68. # @DESCRIPTION:
  69. # Where to store global game log files, usually followed by
  70. # package name. May be set by the user.
  71. GAMES_LOGDIR=${GAMES_LOGDIR:-/var/log/games}
  72. # @ECLASS-VARIABLE: GAMES_BINDIR
  73. # @DESCRIPTION:
  74. # Where to install the game binaries. May be set by the user. This is in PATH.
  75. GAMES_BINDIR=${GAMES_BINDIR:-${GAMES_PREFIX}/bin}
  76. # @ECLASS-VARIABLE: GAMES_ENVD
  77. # @INTERNAL
  78. # @DESCRIPTION:
  79. # The games environment file name which sets games specific LDPATH and PATH.
  80. GAMES_ENVD="90games"
  81. # @ECLASS-VARIABLE: GAMES_USER
  82. # @DESCRIPTION:
  83. # The USER who owns all game files and usually has write permissions.
  84. # May be set by the user.
  85. GAMES_USER=${GAMES_USER:-root}
  86. # @ECLASS-VARIABLE: GAMES_USER_DED
  87. # @DESCRIPTION:
  88. # The USER who owns all game files related to the dedicated server part
  89. # of a package. May be set by the user.
  90. GAMES_USER_DED=${GAMES_USER_DED:-games}
  91. # @ECLASS-VARIABLE: GAMES_GROUP
  92. # @DESCRIPTION:
  93. # The GROUP that owns all game files and usually does not have
  94. # write permissions. May be set by the user.
  95. # If you want games world-executable, then you can at least set this variable
  96. # to 'users' which is almost the same.
  97. GAMES_GROUP=${GAMES_GROUP:-games}
  98. # @FUNCTION: games_get_libdir
  99. # @DESCRIPTION:
  100. # Gets the directory where to install games libraries. This is in LDPATH.
  101. games_get_libdir() {
  102. echo ${GAMES_PREFIX}/$(get_libdir)
  103. }
  104. # @FUNCTION: egamesconf
  105. # @USAGE: [<args>...]
  106. # @DESCRIPTION:
  107. # Games equivalent to 'econf' for autotools based build systems. It passes
  108. # the necessary games specific directories automatically.
  109. egamesconf() {
  110. # handle verbose build log pre-EAPI5
  111. local _gamesconf
  112. if has "${EAPI:-0}" 0 1 2 3 4 ; then
  113. if grep -q -s disable-silent-rules "${ECONF_SOURCE:-.}"/configure ; then
  114. _gamesconf="--disable-silent-rules"
  115. fi
  116. fi
  117. # bug 493954
  118. if grep -q -s datarootdir "${ECONF_SOURCE:-.}"/configure ; then
  119. _gamesconf="${_gamesconf} --datarootdir=/usr/share"
  120. fi
  121. econf \
  122. --prefix="${GAMES_PREFIX}" \
  123. --libdir="$(games_get_libdir)" \
  124. --datadir="${GAMES_DATADIR}" \
  125. --sysconfdir="${GAMES_SYSCONFDIR}" \
  126. --localstatedir="${GAMES_STATEDIR}" \
  127. ${_gamesconf} \
  128. "$@"
  129. }
  130. # @FUNCTION: gameswrapper
  131. # @USAGE: <command> [<args>...]
  132. # @INTERNAL
  133. # @DESCRIPTION:
  134. # Wraps an install command like dobin, dolib etc, so that
  135. # it has GAMES_PREFIX as prefix.
  136. gameswrapper() {
  137. # dont want to pollute calling env
  138. (
  139. into "${GAMES_PREFIX}"
  140. cmd=$1
  141. shift
  142. ${cmd} "$@"
  143. )
  144. }
  145. # @FUNCTION: dogamesbin
  146. # @USAGE: <path>...
  147. # @DESCRIPTION:
  148. # Install one or more games binaries.
  149. dogamesbin() { gameswrapper ${FUNCNAME/games} "$@"; }
  150. # @FUNCTION: dogamessbin
  151. # @USAGE: <path>...
  152. # @DESCRIPTION:
  153. # Install one or more games system binaries.
  154. dogamessbin() { gameswrapper ${FUNCNAME/games} "$@"; }
  155. # @FUNCTION: dogameslib
  156. # @USAGE: <path>...
  157. # @DESCRIPTION:
  158. # Install one or more games libraries.
  159. dogameslib() { gameswrapper ${FUNCNAME/games} "$@"; }
  160. # @FUNCTION: dogameslib.a
  161. # @USAGE: <path>...
  162. # @DESCRIPTION:
  163. # Install one or more static games libraries.
  164. dogameslib.a() { gameswrapper ${FUNCNAME/games} "$@"; }
  165. # @FUNCTION: dogameslib.so
  166. # @USAGE: <path>...
  167. # @DESCRIPTION:
  168. # Install one or more shared games libraries.
  169. dogameslib.so() { gameswrapper ${FUNCNAME/games} "$@"; }
  170. # @FUNCTION: newgamesbin
  171. # @USAGE: <path> <newname>
  172. # @DESCRIPTION:
  173. # Install one games binary with a new name.
  174. newgamesbin() { gameswrapper ${FUNCNAME/games} "$@"; }
  175. # @FUNCTION: newgamessbin
  176. # @USAGE: <path> <newname>
  177. # @DESCRIPTION:
  178. # Install one system games binary with a new name.
  179. newgamessbin() { gameswrapper ${FUNCNAME/games} "$@"; }
  180. # @FUNCTION: games_make_wrapper
  181. # @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
  182. # @DESCRIPTION:
  183. # Create a shell wrapper script named wrapper in installpath
  184. # (defaults to the games bindir) to execute target (default of wrapper) by
  185. # first optionally setting LD_LIBRARY_PATH to the colon-delimited
  186. # libpaths followed by optionally changing directory to chdir.
  187. games_make_wrapper() { gameswrapper ${FUNCNAME/games_} "$@"; }
  188. # @FUNCTION: gamesowners
  189. # @USAGE: [<args excluding owner/group>...] <path>...
  190. # @DESCRIPTION:
  191. # Run 'chown' with the given args on the given files. Owner and
  192. # group are GAMES_USER and GAMES_GROUP and must not be passed
  193. # as args.
  194. gamesowners() { chown ${GAMES_USER}:${GAMES_GROUP} "$@"; }
  195. # @FUNCTION: gamesperms
  196. # @USAGE: <path>...
  197. # @DESCRIPTION:
  198. # Run 'chmod' with games specific permissions on the given files.
  199. gamesperms() { chmod u+rw,g+r-w,o-rwx "$@"; }
  200. # @FUNCTION: prepgamesdirs
  201. # @DESCRIPTION:
  202. # Fix all permissions/owners of files in games related directories,
  203. # usually called at the end of src_install().
  204. prepgamesdirs() {
  205. local dir f mode
  206. for dir in \
  207. "${GAMES_PREFIX}" "${GAMES_PREFIX_OPT}" "${GAMES_DATADIR}" \
  208. "${GAMES_SYSCONFDIR}" "${GAMES_STATEDIR}" "$(games_get_libdir)" \
  209. "${GAMES_BINDIR}" "$@"
  210. do
  211. [[ ! -d ${D}/${dir} ]] && continue
  212. (
  213. gamesowners -R "${D}/${dir}"
  214. find "${D}/${dir}" -type d -print0 | xargs -0 chmod 750
  215. mode=o-rwx,g+r,g-w
  216. [[ ${dir} = ${GAMES_STATEDIR} ]] && mode=o-rwx,g+r
  217. find "${D}/${dir}" -type f -print0 | xargs -0 chmod $mode
  218. # common trees should not be games owned #264872 #537580
  219. fowners root:0 "${dir}"
  220. fperms 755 "${dir}"
  221. if [[ ${dir} == "${GAMES_PREFIX}" \
  222. || ${dir} == "${GAMES_PREFIX_OPT}" ]] ; then
  223. for d in $(get_libdir) bin ; do
  224. # check if dirs exist to avoid "nonfatal" option
  225. if [[ -e ${D}/${dir}/${d} ]] ; then
  226. fowners root:0 "${dir}/${d}"
  227. fperms 755 "${dir}/${d}"
  228. fi
  229. done
  230. fi
  231. ) &>/dev/null
  232. f=$(find "${D}/${dir}" -perm +4000 -a -uid 0 2>/dev/null)
  233. if [[ -n ${f} ]] ; then
  234. eerror "A game was detected that is setuid root!"
  235. eerror "${f}"
  236. die "refusing to merge a setuid root game"
  237. fi
  238. done
  239. [[ -d ${D}/${GAMES_BINDIR} ]] || return 0
  240. find "${D}/${GAMES_BINDIR}" -maxdepth 1 -type f -exec chmod 750 '{}' \;
  241. }
  242. # @FUNCTION: games_pkg_setup
  243. # @DESCRIPTION:
  244. # Export some toolchain specific variables and create games related groups
  245. # and users. This function is exported as pkg_setup().
  246. games_pkg_setup() {
  247. tc-export CC CXX LD AR RANLIB
  248. enewgroup "${GAMES_GROUP}" 35
  249. [[ ${GAMES_USER} != "root" ]] \
  250. && enewuser "${GAMES_USER}" 35 -1 "${GAMES_PREFIX}" "${GAMES_GROUP}"
  251. [[ ${GAMES_USER_DED} != "root" ]] \
  252. && enewuser "${GAMES_USER_DED}" 36 /bin/bash "${GAMES_PREFIX}" "${GAMES_GROUP}"
  253. # Dear portage team, we are so sorry. Lots of love, games team.
  254. # See Bug #61680
  255. [[ ${USERLAND} != "GNU" ]] && return 0
  256. [[ $(egetshell "${GAMES_USER_DED}") == "/bin/false" ]] \
  257. && usermod -s /bin/bash "${GAMES_USER_DED}"
  258. }
  259. # @FUNCTION: games_src_configure
  260. # @DESCRIPTION:
  261. # Runs egamesconf if there is a configure file.
  262. # This function is exported as src_configure().
  263. games_src_configure() {
  264. [[ -x "${ECONF_SOURCE:-.}"/configure ]] && egamesconf
  265. }
  266. # @FUNCTION: games_src_compile
  267. # @DESCRIPTION:
  268. # Runs base_src_make(). This function is exported as src_compile().
  269. games_src_compile() {
  270. case ${EAPI:-0} in
  271. 0|1) games_src_configure ;;
  272. esac
  273. base_src_make
  274. }
  275. # @FUNCTION: games_pkg_preinst
  276. # @DESCRIPTION:
  277. # Synchronizes GAMES_STATEDIR of the ebuild image with the live filesystem.
  278. games_pkg_preinst() {
  279. local f
  280. while read f ; do
  281. if [[ -e ${ROOT}/${GAMES_STATEDIR}/${f} ]] ; then
  282. cp -p \
  283. "${ROOT}/${GAMES_STATEDIR}/${f}" \
  284. "${D}/${GAMES_STATEDIR}/${f}" \
  285. || die "cp failed"
  286. # make the date match the rest of the install
  287. touch "${D}/${GAMES_STATEDIR}/${f}"
  288. fi
  289. done < <(find "${D}/${GAMES_STATEDIR}" -type f -printf '%P\n' 2>/dev/null)
  290. }
  291. # @FUNCTION: games_pkg_postinst
  292. # @DESCRIPTION:
  293. # Prints some warnings and infos, also related to games groups.
  294. games_pkg_postinst() {
  295. if [[ -z "${GAMES_SHOW_WARNING}" ]] ; then
  296. ewarn "Remember, in order to play games, you have to"
  297. ewarn "be in the '${GAMES_GROUP}' group."
  298. echo
  299. case ${CHOST} in
  300. *-darwin*) ewarn "Just run 'niutil -appendprop / /groups/games users <USER>'";;
  301. *-freebsd*|*-dragonfly*) ewarn "Just run 'pw groupmod ${GAMES_GROUP} -m <USER>'";;
  302. *) ewarn "Just run 'gpasswd -a <USER> ${GAMES_GROUP}', then have <USER> re-login.";;
  303. esac
  304. echo
  305. einfo "For more info about Gentoo gaming in general, see our website:"
  306. einfo " https://games.gentoo.org/"
  307. echo
  308. fi
  309. }
  310. # @FUNCTION: games_ut_unpack
  311. # @USAGE: <directory or file to unpack>
  312. # @DESCRIPTION:
  313. # Unpack .uz2 files for UT2003/UT2004.
  314. games_ut_unpack() {
  315. local ut_unpack="$1"
  316. local f=
  317. if [[ -z ${ut_unpack} ]] ; then
  318. die "You must provide an argument to games_ut_unpack"
  319. fi
  320. if [[ -f ${ut_unpack} ]] ; then
  321. uz2unpack "${ut_unpack}" "${ut_unpack%.uz2}" \
  322. || die "uncompressing file ${ut_unpack}"
  323. fi
  324. if [[ -d ${ut_unpack} ]] ; then
  325. while read f ; do
  326. uz2unpack "${ut_unpack}/${f}" "${ut_unpack}/${f%.uz2}" \
  327. || die "uncompressing file ${f}"
  328. rm -f "${ut_unpack}/${f}" || die "deleting compressed file ${f}"
  329. done < <(find "${ut_unpack}" -maxdepth 1 -name '*.uz2' -printf '%f\n' 2>/dev/null)
  330. fi
  331. }
  332. # @FUNCTION: games_umod_unpack
  333. # @USAGE: <file to unpack>
  334. # @DESCRIPTION:
  335. # Unpacks .umod/.ut2mod/.ut4mod files for UT/UT2003/UT2004.
  336. # Don't forget to set 'dir' and 'Ddir'.
  337. games_umod_unpack() {
  338. local umod=$1
  339. mkdir -p "${Ddir}"/System
  340. cp "${dir}"/System/{ucc-bin,{Manifest,Def{ault,User}}.ini,{Engine,Core,zlib,ogg,vorbis}.so,{Engine,Core}.int} "${Ddir}"/System
  341. cd "${Ddir}"/System
  342. UT_DATA_PATH=${Ddir}/System ./ucc-bin umodunpack -x "${S}/${umod}" -nohomedir &> /dev/null \
  343. || die "uncompressing file ${umod}"
  344. rm -f "${Ddir}"/System/{ucc-bin,{Manifest,Def{ault,User},User,UT200{3,4}}.ini,{Engine,Core,zlib,ogg,vorbis}.so,{Engine,Core}.int,ucc.log} &>/dev/null \
  345. || die "Removing temporary files"
  346. }
  347. fi