summaryrefslogtreecommitdiffstats
path: root/sync/src/sync_syncml_item.c
diff options
context:
space:
mode:
Diffstat (limited to 'sync/src/sync_syncml_item.c')
-rw-r--r--sync/src/sync_syncml_item.c248
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;
+}