aboutsummaryrefslogblamecommitdiffstats
path: root/capplet/mail-guess-servers.c
blob: 26fc630f16a71081344da28a7fe467e973f14388 (plain) (tree)

















































































































































































































































































                                                                                                                          
/* -*- 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 "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: 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, *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