168 lines
4.6 KiB
Bash
Executable File
168 lines
4.6 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# sogrep - find shared library links in an Arch Linux repository.
|
|
#
|
|
# Copyright (c) 2019 by Eli Schwartz <eschwartz@archlinux.org>
|
|
#
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
m4_include(lib/common.sh)
|
|
|
|
# globals
|
|
: ${SOLINKS_MIRROR:="https://mirror.pkgbuild.com"}
|
|
: ${SOCACHE_DIR:="${XDG_CACHE_HOME:-${HOME}/.cache}/sogrep"}
|
|
|
|
m4_include(lib/valid-repos.sh)
|
|
arches=('x86_64')
|
|
|
|
# options
|
|
REFRESH=0
|
|
VERBOSE=0
|
|
|
|
source /usr/share/makepkg/util/parseopts.sh
|
|
source /usr/share/makepkg/util/util.sh
|
|
|
|
recache() {
|
|
local repo arch verbosity=-s
|
|
|
|
(( VERBOSE )) && verbosity=--progress-bar
|
|
|
|
for repo in "${_repos[@]}"; do
|
|
for arch in "${arches[@]}"; do
|
|
# delete extracted tarballs from previous sogrep versions
|
|
rm -rf "${SOCACHE_DIR}/${arch}/${repo}"
|
|
|
|
# fetch repo links database if newer than our cached copy
|
|
local dbpath=${SOCACHE_DIR}/${arch}/${repo}.links.tar.gz
|
|
mkdir -p "${dbpath%/*}"
|
|
(( VERBOSE )) && echo "Fetching ${repo}.links.tar.gz..."
|
|
curl -LR "${verbosity}" -o "${dbpath}" -z "${dbpath}" \
|
|
"${SOLINKS_MIRROR}/${repo}/os/${arch}/${repo}.links.tar.gz"
|
|
done
|
|
done
|
|
}
|
|
|
|
is_outdated_cache() {
|
|
local repo arch
|
|
|
|
# links databases are generated at about the same time every day; we should
|
|
# attempt to check for new database files if any of them are over a day old
|
|
|
|
for repo in "${_repos[@]}"; do
|
|
for arch in "${arches[@]}"; do
|
|
local dbpath=${SOCACHE_DIR}/${arch}/${repo}.links.tar.gz
|
|
if [[ ! -f ${dbpath} ]] || [[ $(find "${dbpath}" -mtime +0) ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
search() {
|
|
local repo=$1 arch lib=$2 srepos=("${_repos[@]}")
|
|
|
|
if [[ $repo != all ]]; then
|
|
if ! in_array "${repo}" "${_repos[@]}"; then
|
|
echo "${BASH_SOURCE[0]##*/}: unrecognized repo '$repo'"
|
|
echo "Try '${BASH_SOURCE[0]##*/} --help' for more information."
|
|
exit 1
|
|
fi
|
|
srepos=("${repo}")
|
|
fi
|
|
|
|
setup_workdir
|
|
|
|
for arch in "${arches[@]}"; do
|
|
for repo in "${srepos[@]}"; do
|
|
local prefix=
|
|
(( VERBOSE && ${#srepos[@]} > 1 )) && prefix=${repo}/
|
|
local db=${SOCACHE_DIR}/${arch}/${repo}.links.tar.gz
|
|
if [[ -f ${db} ]]; then
|
|
local extracted=${WORKDIR}/${arch}/${repo}
|
|
mkdir -p "${extracted}"
|
|
bsdtar -C "${extracted}" -xf "${db}"
|
|
while read -rd '' pkg; do
|
|
read -r match
|
|
pkg=${pkg#${extracted}/}
|
|
pkg="${prefix}${pkg%-*-*/links}"
|
|
|
|
if (( VERBOSE )); then
|
|
printf '%-35s %s\n' "${pkg}" "${match}"
|
|
else
|
|
printf '%s\n' "${pkg}"
|
|
fi
|
|
done < <(grep -rZ "${lib}" "${extracted}") | sort -u
|
|
fi
|
|
done
|
|
done | resort
|
|
}
|
|
|
|
usage() {
|
|
cat <<- _EOF_
|
|
Usage: ${BASH_SOURCE[0]##*/} [OPTIONS] REPO LIBNAME
|
|
|
|
Check the soname links database for Arch Linux repositories containing
|
|
packages linked to a given shared library. If the repository specified
|
|
is "all", then all repositories will be searched, otherwise only the
|
|
named repository will be searched.
|
|
|
|
If the links database does not exist, it will be downloaded first.
|
|
|
|
OPTIONS
|
|
-v, --verbose Show matched links in addition to pkgname
|
|
-r, --refresh Refresh the links databases
|
|
-h, --help Show this help text
|
|
_EOF_
|
|
}
|
|
|
|
# utility function to resort with multiple repos + no-verbose
|
|
resort() { sort -u; }
|
|
|
|
if (( $# == 0 )); then
|
|
echo "error: No arguments passed."
|
|
echo "Try '${BASH_SOURCE[0]##*/} --help' for more information."
|
|
exit 1
|
|
fi
|
|
OPT_SHORT='vrh'
|
|
OPT_LONG=('verbose' 'refresh' 'help')
|
|
if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
|
|
exit 1
|
|
fi
|
|
set -- "${OPTRET[@]}"
|
|
|
|
while :; do
|
|
case $1 in
|
|
-v|--verbose)
|
|
resort() { cat; }
|
|
VERBOSE=1
|
|
;;
|
|
-r|--refresh)
|
|
REFRESH=1
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
--)
|
|
shift; break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if ! (( ( REFRESH && $# == 0 ) || $# == 2 )); then
|
|
echo "error: Incorrect number of arguments passed."
|
|
echo "Try '${BASH_SOURCE[0]##*/} --help' for more information."
|
|
exit 1
|
|
fi
|
|
|
|
# trigger a refresh if requested explicitly or the cached dbs might be outdated
|
|
if (( REFRESH )) || [[ ! -d ${SOCACHE_DIR} ]] || is_outdated_cache; then
|
|
recache
|
|
(( $# == 2 )) || exit 0
|
|
fi
|
|
|
|
search "$@"
|