+ def unsafe_connect
+ say "Connecting to IMAP server #{host}:#{port}..."
+
+ ## apparently imap.rb does a lot of threaded stuff internally and
+ ## if an exception occurs, it will catch it and re-raise it on the
+ ## calling thread. but i can't seem to catch that exception, so
+ ## i've resorted to initializing it in its own thread. surely
+ ## there's a better way.
+ exception = nil
+ ::Thread.new do
+ begin
+ #raise Net::IMAP::ByeResponseError, "simulated imap failure"
+ @imap = Net::IMAP.new host, port, ssl?
+ say "Logging in..."
+
+ ## although RFC1730 claims that "If an AUTHENTICATE command
+ ## fails with a NO response, the client may try another", in
+ ## practice it seems like they can also send a BAD response.
+ begin
+ @imap.authenticate 'CRAM-MD5', @username, @password
+ rescue Net::IMAP::BadResponseError, Net::IMAP::NoResponseError => e
+ Redwood::log "CRAM-MD5 authentication failed: #{e.class}. Trying LOGIN auth..."
+ begin
+ @imap.authenticate 'LOGIN', @username, @password
+ rescue Net::IMAP::BadResponseError, Net::IMAP::NoResponseError => e
+ Redwood::log "LOGIN authentication failed: #{e.class}. Trying plain-text LOGIN..."
+ @imap.login @username, @password
+ end
+ end
+ say "Successfully connected to #{@parsed_uri}."
+ rescue Exception => e
+ exception = e
+ ensure
+ shutup
+ end
+ end.join
+
+ raise exception if exception
+ end
+