1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
# frozen_string_literal: true
require 'mail/check_delivery_params'
module Mail
# A delivery method implementation which sends via sendmail.
#
# To use this, first find out where the sendmail binary is on your computer,
# if you are on a mac or unix box, it is usually in /usr/sbin/sendmail, this will
# be your sendmail location.
#
# Mail.defaults do
# delivery_method :sendmail
# end
#
# Or if your sendmail binary is not at '/usr/sbin/sendmail'
#
# Mail.defaults do
# delivery_method :sendmail, :location => '/absolute/path/to/your/sendmail'
# end
#
# Then just deliver the email as normal:
#
# Mail.deliver do
# to 'mikel@test.lindsaar.net'
# from 'ada@test.lindsaar.net'
# subject 'testing sendmail'
# body 'testing sendmail'
# end
#
# Or by calling deliver on a Mail message
#
# mail = Mail.new do
# to 'mikel@test.lindsaar.net'
# from 'ada@test.lindsaar.net'
# subject 'testing sendmail'
# body 'testing sendmail'
# end
#
# mail.deliver!
class Sendmail
include Mail::CheckDeliveryParams
def initialize(values)
self.settings = { :location => '/usr/sbin/sendmail',
:arguments => '-i' }.merge(values)
end
attr_accessor :settings
def deliver!(mail)
smtp_from, smtp_to, message = check_delivery_params(mail)
from = "-f #{self.class.shellquote(smtp_from)}"
to = smtp_to.map { |_to| self.class.shellquote(_to) }.join(' ')
arguments = "#{settings[:arguments]} #{from} --"
self.class.call(settings[:location], arguments, to, message)
end
def self.call(path, arguments, destinations, encoded_message)
popen "#{path} #{arguments} #{destinations}" do |io|
io.puts ::Mail::Utilities.to_lf(encoded_message)
io.flush
end
end
if RUBY_VERSION < '1.9.0'
def self.popen(command, &block)
IO.popen "#{command} 2>&1", 'w+', &block
end
else
def self.popen(command, &block)
IO.popen command, 'w+', :err => :out, &block
end
end
# The following is an adaptation of ruby 1.9.2's shellwords.rb file,
# it is modified to include '+' in the allowed list to allow for
# sendmail to accept email addresses as the sender with a + in them.
def self.shellquote(address)
# Process as a single byte sequence because not all shell
# implementations are multibyte aware.
#
# A LF cannot be escaped with a backslash because a backslash + LF
# combo is regarded as line continuation and simply ignored. Strip it.
escaped = address.gsub(/([^A-Za-z0-9_\s\+\-.,:\/@])/n, "\\\\\\1").gsub("\n", '')
%("#{escaped}")
end
end
end
|