#!/bin/bash
#    
#    This script enhances courier's mailbot program. It allows to use the
#    original message's subject in the reply's subject header. This is still
#    work in progress. Additional features may be added upon request. Please
#    report any problems to the author (see below).
#    
#    Script version 0.6
#    
#    Copyright © 2010, 2011 by Martin Gollowitzer <gollo@fsfe.org> and Bernd
#    Wurst <bernd@schokokeks.org>
#    
#    Permission is hereby granted, free of charge, to any person obtaining a
#    copy
#    of this software and associated documentation files (the "Software"), to
#    deal
#    in the Software without restriction, including without limitation the
#    rights
#    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#    copies of the Software, and to permit persons to whom the Software is
#    furnished to do so, subject to the following conditions:
#    
#    The above copyright notice and this permission notice shall be included in
#    all copies or substantial portions of the Software.
#    
#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#    FROM,
#    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#    THE SOFTWARE.

### Begin configuration section ###

# These are default settings which can be overwritten by a configuration file
# given as the first parameter

# Name for From: header in autoresponse; do not use quotes here
defusername=''

# E-Mail for From: header in autoresponse
defemail="$(whoami)@$(hostname -d)"

# If you want to set a Reply-To: header, set the e-mail address here; if not,
# leave it empty
defreplyto=''

# Name for optional Reply-To: header in autoresponse
defrtusername=''

# Subject for autoresponse. %INSUBJECT is being replaced by the original subject
defsubject="Your message '%INSUBJECT' was received"

# Path to mailbot
defmailbot='/usr/bin/mailbot'

# Set response type (reply, replyall, replydsn, forward, forwardatt)
defresponsetype='reply'

# If replydsn is used, set the e-mail address that generates the DSN here
defdsnmail=''

# Quote original message in reply, replyall and replydsn?
defquote='no'

# If quoting is enabled and you want to use a salutation different from the
# default ("%F writes:"), enter it here. Leave empty otherwise. Do not use
# quotes here.
defsalut=''

# If response type is forward and you want to use a different marker to separate
# the forwarded message from the autoreply text (default: 
# --- Forwarded message ---), set it here. Leave empty otherwise.
defmarker=''
 
# How long (in days) should mailbot wait before sending a second autoresponse?
deftimeout='7'

# Directory for temporary files. If nothing is set, /tmp is used.
deftmpdir=""

# Path where your response message and bounceDB reside
defdatapath="$HOME/autoresponse/example"

# File name of response message file
defmessagefile='autoresponse.txt'

# Encoding for response message file
defencoding='utf-8'

# Does the message file contain a MIME response (including headers)?
defmimem='no'

# File name for bounceDB
defbouncedbfile='bouncedb'

# Activate debug mode? If this is set to yes, you will receive the entire
# message that was parsed by this script to e-mail address set in $defdebugmail
# and the generated autoresponse (which is then *not* sent to the original
# sender!)
defdebug='no'
defdebugmail='example@example.com'

### End of configuration section ###


# Output usage information of no config file is given
if [ -z "${1}" ] || [ ! -f "${1}" ]; then
 echo "Wrapper script for the mailbot application from courier MTA"
 echo "usage: $0 [configfile]"
 exit 1
fi

# the first parameter is a configuration file
source $1

# We use configuration parameters from config or the default values above
username=${USERNAME:-$defusername}
email=${EMAIL:-$defemail}
replyto=${REPLYTO:-$defreplyto}
rtusername=${RTUSERNAME:-$defrtusername}
subject=${SUBJECT:-$defsubject}
mailbot=${MAILBOT:-$defmailbot}
responsetype=${RESPONSETYPE:-$defresponsetype}
dsnmail=${DSNMAIL:-$defdsnmail}
quote=${QUOTE:-$defquote}
salut=${SALUT:-$defsalut}
marker=${MARKER:-$defmarker}
timeout=${TIMEOUT:-$deftimeout}
tmpdir=${TMPDIR:-$deftmpdir}
datapath=${DATAPATH:-$defdatapath}
messagefile=${MESSAGEFILE:-$defmessagefile}
encoding=${ENCODING:-$defencoding}
mimem=${MIMEM:-$defmimem}
bouncedbfile=${BOUNCEDBFILE:-$defbouncedbfile}
debug=${DEBUG:-$defdebug}
debugmail=${DEBUGMAIL:-$defdebugmail}


cmd="tempfile"

cmdbin="$(which $cmd)"

if [ "$cmdbin" == "" ]; then
 echo "Couldn't find the $cmd binary in your PATH. You might need to install \
       the debianutils package!"
 exit 1
fi

[[ -n "$tmpdir" && -d "$tmpdir" ]] && cmd="$cmd --directory=${tmpdir}"

# filename for temporary file
tmpfile="$($cmd)"

if [ "$debug" == "yes" ] ; then
  # filename for debug log file
  debugfile="$($cmd)"
fi

if [ ! -d "$datapath" ] ; then
  echo "Data path \"${datapath}\" does not exist"
  exit 1
fi

# full path for reply message file
messagepath="$datapath/$messagefile"

if [ ! -f "$messagepath" ] ; then
  echo "Reply message file does not exist!"
  exit 1
fi

# full path for bounceDB file
bouncedbpath="$datapath/$bouncedbfile"

# read input from stdin to temporary file
cat > $tmpfile

# Debug mode output is being mailed here
[ "$debug" == "yes" ] && cat $tmpfile | \
mail -s "Debug output [1]: parsed message" "$debugmail"

# Write the subject of the original mail to $insubject
insubject="$(grep --max-count=1 -ie "^Subject: " "$tmpfile" | \
             sed -e 's/^Subject: //i')"

outsubject="$(echo "$subject" | sed -e "s/\%INSUBJECT/$insubject/")"

# Since I don't know why the forward/forwardatt really exists as it does not set
# a To: header, I create a To: from the From: header here. I'll try to figure
# out what this is good for.
forwardto="$(cat $tmpfile | grep --max-count=1 -ie "^From: " | \
             sed -e 's/From:/To:/i')"


# From: header
fromh="From: $username <$email>"

# if $replyto is set, $rpt is set to yes
if [ "$replyto" == "" ]; then
 rpt="no"
else
 [ "$rtusername" == ""] && rtusername="$username"
 rpt="yes"
fi


# Check if message file is a MIME response
# Used for all response types
if [ "$mimem" == "yes" ]; then
 fileparam="-m"
else
 fileparam="-t"
fi

# Starting to build a command

mycommand="cat $tmpfile | $mailbot -T $responsetype" 

if [ "$responsetype" == "replydsn" ]; then
[ "$dsnmail" == "" ] && dsnmail="$email"
mycommand="$mycommand -M \"$dsnmail\""
fi

mycommand="$mycommand $fileparam $messagepath -c $encoding -d $bouncedbpath"
mycommand="$mycommand -D $timeout -s \"$outsubject\" -A \"$fromh\""

case "$responsetype" in 
 reply|replyall|replydsn)
  if [ "$quote" == "yes" ]; then
   [ "$salut" != "" ] && mycommand="$mycommand -S \"$salut\""
  else
   mycommand="$mycommand -N"
  fi
  ;;
 forward)
  mycommand="$mycommand -A \"$forwardto\""
  [ "$marker" != "" ] && mycommand="$mycommand -F \"$marker\""
  ;;
 forwardatt)
  mycommand="$mycommand -A \"$forwardto\""
  ;;
 *)
  if [ "$debug" == "yes" ]; then
    echo "Wrong or missing response type! (Original subject: $insubject)" | \
    mail -s "Debug message: Wrong response type" $debugmail
  fi
  echo "Wrong or missing response type!"
  exit 3
  ;;
esac

[ "$rpt" == "yes" ] && mycommand="$mycommand -A \"Reply-To: $rtusername <$replyto>\""

[ "$debug" == "yes" ] && mycommand="$mycommand -n | tee $debugfile"

[ "$debug" == "yes" ] && \
echo "The following command will be executed: $mycommand" | \
mail -s "Debug output [2]: executed command" $debugmail

eval $mycommand

# remove temporary file
rm -f $tmpfile
rmexit=$?

# if in debug mode: reporting and removal of debug log
if [ "$debug" == "yes" ]; then
 cat $debugfile | mail -s "Debug output [3]: generated message" $debugmail
 rm -f $debugfile
 rmexitd=$?
 echo "Files should be deleted (exit codes: $rmexit, $rmexitd)!" \
 | mail -s "Debug output [4]: removal of files" $debugmail
fi
 
# End
exit 0
