From: <dg...@su...> - 2009-01-13 23:49:34
|
Author: Graham Cobb Date: Wed Jan 14 00:48:41 2009 New Revision: 5136 URL: http://www.opensync.org/changeset/5136 Log: Replace environment save/restore with repeated config and repeated discovery Modified: plugins/gpe/ChangeLog plugins/gpe/src/calendar.c plugins/gpe/src/contacts.c plugins/gpe/src/gpe_sync.c plugins/gpe/src/gpe_sync.h plugins/gpe/src/todo.c Modified: plugins/gpe/ChangeLog ============================================================================== --- plugins/gpe/ChangeLog Tue Jan 13 23:59:59 2009 (r5135) +++ plugins/gpe/ChangeLog Wed Jan 14 00:48:41 2009 (r5136) @@ -1,3 +1,22 @@ +2009-01-13 Graham Cobb <g+...@co...> + + * src/contacts.c (gpe_contacts_commit_change, gpe_contacts_get_changes): + Assert plugin is configured and discovered. + + * src/todo.c (gpe_todo_commit_change, gpe_todo_get_changes): + Assert plugin is configured and discovered. + + * src/calendar.c (gpe_calendar_commit_change, gpe_calendar_get_changes): + Assert plugin is configured and discovered. + + * src/gpe_sync.c (discover): Split discovery into "internal" and full. + Change order of discovery parameters to match API change. + + * src/gpe_sync.h: Add "configured" and "discovered" flags to environment. + Add version numbers to environment. + Add const qualifier to calendar path string. + Create gpe_assert and gpe_assert_error. + 2009-01-12 Graham Cobb <g+...@co...> * README: Rewrite to bring up to date Modified: plugins/gpe/src/calendar.c ============================================================================== --- plugins/gpe/src/calendar.c Tue Jan 13 23:59:59 2009 (r5135) +++ plugins/gpe/src/calendar.c Wed Jan 14 00:48:41 2009 (r5136) @@ -39,6 +39,12 @@ char *error = NULL; char *data_ptr; unsigned int data_size; + + if (!gpe_assert(env->configured && env->discovered)) { + osync_trace(TRACE_ERROR, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered ); + osync_context_report_error (ctx, OSYNC_ERROR_GENERIC, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered); + return; + } switch (osync_change_get_changetype (change)) { case OSYNC_CHANGE_TYPE_DELETED: @@ -115,6 +121,12 @@ gpe_environment *env = (gpe_environment *)userdata; sink_environment *sinkenv = (sink_environment *)osync_objtype_sink_get_userdata(osync_plugin_info_get_sink(info)); + if (!gpe_assert(env->configured && env->discovered)) { + osync_trace(TRACE_ERROR, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered ); + osync_context_report_error (ctx, OSYNC_ERROR_GENERIC, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered); + return; + } + if (osync_objtype_sink_get_slowsync(sinkenv->sink)) { osync_trace(TRACE_INTERNAL, "Slow sync requested"); if (!osync_hashtable_slowsync(sinkenv->hashtable, &error)) { Modified: plugins/gpe/src/contacts.c ============================================================================== --- plugins/gpe/src/contacts.c Tue Jan 13 23:59:59 2009 (r5135) +++ plugins/gpe/src/contacts.c Wed Jan 14 00:48:41 2009 (r5136) @@ -39,6 +39,12 @@ char *error = NULL; char *data_ptr; unsigned int data_size; + + if (!gpe_assert(env->configured && env->discovered)) { + osync_trace(TRACE_ERROR, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered ); + osync_context_report_error (ctx, OSYNC_ERROR_GENERIC, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered); + return; + } switch (osync_change_get_changetype (change)) { case OSYNC_CHANGE_TYPE_DELETED: @@ -115,6 +121,12 @@ gpe_environment *env = (gpe_environment *)userdata; sink_environment *sinkenv = (sink_environment *)osync_objtype_sink_get_userdata(osync_plugin_info_get_sink(info)); + if (!gpe_assert(env->configured && env->discovered)) { + osync_trace(TRACE_ERROR, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered ); + osync_context_report_error (ctx, OSYNC_ERROR_GENERIC, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered); + return; + } + if (osync_objtype_sink_get_slowsync(sinkenv->sink)) { osync_trace(TRACE_INTERNAL, "Slow sync requested"); if (!osync_hashtable_slowsync(sinkenv->hashtable, &error)) { Modified: plugins/gpe/src/gpe_sync.c ============================================================================== --- plugins/gpe/src/gpe_sync.c Tue Jan 13 23:59:59 2009 (r5135) +++ plugins/gpe/src/gpe_sync.c Wed Jan 14 00:48:41 2009 (r5136) @@ -21,241 +21,6 @@ #include "gpe_sync.h" -/* Save and restore environment data */ -static void save_environment(gpe_environment *env, OSyncPluginInfo *info) -{ - char buf[20]; - - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p)", __func__, env, info); - - /* We save the fields in the Anchor DB */ - char *anchorpath = g_strdup_printf("%s/anchor.db", osync_plugin_info_get_configdir(info)); - - /* For sinks we just need to save the objformat name */ - if (env->contact_sink.objformat) osync_anchor_update(anchorpath, "EnvContactSinkObjFormat", osync_objformat_get_name(env->contact_sink.objformat)); - if (env->todo_sink.objformat) osync_anchor_update(anchorpath, "EnvTodoSinkObjFormat", osync_objformat_get_name(env->todo_sink.objformat)); - if (env->calendar_sink.objformat) osync_anchor_update(anchorpath, "EnvCalendarSinkObjFormat", osync_objformat_get_name(env->calendar_sink.objformat)); - - /* Config info */ - if (env->device_addr) osync_anchor_update(anchorpath, "EnvDeviceAddr", env->device_addr); - if (env->username) osync_anchor_update(anchorpath, "EnvUsername", env->username); - if (env->command) osync_anchor_update(anchorpath, "EnvCommand", env->command); - snprintf(buf, sizeof(buf), "%d", env->device_port); - osync_anchor_update(anchorpath, "EnvDevicePort", buf); - snprintf(buf, sizeof(buf), "%d", env->use_ssh); - osync_anchor_update(anchorpath, "EnvUseSsh", buf); - snprintf(buf, sizeof(buf), "%d", env->use_local); - osync_anchor_update(anchorpath, "EnvUseLocal", buf); - snprintf(buf, sizeof(buf), "%d", env->use_remote); - osync_anchor_update(anchorpath, "EnvUseRemote", buf); - if (env->calendar) osync_anchor_update(anchorpath, "EnvCalendar", env->calendar); - snprintf(buf, sizeof(buf), "%d", env->debuglevel); - osync_anchor_update(anchorpath, "EnvDebuglevel", buf); - - g_free(anchorpath); - osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); -} -static void restore_environment(gpe_environment *env, OSyncPluginInfo *info) -{ - char *value; - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p)", __func__, env, info); - - /* We save the fields in the Anchor DB */ - char *anchorpath = g_strdup_printf("%s/anchor.db", osync_plugin_info_get_configdir(info)); - - /* For sinks we just need to restore the objformat */ - OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); - value = osync_anchor_retrieve(anchorpath, "EnvContactSinkObjFormat"); - if (value) env->contact_sink.objformat = osync_format_env_find_objformat(formatenv, value); - value = osync_anchor_retrieve(anchorpath, "EnvTodoSinkObjFormat"); - if (value) env->todo_sink.objformat = osync_format_env_find_objformat(formatenv, value); - value = osync_anchor_retrieve(anchorpath, "EnvCalendarSinkObjFormat"); - if (value) env->calendar_sink.objformat = osync_format_env_find_objformat(formatenv, value); - - /* Config info */ - env->device_addr = osync_anchor_retrieve(anchorpath, "EnvDeviceAddr"); - env->username = osync_anchor_retrieve(anchorpath, "EnvUsername"); - env->command = osync_anchor_retrieve(anchorpath, "EnvCommand"); - value = osync_anchor_retrieve(anchorpath, "EnvDevicePort"); - if (value) env->device_port = atoi(value); - value = osync_anchor_retrieve(anchorpath, "EnvUseSsh"); - if (value) env->use_ssh = atoi(value); - value = osync_anchor_retrieve(anchorpath, "EnvUseLocal"); - if (value) env->use_local = atoi(value); - value = osync_anchor_retrieve(anchorpath, "EnvUseRemote"); - if (value) env->use_remote = atoi(value); - env->calendar = osync_anchor_retrieve(anchorpath, "EnvCalendar"); - value = osync_anchor_retrieve(anchorpath, "EnvDebuglevel"); - if (value) env->debuglevel = atoi(value); - - g_free(anchorpath); - osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); -} - -/*! \brief Closes the connection to the databases - * - * \brief ctx The context of the plugin - */ -static void gpe_disconnect_internal(gpe_environment *env) -{ - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p)", __func__, env); - - if (env->client) { - gpesync_client_close (env->client); - env->client = NULL; - } - - osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); -} -static void gpe_disconnect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) -{ - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, data, info, ctx); - OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); - void *userdata = (sink_environment *)osync_objtype_sink_get_userdata(sink); - gpe_environment *env = ((sink_environment *)userdata)->gpe_env; - - gpe_disconnect_internal(env); - - //Answer the call - osync_context_report_success(ctx); - osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); -} - -/*! \brief Connects to the databases of GPE - * - * \param ctx The context of the plugin - */ -static void gpe_connect_internal(gpe_environment *env, char **client_err) -{ - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p)", __func__, env, client_err); - - // Do nothing if already connected - if (env->client) { - osync_trace(TRACE_INTERNAL, "GPE-SYNC %s: already connected", __func__); - } else { - if (env->use_local) { - env->client = gpesync_client_open_local(env->command, client_err); - } - else if (env->use_ssh) - { - gchar *path = g_strdup_printf ("%s@%s", env->username, env->device_addr); - env->client = gpesync_client_open_ssh (path, env->command, client_err); - } - else - env->client = gpesync_client_open (env->device_addr, env->device_port, client_err); - } - - osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); -} -static void gpe_connect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) -{ - char *client_err = NULL; - - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, data, info, ctx); - - // We need to get the context to load all our stuff. - OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); - void *userdata = (sink_environment *)osync_objtype_sink_get_userdata(sink); - gpe_environment *env = ((sink_environment *)userdata)->gpe_env; - - gpe_connect_internal(env, &client_err); - - if (env->client == NULL) { - osync_context_report_error(ctx, OSYNC_ERROR_NO_CONNECTION, client_err); - osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: connect failed: %s", __func__, client_err); - if (client_err) g_free(client_err); - return; - } - - // Set calendar name -- note that we checked that the version of gpesyncd supports - // setting the calendar name in the discovery phase - if (env->calendar) { - gchar *response = NULL; - gpesync_client_exec_printf(env->client, "path vevent %s", client_callback_string, &response, NULL, env->calendar); - if (strncmp(response, "OK", 2) != 0) { - osync_context_report_error(ctx, OSYNC_ERROR_MISCONFIGURATION, "calendar %s not found", - env->calendar); - osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: calendar %s not found", - __func__, env->calendar); - gpe_disconnect_internal(env); - g_free(response); - return; - } - g_free(response); - } - - osync_context_report_success(ctx); - - osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); -} - -/*! \brief This is called once all objects have been sent to the plugin - * - * \param ctx The context of the plugin - */ -static void sync_done(void *data, OSyncPluginInfo *info, OSyncContext *ctx) -{ - OSyncError *error = NULL; - - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, data, info, ctx); - OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); - void *userdata = (sink_environment *)osync_objtype_sink_get_userdata(sink); - gpe_environment *env = ((sink_environment *)userdata)->gpe_env; - - //If we use anchors we have to update it now. - - // Save hashtables - if (!osync_hashtable_save(env->contact_sink.hashtable, &error)) - goto error; - if (!osync_hashtable_save(env->todo_sink.hashtable, &error)) - goto error; - if (!osync_hashtable_save(env->calendar_sink.hashtable, &error)) - goto error; - - //Answer the call - osync_context_report_success(ctx); - osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); - return; - -error: - osync_context_report_osyncerror(ctx, error); - osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: %s", __func__, osync_error_print(&error)); - osync_error_unref(&error); -} - -static void free_sink(sink_environment *sinkenv) -{ - sinkenv->sink = NULL; - if (sinkenv->hashtable) osync_hashtable_unref(sinkenv->hashtable); - sinkenv->hashtable = NULL; -} - - -/*! \brief The counterpart to initialize - * - * \param data The data of the plugin (configuration, etc.) - */ -static void finalize(void *data) -{ - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p)", __func__, data); - gpe_environment *env = (gpe_environment *)data; - - //Free all stuff that you have allocated here. - g_free(env->username); - g_free(env->device_addr); - - if (env->client) - gpesync_client_close (env->client); - - free_sink(&env->contact_sink); - free_sink(&env->todo_sink); - free_sink(&env->calendar_sink); - free_sink(&env->main_sink); - - g_free(env); - osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); -} - /*! \brief Fetches the configuration data and validates it * * \param env The GPE plugin environment @@ -387,6 +152,8 @@ if (env->calendar) osync_trace(TRACE_INTERNAL, "GPE-SYNC %s: calendar = %d", __func__, env->calendar); } + env->configured = TRUE; + osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); return TRUE; @@ -394,73 +161,72 @@ return FALSE; } -/*! \brief Initializes the plugin (needed for opensync) +/*! \brief Closes the connection to the databases * - * \param member The member of the sync pair - * \param error If an error occurs it will be stored here + * \brief ctx The context of the plugin */ -static void *initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) +static void gpe_disconnect_internal(gpe_environment *env) { - const char *configdata = NULL; - - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, plugin, info, error); - - gpe_environment *env = osync_try_malloc0(sizeof(gpe_environment), error); - if (!env) - goto error; - - restore_environment(env, info); - - // Create the main sink (which handles connect & disconnect) - env->main_sink.sink = osync_objtype_main_sink_new(error); - if (!env->main_sink.sink) goto error_free_env; + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p)", __func__, env); + + if (env->client) { + gpesync_client_close (env->client); + env->client = NULL; + } - OSyncObjTypeSinkFunctions functions; - memset(&functions, 0, sizeof(functions)); - functions.connect = gpe_connect; - functions.disconnect = gpe_disconnect; - functions.sync_done = sync_done; - osync_objtype_sink_set_functions(env->main_sink.sink, functions, &env->main_sink); + osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); +} +static void gpe_disconnect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) +{ + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, data, info, ctx); + OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); + void *userdata = (sink_environment *)osync_objtype_sink_get_userdata(sink); + gpe_environment *env = ((sink_environment *)userdata)->gpe_env; + + gpe_disconnect_internal(env); - osync_plugin_info_set_main_sink(info, env->main_sink.sink); - env->main_sink.gpe_env = env; + //Answer the call + osync_context_report_success(ctx); + osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); +} - // Set up contact sink - if (!gpe_contacts_setup(&env->contact_sink, env, info, error)) - goto error_free_env; - - // Set up calendar sink - if (!gpe_calendar_setup(&env->calendar_sink, env, info, error)) - goto error_free_env; - - // Set up todo sink - if (!gpe_todo_setup(&env->todo_sink, env, info, error)) - goto error_free_env; +/*! \brief Connects to the databases of GPE + * + * \param ctx The context of the plugin + */ +static void gpe_connect_internal(gpe_environment *env, char **client_err) +{ + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p)", __func__, env, client_err); - // All done - osync_trace(TRACE_EXIT, "GPE-SYNC %s: %p", __func__, env); - return (void *)env; + // Do nothing if already connected + if (env->client) { + osync_trace(TRACE_INTERNAL, "GPE-SYNC %s: already connected", __func__); + } else { + if (env->use_local) { + env->client = gpesync_client_open_local(env->command, client_err); + } + else if (env->use_ssh) + { + gchar *path = g_strdup_printf ("%s@%s", env->username, env->device_addr); + env->client = gpesync_client_open_ssh (path, env->command, client_err); + } + else + env->client = gpesync_client_open (env->device_addr, env->device_port, client_err); + } -error_free_env: - finalize(env); -error: - osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: %s", __func__, osync_error_print(error)); - return NULL; + osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); } /* Here we actually tell opensync which sinks are available. */ -static osync_bool discover(void *data, OSyncPluginInfo *info, OSyncError **error) +static osync_bool gpe_discover_internal(gpe_environment *env, OSyncPluginInfo *info, OSyncError **error) { gchar *err_string = NULL; gchar *response = NULL; unsigned int v_major = 1, v_minor = 0, v_edit = 0; // Default version 1.0.0 - osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, data, info, error); - - gpe_environment *env = (gpe_environment *)data; + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, env, info, error); - // Get config - if (!gpe_parse_settings(env, info, error)) goto error; + if (!gpe_assert_error(env->configured && !env->discovered, error)) goto error; // Try to connect gpe_connect_internal(env, &err_string); @@ -491,16 +257,10 @@ goto error; } - gchar *version_string = g_strdup_printf("%d.%d.%d", v_major, v_minor, v_edit); - OSyncVersion *version = osync_version_new(error); - osync_version_set_plugin(version, "gpe-sync"); - //osync_version_set_modelversion(version, "version"); - //osync_version_set_firmwareversion(version, "firmwareversion"); - osync_version_set_softwareversion(version, version_string); - //osync_version_set_hardwareversion(version, "hardwareversion"); - osync_plugin_info_set_version(info, version); - osync_version_unref(version); - g_free(version_string); + env->v_major = v_major; + env->v_minor = v_minor; + env->v_edit = v_edit; + /* TODO: check these are the same versions which were reported at discovery time */ if (env->calendar) { // Calendar support requires at least version 1.2 @@ -523,7 +283,7 @@ } } - // Set objformats (could be dependent on version info in future) + // Work out formats for data received from peer (could be dependent on version info in future) OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); env->contact_sink.objformat = osync_format_env_find_objformat(formatenv, "vcard30"); @@ -547,6 +307,47 @@ goto error; } + env->discovered = TRUE; + + gpe_disconnect_internal(env); + + g_free(response); + osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); + return TRUE; + + error: + if (env->client) gpe_disconnect_internal(env); + if (err_string) g_free(err_string); + if (response) g_free(response); + return FALSE; + +} + +static osync_bool discover(OSyncPluginInfo *info, void *data, OSyncError **error) +{ + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, data, info, error); + + gpe_environment *env = (gpe_environment *)data; + + if (!gpe_assert_error(!env->configured && !env->discovered, error)) goto error; + + // Get config + if (!gpe_parse_settings(env, info, error)) goto error; + + // Do discovery + if (!gpe_discover_internal(env, info, error)) goto error; + + gchar *version_string = g_strdup_printf("%d.%d.%d", env->v_major, env->v_minor, env->v_edit); + OSyncVersion *version = osync_version_new(error); + osync_version_set_plugin(version, "gpe-sync"); + //osync_version_set_modelversion(version, "version"); + //osync_version_set_firmwareversion(version, "firmwareversion"); + osync_version_set_softwareversion(version, version_string); + //osync_version_set_hardwareversion(version, "hardwareversion"); + osync_plugin_info_set_version(info, version); + osync_version_unref(version); + g_free(version_string); + // Report available sinks... // GPE always supports contacts, todos and events if (env->contact_sink.sink) osync_objtype_sink_set_available(env->contact_sink.sink, TRUE); @@ -554,22 +355,199 @@ if (env->calendar_sink.sink) osync_objtype_sink_set_available(env->calendar_sink.sink, TRUE); // One day we may add notes... - gpe_disconnect_internal(env); - - save_environment(env, info); + if (!gpe_assert_error(env->configured && env->discovered, error)) goto error; - g_free(response); osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); return TRUE; error: - if (env->client) gpe_disconnect_internal(env); - if (err_string) g_free(err_string); - if (response) g_free(response); return FALSE; } +static void gpe_connect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) +{ + char *client_err = NULL; + OSyncError *error = NULL; + + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, data, info, ctx); + + // We need to get the context to load all our stuff. + OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); + void *userdata = (sink_environment *)osync_objtype_sink_get_userdata(sink); + gpe_environment *env = ((sink_environment *)userdata)->gpe_env; + + /* Re-parse and re-discover */ + if ( + !gpe_assert_error(!env->configured && !env->discovered, &error) || + !gpe_parse_settings(env, info, &error) || + !gpe_discover_internal(env, info, &error) || + !gpe_assert_error(env->configured && env->discovered, &error) + ) { + osync_context_report_osyncerror(ctx, error); + client_err = osync_error_print_stack(&error); + osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: connect failed: %s", __func__, client_err); + if (client_err) g_free(client_err); + osync_error_unref(&error); + return; + } + + gpe_connect_internal(env, &client_err); + + if (env->client == NULL) { + osync_context_report_error(ctx, OSYNC_ERROR_NO_CONNECTION, client_err); + osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: connect failed: %s", __func__, client_err); + if (client_err) g_free(client_err); + return; + } + + // Set calendar name -- note that we checked that the version of gpesyncd supports + // setting the calendar name in the discovery phase + if (env->calendar) { + gchar *response = NULL; + gpesync_client_exec_printf(env->client, "path vevent %s", client_callback_string, &response, NULL, env->calendar); + if (strncmp(response, "OK", 2) != 0) { + osync_context_report_error(ctx, OSYNC_ERROR_MISCONFIGURATION, "calendar %s not found", + env->calendar); + osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: calendar %s not found", + __func__, env->calendar); + gpe_disconnect_internal(env); + g_free(response); + return; + } + g_free(response); + } + + osync_context_report_success(ctx); + + osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); +} + +/*! \brief This is called once all objects have been sent to the plugin + * + * \param ctx The context of the plugin + */ +static void sync_done(void *data, OSyncPluginInfo *info, OSyncContext *ctx) +{ + OSyncError *error = NULL; + + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, data, info, ctx); + OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); + void *userdata = (sink_environment *)osync_objtype_sink_get_userdata(sink); + gpe_environment *env = ((sink_environment *)userdata)->gpe_env; + + if (!gpe_assert(env->configured && env->discovered)) { + osync_trace(TRACE_ERROR, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered ); + osync_context_report_error (ctx, OSYNC_ERROR_GENERIC, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered); + return; + } + + //If we use anchors we have to update it now. + + // Save hashtables + if (!osync_hashtable_save(env->contact_sink.hashtable, &error)) + goto error; + if (!osync_hashtable_save(env->todo_sink.hashtable, &error)) + goto error; + if (!osync_hashtable_save(env->calendar_sink.hashtable, &error)) + goto error; + + //Answer the call + osync_context_report_success(ctx); + osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); + return; + +error: + osync_context_report_osyncerror(ctx, error); + osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: %s", __func__, osync_error_print(&error)); + osync_error_unref(&error); +} + +static void free_sink(sink_environment *sinkenv) +{ + sinkenv->sink = NULL; + if (sinkenv->hashtable) osync_hashtable_unref(sinkenv->hashtable); + sinkenv->hashtable = NULL; +} + + +/*! \brief The counterpart to initialize + * + * \param data The data of the plugin (configuration, etc.) + */ +static void finalize(void *data) +{ + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p)", __func__, data); + gpe_environment *env = (gpe_environment *)data; + + //Free all stuff that you have allocated here. + g_free(env->username); + g_free(env->device_addr); + + if (env->client) + gpesync_client_close (env->client); + + free_sink(&env->contact_sink); + free_sink(&env->todo_sink); + free_sink(&env->calendar_sink); + free_sink(&env->main_sink); + + g_free(env); + osync_trace(TRACE_EXIT, "GPE-SYNC %s", __func__); +} + +/*! \brief Initializes the plugin (needed for opensync) + * + * \param member The member of the sync pair + * \param error If an error occurs it will be stored here + */ +static void *initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) +{ + const char *configdata = NULL; + + osync_trace(TRACE_ENTRY, "GPE-SYNC %s(%p, %p, %p)", __func__, plugin, info, error); + + gpe_environment *env = osync_try_malloc0(sizeof(gpe_environment), error); + if (!env) + goto error; + + // Create the main sink (which handles connect & disconnect) + env->main_sink.sink = osync_objtype_main_sink_new(error); + if (!env->main_sink.sink) goto error_free_env; + + OSyncObjTypeSinkFunctions functions; + memset(&functions, 0, sizeof(functions)); + functions.connect = gpe_connect; + functions.disconnect = gpe_disconnect; + functions.sync_done = sync_done; + osync_objtype_sink_set_functions(env->main_sink.sink, functions, &env->main_sink); + + osync_plugin_info_set_main_sink(info, env->main_sink.sink); + env->main_sink.gpe_env = env; + + // Set up contact sink + if (!gpe_contacts_setup(&env->contact_sink, env, info, error)) + goto error_free_env; + + // Set up calendar sink + if (!gpe_calendar_setup(&env->calendar_sink, env, info, error)) + goto error_free_env; + + // Set up todo sink + if (!gpe_todo_setup(&env->todo_sink, env, info, error)) + goto error_free_env; + + // All done + osync_trace(TRACE_EXIT, "GPE-SYNC %s: %p", __func__, env); + return (void *)env; + +error_free_env: + finalize(env); +error: + osync_trace(TRACE_EXIT_ERROR, "GPE-SYNC %s: %s", __func__, osync_error_print(error)); + return NULL; +} + /*! \brief This function has to be in every opensync plugin * * \brief env The environment of the plugin containing basic Modified: plugins/gpe/src/gpe_sync.h ============================================================================== --- plugins/gpe/src/gpe_sync.h Tue Jan 13 23:59:59 2009 (r5135) +++ plugins/gpe/src/gpe_sync.h Wed Jan 14 00:48:41 2009 (r5136) @@ -63,9 +63,18 @@ int use_ssh; int use_local; int use_remote; - char *calendar; // Name of GPE calendar to use or NULL + const char *calendar; // Name of GPE calendar to use or NULL int debuglevel; + + /* Peer information */ + int v_major; + int v_minor; + int v_edit; + + /* Status */ + int configured; /* Configuration has been parsed */ + int discovered; /* Discovery has happened */ } gpe_environment; #include "utils.h" @@ -91,4 +100,12 @@ #define MIN_PROTOCOL_MAJOR 1 #define MIN_PROTOCOL_MINOR 0 +#ifndef NDEBUG +#define gpe_assert(x) ( (x) ? TRUE : ( fprintf(stderr, "%s:%i:E:%s: Assertion \"" #x "\" failed\n", __FILE__, __LINE__, __func__), abort(), FALSE ) ) +#else +#define gpe_assert(x) (x) +#endif + +#define gpe_assert_error(x, e) ( gpe_assert(x) ? TRUE : ( osync_error_set((e), OSYNC_ERROR_GENERIC, "%s:%i:E:%s: Assertion \"" #x "\" failed\n", __FILE__, __LINE__, __func__) , FALSE ) ) + #endif Modified: plugins/gpe/src/todo.c ============================================================================== --- plugins/gpe/src/todo.c Tue Jan 13 23:59:59 2009 (r5135) +++ plugins/gpe/src/todo.c Wed Jan 14 00:48:41 2009 (r5136) @@ -39,6 +39,12 @@ char *error = NULL; char *data_ptr; unsigned int data_size; + + if (!gpe_assert(env->configured && env->discovered)) { + osync_trace(TRACE_ERROR, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered ); + osync_context_report_error (ctx, OSYNC_ERROR_GENERIC, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered); + return; + } switch (osync_change_get_changetype (change)) { case OSYNC_CHANGE_TYPE_DELETED: @@ -116,6 +122,12 @@ gpe_environment *env = (gpe_environment *)userdata; sink_environment *sinkenv = (sink_environment *)osync_objtype_sink_get_userdata(osync_plugin_info_get_sink(info)); + if (!gpe_assert(env->configured && env->discovered)) { + osync_trace(TRACE_ERROR, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered ); + osync_context_report_error (ctx, OSYNC_ERROR_GENERIC, "GPE plugin not initialised: configured = %d, discovered = %d", env->configured, env->discovered); + return; + } + if (osync_objtype_sink_get_slowsync(sinkenv->sink)) { osync_trace(TRACE_INTERNAL, "Slow sync requested"); if (!osync_hashtable_slowsync(sinkenv->hashtable, &error)) { |