Files
ports/core/scratchpkg/revdep
2020-05-03 23:38:23 +08:00

135 lines
2.9 KiB
Bash
Executable File

#!/bin/sh
#
# script to fix broken binaries/libraries
#
usage() {
cat << EOF
Usage:
$(basename $0) [option] [arg]
Options:
-r, --rebuild rebuild & reinstall broken package
-y, --yes dont ask user confirmation to rebuild package (use with -r/--rebuild)
-h, --help print this help message
EOF
}
confirm() {
printf "$1 (Y/n) "
read -r response
case "$response" in
[Nn][Oo]|[Nn]) echo "$2"; exit 2 ;;
*) : ;;
esac
}
extract_opts() {
while [ "$1" ]; do
case $1 in
--*) opts="$opts $1";;
-*) char=${#1}; count=1
while [ "$count" != "$char" ]; do
count=$((count+1))
opts="$opts -$(echo $1 | cut -c $count)"
done;;
*) opts="$opts $1"
esac
shift
done
echo $opts
}
parse_opt() {
while [ $1 ]; do
case $1 in
-r|--rebuild) REBUILD=1 ;;
-y|--yes) NOCONFIRM=1 ;;
-h|--help) usage; exit 0 ;;
*) echo "Invalid option ($1)"; exit 1 ;;
esac
shift
done
}
rebuild() {
printf "Calculating rebuild order...\033[0K\r"
for allpkg in $(scratch deplist $pkgdone | awk '{print $2}'); do
for pkg in $pkgdone; do
if [ "$pkg" = "$allpkg" ]; then
order="$order $allpkg"
break
fi
done
done
if [ "$order" ]; then
if [ "$NOCONFIRM" = "" ]; then
echo "Package will be rebuild & reinstall by this order:"
echo "$order"
echo
confirm "Continue rebuild & reinstall broken packages?" "Operation cancelled."
fi
for p in $order; do
scratch build -f $p && scratch install -r $p || exit 1
done
fi
}
scan_files() {
echo "Checking for broken linkage..."
for i in /lib/* /usr/lib/* /bin/* /sbin/* /usr/bin/* /usr/sbin/*; do
case "$(file $i)" in
*executable*statically\ linked*|*symbolic\ link*) continue;;
esac
case "$(file -bi $i)" in
*application/x-sharedlib* | *application/x-executable* | *application/x-pie-executable*)
printf " $i\033[0K\r"
for f in $(ldd $i 2>&1 | grep "Error loading shared library" | sed "s/.*needed by //;s/)//" | sort | uniq); do
[ "$f" ] || continue
case "$(file $f)" in
*symbolic\ link*) continue;;
esac
if ! echo $done | grep -wq $f; then
pkg=$(scratch provide $f$ | awk '{print $1}' | head -n1)
[ "$pkg" ] || continue
req=$(ldd $f 2>&1 | grep "needed by $f" | awk '{print $5}' | sed 's/://')
echo " $pkg -> $f (required $req)"
if ! echo $pkgdone | grep -wq $pkg; then
pkgdone="$pkgdone $pkg"
unset pkg
fi
done="$done $f"
unset f
fi
done
esac
done
printf "\033[0K"
}
parse_opt $(extract_opts "$@")
if [ "$(id -u)" != 0 ] && [ "$REBUILD" = 1 ]; then
echo "$(basename $0) need to run as root to rebuild & reinstall package"
exit 1
fi
scan_files
if [ "$pkgdone" ]; then
echo
echo "Broken package(s):"
for rebuild in $pkgdone; do
echo " $rebuild"
done
echo
if [ "$REBUILD" = 1 ]; then
rebuild
fi
else
echo "All packages is doing fine."
fi
exit 0