#!/bin/bash
#
# Name 		  : Intelligent Mirror Selector (ims)
# Project         : intelligent mirror selector for blackPanther OS
# Module          : sbin
# File            : mirrorselector
# License	  : GPL
# Version         : 0.6
# Author          : Charles Barcza
# Created On      : januar 2011
# Purpose         : periodic check mirrors availability
#---------------------------------------------------------------
#
. /etc/blackPanther-default-apps.conf

DEBUG=syslog
processname=`basename $0`
PIDFILE="/var/run/$processname.pid"
PID=$$

dbg()
{
    if [ "$DEBUG" = "syslog" ];then
	enter=""
       	logger ${@}
    elif [ -n "$DEBUG" ]; then
	enter="\n"
	quiet=-q
        space='echo'
       	$SETCOLOR_FAIL
       	echo -en "DBG: ${@}"
       	$SETCOLOR_NORMAL
    fi 
}

ICFG=/etc/urpmi/urpmi.cfg
MIRRORS=/etc/urpmi/mirrors
SRCLIST="/var/lib/urpmi/Update/MD5SUM"
GETLIST=$(mktemp -q /tmp/ims-getlist.XXXXXX)
MIRRORLIST=$(mktemp -q /tmp/ims-mirrorlist.XXXXXX)
MIRROR_PATH="$MIRRORLIST"
BEST_MIRROR=""
BEST_TIME=100
TMP=$(mktemp -q /tmp/ims-tmp.XXXXXX)
LIST=$(mktemp -q /tmp/ims-list.XXXXXX)
MIRROR=$(mktemp -q /tmp/ims-mirror.XXXXXX)

function mirrorlist() {
dbg " >> Listing mirrors...$enter"
cd /etc/urpmi/mirrors
ls > $MIRRORLIST
MIRRORNUM=$(cat $MIRRORLIST | wc -l)
}

function chkdiff() {
dbg " >> Run different check...$enter"
if [ -f "$GETLIST" ];then
    if [ -n "$DEBUG_VERBOSE" ];then
    echo "DIFFING......"
    echo "-SRC---------------------------------------------"
    cat $SRCLIST 
    echo "-GET---------------------------------------------"
    cat $GETLIST
    fi
    ret=`diff -q $SRCLIST $GETLIST 2>/dev/null`
    if [ -n "$ret" ]
    then
	dbg "$enterDetected different source...Need update"
     else
	dbg "Source is matched..."
    fi

fi
}

function cleanup() {
    dbg " >> Clean temporary files...$enter"
    rm -f $TMP
    rm -f $LIST
    rm -f $GETLIST
    rm -f $MIRROR
    rm -f $MIRRORLIST
    find /tmp/ -type f -name "ims-*" | xargs rm -f 2>/dev/null
    #find /tmp/ -type f -cmin +10 -name "ims-*" -exec rm -f \{\} \; 2>/dev/null
    dbg "iMirror Selector done...$enter"
    cat $PIDFILE > /tmp/ims-pid 2>/dev/null
    rm -f $PIDFILE
    kill $(cat /tmp/ims-pid) 2>/dev/null
    exit
}

function validating() {
dbg " >> Run validating...$enter"
[ "$RETRY" = "" ]&& RETRY=$(cat $LIST | wc -l)
    dbg "RETRY: $RETRY"
[ "$RETRY" = "0" ]&& cleanup
$space

chkaddr=$(cat $ICFG | grep -A 1 update | head -n 1|  awk '{ print $2 }') 
chkpath="$chkaddr/media_info/MD5SU"
dbg $chkpath
$space

wget $quiet -c "$chkpath" -O $GETLIST || ERROR=1

if [ -n "$ERROR" ]
then 
    echo "CFG: $cfg"
    dbg "Error source not valid?! Error in path or internet access?!$enter"
    RETRY=`expr $RETRY - 1`
    echo "RETRY: $RETRY"
    echo "LISTPATH:$LIST - $cfg"
    perl -pi -e "s,\[.* $cfg,,g" $LIST
    validating
    cleanup
 else
    dbg "Validated mirror source..."
    $space
  #  chkdiff
fi
}


function checkconf() {
dbg " >> Run Config check...$enter"
CONF=`readlink $ICFG`
NCONF=$MIRRORS/$cfg

if [ "$CONF" = "$NCONF" ]
then 
    dbg "Matched configuration...exiting $enter"
    logger "[Mirror selector]: Good matched configuration detected"
    cleanup
 else
    dbg "New speedy server detected ! Switch to: $TOP $enter"
    logger "[Mirror selector]: Switch to $TOP best server.."
    linking
fi
}

function checkservers() {
dbg " >> Pinging Servers..."
$space

for mirror in `cat $MIRROR_PATH` ; do
    M=$(ping $mirror -B -w 2 -n -c 4 2>/dev/null | grep rtt | awk -F '/' '{print $5}')
    if [ ! -z "$M" ]; then
        M=${M/.*};
        if [ "$M" -lt "$BEST_TIME" ]; then
            BEST_MIRROR=$mirror
    	    LASTSYNC=$(cat $MIRROR_PATH | grep -A 13 "$BEST_MIRROR" | tail -n 1 | cut -c 1-)
	    echo -e "[${M}] $mirror" >> $LIST
	fi
    fi

done
}

function sorting() {
dbg " >> Run sorting...$enter"
TOP=`cat $LIST | sort -n| head -n 1 | sed -e 's|\[.*\] ||'`
[ -n "$TOP" ]&&cfg=$TOP

}

function linking() {
dbg " >> Run linking...$enter"
if [ -n "$cfg" ];then
    dbg "Linking $MIRRORS/$cfg to $ICFG $enter"
    if [ -L "$ICFG" -o ! -f "$ICFG" ]
    then
	ln -sf $MIRRORS/$cfg $ICFG
      else
        dbg "Error? Owner modified install configuration $enter"
	logger "[Mirror selector]: Owner modified install configuration, automatice disabled temporary!"
    fi
 else
    if [ ! -f "$ICFG" ]
    then
	dbg "Connection error? Create failsafe mirror link.. $enter"
	logger "[Mirror selector]: Internet connection broken? Create failsafe mirror link.."
	ln -sf $MIRRORS/ftp.fsn.hu $ICFG
    else
        dbg "Error? Missing default mirror $enter"
	logger "[Mirror selector]: Default update mirror is missing! try again later.."
    fi
fi
}

function internet() {
echo
dbg " >> Run internet checking...$enter"
if [ -z `echo "$PATH" | grep "/usr/lib/blackPanther-default-apps/bin"` ]; then
    export PATH="/usr/lib/blackPanther-default-apps/bin:$PATH"
fi
NET=$(sh default-netchk)
if [ "$NET" != "OK" ];then
    dbg "Status is $NET ! Not have a active Internet connection..exiting$enter"
    trap cleanup SIGINT SIGTERM
    else
    dbg "Internet connection is $NET $enter"
fi 
}

function proc() {
if [ -f $PIDFILE ];then
    dbg "[iMirror Selector] Have a $PIDFILE, exiting"
    find /var/run/ -type f -cmin +30 -name $processname.pid -exec rm -f \{\} \; 2>/dev/null
 exit
fi
}

proc
echo $$ > $PIDFILE
dbg "Welcome to iMirror Selector! You System is a $(cat /etc/blackPanther-release| sed -e 's|release |v|' -e 's|for.*||') $enter"
internet
mirrorlist
if [ ! -n "$MIRRORNUM" ];then dbg "[iMirror Selector] ERROR IN MIRROR LIST! $enter" && cleanup ;fi
dbg "The listed mirrors: $MIRRORNUM $enter"
checkservers
dbg $(cat "$LIST" | sort -n)
$space
sorting
dbg "Best speed: $TOP $enter"
checkconf
#validating
#linking
#chkdiff
sleep 2
cleanup
trap cleanup SIGINT SIGTERM
dbg " >> iMirror Selector done...$enter"
