--- fcaps.eclass +++ fcaps.eclass @@ -10,8 +10,9 @@ # This is not the same as USE=caps which controls runtime capability changes, # often via packages like libcap. # -# Due to probable capability-loss on moving or copying, this happens in -# pkg_postinst phase (at least for now). +# Due to possible capability-loss on moving or copying, this now happens +# both in src_install and pkg_postinst. If it was needed in pkg_postinst, this +# generates a warning. # # @EXAMPLE: # You can manually set the caps on ping and ping6 by doing: @@ -39,10 +40,10 @@ # @ECLASS-VARIABLE: FILECAPS # @DEFAULT_UNSET # @DESCRIPTION: -# An array of fcap arguments to use to automatically execute fcaps. See that +# An array of fcap arguments to use to automatically execute fcaps. See that # function for more details. # -# All args are consumed until the '--' marker is found. So if you have: +# All args are consumed until the '--' marker is found. So if you have: # @CODE # FILECAPS=( moo cow -- fat cat -- chubby penguin ) # @CODE @@ -72,8 +73,8 @@ # capabilities were properly set on the file. # # If the system is unable to set capabilities, it will use the specified user, -# group, and mode (presumably to make the binary set*id). The defaults there -# are root:0 and 4711. Otherwise, the ownership and permissions will be +# group, and mode (presumably to make the binary set*id). The defaults there +# are root:0 and 4711. Otherwise, the ownership and permissions will be # unchanged. fcaps() { debug-print-function ${FUNCNAME} "$@" @@ -118,7 +119,7 @@ [[ ${file} != /* ]] && file="${root}/${file}" if use filecaps ; then - # Try to set capabilities. Ignore errors when the + # Try to set capabilities. Ignore errors when the # fs doesn't support it, but abort on all others. debug-print "${FUNCNAME}: setting caps '${caps}' on '${file}'" @@ -155,6 +156,27 @@ local out cmd notfound=0 for cmd in _libcap _libcap_ng ; do + # If in postinst, check whether caps were already set, as they normally should be + if [[ ${EBUILD_PHASE} == "postinst" ]] ; then + if out=$(LC_ALL=C ${cmd}_verify 2>&1) ; then + debug-print "Caps '${caps}' were already set on '${file}'" + else + case ${out} in + *"command not found"*) + : $(( ++notfound )) + continue + ;; + *) + ewarn "Caps weren't set, although we expected them to be set:" + ewarn "* portage will now set caps ${caps} on $file" + ewarn "* please verify that moving/copying files doesn't destroy XATTRs" + ;; + esac + fi + else + debug-print "Setting caps '${caps}' on '${file}'" + fi + if ! out=$(LC_ALL=C ${cmd} 2>&1) ; then case ${out} in *"command not found"*) @@ -173,14 +195,14 @@ break ;; *) - eerror "Setting caps '${caps}' on file '${file}' failed:" + eerror "Setting caps '${caps}' on file '${file}' with '${cmd}' failed:" eerror "${out}" - die "could not set caps" + die "Could not set caps" ;; esac else # Sanity check that everything took. - ${cmd}_verify || die "Checking caps '${caps}' on '${file}' failed" + ${cmd}_verify && debug-print "Caps '${caps}' are set on '${file}'" || die "Checking caps '${caps}' on '${file}' failed" # Everything worked. Move on to the next file. continue 2 @@ -199,19 +221,32 @@ done } +# @FUNCTION: fcaps_parse +# @DESCRIPTION: +# Process the FILECAPS array. +fcaps_parse() { + # only proceed if FILECAPS is set and not empty + if [ ${FILECAPS[0]} ] ; then + local arg args=() + for arg in "${FILECAPS[@]}" "--" ; do + if [[ ${arg} == "--" ]] ; then + fcaps "${args[@]}" + args=() + else + args+=( "${arg}" ) + fi + done + else + debug-print "${FUNCNAME}: FILECAPS is empty but ebuild uses fcap, assuming direct fcaps call" + fi +} + + # @FUNCTION: fcaps_pkg_postinst # @DESCRIPTION: # Process the FILECAPS array. fcaps_pkg_postinst() { - local arg args=() - for arg in "${FILECAPS[@]}" "--" ; do - if [[ ${arg} == "--" ]] ; then - fcaps "${args[@]}" - args=() - else - args+=( "${arg}" ) - fi - done + fcaps_parse } EXPORT_FUNCTIONS pkg_postinst