#!/bin/bash

# Sends piped message to predetermined email address using an account on gmail.
# Specifically meant to be used by CRON since CRON's normal output via MAILTO
#   is limited to mailservers that will accept unauthenticated relayed mail.

export PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/sw/bin

dbug=0

retry=3  # attempts to retry (on unknown errors only, things like connection drops)
# gmail (and I suspect others) will for unknown reasons sometimes drop connection
# while this script tries to connect and send mail.  we handle this with persistence.

# path to the Expect script for SSL SMTP, by default in the same folder as this script
escr="${0%/*}/mail_authsmtpssl.exp"
gothelo="gmail_from_cron"

# this is your gmail account information.  gotfrom can be different if you use aliases
gotuser="myuser@gmail.com"
gotpass="mypass"
gotfrom="myuser@gmail.com"
gotsmtp="smtp.gmail.com"
gotport="587"

# this is who to send the email to, and the message subject
  gotto="virtual1@wherever.net"
 gotsub="Message from $USER on $HOSTNAME via CRON"

# build the message to email from stdin
gotmsg=""
while read line; do
    gotmsg="${gotmsg}${line}"$'\n'
done
if [ -z "$gotmsg" ] ; then  #  do not email if there is no message provided (like CRON)
  exit
fi

# temp files
tfile1="/tmp/smtptemp1"
tfile2="/tmp/smtptemp2"

# build the PLAIN AUTH string.  bash has problems with chr(0) in strings so we go about it this way
echo "0: 00" | xxd -r > "$tfile1"
cat "$tfile1" > "$tfile2"
echo -n "$gotuser" >> "$tfile2"
cat "$tfile1" >> "$tfile2"
echo -n "$gotpass" >> "$tfile2"
rm "$tfile1"
authcode=$(cat "$tfile2" | openssl base64)
if [ "$dbug" == 1 ] ; then
  echo "PLAIN auth code is: \"$authcode\""
  echo
  echo -n "That reverses to: "
  echo -n "$authcode" | xxd -c 32
fi
rm "$tfile2"

# try to send mail.  obviously avoid "EMAILSUCCESSFUL" and "EMAILFAILED" in your email message
tries=0
while true ; do
  r=$(expect "$escr" $gotsmtp $gotport "$authcode" "$gothelo" "$gotfrom" "$gotto" "$gotsub" "$gotmsg" $dbug 2>&1)
  #expect "$escr" $gotsmtp $gotport "$authcode" "$gothelo" "$gotfrom" "$gotto" "$gotsub" "$gotmsg" $dbug
  #r="EMAILSUCCESSFUL"
  rm=$(echo "$r" | grep "EMAILSUCCESSFUL")
  if [ -n "$rm" ] ; then
    rc=0
    rm="SUCCESS"
    if [ "$dbug" == 1 ] ; then echo "($rm)" 1>&2 ; fi
    break
  else
    rm=$(echo "$r" | grep "EMAILFAILED")
    if [ -n "$rm" ] ; then
      rc=1
      rm=${rm:13:999}
      echo "$rm" 1>&2
      break
    else
      ((tries++))
      if [ $tries -ge $retry ] ; then
        rc=2
        rm="unexpected error"
        echo "$rm" 1>&2
        break
      fi
    fi
  fi
done

# done.  exits with 0 for success, 1 for common failures, 2 for unexpected failures
if [ "$dbug" == 1 ] ; then echo "return code $rc" 1>&2 ; fi
exit $rc
