#!/bin/bash ####################################### # Inspiration from bug #34921 # Thanks to Paul Varner # Distributed under the GPL v2 # Written by John Mylchreest (johnm@gentoo.org) # This version is based on module-rebuild-0.5 # Changed for vdrplugins by Matthias Schwarzott (zzam@gentoo.org) # Copyright Gentoo Authors # Changed to a new db-format with seperate files for each ebuild. if [[ `id -u` != 0 ]]; then echo "This application must be ran as root." exit 1 fi R_VERSION="0.5" R_DBPATH="${ROOT}/usr/share/vdr/vdrplugin-rebuild" R_PORTAGEQ="`type -p portageq 2>/dev/null`" if [[ -z ${R_PORTAGEQ} ]]; then echo "** FATAL: Unable to find portageq." exit 1 fi R_PORTDIR=$(${R_PORTAGEQ} get_repo_path $(${R_PORTAGEQ} envvar EROOT) gentoo) R_VDBPATH=`${R_PORTAGEQ} vdb_path` R_OPTION_X=0; R_OPTION_C=0; R_OPTION_ENABLED=0; R_OPTION_SKIPPED=0; R_OPTION_PATCHLEVEL=0; R_OPTION_PM="portage"; R_PLUGIN_ENABLE="${ROOT}/etc/conf.d/vdr.plugins" R_PLUGINS_SKIPPED="${ROOT}/var/lib/vdr/tmp/plugins_skipped_ALL" eerror() { echo -e "${C_BOLD}${C_RED}** ${@}.${C_NORM}" } package_valid() { local package=${1} [[ -z ${package} ]] && return 1 [[ -z ${package/*\/*} ]] && return 0 || return 1 } package_valid_strict() { local package=${1} package_valid ${package} && [[ -z ${package%%*-[0-9]*} ]] && return 0 || return 1 } package_exists() { local package=${1} package=${package%-[0-9]*} if $(${R_PORTAGEQ} has_version / ${package}); then return 0 else return 1 fi } db_plug_exists() { local package=${1} dbfile=${R_DBPATH}/${package/\//-} [[ -e ${dbfile} ]] && grep -q VDRPLUGIN_DB "${dbfile}" && return 0 return 1 } db_plug_is_good() { local package=${1} dbfile=${R_DBPATH}/${package/\//-} grep -q ^EBUILD= "${dbfile}" && return 0 return 1 } db_plug_list() { local dbfile line auto pkg a=0 b=0 ebuild ebuild_v plugins shortname for dbfile in $(find "${R_DBPATH}" -type f); do grep -q VDRPLUGIN_DB=1 "${dbfile}" || continue ebuild="" ebuild_v="" plugins="" eval $(. "${dbfile}"; echo ebuild=\"${EBUILD}\"; echo ebuild_v=\"${EBUILD_V}\"; echo plugins=\"${PLUGINS}\") auto=1 if [[ -z ${ebuild} ]]; then { eerror "Error in pkg database detected" echo "You need to run \"vdrplugin-rebuild populate\"" } >&2 exit 1 fi shortname=${ebuild#*/} if [[ ${plugins} == "" ]]; then plugins=${shortname} fi set -- ${plugins} firstplug="$1" if [[ ${R_OPTION_ENABLED} == 1 ]]; then # look if any of all plugins installed by this ebuild is enabled local p= match=0 for p in ${plugins}; do # match fixed strings, whole line if fgrep -q -x ${p#vdr-} "${R_PLUGIN_ENABLE}" then match=1 fi done if [[ $match = 0 ]]; then # do not merge if not enabled auto=0 fi fi if [[ ${R_OPTION_SKIPPED} == 1 ]]; then local p= match=0 for p in ${plugins}; do if fgrep -q -x ${p#vdr-} "${R_PLUGINS_SKIPPED}" then match=1 fi done # not merge when not in list of skipped plugins if [[ $match = 0 ]]; then auto=0 fi fi if [[ ${R_OPTION_PATCHLEVEL} == 1 ]]; then local p_chksum="${vdr_checksum_dir}/header-md5-${firstplug}" if cmp -s "${vdr_checksum}" "${p_chksum}"; then # do not merge when patchlevel is equal auto=0 fi fi if [[ ${R_OPTION_X} == 1 ]]; then pkg=${ebuild} package_valid ${pkg} else pkg=${ebuild}-${ebuild_v} package_valid_strict ${pkg} && pkg="=${pkg}" fi if [[ ${auto} = 1 ]]; then tomerge[${a}]=${pkg} a=$((${a} + 1)) else toignore[${b}]=${pkg} b=$((${b} + 1)) fi done pkg="${tomerge[@]}${toignore[@]}" if [[ -z ${pkg} ]]; then echo -e "${C_BOLD}${C_RED}** There are no known plugins. Quitting.${C_NORM}" exit 1 fi if [[ -n ${tomerge[@]} ]]; then echo -e "${C_BOLD}${C_GREEN}** Packages which I will emerge are:${C_NORM}" for pkg in ${tomerge[@]}; do echo -e "\t${pkg}" done fi #if [[ -n ${toignore[@]} ]]; then # echo -e "${C_BOLD}${C_GREEN}** Packages which I will ignore are:${C_NORM}" # for pkg in ${toignore[@]}; do # echo -e "\t${pkg}" # done #fi } # legacy stuff - should not be needed normally db_plug_add() { local package=${1} dbfile=${R_DBPATH}/${package/\//-} if db_plug_exists ${package} && db_plug_is_good ${package}; then echo -e "${C_BOLD}** Plugin ${package} already exists in vdrplugindb.${C_NORM}" return 0 else if package_exists ${package}; then if [[ -f ${dbfile} ]]; then rm -f "${dbfile}" echo -e "${C_BOLD}${C_GREEN}** Fixing db entry for ${package}.${C_NORM}" else echo -e "${C_BOLD}${C_GREEN}** Adding ${package} to vdrplugindb.${C_NORM}" fi local ebuild=${package%-[0-9]*} local ebuild_v="${package#${ebuild}-}" cat <<-EOT > "${dbfile}" VDRPLUGIN_DB=1 CREATOR=vdrplugin-rebuild-POPULATE EBUILD=${ebuild} EBUILD_V=${ebuild_v} EOT return 0 else echo -e "${C_RED}** Unable to locate an available ebuild for ${package}.${C_NORM}" echo "** Please manually emerge ${package} first." fi fi return 1 } db_plug_populate() { local i x=0 pkg version list pad echo -e "${C_BOLD}${C_GREEN}** Populating database with installed Packages.${C_NORM}" # Lets find them all # chances are we will get a few dupes in here. for pkg in $(grep -l ${vdr_plugin_dir}/libvdr ${R_VDBPATH}/*/*/CONTENTS); do pad=""; x=0; if [[ -z ${pkg//${R_VDBPATH}*} ]]; then for((i=0;i<=${#pkg};i++)); do [[ ${pkg:${i}:1} = / ]] && x=$((${x} + 1)); [[ ${x} == 4 ]] || [[ ${x} == 5 ]] && pad="${pad}${pkg:${i}:1}"; done pname="${pad:1}" db_plug_add "${pname}" fi done } db_plug_merge() { local i pkg echo -e "${C_BOLD}** Preparing to merge plugins:${C_NORM}" db_plug_list >/dev/null if [[ -z ${tomerge[@]} ]]; then echo -e "${C_BOLD}${C_RED}** No packages to merge. Quitting.${C_NORM}" exit 1 fi echo -e "${C_BOLD}${C_GREEN}** Packages which I will emerge are:"${C_NORM} for pkg in ${tomerge[@]}; do echo -e "\t${pkg}" done for((i=1;i<6;i++)); do echo -en "${C_BOLD}${C_RED}$((6 - ${i})) ${C_NORM}" sleep 1 done echo case ${R_OPTION_PM} in portage) emerge --ignore-default-opts --oneshot --nodeps --keep-going ${R_PM_OPTS} ${tomerge[@]};; paludis) cave resolve -1x -Cs ${R_PM_OPTS} ${tomerge[@]};; *) echo "** Unsupported package manager"; phelp; exit 1;; esac } get_vdr_plugin_dir() { local d include_dir=/usr/include/vdr d="$(awk '/^PLUGINLIBDIR/{ print $3 }' ${include_dir}/Make.config)" if [ -n "${d}" ]; then d="$(pkg-config --variable=libdir vdr)" fi echo "${d}" return 0 } phelp() { cat << EOF vdrplugin-rebuild [options] action [options to emerge] Version: ${R_VERSION} Where options are: -X - Emerge based on package names, not exact versions. -C - Disable all coloured output. -e - Only merge enabled plugins. -s - Only merge plugins that were skipped at last vdr start. -p - Only merge plugins that are not compiled against this vdr. -P - Specify package manager: portage(default) or paludis Where action is one of: list - List packages to auto-rebuild. rebuild - Rebuild packages. populate - Populate the database with any packages which currently install plugins for vdr (should not be necessary). EOF } while [ -n "$1" ]; do case "$1" in -X) R_OPTION_X='1';; -C) R_OPTION_C='1';; -e) R_OPTION_ENABLED='1';; -s) R_OPTION_SKIPPED='1';; -p) R_OPTION_PATCHLEVEL='1';; -P) R_OPTION_PM="$2"; shift;; -*) phelp; exit 1;; *) break;; esac shift done if [[ ${R_OPTION_C} == 0 ]]; then C_BOLD='\e[1m' C_NORM='\e[0m' C_GREEN='\e[32m' C_RED='\e[31m' else C_BOLD='' C_NORM='' C_GREEN='' C_RED='' fi vdr_plugin_dir=$(get_vdr_plugin_dir) if [[ ${R_OPTION_SKIPPED} == 1 && ! -f ${R_PLUGINS_SKIPPED} ]]; then echo -e "${C_BOLD}${C_GREEN}No Plugins skipped, nothing todo${C_NORM}" exit 0 fi if [[ ${R_OPTION_PATCHLEVEL} == 1 ]]; then # needed for plugin patchlevel check vdr_checksum_dir="${vdr_plugin_dir%/plugins}/checksums" vdr_checksum=/var/lib/vdr/tmp/rebuild-vdr-checksum if ! vdr-get-header-checksum > "${vdr_checksum}"; then echo -e "${C_BOLD}${C_RED}Could not get vdr header checksum${C_NORM}" exit 1 fi fi R_CMD="$1" shift R_PM_OPTS="$@" # If the vdrplugindb doesnt exist, lets populate it automatically. if [[ ! -d ${R_DBPATH} ]]; then echo -e "${C_BOLD}${C_RED}No vdrplugindb found...${C_NORM}" mkdir -p ${R_DBPATH} echo -e "${C_BOLD}Populating vdrplugindb...${C_NORM}" if [[ ${R_CMD} != populate ]]; then db_plug_populate fi fi case ${R_CMD} in list) db_plug_list;; rebuild) db_plug_merge;; populate) db_plug_populate;; *) phelp; exit 1;; esac