logo

overlay

My own overlay for experimentations, use with caution, no support is provided git clone https://hacktivis.me/git/overlay.git

games.eclass (12562B)


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