osync_bool osync_queue_is_alive(OSyncQueue *queue)
{
  OSyncMessage *message = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, queue);
	
  // FIXME
  /*if (!osync_queue_connect(queue, O_WRONLY | O_NONBLOCK, NULL)) {
    osync_trace(TRACE_EXIT_ERROR, "%s: Unable to connect", __func__);
    return FALSE;
    }*/
	
  message = osync_message_new(OSYNC_MESSAGE_NOOP, 0, NULL);
  if (!message) {
    osync_trace(TRACE_EXIT_ERROR, "%s: Unable to create new message", __func__);
    return FALSE;
  }
	
  if (!osync_queue_send_message(queue, NULL, message, NULL)) {
    osync_trace(TRACE_EXIT, "%s: Not alive", __func__);
    return FALSE;
  }
	
  osync_queue_disconnect(queue, NULL);
	
  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;
}
OSyncSinkEngine *osync_sink_engine_new(int position, OSyncClientProxy *proxy, OSyncObjEngine *objengine, OSyncError **error)
{
    OSyncSinkEngine *sinkengine = NULL;
    osync_trace(TRACE_ENTRY, "%s(%i, %p, %p, %p)", __func__, position, proxy, objengine, error);
    osync_assert(proxy);
    osync_assert(objengine);

    sinkengine = osync_try_malloc0(sizeof(OSyncSinkEngine), error);
    if (!sinkengine)
        goto error;
    sinkengine->ref_count = 1;
    sinkengine->position = position;

    /* we dont reference the proxy to avoid circular dependencies. This object is completely
     * dependent on the proxy anyways */
    sinkengine->proxy = proxy;

    sinkengine->engine = objengine;
    osync_obj_engine_ref(objengine);

    osync_trace(TRACE_EXIT, "%s: %p", __func__, sinkengine);
    return sinkengine;

error:
    osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
    return NULL;
}
osync_bool osync_mapping_engine_supports_ignore(OSyncMappingEngine *engine)
{
  OSyncObjEngine *parent = NULL;
  osync_bool ignore_supported = TRUE;
  GList *s = NULL;

  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, engine);
  osync_assert(engine);

  parent = engine->parent;
  for (s = parent->sink_engines; s; s = s->next) {
    OSyncSinkEngine *sink_engine = s->data;
		
    OSyncMember *member = osync_client_proxy_get_member(sink_engine->proxy);
    OSyncMappingEntryEngine *entry_engine = osync_mapping_engine_get_entry(engine, sink_engine);

    /* check if mapping could be solved by "ignore" conflict handler */
    const char *objtype = entry_engine->sink_engine->engine->objtype;
    OSyncObjTypeSink *objtype_sink = osync_member_find_objtype_sink(member, objtype);

    /* if there is no sink read function, ignore is not support for this mapping. */
    if (!objtype_sink || !osync_objtype_sink_get_function_read(objtype_sink))
      ignore_supported = FALSE; 

  }
	
  osync_trace(TRACE_EXIT, "%s: conflict handler ignore supported: %s", __func__, ignore_supported ? "TRUE" : "FALSE");
  return ignore_supported;
}
static void _osync_obj_engine_connect_callback(OSyncClientProxy *proxy, void *userdata, osync_bool slowsync, OSyncError *error)
{
  OSyncSinkEngine *sinkengine = userdata;
  OSyncObjEngine *engine = sinkengine->engine;
  OSyncError *locerror = NULL;
	
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, proxy, userdata, slowsync, error);
	
  if (error) {
    osync_trace(TRACE_INTERNAL, "Obj Engine received connect error: %s", osync_error_print(&error));
    osync_obj_engine_set_error(engine, error);
    engine->sink_errors = engine->sink_errors | (0x1 << sinkengine->position);
    osync_status_update_member(engine->parent, osync_client_proxy_get_member(proxy), OSYNC_CLIENT_EVENT_ERROR, engine->objtype, error);
  } else {
    engine->sink_connects = engine->sink_connects | (0x1 << sinkengine->position);
    osync_status_update_member(engine->parent, osync_client_proxy_get_member(proxy), OSYNC_CLIENT_EVENT_CONNECTED, engine->objtype, NULL);
  }

  if (slowsync) {
    osync_obj_engine_set_slowsync(engine, TRUE);
    osync_trace(TRACE_INTERNAL, "SlowSync requested during connect.");
  }
			
  if (osync_bitcount(engine->sink_errors | engine->sink_connects) == g_list_length(engine->sink_engines)) {
    if (osync_bitcount(engine->sink_errors)) {
      osync_error_set(&locerror, OSYNC_ERROR_GENERIC, "At least one sink_engine failed while connecting");
      osync_obj_engine_set_error(engine, locerror);
    }

    osync_obj_engine_event(engine, OSYNC_ENGINE_EVENT_CONNECTED, locerror ? locerror : error);
  } else
    osync_trace(TRACE_INTERNAL, "Not yet: %i", osync_bitcount(engine->sink_errors | engine->sink_connects));
	
  osync_trace(TRACE_EXIT, "%s", __func__);
}
void osync_status_update_change(OSyncEngine *engine, OSyncChange *change, OSyncMember *member, OSyncMapping *mapping, OSyncChangeEvent type, OSyncError *error)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %i, %p)", __func__, engine, change, member, mapping, type, error);
	
	if (engine->changestat_callback) {
		OSyncChangeUpdate *update = g_malloc0(sizeof(OSyncChangeUpdate));
		if (!update)
			return;
		
		update->type = type;
		
		update->change = change;
		osync_change_ref(change);
		
		update->member = member;
		osync_member_ref(member);
		
		update->error = error;
		osync_error_ref(&error);
		
		engine->changestat_callback(update, engine->changestat_userdata);
		
		osync_status_free_change_update(update);
	} else
		osync_trace(TRACE_INTERNAL, "Status Update Ignored");
		
	osync_trace(TRACE_EXIT, "%s", __func__);
}
osync_bool osync_obj_engine_map_changes(OSyncObjEngine *engine, OSyncError **error)
{
  OSyncMappingEngine *mapping_engine = NULL;
  GList *new_mappings = NULL, *v = NULL;
	
  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, engine);
  //osync_trace_disable();

  /* Go through all sink engines that are available */
  for (v = engine->sink_engines; v; v = v->next) {
    OSyncSinkEngine *sinkengine = v->data;
		
    /* We use a temp list to speed things up. We dont have to compare with newly created mappings for
     * the current sinkengine, since there will be only one entry (for the current sinkengine) so there
     * is no need to compare */
    new_mappings = NULL;
		
    /* For each sinkengine, go through all unmapped changes */
    while (sinkengine->unmapped) {
      OSyncChange *change = sinkengine->unmapped->data;
      OSyncConvCmpResult result = 0;
      OSyncMappingEntryEngine *entry_engine = NULL;
			
      osync_trace(TRACE_INTERNAL, "Looking for mapping for change %s, changetype %i from member %lli", osync_change_get_uid(change), osync_change_get_changetype(change), osync_member_get_id(osync_client_proxy_get_member(sinkengine->proxy)));
	
      /* See if there is an exisiting mapping, which fits the unmapped change */
      result = _osync_obj_engine_mapping_find(engine, change, sinkengine, &mapping_engine);
      if (result == OSYNC_CONV_DATA_MISMATCH) {
        /* If there is none, create one */
        mapping_engine = _osync_obj_engine_create_mapping_engine(engine, error);
        if (!mapping_engine)
          goto error;
				
        osync_trace(TRACE_INTERNAL, "Unable to find mapping. Creating new mapping with id %lli", osync_mapping_get_id(mapping_engine->mapping));
				
        new_mappings = g_list_append(new_mappings, mapping_engine);
      } else if (result == OSYNC_CONV_DATA_SIMILAR) {
        mapping_engine->conflict = TRUE;
      }
      /* Update the entry which belongs to our sinkengine with the the change */
      entry_engine = osync_mapping_engine_get_entry(mapping_engine, sinkengine);
      osync_assert(entry_engine);
			
      osync_entry_engine_update(entry_engine, change);
      sinkengine->unmapped = g_list_remove(sinkengine->unmapped, sinkengine->unmapped->data);
      osync_change_unref(change);
    }
		
    engine->mapping_engines = g_list_concat(engine->mapping_engines, new_mappings);
  }
	
  //osync_trace_enable();
  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;

 error:
  osync_trace_enable();
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return FALSE;
}
static void _osync_obj_engine_sync_done_callback(OSyncClientProxy *proxy, void *userdata, OSyncError *error)
{
  OSyncSinkEngine *sinkengine = userdata;
  OSyncObjEngine *engine = sinkengine->engine;
  OSyncError *locerror = NULL;
	
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, proxy, userdata, error);
	
  if (error) {
    osync_obj_engine_set_error(engine, error);
    engine->sink_errors = engine->sink_errors | (0x1 << sinkengine->position);
    osync_status_update_member(engine->parent, osync_client_proxy_get_member(proxy), OSYNC_CLIENT_EVENT_ERROR, engine->objtype, error);
  } else {
    engine->sink_sync_done = engine->sink_sync_done | (0x1 << sinkengine->position);
    osync_status_update_member(engine->parent, osync_client_proxy_get_member(proxy), OSYNC_CLIENT_EVENT_SYNC_DONE, engine->objtype, NULL);
  }
			
  if (osync_bitcount(engine->sink_errors | engine->sink_sync_done) == g_list_length(engine->sink_engines)) {
    if (osync_bitcount(engine->sink_sync_done) < osync_bitcount(engine->sink_connects)) {
      osync_error_set(&locerror, OSYNC_ERROR_GENERIC, "Fewer sink_engines reported sync_done than connected");
      osync_obj_engine_set_error(engine, locerror);
    }

    osync_obj_engine_event(engine, OSYNC_ENGINE_EVENT_SYNC_DONE, locerror ? locerror : error);
  } else
    osync_trace(TRACE_INTERNAL, "Not yet: %i", osync_bitcount(engine->sink_errors | engine->sink_sync_done));
	
  osync_trace(TRACE_EXIT, "%s", __func__);
}
Example #8
0
void check_mapping(OSyncMappingTable *maptable, int memberid, int mappingid, unsigned int numentries, const char *uid)
{
	unsigned int i = 0;
	osync_trace(TRACE_ENTRY, "%s(%p, %i, %i, %i, %s)", __func__, maptable, memberid, mappingid, numentries, uid);
	
	for (i = 0; i < osync_mapping_table_num_mappings(maptable); i++) {
		OSyncMapping *mapping = osync_mapping_table_nth_mapping(maptable, i);
		OSyncMappingEntry *testentry = osync_mapping_find_entry_by_member_id(mapping, memberid);
		if (testentry) {
			if ((mappingid != -1 && osync_mapping_get_id(mapping) == mappingid) || (mappingid == -1 && !strcmp(osync_mapping_entry_get_uid(testentry), uid))) {
				unsigned int n = 0;
				fail_unless(osync_mapping_num_entries(mapping) == numentries);
				for (n = 0; n < osync_mapping_num_entries(mapping); n++) {
					OSyncMappingEntry *entry = osync_mapping_nth_entry(mapping, n);
					if (osync_mapping_entry_get_member_id(entry) == memberid) {
						fail_unless(!strcmp(osync_mapping_entry_get_uid(entry), uid), NULL);
						goto out;
					}
				}
				fail(NULL);
			}
		}
	}
	fail(NULL);

out:
	osync_trace(TRACE_EXIT, "%s", __func__);
}
osync_bool osync_module_load(OSyncModule *module, const char *path, OSyncError **error)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, module, path, error);
	osync_assert(module);
	osync_assert(!module->module);
	
	if (!g_module_supported()) {
		osync_error_set(error, OSYNC_ERROR_GENERIC, "This platform does not support loading of modules");
		goto error;
	}

	/* Try to open the module or fail if an error occurs.
	 *
	 * Do local bind to avoid symbol-clashing - i.e. plugins having the same
	 * functions name - e.g. finalize().
	 *
	 * Don't do lazy binding, otherwise symbols of kdepim-sync can't get loaded.
	 * Related to C++ and dlopen?
	 */
	module->module = g_module_open(path, G_MODULE_BIND_LOCAL);
	if (!module->module) {
		osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to open module %s: %s", path, g_module_error());
		goto error;
	}
	
	module->path = osync_strdup(path);
	
	osync_trace(TRACE_EXIT, "%s", __func__);
	return TRUE;

 error:
	osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
	return FALSE;
}
Example #10
0
static osync_bool demarshal_file(OSyncMarshal *marshal, char **output, unsigned int *outpsize, void *user_data, OSyncError **error)
{
	OSyncFileFormat *file = NULL;
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, marshal, output, outpsize, error);

	file = osync_try_malloc0(sizeof(OSyncFileFormat), error);
	if (!file)
		goto error;

	if (!osync_marshal_read_string(marshal, &(file->path), error))
		goto error;

	if (!osync_marshal_read_buffer(marshal, (void *)&(file->data), &(file->size), error))
		goto error;

	*output = (char *)file;
	*outpsize = sizeof(OSyncFileFormat);

	osync_trace(TRACE_EXIT, "%s", __func__);
	return TRUE;

error:

	osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
	return FALSE;
}
Example #11
0
OSyncMappingTable *mappingtable_load(const char *path, const char *objtype, unsigned int num_mappings)
{
	OSyncError *error = NULL;
	OSyncMappingTable *table = NULL;
	OSyncArchive *archive = NULL;

	osync_trace(TRACE_ENTRY, "%s(%s, %s, %i)", __func__, path, objtype, num_mappings);
	
	table = osync_mapping_table_new(&error);
	fail_unless(table != NULL, NULL);
	fail_unless(error == NULL, NULL);
	
	archive = osync_archive_new(path, &error);
	fail_unless(archive != NULL, NULL);
	fail_unless(error == NULL, NULL);
	
	fail_unless(osync_mapping_table_load(table, archive, objtype, &error), NULL);
	fail_unless(error == NULL, NULL);
	
	osync_archive_unref(archive);
	
	fail_unless(osync_mapping_table_num_mappings(table) == num_mappings, NULL);
	
	osync_trace(TRACE_EXIT, "%s: %p", __func__, table);
	return table;
}
/*! @brief Sets the queue to use the gmainloop with the given context
 * 
 * This function will attach the OSyncQueue as a source to the given context.
 * The queue will then be check for new messages and the messages will be
 * handled.
 * 
 * @param queue The queue to set up
 * @param context The context to use. NULL for default loop
 * 
 */
void osync_queue_setup_with_gmainloop(OSyncQueue *queue, GMainContext *context)
{
  OSyncQueue **queueptr = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, queue, context);
	
  queue->incoming_functions = g_malloc0(sizeof(GSourceFuncs));
  queue->incoming_functions->prepare = _incoming_prepare;
  queue->incoming_functions->check = _incoming_check;
  queue->incoming_functions->dispatch = _incoming_dispatch;
  queue->incoming_functions->finalize = NULL;

  queue->incoming_source = g_source_new(queue->incoming_functions, sizeof(GSource) + sizeof(OSyncQueue *));
  queueptr = (OSyncQueue **)(queue->incoming_source + 1);
  *queueptr = queue;
  g_source_set_callback(queue->incoming_source, NULL, queue, NULL);
  g_source_attach(queue->incoming_source, context);
  queue->incomingContext = context;
  // For the source
  if (context)
    g_main_context_ref(context);
	
  //To unref it later
  if (context)
    g_main_context_ref(context);
	
  osync_trace(TRACE_EXIT, "%s", __func__);
}
/* Creates anonymous pipes which dont have to be created and are automatically connected.
 * 
 * Lets assume parent wants to send, child wants to receive
 * 
 * osync_queue_new_pipes()
 * fork()
 * 
 * Parent:
 * connect(write_queue)
 * disconnect(read_queue)
 * 
 * Child:
 * connect(read_queue)
 * close(write_queue)
 * 
 * 
 *  */
osync_bool osync_queue_new_pipes(OSyncQueue **read_queue, OSyncQueue **write_queue, OSyncError **error)
{
#ifdef _WIN32
  return FALSE;
#else
  int filedes[2];
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, read_queue, write_queue, error);
	
  if (pipe(filedes) < 0) {
    osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to create pipes");
    goto error;
  }
	
  *read_queue = osync_queue_new_from_fd(filedes[0], error);
  if (!*read_queue)
    goto error_close_pipes;
	
  *write_queue = osync_queue_new_from_fd(filedes[1], error);
  if (!*write_queue)
    goto error_free_read_queue;
	
  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;

 error_free_read_queue:
  osync_queue_free(*read_queue);
 error_close_pipes:
  close(filedes[0]);
  close(filedes[1]);
 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return FALSE;
#endif
}
OSyncQueue *osync_queue_new(const char *name, OSyncError **error)
{
  OSyncQueue *queue = NULL;
  osync_trace(TRACE_ENTRY, "%s(%s, %p)", __func__, name, error);
	
  queue = osync_try_malloc0(sizeof(OSyncQueue), error);
  if (!queue)
    goto error;
	
  if (name)
    queue->name = g_strdup(name);
  queue->fd = -1;
	
  if (!g_thread_supported ())
    g_thread_init (NULL);
	
  queue->pendingLock = g_mutex_new();
	
  queue->context = g_main_context_new();
	
  queue->outgoing = g_async_queue_new();
  queue->incoming = g_async_queue_new();

  queue->disconnectLock = g_mutex_new();

  osync_trace(TRACE_EXIT, "%s: %p", __func__, queue);
  return queue;

 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return NULL;
}
Example #15
0
double check_sync(OSyncEngine *engine, const char *name, int num)
{
	int ret;
	printf(".");
	fflush(stdout);
	starttime = _second();
	osync_trace(TRACE_INTERNAL, "++++++++++++++++ Test \"%s %i\" starting ++++++++++++++", name, num);
	osengine_set_enginestatus_callback(engine, engine_status, NULL);
	sync_now(engine);
	osengine_set_enginestatus_callback(engine, NULL, NULL);
	int wasted = 0;
	int alldeciders = 0;
	osengine_get_wasted(engine, &alldeciders, &wasted);
	osync_trace(TRACE_INTERNAL, "++++++++++++++++ Test \"%s %i\" ended (%i / %i (%i%%)) ++++++++++++++", name, num, wasted, alldeciders, (int)(((float)wasted / (float)alldeciders) * 100));
	double thistime = _second() - starttime;

	printf(".");
	fflush(stdout);

	char *tempdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir());
	if (!mkdtemp(tempdir))
	{
		g_free(tempdir);
		osync_trace(TRACE_INTERNAL, "unable to create temporary dir: %s", g_strerror(errno));
		abort();
	}
	char *command = g_strdup_printf("mv %s/* %s &> /dev/null", localdir, tempdir);
	ret = system(command);
	if (ret)
	{
		g_free(tempdir);
		g_free(command);
		osync_trace(TRACE_INTERNAL, "Unable to move files to temporary dir: %d", ret);
		abort();
	}
	g_free(command);
	printf(".");
	fflush(stdout);

	check_empty();

	printf(".");
	fflush(stdout);

	osync_group_set_slow_sync(engine->group, "data", TRUE);

	sync_now(engine);
	printf(".");
	fflush(stdout);
	command = g_strdup_printf("test \"x$(diff -x \".*\" %s %s)\" = \"x\"", localdir, tempdir);
	int result = system(command);
	g_free(command);

	g_free(tempdir);
	if (result)
		abort();

	printf(" success\n");
	return thistime;
}
osync_bool osync_capabilities_save(OSyncCapabilities *capabilities, const char *file, OSyncError **error)
{
	unsigned int size;
	char *buffer;
	osync_bool ret;

	osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, capabilities, __NULLSTR(file), error);

	osync_assert(capabilities);
	osync_assert(file);

	osync_capabilities_sort(capabilities);

	ret = osync_capabilities_assemble(capabilities, &buffer, &size, error);
	if (!ret)
		goto error;

	ret = osync_file_write(file, buffer, size, 0600, error);
	osync_free(buffer);

	if (!ret)
		goto error;
	
	osync_trace(TRACE_EXIT, "%s", __func__);
	return TRUE;

error:	
	osync_trace(TRACE_EXIT_ERROR, "%s: %s" , __func__, osync_error_print(error));
	return FALSE;
}
void osync_obj_engine_event(OSyncObjEngine *engine, OSyncEngineEvent event, OSyncError *error)
{
  osync_trace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, engine, event, error);
  osync_assert(engine);

  /* TODO: Create own enum OSyncObjEngine for objengine events. */
  osync_assert_msg(event != OSYNC_ENGINE_EVENT_ERROR, "OSyncObjEngine isn't supposed to emit OSYNC_ENGINE_EVENT_ERROR events!");
	
  /* engine event callback gets called with most recent OSyncError or NULL.
     Don't use engine->error for the engine event callback. Previous appears errors
     in this objengine would get passed to this engine, which will be interpeted by the
     engine as error for the current event.

     Example:
	   
     EVENT_CONNECTED		(obj)engine->error: NULL
     EVENT_READ **ERROR**		(obj)engine->error: 0x....
     # OSyncEngine aborts sync and emit disconnect event, we reply with:
     EVENT_DISCONNECTED		(obj)engine->error: 0x.....

     If we would pass in this case enigne->error instead of the most recent
     OSyncError, OSyncEngien would interpret this as the disconnect failed as well.
     So we just pass the most recent OSyncError pointer, which could be NULL -> no error.
  */
	     
  engine->callback(engine, event, error, engine->callback_userdata);

  osync_trace(TRACE_EXIT, "%s", __func__);
  return;
}
OSyncCapabilities *osync_capabilities_load(const char *file, OSyncError **error)
{
	unsigned int size;
	char *buffer;
	OSyncCapabilities *capabilities;
	osync_bool b;

	osync_trace(TRACE_ENTRY, "%s(%s, %p)", __func__, file, error);
	osync_assert(file);
	
	b = osync_file_read(file, &buffer, &size, error);
	if(!b) {
		osync_trace(TRACE_EXIT_ERROR, "%s: %s" , __func__, osync_error_print(error));
		return NULL;
	}
	
	capabilities = osync_capabilities_parse(buffer, size, error);
	osync_free(buffer);
	if(!capabilities) {
		osync_trace(TRACE_EXIT_ERROR, "%s: %s" , __func__, osync_error_print(error));
		return NULL;
	}

	osync_trace(TRACE_EXIT, "%s: %p", __func__, capabilities);
	return capabilities;
}
static void _osync_obj_engine_commit_change_callback(OSyncClientProxy *proxy, void *userdata, const char *uid, OSyncError *error)
{
  OSyncMappingEntryEngine *entry_engine = userdata;
  OSyncObjEngine *engine = entry_engine->objengine;
  OSyncSinkEngine *sinkengine = entry_engine->sink_engine;
  OSyncError *locerror = NULL;
  OSyncMapping *mapping = NULL;
  OSyncMember *member = NULL;
  OSyncMappingEntry *entry = NULL;
  const char *objtype = NULL;
  long long int id = 0;

	
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %s, %p)", __func__, proxy, userdata, uid, error);
	
  osync_entry_engine_set_dirty(entry_engine, FALSE);
	
  mapping = entry_engine->mapping_engine->mapping;
  member = osync_client_proxy_get_member(proxy);
  entry = entry_engine->entry;
  objtype = osync_change_get_objtype(entry_engine->change);
  id = osync_mapping_entry_get_id(entry);
	
  if (error) {
    /* Error handling (tests: single_commit_error, ...) */

    /* TODO: Review differences between Mapping and Change status events - Are both really needed?! */
    osync_status_update_change(engine->parent, entry_engine->change, osync_client_proxy_get_member(proxy), entry_engine->mapping_engine->mapping, OSYNC_CHANGE_EVENT_ERROR, error);
    osync_status_update_mapping(engine->parent, entry_engine->mapping_engine, OSYNC_MAPPING_EVENT_ERROR, error);

    osync_obj_engine_set_error(engine, error);
    engine->sink_errors = engine->sink_errors | (0x1 << sinkengine->position);
    goto error;
  }
	
  if (uid)
    osync_change_set_uid(entry_engine->change, uid);
	
  if (engine->archive) {
    if (osync_change_get_changetype(entry_engine->change) == OSYNC_CHANGE_TYPE_DELETED) {
      /* TODO error handling */
      osync_archive_delete_change(engine->archive, id, objtype, &locerror);
    } else {

      /* TODO error handling */
      osync_archive_save_change(engine->archive, id, osync_change_get_uid(entry_engine->change), objtype, osync_mapping_get_id(mapping), osync_member_get_id(member), &locerror);
    }
  }

  osync_assert(entry_engine->mapping_engine);
  osync_status_update_change(engine->parent, entry_engine->change, osync_client_proxy_get_member(proxy), entry_engine->mapping_engine->mapping, OSYNC_CHANGE_EVENT_WRITTEN, NULL);
  osync_entry_engine_update(entry_engine, NULL);
	
  osync_trace(TRACE_EXIT, "%s", __func__);
  return;

 error:	
  _osync_obj_engine_generate_written_event(engine, error);
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error));
}
OSyncCapabilitiesObjType *osync_capabilities_add_new_objtype(OSyncCapabilities *capabilities, const char *objtype, OSyncError **error)
{
	OSyncCapabilitiesObjType *capsobjtype = NULL;
	osync_trace(TRACE_ENTRY, "%s: %p %p", __func__, capabilities, objtype);

	osync_assert(capabilities);
	osync_assert(objtype);

	capsobjtype = osync_capabilities_objtype_new(objtype, error);
	if (!capsobjtype)
		goto error;

	osync_capabilities_add_objtype(capabilities, capsobjtype);
	osync_capabilities_objtype_unref(capsobjtype);

	osync_trace(TRACE_EXIT, "%s: %p", __func__, capsobjtype);
	return capsobjtype;

error:
	if (capsobjtype)
		osync_capabilities_objtype_unref(capsobjtype);

	osync_trace(TRACE_EXIT, "%s: %s", __func__, osync_error_print(error));
	return NULL;
}
static osync_bool _inject_changelog_entries(OSyncObjEngine *engine, OSyncError **error) {
  OSyncList *ids = NULL;
  OSyncList *changetypes = NULL;
  OSyncList *j = NULL, *t = NULL;

  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, engine);

  osync_assert(engine);
  osync_assert(engine->archive);
  osync_assert(engine->objtype);
	
  if (!osync_archive_load_ignored_conflicts(engine->archive, engine->objtype, &ids, &changetypes, error)) {
    osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
    return FALSE;
  }

  t = changetypes;
  for (j = ids; j; j = j->next) {
    long long int id = (long long int)GPOINTER_TO_INT(j->data);

    OSyncMapping *ignored_mapping = osync_mapping_table_find_mapping(engine->mapping_table, id);

    GList *e;
    for (e = engine->mapping_engines; e; e = e->next) {
      OSyncMappingEngine *mapping_engine = e->data;

      if (mapping_engine->mapping == ignored_mapping) {
        GList *m;
        for (m = mapping_engine->entries; m; m = m->next) {
          OSyncMappingEntryEngine *entry = m->data;
          OSyncChangeType changetype = (OSyncChangeType) t->data;
          OSyncChange *ignored_change = osync_change_new(error);
          OSyncObjFormat *dummyformat = NULL;
          OSyncData *data = NULL;

          osync_change_set_changetype(ignored_change, changetype); 
          osync_entry_engine_update(entry, ignored_change);

          dummyformat = osync_objformat_new("plain", engine->objtype, NULL);
          data = osync_data_new(NULL, 0, dummyformat, NULL);
          osync_change_set_data(ignored_change, data);
          osync_objformat_unref(dummyformat);

          osync_change_set_uid(ignored_change, osync_mapping_entry_get_uid(entry->entry));

          osync_trace(TRACE_INTERNAL, "CHANGE: %p", entry->change);
        }
        break;
      }
    }

    t = t->next;
  }

  osync_list_free(ids);
  osync_list_free(changetypes);

  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;
}
Example #22
0
static OSyncConvCmpResult compare_file(const char *leftdata, unsigned int leftsize, const char *rightdata, unsigned int rightsize, void *user_data, OSyncError **error)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %i, %p, %i)", __func__, leftdata, leftsize, rightdata, rightsize);
	osync_assert(leftdata);
	osync_assert(rightdata);
	
	OSyncFileFormat *leftfile = (OSyncFileFormat *)leftdata;
	OSyncFileFormat *rightfile = (OSyncFileFormat *)rightdata;
	
	osync_assert(rightfile->path);
	osync_assert(leftfile->path);
	
	osync_trace(TRACE_INTERNAL, "Comparing %s and %s", leftfile->path, rightfile->path);
			
	
	if (mock_format_get_error("MOCK_FORMAT_PATH_COMPARE_NO") || !strcmp(leftfile->path, rightfile->path)) {
		if (leftfile->size == rightfile->size) {
			if (leftfile->size == 0 || !memcmp(leftfile->data, rightfile->data, rightfile->size)) {
				osync_trace(TRACE_EXIT, "%s: Same", __func__);
				return OSYNC_CONV_DATA_SAME;
			}
		}
		
		osync_trace(TRACE_EXIT, "%s: Similar", __func__);
		return OSYNC_CONV_DATA_SIMILAR;
	}
	
	osync_trace(TRACE_EXIT, "%s: Mismatch", __func__);
	return OSYNC_CONV_DATA_MISMATCH;
}
OSyncXMLField *osync_xmlfield_new(OSyncXMLFormat *xmlformat, const char *name, OSyncError **error)
{
  xmlNodePtr node = NULL;
  OSyncXMLField *xmlfield = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, xmlformat, name, error);
  osync_assert(xmlformat);
  osync_assert(name);
	
  node = xmlNewTextChild(xmlDocGetRootElement(xmlformat->doc), NULL, BAD_CAST name, NULL);
	
  xmlfield = osync_xmlfield_new_node(xmlformat, node, error);
  if(!xmlfield) {
    xmlUnlinkNode(node);
    xmlFreeNode(node);
    osync_trace(TRACE_EXIT_ERROR, "%s: %s" , __func__, osync_error_print(error));
    return NULL;
  }

  /* XMLFormat entry got added - not sure if it is still sorted */
  osync_xmlformat_set_unsorted(xmlformat);

  /* This XMLField has no keys, so it's for sure it's sorted */
  xmlfield->sorted = TRUE;
	
  osync_trace(TRACE_EXIT, "%s: %p", __func__, xmlfield);
  return xmlfield;
}
Example #24
0
static gchar* get_uid_from_event(gchar *vevent)
{
	gchar uid[BUFFSIZE];
	gchar *start;
	int ii;

	if (!vevent) {
		osync_trace(TRACE_INTERNAL, "Claws Mail: Event UID search: No event given");
		return g_strdup("123");
	}

	start = strstr(vevent, VEVENT_UID_STR);
	if (!start) {
		osync_trace(TRACE_INTERNAL, "Claws Mail: Event doesn't have a UID: '%s'",
								vevent);
		return g_strdup("123");
	}

	start += strlen(VEVENT_UID_STR);
	ii = 0;
	while(start && *start && (*start != '\n') &&
				(*start != '\r') && (ii < BUFFSIZE-1))
		uid[ii++] = *start++;
	uid[ii] = '\0';

	return g_strdup(uid);
}
void osync_status_update_member(OSyncEngine *engine, OSyncMember *member, OSyncMemberEvent type, const char *objtype, OSyncError *error)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %s, %p)", __func__, engine, member, type, objtype, error);
	
	if (engine->mebstat_callback) {
		OSyncMemberUpdate *update = g_malloc0(sizeof(OSyncMemberUpdate));
		if (!update)
			return;
		
		update->type = type;
		
		update->member = member;
		osync_member_ref(member);
		
		update->error = error;
		osync_error_ref(&error);
		
		update->objtype = g_strdup(objtype);
		
		engine->mebstat_callback(update, engine->mebstat_userdata);
		
		osync_status_free_member_update(update);
	} else
		osync_trace(TRACE_INTERNAL, "Status Update Ignored");
		
	osync_trace(TRACE_EXIT, "%s", __func__);
}
/*! @brief Unlocks a group
 * 
 * @param group The group to unlock
 * 
 */
void osync_group_unlock(OSyncGroup *group)
{
  char *lockfile = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, group);
  osync_assert(group);
	
  if (!group->configdir) {
    osync_trace(TRACE_EXIT, "%s: No configdir", __func__);
    return;
  }
	
  if (!group->lock_fd) {
    osync_trace(TRACE_EXIT, "%s: You have to lock the group before unlocking", __func__);
    return;
  }
    
#ifndef _WIN32
  flock(group->lock_fd, LOCK_UN);
  close(group->lock_fd);	
#endif
  group->lock_fd = 0;
	
  lockfile = g_strdup_printf("%s%clock", group->configdir, G_DIR_SEPARATOR);
	
  g_unlink(lockfile);
  g_free(lockfile);
	
  osync_trace(TRACE_EXIT, "%s", __func__);
}
Example #27
0
/* Here we actually tell opensync which sinks are available. */
static osync_bool discover(void *userdata, OSyncPluginInfo *info, OSyncError **error)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, userdata, info, error);

//	plugin_environment *env = (plugin_environment *)userdata;

	// Report avaliable sinks...
	OSyncObjTypeSink *sink = osync_plugin_info_find_objtype(info, "<objtype e.g. note>");
	if (!sink) {
		return FALSE;
	}
	osync_objtype_sink_set_available(sink, TRUE);
	
	OSyncVersion *version = osync_version_new(error);
	osync_version_set_plugin(version, "<your plugin-name>");
	//osync_version_set_version(version, "version");
	//osync_version_set_modelversion(version, "version");
	//osync_version_set_firmwareversion(version, "firmwareversion");
	//osync_version_set_softwareversion(version, "softwareversion");
	//osync_version_set_hardwareversion(version, "hardwareversion");
	osync_plugin_info_set_version(info, version);
	osync_version_unref(version);

	osync_trace(TRACE_EXIT, "%s", __func__);
	return TRUE;
}
Example #28
0
osync_bool osync_db_reset_full(OSyncDB *db, OSyncError **error)
{
	sqlite3_stmt *ppStmt = NULL;
	char *query = NULL;
	osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, db, error);

	osync_assert(db);

	query = osync_strdup("SELECT name FROM (SELECT * FROM sqlite_master) WHERE type='table'");

	if (sqlite3_prepare(db->sqlite3db, query, -1, &ppStmt, NULL) != SQLITE_OK) {
		osync_error_set(error, OSYNC_ERROR_GENERIC, "Query Error: %s", sqlite3_errmsg(db->sqlite3db));
		goto error;
	}

	while (sqlite3_step(ppStmt) == SQLITE_ROW) {
		const char *table = (const char *) sqlite3_column_text(ppStmt, 0);
		if (!osync_db_reset_table(db, table, error))
			goto error;
	}

	sqlite3_finalize(ppStmt);

	osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
	return TRUE;

 error:
	sqlite3_finalize(ppStmt);
	osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); 
	return FALSE;
}
osync_bool osync_mapping_engine_use_latest(OSyncMappingEngine *engine, OSyncError **error)
{
  OSyncMappingEntryEngine *latest_entry = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, engine, error);
	
  latest_entry = _osync_mapping_engine_get_latest_entry(engine, error);

  if (!latest_entry)
    goto error;

  osync_mapping_engine_set_master(engine, latest_entry);

  engine->conflict = FALSE;
  osync_status_update_mapping(engine->parent->parent, engine, OSYNC_MAPPING_EVENT_SOLVED, NULL);
  engine->parent->conflicts = g_list_remove(engine->parent->conflicts, engine);
	
  if (osync_engine_check_get_changes(engine->parent->parent) && osync_bitcount(engine->parent->sink_errors | engine->parent->sink_get_changes) == g_list_length(engine->parent->sink_engines)) {
    OSyncError *error = NULL;
    if (!osync_obj_engine_command(engine->parent, OSYNC_ENGINE_COMMAND_WRITE, &error))
      goto error;
  } else
    osync_trace(TRACE_INTERNAL, "Not triggering write. didnt receive all reads yet");
	
  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;

 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return FALSE;
}
/*! @brief dlopen()s a format plugin
 * 
 * The get_info() function on the format plugin gets called
 * 
 * @param env The environment in which to open the plugin
 * @param path Where to find this plugin
 * @param error Pointer to a error struct
 * @return Pointer to the plugin on success, NULL otherwise
 * 
 */
osync_bool osync_module_load(OSyncModule *module, const char *path, OSyncError **error)
{
  osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, module, path, error);
  osync_assert(module);
  osync_assert(!module->module);
	
  if (!g_module_supported()) {
    osync_error_set(error, OSYNC_ERROR_GENERIC, "This platform does not support loading of modules");
    goto error;
  }

  /* Try to open the module or fail if an error occurs */
  module->module = g_module_open(path, 0);
  if (!module->module) {
    osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to open module %s: %s", path, g_module_error());
    goto error;
  }
	
  module->path = g_strdup(path);
	
  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;

 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return FALSE;
}