Esempio n. 1
0
static osync_bool osync_format_converter_tree_target_fn_simple_reached_lastconverter(const void *data, OSyncFormatConverterTree *tree)
{
  OSyncObjFormat *target = (OSyncObjFormat *)data;
  GList *c;
  OSyncFormatConverter *converter = NULL;
  for (c = tree->unused; c; c = c->next) {
    converter = c->data;
    if (!strcmp(osync_objformat_get_name(target), osync_objformat_get_name(osync_converter_get_targetformat(converter)))) return FALSE;
  }
  return TRUE;
}
OSyncConvCmpResult osync_data_compare(OSyncData *leftdata, OSyncData *rightdata)
{
  OSyncConvCmpResult ret = 0;
  osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, leftdata, rightdata);
  osync_assert(leftdata);
  osync_assert(rightdata);

  if (leftdata == rightdata) {
    osync_trace(TRACE_EXIT, "%s: SAME: OK. data is the same", __func__);
    return OSYNC_CONV_DATA_SAME;
  }
	
  if (leftdata->data == rightdata->data && leftdata->size == rightdata->size) {
    osync_trace(TRACE_EXIT, "%s: SAME: OK. data point to same memory", __func__);
    return OSYNC_CONV_DATA_SAME;
  }
	
  if (!leftdata->objformat || !rightdata->objformat || strcmp(osync_objformat_get_name(leftdata->objformat), osync_objformat_get_name(rightdata->objformat))) {
    osync_trace(TRACE_EXIT, "%s: MISMATCH: Objformats do not match", __func__);
    return OSYNC_CONV_DATA_MISMATCH;
  }
		
  if (!rightdata->data || !leftdata->data) {
    osync_trace(TRACE_EXIT, "%s: MISMATCH: One change has no data", __func__);
    return OSYNC_CONV_DATA_MISMATCH;
  }
	
  ret = osync_objformat_compare(leftdata->objformat, leftdata->data, leftdata->size, rightdata->data, rightdata->size);
  osync_trace(TRACE_EXIT, "%s: %i", __func__, ret);
  return ret;
}
Esempio n. 3
0
static osync_bool osync_format_converter_path_vertice_validate_path_with_detector(OSyncFormatConverterPathVertice *ve, OSyncFormatEnv *env, OSyncFormatConverter *converter) {

  OSyncList *cs = NULL;
  OSyncList *cd = NULL;
  osync_bool has_nondetector = FALSE;
  OSyncList *converters_seeknondetectors = NULL;
  osync_trace(TRACE_INTERNAL, "Converter %s to %s type %i", osync_objformat_get_name(osync_converter_get_sourceformat(converter)), osync_objformat_get_name(osync_converter_get_targetformat(converter)), osync_converter_get_type(converter));

  /* We search the converters for the given conversion to see if there are other converters than "detector" for this conversion */
  converters_seeknondetectors = osync_format_env_find_converters(env, osync_converter_get_sourceformat(converter), osync_converter_get_targetformat(converter));
  for(cd = converters_seeknondetectors; cd ; cd = cd->next) {
    OSyncFormatConverter *converter_seeknondetectors = cd->data;
    if ( converter_seeknondetectors && (osync_converter_get_type(converter_seeknondetectors) != OSYNC_CONVERTER_DETECTOR) ) {
      osync_trace(TRACE_INTERNAL, "Found non detector converter. We will pair the detector later on with this 'non detector' converter if a detector is available.");
      has_nondetector = TRUE;
      break;
    }
  }

  if (has_nondetector) {
    OSyncList *converters_sameformat = NULL;
    /*  There were other converters than the detector (if there is a detector at all) for the given conversion. */

    /* Skip the detector : it will be handled when processing the non detector converter
       Non detector are preferred in that we will validate them instead of the detector but still the detector
       will be called before telling if the "non detector" converter is valid for the */
    if ( osync_converter_get_type(converter) == OSYNC_CONVERTER_DETECTOR )
      return FALSE;

    /* Looking after detector for non detector converter.
       If there was a detector converter for the same conversion as the non detector converter and the detection fails force the failure
       of the non detector converter */
    converters_sameformat = osync_format_env_find_converters(env, osync_converter_get_sourceformat(converter), osync_converter_get_targetformat(converter));
    for(cs = converters_sameformat; cs ; cs = cs->next) {
      OSyncFormatConverter *converter_sameformat = cs->data;
      if ( converter_sameformat && (osync_converter_get_type(converter_sameformat) == OSYNC_CONVERTER_DETECTOR) ) {
        osync_trace(TRACE_INTERNAL, "detector found");
        if(!osync_converter_detect(converter_sameformat, ve->data)) {
          osync_trace(TRACE_INTERNAL, "Invoked detector for converter from %s to %s: FALSE", osync_objformat_get_name(osync_converter_get_sourceformat(converter)), osync_objformat_get_name(osync_converter_get_targetformat(converter)));
          return FALSE;
        } else {
          osync_trace(TRACE_INTERNAL, "Invoked detector for converter from %s to %s: TRUE", osync_objformat_get_name(osync_converter_get_sourceformat(converter)), osync_objformat_get_name(osync_converter_get_targetformat(converter)));
        }
      }
    }
  } else {
    /*  The detector was the only converter for the given conversion. Check that the "conversion" (detection) is valid. */
    osync_trace(TRACE_INTERNAL, "alone detector found");
    if(!osync_converter_detect(converter, ve->data)) {
      osync_trace(TRACE_INTERNAL, "Invoked detector for converter from %s to %s: FALSE", osync_objformat_get_name(osync_converter_get_sourceformat(converter)), osync_objformat_get_name(osync_converter_get_targetformat(converter)));
      return FALSE;
    } else {
      osync_trace(TRACE_INTERNAL, "Invoked detector for converter from %s to %s: TRUE", osync_objformat_get_name(osync_converter_get_sourceformat(converter)), osync_objformat_get_name(osync_converter_get_targetformat(converter)));
    }
  }

  return TRUE;
}
Esempio n. 4
0
static osync_bool osync_format_converter_tree_target_fn_format_sinks_reached_lastconverter(const void *data, OSyncFormatConverterTree *tree)
{
  OSyncList *f, *formats = (OSyncList *) data;
  GList *c;
  OSyncFormatConverter *converter = NULL;
  for (c = tree->unused; c; c = c->next) {
    converter = c->data;
    for (f = formats; f; f = f->next) {
      OSyncObjFormatSink *format_sink = f->data;
      const char *format = osync_objformat_sink_get_objformat(format_sink);
      if (!strcmp(format, osync_objformat_get_name(osync_converter_get_targetformat(converter)))) return FALSE;
    }
  }
  return TRUE;
}
Esempio n. 5
0
/** Function used on a path search OSyncFormatConverterPathVertice objformat to check if it matches an OSyncList of OSyncObjFormatSinks 
 * @param data List of OSyncObjFormatSinks
 * @param fmt format to compare with
 * @see osync_conv_find_path_fn(), osync_change_convert_fmtnames()
 */
static osync_bool osync_format_converter_path_vertice_target_fn_format_sinks(const void *data, OSyncObjFormat *fmt)
{
  OSyncList *f, *formats = (OSyncList *) data;
  for (f = formats; f; f = f->next) {
    OSyncObjFormatSink *format_sink = f->data;
    const char *format = osync_objformat_sink_get_objformat(format_sink);
    /*if (osync_objformat_is_equal(fmt, format))*/
    if (!strcmp(format, osync_objformat_get_name(fmt)))
      /* Found */
      return TRUE;
  }

  /* Not found */
  return FALSE;
}
Esempio n. 6
0
OSyncObjFormat *osync_format_env_find_objformat(OSyncFormatEnv *env, const char *name)
{
  GList *element = NULL;
	
  osync_assert(env);

  if (!name)
    return NULL;
	
  for (element = env->objformats; element; element = element->next) {
    OSyncObjFormat *format = element->data;
    if (!strcmp(osync_objformat_get_name(format), name))
      return format;
  }
  return NULL;
}
Esempio n. 7
0
//typedef void (* OSyncContextChangeFn) (OSyncChange *, void *);
static void _osyncplugin_ctx_change_callback(OSyncChange *change, void *user_data)
{
	Command *cmd = (Command *) user_data;		
	OSyncObjTypeSink *sink = cmd->sink;

	printf("GETCHANGES:\t%s\t%s\t%s", 
	       _osyncplugin_changetype_str(change), 
	       osync_objtype_sink_get_name(sink),	
	       osync_change_get_uid(change));

	if (osync_change_get_objformat(change))
		printf("\t%s", osync_objformat_get_name(osync_change_get_objformat(change)));

	printf("\n");

	osync_change_ref(change);
	changesList = g_list_append(changesList, change);
}
Esempio n. 8
0
OSyncObjFormat *osync_format_env_detect_objformat(OSyncFormatEnv *env, OSyncData *data)
{
  GList *d = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data);
	
  /* Run all datadetectors for our source type */
  for (d = env->converters; d; d = d->next) {
    OSyncFormatConverter *converter = d->data;
    /* We check if the converter might be able to converter the change */
    if (osync_converter_get_type(converter) == OSYNC_CONVERTER_DETECTOR && osync_converter_matches(converter, data)) {
      osync_trace(TRACE_INTERNAL, "running detector %s for format %s", osync_objformat_get_name(osync_converter_get_targetformat(converter)), osync_objformat_get_name(osync_data_get_objformat(data)));
      if (osync_converter_detect(converter, data))  {
        OSyncObjFormat *detected_format = osync_converter_get_targetformat(converter);
        osync_trace(TRACE_EXIT, "%s: %p", __func__, detected_format);
        return detected_format;
      }
    }
  }
	
  osync_trace(TRACE_EXIT, "%s: No detector triggered", __func__);
  return NULL;
}
Esempio n. 9
0
void osync_format_env_free(OSyncFormatEnv *env)
{
  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, env);
  osync_assert(env);
	
  /* Free the formats */
  while (env->objformats) {
    osync_trace(TRACE_INTERNAL, "FORMAT: %s", osync_objformat_get_name(env->objformats->data));
    osync_objformat_unref(env->objformats->data);
    env->objformats = g_list_remove(env->objformats, env->objformats->data);
  }
	
  osync_format_env_converter_finalize(env);
	
  /* Free the converters */
  while (env->converters) {
    osync_converter_unref(env->converters->data);
    env->converters = g_list_remove(env->converters, env->converters->data);
  }
	
  /* Free the filters */
  while (env->custom_filters) {
    osync_custom_filter_unref(env->custom_filters->data);
    env->custom_filters = g_list_remove(env->custom_filters, env->custom_filters->data);
  }
	
  /* Free the modules */
  while (env->modules) {
    osync_module_free(env->modules->data);
    env->modules = g_list_remove(env->modules, env->modules->data);
  }
	
  g_free(env);
	
  osync_trace(TRACE_EXIT, "%s", __func__);
}
Esempio n. 10
0
void change_content(OSyncEngine *engine)
{
	GList *m;
	for (m = members; m; m = m->next) {
		member_info *meminfo = m->data;
		
		busy = TRUE;
		osync_member_connect(meminfo->member, (OSyncEngCallback)stress_message_callback, NULL);
		if (busy)
			g_main_loop_run(loop);
		
		GList *c = NULL;
		for (c = meminfo->changes; c; c = c->next) {
			change_info *chinfo = c->data;
			if (g_random_int_range(0, 3) == 0) {
				switch (g_random_int_range(1, 6)) {
					case 1:
					case 5:
						if (osync_member_modify_random_data(meminfo->member, chinfo->change)) {
							printf("Modifying data %s for member %lli. Objtype: %s Format: %s\n", osync_change_get_uid(chinfo->change), osync_member_get_id(meminfo->member), osync_objtype_get_name(osync_change_get_objtype(chinfo->change)), osync_objformat_get_name(osync_change_get_objformat(chinfo->change)));
							chinfo->type = CHANGE_MODIFIED;
						}
						break;
					case 2:
						if (osync_member_delete_data(meminfo->member, chinfo->change)) {
							printf("Deleting data %s for member %lli. Objtype: %s Format: %s\n", osync_change_get_uid(chinfo->change), osync_member_get_id(meminfo->member), osync_objtype_get_name(osync_change_get_objtype(chinfo->change)), osync_objformat_get_name(osync_change_get_objformat(chinfo->change)));
							if (!osync_group_get_slow_sync(engine->group, osync_objtype_get_name(osync_change_get_objtype(chinfo->change))));
								chinfo->type = CHANGE_DELETED;
						}
						break;
					case 3:
						//printf("Modifying all for %s\n", osync_change_get_uid(change));
						break;
					case 4:
						//printf("Deleting all for %s\n", osync_change_get_uid(change));
						break;
					default:
						printf("error\n");
				}
			}
		}
		
		int num_new = g_random_int_range(0, 8);
		int n = 0;;
		for (n = 0; n < num_new; n++) {
			change_info *chinfo = g_malloc0(sizeof(change_info));
			if ((chinfo->change = osync_member_add_random_data(meminfo->member, NULL))) {
				if (find_change_info(meminfo, chinfo->change))
					continue;
				meminfo->changes = g_list_append(meminfo->changes, chinfo);
				chinfo->type = CHANGE_ADDED;
				chinfo->uid = g_strdup(osync_change_get_uid(chinfo->change));
				printf("Adding new data %s for member %lli. Objtype: %s Format: %s\n", osync_change_get_uid(chinfo->change), osync_member_get_id(meminfo->member), osync_objtype_get_name(osync_change_get_objtype(chinfo->change)), osync_objformat_get_name(osync_change_get_objformat(chinfo->change)));
			}
		}
		
		busy = TRUE;
		osync_member_disconnect(meminfo->member, (OSyncEngCallback)stress_message_callback, NULL);
		if (busy)
			g_main_loop_run(loop);
	}
}
$NetBSD$

Don't continue the if block.

--- tools/osyncstress.c.orig	2009-09-20 20:14:18.000000000 +0000
+++ tools/osyncstress.c
@@ -184,7 +184,7 @@ void change_content(OSyncEngine *engine)
 					case 2:
 						if (osync_member_delete_data(meminfo->member, chinfo->change)) {
 							printf("Deleting data %s for member %lli. Objtype: %s Format: %s\n", osync_change_get_uid(chinfo->change), osync_member_get_id(meminfo->member), osync_objtype_get_name(osync_change_get_objtype(chinfo->change)), osync_objformat_get_name(osync_change_get_objformat(chinfo->change)));
-							if (!osync_group_get_slow_sync(engine->group, osync_objtype_get_name(osync_change_get_objtype(chinfo->change))));
+							if (!osync_group_get_slow_sync(engine->group, osync_objtype_get_name(osync_change_get_objtype(chinfo->change))))
 								chinfo->type = CHANGE_DELETED;
 						}
 						break;
Esempio n. 12
0
OSyncFormatConverterPath *osync_format_env_find_path(OSyncFormatEnv *env, OSyncObjFormat *sourceformat, OSyncObjFormat *targetformat, OSyncError **error)
{
  OSyncFormatConverterPath *path = NULL;
  OSyncData *sourcedata = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s, %p)", __func__, env, sourceformat, targetformat, targetformat ? osync_objformat_get_name(targetformat) : "NONE", error);

  sourcedata = osync_data_new(NULL, 0, sourceformat, error);
  if (!sourcedata)
    goto error;

  path = osync_format_env_find_path_fn(env, sourcedata, osync_format_converter_path_vertice_target_fn_simple, osync_format_converter_tree_target_fn_simple_reached_lastconverter, targetformat, NULL, error);

  osync_data_unref(sourcedata);

  if (!path)
    goto error;
	
  osync_trace(TRACE_EXIT, "%s: %p", __func__, path);
  return path;

 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return NULL;
}
Esempio n. 13
0
static OSyncFormatConverterPathVertice *osync_format_converter_path_vertice_get_next_vertice_neighbour(OSyncFormatEnv *env, OSyncFormatConverterTree *tree, OSyncFormatConverterPathVertice *ve, OSyncError **error)
{
  GList *c = NULL;
  OSyncFormatConverter *converter = NULL;
  OSyncObjFormat *fmt_target = NULL;
  OSyncFormatConverterPathVertice *neigh = NULL;
  const char *source_objtype = NULL;
  const char *target_objtype = NULL;
	
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, env, tree, ve);
	
  /* Ok. we need to get the next valid neighbour to our input OSyncFormatConverterPathVertice.
   * Valid neighbours are the once that are reachable by a conversion. So
   * we now go through all converters and check if they are valid */
  for (c = tree->unused; c; c = c->next) {
    OSyncObjFormat *sourceformat = NULL, *targetformat = NULL;
    converter = c->data;
    fmt_target = osync_converter_get_targetformat(converter);
		
    /* Check only valid converters, from the right format */
    if (!osync_objformat_is_equal(osync_converter_get_sourceformat(converter), ve->format))
      continue;

    /* Only validate with the help of detectors, if data is
       available to run a detector on it. 
       Check if a detector validate this path */
    if (osync_data_has_data(ve->data) 
        && !osync_format_converter_path_vertice_validate_path_with_detector(ve, env, converter))
      continue;

    /* Remove the converter from the unused list */
    tree->unused = g_list_remove(tree->unused, converter);

    /* Allocate the new neighbour */
    neigh = osync_format_converter_path_vertice_new(error);
    if (!neigh)
      goto error;
		
    neigh->format = fmt_target;
    neigh->path = g_list_copy(ve->path);
    neigh->path = g_list_append(neigh->path, converter);
	
    /* Distance calculation */
    neigh->conversions = ve->conversions + 1;
		
    neigh->losses = ve->losses;
    if (osync_converter_get_type(converter) == OSYNC_CONVERTER_DECAP)
      neigh->losses++;
		
    neigh->objtype_changes = ve->objtype_changes;
		
    sourceformat = osync_converter_get_sourceformat(converter);
    targetformat = osync_converter_get_targetformat(converter);
		
    source_objtype = osync_objformat_get_objtype(sourceformat);
    target_objtype = osync_objformat_get_objtype(targetformat);
    if (strcmp(source_objtype, target_objtype))
      neigh->objtype_changes++;

    osync_trace(TRACE_EXIT, "%s: %p (converter from %s to %s) objtype changes : %i losses : %i, conversions : %i", __func__, neigh, osync_objformat_get_name(sourceformat), osync_objformat_get_name(targetformat), neigh->objtype_changes, neigh->losses, neigh->conversions);
    return neigh;
  }
	
  osync_trace(TRACE_EXIT, "%s: None found", __func__);
  return NULL;

 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return NULL;
}
Esempio n. 14
0
OSyncFormatConverterPath *osync_format_env_find_path_with_detectors(OSyncFormatEnv *env, OSyncData *sourcedata, OSyncObjFormat *targetformat, const char *preferred_format, OSyncError **error)
{
  OSyncFormatConverterPath *path = NULL;
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s, %p)", __func__, env, sourcedata, targetformat, targetformat ? osync_objformat_get_name(targetformat) : "NONE", error);
	
  path = osync_format_env_find_path_fn(env, sourcedata, osync_format_converter_path_vertice_target_fn_simple, osync_format_converter_tree_target_fn_simple_reached_lastconverter, targetformat, preferred_format, error);
  if (!path) {
    osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
    return NULL;
  }
	
  osync_trace(TRACE_EXIT, "%s: %p", __func__, path);
  return path;
}
osync_bool osync_obj_engine_command(OSyncObjEngine *engine, OSyncEngineCmd cmd, OSyncError **error)
{
  GList *p = NULL;
  GList *m = NULL;
  GList *e = NULL;
  OSyncSinkEngine *sinkengine =  NULL;

	
  osync_trace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, engine, cmd, error);
  osync_assert(engine);
	
  switch (cmd) {
    int write_sinks = 0;
    osync_bool proxy_disconnect = FALSE;
  case OSYNC_ENGINE_COMMAND_CONNECT:
    for (p = engine->sink_engines; p; p = p->next) {
      sinkengine = p->data;

      if (!osync_client_proxy_connect(sinkengine->proxy, _osync_obj_engine_connect_callback, sinkengine, engine->objtype, engine->slowsync, error))
        goto error;
    }
    break;
  case OSYNC_ENGINE_COMMAND_READ:
    for (p = engine->sink_engines; p; p = p->next) {
      sinkengine = p->data;
      for (m = sinkengine->entries; m; m = m->next) {
        OSyncMappingEntryEngine *entry = m->data;
        OSyncChange *change = entry->change;

        if (!change)
          continue;

        if (!osync_client_proxy_read(sinkengine->proxy, _osync_obj_engine_read_ignored_callback, sinkengine, change, error))
          goto error;
      }
    }

    if (engine->archive) {
      /* Flush the changelog - to avoid double entries of ignored entries */
      if (!osync_archive_flush_ignored_conflict(engine->archive, engine->objtype, error))
        goto error;
    }

    write_sinks = _osync_obj_engine_num_write_sinks(engine);

    /* Get change entries since last sync. (get_changes) */
    for (p = engine->sink_engines; p; p = p->next) {
      OSyncMember *member = NULL;
      OSyncObjTypeSink *objtype_sink = NULL;

      sinkengine = p->data;

      member = osync_client_proxy_get_member(sinkengine->proxy);
      objtype_sink = osync_member_find_objtype_sink(member, engine->objtype);

      /* Is there at least one other writeable sink? */
      if (objtype_sink && osync_objtype_sink_get_write(objtype_sink) && write_sinks) {
        _osync_obj_engine_read_callback(sinkengine->proxy, sinkengine, *error);
        osync_trace(TRACE_INTERNAL, "no other writable sinks .... SKIP");
        continue;
      }

      if (!osync_client_proxy_get_changes(sinkengine->proxy, _osync_obj_engine_read_callback, sinkengine, engine->objtype, engine->slowsync, error))
        goto error;
    }

    break;
  case OSYNC_ENGINE_COMMAND_WRITE:
    if (engine->conflicts) {
      osync_trace(TRACE_INTERNAL, "We still have conflict. Delaying write");
      break;
    }
		
    if (engine->written) {
      osync_trace(TRACE_INTERNAL, "Already written");
      break;
    }
				
    engine->written = TRUE;
		
    /* Write the changes. First, we can multiply the winner in the mapping */
    osync_trace(TRACE_INTERNAL, "Preparing write. multiplying %i mappings", g_list_length(engine->mapping_engines));
    for (m = engine->mapping_engines; m; m = m->next) {
      OSyncMappingEngine *mapping_engine = m->data;
      if (!osync_mapping_engine_multiply(mapping_engine, error))
        goto error;
    }
			
    osync_trace(TRACE_INTERNAL, "Starting to write");
    for (p = engine->sink_engines; p; p = p->next) {
      OSyncMember *member = NULL;
      long long int memberid = 0;
      OSyncObjTypeSink *objtype_sink = NULL;
      OSyncFormatConverterPath *path = NULL;

      sinkengine = p->data;
      member = osync_client_proxy_get_member(sinkengine->proxy);
      memberid = osync_member_get_id(member);
      objtype_sink = osync_member_find_objtype_sink(member, engine->objtype);
				
      /* If sink could not be found use "data" sink if available */
      if (!objtype_sink)
        objtype_sink = osync_member_find_objtype_sink(member, "data");
      /* TODO: Review if objtype_sink = NULL is valid at all. */

      for (e = sinkengine->entries; e; e = e->next) {
        OSyncMappingEntryEngine *entry_engine = e->data;
        osync_assert(entry_engine);

        /* Merger - Save the entire xml and demerge */
        /* TODO: is here the right place to save the xml???? */
        if (osync_group_get_merger_enabled(osync_engine_get_group(engine->parent)) &&
            osync_group_get_converter_enabled(osync_engine_get_group(engine->parent)) &&	
            entry_engine->change &&
            (osync_change_get_changetype(entry_engine->change) != OSYNC_CHANGE_TYPE_DELETED) &&
            !strncmp(osync_objformat_get_name(osync_change_get_objformat(entry_engine->change)), "xmlformat-", 10) )
          {
            char *buffer = NULL;
            unsigned int xmlformat_size = 0, size = 0;
            OSyncXMLFormat *xmlformat = NULL;
            const char *objtype = NULL;
            OSyncMapping *mapping = NULL;
            OSyncMerger *merger = NULL; 

            osync_trace(TRACE_INTERNAL, "Entry %s for member %lli: Dirty: %i", osync_change_get_uid(entry_engine->change), memberid, osync_entry_engine_is_dirty(entry_engine));

            osync_trace(TRACE_INTERNAL, "Save the entire XMLFormat and demerge.");
            objtype = osync_change_get_objtype(entry_engine->change);
            mapping = entry_engine->mapping_engine->mapping;
						
            osync_data_get_data(osync_change_get_data(entry_engine->change), (char **) &xmlformat, &xmlformat_size);
            osync_assert(xmlformat_size == osync_xmlformat_size());

            if(!osync_xmlformat_assemble(xmlformat, &buffer, &size)) {
              osync_error_set(error, OSYNC_ERROR_GENERIC, "Could not assamble the xmlformat");
              goto error;	
            }

            if(!osync_archive_save_data(engine->archive, osync_mapping_get_id(mapping), objtype, buffer, size, error)) {
              g_free(buffer);	
              goto error;			
            }
            g_free(buffer);
						
            merger = osync_member_get_merger(osync_client_proxy_get_member(sinkengine->proxy));
            if(merger)
              osync_merger_demerge(merger, xmlformat);
          }


        /* Only commit change if the objtype sink is able/allowed to write. */
        if (objtype_sink && osync_objtype_sink_get_write(objtype_sink) && osync_entry_engine_is_dirty(entry_engine)) {
          OSyncChange *change = entry_engine->change;
          osync_assert(entry_engine->change);

          /* Convert to requested target format if the changetype is not DELETED */
          if (osync_group_get_converter_enabled(osync_engine_get_group(engine->parent)) && (osync_change_get_changetype(change) != OSYNC_CHANGE_TYPE_DELETED)) {

            char *objtype = NULL;
            OSyncList *format_sinks = NULL;
            unsigned int length = 0;
            OSyncFormatConverter *converter = NULL;

            osync_trace(TRACE_INTERNAL, "Starting to convert from objtype %s and format %s", osync_change_get_objtype(entry_engine->change), osync_objformat_get_name(osync_change_get_objformat(entry_engine->change)));
            /* We have to save the objtype of the change so that it does not get
             * overwritten by the conversion */
            objtype = g_strdup(osync_change_get_objtype(change));
							
            /* Now we have to convert to one of the formats
             * that the client can understand */
            format_sinks = osync_objtype_sink_get_objformat_sinks(objtype_sink);
            if (!format_sinks) {
              osync_error_set(error, OSYNC_ERROR_GENERIC, "There are no available format sinks.");
              goto error;
            }
						
            /* We cache the converter path for each sink/member couple */
            if (!path) {
              path = osync_format_env_find_path_formats_with_detectors(engine->formatenv, osync_change_get_data(entry_engine->change), format_sinks, osync_objtype_sink_get_preferred_format(objtype_sink), error);
            }
            if (!path)
              goto error;

            length = osync_converter_path_num_edges(path);
            converter = osync_converter_path_nth_edge(path, length - 1);
            if (converter) {
              OSyncObjFormat *format = osync_converter_get_targetformat(converter);
              OSyncObjFormatSink *formatsink = osync_objtype_sink_find_objformat_sink(objtype_sink, format);
              osync_converter_path_set_config(path, osync_objformat_sink_get_config(formatsink));
            }

            if (!osync_format_env_convert(engine->formatenv, path, osync_change_get_data(entry_engine->change), error)) {
              osync_converter_path_unref(path);
              goto error;
            }
            osync_trace(TRACE_INTERNAL, "converted to format %s", osync_objformat_get_name(osync_change_get_objformat(entry_engine->change)));
							
							
            osync_change_set_objtype(change, objtype);
            g_free(objtype);
          }
						
          osync_trace(TRACE_INTERNAL, "Writing change %s, changetype %i, format %s , objtype %s from member %lli", 
                      osync_change_get_uid(change), 
                      osync_change_get_changetype(change), 
                      osync_objformat_get_name(osync_change_get_objformat(change)), 
                      osync_change_get_objtype(change), 
                      osync_member_get_id(osync_client_proxy_get_member(sinkengine->proxy)));
	
          if (!osync_client_proxy_commit_change(sinkengine->proxy, _osync_obj_engine_commit_change_callback, entry_engine, osync_entry_engine_get_change(entry_engine), error))
            goto error;
        } else if (entry_engine->change) {
          OSyncMapping *mapping = entry_engine->mapping_engine->mapping;
          OSyncMember *member = osync_client_proxy_get_member(sinkengine->proxy);
          OSyncMappingEntry *entry = entry_engine->entry;
          const char *objtype = osync_change_get_objtype(entry_engine->change);
						
          if (engine->archive) {
            if (osync_change_get_changetype(entry_engine->change) == OSYNC_CHANGE_TYPE_DELETED) {
              if (!osync_archive_delete_change(engine->archive, osync_mapping_entry_get_id(entry), objtype, error))
                goto error;
            } else {
              if (!osync_archive_save_change(engine->archive, osync_mapping_entry_get_id(entry), osync_change_get_uid(entry_engine->change), objtype, osync_mapping_get_id(mapping), osync_member_get_id(member), error))
                goto error;
            }
          }
        }
      }
			
      if (path)
        osync_converter_path_unref(path);

      if (!osync_client_proxy_committed_all(sinkengine->proxy, _osync_obj_engine_written_callback, sinkengine, engine->objtype, error))
        goto error;
    }
    break;
  case OSYNC_ENGINE_COMMAND_SYNC_DONE:
    for (p = engine->sink_engines; p; p = p->next) {
      sinkengine = p->data;
      if (!osync_client_proxy_sync_done(sinkengine->proxy, _osync_obj_engine_sync_done_callback, sinkengine, engine->objtype, error))
        goto error;
    }
    break;
  case OSYNC_ENGINE_COMMAND_DISCONNECT:;
    for (p = engine->sink_engines; p; p = p->next) {
      sinkengine = p->data;

      /* Don't call client disconnect functions if the sink is already disconnected.
         This avoids unintended disconnect calls of clients/plugins which might not prepared
         for a disconnect call when their never got connected. (testcases: *_connect_error, *_connect_timeout ..) */
      if (!osync_sink_engine_is_connected(sinkengine))
        continue;

      proxy_disconnect = TRUE;

      if (!osync_client_proxy_disconnect(sinkengine->proxy, _osync_obj_engine_disconnect_callback, sinkengine, engine->objtype, error))
        goto error;
    }
			
    /* If no client needs to be disconnected, we MUST NOT expected any 
       disconnected_callback which generates an OSYNC_ENGINE_EVENT_DISCONNECTED event.
       So we directly generate such event on our own. (testcases: double_connect_*, triple_connnect_*) */ 
    if (!proxy_disconnect)
      _osync_obj_engine_generate_event_disconnected(engine, NULL);

    break;
  case OSYNC_ENGINE_COMMAND_SOLVE:
  case OSYNC_ENGINE_COMMAND_DISCOVER:
  case OSYNC_ENGINE_COMMAND_ABORT:
    break;
  }
	
  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;

 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return FALSE;
}
osync_bool osync_sink_engine_write(OSyncSinkEngine *engine, OSyncArchive *archive, OSyncError **error)
{
    OSyncList *o;
    const char *objtype;
    OSyncMember *member;

    osync_assert(engine);
    osync_assert(archive);

    objtype = osync_obj_engine_get_objtype(engine->engine);
    member = osync_client_proxy_get_member(engine->proxy);

    for (o = engine->entries; o; o = o->next) {
        OSyncMappingEntryEngine *entry_engine = o->data;
        osync_assert(entry_engine);

        if (osync_entry_engine_is_dirty(entry_engine)) {
            OSyncChange *change = osync_entry_engine_get_change(entry_engine);
            osync_assert(change);

            osync_trace(TRACE_INTERNAL, "Writing change %s, changetype %i, format %s , objtype %s from member %i",
                        osync_change_get_uid(change),
                        osync_change_get_changetype(change),
                        osync_objformat_get_name(osync_change_get_objformat(change)),
                        osync_change_get_objtype(change),
                        osync_member_get_id(member));

            if (!osync_client_proxy_commit_change(engine->proxy,
                                                  osync_obj_engine_commit_change_callback,
                                                  entry_engine, change, error))
                goto error;

        } else if (entry_engine->change) {
            OSyncMapping *mapping = entry_engine->mapping_engine->mapping;
            OSyncMappingEntry *entry = entry_engine->entry;

            /* FIXME: Don't mix up in this function objtypes */
            /* osync_assert_msg(!strcmp(objtype, osync_change_get_objtype(entry_engine->change), "Mixed-objtype in final write!")); */

            if (osync_change_get_changetype(entry_engine->change) == OSYNC_CHANGE_TYPE_DELETED) {
                if (!osync_archive_delete_change(archive, osync_mapping_entry_get_id(entry),
                                                 osync_change_get_objtype(entry_engine->change), error))
                    goto error;
            } else {
                if (!osync_archive_save_change(archive,
                                               osync_mapping_entry_get_id(entry),
                                               osync_change_get_uid(entry_engine->change),
                                               osync_change_get_objtype(entry_engine->change),
                                               osync_mapping_get_id(mapping),
                                               osync_member_get_id(member), objtype, error))
                    goto error;
            }
        }
    }

    if (!osync_client_proxy_committed_all(engine->proxy, osync_obj_engine_written_callback, engine, objtype, error))
        goto error;

    return TRUE;

error:
    return FALSE;
}
Esempio n. 17
0
static OSyncFormatConverterPath *osync_format_env_find_path_fn(OSyncFormatEnv *env, OSyncData *sourcedata, OSyncPathTargetFn target_fn, OSyncTargetLastConverterFn last_converter_fn, const void *fndata, const char * preferred_format, OSyncError **error)
{
  OSyncFormatConverterPath *path = NULL;
  OSyncFormatConverterTree *tree = NULL;
  OSyncFormatConverterPathVertice *begin = NULL;
  OSyncFormatConverterPathVertice *result = NULL;
  OSyncFormatConverterPathVertice *neighbour = NULL;
  GList *e, *v;
  guint vertice_id = 0;
	
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, env, sourcedata, target_fn, fndata, error);
  osync_assert(env);
  osync_assert(sourcedata);
  osync_assert(target_fn);
	
  //Vertice = Spitze = Format
  //edge = Kante = Converter

  /* Optimization: check if the format is already valid */
  if (target_fn(fndata, osync_data_get_objformat(sourcedata))) {
    path = osync_converter_path_new(error);
    if (!path)
      goto error;
		
    osync_trace(TRACE_EXIT, "%s: Target already valid", __func__);
    return path;
  }

  /* Make a new search tree */
  tree = osync_try_malloc0(sizeof(OSyncFormatConverterTree), error);
  if (!tree)
    goto error;
  tree->unused = g_list_copy(env->converters);
	
  /* We make our starting point (which is the current format of the 
   * change of course */
  begin = osync_format_converter_path_vertice_new(error);
  if (!begin)
    goto error_free_tree;
	
  begin->format = osync_data_get_objformat(sourcedata);
  begin->path = NULL;
  begin->id = vertice_id;
  begin->neighbour_id = 0;
	
  tree->search = g_list_append(NULL, begin);
	
  /* While there are still vertices in our
   * search queue */
  while (g_list_length(tree->search)) {
    /* log current tree search list */
    GString *string = g_string_new("");
    guint size = g_list_length(tree->search);
    guint count = 0;
    guint neighbour_id = 0;
    OSyncFormatConverterPathVertice *current = NULL;
    OSyncFormatConverterPath *path_tmp = NULL;
    for (v = tree->search; v; v = v->next) {
      OSyncFormatConverterPathVertice *vertice = v->data;
      GString *string2 = g_string_new("");
      guint size2 = g_list_length(vertice->path);
      guint count2 = 0;
      count ++;
      for (e = vertice->path; e; e = e->next) {
        OSyncFormatConverter *edge = e->data;
        count2 ++;
        if (count2 == 1) {
          g_string_append(string2, osync_objformat_get_name(osync_converter_get_sourceformat(edge)));
          g_string_append(string2, " -> ");
        }
        g_string_append(string2, osync_objformat_get_name(osync_converter_get_targetformat(edge)));
        if (size2 > 1 && count2 < size2)
          g_string_append(string2, " -> ");
      }
      g_string_append(string, osync_objformat_get_name(vertice->format));
      g_string_append(string, " ( ");
      g_string_append(string, string2->str);
      g_string_append(string, " ) ");

      g_string_free(string2, TRUE);

      if (size > 1 && count < size)
        g_string_append(string, " -> ");
    }
    osync_trace(TRACE_INTERNAL, "Tree : %s", string->str);
    g_string_free(string, TRUE);

    /* Get the first OSyncFormatConverterPathVertice from the search queue
     * and remove it from the queue */
    current = tree->search->data;
    tree->search = g_list_remove(tree->search, current);
		
    /* log current OSyncFormatConverterPathVertice */
    string = g_string_new("");
    size = g_list_length(current->path);
    count = 0;
    for (e = current->path; e; e = e->next) {
      OSyncFormatConverter *edge = e->data;
      count ++;
      if (count == 1) {
        g_string_append(string, osync_objformat_get_name(osync_converter_get_sourceformat(edge)));
        g_string_append(string, " -> ");
      }
      g_string_append(string, osync_objformat_get_name(osync_converter_get_targetformat(edge)));
      if (size > 1 && count < size)
        g_string_append(string, " -> ");
    }
    osync_trace(TRACE_INTERNAL, "Next vertice : %s (%s).", osync_objformat_get_name(current->format), string->str);
    g_string_free(string, TRUE);

    current->neighbour_id = 0;
    vertice_id++; // current OSyncFormatConverterPathVertice id for its neighbours

    /* Check if we have reached a target format */
    if (target_fn(fndata, current->format)) {
      osync_trace(TRACE_INTERNAL, "Target %s found", osync_objformat_get_name(current->format));
      /* Done. return the result */
      result = current;
      break;
    }
		
    /*
     * Optimizations : 
     */
    if (last_converter_fn(fndata, tree)) {
      osync_trace(TRACE_INTERNAL, "Last converter for target format reached: %s.", (result)?osync_objformat_get_name(result->format):"null");
      osync_format_converter_path_vertice_unref(current);
      break;
    }
    /* Check if saved result is equal to current regarding losses, objtype_changes
     * and conversions. If yes, we can skip further searches and break here */
    if (result) {
      if (result->losses <= current->losses && result->objtype_changes <= current->objtype_changes && result->conversions <= current->conversions) {
        osync_trace(TRACE_INTERNAL, "Target %s found in queue", osync_objformat_get_name(result->format));
        tree->search = g_list_remove(tree->search, result);
        break;
      } else {
        result = NULL;
      }
    }


    /*
     * If we dont have reached a target, we look at our neighbours 
     */
    osync_trace(TRACE_INTERNAL, "Looking at %s's neighbours.", osync_objformat_get_name(current->format));

    /* Convert the "current" data to the last edge found in the "current" conversion path  */
    current->data = osync_data_clone(sourcedata, error);
    path_tmp = osync_converter_path_new(error);
    if (!path_tmp)
      goto error;
    for (e = current->path; e; e = e->next) {
      OSyncFormatConverter *edge = e->data;
      osync_converter_path_add_edge(path_tmp, edge);
    }
    if (!(osync_format_env_convert(env, path_tmp, current->data, error))) {
      osync_trace(TRACE_INTERNAL, "osync format env convert on this path failed - skipping the conversion");
      continue;
    }
    osync_converter_path_unref(path_tmp);

    /* Find all the neighboors or "current" at its current conversion point */
    while ((neighbour = osync_format_converter_path_vertice_get_next_vertice_neighbour(env, tree, current, error))) {
      GString *string = g_string_new("");
      guint size = g_list_length(neighbour->path);
      guint count = 0;

      neighbour->id = vertice_id;
      neighbour_id++;
      neighbour->neighbour_id = neighbour_id;

      neighbour->preferred = FALSE;
      if (current->preferred)	  /* preferred is inherited by the neighbours */
        neighbour->preferred = TRUE;
      if(preferred_format && !strcmp(preferred_format, osync_objformat_get_name(neighbour->format)))
        neighbour->preferred = TRUE;

      /* log neighbour to be added to the tree search list */
      for (e = neighbour->path; e; e = e->next) {
        OSyncFormatConverter *edge = e->data;
        count ++;
        if (count == 1) {
          g_string_append(string, osync_objformat_get_name(osync_converter_get_sourceformat(edge)));
          g_string_append(string, " -> ");
        }
        g_string_append(string, osync_objformat_get_name(osync_converter_get_targetformat(edge)));
        if (size > 1 && count < size)
          g_string_append(string, " -> ");
      }
      osync_trace(TRACE_INTERNAL, "%s's neighbour : %s (%s)", osync_objformat_get_name(current->format), osync_objformat_get_name(neighbour->format), string->str);
      g_string_free(string, TRUE);

      /* We found a neighbour and insert it sorted in our search queue 
         If vertices are equals in losses, objtypes and conversions, first registered is inserted before the others 
         in the same OSyncFormatConverterPathVertice group (vertice_id) */
      tree->search = g_list_insert_sorted(tree->search, neighbour, osync_format_converter_path_vertice_compare_distance); 

      /* Optimization:
       * We found a possible target. Save it. */
      if (target_fn(fndata, neighbour->format)) {
        osync_trace(TRACE_INTERNAL, "Possible target found.");
        result = neighbour;
        osync_format_converter_path_vertice_ref(result);
      }
    }

    if (osync_error_is_set(error))
      goto error_free_tree;
		
    /* Done, drop the reference to the OSyncFormatConverterPathVertice */
    osync_format_converter_path_vertice_unref(current);
  }
			
  if (!result) {
    osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to find conversion path");
    goto error_free_tree;
  }
	
  /* Found it. Create a path object */
  path = osync_converter_path_new(error);
  if (!path)
    goto error;
	
  for (e = result->path; e; e = e->next) {
    OSyncFormatConverter *edge = e->data;
    osync_converter_path_add_edge(path, edge);
  }
	
  /* Drop the reference to the result OSyncFormatConverterPathVertice */
  osync_format_converter_path_vertice_unref(result);
	
  /* Free the tree */
  osync_converter_tree_free(tree);
	
  osync_trace(TRACE_EXIT, "%s: %p", __func__, path);
  return path;

 error_free_tree:
  osync_converter_tree_free(tree);
 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return NULL;
}