#!/bin/bash
#
#-------------------------------------------------------------------------------
# (S)FTPs files from the HMC efix (s)ftp server
#
# Possible return codes are:
#
# 0 - no error
# 1 - usage error, invalid argument
# 2 - invalid userID/password combination
# 3 - source file not found on server
# 4 - '(s)ftp' connection error
# 5 - "other" 'ftp' error
# 6 - target file not written to HMC
# 7 - No special hmcdump partition
# 8 - bzImage not written
# 9 - initrd.gz not written
# 10 - disk1.img not written
# 11 - disk2.img not written
# 12 - disk3.img not written
# 255 - other sftp error (expect related error)
#
#-------------------------------------------------------------------------------
#
# Usage: getRemoteUpgrFiles <server> <remote-dir> <username> <password> [sftp]
#
# Defaults to 'ftp' if the 'sftp' option is not given.
#

function exit_cleanup {
#   rm -f $FTP_LOG_FILE
   rm -f $TMP_FTP
   chown hscroot.hmc $FTP_LOG_FILE 2>/dev/null
   cd /
   umount $INSTALL_DIR 2>/dev/null
   exit $1
}

function getReturnCode {
    case "$1" in
    "bzImage" )
	exit_cleanup 8
	;;
     "initrd.gz" )
        exit_cleanup 9
	;;
     "disk1.img" )
        exit_cleanup 10
	;;
     "disk2.img" )
        exit_cleanup 11
	;;
     "disk3.img" )
	exit_cleanup 12
	;;
     * )
        exit_cleanup 6
	;;
     esac
}

function ftpRemoteFiles {
   FTP_SERVER=$1
   REMOTE_DIR=$2
   USER=$3
   PASS=$4
   >$FTP_LOG_FILE 
   >$TMP_FTP
   chmod 600 $TMP_FTP
   echo "host $FTP_SERVER" > $TMP_FTP
   echo "user $USER" >> $TMP_FTP
   echo "pass $PASS" >> $TMP_FTP
   LANG=en_US $FTP_CMD -f $TMP_FTP -d $FTP_LOG_FILE -V -t $TIMEOUT -o useMDTM=0 $INSTALL_DIR $REMOTE_DIR/bzImage $REMOTE_DIR/initrd.gz $REMOTE_DIR/disk1.img $REMOTE_DIR/disk2.img $REMOTE_DIR/disk3.img

} # end function getRemoteFiles

function sftpRemoteFiles {
   FTP_SERVER=$1
   REMOTE_DIR=$2
   USER=$3
   PASS=$4

   /opt/hsc/bin/sftpGetFile $FTP_SERVER $REMOTE_DIR/bzImage $USER $PASS $INSTALL_DIR 2>&1 > $FTP_LOG_FILE
   SFTP_RC=$?
   if [ $SFTP_RC -ne 0 ]; then
      return
   fi
   /opt/hsc/bin/sftpGetFile $FTP_SERVER $REMOTE_DIR/initrd.gz $USER $PASS $INSTALL_DIR 2>&1 > $FTP_LOG_FILE
   SFTP_RC=$?
   if [ $SFTP_RC -ne 0 ]; then
      return
   fi
   /opt/hsc/bin/sftpGetFile $FTP_SERVER $REMOTE_DIR/disk1.img $USER $PASS $INSTALL_DIR 2>&1 > $FTP_LOG_FILE
   SFTP_RC=$?
   if [ $SFTP_RC -ne 0 ]; then
      return
   fi
   /opt/hsc/bin/sftpGetFile $FTP_SERVER $REMOTE_DIR/disk2.img $USER $PASS $INSTALL_DIR 2>&1 > $FTP_LOG_FILE
   SFTP_RC=$?
   if [ $SFTP_RC -ne 0 ]; then
      return
   fi
   /opt/hsc/bin/sftpGetFile $FTP_SERVER $REMOTE_DIR/disk3.img $USER $PASS $INSTALL_DIR 2>&1 > $FTP_LOG_FILE
   SFTP_RC=$?
   if [ $SFTP_RC -ne 0 ]; then
      return
   fi
} # end function sgetRemoteFiles

function ftpChecksumFile {
   FTP_SERVER=$1
   REMOTE_DIR=$2
   USER=$3
   PASS=$4
   >$FTP_LOG_FILE
   LANG=en_US $FTP_CMD -u $USER -p $PASS -d $FTP_LOG_FILE -V -t $TIMEOUT -o useMDTM=0 $FTP_SERVER $INSTALL_DIR $REMOTE_DIR/hmcnetworkfiles.sum
} # end function ftpChecksumFile

function sftpChecksumFile {
   FTP_SERVER=$1
   REMOTE_DIR=$2
   USER=$3
   PASS=$4

   /opt/hsc/bin/sftpGetFile $FTP_SERVER $REMOTE_DIR/hmcnetworkfiles.sum $USER $PASS $INSTALL_DIR 2>&1 > $FTP_LOG_FILE

} # end function sftpChecksumFile



#-------------------------------------------------------------------------------
# "Main" program start   
#-------------------------------------------------------------------------------

LANG=en_US
export LANG
TIMEOUT=60

FTP_LOG_FILE=/var/hsc/log/getupgrftp.log
TMP_FTP=/tmp/ftp_file$$
FTP_CMD=/usr/bin/ncftpget
INSTALL_DIR=/hmcdump
FILE_LIST="bzImage initrd.gz disk1.img disk2.img disk3.img"
XFER_METHOD=ftp
SFTP_RC=0

if [ "$1" = "" ]
then
   echo "Usage: getRemoteUpgrFiles <ftp server> <remote dir> <user> <password> [sftp]"
   exit_cleanup 1
fi
if [ ! -d $INSTALL_DIR ]; then
   mkdir -p $INSTALL_DIR
fi
mount $INSTALL_DIR 2>/dev/null
if [ $? -ne 0 ]; then
  # need to do something here, either the filesystem is not created
  cat /etc/fstab | grep -q "$INSTALL_DIR"
  if [ $? -ne 0 ]; then
  # something is wrong fstab does not have the special partition needed
     exit_cleanup 7 
  fi
fi
if [ "$5" = "sftp" ];then
  XFER_METHOD=sftp
fi
cd $INSTALL_DIR
#-------------------------------------------------------------------------------
# 'ftp' the file from service server
#-------------------------------------------------------------------------------
if [ "$XFER_METHOD" = "ftp" ];then
  ftpRemoteFiles $1 $2 $3 $4 
else
  sftpRemoteFiles $1 $2 $3 $4 
fi

# good transfer, now see if the file actually got written to the HMC
if [ $? -eq 0 ]; then
  all_transferred=1
  for i in $FILE_LIST
  do
    if [ ! -f $INSTALL_DIR/$i ]; then
      all_transferred=0
      break
    fi
  done
  if [ $all_transferred -eq 1 ]; then
     # Now make sure at the minimum the file size are all ok, i.e none zero
     typeset -i fileSize
     zero_filesize=0
     for i in $FILE_LIST
     do
        fileSize=`/usr/bin/du -m $INSTALL_DIR/$i | /usr/bin/cut -f1`
        if [ $fileSize -eq 0 ]; then
	   zero_filesize=1
	   break
	fi
     done 
     if [ $zero_filesize -eq 1 ]; then
        getReturnCode $i
     fi
     # Now make sure at the checksum the file size are all ok
     rm -f $INSTALL_DIR/hmcnetworkfiles.sum 2>/dev/null
     if [ "$XFER_METHOD" = "ftp" ];then
       ftpChecksumFile $1 $2 $3 $4 
     else
       sftpChecksumFile $1 $2 $3 $4 
     fi
     if [ -f $INSTALL_DIR/hmcnetworkfiles.sum ]; then
  	for i in $FILE_LIST
	do
	   s1=`/usr/bin/sum $INSTALL_DIR/$i | cut -d' ' -f1`
	   s2=`/usr/bin/grep "$i" $INSTALL_DIR/hmcnetworkfiles.sum | cut -d':' -f1`
	   if [ "$s1" != "$s2" ]; then
	      getReturnCode $i
	   fi
	done
     fi
     exit_cleanup 0
  else
    getReturnCode $i
  fi
else
   if [ "$XFER_METHOD" = "ftp" ];then
     # look for "Transfer complete", "Successful transfer" or equivalent msg code
     # careful on grep'ing for all these values - note the space
     grep -q "^226" $FTP_LOG_FILE 2>&1 >/dev/null
     if [ $? -ne 0 ];then
       # ftp failed for some reason - find out why
  
       # special case for i5 OS FTP
       grep -q "^250" $FTP_LOG_FILE 2>&1 >/dev/null
       if [ $? -eq 0 ]
       then
  	exit_cleanup 0
       fi
  
       grep -q -i "not logged in" $FTP_LOG_FILE > /dev/null 2>&1
       if [ $? -eq 0 ]; then
           # Oops - error logging in
           exit_cleanup 2
       fi

       grep -q -i "Connection refused" $FTP_LOG_FILE > /dev/null 2>&1
       if [ $? -eq 0 ]; then
           # error accessing server
           exit_cleanup 4
       fi

       grep -q -i "unknown host" $FTP_LOG_FILE > /dev/null 2>&1
       if [ $? -eq 0 ]; then
           # error accessing server
           exit_cleanup 4
       fi

       grep -q -i "Not connected" $FTP_LOG_FILE > /dev/null 2>&1
       if [ $? -eq 0 ]; then
           # error accessing server
           exit_cleaup 4
       fi

       grep -q -i "Login failed" $FTP_LOG_FILE > /dev/null 2>&1
       if [ $? -eq 0 ]; then
           # error logging in
           exit_cleanup 2
       fi

#       grep -i "Permission denied" $FTP_LOG_FILE > /dev/null 2>&1
#       if [ $? -eq 0 ]; then
#           # permission issues
#           exit_cleanup 26
#       fi

       grep -i "Connection timed out" $FTP_LOG_FILE 2>&1 >/dev/null
       if [ $? -eq 0 ]
       then
          exit_cleanup 4
       fi

       grep -q "^230" $FTP_LOG_FILE 2>&1 >/dev/null
       if [ $? -ne 0 ]
       then
          exit_cleanup 2
       fi
   
       grep -i "^550" $FTP_LOG_FILE 2>&1 >/dev/null
       if [ $? -eq 0 ]
       then
          exit_cleanup 3
       fi

       grep -i "^530" $FTP_LOG_FILE 2>&1 >/dev/null
       if [ $? -eq 0 ]
       then
          exit_cleanup 2
       fi
   
       errRC=$(grep -i "Not connected" $FTP_LOG_FILE)
       if [ -n "$errRC" ]
       then
          exit_cleanup 4
       else
          # none of the above errors
          exit_cleanup 5
       fi
     fi
   elif [ "$XFER_METHOD" = "sftp" ];then

      # user / password invalid
      if [ $SFTP_RC -eq 2 ];then
          exit_cleanup 2
      fi

       grep -i "Couldn't stat remote file" $FTP_LOG_FILE 2>&1 >/dev/null
       if [ $? -eq 0 ]
       then
          exit_cleanup 3
       fi

       ping -c 1 $FTP_SERVER >/dev/null 2>&1
       if [ $? -ne 0 ]
       then
         ping6 -c 1 $FTP_SERVER >/dev/null 2>&1
         if [ $? -ne 0 ]; then
  	   exit_cleanup 4
         fi
       fi

       grep -i "Not connected" $FTP_LOG > /dev/null 2>&1
       if [ $? -eq 0 ]; then
           # error accessing server
           exit_cleaup 4
       fi

       grep -i "Connection timed out" $FTP_LOG_FILE 2>&1 >/dev/null
       if [ $? -eq 0 ]
       then
          exit_cleanup 4
       fi

       # expect type of error
       grep -i "while executing" $FTP_LOG_FILE 2>&1 >/dev/null
       if [ $? -eq 0 ]
       then
          exit_cleanup 6
       fi

       # none of the above errors
       exit_cleanup 5
   else
       exit_cleanup 255
   fi
fi
exit_cleanup 0

