|
# File lib/rfilter/deliver.rb, line 216
def deliver_maildir(dir, message)
require 'socket'
# First, make the required directories
new = File.join(dir, 'new')
tmp = File.join(dir, 'tmp')
[ dir, new, tmp, File.join(dir, 'cur') ].each { |d|
begin
Dir.mkdir(d, 0700)
rescue Errno::EEXIST
raise unless FileTest::directory?(d)
end
}
sequence = @@mail_deliver_maildir_count
@@mail_deliver_maildir_count = @@mail_deliver_maildir_count.next
tmp_name = nil
new_name = nil
hostname = Socket::gethostname.gsub(/[^\w]/, '_').untaint
pid = Process::pid
3.times { |i|
name = sprintf("%d.%d_%d.%s", Time::now.to_i, pid, sequence, hostname)
tmp_name = File.join(tmp, name)
new_name = File.join(new, name)
begin
File::stat(tmp_name)
rescue Errno::ENOENT
break
rescue Exception
raise if i == 2
end
raise "Too many tmp file conflicts." if i == 2
sleep(2)
}
begin
File.open(tmp_name,
File::CREAT|File::EXCL|File::WRONLY|SYNC_IF_NO_FSYNC,
0600) { |f|
# Write the message to the file
first = true
message.each { |line|
if first
first = false
next if line =~ /From /
end
f << line
f << "\n" unless line[-1] == ?\n
}
f.fsync if defined? f.fsync
}
File.link(tmp_name, new_name)
ensure
begin
File.delete(tmp_name)
rescue Errno::ENOENT
end
end
new_name
end
|