rgrove-larch 1.0.0.6 → 1.0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY +2 -0
- data/bin/larch +16 -9
- data/lib/larch/imap.rb +20 -3
- data/lib/larch/version.rb +1 -1
- metadata +1 -1
data/HISTORY
CHANGED
@@ -2,8 +2,10 @@ Larch History
|
|
2
2
|
================================================================================
|
3
3
|
|
4
4
|
Version 1.0.1 (?)
|
5
|
+
* Ruby 1.9.1 support.
|
5
6
|
* Much more robust handling of unexpected server disconnects and dropped
|
6
7
|
connections.
|
8
|
+
* Option to verify server SSL certificates.
|
7
9
|
* Fix excessive post-scan processing times for very large mailboxes.
|
8
10
|
* Fetch message headers in blocks of up to 1024 at a time rather than all at
|
9
11
|
once, to prevent potential problems with certain servers when a mailbox
|
data/bin/larch
CHANGED
@@ -22,18 +22,21 @@ EOS
|
|
22
22
|
opt :from, "URI of the source IMAP server.", :short => '-f', :type => :string, :required => true
|
23
23
|
opt :to, "URI of the destination IMAP server.", :short => '-t', :type => :string, :required => true
|
24
24
|
|
25
|
-
text "\
|
26
|
-
|
27
|
-
# opt :dry_run, "Don't actually do anything.", :short => '-n'
|
28
|
-
opt :fast_scan, "Use a faster (but less accurate) method to scan mailboxes. This may result in messages being re-copied.", :short => :none
|
25
|
+
text "\nCopy Options:"
|
29
26
|
opt :from_folder, "Source folder to copy from", :short => :none, :default => 'INBOX'
|
30
27
|
opt :from_pass, "Source server password (Default: prompt)", :short => :none, :type => :string
|
31
28
|
opt :from_user, "Source server username (Default: prompt)", :short => :none, :type => :string
|
32
|
-
opt :max_retries, "Maximum number of times to retry after a recoverable error", :short => :none, :default => 3
|
33
|
-
opt :no_create_folder, "Don't create destination folders that don't already exist", :short => :none
|
34
29
|
opt :to_folder, "Destination folder to copy to", :short => :none, :default => 'INBOX'
|
35
30
|
opt :to_pass, "Destination server password (Default: prompt)", :short => :none, :type => :string
|
36
31
|
opt :to_user, "Destination server username (Default: prompt)", :short => :none, :type => :string
|
32
|
+
|
33
|
+
text "\nGeneral Options:"
|
34
|
+
# opt :dry_run, "Don't actually do anything.", :short => '-n'
|
35
|
+
opt :fast_scan, "Use a faster (but less accurate) method to scan mailboxes. This may result in messages being re-copied.", :short => :none
|
36
|
+
opt :max_retries, "Maximum number of times to retry after a recoverable error", :short => :none, :default => 3
|
37
|
+
opt :no_create_folder, "Don't create destination folders that don't already exist", :short => :none
|
38
|
+
opt :ssl_certs, "Path to a trusted certificate bundle to use to verify server SSL certificates", :short => :none
|
39
|
+
opt :ssl_verify, "Verify server SSL certificates", :short => :none
|
37
40
|
opt :verbosity, "Output verbosity: debug, info, warn, error, or fatal", :short => '-V', :default => 'info'
|
38
41
|
end
|
39
42
|
|
@@ -78,17 +81,21 @@ EOS
|
|
78
81
|
|
79
82
|
source = IMAP.new(options[:from], options[:from_user], options[:from_pass],
|
80
83
|
:fast_scan => options[:fast_scan],
|
81
|
-
:max_retries => options[:max_retries]
|
84
|
+
:max_retries => options[:max_retries],
|
85
|
+
:ssl_certs => options[:ssl_certs] || nil,
|
86
|
+
:ssl_verify => options[:ssl_verify])
|
82
87
|
|
83
88
|
dest = IMAP.new(options[:to], options[:to_user], options[:to_pass],
|
84
89
|
:create_mailbox => !options[:no_create_folder],
|
85
90
|
:fast_scan => options[:fast_scan],
|
86
|
-
:max_retries => options[:max_retries]
|
91
|
+
:max_retries => options[:max_retries],
|
92
|
+
:ssl_certs => options[:ssl_certs] || nil,
|
93
|
+
:ssl_verify => options[:ssl_verify])
|
87
94
|
|
88
95
|
unless RUBY_PLATFORM =~ /mswin|mingw|bccwin|wince|java/
|
89
96
|
begin
|
90
97
|
for sig in [:SIGINT, :SIGQUIT, :SIGTERM]
|
91
|
-
trap(sig) { @log.fatal "Interrupted (#{sig})"; exit }
|
98
|
+
trap(sig) { @log.fatal "Interrupted (#{sig})"; Kernel.exit }
|
92
99
|
end
|
93
100
|
rescue => e
|
94
101
|
end
|
data/lib/larch/imap.rb
CHANGED
@@ -47,6 +47,17 @@ class IMAP
|
|
47
47
|
# After a recoverable error occurs, retry the operation up to this many
|
48
48
|
# times. Default is 3.
|
49
49
|
#
|
50
|
+
# [:ssl_certs]
|
51
|
+
# Path to a trusted certificate bundle to use to verify server SSL
|
52
|
+
# certificates. You can download a bundle of certificate authority root
|
53
|
+
# certs at http://curl.haxx.se/ca/cacert.pem (it's up to you to verify that
|
54
|
+
# this bundle hasn't been tampered with, however; don't trust it blindly).
|
55
|
+
#
|
56
|
+
# [:ssl_verify]
|
57
|
+
# If +true+, server SSL certificates will be verified against the trusted
|
58
|
+
# certificate bundle specified in +ssl_certs+. By default, server SSL
|
59
|
+
# certificates are not verified.
|
60
|
+
#
|
50
61
|
def initialize(uri, username, password, options = {})
|
51
62
|
raise ArgumentError, "not an IMAP URI: #{uri}" unless uri.is_a?(URI) || uri =~ REGEX_URI
|
52
63
|
raise ArgumentError, "must provide a username and password" unless username && password
|
@@ -55,7 +66,7 @@ class IMAP
|
|
55
66
|
@uri = uri.is_a?(URI) ? uri : URI(uri)
|
56
67
|
@username = username
|
57
68
|
@password = password
|
58
|
-
@options = {:max_retries => 3}.merge(options)
|
69
|
+
@options = {:max_retries => 3, :ssl_verify => false}.merge(options)
|
59
70
|
|
60
71
|
@ids = {}
|
61
72
|
@imap = nil
|
@@ -383,6 +394,11 @@ class IMAP
|
|
383
394
|
OpenSSL::SSL::SSLError => e
|
384
395
|
|
385
396
|
raise unless (retries += 1) <= @options[:max_retries]
|
397
|
+
|
398
|
+
# Special check to ensure that we don't retry on OpenSSL certificate
|
399
|
+
# verification errors.
|
400
|
+
raise if e.is_a?(OpenSSL::SSL::SSLError) && e.message =~ /certificate verify failed/
|
401
|
+
|
386
402
|
info "#{e.class.name}: #{e.message} (will retry)"
|
387
403
|
|
388
404
|
reset
|
@@ -449,7 +465,9 @@ class IMAP
|
|
449
465
|
|
450
466
|
Thread.new do
|
451
467
|
begin
|
452
|
-
@imap = Net::IMAP.new(host, port, ssl
|
468
|
+
@imap = Net::IMAP.new(host, port, ssl?,
|
469
|
+
ssl? && @options[:ssl_verify] ? @options[:ssl_certs] : nil,
|
470
|
+
@options[:ssl_verify])
|
453
471
|
|
454
472
|
info "connected on port #{port}" << (ssl? ? ' using SSL' : '')
|
455
473
|
|
@@ -483,7 +501,6 @@ class IMAP
|
|
483
501
|
|
484
502
|
rescue => e
|
485
503
|
exception = e
|
486
|
-
error e.message
|
487
504
|
end
|
488
505
|
end.join
|
489
506
|
|
data/lib/larch/version.rb
CHANGED