#!/bin/bash version="1.21" tanpath="/var/lib/pacman" tandb="pacsync.db" errors=0 upgrade=0 message() { echo "==> $1" >&2 } usage() { echo "pacsync version $version" echo "usage: $0 [package]" echo "" echo "operations:" echo " sync Download a fresh package list from the server" echo " install Download and install " echo " upgrade Download and upgrade " echo " report Generate a report of all packages that could be upgraded" echo " sysupgrade Same as \"report\", but actually do the upgrades" echo " clean Removes all files from package cache to clear up diskspace" echo "" } checkdb() { if [ ! -f $tanpath/$tandb ]; then message "missing package list. (use \"sync\" first)" exit 1 fi } download() { targ=$1 shift cl= for file in $*; do cl="$cl $SYNC_SERVER/$file" done message "Downloading $targ" $ftpagent $cl if [ $? -gt 0 ]; then message "ERROR: could not download $targ" return 1 fi return 0 } dosync() { cd /tmp download "package list" pacsync/$tandb if [ $? -gt 0 ]; then exit 1 fi rm -f $tanpath/$tandb mv /tmp/$tandb $tanpath/$tandb message "Done." } doinstall() { pkg2dl= pkg2inst= for pkgname in $*; do line=`egrep "^[a-z]+/$pkgname-[a-zA-Z0-9\.]+-[0-9]+\.pkg\.tar\.gz$" $tanpath/$tandb` if [ $? -gt 0 ]; then message "package $pkgname not found" exit 1 fi pacman=`pacman -Q $pkgname 2>/dev/null` if [ $? -eq 0 ]; then message "$pkgname is already installed (try using \"upgrade\")" exit 1 fi filename=`echo $line | sed 's|^[a-z]*/||g'` pkg2inst="$pkg2inst $filename" if [ ! -f /var/cache/pacman/pkg/$filename ]; then pkg2dl="$pkg2dl $filename" fi done # download packages that aren't already cached if [ "$pkg2dl" != "" ]; then download "packages" $pkg2dl if [ $? -gt 0 ]; then exit 1 fi if [ `pwd` != "/var/cache/pacman/pkg" ]; then # move downloaded files into cache mkdir -p /var/cache/pacman/pkg mv $pkg2dl /var/cache/pacman/pkg/ fi fi # install packages message "Installing packages" cd /var/cache/pacman/pkg pacman -A $pkg2inst if [ $? -gt 0 ]; then echo "ERROR: some packages failed to install" exit 1 fi message "Done" exit 0 } doupgrade() { pkg2dl= pkg2up= for pkgname in $*; do line=`egrep "^[a-z]+/$pkgname-[a-zA-Z0-9\.]+-[0-9]+\.pkg\.tar\.gz$" $tanpath/$tandb` if [ $? -gt 0 ]; then message "package $pkgname not found" exit 1 fi pacman=`pacman -Q $pkgname 2>/dev/null` if [ $? -gt 0 ]; then message "$pkgname is not installed (use \"install\" first)" exit 1 fi pkgver=`echo $pacman | awk '{print $2}'` package="$pkgname-$pkgver" filename=`echo $line | sed 's|^[a-z]*/||g'` # compare filename and package. if they are at all different, we # assume that the newer version is on the server and do the upgrade if [ "$filename" = "$package.pkg.tar.gz" ]; then message "$pkgname is already up to date (skipping)" else pkg2up="$pkg2up $filename" if [ ! -f /var/cache/pacman/pkg/$filename ]; then pkg2dl="$pkg2dl $filename" fi fi done # download packages that aren't already cached if [ "$pkg2dl" != "" ]; then download "packages" $pkg2dl if [ $? -gt 0 ]; then exit 1 fi if [ `pwd` != "/var/cache/pacman/pkg" ]; then # move downloaded files into cache mkdir -p /var/cache/pacman/pkg mv $pkg2dl /var/cache/pacman/pkg/ fi fi # install packages if [ "$pkg2up" != "" ]; then message "Upgrading packages" cd /var/cache/pacman/pkg pacman -U $pkg2up if [ $? -gt 0 ]; then echo "ERROR: some packages failed to upgrade" exit 1 fi message "Done" fi exit 0 } doreport() { headers=0 pkg2up= for pkgfile in `cat $tanpath/$tandb | sed "s|^[a-z]*/||g"`; do pkgname=`echo $pkgfile | sed 's|-[a-zA-Z0-9\.]*-[0-9]*\.pkg\.tar\.gz||g'` pacman=`pacman -Q $pkgname 2>/dev/null` if [ $? -gt 0 ]; then # skip this one, it's not installed continue fi pkgver=`echo $pacman | awk '{print $2}'` locfile="$pkgname-$pkgver" remfile=`echo $pkgfile | sed 's|^[a-zA-Z]*/||g' | sed 's|\.pkg\.tar\.gz||g'` # compare locfile and remfile if [ "$locfile" = "$remfile" ]; then # this package is up to date continue else if [ "$headers" = "0" ]; then echo "+--------------------------------------+--------------------------------------+" echo "| LOCAL | REMOTE |" echo "+--------------------------------------+--------------------------------------+" headers=1 fi echo -n "| $locfile" awk "BEGIN { for (j=length(\"$locfile\"); j<36; j++) printf \" \" }" echo -n " | " awk "BEGIN { for (j=length(\"$remfile\"); j<36; j++) printf \" \" }" echo "$remfile |" pkg2up="$pkg2up $pkgname" fi done if [ "$headers" = "1" ]; then echo "+--------------------------------------+--------------------------------------+" fi # do we upgrade? if [ "$upgrade" = "1" -a "$pkg2up" != "" ]; then echo "" echo -n "Do you want to upgrade these packages? [Y/n] " read answer echo "" if [ "$answer" = "y" -o "$answer" = "Y" -o "$answer" = "" ]; then doupgrade $pkg2up fi fi exit 0 } if [ $# -lt 1 ]; then usage exit 0 fi if [ -f /etc/pacsync.conf ]; then . /etc/pacsync.conf else message "error: missing configuration file!" exit 1 fi proto=`echo $SYNC_SERVER | sed 's|://.*||'` # check for a download utility if [ -x /usr/bin/lftpget -a "$proto" = "ftp" ]; then ftpagent="/usr/bin/lftpget" elif [ -x /usr/bin/wget ]; then ftpagent="/usr/bin/wget --passive-ftp --tries=3 --waitretry=3" else message "error: you need an ftp client installed (lftp or wget) in /usr/bin" exit 1 fi op=$1 shift if [ "$1" = "-v" ]; then verbose=1 shift fi case $op in sync) dosync ;; install) checkdb if [ "$1" = "" ]; then message "error: no package specified" exit 1 fi doinstall $* ;; upgrade) checkdb if [ "$1" = "" ]; then message "error: no package specified" exit 1 fi doupgrade $* ;; report) checkdb doreport ;; sysupgrade) checkdb upgrade=1 doreport ;; clean) message "Removing packages from cache" rm -f /var/cache/pacman/pkg/* ;; *) message "error: invalid operation" exit 1 ;; esac