--- scanelf-rebuild.sh.orig 2007-07-05 11:23:53.000000000 -0400 +++ scanelf-rebuild.sh 2007-07-05 11:46:23.000000000 -0400 @@ -2,6 +2,18 @@ # Spit out a portage-compatible list of packages to build because of lib # breakages. +declare quiet # if defined, output less noise +declare avoid_utils # whitespace-delimited list of utils not to use +declare checks # array of what checks to run + +# Exit and optionally output to sterr +die() { + local status=$1 + shift + echo "$@" >&2 + exit $status +} +# Print out the commandline options print_usage() { cat << EOF Usage: $0 [OPTIONS] @@ -10,13 +22,10 @@ -h, --help Print this usage -e, --exact Emerge based on exact package version - -q, --quiet Be less verbose (also passed to emerge command) + -q, --quiet Be less verbose -u, --no-util UTIL Do not use features provided by UTIL --no-util=UTIL UTIL can be one of portage-utils, pkgcore, or equery or it can be a *quoted* space-delimited list. - -L, --library NAME Emerge existing packages that use the library with NAME - --library=NAME NAME can be a full path to the library or a basic - regular expression (man grep) -b, --check-linking Check dynamic linking for binaries -l, --check-libtool Check *.la files for missing dependencies @@ -24,7 +33,20 @@ Report bugs to EOF +# TODO: +# -L, --library NAME Emerge existing packages that use the library with NAME +# --library=NAME NAME can be a full path to the library or a basic +# regular expression (man grep) +} +# Print feedback to stderr +# Use stderr so as not to interfere with package-manager-friendly output +# This function is redefined based on $quiet -- see get_args +chatter() { + [[ $quiet ]] && chatter() { :; } || chatter() { echo "$@" >&2; } + chatter "$@" } +# Get the NEEDED sonames from scanelf and print out the ones that don't exist +# on the filesystem. get_missing_sonames() { local soname IFS=$'\n,' list=($(scanelf -BLpF%n#F)) list=($(sort -u <<< "${list[*]}")) @@ -32,6 +54,7 @@ [[ -e $soname ]] || echo $soname done | sort -u } +# Get the package names for packages with missing sonames check_bins() { local missing_sonames broken_pkgs bin libs pv p missing_sonames=$(get_missing_sonames) @@ -41,14 +64,15 @@ while read bin libs; do feedback=$(grep -oF "$missing_sonames" <<< "$libs") feedback="${feedback##[[:space:]]}"; feedback="${feedback%%[[:space:]]}" - echo "$bin is missing ${feedback//[[:space:]]/ and }" >&2 + chatter "$bin is missing ${feedback//[[:space:]]/ and }" echo "$bin" done <<< "$broken_pkgs" ) | sort -u | slot else - echo "Dynamic linking is consistent" >&2 + chatter "Dynamic linking is consistent" fi } +# Get all the *.la files in likely places get_all_las() { local IFS paths paths=( @@ -61,6 +85,7 @@ paths=($(sort -u <<< "${paths[*]%/}")) find -L ${paths[@]} -type f -name '*.la' 2> /dev/null | sort -u } +# grep (heh) the dependency libs from the given .la file or files get_dependency_libs() { awk -F"[=']" '/^dependency_libs/{ gsub("^-[^[:space:]]*", "", $NF); @@ -68,6 +93,7 @@ print $NF }' "$@" } +# Get package names for packages owning las with missing dependencies check_las() { local oIFS="$IFS" local IFS @@ -80,7 +106,7 @@ IFS="$oIFS" for dep in ${deps[@]}; do [[ $dep = /* && ! -e $dep ]] || continue - echo "$la is missing $dep" >&2 + chatter "$la is missing $dep" echo "$la" done done < <(get_all_las) | sort -u @@ -89,9 +115,11 @@ if (( ${#broken_las[@]} > 0)); then get_packages <<< "${broken_las[*]}" | sort -u | slot else - echo "No dependencies missing from .la files" >&2 + chatter "No dependencies missing from .la files" fi } +# Convert category/package-version into category/package:slot +# This function may be changed by commandline options: see get_args() slot() { while read pv; do p="${pv%%-r[[:digit:]]*}" @@ -99,27 +127,36 @@ echo "$p:$(&2; print_usage; exit 1;; + *) print_usage; die 1 "Invalid parameter $1";; esac shift done + # Rewrite get_packages based on what's available and possibly the commandline + # arg --no-util if [[ avoid_utils != *portage-utils* ]] && hash qfile 2> /dev/null; then get_packages() { qfile -qvC "$@"; } elif [[ avoid_utils != *pkgcore* ]] && hash pquery 2> /dev/null; then @@ -152,6 +191,7 @@ sed 's:/var/db/pkg/\(.*\)/CONTENTS:=\1:' } fi + # Run the program, checking items requested at the commandline for check in ${checks[@]}; do case $check in linking) check_bins;;