#!/bin/bash

# DISCLAIMER   :   It is recomended to test this script on a test machine.
#                  ManageEngine will not be responsible for any damage/loss
#                  to the data/setup based on the behavior of the script.
#
# DESCRIPTION  :   Script to add/modify the Cronjob for every minute/hour/day_of_month/month/day_of_week to
#                  existing/uploaded script/application in linux agent machines.
#
# ARGUMENT(S):
#
#  1) To add Cronjob for the script/application located in the agent machine.
#
#         ARGUMENT FORMAT: <source_path_of_file_in_agent_machine> "m<N>" "h<N>" "d<N>" "mo<N>" "w<N>" "<N>"
# 
#         EXAMPLE:  
#         For adding Cronjob every 5 minutes : /home/test/me_script.bash "m5" "h" "d" "mo" "w" "1"

#           EVEN IF ONLY FOR EVERY 5 MINUTES CRONJOB SHOULD BE ADDED, 
#           ALL OTHER 7 ARGUMENTS such as "h" "d" "mo" "w" "1" SHOULD BE PASSED
#
#           ARGUMENTS EXPLAINED
#            <file>  - full path of script/application 
#            m<N>    - for every Nth minute; 1 <= N <= 59
#            h<N>    - for every Nth hour; 1 <= N <= 24
#            d<N>    - for every Nth day of month; 1 <= N <= 31
#            mo<N>   - for every Nth month; 1 <= N <= 12
#            w<N>    - for every Nth day of week; 1 <= N <= 6
#            N       - 1,0; 1 - Modify exisitng cronjob for specified script/application, 
#                           0 - Not to modify existing cronjob
#
#  2) To add Cronjob for uploaded script via Server console
#
#         ARGUMENT FORMAT: <exact_file_name_of_uploaded_file> "m<N>" "h<N>" "d<N>" "mo<N>" "w<N>" "<N>"
# 
#         DEPENDENCY FILE(S): Upload file for which cronjob is applied from server to linux agent machine.
#
#         EXAMPLE:  
#         For adding Cronjob every 5 minutes : /home/test/me_script.bash "m5" "h" "d" "mo" "w" "1"

#           EVEN IF ONLY FOR EVERY 5 MINUTES CRONJOB SHOULD BE ADDED, 
#           ALL OTHER 7 ARGUMENTS such as "h" "d" "mo" "w" "1" SHOULD BE PASSED
#
#           ARGUMENTS EXPLAINED
#            <file>  - exact name of script/application uploaded from server console 
#            m<N>    - for every Nth minute; 1 <= N <= 59
#            h<N>    - for every Nth hour; 1 <= N <= 24
#            d<N>    - for every Nth day of month; 1 <= N <= 31
#            mo<N>   - for every Nth month; 1 <= N <= 12
#            w<N>    - for every Nth day of week; 1 <= N <= 6
#            N       - 1,0; 1 - Overwriting exisitng cronjob for specified script/application, 
#                           0 - not to overwrite the same
#
#           RETURN VALUE          MEANING
#
#                0             Cronjob added successfully
#                1             Error while adding Cronjob
#                2             Invalid arguments.

# NOTE :
#   To see the script output, Kindly enable the option Enable logging in Troubleshooting while deploying configuration.

errorCode=2

euid=$(id -u)
for i in 1; do
 #check root access
  if [ $euid -ne 0 ]; then
    echo "This script must be run as root"
    break
  fi

  # check number of arguments
  if [ $# -lt 7 ]; then
    echo "Incorrect Usage : Arguments mismatch."
    echo "Refer ARGUMENT(S) section in this script."
    break
  fi

  isPath=$(echo "$1" | sed -n '/^\// p' | wc -l)

  if [ "$isPath" -eq 0 ]; then
    #fileName=$(ls | sed -e '/AddCronJob\.sh\|DelCronJob\.sh\|ModifyCronJob\.sh\|ListCronJobs.sh/ d')
    fileName=$1
    runDir=$PWD
    cd ..
    fileDir=$PWD
    cd $runDir
    cp $runDir"/"$fileName $fileDir"/"$fileName
    filePath=$(echo $fileDir"/"$fileName)
    min=$(echo $2 | sed 's/m/\*/')
    hour=$(echo $3 | sed 's/h/\*/')
    dom=$(echo $4 | sed 's/d/\*/')
    month=$(echo $5 | sed 's/mo/\*/')
    dow=$(echo $6 | sed 's/w/\*/')
    overWrite=$7
  else
    filePath=$1
    min=$(echo $2 | sed 's/m/\*/')
    hour=$(echo $3 | sed 's/h/\*/')
    dom=$(echo $4 | sed 's/d/\*/')
    month=$(echo $5 | sed 's/mo/\*/')
    dow=$(echo $6 | sed 's/w/\*/')
    overWrite=$7
  fi

  if [ ! -e "$filePath" ]; then
    echo "No such file or Directory"
    break
  fi

  #Check the minutes
  if [ "$min" != "*" ]; then
    isNum=$(echo "$min" | sed -n '/^[0-9][0-9]*/ p' | wc -l)
    if [ "$isNum" -eq 1 ]; then
      if [ "$min" -gt 59 -o "$min" -lt 1 ]; then
        echo "Invalid Minutes"
        break
      fi
    else
      min=$(echo "$min" | sed -e 's/\*/*\//' | sed 's/\/0\(.\)/\/\1/')
      isValmin=$(echo "$min" | sed 's/\*\/\(.*\)/\1/')
      if [ "$isValmin" -gt 59 -o "$isValmin" -lt 1 ]; then
        echo "Invalid minute"
        break
      fi
    fi
  fi

  #Check the hour
  if [ "$hour" != "*" ]; then
    isNum=$(echo "$hour" | sed -n '/^[0-9][0-9]*/ p' | wc -l)
    if [ "$isNum" -eq 1 ]; then
      if [ "$hour" -gt 23 -o "$hour" -lt 1 ]; then
        echo "Invalid Hour"
        break
      fi
    else
      hour=$(echo "$hour" | sed -e 's/\*/*\//' | sed 's/\/0\(.\)/\/\1/')
      isValhour=$(echo "$hour" | sed 's/\*\/\(.*\)/\1/')
      if [ "$isValhour" -gt 23 -o "$isValhour" -lt 1 ]; then
        echo "Invalid hour"
        break
      fi
    fi
  fi

  #Check the Day of Month
  if [ "$dom" != "*" ]; then
    isNum=$(echo "$dow" | sed -n '/^[0-9][0-9]*/ p' | wc -l)
    if [ $isNum -eq 1 ]; then
      if [ "$dow" -gt 31 -o "$dow" -lt 1 ]; then
        echo "Invalid Day of Day of Month"
        break
      fi
    else
      dom=$(echo "$dom" | sed -e 's/\*/*\//' | sed 's/\/0\(.\)/\/\1/')
      isValdom=$(echo "$dom" | sed 's/\*\/\(.*\)/\1/')
      if [ "$isValdom" -gt 31 -o "$isValdom" -lt 1 ]; then
        echo "Invalid Day of Day of Month"
        break
      fi
    fi
  fi

  #Check the Month
  if [ "$month" != "*" ]; then
    isNum=$(echo "$month" | sed -n '/^[0-9][0-9]*/ p' | wc -l)
    if [ "$isNum" -eq 1 ]; then
      if [ "$month" -gt 12 -o "$month" -lt 1 ]; then
        echo "Invalid Month"
        break
      fi
    else
      month=$(echo "$month" | sed -e 's/\*/*\//' | sed 's/\/0\(.\)/\/\1/')
      isValmonth=$(echo "$month" | sed 's/\*\/\(.*\)/\1/')
      if [ "$isValmonth" -gt 12 -o "$isValmonth" -lt 1 ]; then
        echo "Invalid Month"
        break
      fi
    fi
  fi

  #Check the Day of Week
  if [ "$dow" != "*" ]; then
    isNum=$(echo "$dow" | sed -n '/^[0-9][0-9]*/ p' | wc -l)
    if [ "$isNum" -eq 1 ]; then
      if [ "$dow" -gt 6 -o "$dow" -lt 1 ]; then
        echo "Invalid Day of Week"
        break
      fi
    else
      dow=$(echo "$dow" | sed -e 's/\*/*\//' | sed 's/\/0\(.\)/\/\1/')
      isValdow=$(echo "$dow" | sed 's/\*\/\(.*\)/\1/')
      if [ "$isValdow" -gt 6 -o "$isValdow" -lt 1 ]; then
        echo "Invalid Day of Week"
        break
      fi
    fi
  fi

  errorCode=0

  #Check Job already exist or not

  filePath=$(echo "$filePath" | sed 's/\//\\\//g')
  isExist=$(crontab -l | sed -n '/\ '$filePath'$/p' | wc -l)

  if [ "$isExist" -eq 1 -a "$overWrite" -eq 1 ]; then
    #remove the existing job
    crontab -l | sed '/\ '$filePath'$/ {
    d
  }' | crontab -
  elif [ "$isExist" -eq 1 -a "$overWrite" -eq 0 ];  then
    echo "Task already exist"
    break
  fi
  #add the job
  #(crontab -l 2>/dev/null; echo "#$taskName" ) | crontab -

  filePath=$(echo "$filePath" | sed 's/\\\//\//g')
  (crontab -l 2>/dev/null; echo "$min $hour $dom $month $dow /bin/bash $filePath") | crontab -

  if [ $? -eq 0 ]; then
    echo "Cronjob: $filePath added successfully"
  else
    echo "Error while adding Cronjob for $filePath"
    errorCode=1
  fi
done

errorFunc() {
  return $errorCode
}
errorFunc
