/* * path is here the full path to an item */ static NAObjectItem * read_item( NagpMateConfProvider *provider, const gchar *path, GSList **messages ) { static const gchar *thisfn = "nagp_reader_read_item"; NAObjectItem *item; gchar *full_path; gchar *type; gchar *id; ReaderData *data; g_debug( "%s: provider=%p, path=%s", thisfn, ( void * ) provider, path ); g_return_val_if_fail( NAGP_IS_MATECONF_PROVIDER( provider ), NULL ); g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider ), NULL ); g_return_val_if_fail( !provider->private->dispose_has_run, NULL ); full_path = mateconf_concat_dir_and_key( path, NAGP_ENTRY_TYPE ); type = na_mateconf_utils_read_string( provider->private->mateconf, full_path, TRUE, NAGP_VALUE_TYPE_ACTION ); g_free( full_path ); item = NULL; /* an item may have 'Action' or 'Menu' type; defaults to Action */ if( !type || !strlen( type ) || !strcmp( type, NAGP_VALUE_TYPE_ACTION )){ item = NA_OBJECT_ITEM( na_object_action_new()); } else if( !strcmp( type, NAGP_VALUE_TYPE_MENU )){ item = NA_OBJECT_ITEM( na_object_menu_new()); } else { g_warning( "%s: unknown type '%s' at %s", thisfn, type, path ); } g_free( type ); if( item ){ id = g_path_get_basename( path ); na_object_set_id( item, id ); g_free( id ); data = g_new0( ReaderData, 1 ); data->path = ( gchar * ) path; data->entries = na_mateconf_utils_get_entries( provider->private->mateconf, path ); na_mateconf_utils_dump_entries( data->entries ); na_ifactory_provider_read_item( NA_IFACTORY_PROVIDER( provider ), data, NA_IFACTORY_OBJECT( item ), messages ); na_mateconf_utils_free_entries( data->entries ); g_free( data ); } return( item ); }
static NADataBoxed * get_boxed_from_path( const NagpMateConfProvider *provider, const gchar *path, ReaderData *reader_data, const NADataDef *def ) { static const gchar *thisfn = "nagp_reader_get_boxed_from_path"; NADataBoxed *boxed; gboolean have_entry; gchar *str_value; gboolean bool_value; GSList *slist_value; gint int_value; boxed = NULL; have_entry = na_mateconf_utils_has_entry( reader_data->entries, def->mateconf_entry ); g_debug( "%s: entry=%s, have_entry=%s", thisfn, def->mateconf_entry, have_entry ? "True":"False" ); if( have_entry ){ gchar *entry_path = mateconf_concat_dir_and_key( path, def->mateconf_entry ); boxed = na_data_boxed_new( def ); switch( def->type ){ case NA_DATA_TYPE_STRING: case NA_DATA_TYPE_LOCALE_STRING: str_value = na_mateconf_utils_read_string( provider->private->mateconf, entry_path, TRUE, NULL ); na_boxed_set_from_string( NA_BOXED( boxed ), str_value ); g_free( str_value ); break; case NA_DATA_TYPE_BOOLEAN: bool_value = na_mateconf_utils_read_bool( provider->private->mateconf, entry_path, TRUE, FALSE ); na_boxed_set_from_void( NA_BOXED( boxed ), GUINT_TO_POINTER( bool_value )); break; case NA_DATA_TYPE_STRING_LIST: slist_value = na_mateconf_utils_read_string_list( provider->private->mateconf, entry_path ); na_boxed_set_from_void( NA_BOXED( boxed ), slist_value ); na_core_utils_slist_free( slist_value ); break; case NA_DATA_TYPE_UINT: int_value = na_mateconf_utils_read_int( provider->private->mateconf, entry_path, TRUE, 0 ); na_boxed_set_from_void( NA_BOXED( boxed ), GUINT_TO_POINTER( int_value )); break; default: g_warning( "%s: unknown type=%u for %s", thisfn, def->type, def->name ); g_free( boxed ); boxed = NULL; } g_free( entry_path ); } return( boxed ); }
static void read_done_action_read_profiles( const NAIFactoryProvider *provider, NAObjectAction *action, ReaderData *data, GSList **messages ) { static const gchar *thisfn = "nagp_reader_read_done_action_read_profiles"; GSList *order; GSList *list_profiles; GSList *ip; gchar *profile_id; gchar *profile_path; NAObjectId *found; NAObjectProfile *profile; data->parent = NA_OBJECT_ITEM( action ); order = na_object_get_items_slist( action ); list_profiles = na_mateconf_utils_get_subdirs( NAGP_MATECONF_PROVIDER( provider )->private->mateconf, data->path ); /* read profiles in the specified order * as a protection against bugs in CACT, we check that profile has not * already been loaded */ for( ip = order ; ip ; ip = ip->next ){ profile_id = ( gchar * ) ip->data; found = na_object_get_item( action, profile_id ); if( !found ){ g_debug( "nagp_reader_read_done_action: loading profile=%s", profile_id ); profile_path = mateconf_concat_dir_and_key( data->path, profile_id ); read_done_action_load_profile( provider, data, profile_path, messages ); g_free( profile_path ); } } /* append other profiles * this is mandatory for pre-2.29 actions which introduced order of profiles */ for( ip = list_profiles ; ip ; ip = ip->next ){ profile_id = g_path_get_basename(( const gchar * ) ip->data ); found = na_object_get_item( action, profile_id ); if( !found ){ g_debug( "nagp_reader_read_done_action: loading profile=%s", profile_id ); read_done_action_load_profile( provider, data, ( const gchar * ) ip->data, messages ); } g_free( profile_id ); } /* make sure we have at least one profile */ if( !na_object_get_items_count( action )){ g_warning( "%s: no profile found in MateConf backend", thisfn ); profile = na_object_profile_new_with_defaults(); na_object_attach_profile( action, profile ); } }
static void recursive_unset_helper (MateConfSources *sources, const char *key, const char *locale, MateConfUnsetFlags flags, GSList **notifies, GError **first_error) { GError* err = NULL; GSList* subdirs; GSList* entries; GSList* tmp; const char *locales[2] = { NULL, NULL }; MateConfSources* modified_sources; MateConfSources** modifiedp = NULL; if (notifies) { modified_sources = NULL; modifiedp = &modified_sources; } err = NULL; subdirs = mateconf_sources_all_dirs (sources, key, &err); if (subdirs != NULL) { tmp = subdirs; while (tmp != NULL) { char *s = tmp->data; char *full = mateconf_concat_dir_and_key (key, s); recursive_unset_helper (sources, full, locale, flags, notifies, first_error); g_free (s); g_free (full); tmp = g_slist_next (tmp); } g_slist_free (subdirs); } else { if (err != NULL) { mateconf_log (GCL_DEBUG, "Error listing subdirs of '%s': %s\n", key, err->message); if (*first_error) g_error_free (err); else *first_error = err; err = NULL; } } locales[0] = locale; entries = mateconf_sources_all_entries (sources, key, locale ? locales : NULL, &err); if (err != NULL) { mateconf_log (GCL_DEBUG, "Failure listing entries in '%s': %s\n", key, err->message); if (*first_error) g_error_free (err); else *first_error = err; err = NULL; } if (entries != NULL) { tmp = entries; while (tmp != NULL) { MateConfEntry* entry = tmp->data; char *full, *freeme; full = freeme = mateconf_concat_dir_and_key (key, mateconf_entry_get_key (entry)); mateconf_sources_unset_value (sources, full, locale, modifiedp, &err); if (notifies) { *notifies = prepend_unset_notify (*notifies, modified_sources, full); modified_sources = NULL; freeme = NULL; } if (err != NULL) { mateconf_log (GCL_DEBUG, "Error unsetting '%s': %s\n", full, err->message); if (*first_error) g_error_free (err); else *first_error = err; err = NULL; } if (flags & MATECONF_UNSET_INCLUDING_SCHEMA_NAMES) { mateconf_sources_set_schema (sources, full, NULL, &err); if (err != NULL) { mateconf_log (GCL_DEBUG, "Error unsetting schema on '%s': %s\n", full, err->message); if (*first_error) g_error_free (err); else *first_error = err; err = NULL; } } mateconf_entry_free (entry); g_free (freeme); tmp = g_slist_next (tmp); } g_slist_free (entries); } mateconf_sources_unset_value (sources, key, locale, modifiedp, &err); if (notifies) { *notifies = prepend_unset_notify (*notifies, modified_sources, g_strdup (key)); modified_sources = NULL; } if (err != NULL) { mateconf_log (GCL_DEBUG, "Error unsetting '%s': %s\n", key, err->message); if (*first_error) g_error_free (err); else *first_error = err; err = NULL; } }
GSList* mateconf_sources_all_entries (MateConfSources* sources, const gchar* dir, const gchar** locales, GError** err) { GList* tmp; GHashTable* hash; GSList* flattened; gboolean first_pass = TRUE; /* as an optimization, don't bother doing hash lookups on first source */ struct DefaultsLookupData dld = { NULL, NULL }; dld.sources = sources; dld.locales = locales; /* Empty MateConfSources, skip it */ if (sources->sources == NULL) return NULL; hash = g_hash_table_new(g_str_hash, g_str_equal); tmp = sources->sources; while (tmp != NULL) { MateConfSource* src; GSList* pairs; GSList* iter; GError* error = NULL; src = tmp->data; pairs = mateconf_source_all_entries(src, dir, locales, &error); iter = pairs; /* On error, set error and bail */ if (error != NULL) { g_hash_table_foreach(hash, hash_destroy_entries_func, NULL); g_hash_table_destroy(hash); if (err) { g_return_val_if_fail(*err == NULL, NULL); *err = error; return NULL; } else { g_error_free(error); return NULL; } } /* Iterate over the list of entries, stuffing them in the hash and setting their writability flag if they're new */ while (iter != NULL) { MateConfEntry* pair = iter->data; MateConfEntry* previous; gchar *full; if (first_pass) previous = NULL; /* Can't possibly be there. */ else previous = g_hash_table_lookup(hash, pair->key); if (previous != NULL) { if (mateconf_entry_get_value (previous) != NULL) /* Discard this latest one */ ; else { /* Save the new value, previously we had an entry but no value */ mateconf_entry_set_value_nocopy (previous, mateconf_entry_steal_value(pair)); /* As an efficiency hack, remember that * entry->key is relative not absolute on the * mateconfd side */ full = mateconf_concat_dir_and_key (dir, previous->key); mateconf_entry_set_is_writable (previous, key_is_writable (sources, src, full, NULL)); g_free (full); } if (mateconf_entry_get_schema_name (previous) != NULL) /* Discard this latest one */ ; else { /* Save the new schema name, previously we had an entry but no schema name*/ if (mateconf_entry_get_schema_name (pair) != NULL) { mateconf_entry_set_schema_name (previous, mateconf_entry_get_schema_name (pair)); } } mateconf_entry_free(pair); } else { /* Save */ g_hash_table_insert(hash, pair->key, pair); /* As an efficiency hack, remember that * entry->key is relative not absolute on the * mateconfd side */ full = mateconf_concat_dir_and_key (dir, pair->key); mateconf_entry_set_is_writable (pair, key_is_writable (sources, src, full, NULL)); g_free (full); } iter = g_slist_next(iter); } /* All pairs are either stored or destroyed. */ g_slist_free(pairs); first_pass = FALSE; tmp = g_list_next(tmp); } flattened = NULL; g_hash_table_foreach(hash, hash_lookup_defaults_func, &dld); g_hash_table_foreach(hash, hash_listify_func, &flattened); g_hash_table_destroy(hash); return flattened; }
/* Check whether all_dirs works if you implicitly create directories by creating keys inside them */ static void check_dir_listing(MateConfEngine* conf) { const gchar** iter; GSList* entries; GSList* iter2; GError* error = NULL; gboolean found[sizeof(keys_in_foo)]; int i; gboolean got_it; iter = keys_in_foo; while (*iter) { gchar* full_key; gchar* tmp; tmp = g_strconcat(*iter, "/woo", NULL); full_key = mateconf_concat_dir_and_key("/testing/foo", tmp); g_free(tmp); mateconf_engine_set_int(conf, full_key, 10, &error); check (error == NULL, "Error setting key %s: %s", full_key, error ? error->message : ""); g_free(full_key); ++iter; } /* Check that "testing" comes back in a list of / */ entries = mateconf_engine_all_dirs(conf, "/", &error); check (error == NULL, "Error getting list of dirs in /: %s", error ? error->message : ""); got_it = FALSE; iter2 = entries; while (iter2 != NULL) { if (strcmp(iter2->data, "/testing") == 0) got_it = TRUE; iter2 = g_slist_next(iter2); } g_slist_free(entries); check(got_it, "Did not get 'testing' in listing of / after setting keys such as /testing/foo/bar/woo"); /* Check that "foo" comes back in a list of /testing */ entries = mateconf_engine_all_dirs(conf, "/testing", &error); check (error == NULL, "Error getting list of dirs in /testing: %s", error ? error->message : ""); got_it = FALSE; iter2 = entries; while (iter2 != NULL) { if (strcmp(iter2->data, "/testing/foo") == 0) got_it = TRUE; iter2 = g_slist_next(iter2); } g_slist_free(entries); check(got_it, "Did not get 'foo' in listing of /testing after setting keys such as /testing/foo/bar/woo"); /* Check that /testing/foo/ subdirs come back in a listing of /testing/foo */ entries = mateconf_engine_all_dirs(conf, "/testing/foo", &error); check (error == NULL, "Error getting list of dirs in /testing/foo: %s", error ? error->message : ""); iter2 = entries; while (iter2 != NULL) { i = 0; iter = keys_in_foo; while (*iter) { gchar *full = mateconf_concat_dir_and_key ("/testing/foo", *iter); if (strcmp(iter2->data, full) == 0) found[i] = TRUE; g_free (full); ++i; ++iter; } iter2 = g_slist_next(iter2); } g_slist_free(entries); i = 0; iter = keys_in_foo; while (*iter) { check(found[i], "Did not get key %s back in the /testing/foo listing", *iter); ++i; ++iter; } iter = keys_in_foo; while (*iter) { gchar* full_key; gchar* tmp; tmp = g_strconcat(*iter, "/woo", NULL); full_key = mateconf_concat_dir_and_key("/testing/foo", tmp); g_free(tmp); mateconf_engine_unset(conf, full_key, &error); check (error == NULL, "Error unsetting key %s: %s", full_key, error ? error->message : ""); g_free(full_key); ++iter; } }