Skip to content
rthrd edited this page Oct 22, 2014 · 3 revisions

Well, my msmtp queue is broken, and I cannot figure out why.

So here is my makeshift surrogate sendmail hook using sendEmail, a lightweight, command line SMTP email client:

# sendmail.rb -- hook for sending mail
# using sendEmail, as my msmtp is broken ;-(

# shall I do verbose logging?
#verbose = "-v -l /pass/to/log.file"
#verbose = ""

# define command line snippet for smtp login for each account.email
# ToDo: there should be more secure methods to protect the passwords 
# than setting the mode of this file to 600!?
smtp_login_data = {
  '[email protected]' =>
      '-s smtp.isp.tld -xu my.fist.login -xp SECRET,DO NOT READ',
  '[email protected]' =>
      '-s smtp.isp.tld -xu my.second.login -xp SECRET,DO NOT READ',
  '[email protected]' =>
      '-s mail.another-isp.tld -xu my.third.login -xp SECRET,DO NOT READ',
}

# write message to temporary file
tmp = Tempfile.new "sup-sendEmail."
tmp.puts message
tmp.close

# build address options for sendEmail:
# message.header['To|CC|BCC'] might be a list of complex addresses
# we have to convert them to a comma separated string of plain
# addresses prepended with the appropriate option
options_to_header_keys_map = {
        '-f' => 'From',
        '-t' => 'To',
        '-cc' => 'CC',
        '-bcc' => 'BCC'}
addresses = options_to_header_keys_map.collect do |o,k|
  as = RMail::Address.parse(message.header[k]).collect do |a|
    a.address
  end
  if as.length > 0
    "#{o} \"#{as.join(', ')}\""
  else
    ""
  end
end.join " "

# luckily attachements seem to survive sendEmails enveloping.
# ToDo: is this foolproof?

# call sendEmail -- eval is evil, and system is it's sister, but as all
# evaled data originates from me, I consider it's use as save enough.
system "/usr/bin/sendEmail #{verbose} #{addresses} -u \"#{message.header['Subject']}\"  #{smtp_login_data[account.email]} -o message-format=raw -o message-file=\"#{tmp.path}\""

# save exitstate
err = $?.exitstatus

# delete temporary file
tmp.unlink

# return exitstate
err
Clone this wiki locally