#!/bin/sh
#
#  FTP transfer script
#  Adtecinc
#  Mike Goins
#
#  Usage: transfer ip_address put|get local_file [remote file]
#  relative paths may be used for local file or remote file
#  host ip of "HOSTIPADDRESS" is used, then the existing 
#  HOSTIPADRESS
#  from the mirror command is used to send file.  This is 
#  primarily intended to be used internally but would also
#  be available to the CL.

# TODO:  Test globbing
# TODO:  Add STOP, Mirror, STATUS commands
# TODO:  Fix Put return code 255
# TODO:
# TODO:



shopt -s -o nounset                   # force use of only explicit variables
declare -rx SCRIPT=${0##*/}           # script name 
declare -r SEP="/"                    # system separator
declare -r PUT_CMD="put"
declare -r GET_CMD="get"
declare -r TAG=$'\040\040\040\040[FTPC]'                  # syslog tag
declare -r PRI="info"                 # syslog priority
declare -r HOST="HOSTIPADDRESS"       # define the default flag
declare -r HOST_FORCE="HIP_FORCE"       # define the override flag.

declare LOCAL_MEDIA_DIR
declare -i RET=0

declare -ri LAN_NOT_READY=21          # Error codes        
declare -ri BAD_ARGUMENTS=2                          
declare -ri ALREADY_FTPING=25
declare -ri NO_HOST_IP=26       
declare -ri NOT_FTPING=24
declare -ri FILE_NOT_FOUND=17


# declared variables, imported in cfg file.
declare HOSTIPADDRESS
declare HOSTMODE=MirrorList
declare REMOTE_DIR                      # not in API
declare FTP_PORT=21                         # not in API
declare CLTUSERPASSWORD=adtec,408adtec2231
declare FTPCLIENTPASV=passive
declare ENABLE_NEWER=true                   # not in API
declare MIRRORLISTFILE="LIST.MVL"
declare HOSTTIMER=60
declare FTPTIMEOUT=10
declare FTPDATATIMEOUT=45
declare DONOTREPLACEMPEG=NO

declare PID=$$
declare STAT_DIR=/var/tmp/

#  import CFG file
declare CFG_FILE="/etc/sysconfig/mirror.cfg"
test -f $CFG_FILE && . $CFG_FILE


# here we are going to test to see if we are NOT in CCMS mode and
# received the HOSTIPADDRESS argument. This is to prevent the DPI 
# from sending VERIFICATIONS while not in CCMS mode.
if [ $# -gt 0 ]; then
  if [ "${1}" == "HOSTIPADDRESS" ]; then
    case "$HOSTMODE" in
        CCMS|Ccms|ccms)   # This is the mode where "HOSTIPADDRESS" argument is allowed
        ;;
        *)                # Other modes do not allow "HOSTIPADDRESS" argument
            logger -p $PRI -t "${TAG}" Bad host mode: $HOSTMODE
            exit $BAD_ARGUMENTS
        ;;
    esac
  fi
fi
# sanity check for IP
#if [ -z "$HOSTIPADDRESS" ]; then
#   exit $NO_HOST_IP
#fi

# import global, not yet needed
test -f "/etc/env.global" && . "/etc/env.global"

# establish path to tnftp utility
declare FTP="/usr/local/bin/tnftp"

# set the media path from global file, to be used on GET
#function set_media_path () {
   #setup local media dir
declare TMP=$CONTENT_PATH
if [ -d "$TMP" ]; then   
   LOCAL_MEDIA_DIR=$TMP
else # use default
   LOCAL_MEDIA_DIR="/media/hd0/media/"
fi
#}

#  Upload file routine.  Simple wrapper around 'tnftp -u'
function put_file () {
    local SERVER
    local REMOTE_NAME
    local LOCAL_NAME
    if [[ $2 != /* ]]; then   # fix reltaive path
         LOCAL_NAME="${LOCAL_MEDIA_DIR}${2}"
    else 
         LOCAL_NAME="$2"
    fi
    #if [ -f "$LOCAL_NAME" ] || [ -d "$LOCAL_NAME" ]; then   #could setup for dirs and files
    if [ -f "$LOCAL_NAME" ]; then   # arg is file and exists
        ##  test for argv and assign the remote name for upload.  Can be same.
        #if [ $# -eq "2" ]; then
        #    REMOTE_NAME=`basename "${2}"`
        #else 
        #    # if the remote name is absolute, then it may fail under chroot logins.
        REMOTE_NAME="${3}"
        #fi
        #  if defined "tag" is used, then just use the mirror HostipAddress.
        if [ "${1}" == $HOST ] || [ "${1}" == $HOST_FORCE ] ; then
            SERVER=$HOSTIPADDRESS
        else 
            SERVER=${1}
        fi
        USERNAME=${4/,/:}
        USERPASS=${USERNAME//@/%40}
        ${FTP} -viu ftp://${USERPASS}@${SERVER}:${FTP_PORT}${SEP}${REMOTE_NAME} ${LOCAL_NAME} > ${STAT_DIR}ftp_${SERVER}_${PID}
        RET=$?
        if [ "$RET" -eq "255" ]; then
           logger -p $PRI -t "${TAG}" "Uploaded: ${2} to ${SERVER}:${FTP_PORT}${SEP}${REMOTE_NAME}"
           # WARN: Not sure why a Put command returns 255
        else
           logger -p $PRI -t "${TAG}" "Upload failed: ${2} to ${SERVER}:${FTP_PORT}${SEP}${REMOTE_NAME}"
        fi
    else    
        RET=$FILE_NOT_FOUND
    fi
    return $RET
}

function get_file () {
    local SERVER
    local LOCAL_NAME
        #  test for argv and assign the remote name for upload.  Can be same.
#        if [ $# -eq "2" ]; then
#            LOCAL_NAME="${2}"
#        else 
#            LOCAL_NAME="${3}"
#        fi
        if [ "${1}" == $HOST ] || [ "${1}" == $HOST_FORCE ] ; then
            SERVER=$HOSTIPADDRESS
        else 
            SERVER=${1}
        fi
	
        #  if defined "tag" is used, then just use the mirror HOT.
        if [ "${1}" == $HOST ]; then
            SERVER=$HOSTIPADDRESS
        else 
            SERVER=${1}
        fi
        USERNAME=${4/,/:}
        USERPASS=${USERNAME/@/%40}
        local CMD="${FTP} -Vi -o "${LOCAL_MEDIA_DIR}${SEP}${3}" ftp://${USERPASS}@${SERVER}:${FTP_PORT}${SEP}${2}"
        logger -p $PRI -t "${TAG}" "Downloading: ${SERVER}:${FTP_PORT}${SEP}${2} to ${LOCAL_NAME}"
        #echo $CMD
        $CMD &>/dev/null
}

# not ideal but works
#set_media_path  

#  main body of script, just parses positional arguments.
if [ $# -lt "3" ]; then
	 echo "Usage: transfer  ip_address get remote_filename [local_filename]"
	 echo "       transfer  ip_address put local_file [remote_file]"
	 echo "       transfer  ip_address get local_file [remote_file] username password"
	 echo "       transfer  ip_address put local_file [remote_file] username password"
	 echo "A utility for ftp transferring files."
	 echo "If username and password not supplied then CPW is used."
	 exit $BAD_ARGUMENTS
elif [ $# -eq "3" ]; then 
    # two args: IPA put localfile
    if [ "$2" == "${PUT_CMD}" ]; then
        put_file "$1" "$3" `basename "${3}"` "${CLTUSERPASSWORD}"
        exit $?
    elif [ "$2" == "${GET_CMD}" ]; then
        get_file "$1" "$3" `basename "${3}"` "${CLTUSERPASSWORD}"
        exit $?
    else
        exit $BAD_ARGUMENTS
    fi
elif [ "$#" -eq "4" ]; then 
    # IPA put localfile remotefile
    if [ "$2" == "${PUT_CMD}" ]; then
        put_file "$1" "$3" "$4" "${CLTUSERPASSWORD}"
        exit $?
    elif [ "$2" == "${GET_CMD}" ]; then
        get_file "$1" "$3" "$4" "${CLTUSERPASSWORD}"
        exit $?
    else
        exit $BAD_ARGUMENTS
    fi
elif [ "$#" -eq "5" ]; then 
    # IPA put localfile username password
    if [ "$2" == "${PUT_CMD}" ]; then
        put_file "$1" "$3" `basename "${3}"` "${4},${5}"
        exit $?
    elif [ "$2" == "${GET_CMD}" ]; then
        get_file "$1" "$3" `basename "${3}"` "${4},${5}}"
        exit $?
    else
        exit $BAD_ARGUMENTS
    fi
elif [ "$#" -eq "6" ]; then 
    # IPA put localfile remotefile username password
    if [ "$2" == "${PUT_CMD}" ]; then
        put_file "$1" "$3" "$4" "${5},${6}"
        exit $?
    elif [ "$2" == "${GET_CMD}" ]; then
        get_file "$1" "$3" "$4" "${5},${6}" 
        exit $?
    else
        exit $BAD_ARGUMENTS
    fi
else 
    exit $BAD_ARGUMENTS
fi
