#!/bin/sh
##############################################################################
#
# cmirror - Bourne Shell (Configurable Mirror Script) version 1.5 (8/95)
#	by:	Adam Radulovic (adampr@i-link.net,adampr@engin.umich.edu)
#
# To explain little the search strings, here is a few examples:
# To search for just "linux" do:
# linux
#
# To search for "linux" and "patch" do:
# linux\|patch
#
# To search for "linux", "patch" and "INDEX" do:
# linux\|patch\|INDEX
#
# Variable Definitions || Read all the definitions carefully, it is the engin
#	 	       -- of this whole script
#
#
# $HOST			: Ftp site where you wish to receive new files from.
# $IN_DIR 		: Mirror directory on localhost to place files.
# $HOST_FROM_DIR	: Mirror directory on remote $HOST to receive files from.
# $IFL			: Information File Location (warning: do not do ~ ).
# $ENOTICE		: Email address for new files Notice (put 0 to disable).
# $SEARCH		: Enter a substring to search by, remember if you want.
#			- to search for more then one do first\|second , etc..
#			- Leave it blank to mirror all the files from remote
#			- $HOST.
# $RMSRCH		: Enter a substring to search for and exclude from your
#			- mirror site, even though they are located on the  
#			- remote $HOST and found by $SEARCH. If you do not want
#			- anything to be removed, place "/". (This will remove
#			- diretories out of the list since cmirror receives
#			- only one directory at a time.  
# $TWO			: Default is 1, but if you log onto a site with
#			- only one file owner identifier set this to 0
#			- (i.e. ftp.funet.fi does this). 
# $RM			: Default is 2. If 2 moves file to specified directory
#			- for $OLD. If 1 removes files of the localhost if they
#			- do not appear on the remote host and are not inside
#			- $NORM. If 0, leaves files on localhost.
# $OLD			: If $RM is set to 2, this should have a directory to 
#			- place the old files that were found on localhost and
#			- not on the remote $HOST.
# $NORM			: Enter a subtring to search for in the localhost 
#			- mirroring directory, and keep even though file is
#			- not located on remote $HOST. If you do not want
#			- anything to be saved, place "xxxxxxxx". 
# $MODE			: The mode to change the new files to with chmod.
# $OWNER		: The ownership to change the new files to with chown.
#
##############################################################################
#
# cmirror variables
#

HOST="uiarchive.cso.uiuc.edu"
IN_DIR="/home/ftp/pub/Linux/kernel/v1.3"
HOST_FROM_DIR="/pub/systems/linux/sunsite/kernel/v1.3"
IFL="/root/.mirror"
ENOTICE="EMAIL_ADDRESS_HERE"
SEARCH="linux\|patch|/"
RMSRCH="NCEMRSoft\|linux-1.3.0.tar.gz\|patch-1.3.1.gz"
TWO="1"
RM="2"
OLD="/tmp"
NORM="linux-1.3.15.tar.gz\|patch-1.3.15.gz"
MODE="644"
OWNER="ftp.wheel"

#
##############################################################################
#
# cmirror script
#

# Check for a DNS entry for $HOST, if not found, quit out
NSCHECK=`nslookup \$HOST 2> /dev/null | grep "Non-existent"`
if [ $NSCHECK ] ; then

        echo "No DNS entry for $HOST, exiting..."
        exit 1;

fi

# Moving Into directory where mirrored files go
cd $IN_DIR

# Clean Up
rm $IFL/retry 2> /dev/null

# Getting file information out of the localhost for the mirrored directory 
ls -l | grep "$SEARCH" | grep -v "$RMSRCH" | awk '{printf ("%s %s\n",$5,$9)}' > $IFL/crntfiles

# Getting file information from $HOST in the $HOST_FROM_DIR
if [ "$TWO" = "0" ] ; then

	# If you are logging onto a site (i.e. ftp.funet.fi) with only one (two default)
	# file owner identifier
        echo "ls -l" | ncftp $HOST:$HOST_FROM_DIR 1> $IFL/files 2> $IFL/files
        TESTME=`cat $IFL/files`
        cat $IFL/files | grep  "$SEARCH" | grep -v "$RMSRCH" | awk '{printf ("%s %s\n",$4,$8)}' > $IFL/files

else

        echo "ls -l" | ncftp $HOST:$HOST_FROM_DIR 1> $IFL/files 2> $IFL/files
        TESTME=`cat $IFL/files`
        cat $IFL/files | grep  "$SEARCH" | grep -v "$RMSRCH" | awk '{printf ("%s %s\n",$5,$9)}' > $IFL/files

fi

# Making sure FTP did not exit with an error
TESTING=`echo "$TESTME" | grep "Login failed.\|User anonymous access denied.\|Not connected.\|No route to host\|Network is"`
if [ "$TESTING" ] ; then

	echo "Error starting FTP with $HOST::$TESTING"
	exit 1;

fi

# Checks if there is a need to receive files
LATEST=`diff \$IFL/crntfiles \$IFL/files | awk '{print \$3}' | sort | uniq`

# If there are files that need to be updated/received, takes proper actions
if [ "$LATEST" = "" ] ; then

	echo "No updates, exiting..."
	exit 1;

else
# Giving the list of files need updating
        echo Updating Files $LATEST


        # Removes files that are located on localhost and not on the remote host        
	if [ "$RM" = "1" ] ; then

                for i in $LATEST
                do
                        rm $i 2> $IFL/rmaction
                done

        # Moves files into the $OLD directory if files are located on locahost
        # and not on remote $HOST
        elif [ "$RM" = "2" ] ; then

                for i in $LATEST
                do
                        mv $i $OLD 2> $IFL/mvaction
                done

        fi

        ls -l | grep "$SEARCH" | grep -v "$RMSRCH" | awk '{printf ("%s %s\n",$5,$9)}' > $IFL/crntfiles
        GETTING=`diff \$IFL/crntfiles \$IFL/files | awk '{print \$3}' | sort | uniq | grep -v "\$NORM" `
        
	
	if [ "$ENOTICE" = "0" ] ; then

                echo "^GReceiving new files from $HOST :: $GETTING ::"

        elif [ "$GETTING" ] ; then

                echo "^GReceiving new files from $HOST :: $GETTING ::" | mail $ENOTICE
        
	fi

        RETRY="1"
        # Start loop to get all the files inside $GETTING
        while test $RETRY -eq 1
        do
                # Reset RETRY variable
                RETRY="0"

                # Receives all the files in the $GETTING variable
                for i in $GETTING
                do
                        # Notify what file is currently being received
                        echo Currently getting file - $i -

                        # Record the ftp message in case there was a problem
                        FTPMSG=`echo "get "$i | ncftp $HOST:$HOST_FROM_DIR | grep "Login failed."`

                        # If there was a problem, record file name for later retry                        
			if [ "$FTPMSG" ] ; then

                                echo $i >> $IFL/retry
                                RETRY="1"
                                echo Failed to receive $i, will retry later

                        else

                                chmod $MODE $i
                                chown $OWNER $i

                        fi

                done

                if [ "$RETRY" = "1" ] ; then

                        # New batch which failed that needs to be retrieved
                        GETTING=`cat $IFL/retry`

                        # No need for the retry file
                        rm $IFL/retry 2> /dev/null

                fi

        done

fi

# end cmirror sciprt
##############################################################################
#
#EOF
#
