From 72df153b88dc1bf01d639efe469a655ffa2c53c0 Mon Sep 17 00:00:00 2001
From: Britney Fransen <brfransen@gmail.com>
Date: Wed, 20 Jan 2016 23:16:54 +0000
Subject: findbrokenpkgs: initial inclusion

---
 abs/extra/findbrokenpkgs/PKGBUILD              |  18 ++
 abs/extra/findbrokenpkgs/findbrokenpkgs-1.1.sh | 326 +++++++++++++++++++++++++
 2 files changed, 344 insertions(+)
 create mode 100644 abs/extra/findbrokenpkgs/PKGBUILD
 create mode 100644 abs/extra/findbrokenpkgs/findbrokenpkgs-1.1.sh

diff --git a/abs/extra/findbrokenpkgs/PKGBUILD b/abs/extra/findbrokenpkgs/PKGBUILD
new file mode 100644
index 0000000..32d7a38
--- /dev/null
+++ b/abs/extra/findbrokenpkgs/PKGBUILD
@@ -0,0 +1,18 @@
+# Maintaine: Jaroslav Lichtblau <dragonlord@aur.archlinux.org>
+# Contributor: Stefan Husmann <stefan-husmann@t-online.de>
+# Contributor: Paul Bredbury <brebs@sent.com>
+
+pkgname=findbrokenpkgs
+pkgver=1.1
+pkgrel=1
+pkgdesc="Broken package identifier for Arch Linux, based on Gentoo's revdep-rebuild"
+arch=('any')
+url="http://bbs.archlinux.org/viewtopic.php?id=13882"
+license=('GPL')
+depends=('binutils' 'pacman')
+source=($pkgname-$pkgver.sh)
+md5sums=('ee683c467e4881736ed60a15ebbcc7a5')
+
+package() {
+  install -Dm755 $pkgname-$pkgver.sh "${pkgdir}"/usr/bin/$pkgname
+}
diff --git a/abs/extra/findbrokenpkgs/findbrokenpkgs-1.1.sh b/abs/extra/findbrokenpkgs/findbrokenpkgs-1.1.sh
new file mode 100644
index 0000000..ee59628
--- /dev/null
+++ b/abs/extra/findbrokenpkgs/findbrokenpkgs-1.1.sh
@@ -0,0 +1,326 @@
+#! /bin/bash
+# Distributed under the terms of the GNU General Public License v2
+
+# Shamelessly copied mostly from Gentoo's revdep-rebuild utility.
+# http://sources.gentoo.org/viewcvs.py/gentoo-x86/app-portage/gentoolkit/
+# $ equery belongs /usr/bin/revdep-rebuild
+# app-portage/gentoolkit-0.2.3-r1
+# $ cat /usr/portage/app-portage/gentoolkit/gentoolkit-0.2.3-r1.ebuild | grep LICENSE
+# LICENSE="GPL-2"
+
+# findbrokenpkgs for Arch Linux.
+# Converted to use pacman instead of emerge by Paul Bredbury <brebs@sent.com>
+#
+# v1.1 - files now in $HOME/.findbrokenpkgs/ directory - based on changes from
+# Stefan Husmann, repackaged by Jaroslav Lichtblau
+
+# Customizable variables:
+#
+# LD_LIBRARY_MASK - Mask of specially evaluated libraries
+# SEARCH_DIRS - List of directories to search for executables and libraries
+# SEARCH_DIRS_MASK - List of directories to not search
+#
+# These variables can be prepended to by setting the variable in
+# your environment prior to execution.
+#
+# An entry of "-*" means to clear the variable from that point forward.
+# Example: env SEARCH_DIRS="/usr/bin -*" findbrokenpkgs will set SEARCH_DIRS
+# to contain only /usr/bin
+
+if [ "$1" = "-h" -o "$1" = "-help" -o "$1" = "--help" ] ; then
+	echo "Broken package identifier, version 1.0"
+	echo "Checks dynamic library linking."
+	echo
+	echo "Usage: $0 [OPTIONS]"
+	echo
+	echo " -nc, --no-color       Turn off colored output"
+	echo " -nw, --no-warning     Disable newbie-friendly warning"
+	echo "  -q, --quiet          Be less verbose"
+	echo
+	echo "Report bugs to http://bbs.archlinux.org/viewtopic.php?id=13882"
+	exit 0
+fi
+
+# Update the incremental variables using /etc/profile.env, /etc/ld.so.conf,
+# and the environment.
+
+# Read the incremental variables from environment
+PRELIMINARY_SEARCH_DIRS="$SEARCH_DIRS"
+PRELIMINARY_SEARCH_DIRS_MASK="$SEARCH_DIRS_MASK"
+PRELIMINARY_LD_LIBRARY_MASK="$LD_LIBRARY_MASK"
+SONAME_SEARCH="not found"
+SONAME_GREP=grep
+
+# Add the defaults
+if [ -d /etc/findbrokenpkgs ] ; then
+	for file in $(ls /etc/findbrokenpkgs) ; do
+		PRELIMINARY_SEARCH_DIRS="$PRELIMINARY_SEARCH_DIRS $(. /etc/findbrokenpkgs/${file}; echo $SEARCH_DIRS)"
+		PRELIMINARY_SEARCH_DIRS_MASK="$PRELIMINARY_SEARCH_DIRS_MASK $(. /etc/findbrokenpkgs/${file}; echo $SEARCH_DIRS_MASK)"
+		PRELIMINARY_LD_LIBRARY_MASK="$PRELIMINARY_LD_LIBRARY_MASK $(. /etc/findbrokenpkgs/${file}; echo $LD_LIBRARY_MASK)"
+	done
+else
+	PRELIMINARY_SEARCH_DIRS="$PRELIMINARY_SEARCH_DIRS /bin /sbin /usr/bin /usr/sbin /lib* /usr/lib*"
+	# openoffice is a binary, and we don't want to check that monster
+	PRELIMINARY_SEARCH_DIRS_MASK="$PRELIMINARY_SEARCH_DIRS_MASK /opt/openoffice"
+	# Binary libraries
+	PRELIMINARY_LD_LIBRARY_MASK="$PRELIMINARY_LD_LIBRARY_MASK libodbcinst.so libodbc.so libjava.so libjvm.so"
+fi
+
+# Get the ROOTPATH and PATH from /etc/profile.env
+if [ -e "/etc/profile.env" ] ; then
+	PRELIMINARY_SEARCH_DIRS="$PRELIMINARY_SEARCH_DIRS $((. /etc/profile.env; echo ${ROOTPATH}:${PATH}) | tr ':' ' ')"
+fi
+
+# Get the directories from /etc/ld.so.conf
+if [ -e /etc/ld.so.conf ] ; then
+	PRELIMINARY_SEARCH_DIRS="$PRELIMINARY_SEARCH_DIRS $(grep -v "^#" /etc/ld.so.conf | tr '\n' ' ')"
+fi
+
+# Set the final variables
+# Note: Using $(echo $variable) removes extraneous spaces from variable assignment
+unset SEARCH_DIRS
+for i in $(echo $PRELIMINARY_SEARCH_DIRS) ; do
+	[ "$i" = "-*" ] && break
+	# Append a / at the end so that links and directories are treated the same by find
+	# Remove any existing trailing slashes to prevent double-slashes
+	SEARCH_DIRS="$(echo $SEARCH_DIRS ${i/%\//}/)"
+done
+# Remove any double-slashes from the path
+SEARCH_DIRS="$(echo $SEARCH_DIRS | sed 's:/\+:/:g')"
+
+unset SEARCH_DIRS_MASK
+for i in $(echo $PRELIMINARY_SEARCH_DIRS_MASK) ; do
+	[ "$i" = "-*" ] && break
+	SEARCH_DIRS_MASK="$(echo $SEARCH_DIRS_MASK $i)"
+done
+
+unset LD_LIBRARY_MASK
+for i in $(echo $PRELIMINARY_LD_LIBRARY_MASK) ; do
+	[ "$i" = "-*" ] && break
+	LD_LIBRARY_MASK="$(echo $LD_LIBRARY_MASK $i)"
+done
+
+# Base of temporary files names.
+[ -d ${HOME}/.findbrokenpkgs ] || mkdir ${HOME}/.findbrokenpkgs
+touch ${HOME}/.findbrokenpkgs/findbrokenpkgs_0.test 2>/dev/null
+if [ $? -eq 0 ] ; then
+	LIST="${HOME}/.findbrokenpkgs/findbrokenpkgs"
+	rm ~/.findbrokenpkgs/findbrokenpkgs_0.test
+else
+	# Try to use /var/tmp since $HOME is not available
+	touch /var/tmp/.findbrokenpkgs/findbrokenpkgs_0.test 2>/dev/null
+	if [ $? -eq 0 ] ; then
+	LIST="/var/tmp/.findbrokenpkgs/findbrokenpkgs"
+	rm /var/tmp/.findbrokenpkgs/findbrokenpkgs_0.test
+	else
+		echo
+		echo "!!! Unable to write temporary files to either $HOME or /var/tmp !!!"
+		echo
+		exit 1
+	fi
+fi
+
+shopt -s nullglob
+shopt -s expand_aliases
+unalias -a
+alias echo_v=echo
+
+while [ ! -z "$1" ] ; do
+	case "$1" in
+	-q | --quiet )
+		alias echo_v=:
+		shift
+		;;
+	-nc | --no-color )
+		NOCOLOR=true
+		shift
+		;;
+	-nw | --no-warning )
+		NOWARNING=true
+		shift
+		;;
+	* )
+		echo "Unknown option:  $1"
+		exit 1
+		;;
+	esac
+done
+
+# Color Definitions
+if [ "$NOCOLOR" = "yes" -o "$NOCOLOR" = "true" ] ; then
+	NO=""
+	BR=""
+	CY=""
+	GR=""
+	RD=""
+	YL=""
+	BL=""
+else
+	NO="\x1b[0m"
+	BR="\x1b[0;01m"
+	CY="\x1b[36;01m"
+	GR="\x1b[32;01m"
+	RD="\x1b[31;01m"
+	YL="\x1b[33;01m"
+	BL="\x1b[34;01m"
+fi
+
+function set_trap () {
+	trap "rm_temp $1" SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
+}
+
+function rm_temp () {
+	echo " terminated."
+	echo "Removing incomplete $1."
+	rm $1
+	echo
+	exit 1
+}
+
+# Want program results (especially from pacman) in English
+export LC_ALL=C
+
+# Always delete the temporary files from a previous run
+rm -f ${LIST}.[0-9]_*
+
+# Clean up no longer needed environment variables
+unset PREVIOUS_SEARCH_DIRS PREVIOUS_SEARCH_DIRS_MASK PREVIOUS_LD_LIBRARY_MASK PREVIOUS_PREVIOUS_OPTIONS
+unset PRELIMINARY_SEARCH_DIRS PRELIMINARY_SEARCH_DIRS_MASK PRELIMINARY_LD_LIBRARY_MASK
+
+# Log our environment
+echo "SEARCH_DIRS=\"$SEARCH_DIRS\"" > $LIST.0_env
+echo "SEARCH_DIRS_MASK=\"$SEARCH_DIRS_MASK\"" >> $LIST.0_env
+echo "LD_LIBRARY_MASK=\"$LD_LIBRARY_MASK\"" >> $LIST.0_env
+
+echo_v
+echo_v "Checking reverse dependencies..."
+echo_v
+echo_v -n -e "${GR}Collecting system binaries and libraries...${NO}"
+
+set_trap "$LIST.1_*"
+
+# Be extra paranoid and pipe results through sed to remove multiple slashes
+# using -perm /u+x for find command
+find $SEARCH_DIRS -type f \( -perm /u+x -o -name '*.so' -o -name '*.so.*' -o -name '*.la' \) 2>/dev/null | sort | uniq | sed 's:/\+:/:g' >$LIST.0_files
+
+# Remove files that match SEARCH_DIR_MASK
+for dir in $SEARCH_DIRS_MASK ; do
+	grep -v "^$dir" $LIST.0_files > $LIST.1_files
+	mv $LIST.1_files $LIST.0_files
+done
+
+mv $LIST.0_files $LIST.1_files
+echo_v -e " ${GR}done.${NO}\n  ($LIST.1_files)"
+
+echo_v
+echo_v -n -e "${GR}Collecting complete LD_LIBRARY_PATH...${NO}"
+set_trap "$LIST.2_ldpath"
+# Ensure that the "trusted" lib directories are at the start of the path
+(
+	echo /lib* /usr/lib* | sed 's/ /:/g'
+	sed '/^#/d;s/#.*$//' </etc/ld.so.conf
+	sed 's:/[^/]*$::' <$LIST.1_files | sort -ru
+) | tr '\n' : | tr -d '\r' | sed 's/:$//' >$LIST.2_ldpath
+echo_v -e " ${GR}done.${NO}\n  ($LIST.2_ldpath)"
+COMPLETE_LD_LIBRARY_PATH="$(cat $LIST.2_ldpath)"
+
+echo_v
+echo_v -e "${GR}Checking dynamic linking consistency...${NO}"
+set_trap "$LIST.3_rebuild"
+LD_MASK="\\(	$(echo "$LD_LIBRARY_MASK" | sed 's/\./\\./g;s/ / \\|	/g') \\)"
+echo -n > $LIST.3_rebuild
+cat $LIST.1_files | egrep -v '*\.la$' | while read FILE ; do
+	# Note: double checking seems to be faster than single
+	# with complete path (special add-ons are rare).
+	if ldd "$FILE" 2>/dev/null | grep -v "$LD_MASK" | $SONAME_GREP -q "$SONAME_SEARCH" ; then
+		if LD_LIBRARY_PATH="$COMPLETE_LD_LIBRARY_PATH" ldd "$FILE" 2>/dev/null | grep -v "$LD_MASK" | $SONAME_GREP -q "$SONAME_SEARCH" ; then
+			# Only build missing direct dependencies
+			ALL_MISSING_LIBS=$(ldd "$FILE" 2>/dev/null | sort -u | sed -n 's/	\(.*\) => not found/\1/p' | tr '\n' ' ' | sed 's/ $//' )
+			REQUIRED_LIBS=$(objdump -x $FILE | grep NEEDED | awk '{print $2}' | tr '\n' ' ' | sed 's/ $//')
+			MISSING_LIBS=""
+			for lib in $ALL_MISSING_LIBS ; do
+				if echo $REQUIRED_LIBS | grep -q $lib ; then
+					MISSING_LIBS="$MISSING_LIBS $lib"
+				fi
+			done
+			if [ "$MISSING_LIBS" != "" ] ; then
+				echo "$FILE" >> $LIST.3_rebuild
+				# MISSING_LIBS already starts with a space
+				echo_v -e "  $FILE ${RD}needs missing${NO}${MISSING_LIBS}"
+			fi
+		fi
+	fi
+done
+# Not sure if *.la files should even be checked
+cat $LIST.1_files | egrep '*\.la$' | while read FILE ; do
+	for depend in $(grep '^dependency_libs' $FILE | awk -F'=' '{print $2}' | sed "s/'//g") ; do
+		[ ${depend:0:1} != '/' ] && continue
+		if [ ! -e $depend ] ; then
+			echo "$FILE" >> $LIST.3_rebuild
+			echo_v -e "  $FILE ${RD}needs missing${NO} ${depend}"
+		fi
+	done
+done
+echo_v -e " ${GR}done${NO}.\n  ($LIST.3_rebuild)"
+
+echo_v
+echo_v -n -e "${GR}Assigning files to packages...${NO}"
+set_trap "$LIST.4_*"
+echo -n > $LIST.4_package_owners
+echo -n > $LIST.4_packages_raw
+echo -n > $LIST.4_orphans
+
+cat $LIST.3_rebuild | while read FILE ; do
+	EXACT_PKG=$(pacman -Qo $FILE | awk '{print $5 " " $6}')
+	PKG=$(echo $EXACT_PKG | awk '{print $1}')
+	if [ -z "$PKG" ] ; then
+		echo_v -n -e "\n  ${RD}*** $FILE is orphan & broken! ***${NO}"
+		echo "$FILE -> (none)" >> $LIST.4_package_owners
+		echo "$FILE" >> $LIST.4_orphans
+		echo_v -n -e "\n  $FILE ${RD}-> (none)${NO}"
+	else
+		echo "$PKG" >> $LIST.4_packages_raw
+		echo "$FILE -> $EXACT_PKG" >> $LIST.4_package_owners
+		echo_v -n -e "\n  $FILE ${CY}->${NO} ${BR}$PKG${NO}"
+	fi
+done
+echo_v
+echo_v -e " ${GR}done.${NO}\n  ($LIST.4_*)"
+
+echo_v
+echo_v -n -e "${GR}Cleaning list of packages to rebuild...${NO}"
+set_trap "$LIST.5_packages"
+sort -u $LIST.4_packages_raw >$LIST.5_packages
+echo_v -e " ${GR}done.${NO}\n  ($LIST.5_packages)"
+
+REBUILD_LIST="$(cat $LIST.5_packages | tr '\n' ' ')"
+ORPHAN_LIST="$(cat $LIST.4_orphans)"
+
+# Clean up no longer needed environment variables
+unset COMPLETE_LD_LIBRARY_PATH SEARCH_DIRS SEARCH_DIRS_MASK LD_LIBRARY_MASK
+
+trap - SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
+
+if [ -z "$REBUILD_LIST" ] && [ -z "$ORPHAN_LIST" ] ; then
+	echo_v -e "\n${GR}Dynamic linking on your system is consistent.${NO}"
+	# All OK, so delete temporary files
+	rm -f ${LIST}.[0-9]_*
+else
+	# Show broken files & packages
+	if [ -n "$ORPHAN_LIST" ] ; then
+		echo -e "\n${RD}Orphaned broken files:${NO}"
+		echo "$ORPHAN_LIST"
+		echo_v -e "\n${GR}This list of orphaned broken files is in $LIST.4_orphans${NO}"
+	fi
+	if [ -n "$REBUILD_LIST" ] ; then
+		echo -e "\n${RD}Recompile these packages:${NO}"
+		echo -e "${BR}$REBUILD_LIST${NO}"
+		if ! [ "$NOWARNING" = "yes" -o "$NOWARNING" = "true" ] ; then
+			echo_v -e "\nSome/all breakages may be ${GR}OK${NO} - this program cannot distinguish between ${RD}required${NO}"
+			echo_v -e "and ${GR}optional${NO} dependencies. See http://bbs.archlinux.org/viewtopic.php?id=13882"
+		fi
+	fi
+	# The temporary files are deliberately not deleted, as a source of info
+fi
+
+exit 0
-- 
cgit v0.12

