Ejemplo n.º 1
0
static void _osyncplugin_ctx_callback_disconnect(void *user_data, OSyncError *error)
{
	OSyncError *locerror = NULL;
	Command *cmd = NULL;
	OSyncObjTypeSink *sink = NULL;

	assert(user_data);

	cmd = (Command *) user_data;		
	sink = cmd->sink;

	if (error) {
		osync_error_set_from_error(&locerror, &error);
		goto error;
	}

	if (osync_objtype_sink_get_name(sink))
		printf("Sink \"%s\"", osync_objtype_sink_get_name(sink));
	else
		printf("Main Sink");

	printf(" disconnected.\n");

	g_mutex_lock(cmd->mutex);
	g_cond_signal(cmd->cond);
	cmd->done = TRUE;
	g_mutex_unlock(cmd->mutex);

	return;
 error:
	fprintf(stderr, "ERROR: %s\n", osync_error_print(&locerror));
	return;
}
Ejemplo n.º 2
0
static void _osyncplugin_ctx_callback_slowsync(void *user_data)
{

	OSyncObjTypeSink *sink = (OSyncObjTypeSink *) user_data;

	printf("SlowSync got requested by CONNECT function");
	if (osync_objtype_sink_get_name(sink))
		printf(" for ObjType: \"%s\"", osync_objtype_sink_get_name(sink));

	connect_requested_slowsync = TRUE;

	printf(".\n");
}
Ejemplo n.º 3
0
static void _osyncplugin_ctx_callback_syncdone(void *user_data, OSyncError *error)
{
	OSyncError *locerror = NULL;
	Command *cmd = (Command *) user_data;		
	OSyncObjTypeSink *sink = NULL;

	assert(user_data);

	sink = cmd->sink;

	if (error) {
		osync_error_set_from_error(&locerror, &error);
		goto error;
	}

	g_mutex_lock(cmd->mutex);
	g_cond_signal(cmd->cond);
	cmd->done = TRUE;
	g_mutex_unlock(cmd->mutex);

	return;
 error:
	fprintf(stderr, "ERROR for sink \"%s\": %s\n", osync_objtype_sink_get_name(sink), osync_error_print(&locerror));
	return;
}
Ejemplo n.º 4
0
static void connect(void *userdata, OSyncPluginInfo *info, OSyncContext *ctx)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, userdata, info, ctx);
	//Each time you get passed a context (which is used to track
	//calls to your plugin) you can get the data your returned in
	//initialize via this call:
	// plugin_environment *env = (plugin_environment *)userdata;

	//The sink specific userdata you can get with this calls:
	OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info);
	sink_environment *sinkenv = osync_objtype_sink_get_userdata(sink);


	OSyncError *error = NULL;

	/*
	 * Now connect to your devices and report
	 * 
	 * an error via:
	 * osync_context_report_error(ctx, ERROR_CODE, "Some message");
	 * 
	 * or success via:
	 * osync_context_report_success(ctx);
	 * 
	 * You have to use one of these 2 somewhere to answer the context.
	 * 
	 */


	//If you need a hashtable you make it here
	char *tablepath = osync_strdup_printf("%s/hashtable.db", osync_plugin_info_get_configdir(info));
	sinkenv->hashtable = osync_hashtable_new(tablepath, osync_objtype_sink_get_name(sink), &error);
	osync_free(tablepath);

	if (!sinkenv->hashtable)
		goto error;

	//you can also use the anchor system to detect a device reset
	//or some parameter change here. Check the docs to see how it works
	char *lanchor = NULL;
	//Now you get the last stored anchor from the device
	char *anchorpath = osync_strdup_printf("%s/anchor.db", osync_plugin_info_get_configdir(info));

	if (!osync_anchor_compare(anchorpath, "lanchor", lanchor))
		osync_objtype_sink_set_slowsync(sink, TRUE);

	osync_free(anchorpath);

	osync_context_report_success(ctx);
	osync_trace(TRACE_EXIT, "%s", __func__);
	return;

error:
	osync_context_report_osyncerror(ctx, error);
	osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error));
	osync_error_unref(&error);
}
Ejemplo n.º 5
0
//typedef void (* OSyncContextCallbackFn)(void *, OSyncError *);
static void _osyncplugin_ctx_callback_getchanges(void *user_data, OSyncError *error)
{
	Command *cmd = (Command *) user_data;		
	OSyncObjTypeSink *sink = cmd->sink;

	if (error)
		fprintf(stderr, "Sink \"%s\": %s\n", osync_objtype_sink_get_name(sink), osync_error_print(&error));

	g_mutex_lock(cmd->mutex);
	g_cond_signal(cmd->cond);
	cmd->done = TRUE;
	g_mutex_unlock(cmd->mutex);

}
Ejemplo n.º 6
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);
}
OSyncObjTypeSink *osync_plugin_info_find_objtype(OSyncPluginInfo *info, const char *name)
{
	OSyncList *p;
	OSyncObjTypeSink *sink = NULL;
	osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, info, name);
	osync_assert(info);

	for (p = info->objtype_sinks; p; p = p->next) {
		sink = p->data;
		if (g_ascii_strcasecmp(osync_objtype_sink_get_name(sink), name) == 0)
			goto done;
	}
	
	osync_trace(TRACE_EXIT, "%s: NULL", __func__);
	return NULL;

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

}
Ejemplo n.º 8
0
static void mock_read(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *change, void *data)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, sink, info, ctx, change, data);
	MockDir *dir = data;
	OSyncError *error = NULL;

	char *filename = g_strdup_printf("%s/%s", dir->path, osync_change_get_uid(change));

	OSyncFileFormat *file = osync_try_malloc0(sizeof(OSyncFileFormat), &error);
	osync_assert(file);
	file->path = g_strdup(osync_change_get_uid(change));

	struct stat filestats;
	stat(filename, &filestats);
	file->userid = filestats.st_uid;
	file->groupid = filestats.st_gid;
	file->mode = filestats.st_mode;
	file->last_mod = filestats.st_mtime;

	osync_assert(osync_file_read(filename, &(file->data), &(file->size), &error));

	OSyncData *odata = osync_data_new((char *)file, sizeof(OSyncFileFormat), dir->objformat, &error);
	osync_assert(odata);

	osync_trace(TRACE_INTERNAL, "odata: %p", odata);

	osync_data_set_objtype(odata, osync_objtype_sink_get_name(sink));
	osync_change_set_data(change, odata);
	osync_data_unref(odata);

	osync_context_report_success(ctx);

	g_free(filename);

	osync_trace(TRACE_EXIT, "%s", __func__);
	return;
}
Ejemplo n.º 9
0
static void get_changes(void *userdata, OSyncPluginInfo *info, OSyncContext *ctx)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, userdata, info, ctx);

	//plugin_environment *env = (plugin_environment *)userdata;
	OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info);
	OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info);
	sink_environment *sinkenv = osync_objtype_sink_get_userdata(sink);

	OSyncError *error = NULL;

	//If you use opensync hashtables you can detect if you need
	//to do a slow-sync and set this on the hastable directly
	//otherwise you have to make 2 function like "get_changes" and
	//"get_all" and decide which to use using
	//osync_objtype_sink_get_slow_sync
	if (osync_objtype_sink_get_slowsync(sinkenv->sink)) {
		osync_trace(TRACE_INTERNAL, "Slow sync requested");

		if (osync_hashtable_slowsync(sinkenv->hashtable, &error)) {
			osync_context_report_osyncerror(ctx, error);
			osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(&error));
			osync_error_unref(&error);
			return;
		}

	}

	/*
	 * Now you can get the changes.
	 * Loop over all changes you get and do the following:
	 */

	do {
		char *hash = osync_strdup("<the calculated hash of the object>");
		char *uid = osync_strdup("<some uid>");

		//Now get the data of this change
		char *data = NULL;

		//Make the new change to report
		OSyncChange *change = osync_change_new(&error);
		if (!change) {
			osync_context_report_osyncwarning(ctx, error);
			osync_error_unref(&error);
			continue;
		}

		//Now set the uid of the object
		osync_change_set_uid(change, uid);
		osync_change_set_hash(change, hash);
		
		OSyncChangeType changetype = osync_hashtable_get_changetype(sinkenv->hashtable, change);
		osync_change_set_changetype(change, changetype);
		
		// Update entry.
		// Set the hash of the object (optional, only required if you use hashtabled)
		osync_hashtable_update_change(sinkenv->hashtable, change);
		
		if (changetype == OSYNC_CHANGE_TYPE_UNMODIFIED) {
			osync_free(hash);
			osync_free(uid);
			osync_change_unref(change);
			continue;
		}

		osync_free(hash);
		osync_free(uid);

		OSyncObjFormat *format = osync_format_env_find_objformat(formatenv, "<objformat>");
		
		OSyncData *odata = osync_data_new(data, 0, format, &error);
		if (!odata) {
			osync_change_unref(change);
			osync_context_report_osyncwarning(ctx, error);
			osync_error_unref(&error);
			continue;
		}

		osync_data_set_objtype(odata, osync_objtype_sink_get_name(sinkenv->sink));

		//Now you can set the data for the object
		osync_change_set_data(change, odata);
		osync_data_unref(odata);

		// just report the change via
		osync_context_report_change(ctx, change);

		osync_change_unref(change);

		osync_free(uid);
	} while(0);

	//When you are done looping and if you are using hashtables
	//check for deleted entries ... via hashtable
	OSyncList *u, *uids = osync_hashtable_get_deleted(sinkenv->hashtable);
	for (u = uids; u; u = u->next) {
		OSyncChange *change = osync_change_new(&error);
		if (!change) {
			osync_context_report_osyncwarning(ctx, error);
			osync_error_unref(&error);
			continue;
		}

		const char *uid = u->data;
		osync_change_set_uid(change, uid);
		osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED);
		
		OSyncObjFormat *format = osync_format_env_find_objformat(formatenv, "<objformat>");
		
		OSyncData *odata = osync_data_new(NULL, 0, format, &error);
		if (!odata) {
			osync_change_unref(change);
			osync_context_report_osyncwarning(ctx, error);
			osync_error_unref(&error);
			continue;
		}

		osync_data_set_objtype(odata, osync_objtype_sink_get_name(sinkenv->sink));
		osync_change_set_data(change, odata);
		osync_data_unref(odata);

		osync_context_report_change(ctx, change);

		osync_hashtable_update_change(sinkenv->hashtable, change);

		osync_change_unref(change);
	}
	osync_list_free(uids);

	//Now we need to answer the call
	osync_context_report_success(ctx);
	osync_trace(TRACE_EXIT, "%s", __func__);
}
Ejemplo n.º 10
0
static void *initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error)
{
	/*
	 * get the config
	 */
	OSyncPluginConfig *config = osync_plugin_info_get_config(info);
	if (!config) {
		osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get config.");
		goto error;
	}
	/*
	 * You need to specify the <some name>_environment somewhere with
	 * all the members you need
	*/
	plugin_environment *env = osync_try_malloc0(sizeof(plugin_environment), error);
	if (!env)
		goto error;

	env->sink_envs = NULL;
	
	osync_trace(TRACE_INTERNAL, "The config: %s", osync_plugin_info_get_config(info));

	/* 
	 * Process the config here and set the options on your environment
	*/
	/*
	 * Process plugin specific advanced options 
	 */
	OSyncList *optslist = osync_plugin_config_get_advancedoptions(config);
	for (; optslist; optslist = optslist->next) {
		OSyncPluginAdvancedOption *option = optslist->data;

		const char *val = osync_plugin_advancedoption_get_value(option);
		const char *name = osync_plugin_advancedoption_get_name(option);

		if (!strcmp(name,"<your-option>")) {
			if (!strcmp(val, "<your-value>")) {
				/*
				 * set a varaible to a specific value
				 */;
			}
		}
	}
	/*
	 * Process Ressource options
	 */
	int i, numobjs = osync_plugin_info_num_objtypes(info);
	for (i = 0; i < numobjs; i++) {
		sink_environment *sinkenv = osync_try_malloc0(sizeof(sink_environment), error);
		if (!sinkenv)
			goto error_free_env;

		sinkenv->sink = osync_plugin_info_nth_objtype(info, i);
		osync_assert(sinkenv->sink);

		const char *objtype = osync_objtype_sink_get_name(sinkenv->sink);
		OSyncPluginResource *res = osync_plugin_config_find_active_resource(config, objtype);
		
		/* get objformat sinks */
		OSyncList *s = osync_plugin_resource_get_objformat_sinks(res);
		for (; s; s = s->next) {
			OSyncObjFormatSink *fsink = s->data; // there could be only one sink
			const char *objformat = osync_objformat_sink_get_objformat(fsink);
			osync_assert(objformat);
			osync_trace(TRACE_INTERNAL, "objtype %s has objformat %s", objtype, objformat);
		}	

		/* Every sink can have different functions ... */
		OSyncObjTypeSinkFunctions functions;
		memset(&functions, 0, sizeof(functions));
		functions.connect = connect;
		functions.disconnect = disconnect;
		functions.get_changes = get_changes;
		functions.commit = commit_change;
		functions.sync_done = sync_done;

		/* We pass the OSyncFileDir object to the sink, so we dont have to look it up
		 * again once the functions are called */
		osync_objtype_sink_set_functions(sinkenv->sink, functions, sinkenv);
		
		osync_trace(TRACE_INTERNAL, "The configdir: %s", osync_plugin_info_get_configdir(info));
		char *tablepath = osync_strdup_printf("%s/hashtable.db", osync_plugin_info_get_configdir(info));
		sinkenv->hashtable = osync_hashtable_new(tablepath, objtype, error);
		osync_free(tablepath);
		env->sink_envs = osync_list_append(env->sink_envs, sinkenv);
	}
	
	//Now your return your struct.
	return (void *) env;

error_free_env:
	free_env(env);
error:
	osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
	return NULL;
}
Ejemplo n.º 11
0
static void *initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error)
{
	/*
	 * get the config
	 */
	OSyncPluginConfig *config = osync_plugin_info_get_config(info);
	if (!config) {
		osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get config.");
		goto error;
	}
	/*
	 * You need to specify the <some name>_environment somewhere with
	 * all the members you need
	*/
	plugin_environment *env = osync_try_malloc0(sizeof(plugin_environment), error);
	if (!env)
		goto error;

	/* 
	 * Process the config here and set the options on your environment
	 * if required.
	*/
	/*
	 * Process plugin specific advanced options 
	 */
	OSyncList *optslist = osync_plugin_config_get_advancedoptions(config);
	OSyncList *o;
	for (o = optslist; o; o = o->next) {
		OSyncPluginAdvancedOption *option = o->data;

		const char *val = osync_plugin_advancedoption_get_value(option);
		const char *name = osync_plugin_advancedoption_get_name(option);

		if (!strcmp(name,"<your-option>")) {
			if (!strcmp(val, "<your-value>")) {
				/*
				 * set a varaible to a specific value
				 */;
			}
		}
	}
	osync_list_free(optslist);
	
	/*
	 * Process Ressource options
	 */
	OSyncList *l, *list = NULL;
	list = osync_plugin_info_get_objtype_sinks(info);
	for (l=list; l; l = l->next) {
		OSyncObjTypeSink *sink = (OSyncObjTypeSink *) l->data;

		const char *objtype = osync_objtype_sink_get_name(sink);
		OSyncPluginResource *res = osync_plugin_config_find_active_resource(config, objtype);
		
		/* get objformat sinks */
		OSyncList *s = NULL;
		OSyncList *objformats = osync_plugin_resource_get_objformat_sinks(res);
		for (s = objformats; s; s = s->next) {
			OSyncObjFormatSink *fsink = s->data; // there could be only one sink
			const char *objformat = osync_objformat_sink_get_objformat(fsink);
			osync_assert(objformat);
			osync_trace(TRACE_INTERNAL, "objtype %s has objformat %s", objtype, objformat);
		}	
		osync_list_free(objformats);
		/* Every sink can have different functions ... */
		osync_objtype_sink_set_connect_func(sink, connect);
		osync_objtype_sink_set_disconnect_func(sink, disconnect);
		osync_objtype_sink_set_get_changes_func(sink, get_changes);
		osync_objtype_sink_set_commit_func(sink, commit_change);
		osync_objtype_sink_set_sync_done_func(sink, sync_done);

		/*
		 * If you need plugin specific userdata passed to this
		 * plugin sink functions. You can set it with:
		 *
		 * osync_objtype_sink_set_userdata(sink, userdata_pointer);
		 */

		/* Request a Hahstable here - if you need it.
		 * It will be later available via osync_objtype_sink_get_hashtable(OSyncObjTypeSink *)
		 * in the plugin sink functions (e.g. connect, get_changes, commit, ...)
		 */ 
		osync_objtype_sink_enable_hashtable(sink, TRUE);

	}

	osync_list_free(list);
	
	//Now your return your environemtn struct.
	return (void *) env;

error:
	osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
	return NULL;
}
Ejemplo n.º 12
0
void claws_mail_event_get_changes(void *userdata, OSyncPluginInfo *info,
																	OSyncContext *ctx)
{
	int ii;
	char **uids;
	char *vevent;

	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, userdata, info, ctx);

	OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info);
	ClawsMailSinkEnv *sinkenv = osync_objtype_sink_get_userdata(sink);

	OSyncError *error = NULL;

	osync_hashtable_reset_reports(sinkenv->hashtable);

	/* check for slowsync and prepare the "event" hashtable if needed */
	if(osync_objtype_sink_get_slowsync(sinkenv->sink)) {
		osync_trace(TRACE_INTERNAL, "Slow sync requested");
		if(!osync_hashtable_slowsync(sinkenv->hashtable, &error))	{
			osync_context_report_osyncerror(ctx, error);
			osync_trace(TRACE_EXIT_ERROR, "%s - %s", __func__,
									osync_error_print(&error));
			osync_error_unref(&error);
			return;
		}
	}

	/* While getting all events, one at a time */
	while((vevent = claws_mail_connect_get_events()) != NULL) {
		gchar *uid;
		gchar *hash;
		char *data;
		OSyncChangeType changetype;
		OSyncChange *change;
		OSyncData *odata;
		
		hash = event_hash(vevent);
		uid = get_uid_from_event(vevent);

		/* Now get the data of this change */
		data = vevent;

		/* Report every entry .. every unreported entry got deleted. */
		osync_trace(TRACE_INTERNAL, "hhb: Report: %s",uid);
		osync_hashtable_report(sinkenv->hashtable, uid);

		changetype = osync_hashtable_get_changetype(sinkenv->hashtable, uid, hash);

		if (changetype == OSYNC_CHANGE_TYPE_UNMODIFIED) {
			g_free(hash);
			g_free(uid);
			continue;
		}

		/* Set the hash of the object */
		osync_hashtable_update_hash(sinkenv->hashtable, changetype, uid, hash);

		/* Make the new change to report */
		change = osync_change_new(&error);

		if(!change) {
			osync_context_report_osyncwarning(ctx, error);
			osync_error_unref(&error);
			g_free(uid);
			g_free(hash);
			continue;
		}

		/* Now set the uid of the object */
		osync_change_set_uid(change, uid);
		osync_change_set_hash(change, hash);
		osync_change_set_changetype(change, changetype);

		g_free(hash);
		g_free(uid);

		odata = osync_data_new(data, strlen(data), sinkenv->objformat, &error);
		if (!odata) {
			osync_change_unref(change);
			osync_context_report_osyncwarning(ctx, error);
			osync_error_unref(&error);
			continue;
		}

		osync_data_set_objtype(odata, osync_objtype_sink_get_name(sinkenv->sink));

		/* Set the data for the object */
		osync_change_set_data(change, odata);
		osync_data_unref(odata);

		/* Report the change */
		osync_context_report_change(ctx, change);

		osync_change_unref(change);
	}

	/* Check for deleted entries */
	uids = osync_hashtable_get_deleted(sinkenv->hashtable);

	for (ii=0; uids[ii]; ii++) {
		OSyncData *odata;
		OSyncChange *change = osync_change_new(&error);
		if (!change) {
			g_free(uids[ii]);
			osync_context_report_osyncwarning(ctx, error);
			osync_error_unref(&error);
			continue;
		}

		osync_change_set_uid(change, uids[ii]);
		osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED);

		odata = osync_data_new(NULL, 0, sinkenv->objformat, &error);
		if (!odata) {
			g_free(uids[ii]);
			osync_change_unref(change);
			osync_context_report_osyncwarning(ctx, error);
			osync_error_unref(&error);
			continue;
		}

		osync_data_set_objtype(odata, osync_objtype_sink_get_name(sinkenv->sink));
		osync_change_set_data(change, odata);
		osync_data_unref(odata);

		osync_context_report_change(ctx, change);

		osync_hashtable_update_hash(sinkenv->hashtable,
				osync_change_get_changetype(change), osync_change_get_uid(change),
																NULL);

		osync_change_unref(change);
		g_free(uids[ii]);
	}
	g_free(uids);

	osync_context_report_success(ctx);
	osync_trace(TRACE_EXIT, "%s", __func__);
}
Ejemplo n.º 13
0
/* In initialize, we get the config for the plugin. Here we also must register
 * all _possible_ objtype sinks. */
static void *mock_initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, plugin, info, error);

	if (mock_get_error(info->memberid, "INIT_NULL_NOERROR")) {
		osync_trace(TRACE_EXIT, "%s: %s", __func__, "Everything is fine. I don't need plugin userdata.");
		return NULL;
	}

	if (mock_get_error(info->memberid, "INIT_NULL")) {
		osync_error_set(error, OSYNC_ERROR_EXPECTED, "Triggering INIT_NULL error");
		osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
		return NULL;
	}

	mock_env *env = osync_try_malloc0(sizeof(mock_env), error);
	osync_assert(env);

	OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info);
	osync_assert(formatenv);

	OSyncPluginConfig *config = osync_plugin_info_get_config(info);
	osync_assert(config);

	if (mock_get_error(info->memberid, "MAINSINK_CONNECT")) {
		env->mainsink = osync_objtype_main_sink_new(error);

		osync_objtype_sink_set_connect_func(env->mainsink, mock_connect);
		osync_objtype_sink_set_disconnect_func(env->mainsink, mock_mainsink_disconnect);

		osync_objtype_sink_set_userdata(env->mainsink, env);

		osync_plugin_info_set_main_sink(info, env->mainsink);
	}

	/* Now we register the objtypes that we can sync. This plugin is special. It can
	 * synchronize any objtype we configure it to sync and where a conversion
	 * path to the file format can be found */
	OSyncList *objtypesinks = osync_plugin_info_get_objtype_sinks(info);
	OSyncList *list = NULL;
	for (list = objtypesinks;list; list = list->next) {
		MockDir *dir = osync_try_malloc0(sizeof(MockDir), error);
		osync_assert(dir);

		dir->committed_all = TRUE;

		OSyncObjTypeSink *sink = (OSyncObjTypeSink*)list->data;
		osync_assert(sink);

		const char *objtype = osync_objtype_sink_get_name(sink);
		dir->res = osync_plugin_config_find_active_resource(config, objtype);
		osync_plugin_resource_ref(dir->res);
		dir->path = osync_plugin_resource_get_path(dir->res);
		osync_assert(dir->path);

		OSyncList *format_sinks = osync_plugin_resource_get_objformat_sinks(dir->res);
		osync_assert(osync_list_length(format_sinks) == 1);
		OSyncObjFormatSink *format_sink = osync_list_nth_data(format_sinks, 0);
		const char *objformat_str = osync_objformat_sink_get_objformat(format_sink);
		osync_assert(objformat_str);
		dir->objformat = osync_format_env_find_objformat(formatenv, objformat_str);
		osync_assert(dir->objformat);
		osync_objformat_ref(dir->objformat);

		osync_list_free(format_sinks);
		/*
		const char *objformat = osync_objformat_get_name(dir->objformat);
		OSyncObjFormatSink *format_sink = osync_objformat_sink_new(objformat, error);
		if (!format_sink)
			return NULL;

		osync_objtype_sink_add_objformat_sink(sink, format_sink);
		*/

		/* Sanity check for connect_done */
		dir->connect_done = TRUE;

		if (!mock_get_error(info->memberid, "MAINSINK_CONNECT")) {
			osync_objtype_sink_set_connect_func(sink, mock_connect);
			osync_objtype_sink_set_connect_done_func(sink, mock_connect_done);
			osync_objtype_sink_set_disconnect_func(sink, mock_disconnect);
		}

		osync_objtype_sink_set_get_changes_func(sink, mock_get_changes);

		osync_objtype_sink_set_committed_all_func(sink, mock_committed_all);
		osync_objtype_sink_set_commit_func(sink, mock_commit_change);
		osync_objtype_sink_set_read_func(sink, mock_read);
		osync_objtype_sink_set_sync_done_func(sink, mock_sync_done);

		/* We pass the MockDir object to the sink, so we dont have to look it up
		 * again once the functions are called */
		osync_objtype_sink_set_userdata(sink, dir);

		/* Request an Anchor */
		osync_objtype_sink_enable_state_db(sink, TRUE);

		/* Request an Hashtable */
		osync_objtype_sink_enable_hashtable(sink, TRUE);

		//Lets reduce the timeouts a bit so the checks work faster
		osync_objtype_sink_set_connect_timeout(sink, 2);
		osync_objtype_sink_set_getchanges_timeout(sink, 2);
		osync_objtype_sink_set_commit_timeout(sink, 4);
		osync_objtype_sink_set_committedall_timeout(sink, 4);
		osync_objtype_sink_set_syncdone_timeout(sink, 2);
		osync_objtype_sink_set_disconnect_timeout(sink, 2);

		osync_objtype_sink_set_read_timeout(sink, 2);


/* XXX No testcase is currently using this at all! */
#if 0

		if (g_getenv("NO_TIMEOUTS")) {

			/* XXX Timeout value of wouldn't work out, since
			   the Sink object would fallback to the default timeout value:

			 sink->timeout.connect ? sink->timeout.connect : OSYNC_SINK_TIMEOUT_CONNECT;

			 Really needed?!
			 */

			osync_objtype_sink_set_connect_timeout(sink, 0);
			osync_objtype_sink_set_getchanges_timeout(sink, 0);
			osync_objtype_sink_set_commit_timeout(sink, 0);
			osync_objtype_sink_set_committedall_timeout(sink, 0);
			osync_objtype_sink_set_syncdone_timeout(sink, 0);
			osync_objtype_sink_set_disconnect_timeout(sink, 0);

			osync_objtype_sink_set_read_timeout(sink, 0);
		}

		/* What is meant by this?! Maybe OSyncPlugin.useable?! Not used at all...
		if (g_getenv("IS_AVAILABLE"))
			info->functions.is_available = mock_is_available;
		*/

#endif
		env->directories = g_list_append(env->directories, dir);
	}
	osync_list_free(objtypesinks);
	osync_trace(TRACE_EXIT, "%s: %p", __func__, env);
	return (void *)env;
}
Ejemplo n.º 14
0
static void mock_get_changes(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, osync_bool slow_sync, void *data)
{
	osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %i, %p)", __func__, sink, info, ctx, slow_sync, data);
	MockDir *dir = data;
	OSyncError *error = NULL;
	OSyncHashTable *hashtable = osync_objtype_sink_get_hashtable(sink);

	osync_assert(dir->committed_all == TRUE);
	dir->committed_all = FALSE;

	osync_assert(dir->connect_done == TRUE);
	dir->connect_done = FALSE;

	/* Validate that connect_doene and get_changes slow_sync
	 * is the same. To avoid mix-up of a "late slow-sync".
	 */
	if (!mock_get_error(info->memberid, "MAINSINK_CONNECT"))
		osync_assert(dir->connect_done_slowsync == slow_sync);

	if (mock_get_error(info->memberid, "GET_CHANGES_ERROR")) {
		osync_context_report_error(ctx, OSYNC_ERROR_EXPECTED, "Triggering GET_CHANGES_ERROR error");
		osync_trace(TRACE_EXIT_ERROR, "%s - Triggering GET_CHANGES error", __func__);
		return;
	}

	if (mock_get_error(info->memberid, "GET_CHANGES_TIMEOUT")) {
		osync_trace(TRACE_EXIT, "%s - Triggering GET_CHANGES_TIMEOUT (without context report!)", __func__);
		return;
	}

	if (mock_get_error(info->memberid, "GET_CHANGES_TIMEOUT2"))
		g_usleep(8*G_USEC_PER_SEC);

	if (slow_sync) {
		osync_trace(TRACE_INTERNAL, "Slow sync requested");
		osync_assert(osync_hashtable_slowsync(hashtable, &error));
	}

	osync_trace(TRACE_INTERNAL, "get_changes for %s", osync_objtype_sink_get_name(sink));

	mock_report_dir(dir, NULL, ctx, info, sink);

	OSyncList *u, *uids = osync_hashtable_get_deleted(hashtable);
	for (u = uids; u; u = u->next) {
		OSyncChange *change = osync_change_new(&error);
		osync_assert(change);

		const char *uid = u->data;

		osync_change_set_uid(change, uid);
		osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED);

		OSyncData *odata = osync_data_new(NULL, 0, dir->objformat, &error);
		osync_assert(odata);

		osync_data_set_objtype(odata, osync_objtype_sink_get_name(sink));
		osync_change_set_data(change, odata);
		osync_data_unref(odata);

		osync_context_report_change(ctx, change);

		osync_hashtable_update_change(hashtable, change);

		osync_change_unref(change);
	}

	osync_context_report_success(ctx);
	osync_trace(TRACE_EXIT, "%s", __func__);
}
Ejemplo n.º 15
0
/** Report files on a directory
 *
 * NOTE: If 'dir' is non-empty it MUST start it a slash. This is just
 * to make easier concatenation of the paths, and we can just concatenate
 * fsinfo->path and subdir to get the complete path.
 *
 * @param dir The fsinfo->path subdirectory that should be reported. Use
 *            an empty string to report files on fsinfo->path. Should
 *            start with a slash. See note above.
 *
 */
static void mock_report_dir(MockDir *directory, const char *subdir, OSyncContext *ctx, OSyncPluginInfo *info, OSyncObjTypeSink *sink)
{
	GError *gerror = NULL;
	const char *de = NULL;
	char *path = NULL;
	GDir *dir = NULL;
	OSyncError *error = NULL;
	OSyncList *sorted_dir_list = NULL;

	osync_trace(TRACE_ENTRY, "%s(%p, %s, %p, %p)", __func__, directory, subdir, ctx, sink);

	OSyncHashTable *hashtable = osync_objtype_sink_get_hashtable(sink);
	OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info);
	osync_assert(formatenv);

	path = g_build_filename(directory->path, subdir, NULL);
	osync_trace(TRACE_INTERNAL, "path %s", path);

	dir = g_dir_open(path, 0, &gerror);
	osync_assert(dir);

	while((de = g_dir_read_name(dir))) {
		sorted_dir_list = osync_list_insert_sorted(sorted_dir_list,
			g_strdup(de), (OSyncCompareFunc)strcmp);
	}

	g_dir_close(dir);

	while(sorted_dir_list) {
		de = sorted_dir_list->data;
		char *filename = g_build_filename(path, de, NULL);
		char *relative_filename = NULL;
		if (!subdir)
			relative_filename = g_strdup(de);
		else
			relative_filename = g_build_filename(subdir, de, NULL);
		g_free(sorted_dir_list->data);
		sorted_dir_list = osync_list_remove(sorted_dir_list, sorted_dir_list->data);

		osync_trace(TRACE_INTERNAL, "path2 %s %s", filename, relative_filename);

		if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {

			struct stat buf;
			stat(filename, &buf);
			char *hash = mock_generate_hash(&buf);

			/* Report normal files */
			OSyncChange *change = osync_change_new(&error);
			osync_assert(change);

			osync_change_set_uid(change, relative_filename);

			osync_change_set_hash(change, hash);
			g_free(hash);

			OSyncChangeType type = osync_hashtable_get_changetype(hashtable, change);

			osync_change_set_changetype(change, type);
			osync_hashtable_update_change(hashtable, change);

			if (type == OSYNC_CHANGE_TYPE_UNMODIFIED) {
				g_free(filename);
				g_free(relative_filename);
				osync_change_unref(change);
				continue;
			}

			OSyncFileFormat *file = osync_try_malloc0(sizeof(OSyncFileFormat), &error);
			osync_assert(file);

			file->path = g_strdup(relative_filename);

			OSyncData *odata = NULL;

			if (!mock_get_error(info->memberid, "ONLY_INFO")) {
				osync_assert(osync_file_read(filename, &(file->data), &(file->size), &error));

				if (mock_get_error(info->memberid, "SLOW_REPORT"))
					g_usleep(1*G_USEC_PER_SEC);

				odata = osync_data_new((char *)file, sizeof(OSyncFileFormat), directory->objformat, &error);
				osync_assert(odata);


				osync_change_set_data(change, odata);

			}

			osync_data_set_objtype(odata, osync_objtype_sink_get_name(sink));
			osync_data_unref(odata);

			osync_context_report_change(ctx, change);

			osync_change_unref(change);
		}

		g_free(filename);
		g_free(relative_filename);

	}

	g_free(path);
	osync_trace(TRACE_EXIT, "%s", __func__);
}