# 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