aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/e-mail-autoconfig.c388
-rw-r--r--mail/e-mail-autoconfig.h3
-rw-r--r--mail/test-mail-autoconfig.c2
3 files changed, 224 insertions, 169 deletions
diff --git a/mail/e-mail-autoconfig.c b/mail/e-mail-autoconfig.c
index aeebb0fa22..a9e9773050 100644
--- a/mail/e-mail-autoconfig.c
+++ b/mail/e-mail-autoconfig.c
@@ -35,23 +35,29 @@
#define ERROR_IS_NOT_FOUND(error) \
(g_error_matches ((error), SOUP_HTTP_ERROR, SOUP_STATUS_NOT_FOUND))
+typedef struct _EMailAutoconfigResult EMailAutoconfigResult;
typedef struct _ParserClosure ParserClosure;
+struct _EMailAutoconfigResult {
+ gboolean set;
+ gchar *user;
+ gchar *host;
+ guint16 port;
+ CamelNetworkSecurityMethod security_method;
+};
+
struct _EMailAutoconfigPrivate {
gchar *email_address;
gchar *email_local_part;
gchar *email_domain_part;
- gchar *markup_content;
+ EMailAutoconfigResult imap_result;
+ EMailAutoconfigResult pop3_result;
+ EMailAutoconfigResult smtp_result;
};
struct _ParserClosure {
- CamelNetworkSettings *network_settings;
- const gchar *expected_type;
- const gchar *email_address;
- const gchar *email_local_part;
- const gchar *email_domain_part;
- gboolean in_server_element;
- gboolean settings_modified;
+ EMailAutoconfig *autoconfig;
+ EMailAutoconfigResult *result;
};
enum {
@@ -73,90 +79,6 @@ G_DEFINE_TYPE_WITH_CODE (
G_IMPLEMENT_INTERFACE (
G_TYPE_ASYNC_INITABLE, NULL))
-static gchar *
-mail_autoconfig_resolve_name_server (const gchar *domain,
- GCancellable *cancellable,
- GError **error)
-{
- GResolver *resolver;
- GList *records;
- gchar *name_server = NULL;
-
- resolver = g_resolver_get_default ();
-
- records = g_resolver_lookup_records (
- resolver, domain, G_RESOLVER_RECORD_NS, cancellable, error);
-
- /* This list is sorted per RFC 2782, so use the first item. */
- if (records != NULL) {
- GVariant *variant = records->data;
- g_variant_get_child (variant, 0, "s", &name_server);
- }
-
- g_list_free_full (records, (GDestroyNotify) g_variant_unref);
-
- g_object_unref (resolver);
-
- return name_server;
-}
-
-static void
-mail_autoconfig_abort_soup_session_cb (GCancellable *cancellable,
- SoupSession *soup_session)
-{
- soup_session_abort (soup_session);
-}
-
-static gboolean
-mail_autoconfig_lookup (EMailAutoconfig *autoconfig,
- const gchar *domain,
- GCancellable *cancellable,
- GError **error)
-{
- SoupMessage *soup_message;
- SoupSession *soup_session;
- gulong cancel_id = 0;
- guint status;
- gchar *uri;
-
- soup_session = soup_session_sync_new ();
-
- uri = g_strconcat (AUTOCONFIG_BASE_URI, domain, NULL);
- soup_message = soup_message_new (SOUP_METHOD_GET, uri);
- g_free (uri);
-
- if (G_IS_CANCELLABLE (cancellable))
- cancel_id = g_cancellable_connect (
- cancellable,
- G_CALLBACK (mail_autoconfig_abort_soup_session_cb),
- g_object_ref (soup_session),
- (GDestroyNotify) g_object_unref);
-
- status = soup_session_send_message (soup_session, soup_message);
-
- if (cancel_id > 0)
- g_cancellable_disconnect (cancellable, cancel_id);
-
- if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
-
- /* Just to make sure we don't leak. */
- g_free (autoconfig->priv->markup_content);
-
- autoconfig->priv->markup_content =
- g_strdup (soup_message->response_body->data);
- } else {
- g_set_error_literal (
- error, SOUP_HTTP_ERROR,
- soup_message->status_code,
- soup_message->reason_phrase);
- }
-
- g_object_unref (soup_message);
- g_object_unref (soup_session);
-
- return SOUP_STATUS_IS_SUCCESSFUL (status);
-}
-
static void
mail_autoconfig_parse_start_element (GMarkupParseContext *context,
const gchar *element_name,
@@ -166,9 +88,12 @@ mail_autoconfig_parse_start_element (GMarkupParseContext *context,
GError **error)
{
ParserClosure *closure = user_data;
+ EMailAutoconfigPrivate *priv;
gboolean is_incoming_server;
gboolean is_outgoing_server;
+ priv = closure->autoconfig->priv;
+
is_incoming_server = g_str_equal (element_name, "incomingServer");
is_outgoing_server = g_str_equal (element_name, "outgoingServer");
@@ -184,8 +109,12 @@ mail_autoconfig_parse_start_element (GMarkupParseContext *context,
"type", &type,
G_MARKUP_COLLECT_INVALID);
- closure->in_server_element =
- (g_strcmp0 (type, closure->expected_type) == 0);
+ if (g_strcmp0 (type, "imap") == 0)
+ closure->result = &priv->imap_result;
+ if (g_strcmp0 (type, "pop3") == 0)
+ closure->result = &priv->pop3_result;
+ if (g_strcmp0 (type, "smtp") == 0)
+ closure->result = &priv->smtp_result;
}
}
@@ -203,7 +132,7 @@ mail_autoconfig_parse_end_element (GMarkupParseContext *context,
is_outgoing_server = g_str_equal (element_name, "outgoingServer");
if (is_incoming_server || is_outgoing_server)
- closure->in_server_element = FALSE;
+ closure->result = NULL;
}
static void
@@ -214,10 +143,13 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
GError **error)
{
ParserClosure *closure = user_data;
+ EMailAutoconfigPrivate *priv;
const gchar *element_name;
GString *string;
- if (!closure->in_server_element)
+ priv = closure->autoconfig->priv;
+
+ if (closure->result == NULL)
return;
/* Perform the following text substitutions:
@@ -242,7 +174,7 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
}
variable = "%EMAILADDRESS%";
- substitute = closure->email_address;
+ substitute = priv->email_address;
if (strncmp (cp, variable, strlen (variable)) == 0) {
g_string_append (string, substitute);
@@ -251,7 +183,7 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
}
variable = "%EMAILLOCALPART%";
- substitute = closure->email_local_part;
+ substitute = priv->email_local_part;
if (strncmp (cp, variable, strlen (variable)) == 0) {
g_string_append (string, substitute);
@@ -260,7 +192,7 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
}
variable = "%EMAILDOMAIN%";
- substitute = closure->email_domain_part;
+ substitute = priv->email_domain_part;
if (strncmp (cp, variable, strlen (variable)) == 0) {
g_string_append (string, substitute);
@@ -275,39 +207,33 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
element_name = g_markup_parse_context_get_element (context);
if (g_str_equal (element_name, "hostname")) {
- camel_network_settings_set_host (
- closure->network_settings, string->str);
- closure->settings_modified = TRUE;
+ closure->result->host = g_strdup (string->str);
+ closure->result->set = TRUE;
} else if (g_str_equal (element_name, "username")) {
- camel_network_settings_set_user (
- closure->network_settings, string->str);
- closure->settings_modified = TRUE;
+ closure->result->user = g_strdup (string->str);
+ closure->result->set = TRUE;
} else if (g_str_equal (element_name, "port")) {
glong port = strtol (string->str, NULL, 10);
if (port == CLAMP (port, 1, G_MAXUINT16)) {
- camel_network_settings_set_port (
- closure->network_settings, (guint16) port);
- closure->settings_modified = TRUE;
+ closure->result->port = (guint16) port;
+ closure->result->set = TRUE;
}
} else if (g_str_equal (element_name, "socketType")) {
if (g_str_equal (string->str, "plain")) {
- camel_network_settings_set_security_method (
- closure->network_settings,
- CAMEL_NETWORK_SECURITY_METHOD_NONE);
- closure->settings_modified = TRUE;
+ closure->result->security_method =
+ CAMEL_NETWORK_SECURITY_METHOD_NONE;
+ closure->result->set = TRUE;
} else if (g_str_equal (string->str, "SSL")) {
- camel_network_settings_set_security_method (
- closure->network_settings,
- CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT);
- closure->settings_modified = TRUE;
+ closure->result->security_method =
+ CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
+ closure->result->set = TRUE;
} else if (g_str_equal (string->str, "STARTTLS")) {
- camel_network_settings_set_security_method (
- closure->network_settings,
- CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT);
- closure->settings_modified = TRUE;
+ closure->result->security_method =
+ CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
+ closure->result->set = TRUE;
}
}
@@ -323,20 +249,123 @@ static GMarkupParser mail_autoconfig_parser = {
mail_autoconfig_parse_text
};
+static gchar *
+mail_autoconfig_resolve_name_server (const gchar *domain,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GResolver *resolver;
+ GList *records;
+ gchar *name_server = NULL;
+
+ resolver = g_resolver_get_default ();
+
+ records = g_resolver_lookup_records (
+ resolver, domain, G_RESOLVER_RECORD_NS, cancellable, error);
+
+ /* This list is sorted per RFC 2782, so use the first item. */
+ if (records != NULL) {
+ GVariant *variant = records->data;
+ g_variant_get_child (variant, 0, "s", &name_server);
+ }
+
+ g_list_free_full (records, (GDestroyNotify) g_variant_unref);
+
+ g_object_unref (resolver);
+
+ return name_server;
+}
+
+static void
+mail_autoconfig_abort_soup_session_cb (GCancellable *cancellable,
+ SoupSession *soup_session)
+{
+ soup_session_abort (soup_session);
+}
+
+static gboolean
+mail_autoconfig_lookup (EMailAutoconfig *autoconfig,
+ const gchar *domain,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GMarkupParseContext *context;
+ SoupMessage *soup_message;
+ SoupSession *soup_session;
+ ParserClosure closure;
+ gulong cancel_id = 0;
+ gboolean success;
+ guint status;
+ gchar *uri;
+
+ soup_session = soup_session_sync_new ();
+
+ uri = g_strconcat (AUTOCONFIG_BASE_URI, domain, NULL);
+ soup_message = soup_message_new (SOUP_METHOD_GET, uri);
+ g_free (uri);
+
+ if (G_IS_CANCELLABLE (cancellable))
+ cancel_id = g_cancellable_connect (
+ cancellable,
+ G_CALLBACK (mail_autoconfig_abort_soup_session_cb),
+ g_object_ref (soup_session),
+ (GDestroyNotify) g_object_unref);
+
+ status = soup_session_send_message (soup_session, soup_message);
+
+ if (cancel_id > 0)
+ g_cancellable_disconnect (cancellable, cancel_id);
+
+ success = SOUP_STATUS_IS_SUCCESSFUL (status);
+
+ if (!success) {
+ g_set_error_literal (
+ error, SOUP_HTTP_ERROR,
+ soup_message->status_code,
+ soup_message->reason_phrase);
+ goto exit;
+ }
+
+ closure.autoconfig = autoconfig;
+ closure.result = NULL;
+
+ context = g_markup_parse_context_new (
+ &mail_autoconfig_parser, 0,
+ &closure, (GDestroyNotify) NULL);
+
+ success = g_markup_parse_context_parse (
+ context,
+ soup_message->response_body->data,
+ soup_message->response_body->length,
+ error);
+
+ if (success)
+ success = g_markup_parse_context_end_parse (context, error);
+
+ g_markup_parse_context_free (context);
+
+exit:
+ g_object_unref (soup_message);
+ g_object_unref (soup_session);
+
+ return success;
+}
+
static gboolean
mail_autoconfig_set_details (EMailAutoconfig *autoconfig,
- const gchar *expected_type,
+ EMailAutoconfigResult *result,
ESource *source,
const gchar *extension_name)
{
- GMarkupParseContext *context;
ESourceCamel *camel_ext;
ESourceBackend *backend_ext;
CamelSettings *settings;
- ParserClosure closure;
const gchar *backend_name;
- const gchar *markup_content;
- gboolean success;
+
+ g_return_val_if_fail (result != NULL, FALSE);
+
+ if (!result->set)
+ return FALSE;
if (!e_source_has_extension (source, extension_name))
return FALSE;
@@ -349,33 +378,15 @@ mail_autoconfig_set_details (EMailAutoconfig *autoconfig,
settings = e_source_camel_get_settings (camel_ext);
g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), FALSE);
- markup_content = e_mail_autoconfig_get_markup_content (autoconfig);
- g_return_val_if_fail (markup_content != NULL, FALSE);
-
- closure.network_settings = CAMEL_NETWORK_SETTINGS (settings);
- closure.expected_type = expected_type;
- closure.in_server_element = FALSE;
- closure.settings_modified = FALSE;
-
- /* These are used for text substitutions. */
- closure.email_address = autoconfig->priv->email_address;
- closure.email_local_part = autoconfig->priv->email_local_part;
- closure.email_domain_part = autoconfig->priv->email_domain_part;
-
- context = g_markup_parse_context_new (
- &mail_autoconfig_parser, 0, &closure, (GDestroyNotify) NULL);
-
- success = g_markup_parse_context_parse (
- context, markup_content, strlen (markup_content), NULL);
-
- success &= g_markup_parse_context_end_parse (context, NULL);
-
- /* Did we actually configure anything? */
- success &= closure.settings_modified;
-
- g_markup_parse_context_free (context);
+ g_object_set (
+ settings,
+ "user", result->user,
+ "host", result->host,
+ "port", result->port,
+ "security-method", result->security_method,
+ NULL);
- return success;
+ return TRUE;
}
static void
@@ -433,7 +444,13 @@ mail_autoconfig_finalize (GObject *object)
g_free (priv->email_address);
g_free (priv->email_local_part);
g_free (priv->email_domain_part);
- g_free (priv->markup_content);
+
+ g_free (priv->imap_result.user);
+ g_free (priv->imap_result.host);
+ g_free (priv->pop3_result.user);
+ g_free (priv->pop3_result.host);
+ g_free (priv->smtp_result.user);
+ g_free (priv->smtp_result.host);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_mail_autoconfig_parent_class)->finalize (object);
@@ -634,14 +651,6 @@ e_mail_autoconfig_get_email_address (EMailAutoconfig *autoconfig)
return autoconfig->priv->email_address;
}
-const gchar *
-e_mail_autoconfig_get_markup_content (EMailAutoconfig *autoconfig)
-{
- g_return_val_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig), NULL);
-
- return autoconfig->priv->markup_content;
-}
-
gboolean
e_mail_autoconfig_set_imap_details (EMailAutoconfig *autoconfig,
ESource *imap_source)
@@ -650,8 +659,8 @@ e_mail_autoconfig_set_imap_details (EMailAutoconfig *autoconfig,
g_return_val_if_fail (E_IS_SOURCE (imap_source), FALSE);
return mail_autoconfig_set_details (
- autoconfig, "imap", imap_source,
- E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+ autoconfig, &autoconfig->priv->imap_result,
+ imap_source, E_SOURCE_EXTENSION_MAIL_ACCOUNT);
}
gboolean
@@ -662,8 +671,8 @@ e_mail_autoconfig_set_pop3_details (EMailAutoconfig *autoconfig,
g_return_val_if_fail (E_IS_SOURCE (pop3_source), FALSE);
return mail_autoconfig_set_details (
- autoconfig, "pop3", pop3_source,
- E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+ autoconfig, &autoconfig->priv->pop3_result,
+ pop3_source, E_SOURCE_EXTENSION_MAIL_ACCOUNT);
}
gboolean
@@ -674,7 +683,54 @@ e_mail_autoconfig_set_smtp_details (EMailAutoconfig *autoconfig,
g_return_val_if_fail (E_IS_SOURCE (smtp_source), FALSE);
return mail_autoconfig_set_details (
- autoconfig, "smtp", smtp_source,
- E_SOURCE_EXTENSION_MAIL_TRANSPORT);
+ autoconfig, &autoconfig->priv->smtp_result,
+ smtp_source, E_SOURCE_EXTENSION_MAIL_TRANSPORT);
+}
+
+void
+e_mail_autoconfig_dump_results (EMailAutoconfig *autoconfig)
+{
+ const gchar *email_address;
+ gboolean have_results;
+
+ g_return_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig));
+
+ email_address = autoconfig->priv->email_address;
+
+ have_results =
+ autoconfig->priv->imap_result.set ||
+ autoconfig->priv->pop3_result.set ||
+ autoconfig->priv->smtp_result.set;
+
+ if (have_results) {
+ g_print ("Results for <%s>\n", email_address);
+
+ if (autoconfig->priv->imap_result.set) {
+ g_print (
+ "IMAP: %s@%s:%u\n",
+ autoconfig->priv->imap_result.user,
+ autoconfig->priv->imap_result.host,
+ autoconfig->priv->imap_result.port);
+ }
+
+ if (autoconfig->priv->pop3_result.set) {
+ g_print (
+ "POP3: %s@%s:%u\n",
+ autoconfig->priv->pop3_result.user,
+ autoconfig->priv->pop3_result.host,
+ autoconfig->priv->pop3_result.port);
+ }
+
+ if (autoconfig->priv->smtp_result.set) {
+ g_print (
+ "SMTP: %s@%s:%u\n",
+ autoconfig->priv->smtp_result.user,
+ autoconfig->priv->smtp_result.host,
+ autoconfig->priv->smtp_result.port);
+ }
+
+ } else {
+ g_print ("No results for <%s>\n", email_address);
+ }
}
diff --git a/mail/e-mail-autoconfig.h b/mail/e-mail-autoconfig.h
index b0cfb93b13..c59897c8b0 100644
--- a/mail/e-mail-autoconfig.h
+++ b/mail/e-mail-autoconfig.h
@@ -70,8 +70,6 @@ EMailAutoconfig *
GError **error);
const gchar * e_mail_autoconfig_get_email_address
(EMailAutoconfig *autoconfig);
-const gchar * e_mail_autoconfig_get_markup_content
- (EMailAutoconfig *autoconfig);
gboolean e_mail_autoconfig_set_imap_details
(EMailAutoconfig *autoconfig,
ESource *imap_source);
@@ -81,6 +79,7 @@ gboolean e_mail_autoconfig_set_pop3_details
gboolean e_mail_autoconfig_set_smtp_details
(EMailAutoconfig *autoconfig,
ESource *smtp_source);
+void e_mail_autoconfig_dump_results (EMailAutoconfig *autoconfig);
G_END_DECLS
diff --git a/mail/test-mail-autoconfig.c b/mail/test-mail-autoconfig.c
index 10977a17b2..2ce8cb600a 100644
--- a/mail/test-mail-autoconfig.c
+++ b/mail/test-mail-autoconfig.c
@@ -45,7 +45,7 @@ main (gint argc,
g_assert (E_IS_MAIL_AUTOCONFIG (autoconfig));
- g_print ("%s\n", e_mail_autoconfig_get_markup_content (autoconfig));
+ e_mail_autoconfig_dump_results (autoconfig);
g_object_unref (autoconfig);