--- eclass/eutils.eclass 2003/11/30 11:22:32 1.70 +++ eclass/eutils.eclass 2005/01/12 00:21:53 1.141 @@ -1,6 +1,6 @@ -# Copyright 1999-2003 Gentoo Technologies, Inc. +# Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.70 2003/11/30 11:22:32 vapier Exp $ +# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.141 2005/01/12 00:21:53 eradicator Exp $ # # Author: Martin Schlemmer # @@ -9,13 +9,41 @@ # # NB: If you add anything, please comment it! +inherit multilib ECLASS=eutils INHERITED="$INHERITED $ECLASS" -newdepend "!bootstrap? ( sys-devel/patch )" +DEPEND="!bootstrap? ( sys-devel/patch )" DESCRIPTION="Based on the ${ECLASS} eclass" +# Wait for the supplied number of seconds. If no argument is supplied, defaults +# to five seconds. If the EPAUSE_IGNORE env var is set, don't wait. If we're not +# outputting to a terminal, don't wait. For compatability purposes, the argument +# must be an integer greater than zero. +# Bug 62950, Ciaran McCreesh (05 Sep 2004) +epause() { + if [ -z "$EPAUSE_IGNORE" ] && [ -t 1 ] ; then + sleep ${1:-5} + fi +} + +# Beep the specified number of times (defaults to five). If our output +# is not a terminal, don't beep. If the EBEEP_IGNORE env var is set, +# don't beep. +# Bug 62950, Ciaran McCreesh (05 Sep 2004) +ebeep() { + local n + if [ -z "$EBEEP_IGNORE" ] && [ -t 1 ] ; then + for ((n=1 ; n <= ${1:-5} ; n++)) ; do + echo -ne "\a" + sleep 0.1 &>/dev/null ; sleep 0,1 &>/dev/null + echo -ne "\a" + sleep 1 + done + fi +} + # This function generate linker scripts in /usr/lib for dynamic # libs in /lib. This is to fix linking problems when you have # the .so in /lib, and the .a in /usr/lib. What happens is that @@ -35,11 +63,11 @@ # (26 Oct 2002) # gen_usr_ldscript() { - + local libdir="$(get_libdir)" # Just make sure it exists - dodir /usr/lib + dodir /usr/${libdir} - cat > ${D}/usr/lib/$1 <<"END_LDSCRIPT" + cat > "${D}/usr/${libdir}/${1}" << END_LDSCRIPT /* GNU ld script Because Gentoo have critical dynamic libraries in /lib, and the static versions in /usr/lib, we @@ -47,12 +75,9 @@ otherwise we run into linking problems. See bug #4411 on http://bugs.gentoo.org/ for more info. */ -GROUP ( /lib/libxxx ) +GROUP ( /${libdir}/${1} ) END_LDSCRIPT - - dosed "s:libxxx:$1:" /usr/lib/$1 - - return 0 + fperms a+x "/usr/${libdir}/${1}" } # Simple function to draw a line consisting of '=' the same length as $* @@ -146,8 +171,12 @@ if [ "$#" -gt 1 ] then - eerror "Invalid arguments to epatch()" - die "Invalid arguments to epatch()" + local m="" + einfo "${#} patches to apply ..." + for m in "$@" ; do + epatch "${m}" + done + return 0 fi if [ -n "$1" -a -f "$1" ] @@ -167,7 +196,7 @@ local EPATCH_SOURCE="$1/*.${EPATCH_SUFFIX}" fi else - if [ ! -d ${EPATCH_SOURCE} ] + if [ ! -d ${EPATCH_SOURCE} ] || [ -n "$1" ] then if [ -n "$1" -a "${EPATCH_SOURCE}" = "${WORKDIR}/patch" ] then @@ -178,6 +207,7 @@ eerror "Cannot find \$EPATCH_SOURCE! Value for \$EPATCH_SOURCE is:" eerror eerror " ${EPATCH_SOURCE}" + eerror " ( ${EPATCH_SOURCE##*/} )" echo die "Cannot find \$EPATCH_SOURCE!" fi @@ -206,11 +236,11 @@ if [ "${SINGLE_PATCH}" = "no" ] then - einfo "Applying various patches (bugfixes/updates)..." + einfo "Applying various patches (bugfixes/updates) ..." fi for x in ${EPATCH_SOURCE} do - # New ARCH dependant patch naming scheme... + # New ARCH dependant patch naming scheme ... # # ???_arch_foo.patch # @@ -235,10 +265,10 @@ then einfo "${EPATCH_SINGLE_MSG}" else - einfo "Applying ${x##*/}..." + einfo "Applying ${x##*/} ..." fi else - einfo " ${x##*/}..." + einfo " ${x##*/} ..." fi echo "***** ${x##*/} *****" > ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/} @@ -260,7 +290,7 @@ fi echo -n "PATCH COMMAND: " >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/} - echo "patch ${popts} -p${count} < ${PATCH_TARGET}" >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/} + echo "patch -p${count} ${popts} < ${PATCH_TARGET}" >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/} echo >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/} draw_line "***** ${x##*/} *****" >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/} @@ -277,15 +307,15 @@ fi fi - if (cat ${PATCH_TARGET} | patch ${popts} --dry-run -f -p${count}) >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/} 2>&1 + if (cat ${PATCH_TARGET} | patch -p${count} ${popts} --dry-run -f) >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/} 2>&1 then draw_line "***** ${x##*/} *****" > ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/}.real echo >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/}.real - echo "ACTUALLY APPLYING ${x##*/}..." >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/}.real + echo "ACTUALLY APPLYING ${x##*/} ..." >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/}.real echo >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/}.real draw_line "***** ${x##*/} *****" >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/}.real - cat ${PATCH_TARGET} | patch ${popts} -p${count} >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/}.real 2>&1 + cat ${PATCH_TARGET} | patch -p${count} ${popts} >> ${STDERR_TARGET%/*}/${x##*/}-${STDERR_TARGET##*/}.real 2>&1 if [ "$?" -ne 0 ] then @@ -338,9 +368,7 @@ # # (06 March 2003) # - have_NPTL() { - cat > ${T}/test-nptl.c <<-"END" #define _XOPEN_SOURCE #include @@ -362,11 +390,11 @@ } END - einfon "Checking for _CS_GNU_LIBPTHREAD_VERSION support in glibc ... " + einfon "Checking for _CS_GNU_LIBPTHREAD_VERSION support in glibc ..." if gcc -o ${T}/nptl ${T}/test-nptl.c &> /dev/null then echo "yes" - einfon "Checking what PTHREADS implementation we have ... " + einfon "Checking what PTHREADS implementation we have ..." if ${T}/nptl then return 0 @@ -424,7 +452,7 @@ jobs=2 fi - elif [ "${ARCH}" = "ppc" ] + elif [ "${ARCH}" = "ppc" -o "${ARCH}" = "ppc64" ] then # ppc has "processor", but only when compiled with SMP if [ "`grep -c "^processor" /proc/cpuinfo`" -eq 1 ] @@ -433,6 +461,10 @@ else jobs=2 fi + elif [ "${ARCH}" = "s390" ] + then + # s390 has "# processors : " + jobs="$((`grep "^\# processors" /proc/cpuinfo | sed -e "s/^.*: //"` * 2))" else jobs="$((`grep -c ^cpu /proc/cpuinfo` * 2))" die "Unknown ARCH -- ${ARCH}!" @@ -448,31 +480,76 @@ then if [ "${jobs}" -gt "${ADMINPARAM}" ] then - einfo "Setting make jobs to \"-j${ADMINPARAM}\" to ensure successful merge..." + einfo "Setting make jobs to \"-j${ADMINPARAM}\" to ensure successful merge ..." export MAKEOPTS="${MAKEOPTS} -j${ADMINPARAM}" else - einfo "Setting make jobs to \"-j${jobs}\" to ensure successful merge..." + einfo "Setting make jobs to \"-j${jobs}\" to ensure successful merge ..." export MAKEOPTS="${MAKEOPTS} -j${jobs}" fi fi } # Cheap replacement for when debianutils (and thus mktemp) -# do not exist on the users system +# does not exist on the users system # vapier@gentoo.org # -# Takes just 1 parameter (the directory to create tmpfile in) -mymktemp() { +# Takes just 1 optional parameter (the directory to create tmpfile in) +emktemp() { + local exe="touch" + [ "$1" == "-d" ] && exe="mkdir" && shift local topdir="$1" - - [ -z "${topdir}" ] && topdir=/tmp - if [ "`which mktemp 2>/dev/null`" ] + + if [ -z "${topdir}" ] then - mktemp -p ${topdir} + [ -z "${T}" ] \ + && topdir="/tmp" \ + || topdir="${T}" + fi + + if [ -z "$(type -p mktemp)" ] + then + local tmp=/ + while [ -e "${tmp}" ] ; do + tmp="${topdir}/tmp.${RANDOM}.${RANDOM}.${RANDOM}" + done + ${exe} "${tmp}" + echo "${tmp}" + else + [ "${exe}" == "touch" ] \ + && exe="-p" \ + || exe="-d" + mktemp ${exe} "${topdir}" + fi +} + +# Small wrapper for getent (Linux), nidump (Mac OS X), +# and pw (FreeBSD) used in enewuser()/enewgroup() +# Joe Jezak and usata@gentoo.org +# FBSD stuff: Aaron Walker +# +# egetent(database, key) +egetent() { + if useq ppc-macos ; then + case "$2" in + *[!0-9]*) # Non numeric + nidump $1 . | awk -F":" "{ if (\$1 ~ /^$2$/) {print \$0;exit;} }" + ;; + *) # Numeric + nidump $1 . | awk -F":" "{ if (\$3 == $2) {print \$0;exit;} }" + ;; + esac + elif useq x86-fbsd ; then + local action + if [ "$1" == "passwd" ] + then + action="user" + else + action="group" + fi + pw show "${action}" "$2" -q else - local tmp="${topdir}/tmp.${RANDOM}.${RANDOM}.${RANDOM}" - touch ${tmp} - echo ${tmp} + which nscd >& /dev/null && nscd -i "$1" + getent "$1" "$2" fi } @@ -498,13 +575,8 @@ die "Cannot call enewuser without a username" fi - # setup a file for testing usernames/groups - local tmpfile="`mymktemp ${T}`" - chown ${euser} ${tmpfile} >& /dev/null - local realuser="`ls -l ${tmpfile} | awk '{print $3}'`" - - # see if user already exists - if [ "${euser}" == "${realuser}" ] + # lets see if the username already exists + if [ "${euser}" == "`egetent passwd \"${euser}\" | cut -d: -f1`" ] then return 0 fi @@ -519,14 +591,30 @@ then if [ "${euid}" -gt 0 ] then - opts="${opts} -u ${euid}" + if [ ! -z "`egetent passwd ${euid}`" ] + then + euid="next" + fi else eerror "Userid given but is not greater than 0 !" die "${euid} is not a valid UID" fi else - euid="next available" + euid="next" + fi + if [ "${euid}" == "next" ] + then + local pwrange + if [ "${USERLAND}" == "BSD" ] ; then + pwrange="`jot 898 101`" + else + pwrange="`seq 101 999`" + fi + for euid in ${pwrange} ; do + [ -z "`egetent passwd ${euid}`" ] && break + done fi + opts="${opts} -u ${euid}" einfo " - Userid: ${euid}" # handle shell @@ -539,7 +627,12 @@ die "${eshell} does not exist" fi else - eshell="/bin/false" + if [ "${USERLAND}" == "BSD" ] + then + eshell="/usr/bin/false" + else + eshell="/bin/false" + fi fi einfo " - Shell: ${eshell}" opts="${opts} -s ${eshell}" @@ -557,21 +650,33 @@ local egroups="$1"; shift if [ ! -z "${egroups}" ] then - local realgroup= local oldifs="${IFS}" + local defgroup="" exgroups="" + export IFS="," for g in ${egroups} do - chgrp ${g} ${tmpfile} >& /dev/null - realgroup="`ls -l ${tmpfile} | awk '{print $4}'`" - if [ "${g}" != "${realgroup}" ] + export IFS="${oldifs}" + if [ -z "`egetent group \"${g}\"`" ] then - eerror "You must add ${g} to the system first" + eerror "You must add group ${g} to the system first" die "${g} is not a valid GID" fi + if [ -z "${defgroup}" ] + then + defgroup="${g}" + else + exgroups="${exgroups},${g}" + fi + export IFS="," done export IFS="${oldifs}" - opts="${opts} -g ${egroups}" + + opts="${opts} -g ${defgroup}" + if [ ! -z "${exgroups}" ] + then + opts="${opts} -G ${exgroups:1}" + fi else egroups="(none)" fi @@ -581,15 +686,51 @@ local eextra="$@" local oldsandbox="${SANDBOX_ON}" export SANDBOX_ON="0" - if [ -z "${eextra}" ] + if useq ppc-macos then - useradd ${opts} ${euser} \ - -c "added by portage for ${PN}" \ - || die "enewuser failed" + ### Make the user + if [ -z "${eextra}" ] + then + dscl . create /users/${euser} uid ${euid} + dscl . create /users/${euser} shell ${eshell} + dscl . create /users/${euser} home ${ehome} + dscl . create /users/${euser} realname "added by portage for ${PN}" + ### Add the user to the groups specified + local oldifs="${IFS}" + export IFS="," + for g in ${egroups} + do + dscl . merge /groups/${g} users ${euser} + done + export IFS="${oldifs}" + else + einfo "Extra options are not supported on macos yet" + einfo "Please report the ebuild along with the info below" + einfo "eextra: ${eextra}" + die "Required function missing" + fi + elif use x86-fbsd ; then + if [ -z "${eextra}" ] + then + pw useradd ${euser} ${opts} \ + -c "added by portage for ${PN}" \ + die "enewuser failed" + else + einfo " - Extra: ${eextra}" + pw useradd ${euser} ${opts} \ + -c ${eextra} || die "enewuser failed" + fi else - einfo " - Extra: ${eextra}" - useradd ${opts} ${euser} ${eextra} \ - || die "enewuser failed" + if [ -z "${eextra}" ] + then + useradd ${opts} ${euser} \ + -c "added by portage for ${PN}" \ + || die "enewuser failed" + else + einfo " - Extra: ${eextra}" + useradd ${opts} ${euser} ${eextra} \ + || die "enewuser failed" + fi fi export SANDBOX_ON="${oldsandbox}" @@ -620,13 +761,8 @@ die "Cannot call enewgroup without a group" fi - # setup a file for testing groupname - local tmpfile="`mymktemp ${T}`" - chgrp ${egroup} ${tmpfile} >& /dev/null - local realgroup="`ls -l ${tmpfile} | awk '{print $4}'`" - # see if group already exists - if [ "${egroup}" == "${realgroup}" ] + if [ "${egroup}" == "`egetent group \"${egroup}\" | cut -d: -f1`" ] then return 0 fi @@ -641,7 +777,16 @@ then if [ "${egid}" -gt 0 ] then - opts="${opts} -g ${egid}" + if [ -z "`egetent group ${egid}`" ] + then + if useq ppc-macos ; then + opts="${opts} ${egid}" + else + opts="${opts} -g ${egid}" + fi + else + egid="next available; requested gid taken" + fi else eerror "Groupid given but is not greater than 0 !" die "${egid} is not a valid GID" @@ -658,14 +803,42 @@ # add the group local oldsandbox="${SANDBOX_ON}" export SANDBOX_ON="0" - groupadd ${opts} ${egroup} || die "enewgroup failed" + if useq ppc-macos ; then + if [ ! -z "${eextra}" ]; + then + einfo "Extra options are not supported on macos yet" + einfo "Please report the ebuild along with the info below" + einfo "eextra: ${eextra}" + die "Required function missing" + fi + + # If we need the next available + case ${egid} in + *[!0-9]*) # Non numeric + for egid in `jot 898 101`; do + [ -z "`egetent group ${egid}`" ] && break + done + esac + dscl . create /groups/${egroup} gid ${egid} + dscl . create /groups/${egroup} passwd '*' + elif use x86-fbsd ; then + case ${egid} in + *[!0-9]*) # Non numeric + for egid in `jot 898 101`; do + [ -z "`egetent group ${egid}`" ] && break + done + esac + pw groupadd ${egroup} -g ${egid} || die "enewgroup failed" + else + groupadd ${opts} ${egroup} || die "enewgroup failed" + fi export SANDBOX_ON="${oldsandbox}" } # Simple script to replace 'dos2unix' binaries # vapier@gentoo.org # -# edos2unix(file, ...) +# edos2unix(file, ...) edos2unix() { for f in "$@" do @@ -674,45 +847,54 @@ done } + +############################################################## +# START: Handle .desktop files and menu entries # +# maybe this should be separated into a new eclass some time # +# lanius@gentoo.org # +############################################################## + # Make a desktop file ! # Great for making those icons in kde/gnome startmenu ! # Amaze your friends ! Get the women ! Join today ! -# gnome2 /usr/share/applications -# gnome1 /usr/share/gnome/apps/ -# KDE ${KDEDIR}/share/applnk /usr/share/applnk # # make_desktop_entry(, [name], [icon], [type], [path]) # # binary: what binary does the app run with ? # name: the name that will show up in the menu # icon: give your little like a pretty little icon ... -# this can be relative (to /usr/share/pixmaps) or -# a full path to an icon +# this can be relative (to /usr/share/pixmaps) or +# a full path to an icon # type: what kind of application is this ? for categories: -# http://www.freedesktop.org/standards/menu/draft/menu-spec/menu-spec.html +# http://www.freedesktop.org/standards/menu-spec/ # path: if your app needs to startup in a specific dir make_desktop_entry() { - [ -z "$1" ] && eerror "You must specify the executable" && return 1 + [ -z "$1" ] && eerror "make_desktop_entry: You must specify the executable" && return 1 local exec="${1}" local name="${2:-${PN}}" local icon="${3:-${PN}.png}" local type="${4}" - local path="${5:-${GAMES_PREFIX}}" + local subdir="${6}" + local path="${5:-${GAMES_BINDIR}}" if [ -z "${type}" ] then case ${CATEGORY} in "app-emulation") type=Emulator + subdir="Emulation" ;; "games-"*) type=Game + subdir="Games" ;; "net-"*) - type=Network; + type=Network + subdir="${type}" ;; *) type= + subdir= ;; esac fi @@ -727,177 +909,86 @@ Exec=${exec} Path=${path} Icon=${icon} -Categories=Application;${type};" > ${desktop} +Categories=Application;${type};" > "${desktop}" - if [ -d "/usr/share/applications" ] - then - insinto /usr/share/applications - doins ${desktop} - fi + insinto /usr/share/applications + doins "${desktop}" - #if [ -d "/usr/share/gnome/apps" ] - #then - # insinto /usr/share/gnome/apps/Games - # doins ${desktop} - #fi + return 0 +} - #if [ ! -z "`ls /usr/kde/* 2>/dev/null`" ] - #then - # for ver in /usr/kde/* - # do - # insinto ${ver}/share/applnk/Games - # doins ${desktop} - # done - #fi +# Make a GDM/KDM Session file +# +# make_desktop_entry(, <command>) +# title: File to execute to start the Window Manager +# command: Name of the Window Manager - if [ -d "/usr/share/applnk" ] - then - insinto /usr/share/applnk/${type} - doins ${desktop} - fi +make_session_desktop() { + + [ -z "$1" ] && eerror "make_session_desktop: You must specify the title" && return 1 + [ -z "$2" ] && eerror "make_session_desktop: You must specify the command" && return 1 + + local title="${1}" + local command="${2}" + local desktop="${T}/${wm}.desktop" + +echo "[Desktop Entry] +Encoding=UTF-8 +Name=${title} +Comment=This session logs you into ${title} +Exec=${command} +TryExec=${command} +Type=Application" > "${desktop}" + + insinto /usr/share/xsessions + doins "${desktop}" return 0 } -# new convenience patch wrapper function to eventually replace epatch(), -# $PATCHES, $PATCHES1, src_unpack:patch, src_unpack:autopatch and -# /usr/bin/patch -# Features: -# - bulk patch handling similar to epatch()'s -# - automatic patch level detection like epatch()'s -# - automatic patch uncompression like epatch()'s -# - doesn't have the --dry-run overhead of epatch() - inspects patchfiles -# manually instead -# - once I decide it's production-ready, it'll be called from base_src_unpack -# to handle $PATCHES to avoid defining src_unpack just to use xpatch - -# accepts zero or more parameters specifying patchfiles and/or patchdirs - -# known issues: -# - only supports unified style patches (does anyone _really_ use anything -# else?) -# - because it doesn't use --dry-run there is a risk of it failing -# to find the files to patch, ie detect the patchlevel, properly. It doesn't use -# any of the backup heuristics that patch employs to discover a filename. -# however, this isn't dangerous because if it works for the developer who's -# writing the ebuild, it'll always work for the users, and if it doesn't, -# then we'll fix it :-) -# - no support as yet for patches applying outside $S (and not directly in $WORKDIR). -xpatch() { - - debug-print-function ${FUNCNAME} $* - - local list= - local list2= - declare -i plevel - - # parse patch sources - for x in $* +domenu() { + local i + local j + insinto /usr/share/applications + for i in ${@} do - debug-print "${FUNCNAME}: parsing parameter ${x}" - if [ -f "${x}" ] + if [ -f "${i}" ]; then - list="${list} ${x}" - elif [ -d "${x}" ] + doins ${i} + elif [ -d "${i}" ]; then - # handles patchdirs like epatch() for now: no recursion. - # patches are sorted by filename, so with an xy_foo naming scheme you'll get the right order. - # only patches with _$ARCH_ or _all_ in their filenames are applied. - for file in `ls -A ${x}` + for j in ${i}/*.desktop do - debug-print "${FUNCNAME}: parsing in subdir: file ${file}" - if [ -f "${x}/${file}" -a "${file}" != "${file/_all_}" -o \ - "${file}" != "${file/_$ARCH_}" ] - then - list2="${list2} ${x}/${file}" - fi + doins ${j} done - list="`echo ${list2} | sort` ${list}" - else - die "Couldn't find ${x}" - fi + fi done +} - debug-print "${FUNCNAME}: final list of patches: ${list}" - - for x in ${list}; +doicon() { + local i + local j + insinto /usr/share/pixmaps + for i in ${@} do - debug-print "${FUNCNAME}: processing ${x}" - # deal with compressed files. /usr/bin/file is in the system profile, or should be. - case "`/usr/bin/file -b ${x}`" in - *gzip*) - patchfile="${T}/current.patch" - ungzip -c "${x}" > "${patchfile}" - ;; - *bzip2*) - patchfile="${T}/current.patch" - bunzip2 -c "${x}" > "${patchfile}" - ;; - *text*) - patchfile="${x}" - ;; - *) - die "Could not determine filetype of patch ${x}" - ;; - esac - debug-print "${FUNCNAME}: patchfile=${patchfile}" - - # determine patchlevel. supports p0 and higher with either $S or $WORKDIR as base. - target="`/bin/grep -m 1 '^+++ ' ${patchfile}`" - debug-print "${FUNCNAME}: raw target=${target}" - # strip target down to the path/filename, remove leading +++ - target="${target/+++ }"; target="${target%% *}" - # duplicate slashes are discarded by patch wrt the patchlevel. therefore we need - # to discard them as well to calculate the correct patchlevel. - target="${target//\/\//\/}" - debug-print "${FUNCNAME}: stripped target=${target}" - - # look for target - for basedir in "${S}" "${WORKDIR}" "${PWD}"; do - debug-print "${FUNCNAME}: looking in basedir=${basedir}" - cd "${basedir}" - - # try stripping leading directories - target2="${target}" - plevel=0 - debug-print "${FUNCNAME}: trying target2=${target2}, plevel=${plevel}" - while [ ! -f "${target2}" ] - do - target2="${target2#*/}" # removes piece of target2 upto the first occurence of / - plevel=$((plevel+1)) - debug-print "${FUNCNAME}: trying target2=${target2}, plevel=${plevel}" - [ "${target2}" == "${target2/\/}" ] && break - done - test -f "${target2}" && break - - # try stripping filename - needed to support patches creating new files - target2="${target%/*}" - plevel=0 - debug-print "${FUNCNAME}: trying target2=${target2}, plevel=${plevel}" - while [ ! -d "${target2}" ] + if [ -f "${i}" ]; + then + doins ${i} + elif [ -d "${i}" ]; + then + for j in ${i}/*.png do - target2="${target2#*/}" # removes piece of target2 upto the first occurence of / - plevel=$((plevel+1)) - debug-print "${FUNCNAME}: trying target2=${target2}, plevel=${plevel}" - [ "${target2}" == "${target2/\/}" ] && break + doins ${j} done - test -d "${target2}" && break - - done - - test -f "${basedir}/${target2}" || test -d "${basedir}/${target2}" \ - || die "Could not determine patchlevel for ${x}" - debug-print "${FUNCNAME}: determined plevel=${plevel}" - # do the patching - ebegin "Applying patch ${x##*/}..." - /usr/bin/patch -p${plevel} < "${patchfile}" > /dev/null \ - || die "Failed to apply patch ${x}" - eend $? - + fi done - } +############################################################## +# END: Handle .desktop files and menu entries # +############################################################## + + # for internal use only (unpack_pdv and unpack_makeself) find_unpackable_file() { local src="$1" @@ -952,38 +1043,61 @@ local tailskip=`tail -c $((${sizeoff_t}*2)) ${src} | head -c ${sizeoff_t} | hexdump -e \"%i\"` # grab metadata for debug reasons - local metafile="`mymktemp ${T}`" + local metafile="$(emktemp)" tail -c +$((${metaskip}+1)) ${src} > ${metafile} # rip out the final file name from the metadata local datafile="`tail -c +$((${metaskip}+1)) ${src} | strings | head -n 1`" datafile="`basename ${datafile}`" - # now lets uncompress the file if need be - local tmpfile="`mymktemp ${T}`" + # now lets uncompress/untar the file if need be + local tmpfile="$(emktemp)" tail -c +$((${tailskip}+1)) ${src} 2>/dev/null | head -c 512 > ${tmpfile} - local filetype="`file -b ${tmpfile}`" - case ${filetype} in - compress*) - #for some reason gzip dies with this ... dd cant provide buffer fast enough ? - #dd if=${src} ibs=${metaskip} count=1 \ - # | dd ibs=${tailskip} skip=1 \ - # | gzip -dc \ - # > ${datafile} + + local iscompressed="`file -b ${tmpfile}`" + if [ "${iscompressed:0:8}" == "compress" ] ; then + iscompressed=1 + mv ${tmpfile}{,.Z} + gunzip ${tmpfile} + else + iscompressed=0 + fi + local istar="`file -b ${tmpfile}`" + if [ "${istar:0:9}" == "POSIX tar" ] ; then + istar=1 + else + istar=0 + fi + + #for some reason gzip dies with this ... dd cant provide buffer fast enough ? + #dd if=${src} ibs=${metaskip} count=1 \ + # | dd ibs=${tailskip} skip=1 \ + # | gzip -dc \ + # > ${datafile} + if [ ${iscompressed} -eq 1 ] ; then + if [ ${istar} -eq 1 ] ; then + tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \ + | head -c $((${metaskip}-${tailskip})) \ + | tar -xzf - + else tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \ | head -c $((${metaskip}-${tailskip})) \ | gzip -dc \ > ${datafile} - ;; - *) + fi + else + if [ ${istar} -eq 1 ] ; then + tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \ + | head -c $((${metaskip}-${tailskip})) \ + | tar --no-same-owner -xf - + else tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \ | head -c $((${metaskip}-${tailskip})) \ > ${datafile} - #dd if=${src} ibs=${metaskip} count=1 \ - # | dd ibs=${tailskip} skip=1 of=${datafile} - ;; - esac - [ -s "${datafile}" ] || die "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')" + fi + fi + true + #[ -s "${datafile}" ] || die "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')" #assert "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')" } @@ -992,39 +1106,46 @@ # the end of the archive. Loki utilized the format as does # many other game companies. # -# Usage: unpack_makeself [file to unpack] [offset] +# Usage: unpack_makeself [file to unpack] [offset] [tail|dd] # - If the file is not specified then unpack will utilize ${A}. # - If the offset is not specified then we will attempt to extract # the proper offset from the script itself. unpack_makeself() { - local src="`find_unpackable_file $1`" + local src="$(find_unpackable_file "$1")" local skip="$2" + local exe="$3" - local shrtsrc="`basename ${src}`" + local shrtsrc="$(basename "${src}")" echo ">>> Unpacking ${shrtsrc} to ${PWD}" if [ -z "${skip}" ] then local ver="`grep -a '#.*Makeself' ${src} | awk '{print $NF}'`" local skip=0 + exe=tail case ${ver} in 1.5.*) # tested 1.5.{3,4,5} ... guessing 1.5.x series is same - skip=`grep -a ^skip= ${src} | cut -d= -f2` + skip=$(grep -a ^skip= "${src}" | cut -d= -f2) ;; 2.0|2.0.1) - skip=`grep -a ^$'\t'tail ${src} | awk '{print $2}' | cut -b2-` + skip=$(grep -a ^$'\t'tail "${src}" | awk '{print $2}' | cut -b2-) ;; 2.1.1) - skip=`grep -a ^offset= ${src} | awk '{print $2}' | cut -b2-` + skip=$(grep -a ^offset= "${src}" | awk '{print $2}' | cut -b2-) let skip="skip + 1" ;; 2.1.2) - skip=`grep -a ^offset= ${src} | awk '{print $3}' | head -n 1` + skip=$(grep -a ^offset= "${src}" | awk '{print $3}' | head -n 1) let skip="skip + 1" ;; 2.1.3) - skip=`grep -a ^offset= ${src} | awk '{print $3}'` + skip=`grep -a ^offset= "${src}" | awk '{print $3}'` let skip="skip + 1" ;; + 2.1.4) + skip=$(grep -a offset=.*head.*wc "${src}" | awk '{print $3}' | head -n 1) + skip=$(head -n ${skip} "${src}" | wc -c) + exe="dd" + ;; *) eerror "I'm sorry, but I was unable to support the Makeself file." eerror "The version I detected was '${ver}'." @@ -1035,22 +1156,31 @@ esac debug-print "Detected Makeself version ${ver} ... using ${skip} as offset" fi + case ${exe} in + tail) exe="tail -n +${skip} '${src}'";; + dd) exe="dd ibs=${skip} skip=1 obs=1024 conv=sync if='${src}'";; + *) die "makeself cant handle exe '${exe}'" + esac # lets grab the first few bytes of the file to figure out what kind of archive it is - local tmpfile="`mymktemp ${T}`" - tail -n +${skip} ${src} 2>/dev/null | head -c 512 > ${tmpfile} - local filetype="`file -b ${tmpfile}`" + local tmpfile="$(emktemp)" + eval ${exe} 2>/dev/null | head -c 512 > "${tmpfile}" + local filetype="$(file -b "${tmpfile}")" case ${filetype} in *tar\ archive) - tail -n +${skip} ${src} | tar -xf - + eval ${exe} | tar --no-same-owner -xf - ;; bzip2*) - tail -n +${skip} ${src} | bzip2 -dc | tar -xf - + eval ${exe} | bzip2 -dc | tar --no-same-owner -xf - ;; gzip*) - tail -n +${skip} ${src} | tar -xzf - + eval ${exe} | tar --no-same-owner -xzf - + ;; + compress*) + eval ${exe} | gunzip | tar --no-same-owner -xf - ;; *) + eerror "Unknown filetype \"${filetype}\" ?" false ;; esac @@ -1079,13 +1209,18 @@ # here is where we check for the licenses the user already # accepted ... if we don't find a match, we make the user accept + local shopts=$- local alic + set -o noglob #so that bash doesn't expand "*" for alic in ${ACCEPT_LICENSE} ; do - [ "${alic}" == "*" ] && return 0 - [ "${alic}" == "${l}" ] && return 0 + if [[ ${alic} == * || ${alic} == ${l} ]]; then + set +o noglob; set -${shopts} #reset old shell opts + return 0 + fi done + set +o noglob; set -$shopts #reset old shell opts - local licmsg="`mymktemp ${T}`" + local licmsg="$(emktemp)" cat << EOF > ${licmsg} ********************************************************** The following license outlines the terms of use of this @@ -1110,3 +1245,360 @@ ;; esac } + +# Aquire cd(s) for those lovely cd-based emerges. Yes, this violates +# the whole 'non-interactive' policy, but damnit I want CD support ! +# +# with these cdrom functions we handle all the user interaction and +# standardize everything. all you have to do is call cdrom_get_cds() +# and when the function returns, you can assume that the cd has been +# found at CDROM_ROOT. +# +# normally the cdrom functions will refer to the cds as 'cd #1', 'cd #2', +# etc... if you want to give the cds better names, then just export +# the CDROM_NAME_X variables before calling cdrom_get_cds(). +# +# for those multi cd ebuilds, see the cdrom_load_next_cd() below. +# +# Usage: cdrom_get_cds <file on cd1> [file on cd2] [file on cd3] [...] +# - this will attempt to locate a cd based upon a file that is on +# the cd ... the more files you give this function, the more cds +# the cdrom functions will handle +cdrom_get_cds() { + # first we figure out how many cds we're dealing with by + # the # of files they gave us + local cdcnt=0 + local f= + for f in "$@" ; do + cdcnt=$((cdcnt + 1)) + export CDROM_CHECK_${cdcnt}="$f" + done + export CDROM_TOTAL_CDS=${cdcnt} + export CDROM_CURRENT_CD=1 + + # now we see if the user gave use CD_ROOT ... + # if they did, let's just believe them that it's correct + if [[ ! -z ${CD_ROOT} ]] ; then + export CDROM_ROOT=${CD_ROOT} + einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}" + return + fi + # do the same for CD_ROOT_X + if [[ ! -z ${CD_ROOT_1} ]] ; then + local var= + cdcnt=0 + while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do + cdcnt=$((cdcnt + 1)) + var="CD_ROOT_${cdcnt}" + if [[ -z ${!var} ]] ; then + eerror "You must either use just the CD_ROOT" + eerror "or specify ALL the CD_ROOT_X variables." + eerror "In this case, you will need ${CDROM_TOTAL_CDS} CD_ROOT_X variables." + die "could not locate CD_ROOT_${cdcnt}" + fi + export CDROM_ROOTS_${cdcnt}="${!var}" + done + export CDROM_ROOT=${CDROM_ROOTS_1} + einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}" + return + fi + + if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then + einfon "This ebuild will need the " + if [[ -z ${CDROM_NAME} ]] ; then + echo "cdrom for ${PN}." + else + echo "${CDROM_NAME}." + fi + echo + einfo "If you do not have the CD, but have the data files" + einfo "mounted somewhere on your filesystem, just export" + einfo "the variable CD_ROOT so that it points to the" + einfo "directory containing the files." + echo + einfo "For example:" + einfo "export CD_ROOT=/mnt/cdrom" + echo + else + einfo "This package will need access to ${CDROM_TOTAL_CDS} cds." + cdcnt=0 + while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do + cdcnt=$((cdcnt + 1)) + var="CDROM_NAME_${cdcnt}" + [[ ! -z ${!var} ]] && einfo " CD ${cdcnt}: ${!var}" + done + echo + einfo "If you do not have the CDs, but have the data files" + einfo "mounted somewhere on your filesystem, just export" + einfo "the following variables so they point to the right place:" + einfon "" + cdcnt=0 + while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do + cdcnt=$((cdcnt + 1)) + echo -n " CD_ROOT_${cdcnt}" + done + echo + einfo "Or, if you have all the files in the same place, or" + einfo "you only have one cdrom, you can export CD_ROOT" + einfo "and that place will be used as the same data source" + einfo "for all the CDs." + echo + einfo "For example:" + einfo "export CD_ROOT_1=/mnt/cdrom" + echo + fi + export CDROM_CURRENT_CD=0 + cdrom_load_next_cd +} + +# this is only used when you need access to more than one cd. +# when you have finished using the first cd, just call this function. +# when it returns, CDROM_ROOT will be pointing to the second cd. +# remember, you can only go forward in the cd chain, you can't go back. +cdrom_load_next_cd() { + export CDROM_CURRENT_CD=$((CDROM_CURRENT_CD + 1)) + local var= + + if [[ ! -z ${CD_ROOT} ]] ; then + einfo "Using same root as before for CD #${CDROM_CURRENT_CD}" + return + fi + + unset CDROM_ROOT + var=CDROM_ROOTS_${CDROM_CURRENT_CD} + if [[ -z ${!var} ]] ; then + var="CDROM_CHECK_${CDROM_CURRENT_CD}" + cdrom_locate_file_on_cd ${!var} + else + export CDROM_ROOT=${!var} + fi + + einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}" +} + +# this is used internally by the cdrom_get_cds() and cdrom_load_next_cd() +# functions. this should *never* be called from an ebuild. +# all it does is try to locate a give file on a cd ... if the cd isn't +# found, then a message asking for the user to insert the cdrom will be +# displayed and we'll hang out here until: +# (1) the file is found on a mounted cdrom +# (2) the user hits CTRL+C +cdrom_locate_file_on_cd() { + while [[ -z ${CDROM_ROOT} ]] ; do + local dir="$(dirname ${@})" + local file="$(basename ${@})" + local mline="" + local showedmsg=0 + + for mline in $(mount | egrep -e '(iso|cdrom)' | awk '{print $3}') ; do + [[ -d ${mline}/${dir} ]] || continue + [[ ! -z $(find ${mline}/${dir} -iname ${file} -maxdepth 1) ]] \ + && export CDROM_ROOT=${mline} + done + + if [[ -z ${CDROM_ROOT} ]] ; then + echo + if [[ ${showedmsg} -eq 0 ]] ; then + if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then + if [[ -z ${CDROM_NAME} ]] ; then + einfo "Please insert the cdrom for ${PN} now !" + else + einfo "Please insert the ${CDROM_NAME} cdrom now !" + fi + else + if [[ -z ${CDROM_NAME_1} ]] ; then + einfo "Please insert cd #${CDROM_CURRENT_CD} for ${PN} now !" + else + local var="CDROM_NAME_${CDROM_CURRENT_CD}" + einfo "Please insert+mount the ${!var} cdrom now !" + fi + fi + showedmsg=1 + fi + einfo "Press return to scan for the cd again" + einfo "or hit CTRL+C to abort the emerge." + read + fi + done +} + +# Make sure that LINGUAS only contains languages that +# a package can support +# +# usage: strip-linguas <allow LINGUAS> +# strip-linguas -i <directories of .po files> +# strip-linguas -u <directories of .po files> +# +# The first form allows you to specify a list of LINGUAS. +# The -i builds a list of po files found in all the +# directories and uses the intersection of the lists. +# The -u builds a list of po files found in all the +# directories and uses the union of the lists. +strip-linguas() { + local ls newls + if [ "$1" == "-i" ] || [ "$1" == "-u" ] ; then + local op="$1"; shift + ls=" $(find "$1" -name '*.po' -printf '%f ') "; shift + local d f + for d in "$@" ; do + if [ "${op}" == "-u" ] ; then + newls="${ls}" + else + newls="" + fi + for f in $(find "$d" -name '*.po' -printf '%f ') ; do + if [ "${op}" == "-i" ] ; then + [ "${ls/ ${f} /}" != "${ls}" ] && newls="${newls} ${f}" + else + [ "${ls/ ${f} /}" == "${ls}" ] && newls="${newls} ${f}" + fi + done + ls="${newls}" + done + ls="${ls//.po}" + else + ls="$@" + fi + + ls=" ${ls} " + newls="" + for f in ${LINGUAS} ; do + if [ "${ls/ ${f} /}" != "${ls}" ] ; then + newls="${newls} ${f}" + else + ewarn "Sorry, but ${PN} does not support the ${f} LINGUA" + fi + done + if [ -z "${newls}" ] ; then + unset LINGUAS + else + export LINGUAS="${newls}" + fi +} + +# moved from kernel.eclass since they are generally useful outside of +# kernel.eclass -iggy (20041002) + +# the following functions are useful in kernel module ebuilds, etc. +# for an example see ivtv or drbd ebuilds + +# set's ARCH to match what the kernel expects +set_arch_to_kernel() { + i=10 + while ((i--)) ; do + ewarn "PLEASE UPDATE TO YOUR PACKAGE TO USE linux-info.eclass" + done + export EUTILS_ECLASS_PORTAGE_ARCH="${ARCH}" + case ${ARCH} in + x86) export ARCH="i386";; + amd64) export ARCH="x86_64";; + hppa) export ARCH="parisc";; + mips) export ARCH="mips";; + *) export ARCH="${ARCH}";; + esac +} + +# set's ARCH back to what portage expects +set_arch_to_portage() { + i=10 + while ((i--)) ; do + ewarn "PLEASE UPDATE TO YOUR PACKAGE TO USE linux-info.eclass" + done + export ARCH="${EUTILS_ECLASS_PORTAGE_ARCH}" +} + +# Jeremy Huddleston <eradicator@gentoo.org>: +# preserve_old_lib /path/to/libblah.so.0 +# preserve_old_lib_notify /path/to/libblah.so.0 +# +# These functions are useful when a lib in your package changes --soname. Such +# an example might be from libogg.so.0 to libogg.so.1. Removing libogg.so.0 +# would break packages that link against it. Most people get around this +# by using the portage SLOT mechanism, but that is not always a relevant +# solution, so instead you can add the following to your ebuilds: +# +# src_install() { +# ... +# preserve_old_lib /usr/$(get_libdir)/libogg.so.0 +# ... +# } +# +# pkg_postinst() { +# ... +# preserve_old_lib_notify /usr/$(get_libdir)/libogg.so.0 +# ... +# } + +preserve_old_lib() { + LIB=$1 + + if [ -n "${LIB}" -a -f "${ROOT}${LIB}" ]; then + SONAME=`basename ${LIB}` + DIRNAME=`dirname ${LIB}` + + dodir ${DIRNAME} + cp ${ROOT}${LIB} ${D}${DIRNAME} + touch ${D}${LIB} + fi +} + +preserve_old_lib_notify() { + LIB=$1 + + if [ -n "${LIB}" -a -f "${ROOT}${LIB}" ]; then + SONAME=`basename ${LIB}` + + einfo "An old version of an installed library was detected on your system." + einfo "In order to avoid breaking packages that link against is, this older version" + einfo "is not being removed. In order to make full use of this newer version," + einfo "you will need to execute the following command:" + einfo " revdep-rebuild --soname ${SONAME}" + einfo + einfo "After doing that, you can safely remove ${LIB}" + einfo "Note: 'emerge gentoolkit' to get revdep-rebuild" + fi +} + +# Hack for people to figure out if a package was built with +# certain USE flags +# +# Usage: built_with_use [-a|-o] <DEPEND ATOM> <List of USE flags> +# ex: built_with_use xchat gtk2 +# +# Flags: -a all USE flags should be utilized +# -o at least one USE flag should be utilized +# Note: the default flag is '-a' +built_with_use() { + local opt=$1 + [[ ${opt:0:1} = "-" ]] && shift || opt="-a" + + local PKG=$(best_version $1) + shift + + local USEFILE="${ROOT}/var/db/pkg/${PKG}/USE" + [[ ! -e ${USEFILE} ]] && return 1 + + local USE_BUILT=$(<${USEFILE}) + while [[ $# -gt 0 ]] ; do + if [[ ${opt} = "-o" ]] ; then + has $1 ${USE_BUILT} && return 0 + else + has $1 ${USE_BUILT} || return 1 + fi + shift + done + [[ ${opt} = "-a" ]] +} + +# Many configure scripts wrongly bail when a C++ compiler +# could not be detected. #73450 +epunt_cxx() { + local dir=$1 + [[ -z ${dir} ]] && dir=${S} + ebegin "Removing useless C++ checks" + local f + for f in $(find ${dir} -name configure) ; do + patch -p0 "${f}" "${PORTDIR}/eclass/ELT-patches/nocxx/nocxx.patch" > /dev/null + done + eend 0 +}