#!/bin/bash name="Libredbdiff" baseconfpath="/etc/libredbdiff" basedbpath="/var/lib/libredbdiff" conffile="$baseconfpath/pacman.conf.parabola" conffilearch="$baseconfpath/pacman.conf.archlinux" dbpath="$basedbpath/pacman.parabola" dbpatharch="$basedbpath/pacman.archlinux" mirrorlist="$baseconfpath/mirrorlist.parabola" mirrorlistarch="$baseconfpath/mirrorlist.archlinux" mirror='http://repo.parabolagnulinux.org/$repo/os/$arch' mirrorarch='http://mirrors.kernel.org/archlinux/$repo/os/$arch' error() { echo -e "Error. $@" > /dev/stderr ; exit 1; } if [[ $# == 1 ]] ; then [[ $1 == -n ]] && UPDATE=0 [[ $1 == -h ]] && { echo -e "${name}. Show [libre] packages that need to be updated from Arch repositories.\n\nUsage:\nlibredbdiff\t\tInitialize (first run) or update pacman databases\nlibredbdiff -n\t\tPrint results" ; exit 0 ; } elif [[ $# != 0 ]] ; then error "Bad arguments. Nothing done." else UPDATE=1 fi if (( $UPDATE )) ; then [[ $EUID != 0 ]] && { error "To initialize $name or update $name pacman databases, the script must be run as root. Nothing done." ; } [[ -d "$baseconfpath" && -d "$basedbpath" && -d "$dbpath" && -d "$dbpatharch" && -e "${conffile}" && -e "${conffilearch}" && -e "${mirrorlist}" && -e "${mirrorlist}" ]] || { echo "${name} files are missing. Initializing." ; init=1 ; } createdir() { if [[ ! -e $1 ]] ; then echo "Creating directory $1" mkdir "$1" || error "Failed to create directory $1. Exiting." else [[ $init ]] && echo "Warning. ${1} already exists. Skipping." fi } createdir "$baseconfpath" createdir "$basedbpath" createdir "$dbpath" createdir "$dbpatharch" downloadfile() { if [[ ! -e $1 ]] ; then echo "$2" if wget -q "$3" -O "$1"; then return 255 else error "Failed to download ${1}. Exiting." fi else [[ $init ]] && echo "Warning. ${1} already exists. Skipping." fi } downloadfile "${conffile}" "Downloading Parabola pacman.conf" "https://projects.parabolagnulinux.org/abslibre.git/plain/libre/pacman/pacman.conf.x86_64" downloadfile "${conffilearch}" "Downloading Arch pacman.conf" "https://projects.archlinux.org/svntogit/packages.git/plain/pacman/trunk/pacman.conf.x86_64" if [[ $? == 255 ]] ; then echo "Setting Arch mirrorlist file in ${conffilearch}" sed -i "s|/etc/pacman\.d/mirrorlist$|$baseconfpath/mirrorlist.archlinux|" "${conffilearch}" fi setmirror() { local distro="$1" local mirror="$2" local mirrorlist="$3" [[ $init ]] && [[ $mirror ]] && { mirrorescaped="${mirror//./\\.}" ; mirrorescaped="${mirrorescaped//\$/\\$}" echo "Setting ${mirror} as the only enabled ${distro} mirror." && \ sed -i 's|^#\(Server = '"${mirrorescaped}"'\)$|\1|' "${mirrorlist}" } } downloadfile "${mirrorlist}" "Downloading Parabola mirrorlist" "https://repo.parabolagnulinux.org/mirrorlist.txt" if [[ $? == 255 ]] ; then sed -i 's|^Server|#Server|' "${mirrorlist}" setmirror "Parabola" "$mirror" "$mirrorlist" fi downloadfile "${mirrorlistarch}" "Downloading Arch mirrorlist" "https://projects.archlinux.org/svntogit/packages.git/plain/pacman-mirrorlist/trunk/mirrorlist" if [[ $? == 255 ]] ; then setmirror "Arch" "$mirrorarch" "$mirrorlistarch" fi echo -e "\nSynchronizing $name pacman databases for Parabola" pacman --config "${conffile}" -b "${dbpath}" -Sy || error "Failed to synchronize pacman database for Parabola. Exiting." echo -e "\nSynchronizing $name pacman databases for Arch" pacman --config "${conffilearch}" -b "${dbpatharch}" -Sy || error "Failed to synchronize pacman database for Arch. Exiting." echo echo "$name pacman databases are updated. $name is ready. Run libredbdiff -n to print results." exit 0 else filenotfound() { [[ ! -r $1 ]] && { error "Could not read $1. Nothing done.\nIt may be necessary to run libredbdiff without arguments as root to initialize ${name}." ; } } filenotfound "${dbpath}" filenotfound "${dbpatharch}" filenotfound "${conffile}" filenotfound "${conffilearch}" filenotfound "${mirrorlist}" filenotfound "${mirrorlistarch}" fi unset provides ver verarch declare -Ax provides ver verarch comparepkgs() { if [[ ${verarch["$pkgname"]} ]] ; then cmp=$(vercmp ${ver["$pkgname"]} ${verarch["$pkgname"]}) [[ $cmp -lt 0 ]] && echo "${pkgname} needs update from the Arch package of the same name. Versions: ${ver["$pkgname"]} - ${verarch["$pkgname"]}" elif [[ ${provides["$pkgname"]} ]] ; then for provide in ${provides["$pkgname"]} ; do [[ ${verarch["$provide"]} ]] && { cmp=$(vercmp "${ver["$pkgname"]}" "${verarch["$provide"]}") [[ $cmp -lt 0 ]] && echo "${pkgname} may need update from provide candidate ${provide}. Versions: ${ver["$pkgname"]} - ${verarch["$provide"]}" } done else echo "Could not find candidate to compare ${pkgname}" fi } while read -a line ; do verarch["${line[0]}"]="${line[1]}" done < <(pacman --dbpath "${dbpatharch}" --config "${conffilearch}" -Ss | grep -v '^ ' | awk -F/ '{print $2}') expac -b "${dbpath}" -c "${conffile}" -Ss '%r/%n %v %S' | awk -F/ '$1 == "libre" {print $2}' | while read -a line ; do ver["${line[0]}"]="${line[1]}" provides[${line[0]}]="${line[@]:2}" pkgname=${line[0]} comparepkgs done