What type of account is this?
POP3 account
IMAP account
+ WebDav(Exchange) account
Incoming server settings
Username
Password
POP3 server
IMAP server
+ WebDav(Exchange) server
Port
Security type
None
@@ -180,6 +182,8 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based
When I delete from Inbox
IMAP path prefix
Optional
+ WebDav(Exchange) path prefix
+ Optional
Outgoing server settings
SMTP server
@@ -199,6 +203,7 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based
Password
POP before SMTP
IMAP before SMTP
+ WebDav(Exchange) before SMTP
Account options
Email checking frequency
@@ -248,11 +253,11 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based
Send this address a copy of every outgoing message
- Signature
- Append a signature to every message you send
+ Signature
+ Append a signature to every message you send
- Sent Items Folder
- Save all sent messages to this folder
+ Sent Items Folder
+ Save all sent messages to this folder
Remove
The account \"%s\" will be removed from Email.
@@ -262,7 +267,7 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based
allowing this program to connect. If you are not able to sign in with
your correct email address and password, you may not have a paid
\"Plus\" account. Please launch the Web browser to gain access to
- these mail accounts.
+ these mail accounts.
Unrecognized Certificate
Accept Key
Reject Key
diff --git a/src/com/fsck/k9/R.java b/src/com/fsck/k9/R.java
index a02c5d4a0..7dbdb004b 100644
--- a/src/com/fsck/k9/R.java
+++ b/src/com/fsck/k9/R.java
@@ -91,91 +91,93 @@ public final class R {
public static final int text_box_light=0x7f020043;
}
public static final class id {
- public static final int account_always_bcc=0x7f0a000b;
- public static final int account_check_frequency=0x7f0a0018;
- public static final int account_default=0x7f0a0005;
- public static final int account_delete_policy=0x7f0a0013;
- public static final int account_delete_policy_label=0x7f0a0012;
- public static final int account_description=0x7f0a0016;
- public static final int account_email=0x7f0a0002;
- public static final int account_name=0x7f0a000a;
- public static final int account_notify=0x7f0a0019;
- public static final int account_password=0x7f0a0003;
- public static final int account_port=0x7f0a0010;
- public static final int account_require_login=0x7f0a001a;
- public static final int account_require_login_settings=0x7f0a001b;
- public static final int account_security_type=0x7f0a0011;
- public static final int account_server=0x7f0a000f;
- public static final int account_server_label=0x7f0a000e;
- public static final int account_settings=0x7f0a004e;
- public static final int account_signature=0x7f0a000c;
- public static final int account_username=0x7f0a000d;
- public static final int accounts=0x7f0a004d;
- public static final int add_attachment=0x7f0a0053;
- public static final int add_cc_bcc=0x7f0a004f;
- public static final int add_new_account=0x7f0a001d;
- public static final int attachment=0x7f0a003d;
- public static final int attachment_delete=0x7f0a0033;
- public static final int attachment_icon=0x7f0a0039;
- public static final int attachment_info=0x7f0a003a;
- public static final int attachment_name=0x7f0a0034;
- public static final int attachments=0x7f0a002e;
- public static final int bcc=0x7f0a002d;
- public static final int cancel=0x7f0a0009;
- public static final int cc=0x7f0a002c;
- public static final int check_mail=0x7f0a0047;
- public static final int chip=0x7f0a0024;
- public static final int compose=0x7f0a0048;
- public static final int date=0x7f0a0027;
- public static final int debug_logging=0x7f0a0022;
- public static final int delete=0x7f0a0038;
- public static final int delete_account=0x7f0a0046;
- public static final int description=0x7f0a001e;
- public static final int discard=0x7f0a0052;
- public static final int done=0x7f0a0017;
- public static final int download=0x7f0a003b;
- public static final int dump_settings=0x7f0a0049;
- public static final int edit_account=0x7f0a0045;
- public static final int email=0x7f0a001f;
- public static final int empty=0x7f0a001c;
- public static final int folder_name=0x7f0a0029;
- public static final int folder_status=0x7f0a002a;
- public static final int forward=0x7f0a004a;
- public static final int from=0x7f0a0026;
+ public static final int account_always_bcc=0x7f0a000c;
+ public static final int account_check_frequency=0x7f0a001a;
+ public static final int account_default=0x7f0a0006;
+ public static final int account_delete_policy=0x7f0a0014;
+ public static final int account_delete_policy_label=0x7f0a0013;
+ public static final int account_description=0x7f0a0018;
+ public static final int account_email=0x7f0a0003;
+ public static final int account_name=0x7f0a000b;
+ public static final int account_notify=0x7f0a001b;
+ public static final int account_password=0x7f0a0004;
+ public static final int account_port=0x7f0a0011;
+ public static final int account_require_login=0x7f0a001c;
+ public static final int account_require_login_settings=0x7f0a001d;
+ public static final int account_security_type=0x7f0a0012;
+ public static final int account_server=0x7f0a0010;
+ public static final int account_server_label=0x7f0a000f;
+ public static final int account_settings=0x7f0a0050;
+ public static final int account_signature=0x7f0a000d;
+ public static final int account_username=0x7f0a000e;
+ public static final int accounts=0x7f0a004f;
+ public static final int add_attachment=0x7f0a0055;
+ public static final int add_cc_bcc=0x7f0a0051;
+ public static final int add_new_account=0x7f0a001f;
+ public static final int attachment=0x7f0a003f;
+ public static final int attachment_delete=0x7f0a0035;
+ public static final int attachment_icon=0x7f0a003b;
+ public static final int attachment_info=0x7f0a003c;
+ public static final int attachment_name=0x7f0a0036;
+ public static final int attachments=0x7f0a0030;
+ public static final int bcc=0x7f0a002f;
+ public static final int cancel=0x7f0a000a;
+ public static final int cc=0x7f0a002e;
+ public static final int check_mail=0x7f0a0049;
+ public static final int chip=0x7f0a0026;
+ public static final int compose=0x7f0a004a;
+ public static final int date=0x7f0a0029;
+ public static final int debug_logging=0x7f0a0024;
+ public static final int delete=0x7f0a003a;
+ public static final int delete_account=0x7f0a0048;
+ public static final int description=0x7f0a0020;
+ public static final int discard=0x7f0a0054;
+ public static final int done=0x7f0a0019;
+ public static final int download=0x7f0a003d;
+ public static final int dump_settings=0x7f0a004b;
+ public static final int edit_account=0x7f0a0047;
+ public static final int email=0x7f0a0021;
+ public static final int empty=0x7f0a001e;
+ public static final int folder_name=0x7f0a002b;
+ public static final int folder_status=0x7f0a002c;
+ public static final int forward=0x7f0a004c;
+ public static final int from=0x7f0a0028;
public static final int imap=0x7f0a0001;
- public static final int imap_path_prefix=0x7f0a0015;
- public static final int imap_path_prefix_section=0x7f0a0014;
- public static final int main_text=0x7f0a0028;
- public static final int manual_setup=0x7f0a0006;
- public static final int mark_as_read=0x7f0a004b;
- public static final int mark_as_unread=0x7f0a0054;
- public static final int message=0x7f0a0007;
- public static final int message_content=0x7f0a002f;
- public static final int new_message_count=0x7f0a0020;
- public static final int next=0x7f0a0004;
- public static final int open=0x7f0a0044;
+ public static final int imap_path_prefix=0x7f0a0016;
+ public static final int imap_path_prefix_section=0x7f0a0015;
+ public static final int main_text=0x7f0a002a;
+ public static final int manual_setup=0x7f0a0007;
+ public static final int mark_as_read=0x7f0a004d;
+ public static final int mark_as_unread=0x7f0a0056;
+ public static final int message=0x7f0a0008;
+ public static final int message_content=0x7f0a0031;
+ public static final int new_message_count=0x7f0a0022;
+ public static final int next=0x7f0a0005;
+ public static final int open=0x7f0a0046;
public static final int pop=0x7f0a0000;
- public static final int previous=0x7f0a0035;
- public static final int progress=0x7f0a0008;
- public static final int quoted_text=0x7f0a0032;
- public static final int quoted_text_bar=0x7f0a0030;
- public static final int quoted_text_delete=0x7f0a0031;
- public static final int refresh=0x7f0a004c;
- public static final int reply=0x7f0a0036;
- public static final int reply_all=0x7f0a0037;
- public static final int save=0x7f0a0051;
- public static final int send=0x7f0a0050;
- public static final int sensitive_logging=0x7f0a0023;
- public static final int show_pictures=0x7f0a0041;
- public static final int show_pictures_section=0x7f0a0040;
- public static final int subject=0x7f0a0025;
- public static final int text1=0x7f0a0042;
- public static final int text2=0x7f0a0043;
- public static final int to=0x7f0a002b;
- public static final int to_container=0x7f0a003e;
- public static final int to_label=0x7f0a003f;
- public static final int version=0x7f0a0021;
- public static final int view=0x7f0a003c;
+ public static final int previous=0x7f0a0037;
+ public static final int progress=0x7f0a0009;
+ public static final int quoted_text=0x7f0a0034;
+ public static final int quoted_text_bar=0x7f0a0032;
+ public static final int quoted_text_delete=0x7f0a0033;
+ public static final int refresh=0x7f0a004e;
+ public static final int reply=0x7f0a0038;
+ public static final int reply_all=0x7f0a0039;
+ public static final int save=0x7f0a0053;
+ public static final int send=0x7f0a0052;
+ public static final int sensitive_logging=0x7f0a0025;
+ public static final int show_pictures=0x7f0a0043;
+ public static final int show_pictures_section=0x7f0a0042;
+ public static final int subject=0x7f0a0027;
+ public static final int text1=0x7f0a0044;
+ public static final int text2=0x7f0a0045;
+ public static final int to=0x7f0a002d;
+ public static final int to_container=0x7f0a0040;
+ public static final int to_label=0x7f0a0041;
+ public static final int version=0x7f0a0023;
+ public static final int view=0x7f0a003e;
+ public static final int webdav=0x7f0a0002;
+ public static final int webdav_path_prefix_section=0x7f0a0017;
}
public static final class layout {
public static final int account_setup_account_type=0x7f030000;
@@ -209,42 +211,43 @@ public final class R {
public static final int message_view_option=0x7f090006;
}
public static final class string {
- public static final int account_delete_dlg_instructions_fmt=0x7f0600ca;
- public static final int account_delete_dlg_title=0x7f0600c9;
+ public static final int account_delete_dlg_instructions_fmt=0x7f0600cf;
+ public static final int account_delete_dlg_title=0x7f0600ce;
public static final int account_settings_action=0x7f06001b;
- public static final int account_settings_add_account_label=0x7f0600b9;
- public static final int account_settings_always_bcc_label=0x7f0600c3;
- public static final int account_settings_always_bcc_summary=0x7f0600c4;
- public static final int account_settings_composition_label=0x7f0600c2;
- public static final int account_settings_composition_title=0x7f0600c1;
- public static final int account_settings_default=0x7f0600ad;
- public static final int account_settings_default_label=0x7f0600ae;
- public static final int account_settings_default_summary=0x7f0600af;
- public static final int account_settings_description_label=0x7f0600ba;
- public static final int account_settings_email_label=0x7f0600b1;
- public static final int account_settings_incoming_label=0x7f0600b5;
- public static final int account_settings_incoming_summary=0x7f0600b6;
- public static final int account_settings_mail_check_frequency_label=0x7f0600b4;
- public static final int account_settings_name_label=0x7f0600bb;
- public static final int account_settings_notifications=0x7f0600bc;
- public static final int account_settings_notify_label=0x7f0600b0;
- public static final int account_settings_notify_summary=0x7f0600b2;
- public static final int account_settings_outgoing_label=0x7f0600b7;
- public static final int account_settings_outgoing_summary=0x7f0600b8;
- public static final int account_settings_ringtone=0x7f0600bf;
- public static final int account_settings_sent_items_label=0x7f0600c7;
- public static final int account_settings_sent_items_summary=0x7f0600c8;
- public static final int account_settings_servers=0x7f0600c0;
- public static final int account_settings_show_combined_label=0x7f0600b3;
- public static final int account_settings_signature_label=0x7f0600c5;
- public static final int account_settings_signature_summary=0x7f0600c6;
- public static final int account_settings_title_fmt=0x7f0600ac;
- public static final int account_settings_vibrate_enable=0x7f0600bd;
- public static final int account_settings_vibrate_summary=0x7f0600be;
+ public static final int account_settings_add_account_label=0x7f0600be;
+ public static final int account_settings_always_bcc_label=0x7f0600c8;
+ public static final int account_settings_always_bcc_summary=0x7f0600c9;
+ public static final int account_settings_composition_label=0x7f0600c7;
+ public static final int account_settings_composition_title=0x7f0600c6;
+ public static final int account_settings_default=0x7f0600b2;
+ public static final int account_settings_default_label=0x7f0600b3;
+ public static final int account_settings_default_summary=0x7f0600b4;
+ public static final int account_settings_description_label=0x7f0600bf;
+ public static final int account_settings_email_label=0x7f0600b6;
+ public static final int account_settings_incoming_label=0x7f0600ba;
+ public static final int account_settings_incoming_summary=0x7f0600bb;
+ public static final int account_settings_mail_check_frequency_label=0x7f0600b9;
+ public static final int account_settings_name_label=0x7f0600c0;
+ public static final int account_settings_notifications=0x7f0600c1;
+ public static final int account_settings_notify_label=0x7f0600b5;
+ public static final int account_settings_notify_summary=0x7f0600b7;
+ public static final int account_settings_outgoing_label=0x7f0600bc;
+ public static final int account_settings_outgoing_summary=0x7f0600bd;
+ public static final int account_settings_ringtone=0x7f0600c4;
+ public static final int account_settings_sent_items_label=0x7f0600cc;
+ public static final int account_settings_sent_items_summary=0x7f0600cd;
+ public static final int account_settings_servers=0x7f0600c5;
+ public static final int account_settings_show_combined_label=0x7f0600b8;
+ public static final int account_settings_signature_label=0x7f0600ca;
+ public static final int account_settings_signature_summary=0x7f0600cb;
+ public static final int account_settings_title_fmt=0x7f0600b1;
+ public static final int account_settings_vibrate_enable=0x7f0600c2;
+ public static final int account_settings_vibrate_summary=0x7f0600c3;
public static final int account_setup_account_type_imap_action=0x7f060079;
public static final int account_setup_account_type_instructions=0x7f060077;
public static final int account_setup_account_type_pop_action=0x7f060078;
public static final int account_setup_account_type_title=0x7f060076;
+ public static final int account_setup_account_type_webdav_action=0x7f06007a;
public static final int account_setup_basics_default_label=0x7f060069;
public static final int account_setup_basics_email_error_duplicate_fmt=0x7f060067;
public static final int account_setup_basics_email_error_invalid_fmt=0x7f060066;
@@ -260,74 +263,78 @@ public final class R {
public static final int account_setup_check_settings_finishing_msg=0x7f06006f;
public static final int account_setup_check_settings_retr_info_msg=0x7f06006c;
public static final int account_setup_check_settings_title=0x7f06006b;
- public static final int account_setup_failed_dlg_auth_message_fmt=0x7f0600a8;
+ public static final int account_setup_failed_dlg_auth_message_fmt=0x7f0600ad;
/** Username or password incorrect\n(ERR01 Account does not exist)
*/
- public static final int account_setup_failed_dlg_certificate_message_fmt=0x7f0600a9;
+ public static final int account_setup_failed_dlg_certificate_message_fmt=0x7f0600ae;
/** Cannot connect to server\n(Connection timed out)
*/
- public static final int account_setup_failed_dlg_edit_details_action=0x7f0600ab;
- public static final int account_setup_failed_dlg_invalid_certificate_accept=0x7f0600ce;
- public static final int account_setup_failed_dlg_invalid_certificate_reject=0x7f0600cf;
- public static final int account_setup_failed_dlg_invalid_certificate_title=0x7f0600cd;
+ public static final int account_setup_failed_dlg_edit_details_action=0x7f0600b0;
+ public static final int account_setup_failed_dlg_invalid_certificate_accept=0x7f0600d3;
+ public static final int account_setup_failed_dlg_invalid_certificate_reject=0x7f0600d4;
+ public static final int account_setup_failed_dlg_invalid_certificate_title=0x7f0600d2;
/** Cannot safely connect to server\n(Invalid certificate)
*/
- public static final int account_setup_failed_dlg_server_message_fmt=0x7f0600aa;
- public static final int account_setup_failed_dlg_title=0x7f0600a7;
+ public static final int account_setup_failed_dlg_server_message_fmt=0x7f0600af;
+ public static final int account_setup_failed_dlg_title=0x7f0600ac;
public static final int account_setup_finished_toast=0x7f060075;
- public static final int account_setup_incoming_delete_policy_7days_label=0x7f060088;
- public static final int account_setup_incoming_delete_policy_delete_label=0x7f060089;
- public static final int account_setup_incoming_delete_policy_label=0x7f060086;
- public static final int account_setup_incoming_delete_policy_never_label=0x7f060087;
- public static final int account_setup_incoming_imap_path_prefix_hint=0x7f06008b;
- public static final int account_setup_incoming_imap_path_prefix_label=0x7f06008a;
- public static final int account_setup_incoming_imap_server_label=0x7f06007e;
- public static final int account_setup_incoming_password_label=0x7f06007c;
- public static final int account_setup_incoming_pop_server_label=0x7f06007d;
- public static final int account_setup_incoming_port_label=0x7f06007f;
- public static final int account_setup_incoming_security_label=0x7f060080;
- public static final int account_setup_incoming_security_none_label=0x7f060081;
- public static final int account_setup_incoming_security_ssl_label=0x7f060083;
- public static final int account_setup_incoming_security_ssl_optional_label=0x7f060082;
- public static final int account_setup_incoming_security_tls_label=0x7f060085;
- public static final int account_setup_incoming_security_tls_optional_label=0x7f060084;
- public static final int account_setup_incoming_title=0x7f06007a;
- public static final int account_setup_incoming_username_label=0x7f06007b;
+ public static final int account_setup_incoming_delete_policy_7days_label=0x7f06008a;
+ public static final int account_setup_incoming_delete_policy_delete_label=0x7f06008b;
+ public static final int account_setup_incoming_delete_policy_label=0x7f060088;
+ public static final int account_setup_incoming_delete_policy_never_label=0x7f060089;
+ public static final int account_setup_incoming_imap_path_prefix_hint=0x7f06008d;
+ public static final int account_setup_incoming_imap_path_prefix_label=0x7f06008c;
+ public static final int account_setup_incoming_imap_server_label=0x7f06007f;
+ public static final int account_setup_incoming_password_label=0x7f06007d;
+ public static final int account_setup_incoming_pop_server_label=0x7f06007e;
+ public static final int account_setup_incoming_port_label=0x7f060081;
+ public static final int account_setup_incoming_security_label=0x7f060082;
+ public static final int account_setup_incoming_security_none_label=0x7f060083;
+ public static final int account_setup_incoming_security_ssl_label=0x7f060085;
+ public static final int account_setup_incoming_security_ssl_optional_label=0x7f060084;
+ public static final int account_setup_incoming_security_tls_label=0x7f060087;
+ public static final int account_setup_incoming_security_tls_optional_label=0x7f060086;
+ public static final int account_setup_incoming_title=0x7f06007b;
+ public static final int account_setup_incoming_username_label=0x7f06007c;
+ public static final int account_setup_incoming_webdav_path_prefix_hint=0x7f06008f;
+ public static final int account_setup_incoming_webdav_path_prefix_label=0x7f06008e;
+ public static final int account_setup_incoming_webdav_server_label=0x7f060080;
public static final int account_setup_names_account_name_label=0x7f060073;
public static final int account_setup_names_instructions=0x7f060072;
public static final int account_setup_names_title=0x7f060071;
public static final int account_setup_names_user_name_label=0x7f060074;
- public static final int account_setup_options_default_label=0x7f0600a5;
- public static final int account_setup_options_mail_check_frequency_10min=0x7f0600a1;
- public static final int account_setup_options_mail_check_frequency_15min=0x7f0600a2;
- public static final int account_setup_options_mail_check_frequency_1hour=0x7f0600a4;
- public static final int account_setup_options_mail_check_frequency_30min=0x7f0600a3;
- public static final int account_setup_options_mail_check_frequency_5min=0x7f0600a0;
- public static final int account_setup_options_mail_check_frequency_label=0x7f06009e;
+ public static final int account_setup_options_default_label=0x7f0600aa;
+ public static final int account_setup_options_mail_check_frequency_10min=0x7f0600a6;
+ public static final int account_setup_options_mail_check_frequency_15min=0x7f0600a7;
+ public static final int account_setup_options_mail_check_frequency_1hour=0x7f0600a9;
+ public static final int account_setup_options_mail_check_frequency_30min=0x7f0600a8;
+ public static final int account_setup_options_mail_check_frequency_5min=0x7f0600a5;
+ public static final int account_setup_options_mail_check_frequency_label=0x7f0600a3;
/** Frequency also used in account_settings_*
*/
- public static final int account_setup_options_mail_check_frequency_never=0x7f06009f;
- public static final int account_setup_options_notify_label=0x7f0600a6;
- public static final int account_setup_options_title=0x7f06009d;
- public static final int account_setup_outgoing_authentication_basic_label=0x7f060098;
- public static final int account_setup_outgoing_authentication_basic_password_label=0x7f06009a;
- public static final int account_setup_outgoing_authentication_basic_username_label=0x7f060099;
- public static final int account_setup_outgoing_authentication_imap_before_smtp_label=0x7f06009c;
+ public static final int account_setup_options_mail_check_frequency_never=0x7f0600a4;
+ public static final int account_setup_options_notify_label=0x7f0600ab;
+ public static final int account_setup_options_title=0x7f0600a2;
+ public static final int account_setup_outgoing_authentication_basic_label=0x7f06009c;
+ public static final int account_setup_outgoing_authentication_basic_password_label=0x7f06009e;
+ public static final int account_setup_outgoing_authentication_basic_username_label=0x7f06009d;
+ public static final int account_setup_outgoing_authentication_imap_before_smtp_label=0x7f0600a0;
/** The authentication strings below are for a planned (hopefully) change to the above username and password options
*/
- public static final int account_setup_outgoing_authentication_label=0x7f060097;
- public static final int account_setup_outgoing_authentication_pop_before_smtp_label=0x7f06009b;
- public static final int account_setup_outgoing_password_label=0x7f060096;
- public static final int account_setup_outgoing_port_label=0x7f06008e;
- public static final int account_setup_outgoing_require_login_label=0x7f060094;
- public static final int account_setup_outgoing_security_label=0x7f06008f;
- public static final int account_setup_outgoing_security_none_label=0x7f060090;
- public static final int account_setup_outgoing_security_ssl_label=0x7f060091;
- public static final int account_setup_outgoing_security_tls_label=0x7f060093;
- public static final int account_setup_outgoing_security_tls_optional_label=0x7f060092;
- public static final int account_setup_outgoing_smtp_server_label=0x7f06008d;
- public static final int account_setup_outgoing_title=0x7f06008c;
- public static final int account_setup_outgoing_username_label=0x7f060095;
+ public static final int account_setup_outgoing_authentication_label=0x7f06009b;
+ public static final int account_setup_outgoing_authentication_pop_before_smtp_label=0x7f06009f;
+ public static final int account_setup_outgoing_authentication_webdav_before_smtp_label=0x7f0600a1;
+ public static final int account_setup_outgoing_password_label=0x7f06009a;
+ public static final int account_setup_outgoing_port_label=0x7f060092;
+ public static final int account_setup_outgoing_require_login_label=0x7f060098;
+ public static final int account_setup_outgoing_security_label=0x7f060093;
+ public static final int account_setup_outgoing_security_none_label=0x7f060094;
+ public static final int account_setup_outgoing_security_ssl_label=0x7f060095;
+ public static final int account_setup_outgoing_security_tls_label=0x7f060097;
+ public static final int account_setup_outgoing_security_tls_optional_label=0x7f060096;
+ public static final int account_setup_outgoing_smtp_server_label=0x7f060091;
+ public static final int account_setup_outgoing_title=0x7f060090;
+ public static final int account_setup_outgoing_username_label=0x7f060099;
public static final int accounts_action=0x7f06001d;
public static final int accounts_context_menu_title=0x7f060029;
public static final int accounts_title=0x7f060004;
@@ -413,8 +420,8 @@ public final class R {
public static final int okay_action=0x7f060008;
public static final int open_action=0x7f06001a;
public static final int preferences_action=0x7f060019;
- public static final int provider_note_live=0x7f0600cc;
- public static final int provider_note_yahoo=0x7f0600cb;
+ public static final int provider_note_live=0x7f0600d1;
+ public static final int provider_note_yahoo=0x7f0600d0;
public static final int read_action=0x7f06001e;
public static final int read_attachment_desc=0x7f060003;
public static final int read_attachment_label=0x7f060002;
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupAccountType.java b/src/com/fsck/k9/activity/setup/AccountSetupAccountType.java
index 79a346c85..1a6a68bec 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupAccountType.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupAccountType.java
@@ -42,6 +42,7 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
setContentView(R.layout.account_setup_account_type);
((Button)findViewById(R.id.pop)).setOnClickListener(this);
((Button)findViewById(R.id.imap)).setOnClickListener(this);
+ ((Button)findViewById(R.id.webdav)).setOnClickListener(this);
mAccount = (Account)getIntent().getSerializableExtra(EXTRA_ACCOUNT);
mMakeDefault = (boolean)getIntent().getBooleanExtra(EXTRA_MAKE_DEFAULT, false);
@@ -77,6 +78,21 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
finish();
}
+ private void onWebDav() {
+ try {
+ URI uri = new URI(mAccount.getStoreUri());
+ uri = new URI("webdav", uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null);
+ mAccount.setStoreUri(uri.toString());
+ } catch (URISyntaxException use) {
+ /*
+ * This should not happen.
+ */
+ throw new Error(use);
+ }
+ AccountSetupIncoming.actionIncomingSettings(this, mAccount, mMakeDefault);
+ finish();
+ }
+
public void onClick(View v) {
switch (v.getId()) {
case R.id.pop:
@@ -85,6 +101,9 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
case R.id.imap:
onImap();
break;
+ case R.id.webdav:
+ onWebDav();
+ break;
}
}
}
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
index d5ee5b029..e7ef237d4 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
@@ -40,6 +40,12 @@ public class AccountSetupIncoming extends Activity implements OnClickListener {
private static final String imapSchemes[] = {
"imap", "imap+ssl", "imap+ssl+", "imap+tls", "imap+tls+"
};
+ private static final int webdavPorts[] = {
+ 80, 443, 443, 443, 443
+ };
+ private static final String webdavSchemes[] = {
+ "webdav", "webdav+ssl", "webdav+ssl+", "webdav+tls", "webdav+tls+"
+ };
private int mAccountPorts[];
private String mAccountSchemes[];
@@ -200,6 +206,10 @@ public class AccountSetupIncoming extends Activity implements OnClickListener {
if (uri.getPath() != null && uri.getPath().length() > 0) {
mImapPathPrefixView.setText(uri.getPath().substring(1));
}
+ } else if (uri.getScheme().startsWith("webdav")) {
+ serverLabelView.setText(R.string.account_setup_incoming_webdav_server_label);
+ mAccountPorts = webdavPorts;
+ mAccountSchemes = webdavSchemes;
} else {
throw new Error("Unknown account type: " + mAccount.getStoreUri());
}
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
index dfc547070..6ddaf36dc 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
@@ -41,6 +41,12 @@ public class AccountSetupOutgoing extends Activity implements OnClickListener,
private static final String smtpSchemes[] = {
"smtp", "smtp+ssl", "smtp+ssl+", "smtp+tls", "smtp+tls+"
};
+ private static final int webdavPorts[] = {
+ 80, 443, 443, 443, 443
+ };
+ private static final String webdavSchemes[] = {
+ "webdav", "webdav+ssl", "webdav+ssl+", "webdav+tls", "webdav+tls+"
+ };
private EditText mUsernameView;
private EditText mPasswordView;
@@ -72,6 +78,19 @@ public class AccountSetupOutgoing extends Activity implements OnClickListener,
super.onCreate(savedInstanceState);
setContentView(R.layout.account_setup_outgoing);
+ mAccount = (Account)getIntent().getSerializableExtra(EXTRA_ACCOUNT);
+
+ try {
+ if (new URI(mAccount.getStoreUri()).getScheme().startsWith("webdav")) {
+ mAccount.setTransportUri(mAccount.getStoreUri());
+ AccountSetupCheckSettings.actionCheckSettings(this, mAccount, false, true);
+ }
+ } catch (URISyntaxException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
mUsernameView = (EditText)findViewById(R.id.account_username);
mPasswordView = (EditText)findViewById(R.id.account_password);
mServerView = (EditText)findViewById(R.id.account_server);
diff --git a/src/com/fsck/k9/k9.java b/src/com/fsck/k9/k9.java
index 1569c60f1..6a6ad46ab 100644
--- a/src/com/fsck/k9/k9.java
+++ b/src/com/fsck/k9/k9.java
@@ -64,13 +64,14 @@ public class k9 extends Application {
* The MIME type(s) of attachments we're willing to download to SD.
*/
public static final String[] ACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES = new String[] {
- "*/*",
+ "image/*",
};
/**
* The MIME type(s) of attachments we're not willing to download to SD.
*/
public static final String[] UNACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES = new String[] {
+ "image/gif",
};
/**
@@ -87,7 +88,7 @@ public class k9 extends Application {
public static final int DEFAULT_VISIBLE_LIMIT = 100;
/**
- * Number of additional messages to load when a user selectes "Load more messages..."
+ * Number of additioanl messages to load when a user selectes "Load more messages..."
*/
public static final int VISIBLE_LIMIT_INCREMENT = 100;
@@ -157,13 +158,6 @@ public class k9 extends Application {
* doesn't work in Android and MimeMessage does not have access to a Context.
*/
BinaryTempFileBody.setTempDirectory(getCacheDir());
-
- /*
- * Enable background sync of messages
- */
-
- setServicesEnabled(this);
-
}
}
diff --git a/src/com/fsck/k9/mail/Store.java b/src/com/fsck/k9/mail/Store.java
index 9f7474ac8..87157ed58 100644
--- a/src/com/fsck/k9/mail/Store.java
+++ b/src/com/fsck/k9/mail/Store.java
@@ -8,6 +8,7 @@ import android.app.Application;
import com.fsck.k9.mail.store.ImapStore;
import com.fsck.k9.mail.store.LocalStore;
import com.fsck.k9.mail.store.Pop3Store;
+import com.fsck.k9.mail.store.WebDavStore;
/**
* Store is the access point for an email message store. It's location can be
@@ -54,8 +55,11 @@ public abstract class Store {
store = new Pop3Store(uri);
} else if (uri.startsWith("local")) {
store = new LocalStore(uri, application);
+ } else if (uri.startsWith("webdav")) {
+ store = new WebDavStore(uri);
}
+
if (store != null) {
mStores.put(uri, store);
}
diff --git a/src/com/fsck/k9/mail/Transport.java b/src/com/fsck/k9/mail/Transport.java
index eba3f8969..8f55cad8d 100644
--- a/src/com/fsck/k9/mail/Transport.java
+++ b/src/com/fsck/k9/mail/Transport.java
@@ -2,6 +2,7 @@
package com.fsck.k9.mail;
import com.fsck.k9.mail.transport.SmtpTransport;
+import com.fsck.k9.mail.transport.WebDavTransport;
public abstract class Transport {
protected static final int SOCKET_CONNECT_TIMEOUT = 10000;
@@ -9,6 +10,8 @@ public abstract class Transport {
public synchronized static Transport getInstance(String uri) throws MessagingException {
if (uri.startsWith("smtp")) {
return new SmtpTransport(uri);
+ } else if (uri.startsWith("webdav")) {
+ return new WebDavTransport(uri);
} else {
throw new MessagingException("Unable to locate an applicable Transport for " + uri);
}
diff --git a/src/com/fsck/k9/mail/store/TrustManagerFactory.java b/src/com/fsck/k9/mail/store/TrustManagerFactory.java
index 27e449725..70add0670 100644
--- a/src/com/fsck/k9/mail/store/TrustManagerFactory.java
+++ b/src/com/fsck/k9/mail/store/TrustManagerFactory.java
@@ -26,11 +26,11 @@ public final class TrustManagerFactory {
private static X509TrustManager defaultTrustManager;
private static X509TrustManager unsecureTrustManager;
private static X509TrustManager localTrustManager;
-
+
private static SecureX509TrustManager secureTrustManager;
private static X509Certificate[] lastCertChain = null;
-
+
private static File keyStoreFile;
private static KeyStore keyStore;
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
new file mode 100644
index 000000000..48466725c
--- /dev/null
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -0,0 +1,1681 @@
+package com.fsck.k9.mail.store;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.DateFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Stack;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.fsck.k9.k9;
+import com.fsck.k9.mail.FetchProfile;
+import com.fsck.k9.mail.Flag;
+import com.fsck.k9.mail.Folder;
+import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.MessageRetrievalListener;
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.Store;
+import com.fsck.k9.mail.internet.MimeBodyPart;
+import com.fsck.k9.mail.internet.MimeMessage;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ *
+ * Uses WebDAV formatted HTTP calls to an MS Exchange server to fetch emails
+ * and email information. This has only been tested on an MS Exchange
+ * Server 2003. It uses Form-Based authentication and requires that
+ * Outlook Web Access be enabled on the server.
+ *
+ */
+public class WebDavStore extends Store {
+ public static final int CONNECTION_SECURITY_NONE = 0;
+ public static final int CONNECTION_SECURITY_TLS_OPTIONAL = 1;
+ public static final int CONNECTION_SECURITY_TLS_REQUIRED = 2;
+ public static final int CONNECTION_SECURITY_SSL_REQUIRED = 3;
+ public static final int CONNECTION_SECURITY_SSL_OPTIONAL = 4;
+
+ private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.SEEN, Flag.ANSWERED };
+
+ private int mConnectionSecurity;
+ private String mUsername; /* Stores the username for authentications */
+ private String alias;
+ private String mPassword; /* Stores the password for authentications */
+ private String mUrl; /* Stores the base URL for the server */
+
+ private CookieStore mAuthCookies; /* Stores cookies from authentication */
+ private boolean mAuthenticated = false; /* Stores authentication state */
+ private long mLastAuth = -1; /* Stores the timestamp of last auth */
+ private long mAuthTimeout = 5 * 60;
+
+ /**
+ * webdav://user:password@server:port CONNECTION_SECURITY_NONE
+ * webdav+tls://user:password@server:port CONNECTION_SECURITY_TLS_OPTIONAL
+ * webdav+tls+://user:password@server:port CONNECTION_SECURITY_TLS_REQUIRED
+ * webdav+ssl+://user:password@server:port CONNECTION_SECURITY_SSL_REQUIRED
+ * webdav+ssl://user:password@server:port CONNECTION_SECURITY_SSL_OPTIONAL
+ *
+ * @param _uri
+ */
+ public WebDavStore(String _uri) throws MessagingException {
+ URI uri;
+
+ try {
+ uri = new URI(_uri);
+ } catch (URISyntaxException use) {
+ throw new MessagingException("Invalid WebDavStore URI", use);
+ }
+ String scheme = uri.getScheme();
+ if (scheme.equals("webdav")) {
+ mConnectionSecurity = CONNECTION_SECURITY_NONE;
+ } else if (scheme.equals("webdav+ssl")) {
+ mConnectionSecurity = CONNECTION_SECURITY_SSL_OPTIONAL;
+ } else if (scheme.equals("webdav+ssl+")) {
+ mConnectionSecurity = CONNECTION_SECURITY_SSL_REQUIRED;
+ } else if (scheme.equals("webdav+tls")) {
+ mConnectionSecurity = CONNECTION_SECURITY_TLS_OPTIONAL;
+ } else if (scheme.equals("webdav+tls+")) {
+ mConnectionSecurity = CONNECTION_SECURITY_TLS_REQUIRED;
+ } else {
+ throw new MessagingException("Unsupported protocol");
+ }
+
+ String host = uri.getHost();
+
+ if (host.startsWith("http")) {
+ String[] hostParts = host.split("://", 2);
+ if (hostParts.length > 1) {
+ host = hostParts[1];
+ }
+ }
+
+ if (mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED ||
+ mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED ||
+ mConnectionSecurity == CONNECTION_SECURITY_TLS_OPTIONAL ||
+ mConnectionSecurity == CONNECTION_SECURITY_SSL_OPTIONAL) {
+ this.mUrl = "https://" + host;
+ } else {
+ this.mUrl = "http://" + host;
+ }
+
+ if (uri.getUserInfo() != null) {
+ String[] userInfoParts = uri.getUserInfo().split(":", 2);
+ mUsername = userInfoParts[0];
+ String userParts[] = mUsername.split("/", 2);
+
+ if (userParts.length > 1) {
+ alias = userParts[1];
+ } else {
+ alias = mUsername;
+ }
+ if (userInfoParts.length > 1) {
+ mPassword = userInfoParts[1];
+ }
+ }
+ }
+
+
+ @Override
+ public void checkSettings() throws MessagingException {
+ Log.e(k9.LOG_TAG, "WebDavStore.checkSettings() not implemented");
+ }
+
+ @Override
+ public Folder[] getPersonalNamespaces() throws MessagingException {
+ ArrayList folderList = new ArrayList();
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ HttpEntity responseEntity;
+ HttpGeneric httpmethod;
+ HttpResponse response;
+ StringEntity messageEntity;
+ String messageBody;
+ int status_code;
+
+ if (needAuth()) {
+ authenticate();
+ }
+
+ if (this.mAuthenticated == false ||
+ this.mAuthCookies == null) {
+ return folderList.toArray(new Folder[] {});
+ }
+
+ try {
+ /** Set up and execute the request */
+ httpclient.setCookieStore(this.mAuthCookies);
+ messageBody = getFolderListXml();
+ messageEntity = new StringEntity(messageBody);
+ messageEntity.setContentType("text/xml");
+
+ httpmethod = new HttpGeneric(this.mUrl + "/Exchange/" + this.mUsername);
+ httpmethod.setMethod("SEARCH");
+ httpmethod.setEntity(messageEntity);
+ httpmethod.setHeader("Brief", "t");
+
+ response = httpclient.execute(httpmethod);
+ status_code = response.getStatusLine().getStatusCode();
+
+ if (status_code < 200 ||
+ status_code > 300) {
+ throw new IOException("Error getting folder listing");
+ }
+
+ responseEntity = response.getEntity();
+
+ if (responseEntity != null) {
+ /** Parse the returned data */
+ try {
+ InputStream istream = responseEntity.getContent();
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+
+ XMLReader xr = sp.getXMLReader();
+
+ WebDavHandler myHandler = new WebDavHandler();
+ xr.setContentHandler(myHandler);
+
+ xr.parse(new InputSource(istream));
+
+ ParsedDataSet dataset = myHandler.getDataSet();
+
+ String[] folderUrls = dataset.getHrefs();
+ int urlLength = folderUrls.length;
+
+ for (int i = 0; i < urlLength; i++) {
+ String[] urlParts = folderUrls[i].split("/");
+ String folderName = urlParts[urlParts.length - 1];
+ if (folderName.equalsIgnoreCase(k9.INBOX)) {
+ folderName = "INBOX";
+ }
+ folderList.add(getFolder(java.net.URLDecoder.decode(folderName, "UTF-8")));
+ }
+ } catch (SAXException se) {
+ Log.e(k9.LOG_TAG, "Error with SAXParser " + se);
+ } catch (ParserConfigurationException pce) {
+ Log.e(k9.LOG_TAG, "Error with SAXParser " + pce);
+ }
+ }
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "Error with encoding " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException " + ioe);
+ }
+
+ return folderList.toArray(new WebDavFolder[] {});
+ }
+
+ @Override
+ public Folder getFolder(String name) throws MessagingException {
+ WebDavFolder folder;
+ folder = new WebDavFolder(name);
+ return folder;
+ }
+
+ /***************************************************************
+ * WebDAV XML Request body retrieval functions
+ */
+
+ private String getFolderListXml() {
+ StringBuffer buffer = new StringBuffer(200);
+ buffer.append("");
+ buffer.append("\r\n");
+ buffer.append("SELECT \"DAV:ishidden\"\r\n");
+ buffer.append(" FROM \"\"\r\n");
+ buffer.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=True\r\n");
+ buffer.append("\r\n");
+
+ return buffer.toString();
+
+ }
+
+ private String getMessageCountXml(String messageState) {
+ StringBuffer buffer = new StringBuffer(200);
+ buffer.append("");
+ buffer.append("\r\n");
+ buffer.append("SELECT \"DAV:visiblecount\"\r\n");
+ buffer.append(" FROM \"\"\r\n");
+ buffer.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False AND \"urn:schemas:httpmail:read\"="+messageState+"\r\n");
+ buffer.append(" GROUP BY \"DAV:ishidden\"\r\n");
+ buffer.append("\r\n");
+ return buffer.toString();
+ }
+
+ private String getMessageEnvelopeXml(String[] uids) {
+ StringBuffer buffer = new StringBuffer(200);
+ buffer.append("");
+ buffer.append("\r\n");
+ buffer.append("SELECT \"DAV:uid\", \"DAV:getcontentlength\",");
+ buffer.append(" \"urn:schemas:mailheader:received\",");
+ buffer.append(" \"urn:schemas:mailheader:mime-version\",");
+ buffer.append(" \"urn:schemas:mailheader:content-type\",");
+ buffer.append(" \"urn:schemas:mailheader:subject\",");
+ buffer.append(" \"urn:schemas:mailheader:date\",");
+ buffer.append(" \"urn:schemas:mailheader:thread-topic\",");
+ buffer.append(" \"urn:schemas:mailheader:thread-index\",");
+ buffer.append(" \"urn:schemas:mailheader:from\",");
+ buffer.append(" \"urn:schemas:mailheader:to\",");
+ buffer.append(" \"urn:schemas:mailheader:in-reply-to\",");
+ buffer.append(" \"urn:schemas:mailheader:return-path\",");
+ buffer.append(" \"urn:schemas:mailheader:cc\",");
+ buffer.append(" \"urn:schemas:mailheader:references\",");
+ buffer.append(" \"urn:schemas:httpmail:read\"");
+ buffer.append(" \r\n");
+ buffer.append(" FROM \"\"\r\n");
+ buffer.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False AND ");
+ for (int i = 0, count = uids.length; i < count; i++) {
+ if (i != 0) {
+ buffer.append(" OR ");
+ }
+ buffer.append(" \"DAV:uid\"='"+uids[i]+"' ");
+ }
+ buffer.append("\r\n");
+ buffer.append("\r\n");
+ return buffer.toString();
+ }
+
+ private String getMessagesXml() {
+ StringBuffer buffer = new StringBuffer(200);
+ buffer.append("");
+ buffer.append("\r\n");
+ buffer.append("SELECT \"DAV:uid\"\r\n");
+ buffer.append(" FROM \"\"\r\n");
+ buffer.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False\r\n");
+ buffer.append("\r\n");
+ return buffer.toString();
+ }
+
+ private String getMessageUrlsXml(String[] uids) {
+ StringBuffer buffer = new StringBuffer(600);
+ buffer.append("");
+ buffer.append("\r\n");
+ buffer.append("SELECT \"urn:schemas:httpmail:read\", \"DAV:uid\"\r\n");
+ buffer.append(" FROM \"\"\r\n");
+ buffer.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False AND ");
+ for (int i = 0, count = uids.length; i < count; i++) {
+ if (i != 0) {
+ buffer.append(" OR ");
+ }
+
+ buffer.append(" \"DAV:uid\"='"+uids[i]+"' ");
+
+ }
+ buffer.append("\r\n");
+ buffer.append("\r\n");
+ return buffer.toString();
+ }
+
+ private String getMessageFlagsXml(String[] uids) throws MessagingException {
+ if (uids.length == 0) {
+ throw new MessagingException("Attempt to get flags on 0 length array for uids");
+ }
+
+ StringBuffer buffer = new StringBuffer(200);
+ buffer.append("");
+ buffer.append("\r\n");
+ buffer.append("SELECT \"urn:schemas:httpmail:read\", \"DAV:uid\"\r\n");
+ buffer.append(" FROM \"\"\r\n");
+ buffer.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False AND ");
+
+ for (int i = 0, count = uids.length; i < count; i++) {
+ if (i != 0) {
+ buffer.append(" OR ");
+ }
+ buffer.append(" \"DAV:uid\"='"+uids[i]+"' ");
+ }
+ buffer.append("\r\n");
+ buffer.append("\r\n");
+ return buffer.toString();
+ }
+
+ private String getMarkMessagesReadXml(String[] urls) {
+ StringBuffer buffer = new StringBuffer(600);
+ buffer.append("\r\n");
+ buffer.append("\r\n");
+ buffer.append("\r\n");
+ for (int i = 0, count = urls.length; i < count; i++) {
+ buffer.append(" "+urls[i].substring(urls[i].lastIndexOf('/') + 1)+"\r\n");
+ }
+ buffer.append("\r\n");
+ buffer.append("\r\n");
+ buffer.append(" \r\n");
+ buffer.append(" 1\r\n");
+ buffer.append(" \r\n");
+ buffer.append("\r\n");
+ buffer.append("\r\n");
+ return buffer.toString();
+ }
+
+ /***************************************************************
+ * Authentication related methods
+ */
+
+ /**
+ * Performs Form Based authentication regardless of the current
+ * authentication state
+ */
+ public void authenticate() {
+ try {
+ this.mAuthCookies = doAuthentication(this.mUsername, this.mPassword, this.mUrl);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "Error during authentication: " + ioe);
+ this.mAuthCookies = null;
+ }
+
+ if (this.mAuthCookies == null) {
+ this.mAuthenticated = false;
+ } else {
+ this.mAuthenticated = true;
+ this.mLastAuth = System.currentTimeMillis()/1000;
+ }
+ }
+
+ /**
+ * Determines if a new authentication is needed.
+ * Returns true if new authentication is needed.
+ */
+ public boolean needAuth() {
+ boolean status = false;
+ long currentTime = -1;
+ if (this.mAuthenticated == false) {
+ status = true;
+ }
+
+ currentTime = System.currentTimeMillis()/1000;
+ if ((currentTime - this.mLastAuth) > (this.mAuthTimeout)) {
+ status = true;
+ }
+ return status;
+ }
+
+ /**
+ * Performs the Form Based Authentication
+ * Returns the CookieStore object for later use or null
+ */
+ public CookieStore doAuthentication(String username, String password,
+ String url) throws IOException {
+ String authPath = "/exchweb/bin/auth/owaauth.dll";
+ CookieStore cookies = null;
+
+ /* Browser Client */
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+
+ /* Post Method */
+ HttpPost httppost = new HttpPost(url + authPath);
+
+ /** Build the POST data to use */
+ ArrayList pairs = new ArrayList();
+ pairs.add(new BasicNameValuePair("username", username));
+ pairs.add(new BasicNameValuePair("password", password));
+ pairs.add(new BasicNameValuePair("destination", url + "/Exchange/"));
+ pairs.add(new BasicNameValuePair("flags", "0"));
+ pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On"));
+ pairs.add(new BasicNameValuePair("forcedownlevel", "0"));
+ pairs.add(new BasicNameValuePair("trusted", "0"));
+
+ try {
+ UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(pairs);
+
+ httppost.setEntity(formEntity);
+
+ /** Perform the actual POST */
+ HttpResponse response = httpclient.execute(httppost);
+ HttpEntity entity = response.getEntity();
+ int status_code = response.getStatusLine().getStatusCode();
+
+ /** Verify success */
+ if (status_code > 300 ||
+ status_code < 200) {
+ throw new IOException("Error during authentication: "+status_code);
+ }
+
+ cookies = httpclient.getCookieStore();
+ if (cookies == null) {
+ throw new IOException("Error during authentication: No Cookies");
+ }
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "Error encoding POST data for authencation");
+ }
+ return cookies;
+ }
+
+ public CookieStore getAuthCookies() {
+ return mAuthCookies;
+ }
+ public String getAlias() {
+ return alias;
+ }
+ public String getUrl() {
+ return mUrl;
+ }
+
+ /*************************************************************************
+ * Helper and Inner classes
+ */
+
+ /**
+ * A WebDav Folder
+ */
+ class WebDavFolder extends Folder {
+ private String mName;
+ private String mLocalUsername;
+ private String mFolderUrl;
+ private boolean mIsOpen = false;
+ private int mMessageCount = 0;
+ private int mUnreadMessageCount = 0;
+
+ public WebDavFolder(String name) {
+ String[] userParts;
+ String encodedName = new String();
+ try {
+ encodedName = java.net.URLEncoder.encode(name, "UTF-8");
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException URLEncoding folder name, skipping encoded");
+ encodedName = name;
+ }
+
+ encodedName = encodedName.replaceAll("\\+", "%20");
+ this.mName = name;
+ userParts = WebDavStore.this.mUsername.split("/", 2);
+
+ if (userParts.length > 1) {
+ this.mLocalUsername = userParts[1];
+ } else {
+ this.mLocalUsername = WebDavStore.this.mUsername;
+ }
+
+
+ this.mFolderUrl = WebDavStore.this.mUrl + "/Exchange/" + this.mLocalUsername + "/" + encodedName;
+ }
+
+ @Override
+ public void open(OpenMode mode) throws MessagingException {
+ if (needAuth()) {
+ authenticate();
+ }
+
+ if (WebDavStore.this.mAuthCookies == null) {
+ return;
+ }
+
+ this.mIsOpen = true;
+ }
+
+ private int getMessageCount(boolean read, CookieStore authCookies) {
+ String isRead;
+ int messageCount = 0;
+
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ HttpGeneric httpmethod;
+ HttpResponse response;
+ HttpEntity responseEntity;
+ StringEntity bodyEntity;
+ String messageBody;
+ int statusCode;
+
+ if (read) {
+ isRead = new String("True");
+ } else {
+ isRead = new String("False");
+ }
+
+ httpclient.setCookieStore(authCookies);
+
+ messageBody = getMessageCountXml(isRead);
+
+ try {
+ bodyEntity = new StringEntity(messageBody);
+ bodyEntity.setContentType("text/xml");
+
+ httpmethod = new HttpGeneric(this.mFolderUrl);
+ httpmethod.setMethod("SEARCH");
+ httpmethod.setEntity(bodyEntity);
+ httpmethod.setHeader("Brief", "t");
+
+ response = httpclient.execute(httpmethod);
+ statusCode = response.getStatusLine().getStatusCode();
+
+ if (statusCode < 200 ||
+ statusCode > 300) {
+ throw new IOException("Error getting message count, status code was " + statusCode);
+ }
+
+ responseEntity = response.getEntity();
+
+ if (responseEntity != null) {
+ try {
+ ParsedDataSet dataset = new ParsedDataSet();
+ InputStream istream = responseEntity.getContent();
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+
+ XMLReader xr = sp.getXMLReader();
+ WebDavHandler myHandler = new WebDavHandler();
+ xr.setContentHandler(myHandler);
+
+ xr.parse(new InputSource(istream));
+
+ dataset = myHandler.getDataSet();
+ messageCount = dataset.getMessageCount();
+
+ istream.close();
+ } catch (SAXException se) {
+ Log.e(k9.LOG_TAG, "SAXException in getMessageCount " + se);
+ } catch (ParserConfigurationException pce) {
+ Log.e(k9.LOG_TAG, "ParserConfigurationException in getMessageCount " + pce);
+ }
+ }
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException in getMessageCount() " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException in getMessageCount() " + ioe);
+ }
+ return messageCount;
+ }
+
+ @Override
+ public int getMessageCount() throws MessagingException {
+ open(OpenMode.READ_WRITE);
+ this.mMessageCount = getMessageCount(true, WebDavStore.this.mAuthCookies);
+
+ return this.mMessageCount;
+ }
+
+ @Override
+ public int getUnreadMessageCount() throws MessagingException {
+ open(OpenMode.READ_WRITE);
+ this.mUnreadMessageCount = getMessageCount(false, WebDavStore.this.mAuthCookies);
+
+ return this.mUnreadMessageCount;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return this.mIsOpen;
+ }
+
+ @Override
+ public OpenMode getMode() throws MessagingException {
+ return OpenMode.READ_WRITE;
+ }
+
+ @Override
+ public String getName() {
+ return this.mName;
+ }
+
+ @Override
+ public boolean exists() {
+ return true;
+ }
+
+ @Override
+ public void close(boolean expunge) throws MessagingException {
+ this.mMessageCount = 0;
+ this.mUnreadMessageCount = 0;
+
+ this.mIsOpen = false;
+ }
+
+ @Override
+ public boolean create(FolderType type) throws MessagingException {
+ return true;
+ }
+
+ @Override
+ public void delete(boolean recursive) throws MessagingException {
+ throw new Error("WebDavFolder.delete() not implemeneted");
+ }
+
+ @Override
+ public Message getMessage(String uid) throws MessagingException {
+ return new WebDavMessage(uid, this);
+ }
+
+ @Override
+ public Message[] getMessages(int start, int end, MessageRetrievalListener listener)
+ throws MessagingException {
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ ArrayList messages = new ArrayList();
+ String[] uids;
+
+ String messageBody;
+ int prevStart = start;
+
+ /** Reverse the message range since 0 index is newest */
+ start = this.mMessageCount - end;
+ end = this.mMessageCount - prevStart;
+
+ if (start < 0 || end < 0 || end < start) {
+ throw new MessagingException(String.format("Invalid message set %d %d", start, end));
+ }
+
+ /** Verify authentication */
+ if (needAuth()) {
+ authenticate();
+ }
+
+ if (WebDavStore.this.mAuthenticated == false ||
+ WebDavStore.this.mAuthCookies == null) {
+ return messages.toArray(new Message[] {});
+ }
+
+ /** Retrieve and parse the XML entity for our messages */
+ httpclient.setCookieStore(WebDavStore.this.mAuthCookies);
+ messageBody = getMessagesXml();
+
+ try {
+ int status_code = -1;
+ StringEntity messageEntity = new StringEntity(messageBody);
+ HttpGeneric httpmethod = new HttpGeneric(this.mFolderUrl);
+ HttpResponse response;
+ HttpEntity entity;
+
+ messageEntity.setContentType("text/xml");
+ httpmethod.setMethod("SEARCH");
+ httpmethod.setEntity(messageEntity);
+ httpmethod.setHeader("Brief", "t");
+ httpmethod.setHeader("Range", "rows=" + start + "-" + end);
+
+ response = httpclient.execute(httpmethod);
+ status_code = response.getStatusLine().getStatusCode();
+
+ if (status_code < 200 ||
+ status_code > 300) {
+ throw new IOException("Error getting messages, returned HTTP Response code " + status_code);
+ }
+
+ entity = response.getEntity();
+
+ if (entity != null) {
+ try {
+ InputStream istream = entity.getContent();
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+ XMLReader xr = sp.getXMLReader();
+ WebDavHandler myHandler = new WebDavHandler();
+ ParsedDataSet dataset;
+ int uidsLength = 0;
+ int urlsLength = 0;
+
+ xr.setContentHandler(myHandler);
+ xr.parse(new InputSource(istream));
+
+ dataset = myHandler.getDataSet();
+
+ uids = dataset.getUids();
+ HashMap uidToUrl = dataset.getUidToUrl();
+ uidsLength = uids.length;
+
+ for (int i = 0; i < uidsLength; i++) {
+ if (listener != null) {
+ listener.messageStarted(uids[i], i, uidsLength);
+ }
+ WebDavMessage message = new WebDavMessage(uids[i], this);
+ message.setUrl(uidToUrl.get(uids[i]));
+ messages.add(message);
+
+ if (listener != null) {
+ listener.messageFinished(message, i, uidsLength);
+ }
+ }
+ } catch (SAXException se) {
+ Log.e(k9.LOG_TAG, "SAXException in getMessages() " + se);
+ } catch (ParserConfigurationException pce) {
+ Log.e(k9.LOG_TAG, "ParserConfigurationException in getMessages() " + pce);
+ }
+ }
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException: " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException: " + ioe);
+ }
+
+ return messages.toArray(new Message[] {});
+ }
+
+ @Override
+ public Message[] getMessages(MessageRetrievalListener listener) throws MessagingException {
+ return getMessages(null, listener);
+ }
+
+ @Override
+ public Message[] getMessages(String[] uids, MessageRetrievalListener listener) throws MessagingException {
+ ArrayList messageList = new ArrayList();
+ Message[] messages;
+
+ if (uids == null) {
+ messages = getMessages(0, k9.DEFAULT_VISIBLE_LIMIT, listener);
+ } else {
+ for (int i = 0, count = uids.length; i < count; i++) {
+ if (listener != null) {
+ listener.messageStarted(uids[i], i, count);
+ }
+
+ WebDavMessage message = new WebDavMessage(uids[i], this);
+ messageList.add(message);
+
+ if (listener != null) {
+ listener.messageFinished(message, i, count);
+ }
+ }
+ messages = messageList.toArray(new Message[] {});
+ }
+
+ return messages;
+ }
+
+ private HashMap getMessageUrls(String[] uids) {
+ HashMap uidToUrl = new HashMap();
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ String messageBody;
+
+ /** Verify authentication */
+ if (needAuth()) {
+ authenticate();
+ }
+
+ if (WebDavStore.this.mAuthenticated == false ||
+ WebDavStore.this.mAuthCookies == null) {
+ return uidToUrl;
+ }
+
+ /** Retrieve and parse the XML entity for our messages */
+ httpclient.setCookieStore(WebDavStore.this.mAuthCookies);
+ messageBody = getMessageUrlsXml(uids);
+
+ try {
+ int status_code = -1;
+ StringEntity messageEntity = new StringEntity(messageBody);
+ HttpGeneric httpmethod = new HttpGeneric(this.mFolderUrl);
+ HttpResponse response;
+ HttpEntity entity;
+
+ messageEntity.setContentType("text/xml");
+ httpmethod.setMethod("SEARCH");
+ httpmethod.setEntity(messageEntity);
+ httpmethod.setHeader("Brief", "t");
+
+ response = httpclient.execute(httpmethod);
+ status_code = response.getStatusLine().getStatusCode();
+
+ if (status_code < 200 ||
+ status_code > 300) {
+ throw new IOException("Error getting messages, returned HTTP Response code " + status_code);
+ }
+
+ entity = response.getEntity();
+
+ if (entity != null) {
+ try {
+ InputStream istream = entity.getContent();
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+ XMLReader xr = sp.getXMLReader();
+ WebDavHandler myHandler = new WebDavHandler();
+ ParsedDataSet dataset;
+ int uidsLength = 0;
+ int urlsLength = 0;
+
+ xr.setContentHandler(myHandler);
+ xr.parse(new InputSource(istream));
+
+ dataset = myHandler.getDataSet();
+ uidToUrl = dataset.getUidToUrl();
+ } catch (SAXException se) {
+ Log.e(k9.LOG_TAG, "SAXException in getMessages() " + se);
+ } catch (ParserConfigurationException pce) {
+ Log.e(k9.LOG_TAG, "ParserConfigurationException in getMessages() " + pce);
+ }
+ }
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException: " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException: " + ioe);
+ }
+
+ return uidToUrl;
+ }
+
+ @Override
+ public void fetch(Message[] messages, FetchProfile fp, MessageRetrievalListener listener)
+ throws MessagingException {
+ HashMap uidToReadStatus = new HashMap();
+ HashMap envelopes = new HashMap();
+ if (messages == null ||
+ messages.length == 0) {
+ return;
+ }
+
+ /**
+ * Get message info for all messages here since it can be pulled with
+ * a single request. Header data will be set in the for loop.
+ * Listener isn't started yet since it isn't a per-message lookup.
+ */
+ if (fp.contains(FetchProfile.Item.ENVELOPE)) {
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ String messageBody = new String();
+ String[] uids = new String[messages.length];
+
+ for (int i = 0, count = messages.length; i < count; i++) {
+ uids[i] = messages[i].getUid();
+ }
+
+ httpclient.setCookieStore(WebDavStore.this.mAuthCookies);
+ messageBody = getMessageEnvelopeXml(uids);
+
+ try {
+ int status_code = -1;
+ StringEntity messageEntity = new StringEntity(messageBody);
+ HttpGeneric httpmethod = new HttpGeneric(this.mFolderUrl);
+ HttpResponse response;
+ HttpEntity entity;
+
+ messageEntity.setContentType("text/xml");
+ httpmethod.setMethod("SEARCH");
+ httpmethod.setEntity(messageEntity);
+ httpmethod.setHeader("Brief", "t");
+
+ response = httpclient.execute(httpmethod);
+ status_code = response.getStatusLine().getStatusCode();
+
+ if (status_code < 200 ||
+ status_code > 300) {
+ throw new IOException("Error getting message envelopes, returned HTTP Response code " + status_code);
+ }
+
+ entity = response.getEntity();
+
+ if (entity != null) {
+ try {
+ InputStream istream = entity.getContent();
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+ XMLReader xr = sp.getXMLReader();
+ WebDavHandler myHandler = new WebDavHandler();
+ ParsedDataSet dataset;
+
+ xr.setContentHandler(myHandler);
+ xr.parse(new InputSource(istream));
+
+ dataset = myHandler.getDataSet();
+ envelopes = dataset.getMessageEnvelopes();
+ } catch (SAXException se) {
+ Log.e(k9.LOG_TAG, "SAXException in fetch() " + se);
+ } catch (ParserConfigurationException pce) {
+ Log.e(k9.LOG_TAG, "ParserConfigurationException in fetch() " + pce);
+ }
+ }
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException: " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException: " + ioe);
+ }
+ }
+
+ /**
+ * Check for flags and get the status here since it can be pulled with
+ * just one request. Flags will be set inside the for loop.
+ * Listener isn't started yet since it isn't a per-message lookup.
+ */
+ if (fp.contains(FetchProfile.Item.FLAGS)) {
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ String messageBody = new String();
+ String[] uids = new String[messages.length];
+
+ for (int i = 0, count = messages.length; i < count; i++) {
+ uids[i] = messages[i].getUid();
+ }
+
+ httpclient.setCookieStore(WebDavStore.this.mAuthCookies);
+ messageBody = getMessageFlagsXml(uids);
+
+ try {
+ int status_code = -1;
+ StringEntity messageEntity = new StringEntity(messageBody);
+ HttpGeneric httpmethod = new HttpGeneric(this.mFolderUrl);
+ HttpResponse response;
+ HttpEntity entity;
+
+ messageEntity.setContentType("text/xml");
+ httpmethod.setMethod("SEARCH");
+ httpmethod.setEntity(messageEntity);
+ httpmethod.setHeader("Brief", "t");
+
+ response = httpclient.execute(httpmethod);
+ status_code = response.getStatusLine().getStatusCode();
+
+ if (status_code < 200 ||
+ status_code > 300) {
+ throw new IOException("Error getting message flags, returned HTTP Response code " + status_code);
+ }
+
+ entity = response.getEntity();
+
+ if (entity != null) {
+ try {
+ InputStream istream = entity.getContent();
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+ XMLReader xr = sp.getXMLReader();
+ WebDavHandler myHandler = new WebDavHandler();
+ ParsedDataSet dataset;
+
+ xr.setContentHandler(myHandler);
+ xr.parse(new InputSource(istream));
+
+ dataset = myHandler.getDataSet();
+ uidToReadStatus = dataset.getUidToRead();
+ } catch (SAXException se) {
+ Log.e(k9.LOG_TAG, "SAXException in fetch() " + se);
+ } catch (ParserConfigurationException pce) {
+ Log.e(k9.LOG_TAG, "ParserConfigurationException in fetch() " + pce);
+ }
+ }
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException: " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException: " + ioe);
+ }
+ }
+
+ for (int i = 0, count = messages.length; i < count; i++) {
+ if (!(messages[i] instanceof WebDavMessage)) {
+ throw new MessagingException("WebDavStore fetch called with non-WebDavMessage");
+ }
+ WebDavMessage wdMessage = (WebDavMessage) messages[i];
+
+ if (listener != null) {
+ listener.messageStarted(wdMessage.getUid(), i, count);
+ }
+
+ if (fp.contains(FetchProfile.Item.FLAGS)) {
+ wdMessage.setFlagInternal(Flag.SEEN, uidToReadStatus.get(wdMessage.getUid()));
+ }
+
+ if (fp.contains(FetchProfile.Item.ENVELOPE)) {
+ wdMessage.setNewHeaders(envelopes.get(wdMessage.getUid()));
+ }
+
+ /**
+ * Set the body to null if it's asking for the structure because
+ * we don't support it yet.
+ */
+ if (fp.contains(FetchProfile.Item.STRUCTURE)) {
+ wdMessage.setBody(null);
+ }
+
+ /**
+ * Message fetching that we can pull as a stream
+ */
+ if (fp.contains(FetchProfile.Item.BODY) ||
+ fp.contains(FetchProfile.Item.BODY_SANE)) {
+
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ InputStream istream = null;
+ InputStream resultStream = null;
+ HttpGet httpget;
+ HttpEntity entity;
+ HttpResponse response;
+ int statusCode = 0;
+
+ try {
+ httpclient.setCookieStore(WebDavStore.this.mAuthCookies);
+ httpget = new HttpGet(new URI(wdMessage.getUrl()));
+ httpget.setHeader("translate", "f");
+
+ response = httpclient.execute(httpget);
+ statusCode = response.getStatusLine().getStatusCode();
+
+ if (statusCode < 200 ||
+ statusCode > 300) {
+ throw new IOException("Status Code in invalid range");
+ }
+
+ entity = response.getEntity();
+ if (entity != null) {
+ String resultText = new String();
+ String tempText = new String();
+ BufferedReader reader;
+
+ resultText = "";
+ istream = entity.getContent();
+ /**
+ * Keep this commented out for now, messages won't display properly if
+ * we do it like this.
+ */
+ /**
+ if (fp.contains(FetchProfile.Item.BODY_SANE)) {
+ int lines = FETCH_BODY_SANE_SUGGESTED_SIZE / 76;
+ int line = 0;
+
+ reader = new BufferedReader(new InputStreamReader(istream),4096);
+
+ while ((tempText = reader.readLine()) != null &&
+ (line < lines)) {
+ if (resultText.equals("")) {
+ resultText = tempText;
+ } else {
+ resultText = resultText + "\r\n" + tempText;
+ }
+
+ line++;
+ }
+
+ istream.close();
+ istream = new ByteArrayInputStream(resultText.getBytes("UTF-8"));
+ }*/
+
+ wdMessage.parse(istream);
+ }
+
+ } catch (IllegalArgumentException iae) {
+ Log.e(k9.LOG_TAG, "IllegalArgumentException caught " + iae);
+ } catch (URISyntaxException use) {
+ Log.e(k9.LOG_TAG, "URISyntaxException caught " + use);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "Non-success response code loading message, response code was " + statusCode);
+ }
+ }
+
+ if (listener != null) {
+ listener.messageFinished(wdMessage, i, count);
+ }
+ }
+ }
+
+ @Override
+ public Flag[] getPermanentFlags() throws MessagingException {
+ return PERMANENT_FLAGS;
+ }
+
+ @Override
+ public void setFlags(Message[] messages, Flag[] flags, boolean value)
+ throws MessagingException {
+ String[] uids = new String[messages.length];
+
+ if (needAuth()) {
+ authenticate();
+ }
+
+ if (WebDavStore.this.mAuthenticated == false ||
+ WebDavStore.this.mAuthCookies == null) {
+ return;
+ }
+
+ for (int i = 0, count = messages.length; i < count; i++) {
+ uids[i] = messages[i].getUid();
+ }
+
+ for (int i = 0, count = flags.length; i < count; i++) {
+ Flag flag = flags[i];
+
+ if (flag == Flag.SEEN) {
+ markServerMessagesRead(uids);
+ } else if (flag == Flag.DELETED) {
+ deleteServerMessages(uids);
+ }
+ }
+ }
+
+ private void markServerMessagesRead(String[] uids) throws MessagingException {
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ String messageBody = new String();
+ HashMap uidToUrl = getMessageUrls(uids);
+ String[] urls = new String[uids.length];
+
+ for (int i = 0, count = uids.length; i < count; i++) {
+ urls[i] = uidToUrl.get(uids[i]);
+ }
+
+ httpclient.setCookieStore(WebDavStore.this.mAuthCookies);
+ messageBody = getMarkMessagesReadXml(urls);
+
+ try {
+ int status_code = -1;
+ StringEntity messageEntity = new StringEntity(messageBody);
+ HttpGeneric httpmethod = new HttpGeneric(this.mFolderUrl + "/");
+ HttpResponse response;
+ HttpEntity entity;
+
+ messageEntity.setContentType("text/xml");
+ httpmethod.setMethod("BPROPPATCH");
+ httpmethod.setEntity(messageEntity);
+ httpmethod.setHeader("Brief", "t");
+ httpmethod.setHeader("If-Match", "*");
+
+ response = httpclient.execute(httpmethod);
+ status_code = response.getStatusLine().getStatusCode();
+
+ if (status_code < 200 ||
+ status_code > 300) {
+ throw new IOException("Error marking messages as read, returned HTTP Response code " + status_code);
+ }
+
+ entity = response.getEntity();
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException: " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException: " + ioe);
+ }
+ }
+
+ private void deleteServerMessages(String[] uids) throws MessagingException {
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ HashMap uidToUrl = getMessageUrls(uids);
+ String[] urls = new String[uids.length];
+
+ httpclient.setCookieStore(WebDavStore.this.mAuthCookies);
+
+ for (int i = 0, count = uids.length; i < count; i++) {
+ try {
+ int status_code = -1;
+ HttpGeneric httpmethod = new HttpGeneric(uidToUrl.get(uids[i]));
+ HttpResponse response;
+ HttpEntity entity;
+
+ httpmethod.setMethod("DELETE");
+ httpmethod.setHeader("Brief", "t");
+
+ response = httpclient.execute(httpmethod);
+ status_code = response.getStatusLine().getStatusCode();
+
+ if (status_code < 200 ||
+ status_code > 300) {
+ throw new IOException("Error deleting message url: "+urls[i]+" \nResponse Code: "+status_code);
+ }
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException: " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException: " + ioe);
+ }
+ }
+ }
+
+ @Override
+ public void appendMessages(Message[] messages) throws MessagingException {
+ appendMessages(messages, false);
+ }
+
+ public void appendMessages(Message[] messages, boolean copy) throws MessagingException {
+
+ }
+
+ @Override
+ public void copyMessages(Message[] msgs, Folder folder) throws MessagingException {
+
+ }
+
+ @Override
+ public Message[] expunge() throws MessagingException {
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return false;
+ }
+ }
+
+ /**
+ * A WebDav Message
+ */
+ class WebDavMessage extends MimeMessage {
+ private String mUrl = null;
+
+ WebDavMessage(String uid, Folder folder) throws MessagingException {
+ this.mUid = uid;
+ this.mFolder = folder;
+ }
+
+ public void setUrl(String url) {
+ String[] urlParts = url.split("/");
+ int length = urlParts.length;
+ String end = urlParts[length - 1];
+
+ this.mUrl = new String();
+ url = new String();
+
+ /**
+ * We have to decode, then encode the URL because Exchange likes to
+ * not properly encode all characters
+ */
+ try {
+ end = java.net.URLDecoder.decode(end, "UTF-8");
+ end = java.net.URLEncoder.encode(end, "UTF-8");
+ end = end.replaceAll("\\+", "%20");
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException caught in setUrl");
+ } catch (IllegalArgumentException iae) {
+ Log.e(k9.LOG_TAG, "IllegalArgumentException caught in setUrl");
+ }
+
+ for (int i = 0; i < length - 1; i++) {
+ if (i != 0) {
+ url = url + "/" + urlParts[i];
+ } else {
+ url = urlParts[i];
+ }
+ }
+
+ url = url + "/" + end;
+
+ this.mUrl = url;
+ }
+
+ public String getUrl() {
+ return this.mUrl;
+ }
+
+ public void setSize(int size) {
+ this.mSize = size;
+ }
+
+ public void parse(InputStream in) throws IOException, MessagingException {
+ super.parse(in);
+ }
+
+ public void setFlagInternal(Flag flag, boolean set) throws MessagingException {
+ super.setFlag(flag, set);
+ }
+
+ public void setNewHeaders(ParsedMessageEnvelope envelope) throws MessagingException {
+ String[] headers = envelope.getHeaderList();
+ HashMap messageHeaders = envelope.getMessageHeaders();
+
+ for (int i = 0, count = headers.length; i < count; i++) {
+ if (headers[i].equals("Content-Length")) {
+ this.setSize(new Integer(messageHeaders.get(headers[i])).intValue());
+ }
+ this.addHeader(headers[i], messageHeaders.get(headers[i]));
+ }
+ }
+
+ @Override
+ public void setFlag(Flag flag, boolean set) throws MessagingException {
+ super.setFlag(flag, set);
+ mFolder.setFlags(new Message[] { this }, new Flag[] { flag }, set);
+ }
+ }
+
+ /**
+ * XML Parsing Handler
+ * Can handle all XML handling needs
+ */
+ public class WebDavHandler extends DefaultHandler {
+ private ParsedDataSet mDataSet = new ParsedDataSet();
+ private Stack mOpenTags = new Stack();
+
+ public ParsedDataSet getDataSet() {
+ return this.mDataSet;
+ }
+
+ @Override
+ public void startDocument() throws SAXException {
+ this.mDataSet = new ParsedDataSet();
+ }
+
+ @Override
+ public void endDocument() throws SAXException {
+ /* Do nothing */
+ }
+
+ @Override
+ public void startElement(String namespaceURI, String localName,
+ String qName, Attributes atts) throws SAXException {
+ mOpenTags.push(localName);
+ }
+
+ @Override
+ public void endElement(String namespaceURI, String localName, String qName) {
+ mOpenTags.pop();
+
+ /** Reset the hash temp variables */
+ if (localName.equals("response")) {
+ this.mDataSet.addEnvelope();
+ this.mDataSet.clearTempData();
+ }
+ }
+
+ @Override
+ public void characters(char ch[], int start, int length) {
+ String value = new String(ch, start, length);
+ mDataSet.addValue(value, mOpenTags.peek());
+ }
+ }
+
+ /**
+ * Data set for a single E-Mail message's required headers (the envelope)
+ * Only provides accessor methods to the stored data. All processing should be
+ * done elsewhere. This is done rather than having multiple hashmaps
+ * associating UIDs to values
+ */
+ public class ParsedMessageEnvelope {
+ private boolean mReadStatus = false;
+ private String mUid = new String();
+ private HashMap mMessageHeaders = new HashMap();
+ private ArrayList mHeaders = new ArrayList();
+
+ public void addHeader(String field, String value) {
+ this.mMessageHeaders.put(field, value);
+ this.mHeaders.add(field);
+ }
+
+ public HashMap getMessageHeaders() {
+ return this.mMessageHeaders;
+ }
+
+ public String[] getHeaderList() {
+ return this.mHeaders.toArray(new String[] {});
+ }
+
+ public void setReadStatus(boolean status) {
+ this.mReadStatus = status;
+ }
+
+ public boolean getReadStatus() {
+ return this.mReadStatus;
+ }
+
+ public void setUid(String uid) {
+ if (uid != null) {
+ this.mUid = uid;
+ }
+ }
+
+ public String getUid() {
+ return this.mUid;
+ }
+ }
+
+
+ /**
+ * Data set for handling all XML Parses
+ */
+ public class ParsedDataSet {
+ private ArrayList mHrefs = new ArrayList();
+ private ArrayList mUids = new ArrayList();
+ private ArrayList mReads = new ArrayList();
+ private HashMap mUidUrls = new HashMap();
+ private HashMap mUidRead = new HashMap();
+ private HashMap mEnvelopes = new HashMap();
+ private int mMessageCount = 0;
+ private String mTempUid = "";
+ private String mTempUrl = "";
+ private String mFrom = "";
+ private String mTo = "";
+ private String mCc = "";
+ private String mReceived = "";
+ private Boolean mTempRead;
+ private ParsedMessageEnvelope mEnvelope = new ParsedMessageEnvelope();
+ private boolean mRead;
+
+ public void addValue(String value, String tagName) {
+ if (tagName.equals("href")) {
+ this.mHrefs.add(value);
+ this.mTempUrl = value;
+ } else if (tagName.equals("visiblecount")) {
+ this.mMessageCount = new Integer(value).intValue();
+ } else if (tagName.equals("uid")) {
+ this.mUids.add(value);
+ this.mEnvelope.setUid(value);
+ this.mTempUid = value;
+ } else if (tagName.equals("read")) {
+ if (value.equals("0")) {
+ this.mReads.add(false);
+ this.mEnvelope.setReadStatus(false);
+ this.mTempRead = false;
+ } else {
+ this.mReads.add(true);
+ this.mEnvelope.setReadStatus(true);
+ this.mTempRead = true;
+ }
+ } else if (tagName.equals("received")) {
+ this.mReceived = this.mReceived + value;
+ } else if (tagName.equals("mime-version")) {
+ this.mEnvelope.addHeader("MIME-Version", value);
+ } else if (tagName.equals("content-type")) {
+ this.mEnvelope.addHeader("Content-Type", value);
+ } else if (tagName.equals("subject")) {
+ this.mEnvelope.addHeader("Subject", value);
+ } else if (tagName.equals("date")) {
+ value = value.replaceAll("T", " ");
+ String[] valueBreak = value.split("\\.");
+ value = valueBreak[0];
+
+ DateFormat dfInput = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ DateFormat dfOutput = new SimpleDateFormat("EEE, d MMM yy HH:mm:ss Z");
+ String tempDate = "";
+
+ try {
+ Date parsedDate = dfInput.parse(value);
+ tempDate = dfOutput.format(parsedDate);
+ } catch (java.text.ParseException pe) {
+ Log.e(k9.LOG_TAG, "Error parsing date: "+ pe);
+ }
+
+ this.mEnvelope.addHeader("Date", tempDate);
+ } else if (tagName.equals("thread-topic")) {
+ this.mEnvelope.addHeader("Thread-Topic", value);
+ } else if (tagName.equals("thread-index")) {
+ this.mEnvelope.addHeader("Thread-Index", value);
+ } else if (tagName.equals("from")) {
+ this.mFrom = this.mFrom + value;
+ } else if (tagName.equals("to")) {
+ this.mTo = this.mTo + value;
+ } else if (tagName.equals("in-reply-to")) {
+ this.mEnvelope.addHeader("In-Reply-To", value);
+ } else if (tagName.equals("return-path")) {
+ this.mEnvelope.addHeader("Return-Path", value);
+ } else if (tagName.equals("cc")) {
+ this.mCc = this.mCc + value;
+ } else if (tagName.equals("references")) {
+ this.mEnvelope.addHeader("References", value);
+ } else if (tagName.equals("getcontentlength")) {
+ this.mEnvelope.addHeader("Content-Length", value);
+ }
+
+
+ if (!this.mTempUid.equals("") &&
+ this.mTempRead != null) {
+ if (this.mTempRead) {
+ this.mUidRead.put(this.mTempUid, true);
+ } else {
+ this.mUidRead.put(this.mTempUid, false);
+ }
+ }
+
+ if (!this.mTempUid.equals("") &&
+ !this.mTempUrl.equals("")) {
+ this.mUidUrls.put(this.mTempUid, this.mTempUrl);
+ }
+ }
+
+ /**
+ * Clears the temp variables
+ */
+ public void clearTempData() {
+ this.mTempUid = "";
+ this.mTempUrl = "";
+ this.mFrom = "";
+ this.mEnvelope = new ParsedMessageEnvelope();
+ }
+
+ public void addEnvelope() {
+ this.mEnvelope.addHeader("From", this.mFrom);
+ this.mEnvelope.addHeader("To", this.mTo);
+ this.mEnvelope.addHeader("Cc", this.mCc);
+ this.mEnvelope.addHeader("Received", this.mReceived);
+ this.mEnvelopes.put(this.mEnvelope.getUid(), this.mEnvelope);
+ }
+
+ /**
+ * Returns an array of the set of message envelope objects
+ */
+ public HashMap getMessageEnvelopes() {
+ return this.mEnvelopes;
+ }
+
+ /**
+ * Returns the Uid to Url hashmap
+ */
+ public HashMap getUidToUrl() {
+ return this.mUidUrls;
+ }
+
+ /**
+ * Returns the Uid to Read hashmap
+ */
+ public HashMap getUidToRead() {
+ return this.mUidRead;
+ }
+
+ /**
+ * Get all stored Hrefs
+ */
+ public String[] getHrefs() {
+ return this.mHrefs.toArray(new String[] {});
+ }
+
+ /**
+ * Get the first stored Href
+ */
+ public String getHref() {
+ String[] hrefs = this.mHrefs.toArray(new String[] {});
+ return hrefs[0];
+ }
+
+ /**
+ * Get all stored Uids
+ */
+ public String[] getUids() {
+ return this.mUids.toArray(new String[] {});
+ }
+
+ /**
+ * Get the first stored Uid
+ */
+ public String getUid() {
+ String[] uids = this.mUids.toArray(new String[] {});
+ return uids[0];
+ }
+
+ /**
+ * Get message count
+ */
+ public int getMessageCount() {
+ return this.mMessageCount;
+ }
+
+ /**
+ * Get all stored read statuses
+ */
+ public Boolean[] getReadArray() {
+ Boolean[] readStatus = this.mReads.toArray(new Boolean[] {});
+ return readStatus;
+ }
+
+ /**
+ * Get the first stored read status
+ */
+ public boolean getRead() {
+ return this.mRead;
+ }
+ }
+
+ /**
+ * New HTTP Method that allows changing of the method and generic handling
+ * Needed for WebDAV custom methods such as SEARCH and PROPFIND
+ */
+ public class HttpGeneric extends HttpEntityEnclosingRequestBase {
+ public String METHOD_NAME = "POST";
+
+ public HttpGeneric() {
+ super();
+ }
+
+ public HttpGeneric(final URI uri) {
+ super();
+ setURI(uri);
+ }
+
+ /**
+ * @throws IllegalArgumentException if the uri is invalid.
+ */
+ public HttpGeneric(final String uri) {
+ super();
+
+ String[] urlParts = uri.split("/");
+ int length = urlParts.length;
+ String end = urlParts[length - 1];
+ String url = new String();
+
+ /**
+ * We have to decode, then encode the URL because Exchange likes to
+ * not properly encode all characters
+ */
+ try {
+ end = java.net.URLDecoder.decode(end, "UTF-8");
+ end = java.net.URLEncoder.encode(end, "UTF-8");
+ end = end.replaceAll("\\+", "%20");
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException caught in HttpGeneric(String uri)");
+ } catch (IllegalArgumentException iae) {
+ Log.e(k9.LOG_TAG, "IllegalArgumentException caught in HttpGeneric(String uri)");
+ }
+
+ for (int i = 0; i < length - 1; i++) {
+ if (i != 0) {
+ url = url + "/" + urlParts[i];
+ } else {
+ url = urlParts[i];
+ }
+ }
+
+ url = url + "/" + end;
+
+ setURI(URI.create(url));
+ }
+
+ @Override
+ public String getMethod() {
+ return METHOD_NAME;
+ }
+
+ public void setMethod(String method) {
+ if (method != null) {
+ METHOD_NAME = method;
+ }
+ }
+ }
+}
diff --git a/src/com/fsck/k9/mail/transport/WebDavTransport.java b/src/com/fsck/k9/mail/transport/WebDavTransport.java
new file mode 100644
index 000000000..292fc101d
--- /dev/null
+++ b/src/com/fsck/k9/mail/transport/WebDavTransport.java
@@ -0,0 +1,189 @@
+
+package com.fsck.k9.mail.transport;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.SSLException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.CookieStore;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+import android.util.Config;
+import android.util.Log;
+
+import com.fsck.k9.k9;
+import com.fsck.k9.PeekableInputStream;
+import com.fsck.k9.codec.binary.Base64;
+import com.fsck.k9.mail.Address;
+import com.fsck.k9.mail.AuthenticationFailedException;
+import com.fsck.k9.mail.Folder;
+import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.Transport;
+import com.fsck.k9.mail.CertificateValidationException;
+import com.fsck.k9.mail.Message.RecipientType;
+import com.fsck.k9.mail.store.TrustManagerFactory;
+import com.fsck.k9.mail.store.WebDavStore;
+import com.fsck.k9.mail.store.WebDavStore.HttpGeneric;
+import com.fsck.k9.mail.store.WebDavStore.ParsedDataSet;
+import com.fsck.k9.mail.store.WebDavStore.WebDavHandler;
+
+public class WebDavTransport extends Transport {
+ public static final int CONNECTION_SECURITY_NONE = 0;
+ public static final int CONNECTION_SECURITY_TLS_OPTIONAL = 1;
+ public static final int CONNECTION_SECURITY_TLS_REQUIRED = 2;
+ public static final int CONNECTION_SECURITY_SSL_REQUIRED = 3;
+ public static final int CONNECTION_SECURITY_SSL_OPTIONAL = 4;
+
+ String host;
+ int mPort;
+ private int mConnectionSecurity;
+ private String mUsername; /* Stores the username for authentications */
+ private String mPassword; /* Stores the password for authentications */
+ private String mUrl; /* Stores the base URL for the server */
+
+ boolean mSecure;
+ Socket mSocket;
+ PeekableInputStream mIn;
+ OutputStream mOut;
+ private WebDavStore store;
+
+ /**
+ * webdav://user:password@server:port CONNECTION_SECURITY_NONE
+ * webdav+tls://user:password@server:port CONNECTION_SECURITY_TLS_OPTIONAL
+ * webdav+tls+://user:password@server:port CONNECTION_SECURITY_TLS_REQUIRED
+ * webdav+ssl+://user:password@server:port CONNECTION_SECURITY_SSL_REQUIRED
+ * webdav+ssl://user:password@server:port CONNECTION_SECURITY_SSL_OPTIONAL
+ *
+ * @param _uri
+ */
+ public WebDavTransport(String _uri) throws MessagingException {
+ store = new WebDavStore(_uri);
+ Log.d(k9.LOG_TAG, ">>> New WebDavTransport creation complete");
+ }
+
+ public void open() throws MessagingException {
+ Log.d(k9.LOG_TAG, ">>> open called on WebDavTransport ");
+ if (store.needAuth()) {
+ store.authenticate();
+ }
+
+ if (store.getAuthCookies() == null) {
+ return;
+ }
+ }
+
+// public void sendMessage(Message message) throws MessagingException {
+// Address[] from = message.getFrom();
+//
+// }
+
+ public void close() {
+ }
+
+ public String generateTempURI(String subject) {
+ String encodedSubject = URLEncoder.encode(subject);
+ return store.getUrl() + "/Exchange/" + store.getAlias() + "/drafts/" + encodedSubject + ".eml";
+ }
+ public String generateSendURI() {
+ return store.getUrl() + "/Exchange/" + store.getAlias() + "/##DavMailSubmissionURI##/";
+ }
+
+ public void sendMessage(Message message) throws MessagingException {
+ Log.d(k9.LOG_TAG, ">>> sendMessage called.");
+
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ HttpGeneric httpmethod;
+ HttpResponse response;
+ HttpEntity responseEntity;
+ StringEntity bodyEntity;
+ int statusCode;
+ String subject;
+ ByteArrayOutputStream out;
+ try {
+ try {
+ subject = message.getSubject();
+ } catch (MessagingException e) {
+ Log.e(k9.LOG_TAG, "MessagingException while retrieving Subject: " + e);
+ subject = "";
+ }
+ try {
+ out = new ByteArrayOutputStream(message.getSize());
+ } catch (MessagingException e) {
+ Log.e(k9.LOG_TAG, "MessagingException while getting size of message: " + e);
+ out = new ByteArrayOutputStream();
+ }
+ open();
+ message.writeTo(
+ new EOLConvertingOutputStream(
+ new BufferedOutputStream(out, 1024)));
+ httpclient.setCookieStore(store.getAuthCookies());
+
+ bodyEntity = new StringEntity(out.toString(), "UTF-8");
+ bodyEntity.setContentType("message/rfc822");
+
+ httpmethod = store.new HttpGeneric(generateTempURI(subject));
+ httpmethod.setMethod("PUT");
+ httpmethod.setEntity(bodyEntity);
+
+ response = httpclient.execute(httpmethod);
+ statusCode = response.getStatusLine().getStatusCode();
+
+ if (statusCode < 200 ||
+ statusCode > 300) {
+ throw new IOException("Error sending message, status code was " + statusCode);
+ }
+
+ //responseEntity = response.getEntity();
+ //DefaultHttpClient movehttpclient = new DefaultHttpClient();
+ //HttpGeneric movehttpmethod;
+ //HttpResponse moveresponse;
+ //HttpEntity moveresponseEntity;
+ httpmethod = store.new HttpGeneric(generateTempURI(subject));
+ httpmethod.setMethod("MOVE");
+ httpmethod.setHeader("Destination", generateSendURI());
+
+ response = httpclient.execute(httpmethod);
+ statusCode = response.getStatusLine().getStatusCode();
+
+ if (statusCode < 200 ||
+ statusCode > 300) {
+ throw new IOException("Error sending message, status code was " + statusCode);
+ }
+
+ } catch (UnsupportedEncodingException uee) {
+ Log.e(k9.LOG_TAG, "UnsupportedEncodingException in getMessageCount() " + uee);
+ } catch (IOException ioe) {
+ Log.e(k9.LOG_TAG, "IOException in getMessageCount() " + ioe);
+ throw new MessagingException("Unable to send message", ioe);
+ }
+ Log.d(k9.LOG_TAG, ">>> getMessageCount finished");
+ }
+
+}