pacman/pacsync
2002-04-30 18:53:55 +00:00

332 lines
7.9 KiB
Bash
Executable file

#!/bin/bash
version="1.23"
tanpath="/var/lib/pacman"
tandb="pacsync.db"
errors=0
upgrade=0
INSTALL_ROOT="/"
IGNORE_PKG=
message() {
echo "==> $1" >&2
}
usage() {
echo "pacsync version $version"
echo "usage: $0 [--root <root>] [--ignore <pkg>] <operation> [package]"
echo ""
echo "operations:"
echo " sync Download a fresh package list from the server"
echo " install <pkg> Download and install <pkg>"
echo " upgrade <pkg> Download and upgrade <pkg>"
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 ""
echo "options:"
echo " --root <root> Set installation root to <root>"
echo " --ignore <pkg> Ignore packages that have <pkg> in their names when doing"
echo " sysupgrades. (--ignore can be used multiple times)"
echo ""
}
checkdb() {
if [ ! -f $INSTALL_ROOT/$tanpath/$tandb ]; then
message "missing package list. (use \"sync\" first)"
exit 1
fi
}
download() {
targ=$1
shift
cl=
for file in $*; do
# snarf returns a nonzero error code when the file already exists, which
# confuses pacsync, so for now, no resume action...
rm -f $file
cl="$cl $SYNC_SERVER/$file"
done
message "Downloading $targ"
$ftpagent $cl 2>&1
if [ $? -gt 0 ]; then
message "error: could not download $targ"
return 1
fi
return 0
}
dosync() {
download "package list" pacsync/$tandb
if [ $? -gt 0 ]; then
exit 1
fi
rm -f $INSTALL_ROOT/$tanpath/$tandb
mv $tandb $INSTALL_ROOT/$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$" $INSTALL_ROOT/$tanpath/$tandb`
if [ $? -gt 0 ]; then
message "package $pkgname not found"
exit 1
fi
pacman=`pacman -Q -r $INSTALL_ROOT $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 $INSTALL_ROOT/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` != "$INSTALL_ROOT/var/cache/pacman/pkg" ]; then
# move downloaded files into cache
mkdir -p $INSTALL_ROOT/var/cache/pacman/pkg
mv $pkg2dl $INSTALL_ROOT/var/cache/pacman/pkg/
fi
fi
# install packages
message "Installing packages"
cd $INSTALL_ROOT/var/cache/pacman/pkg
pacman -A -r $INSTALL_ROOT $pkg2inst
if [ $? -gt 0 ]; then
message "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$" $INSTALL_ROOT/$tanpath/$tandb`
if [ $? -gt 0 ]; then
message "package $pkgname not found"
exit 1
fi
pacman=`pacman -Q -r $INSTALL_ROOT $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 $INSTALL_ROOT/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` != "$INSTALL_ROOT/var/cache/pacman/pkg" ]; then
# move downloaded files into cache
mkdir -p $INSTALL_ROOT/var/cache/pacman/pkg
mv $pkg2dl $INSTALL_ROOT/var/cache/pacman/pkg/
fi
fi
# install packages
if [ "$pkg2up" != "" ]; then
message "Upgrading packages"
cd $INSTALL_ROOT/var/cache/pacman/pkg
pacman -U -r $INSTALL_ROOT $pkg2up
if [ $? -gt 0 ]; then
message "error: some packages failed to upgrade"
exit 1
fi
message "Done"
fi
exit 0
}
doreport() {
headers=0
newkernel=0
pkg2up=
for pkgfile in `cat $INSTALL_ROOT/$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 -r $INSTALL_ROOT $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 [ `echo "$locfile" | egrep '^kernel-[a-zA-Z0-9\.]+-[0-9]+$'` ]; then
# this is the kernel pacakge -- we handle this one specially
newkernel=1
continue
fi
if [ "$IGNORE_PKG" != "" ]; then
if [ `echo "$locfile" | egrep "$IGNORE_PKG"` ]; then
# ignore this package as per user's request
continue
fi
fi
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
if [ "$newkernel" = "1" ]; then
echo
echo "NOTICE: A new kernel is available for upgrade, but this process will not"
echo " upgrade it for you. If you wish to upgrade, you must explicitly"
echo " request it by running 'pacsync upgrade kernel'. If you choose to"
echo " upgrade, make sure you re-run 'lilo' as well!"
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
}
cd /tmp
if [ $# -lt 1 ]; then
usage
exit 0
fi
if [ "$1" = "--root" ]; then
shift
INSTALL_ROOT=$1
shift
fi
while [ "$1" = "--ignore" ]; do
shift
if [ "$IGNORE_PKG" = "" ]; then
IGNORE_PKG="$1"
else
IGNORE_PKG="$IGNORE_PKG|$1"
fi
shift
done
if [ -f /etc/pacsync.conf ]; then
. /etc/pacsync.conf
else
message "error: Missing /etc/pacsync.conf configuration file!"
exit 1
fi
proto=`echo $SYNC_SERVER | sed 's|://.*||'`
# check for a download utility
if [ -x /usr/bin/snarf ]; then
ftpagent="/usr/bin/snarf"
elif [ -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 (snarf/lftp/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 $INSTALL_ROOT/var/cache/pacman/pkg/*
;;
*)
message "error: invalid operation"
exit 1
;;
esac