diff options
Diffstat (limited to 'sync/src/sync_syncml_item.c')
-rw-r--r-- | sync/src/sync_syncml_item.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/sync/src/sync_syncml_item.c b/sync/src/sync_syncml_item.c new file mode 100644 index 0000000..00a9b56 --- /dev/null +++ b/sync/src/sync_syncml_item.c @@ -0,0 +1,248 @@ + +#include <opensync/opensync.h> +#include <glib.h> +#include <gconf/gconf-client.h> +#include <string.h> +#include "sync_group.h" +#include "sync_item.h" +#include "sync_syncml_item.h" + +#define SYNCML_PLUGIN "syncml-client" +#define SYNCML_CONFIG "<config>" \ + "<gconf-uri>%s</gconf-uri>" \ + "<object-type>%s</object-type>" \ + "<sync-source-name>%s</sync-source-name>" \ + "</config>" + +#define GCONF_ROOT "/apps/libsync/" + +typedef struct { + const gchar *key; + const gchar *value; +} SyncGConfSchema; + +/* NOTE: See the GConf schema that ships with the syncml client api */ +static const SyncGConfSchema syncml_config[] = { + { "/spds/syncml/begin", "0" }, + { "/spds/syncml/checkConn", "1" }, + { "/spds/syncml/deviceId", "localhost" }, + { "/spds/syncml/end", "0" }, + { "/spds/syncml/firstTimeSyncMode", "two-way" }, + { "/spds/syncml/password", "guest" }, + { "/spds/syncml/proxyHost", "" }, + { "/spds/syncml/proxyPort", "" }, + { "/spds/syncml/responseTimeout", "180" }, + { "/spds/syncml/serverName", "" }, + { "/spds/syncml/syncUrl", "" }, + { "/spds/syncml/useProxy", "" }, + { "/spds/syncml/username", "guest" }, + + { "/spds/sources/cal/dir", "/tmp/libsync" }, + { "/spds/sources/cal/last", "0" }, + { "/spds/sources/cal/name", "cal" }, + { "/spds/sources/cal/sync", "two-way" }, + { "/spds/sources/cal/syncModes", "none,slow,two-way" }, + { "/spds/sources/cal/type", "text/x-vcalendar" }, + { "/spds/sources/cal/uri", "cal" }, + + { "/spds/sources/card/dir", "/tmp/libsync" }, + { "/spds/sources/card/last", "0" }, + { "/spds/sources/card/name", "card" }, + { "/spds/sources/card/sync", "two-way" }, + { "/spds/sources/card/syncModes", "none,slow,two-way" }, + { "/spds/sources/card/type", "text/x-vcard" }, + { "/spds/sources/card/uri", "con" }, + + { "/spds/sources/note/dir", "/tmp/libsync" }, + { "/spds/sources/note/last", "0" }, + { "/spds/sources/note/name", "note" }, + { "/spds/sources/note/sync", "two-way" }, + { "/spds/sources/note/syncModes", "none,slow,two-way" }, + { "/spds/sources/note/type", "text/plain" }, + { "/spds/sources/note/uri", "note" }, + + { "/spds/sources/task/dir", "/tmp/libsync" }, + { "/spds/sources/task/last", "0" }, + { "/spds/sources/task/name", "task" }, + { "/spds/sources/task/sync", "two-way" }, + { "/spds/sources/task/syncModes", "none,slow,two-way" }, + { "/spds/sources/task/type", "text/x-vcalendar" }, + { "/spds/sources/task/uri", "task" }, + + { NULL } +}; + +#define NAME_KEY "/spds/syncml/serverName" +#define ADR_KEY "/spds/syncml/syncUrl" +#define USER_KEY "/spds/syncml/username" +#define PASS_KEY "/spds/syncml/password" +#define DIR_KEY "%s/spds/sources/%s/uri" + +typedef struct { + SyncSyncMLType type; + gchar *username; + gchar *password; + gchar *dir; +} SyncSyncMLItemData; + +static const char * +sync_syncml_type_to_type_string (SyncSyncMLType type) +{ + switch (type) { + case CONTACTS: return "contact"; + case EVENTS: return "event"; + case TODO: return "todo"; + case NOTE: return "note"; + default: + g_warning ("Invalid type!"); + return NULL; + } +} + +static const char * +sync_syncml_type_to_source_string (SyncSyncMLType type) +{ + switch (type) { + case CONTACTS: return "card"; + case EVENTS: return "cal"; + case TODO: return "task"; + case NOTE: return "note"; + default: + g_warning ("Invalid type!"); + return NULL; + } +} + +static OSyncMember * +sync_syncml_item_get_member (SyncItem *item) +{ + OSyncMember *member; + OSyncError *error = NULL; + OSyncConfigurationTypes type = NO_CONFIGURATION; + SyncGroup *group; + OSyncGroup *os_group; + + /* Setup SyncML sync member */ + group = sync_item_get_group (item); + os_group = sync_group_get_osync_group (group); + member = osync_member_new (os_group); + if (!osync_member_instance_plugin (member, SYNCML_PLUGIN, &error)) { + g_warning ("Error instancing SyncML client plug-in: %s", + osync_error_print (&error)); + osync_error_free (&error); + return NULL; + } + if (!osync_member_need_config (member, &type, &error)) { + g_warning ("Error reading plug-in config requirements: %s", + osync_error_print (&error)); + osync_error_free (&error); + return NULL; + } + if (type == NO_CONFIGURATION) { + g_warning ("SyncML client plug-in reports no need for " + "configuration"); + } else { + gint i; + SyncSyncMLItemData *data; + gchar *xml_config, *gconf_root, *gconf_path; + OSyncFormatEnv *env; + GConfClient *client = gconf_client_get_default (); + + data = (SyncSyncMLItemData *)sync_item_get_data (item); + + /* Configure OpenSync conf */ + gconf_root = g_strconcat (GCONF_ROOT, + sync_item_get_name (item), NULL); + + xml_config = g_strdup_printf (SYNCML_CONFIG, gconf_root, + sync_syncml_type_to_type_string (data->type), + sync_syncml_type_to_source_string (data->type)); + osync_member_set_config ( + member, xml_config, strlen (xml_config)); + g_free (xml_config); + + /* Configure funambol syncml client GConf keys */ + for (i = 0; syncml_config[i].key; i++) { + gconf_path = g_strconcat ( + gconf_root, syncml_config[i].key, NULL); + + gconf_client_set_string (client, + gconf_path, syncml_config[i].value, NULL); + g_free (gconf_path); + } + + gconf_path = g_strconcat (gconf_root, NAME_KEY, NULL); + gconf_client_set_string (client, gconf_path, + sync_item_get_name (item), NULL); + g_free (gconf_path); + + gconf_path = g_strconcat (gconf_root, ADR_KEY, NULL); + gconf_client_set_string (client, gconf_path, + sync_item_get_adr (item), NULL); + g_free (gconf_path); + + gconf_path = g_strconcat (gconf_root, USER_KEY, NULL); + gconf_client_set_string (client, gconf_path, data->username, + NULL); + g_free (gconf_path); + + gconf_path = g_strconcat (gconf_root, PASS_KEY, NULL); + gconf_client_set_string (client, gconf_path, data->password, + NULL); + g_free (gconf_path); + + gconf_path = g_strdup_printf (DIR_KEY, gconf_root, + sync_syncml_type_to_source_string (data->type)); + gconf_client_set_string (client, gconf_path, data->dir, NULL); + g_free (gconf_path); + + g_free (gconf_root); + + /* Filter out unwanted objects */ + env = osync_conv_env_new (osync_group_get_env (os_group)); + for (i = 0; i < osync_conv_num_objtypes (env); i++) { + const gchar *type = osync_objtype_get_name ( + osync_conv_nth_objtype (env, i)); + + if (strcmp (type, sync_syncml_type_to_type_string ( + data->type)) == 0) + continue; + + osync_group_set_objtype_enabled (os_group, type, 0); + } + } + + return member; +} + +static void +sync_syncml_free_data (SyncSyncMLItemData *data) +{ + g_free (data->username); + g_free (data->password); + if (data->dir) g_free (data->dir); + g_free (data); +} + +SyncItem * +sync_syncml_item_new (const gchar *name, const gchar *address, + SyncSyncMLType type, const gchar *username, + const gchar *password, const gchar *dir) +{ + SyncItem *item; + SyncSyncMLItemData *data; + + item = sync_item_new (name, address, sync_syncml_item_get_member); + + data = g_new0 (SyncSyncMLItemData, 1); + data->type = type; + data->username = username ? g_strdup (username) : g_strdup (""); + data->password = password ? g_strdup (password) : g_strdup (""); + data->dir = dir ? g_strdup (dir) : NULL; + + sync_item_set_data (item, data); + sync_item_set_data_free_func (item, + (SyncItemDataFreeFunc)sync_syncml_free_data); + + return item; +} |