#!/bin/bash

#
# Simple script to list the contents of remote FTP server
# directory and redirect into output file (for subsequent Java
# parsing.  See HMCRestoreTasklet.
#


#---------------------------------------------------------------------------------
# check contents of ftp log file when sending data
#---------------------------------------------------------------------------------
function checkForFtpDataTransferErrors {

    FTP_LOG=$1
    funcRC=0

    # look for server filesytem full/error codes first
    grep -q -i "^452" $FTP_LOG 2>&1 >/dev/null || grep -q -i "^451" $FTP_LOG 2>&1 >/dev/null || grep -q -i "^552" $FTP_LOG 2>&1 >/dev/null
    if [ $? -eq 0 ]; then
        funcRC=29
    else
        # Requested action not taken. File name not allowed (permission errors?)
        grep -q -i "^553" $FTP_LOG 2>&1 >/dev/null
        if [ $? -eq 0 ]; then
            funcRC=50
        else
            # Requested action not taken. File unavailable (e.g., file not found, no access)
            grep -q -i "^550" $FTP_LOG 2>&1 >/dev/null
            if [ $? -eq 0 ]; then
                funcRC=28
            else
                # login check...
#                grep -q -i "Login failed" $FTP_LOG 2>&1 >/dev/null || grep -q -i "Login incorrect" $FTP_LOG 2>&1 >/dev/null || grep -q -i "Identification failed" $FTP_LOG 2>&1 >/dev/null
                grep -q -i "^530" $FTP_LOG 2>&1 >/dev/null
                if [ $? -eq 0 ]; then
                    # error logging in - bad user/password(?)
                    funcRC=22
                else
                    # no critical errors detcted so far - see if operation succeeded.
                    grep -q -i "^226" $FTP_LOG 2>&1 >/dev/null || grep -q -i "^250" $FTP_LOG 2>&1 >/dev/null
                    if [ $? -eq 0 ]; then
                        funcRC=0
                    else
                        # If no file transfer, look for (known) errors
                        grep -q -i "not logged in" $FTP_LOG > /dev/null 2>&1
                        if [ $? -eq 0 ]; then
                            # Oops - error logging in
                            funcRC=21
                        else
                            grep -q -i "Connection refused" $FTP_LOG > /dev/null 2>&1
                            if [ $? -eq 0 ]; then
                                # Oops - error accessing server
                                funcRC=23
                            else
                                grep -q -i "unknown host" $FTP_LOG > /dev/null 2>&1
                                if [ $? -eq 0 ]; then
                                    # Oops - error accessing server
                                    funcRC=24
                                else
                                    grep -q -i "Not connected" $FTP_LOG > /dev/null 2>&1
                                    if [ $? -eq 0 ]; then
                                        # Oops - error accessing server
                                        funcRC=25
                                    else
                                        # last check for permission issues
                                        grep -q -i "Permission denied" $FTP_LOG > /dev/null 2>&1
                                        if [ $? -eq 0 ]; then
                                            # permission issues
                                            funcRC=26
                                        else
                                            # All other errors here
                                            funcRC=27
                                        fi
                                    fi 
                                fi
                            fi
                        fi   
                    fi
                fi
            fi
        fi
    fi
    
    echo "Exiting checkForFtpDataTransferErrors, funcRC = $funcRC." >> $LOG
    return $funcRC
}  


#---------------------------------------------------------------------------------
# check contents of ftp log file when changing directories
#---------------------------------------------------------------------------------
function checkForFtpChdirError {

    FTP_LOG=$1
    funcRC=0

    # First check for the '550' error code indicating the 'cd' comamnd failed.
    # Then check for the connection/login errors
    grep -i "^250 " $FTP_LOG 2>&1 >/dev/null
    if [ $? -eq 0 ]; then
        # Directory change ok
        funcRC=0
    else
        # Look for (known) errors
        grep -i "not logged in" $FTP_LOG > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            # Oops - error logging in
            funcRC=21
        else
            grep -i "Connection refused" $FTP_LOG > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                # Oops - error accessing server
                funcRC=23
            else
                grep -i "unknown host" $FTP_LOG > /dev/null 2>&1
                if [ $? -eq 0 ]; then
                    # Oops - error accessing server
                    funcRC=24
                else
                    grep -i "Not connected" $FTP_LOG > /dev/null 2>&1
                    if [ $? -eq 0 ]; then
                        # Oops - error accessing server
                        funcRC=25
                    else
                        # one more login check...
                        grep -i "Login failed" $FTP_LOG > /dev/null 2>&1
                        if [ $? -eq 0 ]; then
                            # Oops - error logging in
                            funcRC=22
                        else
                            # assuming past these login checks, now check for successful file xfer
                            grep -i "Permission denied" $FTP_LOG > /dev/null 2>&1
                            if [ $? -eq 0 ]; then
                                # permission issues
                                funcRC=26
                            else
                                # last check is for the 'cd' error
                                grep -i "^550 " $FTP_LOG 2>&1 >/dev/null
                                if [ $? -eq 0 ]; then
                                    funcRC=28
                                else
                                    # All other errors here
                                    funcRC=27
                                fi
                            fi
                        fi 
                    fi 
                fi
            fi
        fi   
    fi
    
    echo "Exiting checkForFtpChdirError, funcRC = $funcRC." >> $LOG
    return $funcRC
}


# function to list the contents of ftp site to log file
function generateFtpListFile {
    SERVER=$1
    USER=$2
    PASSWORD=$3
    DIRECTORY=$4

    echo "host $SERVER" > $TMP_FTP
    echo "user $USER" >> $TMP_FTP
    echo "pass $PASSWORD" >> $TMP_FTP

    if [[ "$DIRECTORY" == "" || "$DIRECTORY" == "." ]]; then
        # no remote directory specified
        echo "archive file query does not require a change of directory." >> $LOG
        if [ "${SERVER/*:*/:}" = ":" ]; then
            # has a ":" char, so assume this is IPv6
            LANG=en_US $FTP_CMD -f $TMP_FTP -l -d $FTP_LOG -t $TIMEOUT -o useMDTM=0 ftp://[$SERVER] > $FTP_INFO
        else
            LANG=en_US $FTP_CMD -f $TMP_FTP -l -d $FTP_LOG -t $TIMEOUT -o useMDTM=0 ftp://$SERVER > $FTP_INFO
        fi
#        /usr/lib/mit/bin/ftp -n -u -v $SERVER <<EOF 2>&1 > $FTP_LOG
#user $USER $PASSWORD
#ls
#quit
#EOF
        # Check for errors during the transfer
        checkForFtpDataTransferErrors $FTP_LOG
        funcRC=$?
    else
        # case here where remote target directory is specified

        ### Bypass this checking when using 'ncftp' - eCLipz GA3+
        echo "archive file query requires a change to directory named <$DIRECTORY>." >> $LOG
#        /usr/lib/mit/bin/ftp -n -u -v $SERVER <<EOF 2>&1 > $FTP_LOG
#user $USER $PASSWORD
#cd $DIRECTORY
#quit
#EOF
#        # First check for 'cd' errors (and the usual connection/login errors...)
#        checkForFtpChdirError $FTP_LOG
#        funcRC=$?
        funcRC=0
        
        if [ $funcRC == 0 ]; then
            # repeat ftp with actual data transfer
            if [ "${SERVER/*:*/:}" = ":" ]; then
                # has a ":" char, so assume this is IPv6
                LANG=en_US $FTP_CMD -f $TMP_FTP -l -d $FTP_LOG -t $TIMEOUT -o useMDTM=0 -W "cwd $DIRECTORY" ftp://[$SERVER] > $FTP_INFO
            else
                LANG=en_US $FTP_CMD -f $TMP_FTP -l -d $FTP_LOG -t $TIMEOUT -o useMDTM=0 -W "cwd $DIRECTORY" ftp://$SERVER > $FTP_INFO
            fi
#            /usr/lib/mit/bin/ftp -n -u -v $SERVER <<EOF 2>&1 > $FTP_LOG
#user $USER $PASSWORD
#cd $DIRECTORY
#ls
#quit
#EOF
            # now check for data transfer errors
            checkForFtpDataTransferErrors $FTP_LOG
            funcRC=$?
        fi
    fi    
    
    return $funcRC
}
# --------------  End Subroutines --------------------------------------------



# --------------- BEGIN MAIN PROGRAM  ----------------------------------------

# inputs to this routine are:
#
# $1 - retsore type (not used)
# $2 - ftp server
# $3 - user ID
# $4 - password
# $5 - remote directory (optional)

#
# Just in case we have NLS troubles reading system information...
#
LANG=en_US
export LANG

FTP_CMD=/usr/bin/ncftpls
TIMEOUT=120

TMP_FTP=/tmp/ftp_file_$$
>$TMP_FTP
chmod 600 $TMP_FTP

FTP_LOG=/var/hsc/log/ftp.log
FTP_INFO=/var/hsc/log/ftp.info

LOG=/var/hsc/log/listRemoteArchive.log

# Start log to record backup actions.
echo -e "List remote archive on ftp server log for `date`, server = $2, user ID = $3, directory = <$5>.\n" > $LOG

generateFtpListFile $2 $3 $4 $5
rc=$?

if [ $rc != 0 ]; then
    # upon errors, append ftp log to log
    cat $FTP_LOG >> $LOG

    # The way this is currently implemented,we might end up failing the internal 'cwd' command,
    # but still listing the user's "home dir". Remove it.
    rm -f $FTP_INFO
    echo -e "Data tranfer function completed, with errors." >> $LOG
else
    echo -e "Data transfer function completed, no errors." >> $LOG

    # need to be able to erase file back in the GUI for any user
    chmod +w $FTP_INFO
fi

rm -f $TMP_FTP
rm -f $FTP_LOG

exit $rc
