#!/bin/bash
#
# file:    sync_uribl_datafeed.sh
# version: 1.4
# date:    2015-11-30
# desc:    this is the client script that users can use to sync the 
#          uribl datafeeds.
#
# changelog: 
#  - v1.4 - add commented shopt line for errcho on ubuntu.  uncomment
#           if necessary.
#  - v1.3 - writes error messages to stderr so you'll get cron alerts 
#           on failures
#  - v1.2 - adds stale pid check so it doesnt prevent from running if 
#           it was killed while running, or you had a disk full event.
#
# contact: datafeed@uribl.com if you have problems

##########################################################################
# ADDITIONS TO CRON
##########################################################################
#
#    # 1-minute updates.
#    * * * * * root /usr/bin/sync_uribl_datafeed.sh 1>/dev/null
#

##########################################################################
# ADDITIONS TO RBLDNSD RUNFILE
##########################################################################
#
# Assuming you are using bind forwarders for the zone names, you can
# simply  setup your rbldnsd to answer whatever zone names you chose
# as tie them to a file.
#
#   multi.uribl.local:dnset:datafeed/uribl/multi.txt.gz \
#   black.uribl.local:dnset:datafeed/uribl/black.txt.gz \
#   etc.
#
# In this setup, there are no need for SOA or NS
# entries.   If you need to distribute load between multiple rbldnsd servers,
# you will need to use a combined zone format and create your own custom
# file with SOA and NS entries which point queries to the correct nameservers.
#
# To do this, you can use a combined zone format.  Each of the .txt or
# .txt.gz files have a defined $DATASET already, so you can create a
# custom file to specify your SOA and NS records and combine all the zones
# under it.
#
#  uribl.local:combined:datafeed/uribl.local.rbldnsd,datafeed/uribl/multi.txt,datafeed/uribl/black.txt, .. \
#
#  - In this setup, uribl.local is the main zone and you can name this whatever you want (ie yourdomain.tld).
#  - The uribl.local.rbldnsd file created in the main datafeed/ directory is what contains the SOA and NS
#    information.
#  - In this setup, multi is queried as multi.uribl.local (or multi.yourdomain.tld if you change it), black
#    as black.uribl.local, etc.
#
# If you need assistance setting any of this up, please contact datafeed@uribl.com
#

##########################################################################
# RSYNC CONFIG OPTIONS
##########################################################################
#

# Data Feed Speed. Default: 1
# We no longer offer 5 minute and 10 minute update intervals to new accounts.
UPDATE_INTERVAL=1

# rsync hosts.
RSYNCHOST="datafeed.uribl.com datafeed.rulesemporium.com"

# $RBLDIR below must be set according to your -r <path> that you
# use in the rbldnsd/run file above.
RBLDIR="/mirror/rblzones"

# $URIBLDIR should be the directory under $RBLDIR where you want
# rsync the URIBL zone files to.
URIBLDIR="uribl"

# .gz files require rbldnsd v0.996+
# our gzip's are built with --rsyncable.
ZONEEXT="txt.gz"

# the user your rbldnsd runs as.  we chown files after rsync to
# this user as well.  the default rbldnsd user on recent
# redhat packages is rbldns and the $RBLDIR is /var/lib/rbldnsd
RBLUSER="nobody"

# path to rsync binary and options
RSYNCBINARY="/usr/bin/rsync"

# rsync 2.6.8+ (proto 29)
RSYNCOPTIONS="-trlziv --timeout=60 --partial-dir=.incomplete --delete --exclude=.incomplete/ --exclude=*.tmp --delay-updates "

# rsync  2.6.3 or less (ie proto 28)
# RSYNCOPTIONS="-trlzv --timeout=60 --partial-dir=.incomplete --delete --exclude=.incomplete/ --exclude=*.tmp "

RUNFILE="/var/tmp/uribl-datafeed.pid"

##########################################################################
# DO NOT EDIT BELOW HERE
##########################################################################

MAXSLEEP=`expr 60 \* $UPDATE_INTERVAL`;
STATUS=0

# in Ubuntu, you may need to uncomment the shopt line
# in order for errcho to work correctly.
#shopt -s expand_aliases

alias errcho='>&2 echo'

if [ ! -d $RBLDIR ]; then
 errcho "RBLDIR $RBLDIR does not exist!  Cannot continue.."
 exit 1
fi

if [ ! -d "$RBLDIR/$URIBLDIR" ]; then
 errcho "URIBLDIR $RBLDIR/$URIBLDIR does not exist!  Cannot continue.."
 exit 2
fi

if [ ! -e "$RSYNCBINARY" ]; then
 errcho "$RSYNCBINARY does not exist! Cannot continue.."
 exit 3
fi

echo "Ok, Checking for run file"

if [ -e $RUNFILE ]; then
  echo "$RUNFILE exists, checking for running process."
  PIDCOUNT=`cat $RUNFILE | xargs ps | grep -v PID | wc -l`
  if [ $PIDCOUNT == 0 ] ; then
    echo "No running process found. Removing stale pid file."
    if [ -e $RUNFILE ]; then
      rm -f $RUNFILE
    fi
    echo $$ > $RUNFILE
   else 
    echo "Process currently running, cannot continue."
    exit 0;
  fi
else
  echo $$ > $RUNFILE
fi

# limit the max sleep to 5 minutes.
if [ $MAXSLEEP -gt 300 ]; then
 MAXSLEEP=300
fi

SLEEP=`expr $RANDOM \% $MAXSLEEP`
echo "Sleeping for $SLEEP Seconds..."
sleep $SLEEP

for host in $RSYNCHOST; do
  echo "Start Sync with $host"
  echo "$RSYNCBINARY $RSYNCOPTIONS $host::uribl_com_$UPDATE_INTERVAL/*$ZONEEXT $RBLDIR/$URIBLDIR"

  $RSYNCBINARY $RSYNCOPTIONS $host::uribl_com_$UPDATE_INTERVAL/*$ZONEEXT $RBLDIR/$URIBLDIR
  STATUS=$?
  if [ $STATUS -ne 0 ]; then
      errcho "Failed to Rsync from $host - Error Code: $STATUS"
  else
      echo "Rsync from $host OK!"
      break
  fi
done

# change ownership so rbldnsd can read the files
# if you run this script as the rbldnds user, then
# you can comment out the following 2 lines.
#chown -R $RBLUSER "$RBLDIR/$URIBLDIR"
#chmod 0400 $RBLDIR/$URIBLDIR/*

if [ -e $RUNFILE ]; then
  rm -f $RUNFILE
fi

exit $STATUS

##########################################################################
