/* -*- 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
*
*
* Authors:
* Srinivasa Ragavan
*
* Copyright (C) 2009 Intel Corporation (www.intel.com)
*
*/
/* Template of the code is taken from libsoup tests/ */
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "mail-guess-servers.h"
static char *
xml_to_gchar (xmlChar *xml, EmailProvider *provider)
{
char *gxml = NULL;
char *tmp;
char *repl = NULL, *sec_part;
tmp = xml ? strstr(xml, "\%EMAIL") : NULL;
if (!tmp) {
gxml = xml ? g_strdup(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 : (char *)xml, repl, sec_part);
tmp = strstr (gxml, "\%EMAIL");
if(tmp) {
goto decodepart;
}
}
xmlFree(xml);
return gxml;
}
static SoupMessage *
get_url (SoupSession *session, const char *url)
{
const char *name;
SoupMessage *msg;
const char *header;
msg = soup_message_new (SOUP_METHOD_GET, url);
soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
soup_session_send_message (session, msg);
name = soup_message_get_uri (msg)->path;
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, "type"), provider);
while (node) {
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, "type"), provider);
while (node) {
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 void
parse_msg (SoupMessage *msg, EmailProvider *provider)
{
xmlDocPtr doc;
xmlNodePtr node, top;
doc = xmlReadMemory ((xmlChar *) msg->response_body->data, msg->response_body->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;
}
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;
}
top = node;
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);
}
gboolean
mail_guess_servers(EmailProvider *provider)
{
const char *cafile = NULL;
char *url;
SoupURI *proxy = NULL, *parsed;
int opt;
SoupMessage *msg;
SoupSession *session;
url = g_strdup_printf("%s/%s", "https://live.mozillamessaging.com/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 (proxy) {
g_object_set (G_OBJECT (session),
SOUP_SESSION_PROXY_URI, proxy,
NULL);
}
msg = get_url (session, url);
if (!msg)
return FALSE;
parse_msg(msg, provider);
g_object_unref (msg);
g_object_unref(session);
g_free(url);
return TRUE;
}
#ifdef TEST
int
main (int argc, char **argv)
{
EmailProvider *provider;
g_thread_init (NULL);
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