OSyncData *osync_data_clone(OSyncData *source, OSyncError **error) { OSyncData *data = NULL; char *buffer = NULL; unsigned int size = 0; osync_assert(source); data = osync_data_new(NULL, 0, source->objformat, error); if (!data) return NULL; data->objtype = g_strdup(source->objtype); if (source->data) { if (!osync_objformat_copy(source->objformat, source->data, source->size, &buffer, &size, error)) { osync_data_unref(data); return NULL; } osync_data_set_data(data, buffer, size); } return data; }
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; }
END_TEST START_TEST (detect_smart_no) { OSyncError *error = NULL; OSyncFormatEnv *env = osync_format_env_new(&error); fail_unless(error == NULL); OSyncObjFormat *format1 = osync_objformat_new("Format1", "Type1", &error); OSyncObjFormat *format2 = osync_objformat_new("Format2", "Type1", &error); fail_unless(error == NULL); OSyncFormatConverter *conv = osync_converter_new_detector(format2, format1, detect_false, &error); fail_unless(error == NULL); osync_format_env_register_converter(env, conv, &error); mark_point(); OSyncData *data = osync_data_new("test", 5, format2, &error); fail_unless(error == NULL); OSyncObjFormat *result = osync_format_env_detect_objformat(env, data); fail_unless(!result); fail_unless(osync_data_get_objformat(data) == format2); osync_data_unref(data); osync_format_env_unref(env); }
END_TEST START_TEST (mapping_compare) { char *testbed = setup_testbed(NULL); char *formatdir = g_strdup_printf("%s/formats", testbed); OSyncError *error = NULL; OSyncFormatEnv *formatenv = osync_format_env_new(&error); fail_unless(formatenv != NULL, NULL); fail_unless(error == NULL, NULL); fail_unless(osync_format_env_load_plugins(formatenv, formatdir, &error), NULL); fail_unless(error == NULL, NULL); OSyncObjFormat *format = osync_format_env_find_objformat(formatenv, "mockformat1"); fail_unless(format != NULL, NULL); /*OSyncChange *change = osync_change_new(&error); fail_unless(change != NULL, NULL); fail_unless(error == NULL, NULL); osync_change_set_uid(change, "uid");*/ OSyncData *data1 = osync_data_new("test", 5, format, &error); fail_unless(data1 != NULL, NULL); fail_unless(error == NULL, NULL); OSyncMapping *mapping = osync_mapping_new(&error); fail_unless(mapping != NULL, NULL); fail_unless(error == NULL, NULL); OSyncMappingEntry *entry = osync_mapping_entry_new(&error); fail_unless(entry != NULL, NULL); fail_unless(error == NULL, NULL); //osync_mapping_entry_update(entry, change); osync_format_env_free(formatenv); g_free(formatdir); destroy_testbed(testbed); }
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; }
OSyncFormatConverterPath *osync_format_env_find_path_formats(OSyncFormatEnv *env, OSyncObjFormat *sourceformat, OSyncList *targets, OSyncError **error) { OSyncFormatConverterPath *path = NULL; OSyncData *sourcedata = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, env, sourceformat, targets, 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_format_sinks, osync_format_converter_tree_target_fn_format_sinks_reached_lastconverter, targets, 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; }
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__); }
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__); }
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__); }
/** 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__); }