#! /bin/sh

# uscan: This program looks for watchfiles and checks upstream ftp sites
# for later versions of the software.
#
# Originally written by Christoph Lameter <clameter@debian.org> (I believe)
# Modified by Julian Gilbey <jdg@debian.org>
# HTTP support added by Piotr Roszatycki <dexter@debian.org>
# Copyright 1999, Julian Gilbey
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

TEXTDOMAIN=devscripts
LIBDIR=/usr/share/devscripts
PROGNAME=`basename $0`
PKG_VERSION=2.5.8.2

usage () {
    echo \
$"Usage: $PROGNAME [--help|--version] dir ...
  Process watchfiles in all .../debian/ subdirs of those listed
  to check for upstream releases"
}

version () {
    echo \
$"This is $PROGNAME, from the Debian devscripts package, version $PKG_VERSION
This code is copyright 1999 by Julian Gilbey, all rights reserved.
Original code by Christoph Lameter.
This program comes with ABSOLUTELY NO WARRANTY.
You are free to redistribute this code under the terms of the
GNU General Public License, version 2 or later."
}

if [ $# -gt 0 ]
then
    if [ "$1" = --help ]; then usage; exit 0; fi
    if [ "$1" = --version ]; then version; exit 0; fi
fi

# Upstream watcher to be executed from cron

if [ "$1" = "" ]; then
    DIRS="."
else
    DIRS="$*"
fi

test -z "$USER" && USER=$LOGNAME

# Process a single watch item
# $1 = Remote Site
# $2 = Directory on site
# $3 = Pattern to match, with (...) around version number part
# $4 = Last Version we have (or debian for the current debian version)
# $5 = Actions to take on successful retrieval
watch()
{
#    echo "Entering watch with $*"
    FILEGLOB=`echo "$3" | tr -d '()'`
    if [ "$FILEGLOB" = "$3" ]; then
	# Old style watchfile, pattern uses ? and * shell wildcards
	MATCHING=`echo "$3" | sed -e 's/[?*]/(&/; s/\([?*]\)\([^?*]*\)$/\1)\2/; s/\./\\\./g; s/?/./g; s/\*/.*/g'`
	STYLE="old"
	echo $"Warning: using old style of filename pattern: $3!" >&2
	echo $"(This might lead to incorrect results.)" >&2
    else
	MATCHING="$3"
	STYLE="new"
    fi
    # What is the most recent file, based on the filenames?  We use
    # versort for this purpose.
    if ( echo "$1" | grep "^http://" >/dev/null ); then
	if ! (command -v wget &>/dev/null); then
	    echo $"You need to install the wget package to use http:// sites!" >&2
	    return
	fi
	NFILEVER=`wget -O - -o /dev/null "$1$2" | tr '"' '\012' | \
	    perl -ne '/^'"$MATCHING"'$/ && print "$1\t$_"' | \
		$LIBDIR/versort | tail -1`
    else
	NFILEVER=`echo "user anonymous ${USER}@
passive
dir $2" | \
	    ftp -n $(echo $1 | sed 's%^ftp://%%') | tr ' ' '\012' | \
	    perl -ne '/^'"$MATCHING"'$/ && print "$1\t$_"' | \
	    $LIBDIR/versort | tail -1`
    fi

    # Were there any matches found?
    if [ "$NFILEVER" ]
    then
	# Yes there were.

	# The original version of the code didn't use (...) in the watch
	# file to delimit the version number; thus if there is no (...)
	# in the pattern, we will use the old heuristics, otherwise we
	# use the new.

	if [ "$STYLE" = "old" ]
	then
	    # Old-style heuristics
	    eval `echo "$NFILEVER" | perl -nle '/^\D*(\d[\d.]*\d)\D*\t(.*)$/ && print "NFILE=$2 NVER=$1" or /^(.*)\t(.*)$/ && print "NFILE=$2"'`
	    if [ -z "$NVER" ]
	    then
		echo $"Couldn't determine a pure numeric version number from the file name: $NFILE" >&2
		echo $"Please use a new style watchfile instead!" >&2
		return
	    fi

	    X="$NFILE"
	    # Figure out the type of archive
	    case "$X" in
		*.tar.gz)  X=`expr "$X" : "\(.*\).tar.gz"` ;;
		*.tgz)     X=`expr "$X" : "\(.*\).tgz"` ;;
		*.tar)     X=`expr "$X" : "\(.*\).tar"` ;;
		*.zip)     X=`expr "$X" : "\(.*\).zip"` ;;
		*) echo $"Warning: Unknown Archive type $X" >&2 ;;
	    esac

	else
	    # We have a new, Perl-style regexp with an explicit (...) in
	    # the file pattern which will give us the version number.  We
	    # just have to extract it!
	    eval `echo "$NFILEVER" | perl -ne '/(.*)\t(.*)/ && print "NFILE=$2 NVER=$1";'`
	fi
			
	OURVER="$4";
	if [ "$4" = "debian" ]; then
	    OURVER="$SUVERSION"
	fi
	echo $"Newest version on remote site is $NVER, local version is $OURVER"
	if [ "$NVER" = "$OURVER" ]; then
	    echo $" => Package is up to date"
	    return
	fi
	# We use dpkg's rules to determine whether our current version
	# is newer or older than the remote version.
	if dpkg --compare-versions "$OURVER" gt "$NVER"; then
	    echo $" => remote site does not have current version"
	    return
	fi
	if [ -f ../$NFILE ]; then
	    echo $" => $NFILE already in package directory"
	    return
	fi
	echo $" => Newer Release available"
	echo $"-- Downloading updated Package $NFILE"
	# Download newer package
	if ( echo "$1" | grep "^http://" >/dev/null ); then
	    if ( echo "$NFILE" | grep "^/" >/dev/null ); then
		( cd ..; wget -o /dev/null "$1$NFILE" ) || {
		    echo $"Couldn't download file: wget failed for some reason." >&2
		    return
		}
	    else
		( cd ..; wget -o /dev/null "$1$2/$NFILE" ) || {
		    echo $"Couldn't download file: wget failed for some reason." >&2
		    return
		}
	    fi
	else
	    (
		cd ..; echo "user anonymous ${USER}@
cd $2
get $NFILE" | \
		    ftp -n $(echo $(echo $1 | sed 's%^ftp://%%') | sed 's%^ftp://%%')
	    ) || {
		echo $"Couldn't download file: ftp failed for some reason." >&2
		return
	    }
	fi

	# Do whatever the user wishes to do
	if [ "$5" ]; then
	    echo $"-- Executing user specified script $5 $NFILE $NVER"
	    $5 ../$NFILE $NVER
	fi
    else
	echo $"No match on site $1 pattern $3" >&2
    fi
}

process_watchfile()
{
    read X
    while [ "$X" ]; do
	watch $X
	read X
    done
}

mustsetvar () {
    if [ "x$2" = x ]
    then
	echo >&2 $"$0: unable to determine $3"
	return 1
    else
	# echo $"$0: $3 is $2"
	eval "$1=\"\$2\""
	return 0
    fi
}

ODIR=`pwd`
echo $"-- Scanning for watchfiles in $DIRS"
for i in `find $DIRS -type d -name "debian" 2>/dev/null`; do
    DIR=${i%/debian}
    cd $DIR
    if [ -r "debian/watch" ] && [ -r "debian/changelog" ]; then
        OK=1
	echo $"-- Found watchfile in $DIR"
	# Figure out package info we need
	mustsetvar PACKAGE "`dpkg-parsechangelog | sed -n 's/^Source: //p'`" \
	    $"source package from `pwd`/debian/changelog" || OK=0
	mustsetvar VERSION "`dpkg-parsechangelog | sed -n 's/^Version: //p'`" \
	    $"source version from `pwd`/debian/changelog" || OK=0
	UVERSION=`expr "$VERSION" : '\(.*\)-[0-9.]*$'`
	if [ $OK -eq 1 -a -n "$UVERSION" ]; then
	    SUVERSION=`echo "$UVERSION" | perl -pe 's/^\d+://'`
	    sed -e '/^#/d; /^[ 	]*$/d' debian/watch | process_watchfile
	else
	    echo $"   but couldn't determine upstream version number; skipping"
	fi
    elif [ -r debian/watch ]; then
	echo $"-- Found watchfile in $DIR, but couldn't find/read changelog; skipping" >&2
    elif [ -f debian/watch ]; then
	echo $"-- Found watchfile in $DIR, but it is not readable; skipping" >&2
    fi
    cd $ODIR
done
echo $"-- Scan finished"
