1 # Copyright 1999-2015 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
4 # @ECLASS: games.eclass
6 # Games team <games@gentoo.org>
7 # @SUPPORTED_EAPIS: 0 1 2 3 4 5
8 # @BLURB: Standardizing the install of games.
10 # This eclass makes sure that games are consistently handled in gentoo.
11 # It installs game files by default in FHS-compatible directories
12 # like /usr/share/games and sets more restrictive permissions in order
13 # to avoid some security bugs.
15 # The installation directories as well as the user and group files are
16 # installed as can be controlled by the user. See the variables like
17 # GAMES_BINDIR, GAMES_USER etc. below. These are NOT supposed to be set
20 # For a general guide on writing games ebuilds, see:
21 # https://wiki.gentoo.org/wiki/Project:Games/Ebuild_howto
23 # WARNING: This eclass is DEPRECATED and must not be used by new games
24 # ebuilds, bug #574082. When writing game ebuilds, no specific eclass
25 # is needed. For more details, see the QA team policies page:
26 # https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Policies#Games
29 if [[ -z ${_GAMES_ECLASS} ]]; then
32 inherit base multilib toolchain-funcs eutils user
35 0|1) EXPORT_FUNCTIONS pkg_setup src_compile pkg_preinst pkg_postinst ;;
36 2|3|4|5) EXPORT_FUNCTIONS pkg_setup src_configure src_compile pkg_preinst pkg_postinst ;;
37 *) die "games.eclass is banned in EAPI=${EAPI}, see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Policies#Games" ;;
40 if [[ ${CATEGORY}/${PN} != "games-misc/games-envd" ]] ; then
42 RDEPEND="games-misc/games-envd"
45 # @ECLASS-VARIABLE: GAMES_PREFIX
47 # Prefix where to install games, mostly used by GAMES_BINDIR. Games data should
48 # still go into GAMES_DATADIR. May be set by the user.
49 GAMES_PREFIX=${GAMES_PREFIX:-/usr/games}
51 # @ECLASS-VARIABLE: GAMES_PREFIX_OPT
53 # Prefix where to install precompiled/blob games, usually followed by
54 # package name. May be set by the user.
55 GAMES_PREFIX_OPT=${GAMES_PREFIX_OPT:-/opt}
57 # @ECLASS-VARIABLE: GAMES_DATADIR
59 # Base directory where to install game data files, usually followed by
60 # package name. May be set by the user.
61 GAMES_DATADIR=${GAMES_DATADIR:-/usr/share/games}
63 # @ECLASS-VARIABLE: GAMES_DATADIR_BASE
65 # Similar to GAMES_DATADIR, but only used when a package auto appends 'games'
66 # to the path. May be set by the user.
67 GAMES_DATADIR_BASE=${GAMES_DATADIR_BASE:-/usr/share}
69 # @ECLASS-VARIABLE: GAMES_SYSCONFDIR
71 # Where to install global games configuration files, usually followed by
72 # package name. May be set by the user.
73 GAMES_SYSCONFDIR=${GAMES_SYSCONFDIR:-/etc/games}
75 # @ECLASS-VARIABLE: GAMES_STATEDIR
77 # Where to install/store global variable game data, usually followed by
78 # package name. May be set by the user.
79 GAMES_STATEDIR=${GAMES_STATEDIR:-/var/games}
81 # @ECLASS-VARIABLE: GAMES_LOGDIR
83 # Where to store global game log files, usually followed by
84 # package name. May be set by the user.
85 GAMES_LOGDIR=${GAMES_LOGDIR:-/var/log/games}
87 # @ECLASS-VARIABLE: GAMES_BINDIR
89 # Where to install the game binaries. May be set by the user. This is in PATH.
90 GAMES_BINDIR=${GAMES_BINDIR:-${GAMES_PREFIX}/bin}
92 # @ECLASS-VARIABLE: GAMES_ENVD
95 # The games environment file name which sets games specific LDPATH and PATH.
98 # @ECLASS-VARIABLE: GAMES_USER
100 # The USER who owns all game files and usually has write permissions.
101 # May be set by the user.
102 GAMES_USER=${GAMES_USER:-root}
104 # @ECLASS-VARIABLE: GAMES_USER_DED
106 # The USER who owns all game files related to the dedicated server part
107 # of a package. May be set by the user.
108 GAMES_USER_DED=${GAMES_USER_DED:-games}
110 # @ECLASS-VARIABLE: GAMES_GROUP
112 # The GROUP that owns all game files and usually does not have
113 # write permissions. May be set by the user.
114 # If you want games world-executable, then you can at least set this variable
115 # to 'users' which is almost the same.
116 GAMES_GROUP=${GAMES_GROUP:-games}
118 # @FUNCTION: games_get_libdir
120 # Gets the directory where to install games libraries. This is in LDPATH.
122 echo ${GAMES_PREFIX}/$(get_libdir)
125 # @FUNCTION: egamesconf
126 # @USAGE: [<args>...]
128 # Games equivalent to 'econf' for autotools based build systems. It passes
129 # the necessary games specific directories automatically.
131 # handle verbose build log pre-EAPI5
133 if has "${EAPI:-0}" 0 1 2 3 4 ; then
134 if grep -q -s disable-silent-rules "${ECONF_SOURCE:-.}"/configure ; then
135 _gamesconf="--disable-silent-rules"
140 if grep -q -s datarootdir "${ECONF_SOURCE:-.}"/configure ; then
141 _gamesconf="${_gamesconf} --datarootdir=/usr/share"
145 --prefix="${GAMES_PREFIX}" \
146 --libdir="$(games_get_libdir)" \
147 --datadir="${GAMES_DATADIR}" \
148 --sysconfdir="${GAMES_SYSCONFDIR}" \
149 --localstatedir="${GAMES_STATEDIR}" \
154 # @FUNCTION: gameswrapper
155 # @USAGE: <command> [<args>...]
158 # Wraps an install command like dobin, dolib etc, so that
159 # it has GAMES_PREFIX as prefix.
161 # dont want to pollute calling env
163 into "${GAMES_PREFIX}"
170 # @FUNCTION: dogamesbin
173 # Install one or more games binaries.
174 dogamesbin() { gameswrapper ${FUNCNAME/games} "$@"; }
176 # @FUNCTION: dogamessbin
179 # Install one or more games system binaries.
180 dogamessbin() { gameswrapper ${FUNCNAME/games} "$@"; }
182 # @FUNCTION: dogameslib
185 # Install one or more games libraries.
186 dogameslib() { gameswrapper ${FUNCNAME/games} "$@"; }
188 # @FUNCTION: dogameslib.a
191 # Install one or more static games libraries.
192 dogameslib.a() { gameswrapper ${FUNCNAME/games} "$@"; }
194 # @FUNCTION: dogameslib.so
197 # Install one or more shared games libraries.
198 dogameslib.so() { gameswrapper ${FUNCNAME/games} "$@"; }
200 # @FUNCTION: newgamesbin
201 # @USAGE: <path> <newname>
203 # Install one games binary with a new name.
204 newgamesbin() { gameswrapper ${FUNCNAME/games} "$@"; }
206 # @FUNCTION: newgamessbin
207 # @USAGE: <path> <newname>
209 # Install one system games binary with a new name.
210 newgamessbin() { gameswrapper ${FUNCNAME/games} "$@"; }
212 # @FUNCTION: games_make_wrapper
213 # @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
215 # Create a shell wrapper script named wrapper in installpath
216 # (defaults to the games bindir) to execute target (default of wrapper) by
217 # first optionally setting LD_LIBRARY_PATH to the colon-delimited
218 # libpaths followed by optionally changing directory to chdir.
219 games_make_wrapper() { gameswrapper ${FUNCNAME/games_} "$@"; }
221 # @FUNCTION: gamesowners
222 # @USAGE: [<args excluding owner/group>...] <path>...
224 # Run 'chown' with the given args on the given files. Owner and
225 # group are GAMES_USER and GAMES_GROUP and must not be passed
227 gamesowners() { chown ${GAMES_USER}:${GAMES_GROUP} "$@"; }
229 # @FUNCTION: gamesperms
232 # Run 'chmod' with games specific permissions on the given files.
233 gamesperms() { chmod u+rw,g+r-w,o-rwx "$@"; }
235 # @FUNCTION: prepgamesdirs
237 # Fix all permissions/owners of files in games related directories,
238 # usually called at the end of src_install().
242 "${GAMES_PREFIX}" "${GAMES_PREFIX_OPT}" "${GAMES_DATADIR}" \
243 "${GAMES_SYSCONFDIR}" "${GAMES_STATEDIR}" "$(games_get_libdir)" \
244 "${GAMES_BINDIR}" "$@"
246 [[ ! -d ${D}/${dir} ]] && continue
248 gamesowners -R "${D}/${dir}"
249 find "${D}/${dir}" -type d -print0 | xargs -0 chmod 750
251 [[ ${dir} = ${GAMES_STATEDIR} ]] && mode=o-rwx,g+r
252 find "${D}/${dir}" -type f -print0 | xargs -0 chmod $mode
254 # common trees should not be games owned #264872 #537580
255 fowners root:0 "${dir}"
257 if [[ ${dir} == "${GAMES_PREFIX}" \
258 || ${dir} == "${GAMES_PREFIX_OPT}" ]] ; then
259 for d in $(get_libdir) bin ; do
260 # check if dirs exist to avoid "nonfatal" option
261 if [[ -e ${D}/${dir}/${d} ]] ; then
262 fowners root:0 "${dir}/${d}"
263 fperms 755 "${dir}/${d}"
269 f=$(find "${D}/${dir}" -perm +4000 -a -uid 0 2>/dev/null)
270 if [[ -n ${f} ]] ; then
271 eerror "A game was detected that is setuid root!"
273 die "refusing to merge a setuid root game"
276 [[ -d ${D}/${GAMES_BINDIR} ]] || return 0
277 find "${D}/${GAMES_BINDIR}" -maxdepth 1 -type f -exec chmod 750 '{}' \;
280 # @FUNCTION: games_pkg_setup
282 # Export some toolchain specific variables and create games related groups
283 # and users. This function is exported as pkg_setup().
285 tc-export CC CXX LD AR RANLIB
287 enewgroup "${GAMES_GROUP}" 35
288 [[ ${GAMES_USER} != "root" ]] \
289 && enewuser "${GAMES_USER}" 35 -1 "${GAMES_PREFIX}" "${GAMES_GROUP}"
290 [[ ${GAMES_USER_DED} != "root" ]] \
291 && enewuser "${GAMES_USER_DED}" 36 /bin/bash "${GAMES_PREFIX}" "${GAMES_GROUP}"
293 # Dear portage team, we are so sorry. Lots of love, games team.
295 [[ ${USERLAND} != "GNU" ]] && return 0
296 [[ $(egetshell "${GAMES_USER_DED}") == "/bin/false" ]] \
297 && usermod -s /bin/bash "${GAMES_USER_DED}"
300 # @FUNCTION: games_src_configure
302 # Runs egamesconf if there is a configure file.
303 # This function is exported as src_configure().
304 games_src_configure() {
305 [[ -x "${ECONF_SOURCE:-.}"/configure ]] && egamesconf
308 # @FUNCTION: games_src_compile
310 # Runs base_src_make(). This function is exported as src_compile().
311 games_src_compile() {
313 0|1) games_src_configure ;;
318 # @FUNCTION: games_pkg_preinst
320 # Synchronizes GAMES_STATEDIR of the ebuild image with the live filesystem.
321 games_pkg_preinst() {
325 if [[ -e ${ROOT}/${GAMES_STATEDIR}/${f} ]] ; then
327 "${ROOT}/${GAMES_STATEDIR}/${f}" \
328 "${D}/${GAMES_STATEDIR}/${f}" \
330 # make the date match the rest of the install
331 touch "${D}/${GAMES_STATEDIR}/${f}"
333 done < <(find "${D}/${GAMES_STATEDIR}" -type f -printf '%P\n' 2>/dev/null)
336 # @FUNCTION: games_pkg_postinst
338 # Prints some warnings and infos, also related to games groups.
339 games_pkg_postinst() {
340 if [[ -z "${GAMES_SHOW_WARNING}" ]] ; then
341 ewarn "Remember, in order to play games, you have to"
342 ewarn "be in the '${GAMES_GROUP}' group."
345 *-darwin*) ewarn "Just run 'niutil -appendprop / /groups/games users <USER>'";;
346 *-freebsd*|*-dragonfly*) ewarn "Just run 'pw groupmod ${GAMES_GROUP} -m <USER>'";;
347 *) ewarn "Just run 'gpasswd -a <USER> ${GAMES_GROUP}', then have <USER> re-login.";;
350 einfo "For more info about Gentoo gaming in general, see our website:"
351 einfo " https://games.gentoo.org/"
356 # @FUNCTION: games_ut_unpack
357 # @USAGE: <directory or file to unpack>
359 # Unpack .uz2 files for UT2003/UT2004.
364 if [[ -z ${ut_unpack} ]] ; then
365 die "You must provide an argument to games_ut_unpack"
367 if [[ -f ${ut_unpack} ]] ; then
368 uz2unpack "${ut_unpack}" "${ut_unpack%.uz2}" \
369 || die "uncompressing file ${ut_unpack}"
371 if [[ -d ${ut_unpack} ]] ; then
373 uz2unpack "${ut_unpack}/${f}" "${ut_unpack}/${f%.uz2}" \
374 || die "uncompressing file ${f}"
375 rm -f "${ut_unpack}/${f}" || die "deleting compressed file ${f}"
376 done < <(find "${ut_unpack}" -maxdepth 1 -name '*.uz2' -printf '%f\n' 2>/dev/null)
380 # @FUNCTION: games_umod_unpack
381 # @USAGE: <file to unpack>
383 # Unpacks .umod/.ut2mod/.ut4mod files for UT/UT2003/UT2004.
384 # Don't forget to set 'dir' and 'Ddir'.
385 games_umod_unpack() {
387 mkdir -p "${Ddir}"/System
388 cp "${dir}"/System/{ucc-bin,{Manifest,Def{ault,User}}.ini,{Engine,Core,zlib,ogg,vorbis}.so,{Engine,Core}.int} "${Ddir}"/System
390 UT_DATA_PATH=${Ddir}/System ./ucc-bin umodunpack -x "${S}/${umod}" -nohomedir &> /dev/null \
391 || die "uncompressing file ${umod}"
392 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 \
393 || die "Removing temporary files"