Commit fa627d6e authored by Srinivasa Ragavan's avatar Srinivasa Ragavan

EMailFactory a camel based daemon.

parent 713cd266
......@@ -6,8 +6,8 @@ if ENABLE_CALENDAR
CALENDAR_DIR = calendar
endif
SUBDIRS = libedataserver libebackend servers camel addressbook $(CALENDAR_DIR) libedataserverui docs art po
DIST_SUBDIRS = libedataserver libebackend servers camel addressbook calendar libedataserverui docs art po
SUBDIRS = libedataserver libebackend servers camel addressbook $(CALENDAR_DIR) libedataserverui mail docs art po
DIST_SUBDIRS = libedataserver libebackend servers camel addressbook calendar libedataserverui mail docs art po
%-$(API_VERSION).pc: %.pc
cp $< $@
......
......@@ -1220,6 +1220,22 @@ EVO_SET_COMPILE_FLAGS(E_BACKEND, $E_BACKEND_DEPS)
AC_SUBST(E_BACKEND_CFLAGS)
AC_SUBST(E_BACKEND_LIBS)
dnl ******************************
dnl Email daemon
dnl ******************************
PKG_CHECK_MODULES(E_MAIL_FACTORY, glib-2.0 gtk+-2.0 gdbus-codegen)
AC_SUBST(E_MAIL_FACTORY_CFLAGS)
AC_SUBST(E_MAIL_FACTORY_LIBS)
PKG_CHECK_MODULES(E_MAIL_GDBUS_UTILS, glib-2.0 gtk+-2.0 gdbus-codegen)
AC_SUBST(E_MAIL_GDBUS_UTILS_CFLAGS)
AC_SUBST(E_MAIL_GDBUS_UTILS_LIBS)
PKG_CHECK_MODULES(E_MAIL_UTILS, glib-2.0 gtk+-2.0 )
AC_SUBST(E_MAIL_UTILS_CFLAGS)
AC_SUBST(E_MAIL_UTILS_LIBS)
dnl ******************************
dnl evolution-addressbook flags
dnl ******************************
......@@ -1497,6 +1513,11 @@ libedataserver/eds-version.h
libedataserver/libedataserver.pc
libedataserverui/Makefile
libedataserverui/libedataserverui.pc
mail/Makefile
mail/libemailutils/Makefile
mail/libemailutils/libemail-utils.pc
mail/libegdbus/Makefile
mail/daemon/Makefile
servers/Makefile
servers/groupwise/Makefile
servers/groupwise/libegroupwise.pc
......
SUBDIRS = libemailutils libegdbus daemon
DISTCHECK_CONFIGURE_FLAGS=
CLEANFILES = *~
bin_PROGRAMS = e-mail-factory
e_mail_factory_SOURCES = main.c \
e-mail-local.c \
e-mail-local.h \
e-mail-store.c \
e-mail-store.h \
e-dbus-manager.c \
e-dbus-manager.h \
e-mail-data-store.c \
e-mail-data-store.h \
e-mail-data-session.c \
e-mail-data-session.h \
e-mail-data-folder.c \
e-mail-data-folder.h \
mail-tools.c \
mail-tools.h \
mail-ops.c \
mail-ops.h \
mail-folder-cache.c \
mail-folder-cache.h \
mail-config.c \
mail-config.h \
mail-send-recv.c \
mail-send-recv.h \
mail-session.c \
mail-session.h \
utils.c \
utils.h
noinst_PROGRAMS = test-email-client
test_email_client_SOURCES = test-email-client.c
test_email_client_CPPFLAGS = \
$(E_MAIL_FACTORY_CFLAGS) \
$(GNOME_PLATFORM_CFLAGS) \
$(CAMEL_CFLAGS) \
-Wall -g3 -O0 -ggdb -DPKGDATADIR="\"$(pkgdatadir)\"" \
-I$(top_srcdir)/mail/ \
-I$(top_srcdir)/mail/libemailutils \
-I$(top_srcdir)/mail/libegdbus \
-I$(top_srcdir) \
-I$(top_builddir)
test_email_client_LDADD = \
$(top_builddir)/mail/libemailutils/libemail-utils.la \
$(top_builddir)/mail/libegdbus/libegdbus-mail.la \
$(top_builddir)/camel/libcamel-1.2.la \
$(top_builddir)/camel/libcamel-provider-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
$(top_builddir)/libedataserverui/libedataserverui-1.2.la \
$(E_MAIL_FACTORY_LIBS) \
$(GNOME_PLATFORM_LIBS) \
$(CAMEL_LIBS) \
-lffi
#desktopentry_DATA = e-mail-factory.desktop
#icon_DATA =
#see gcc man page for description: http://www.google.com/search?q=man+gcc
#AM_CFLAGS = @E_MAIL_FACTORY_CFLAGS@ -Wall -Werror -g3 -O0 -ggdb -DPKGDATADIR="\"$(pkgdatadir)\""
#AM_LDFLAGS = @E_MAIL_FACTORY_LIBS@
e_mail_factory_CPPFLAGS = \
$(E_MAIL_FACTORY_CFLAGS) \
$(CAMEL_CFLAGS) \
$(GNOME_PLATFORM_CFLAGS) \
-Wall -g3 -O0 -ggdb -DPKGDATADIR="\"$(pkgdatadir)\"" \
-I$(top_srcdir)/mail/ \
-I$(top_srcdir)/mail/libemailutils \
-I$(top_srcdir)/mail/libegdbus \
-I$(top_srcdir) \
-I$(top_builddir)
e_mail_factory_LDADD = \
$(CAMEL_LIBS) \
$(GNOME_PLATFORM_LIBS) \
$(top_builddir)/camel/libcamel-1.2.la \
$(top_builddir)/camel/libcamel-provider-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
$(top_builddir)/libedataserverui/libedataserverui-1.2.la \
$(top_builddir)/mail/libemailutils/libemail-utils.la \
$(top_builddir)/mail/libegdbus/libegdbus-mail.la \
$(E_MAIL_FACTORY_LIBS) \
-lffi
EXTRA_DIST =
CLEANFILES = *~ #e-mail-factory.desktop
/* e-dbus-manager.c */
#include "e-dbus-manager.h"
#include "e-mail-data-session.h"
#include <gio/gio.h>
#define E_MAIL_DATA_FACTORY_SERVICE_NAME \
"org.gnome.evolution.dataserver.Mail"
G_DEFINE_TYPE (EDBusManager, e_dbus_manager, G_TYPE_OBJECT)
#define MANAGER_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), EDBUS_TYPE_MANAGER, EDBusManagerPrivate))
typedef struct _EDBusManagerPrivate EDBusManagerPrivate;
/* This needs to be global ala the CamelSession*/
EMailDataSession *data_session;
struct _EDBusManagerPrivate
{
guint owner_id;
GMutex *books_lock;
/* A hash of object paths for book URIs to EDataBooks */
GHashTable *books;
GMutex *connections_lock;
/* This is a hash of client addresses to GList* of EDataBooks */
GHashTable *connections;
guint exit_timeout;
};
/* Convenience function to print an error and exit */
G_GNUC_NORETURN static void
die (const gchar *prefix, GError *error)
{
g_error("%s: %s", prefix, error->message);
g_error_free (error);
exit(1);
}
static void
e_dbus_manager_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
switch (property_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
e_dbus_manager_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
switch (property_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
e_dbus_manager_dispose (GObject *object)
{
G_OBJECT_CLASS (e_dbus_manager_parent_class)->dispose (object);
}
static void
e_dbus_manager_finalize (GObject *object)
{
G_OBJECT_CLASS (e_dbus_manager_parent_class)->finalize (object);
}
static void
e_dbus_manager_class_init (EDBusManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (EDBusManagerPrivate));
object_class->get_property = e_dbus_manager_get_property;
object_class->set_property = e_dbus_manager_set_property;
object_class->dispose = e_dbus_manager_dispose;
object_class->finalize = e_dbus_manager_finalize;
}
static void
on_bus_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
EDBusManager *manager = user_data;
EDBusManagerPrivate *priv = MANAGER_PRIVATE(manager);
guint registration_id;
GError *error = NULL;
registration_id = e_mail_data_session_register_gdbus_object (
data_session,
connection,
"/org/gnome/evolution/dataserver/Mail/Session",
&error);
if (error)
die ("Failed to register a Mail Session object", error);
g_assert (registration_id > 0);
}
static void
on_name_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
}
static void
on_name_lost (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
EDBusManager *manager = user_data;
EDBusManagerPrivate *priv = MANAGER_PRIVATE(manager);
e_mail_data_session_release (data_session, connection, name);
#if 0
g_mutex_lock (factory->priv->connections_lock);
while (g_hash_table_lookup_extended (
factory->priv->connections, name,
(gpointer) &key, (gpointer) &list)) {
GList *copy = g_list_copy (list);
/* this should trigger the book's weak ref notify
* function, which will remove it from the list before
* it's freed, and will remove the connection from
* priv->connections once they're all gone */
g_list_foreach (copy, remove_data_book_cb, NULL);
g_list_free (copy);
}
g_mutex_unlock (factory->priv->connections_lock);
#endif
}
static void
e_dbus_manager_init (EDBusManager *self)
{
EDBusManagerPrivate *priv = MANAGER_PRIVATE(self);
data_session = e_mail_data_session_new ();
priv->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
E_MAIL_DATA_FACTORY_SERVICE_NAME,
G_BUS_NAME_OWNER_FLAGS_NONE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
self,
NULL);
}
EDBusManager*
e_dbus_manager_new (void)
{
return g_object_new (EDBUS_TYPE_MANAGER, NULL);
}
/* e-dbus-manager.h */
#ifndef _E_DBUS_MANAGER_H
#define _E_DBUS_MANAGER_H
#include <glib-object.h>
G_BEGIN_DECLS
#define EDBUS_TYPE_MANAGER e_dbus_manager_get_type()
#define EDBUS_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
EDBUS_TYPE_MANAGER, EDBusManager))
#define EDBUS_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
EDBUS_TYPE_MANAGER, EDBusManagerClass))
#define EDBUS_IS_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
EDBUS_TYPE_MANAGER))
#define EDBUS_IS_MANAGER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
EDBUS_TYPE_MANAGER))
#define EDBUS_MANAGER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
EDBUS_TYPE_MANAGER, EDBusManagerClass))
typedef struct {
GObject parent;
} EDBusManager;
typedef struct {
GObjectClass parent_class;
} EDBusManagerClass;
GType e_dbus_manager_get_type (void);
EDBusManager* e_dbus_manager_new (void);
G_END_DECLS
#endif /* _E_DBUS_MANAGER_H */
This diff is collapsed.
/* e-mail-data-folder.h */
#ifndef _E_MAIL_DATA_FOLDER_H
#define _E_MAIL_DATA_FOLDER_H
#include <glib-object.h>
#include <camel/camel.h>
G_BEGIN_DECLS
#define EMAIL_TYPE_DATA_FOLDER e_mail_data_folder_get_type()
#define EMAIL_DATA_FOLDER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
EMAIL_TYPE_DATA_FOLDER, EMailDataFolder))
#define EMAIL_DATA_FOLDER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
EMAIL_TYPE_DATA_FOLDER, EMailDataFolderClass))
#define EMAIL_IS_DATA_FOLDER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
EMAIL_TYPE_DATA_FOLDER))
#define EMAIL_IS_DATA_FOLDER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
EMAIL_TYPE_DATA_FOLDER))
#define EMAIL_DATA_FOLDER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
EMAIL_TYPE_DATA_FOLDER, EMailDataFolderClass))
typedef struct {
GObject parent;
} EMailDataFolder;
typedef struct {
GObjectClass parent_class;
} EMailDataFolderClass;
GType e_mail_data_folder_get_type (void);
EMailDataFolder* e_mail_data_folder_new (CamelFolder *folder);
guint e_mail_data_folder_register_gdbus_object (EMailDataFolder *mfolder, GDBusConnection *connection, const gchar *object_path, GError **error);
const char * e_mail_data_folder_get_path (EMailDataFolder *mfolder);
CamelFolder * e_mail_data_folder_get_camel_folder (EMailDataFolder *efolder);
G_END_DECLS
#endif /* _E_MAIL_DATA_FOLDER_H */
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE node SYSTEM "dbus.dtd">
<!--
Author: Srinivasa Ragavan <sragavan@gnome.org>
Copyright (C) 2011 Intel Corporation
-->
<node>
<interface name="org.gnome.evolution.dataserver.mail.Folder">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="EMailDataFolder"/>
<annotation name="org.gtk.GDBus.Name" value="CF"/>
<!-- Sync APIs -->
<method name="refreshInfo">
<arg name="success" type="b" direction="out"/>
</method>
<method name="sync">
<arg name="expunge" type="b" direction="in"/>
<arg name="success" type="b" direction="out"/>
</method>
<method name="expunge">
<arg name="success" type="b" direction="out"/>
</method>
<signal name="FolderChanged">
<arg name="uids_added" type="as"/>
<arg name="uids_removed" type="as"/>
<arg name="uids_changed" type="as"/>
<arg name="uids_recent" type="as"/>
</signal>
<!-- Info on Folder -->
<method name="getName">
<arg name="name" type="s" direction="out"/>
</method>
<method name="setName">
<arg name="name" type="s" direction="in"/>
</method>
<method name="getFullName">
<arg name="name" type="s" direction="out"/>
</method>
<method name="setFullName">
<arg name="name" type="s" direction="in"/>
</method>
<method name="getDescription">
<arg name="desc" type="s" direction="out"/>
</method>
<method name="setDescription">
<arg name="desc" type="s" direction="in"/>
</method>
<!-- Folder stuff-->
<method name="getPermanentFlags">
<arg name="flags" type="u" direction="out"/>
</method>
<method name="hasSummaryCapability">
<arg name="summary" type="b" direction="out"/>
</method>
<method name="hasSearchCapability">
<arg name="search" type="b" direction="out"/>
</method>
<method name="totalMessageCount">
<arg name="count" type="i" direction="out"/>
</method>
<method name="unreadMessageCount">
<arg name="count" type="i" direction="out"/>
</method>
<method name="deletedMessageCount">
<arg name="count" type="i" direction="out"/>
</method>
<!-- Message & UID -->
<method name="getMessageFlags">
<arg name="uid" type="s" direction="in"/>
<arg name="flags" type="u" direction="out"/>
</method>
<method name="setMessageFlags">
<arg name="uid" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="set" type="u" direction="in"/>
<arg name="success" type="b" direction="out"/>
</method>
<method name="getMessageUserFlag">
<arg name="uid" type="s" direction="in"/>
<arg name="flagname" type="s" direction="in"/>
<arg name="flag" type="b" direction="out"/>
</method>
<method name="setMessageUserFlag">
<arg name="uid" type="s" direction="in"/>
<arg name="flagname" type="s" direction="in"/>
<arg name="set" type="u" direction="in"/>
</method>
<method name="getMessageUserTag">
<arg name="uid" type="s" direction="in"/>
<arg name="param" type="s" direction="in"/>
<arg name="value" type="s" direction="out"/>
</method>
<method name="setMessageUserTag">
<arg name="uid" type="s" direction="in"/>
<arg name="param" type="s" direction="in"/>
<arg name="value" type="s" direction="in"/>
</method>
<!-- Folder operations -->
<method name="getParentStore">
<arg name="store" type="o" direction="out"/>
</method>
<method name="AppendMessage">
<!-- Structure of CamelMessageInfoBase
ssssss - uid, sub, from, to, cc, mlist
uu - flags, size
tt - date_sent, date_received
t - message_id
iat - references
as - userflags
a(ss) - usertags
/* We aren't now sending content_info & headers */
-->
<arg name="info" type="(ssssssuutttiatasa(ss))" direction="in"/>
<arg name="message" type="s" direction="in"/>
<arg name="appendeduid" type="s" direction="out"/>
<arg name="success" type="b" direction="out"/>
</method>
<method name="getUids">
<arg name="uids" type="as" direction="out"/>
</method>
<method name="getMessage">
<arg name="uid" type="s" direction="in"/>
<arg name="message" type="s" direction="out"/>
</method>
<method name="searchByExpression">
<arg name="expression" type="s" direction="in"/>
<arg name="uids" type="as" direction="out"/>
</method>
<method name="searchByUids">
<arg name="expression" type="s" direction="in"/>
<arg name="searchuids" type="as" direction="in"/>
<arg name="resultuids" type="as" direction="out"/>
</method>
<method name="getMessageInfo">
<arg name="uid" type="s" direction="in"/>
<!-- Structure of CamelMessageInfoBase -->
<arg name="info" type="(ssssssuutttiatasa(ss))" direction="out"/>
</method>
<method name="transferMessagesTo">
<arg name="uids" type="as" direction="in"/>
<arg name="destfolder" type="o" direction="in"/>
<arg name="deleteoriginals" type="b" direction="in"/>
<arg name="returnuids" type="as" direction="out"/>
</method>
<method name="prepareSummary">
</method>
</interface>
</node>
/* e-mail-data-session.c */
#include "e-mail-data-session.h"
#include "e-mail-local.h"
#include "e-mail-data-store.h"
#include "e-gdbus-emailsession.h"
#include <camel/camel.h>
#include <gio/gio.h>
#include "mail-ops.h"
#include "utils.h"
extern CamelSession *session;
#define micro(x) if (mail_debug_log(EMAIL_DEBUG_SESSION|EMAIL_DEBUG_MICRO)) x;
#define ipc(x) if (mail_debug_log(EMAIL_DEBUG_SESSION|EMAIL_DEBUG_IPC)) x;
G_DEFINE_TYPE (EMailDataSession, e_mail_data_session, G_TYPE_OBJECT)
#define DATA_SESSION_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), EMAIL_TYPE_DATA_SESSION, EMailDataSessionPrivate))
typedef struct _EMailDataSessionPrivate EMailDataSessionPrivate;
struct _EMailDataSessionPrivate
{
EGdbusSessionCS *gdbus_object;
GMutex *stores_lock;
/* 'uri' -> EBookBackend */
GHashTable *stores;
GMutex *datastores_lock;
/* A hash of object paths for book URIs to EDataBooks */
GHashTable *datastores;
GMutex *connections_lock;
/* This is a hash of client addresses to GList* of EDataBooks */
GHashTable *connections;
guint exit_timeout;
};
static gchar *
construct_mail_session_path (void)
{
static volatile gint counter = 1;
return g_strdup_printf (
"/org/gnome/evolution/dataserver/mail/store/%d/%u",
getpid (), g_atomic_int_exchange_and_add (&counter, 1));
}
typedef struct _email_get_store_data {
EMailDataSession *msession;