aboutsummaryrefslogtreecommitdiffstats
path: root/mail/mail-guess-servers.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/mail-guess-servers.c')
-rw-r--r--mail/mail-guess-servers.c370
1 files changed, 370 insertions, 0 deletions
diff --git a/mail/mail-guess-servers.c b/mail/mail-guess-servers.c
new file mode 100644
index 0000000000..8ab9670e8c
--- /dev/null
+++ b/mail/mail-guess-servers.c
@@ -0,0 +1,370 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Srinivasa Ragavan <srini@linux.intel.com>
+ *
+ * Copyright (C) 2009 Intel Corporation (www.intel.com)
+ *
+ */
+
+/* Template of the code is taken from libsoup tests/ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <libsoup/soup.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+
+#include <libedataserver/e-proxy.h>
+
+#include <shell/e-shell.h>
+#include <e-util/e-util-private.h>
+
+#include "mail-guess-servers.h"
+
+static gchar *
+xml_to_gchar (xmlChar *xml,
+ EmailProvider *provider)
+{
+ gchar *gxml = NULL;
+ gchar *tmp;
+ gchar *repl = NULL;
+ const gchar *sec_part;
+
+ tmp = xml ? strstr((gchar *) xml, "\%EMAIL") : NULL;
+
+ if (!tmp) {
+ gxml = xml ? g_strdup ((gchar *) xml) : NULL;
+ } else {
+ decodepart:
+ *tmp = 0;
+ tmp+=6;
+ if (*tmp == 'A')
+ repl = provider->email;
+ else if (*tmp == 'L')
+ repl = provider->username;
+ else if (*tmp == 'D')
+ repl = provider->domain;
+ sec_part = strstr(tmp, "\%");
+ sec_part++;
+ if (!*sec_part)
+ sec_part = "";
+
+ gxml = g_strdup_printf("%s%s%s", gxml ? gxml : (gchar *)xml, repl, sec_part);
+ tmp = strstr (gxml, "\%EMAIL");
+ if (tmp) {
+ goto decodepart;
+ }
+ }
+
+ xmlFree (xml);
+
+ return gxml;
+}
+
+static SoupMessage *
+get_url (SoupSession *session,
+ const gchar *url)
+{
+ SoupMessage *msg;
+ const gchar *header;
+
+ msg = soup_message_new (SOUP_METHOD_GET, url);
+ soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
+
+ soup_session_send_message (session, msg);
+
+ if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
+ header = soup_message_headers_get_one (msg->response_headers,
+ "Location");
+ if (header) {
+ return get_url (session, header);
+ }
+ } else if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+ return msg;
+ }
+
+ return NULL;
+}
+
+static void
+handle_incoming (xmlNodePtr head,
+ EmailProvider *provider)
+{
+ xmlNodePtr node = head->children;
+
+ provider->recv_type = xml_to_gchar (
+ xmlGetProp (head, (xmlChar *) "type"), provider);
+
+ while (node != NULL) {
+ if (strcmp ((gchar *)node->name, "hostname") == 0) {
+ provider->recv_hostname = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ } else if (strcmp ((gchar *)node->name, "port") == 0) {
+ provider->recv_port = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ } else if (strcmp ((gchar *)node->name, "socketType") == 0) {
+ provider->recv_socket_type = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ } else if (strcmp ((gchar *)node->name, "username") == 0) {
+ provider->recv_username = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ } else if (strcmp ((gchar *)node->name, "authentication") == 0) {
+ provider->recv_auth = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ }
+
+ node = node->next;
+ }
+}
+
+static void
+handle_outgoing (xmlNodePtr head,
+ EmailProvider *provider)
+{
+ xmlNodePtr node = head->children;
+
+ provider->send_type = xml_to_gchar (
+ xmlGetProp (head, (xmlChar *) "type"), provider);
+
+ while (node != NULL) {
+ if (strcmp ((gchar *)node->name, "hostname") == 0) {
+ provider->send_hostname = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ } else if (strcmp ((gchar *)node->name, "port") == 0) {
+ provider->send_port = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ } else if (strcmp ((gchar *)node->name, "socketType") == 0) {
+ provider->send_socket_type = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ } else if (strcmp ((gchar *)node->name, "username") == 0) {
+ provider->send_username = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ } else if (strcmp ((gchar *)node->name, "authentication") == 0) {
+ provider->send_auth = xml_to_gchar (
+ xmlNodeGetContent (node), provider);
+ }
+
+ node = node->next;
+ }
+}
+
+static gboolean
+parse_message (const gchar *msg,
+ gint length,
+ EmailProvider *provider)
+{
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ doc = xmlReadMemory (msg, length, "file.xml", NULL, 0);
+
+ node = doc->children;
+ while (node) {
+ if (strcmp ((gchar *)node->name, "clientConfig") == 0) {
+ break;
+ }
+ node = node->next;
+ }
+
+ if (!node) {
+ g_warning ("Incorrect data: ClientConfig not found ... Quitting\n");
+ return FALSE;
+ }
+
+ node = node->children;
+ while (node) {
+ if (strcmp ((gchar *)node->name, "emailProvider") == 0) {
+ break;
+ }
+ node = node->next;
+ }
+
+ if (!node) {
+ g_warning ("Incorrect data: ClientConfig not found ... Quitting\n");
+ return FALSE;
+ }
+
+ node = node->children;
+ while (node) {
+ if (strcmp ((gchar *)node->name, "incomingServer") == 0) {
+ /* Handle Incoming */
+ handle_incoming (node, provider);
+ } else if (strcmp ((gchar *)node->name, "outgoingServer") == 0) {
+ /* Handle Outgoing */
+ handle_outgoing (node, provider);
+ }
+
+ node = node->next;
+ }
+
+ xmlFreeDoc (doc);
+
+ return TRUE;
+}
+
+static gboolean
+parse_soup_message (SoupMessage *msg,
+ EmailProvider *provider)
+{
+ return parse_message (
+ msg->response_body->data,
+ msg->response_body->length, provider);
+}
+
+static gboolean
+is_online (void)
+{
+ EShell *shell;
+
+ /* FIXME Pass this in. */
+ shell = e_shell_get_default ();
+
+ return e_shell_get_online (shell);
+}
+
+static gboolean
+guess_when_online (EmailProvider *provider)
+{
+ const gchar *cafile = NULL;
+ gchar *url;
+ EProxy *proxy;
+ SoupURI *parsed;
+ SoupMessage *msg;
+ SoupSession *session;
+
+ proxy = e_proxy_new ();
+ e_proxy_setup_proxy (proxy);
+
+ url = g_strdup_printf (
+ "%s/%s", "http://api.gnome.org/evolution/autoconfig",
+ provider->domain);
+ parsed = soup_uri_new (url);
+ soup_uri_free (parsed);
+
+ session = soup_session_sync_new_with_options (
+ SOUP_SESSION_SSL_CA_FILE, cafile,
+ SOUP_SESSION_USER_AGENT, "get ",
+ NULL);
+
+ if (e_proxy_require_proxy_for_uri (proxy, url)) {
+ SoupURI *proxy_uri = e_proxy_peek_uri_for (proxy, url);
+/* fprintf (stderr, "URL '%s' requires a proxy: '%s'\n",
+ url, soup_uri_to_string (proxy_uri, FALSE)); */
+ g_object_set (session, SOUP_SESSION_PROXY_URI, proxy_uri, NULL);
+ }
+
+ msg = get_url (session, url);
+ if (!msg)
+ return FALSE;
+
+ parse_soup_message (msg, provider);
+
+ g_object_unref (proxy);
+ g_object_unref (msg);
+ g_object_unref (session);
+ g_free (url);
+
+ return TRUE;
+
+}
+
+static gchar *
+get_filename_for_offline_autoconfig (const gchar *domain)
+{
+ return g_build_filename (EVOLUTION_PRIVDATADIR, "mail-autoconfig", domain, NULL);
+}
+
+static gboolean
+guess_when_offline (EmailProvider *provider)
+{
+ gchar *filename;
+ gchar *contents;
+ gsize length;
+ gboolean success;
+
+ if (!provider->domain || provider->domain[0] == 0)
+ return FALSE;
+
+ success = FALSE;
+
+ filename = get_filename_for_offline_autoconfig (provider->domain);
+ if (!g_file_get_contents (filename, &contents, &length, NULL)) /* NULL-GError */
+ goto out;
+
+ success = parse_message (contents, (gint) length, provider);
+
+out:
+ g_free (filename);
+ g_free (contents);
+
+ return success;
+}
+
+gboolean
+mail_guess_servers (EmailProvider *provider)
+{
+ if (is_online () && guess_when_online (provider))
+ return TRUE;
+ else
+ return guess_when_offline (provider);
+}
+
+#ifdef TEST
+gint
+main (gint argc,
+ gchar **argv)
+{
+ EmailProvider *provider;
+
+ g_type_init ();
+
+ provider = g_new0 (EmailProvider, 1);
+
+ provider->email = "sragavan@iijmio-mail.jp";
+ provider->domain = "iijmio-mail.jp";
+ provider->username = "sragavan";
+
+ mail_guess_servers (provider);
+
+ printf (
+ "Recv: %s\n%s(%s), %s by %s \n "
+ "Send: %s\n%s(%s), %s by %s\n via %s to %s\n",
+ provider->recv_type, provider->recv_hostname,
+ provider->recv_port, provider->recv_username,
+ provider->recv_auth,
+ provider->send_type, provider->send_hostname,
+ provider->send_port, provider->send_username,
+ provider->send_auth,
+ provider->recv_socket_type,
+ provider->send_socket_type);
+ return 0;
+}
+#endif