aboutsummaryrefslogtreecommitdiffstats
path: root/actionmailer/lib/action_mailer/vendor/tmail/port.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
commitdb045dbbf60b53dbe013ef25554fd013baf88134 (patch)
tree257830e3c76458c8ff3d1329de83f32b23926028 /actionmailer/lib/action_mailer/vendor/tmail/port.rb
downloadrails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.gz
rails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.bz2
rails-db045dbbf60b53dbe013ef25554fd013baf88134.zip
Initial
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionmailer/lib/action_mailer/vendor/tmail/port.rb')
-rwxr-xr-xactionmailer/lib/action_mailer/vendor/tmail/port.rb358
1 files changed, 358 insertions, 0 deletions
diff --git a/actionmailer/lib/action_mailer/vendor/tmail/port.rb b/actionmailer/lib/action_mailer/vendor/tmail/port.rb
new file mode 100755
index 0000000000..982aee8ba1
--- /dev/null
+++ b/actionmailer/lib/action_mailer/vendor/tmail/port.rb
@@ -0,0 +1,358 @@
+#
+# port.rb
+#
+# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
+#
+# This program is free software.
+# You can distribute/modify this program under the terms of
+# the GNU Lesser General Public License version 2 or later.
+#
+
+require 'tmail/stringio'
+
+
+module TMail
+
+ class Port
+ def reproducible?
+ false
+ end
+ end
+
+
+ ###
+ ### FilePort
+ ###
+
+ class FilePort < Port
+
+ def initialize( fname )
+ @filename = File.expand_path(fname)
+ super()
+ end
+
+ attr_reader :filename
+
+ alias ident filename
+
+ def ==( other )
+ other.respond_to?(:filename) and @filename == other.filename
+ end
+
+ alias eql? ==
+
+ def hash
+ @filename.hash
+ end
+
+ def inspect
+ "#<#{self.class}:#{@filename}>"
+ end
+
+ def reproducible?
+ true
+ end
+
+ def size
+ File.size @filename
+ end
+
+
+ def ropen( &block )
+ File.open(@filename, &block)
+ end
+
+ def wopen( &block )
+ File.open(@filename, 'w', &block)
+ end
+
+ def aopen( &block )
+ File.open(@filename, 'a', &block)
+ end
+
+
+ def read_all
+ ropen {|f|
+ return f.read
+ }
+ end
+
+
+ def remove
+ File.unlink @filename
+ end
+
+ def move_to( port )
+ begin
+ File.link @filename, port.filename
+ rescue Errno::EXDEV
+ copy_to port
+ end
+ File.unlink @filename
+ end
+
+ alias mv move_to
+
+ def copy_to( port )
+ if FilePort === port
+ copy_file @filename, port.filename
+ else
+ File.open(@filename) {|r|
+ port.wopen {|w|
+ while s = r.sysread(4096)
+ w.write << s
+ end
+ } }
+ end
+ end
+
+ alias cp copy_to
+
+ private
+
+ # from fileutils.rb
+ def copy_file( src, dest )
+ st = r = w = nil
+
+ File.open(src, 'rb') {|r|
+ File.open(dest, 'wb') {|w|
+ st = r.stat
+ begin
+ while true
+ w.write r.sysread(st.blksize)
+ end
+ rescue EOFError
+ end
+ } }
+ end
+
+ end
+
+
+ module MailFlags
+
+ def seen=( b )
+ set_status 'S', b
+ end
+
+ def seen?
+ get_status 'S'
+ end
+
+ def replied=( b )
+ set_status 'R', b
+ end
+
+ def replied?
+ get_status 'R'
+ end
+
+ def flagged=( b )
+ set_status 'F', b
+ end
+
+ def flagged?
+ get_status 'F'
+ end
+
+ private
+
+ def procinfostr( str, tag, true_p )
+ a = str.upcase.split(//)
+ a.push true_p ? tag : nil
+ a.delete tag unless true_p
+ a.compact.sort.join('').squeeze
+ end
+
+ end
+
+
+ class MhPort < FilePort
+
+ include MailFlags
+
+ private
+
+ def set_status( tag, flag )
+ begin
+ tmpfile = @filename + '.tmailtmp.' + $$.to_s
+ File.open(tmpfile, 'w') {|f|
+ write_status f, tag, flag
+ }
+ File.unlink @filename
+ File.link tmpfile, @filename
+ ensure
+ File.unlink tmpfile
+ end
+ end
+
+ def write_status( f, tag, flag )
+ stat = ''
+ File.open(@filename) {|r|
+ while line = r.gets
+ if line.strip.empty?
+ break
+ elsif m = /\AX-TMail-Status:/i.match(line)
+ stat = m.post_match.strip
+ else
+ f.print line
+ end
+ end
+
+ s = procinfostr(stat, tag, flag)
+ f.puts 'X-TMail-Status: ' + s unless s.empty?
+ f.puts
+
+ while s = r.read(2048)
+ f.write s
+ end
+ }
+ end
+
+ def get_status( tag )
+ File.foreach(@filename) {|line|
+ return false if line.strip.empty?
+ if m = /\AX-TMail-Status:/i.match(line)
+ return m.post_match.strip.include?(tag[0])
+ end
+ }
+ false
+ end
+
+ end
+
+
+ class MaildirPort < FilePort
+
+ def move_to_new
+ new = replace_dir(@filename, 'new')
+ File.rename @filename, new
+ @filename = new
+ end
+
+ def move_to_cur
+ new = replace_dir(@filename, 'cur')
+ File.rename @filename, new
+ @filename = new
+ end
+
+ def replace_dir( path, dir )
+ "#{File.dirname File.dirname(path)}/#{dir}/#{File.basename path}"
+ end
+ private :replace_dir
+
+
+ include MailFlags
+
+ private
+
+ MAIL_FILE = /\A(\d+\.[\d_]+\.[^:]+)(?:\:(\d),(\w+)?)?\z/
+
+ def set_status( tag, flag )
+ if m = MAIL_FILE.match(File.basename(@filename))
+ s, uniq, type, info, = m.to_a
+ return if type and type != '2' # do not change anything
+ newname = File.dirname(@filename) + '/' +
+ uniq + ':2,' + procinfostr(info.to_s, tag, flag)
+ else
+ newname = @filename + ':2,' + tag
+ end
+
+ File.link @filename, newname
+ File.unlink @filename
+ @filename = newname
+ end
+
+ def get_status( tag )
+ m = MAIL_FILE.match(File.basename(@filename)) or return false
+ m[2] == '2' and m[3].to_s.include?(tag[0])
+ end
+
+ end
+
+
+ ###
+ ### StringPort
+ ###
+
+ class StringPort < Port
+
+ def initialize( str = '' )
+ @buffer = str
+ super()
+ end
+
+ def string
+ @buffer
+ end
+
+ def to_s
+ @buffer.dup
+ end
+
+ alias read_all to_s
+
+ def size
+ @buffer.size
+ end
+
+ def ==( other )
+ StringPort === other and @buffer.equal? other.string
+ end
+
+ alias eql? ==
+
+ def hash
+ @buffer.id.hash
+ end
+
+ def inspect
+ "#<#{self.class}:id=#{sprintf '0x%x', @buffer.id}>"
+ end
+
+ def reproducible?
+ true
+ end
+
+ def ropen( &block )
+ @buffer or raise Errno::ENOENT, "#{inspect} is already removed"
+ StringInput.open(@buffer, &block)
+ end
+
+ def wopen( &block )
+ @buffer = ''
+ StringOutput.new(@buffer, &block)
+ end
+
+ def aopen( &block )
+ @buffer ||= ''
+ StringOutput.new(@buffer, &block)
+ end
+
+ def remove
+ @buffer = nil
+ end
+
+ alias rm remove
+
+ def copy_to( port )
+ port.wopen {|f|
+ f.write @buffer
+ }
+ end
+
+ alias cp copy_to
+
+ def move_to( port )
+ if StringPort === port
+ str = @buffer
+ port.instance_eval { @buffer = str }
+ else
+ copy_to port
+ end
+ remove
+ end
+
+ end
+
+end # module TMail