static void update_mounts (GUnixVolumeMonitor *monitor) { GList *new_mounts; GList *removed, *added; GList *l; GUnixMount *mount; GUnixVolume *volume; const char *mount_path; new_mounts = g_unix_mounts_get (NULL); new_mounts = g_list_sort (new_mounts, (GCompareFunc) g_unix_mount_compare); diff_sorted_lists (monitor->last_mounts, new_mounts, (GCompareFunc) g_unix_mount_compare, &added, &removed); for (l = removed; l != NULL; l = l->next) { GUnixMountEntry *mount_entry = l->data; mount = find_mount_by_mountpath (monitor, g_unix_mount_get_mount_path (mount_entry)); if (mount) { _g_unix_mount_unmounted (mount); monitor->mounts = g_list_remove (monitor->mounts, mount); g_signal_emit_by_name (monitor, "mount-removed", mount); g_signal_emit_by_name (mount, "unmounted"); g_object_unref (mount); } } for (l = added; l != NULL; l = l->next) { GUnixMountEntry *mount_entry = l->data; mount_path = g_unix_mount_get_mount_path (mount_entry); volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, mount_path); mount = _g_unix_mount_new (G_VOLUME_MONITOR (monitor), mount_entry, volume); if (mount) { monitor->mounts = g_list_prepend (monitor->mounts, mount); g_signal_emit_by_name (monitor, "mount-added", mount); } } g_list_free (added); g_list_free (removed); g_list_foreach (monitor->last_mounts, (GFunc)g_unix_mount_free, NULL); g_list_free (monitor->last_mounts); monitor->last_mounts = new_mounts; }
static void update_volumes (GUnixVolumeMonitor *monitor) { GList *new_mountpoints; GList *removed, *added; GList *l; GUnixVolume *volume; new_mountpoints = g_unix_mount_points_get (NULL); new_mountpoints = g_list_sort (new_mountpoints, (GCompareFunc) g_unix_mount_point_compare); diff_sorted_lists (monitor->last_mountpoints, new_mountpoints, (GCompareFunc) g_unix_mount_point_compare, &added, &removed); for (l = removed; l != NULL; l = l->next) { GUnixMountPoint *mountpoint = l->data; volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, g_unix_mount_point_get_mount_path (mountpoint)); if (volume) { _g_unix_volume_disconnected (volume); monitor->volumes = g_list_remove (monitor->volumes, volume); g_signal_emit_by_name (monitor, "volume-removed", volume); g_signal_emit_by_name (volume, "removed"); g_object_unref (volume); } } for (l = added; l != NULL; l = l->next) { GUnixMountPoint *mountpoint = l->data; volume = _g_unix_volume_new (G_VOLUME_MONITOR (monitor), mountpoint); if (volume) { monitor->volumes = g_list_prepend (monitor->volumes, volume); g_signal_emit_by_name (monitor, "volume-added", volume); } } g_list_free (added); g_list_free (removed); g_list_foreach (monitor->last_mountpoints, (GFunc)g_unix_mount_point_free, NULL); g_list_free (monitor->last_mountpoints); monitor->last_mountpoints = new_mountpoints; }
static void update_problems (GduSdMonitor *monitor, GList **problem_list, CheckProblemFunc check_func) { GList *want = NULL; GList *added = NULL; GList *removed = NULL; GList *objects; GList *l; objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (monitor->client)); for (l = objects; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); if (check_func (monitor, object)) want = g_list_prepend (want, object); } want = g_list_sort (want, ptr_compare); *problem_list = g_list_sort (*problem_list, ptr_compare); diff_sorted_lists (*problem_list, want, ptr_compare, &added, &removed); for (l = removed; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); *problem_list = g_list_remove (*problem_list, object); g_object_unref (object); } for (l = added; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); *problem_list = g_list_prepend (*problem_list, g_object_ref (object)); } g_list_free (removed); g_list_free (added); g_list_free (want); g_list_free_full (objects, g_object_unref); }
static void process_config_entries (GoaDaemon *daemon, GHashTable *group_name_to_key_file_data) { GHashTableIter iter; const gchar *id; KeyFileData *key_file_data; GList *existing_object_paths; GList *config_object_paths; GList *added; GList *removed; GList *unchanged; GList *l; existing_object_paths = NULL; { GList *existing_objects; existing_objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (daemon->object_manager)); for (l = existing_objects; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); const gchar *object_path; object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); if (g_str_has_prefix (object_path, "/org/gnome/OnlineAccounts/Accounts/")) existing_object_paths = g_list_prepend (existing_object_paths, g_strdup (object_path)); } g_list_foreach (existing_objects, (GFunc) g_object_unref, NULL); g_list_free (existing_objects); } config_object_paths = NULL; g_hash_table_iter_init (&iter, group_name_to_key_file_data); while (g_hash_table_iter_next (&iter, (gpointer*) &id, (gpointer*) &key_file_data)) { gchar *object_path; /* create and validate object path */ object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", id + sizeof "Account " - 1); if (strstr (id + sizeof "Account " - 1, "/") != NULL || !g_variant_is_object_path (object_path)) { g_warning ("`%s' is not a valid account identifier", id); g_free (object_path); continue; } /* steals object_path variable */ config_object_paths = g_list_prepend (config_object_paths, object_path); } existing_object_paths = g_list_sort (existing_object_paths, (GCompareFunc) g_strcmp0); config_object_paths = g_list_sort (config_object_paths, (GCompareFunc) g_strcmp0); diff_sorted_lists (existing_object_paths, config_object_paths, (GCompareFunc) g_strcmp0, &added, &removed, &unchanged); for (l = removed; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObject *object; object = GOA_OBJECT (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (daemon->object_manager), object_path)); g_warn_if_fail (object != NULL); g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_remove), daemon); g_debug ("removing %s", object_path); g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path)); } for (l = added; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObjectSkeleton *object; gchar *group; g_debug ("adding %s", object_path); group = object_path_to_group (object_path); key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group); g_warn_if_fail (key_file_data != NULL); object = goa_object_skeleton_new (object_path); if (update_account_object (daemon, object, key_file_data->path, group, key_file_data->key_file, TRUE)) { g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (object)); g_signal_connect (goa_object_peek_account (GOA_OBJECT (object)), "handle-remove", G_CALLBACK (on_account_handle_remove), daemon); g_signal_connect (goa_object_peek_account (GOA_OBJECT (object)), "handle-ensure-credentials", G_CALLBACK (on_account_handle_ensure_credentials), daemon); } g_object_unref (object); g_free (group); } for (l = unchanged; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObject *object; gchar *group; g_debug ("unchanged %s", object_path); group = object_path_to_group (object_path); key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group); g_warn_if_fail (key_file_data != NULL); object = GOA_OBJECT (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (daemon->object_manager), object_path)); g_warn_if_fail (object != NULL); if (!update_account_object (daemon, GOA_OBJECT_SKELETON (object), key_file_data->path, group, key_file_data->key_file, FALSE)) { g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_remove), daemon); g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_ensure_credentials), daemon); g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path)); } g_object_unref (object); g_free (group); } g_list_free (removed); g_list_free (added); g_list_free (unchanged); g_list_foreach (existing_object_paths, (GFunc) g_free, NULL); g_list_free (existing_object_paths); g_list_foreach (config_object_paths, (GFunc) g_free, NULL); g_list_free (config_object_paths); }
static void provider_update_jobs (StorageProvider *provider) { GDBusObjectManagerServer *object_manager; GList *udisks_objects; GList *lvm_objects; GList *all_objects; GList *wanted; GList *added, *removed; GList *l; object_manager = G_DBUS_OBJECT_MANAGER_SERVER (daemon_get_object_manager (provider->daemon)); udisks_objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (provider->udisks_client)); lvm_objects = g_dbus_object_manager_get_objects (provider->lvm_objman); all_objects = g_list_concat (udisks_objects, lvm_objects); wanted = NULL; for (l = all_objects; l != NULL; l = l->next) { if (!UDISKS_IS_OBJECT (l->data)) continue; UDisksObject *object = UDISKS_OBJECT (l->data); UDisksJob *job; job = udisks_object_peek_job (object); if (job == NULL) continue; const gchar *operation = udisks_job_get_operation (job); if (strcmp (operation, "format-mkfs") != 0 && strcmp (operation, "format-erase") != 0 && strcmp (operation, "lvm-vg-empty-device") != 0) continue; wanted = g_list_prepend (wanted, g_object_ref (job)); } wanted = g_list_sort (wanted, (GCompareFunc)_udisks_job_compare_func); provider->jobs = g_list_sort (provider->jobs, (GCompareFunc)_udisks_job_compare_func); diff_sorted_lists (provider->jobs, wanted, (GCompareFunc)_udisks_job_compare_func, &added, &removed, NULL); for (l = removed; l != NULL; l = l->next) { UDisksJob *job = UDISKS_JOB (l->data); CockpitJob *object; object = g_hash_table_lookup (provider->hash_job_to_storage_job, job); if (object == NULL) { g_warning ("No object for job %p", job); } else { g_warn_if_fail (g_dbus_object_manager_server_unexport (object_manager, g_dbus_object_get_object_path (G_DBUS_OBJECT (object)))); g_hash_table_remove (provider->hash_job_to_storage_job, job); } provider->jobs = g_list_remove (provider->jobs, job); g_object_unref (job); } for (l = added; l != NULL; l = l->next) { UDisksJob *job = UDISKS_JOB (l->data); CockpitObjectSkeleton *object; CockpitJob *cockpit_job; gchar *object_path; object_path = utils_generate_object_path ("/com/redhat/Cockpit/Jobs", udisks_job_get_operation (job)); cockpit_job = storage_job_new (provider, job); object = cockpit_object_skeleton_new (object_path); cockpit_object_skeleton_set_job (object, cockpit_job); g_object_unref (cockpit_job); g_free (object_path); g_warn_if_fail (g_hash_table_lookup (provider->hash_job_to_storage_job, job) == NULL); g_hash_table_insert (provider->hash_job_to_storage_job, g_object_ref (job), object); g_dbus_object_manager_server_export_uniquely (object_manager, G_DBUS_OBJECT_SKELETON (object)); provider->jobs = g_list_prepend (provider->jobs, g_object_ref (job)); } g_list_free (added); g_list_free (removed); g_list_free_full (all_objects, g_object_unref); g_list_free_full (wanted, g_object_unref); }
static void provider_update_objects (StorageProvider *provider) { GDBusObjectManagerServer *object_manager; GList *udisks_objects; GList *lvm_objects; GList *wanted; GList *added, *removed; GList *l; object_manager = G_DBUS_OBJECT_MANAGER_SERVER (daemon_get_object_manager (provider->daemon)); udisks_objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (provider->udisks_client)); lvm_objects = g_dbus_object_manager_get_objects (provider->lvm_objman); wanted = NULL; for (l = udisks_objects; l != NULL; l = l->next) { GDBusInterface *iface = get_udisk_iface (UDISKS_OBJECT (l->data)); if (iface == NULL) continue; wanted = g_list_prepend (wanted, g_object_ref (iface)); } for (l = lvm_objects; l != NULL; l = l->next) { if (!LVM_IS_OBJECT (l->data)) continue; GDBusInterface *iface = get_lvm_iface (LVM_OBJECT (l->data)); if (iface == NULL) continue; wanted = g_list_prepend (wanted, g_object_ref (iface)); } wanted = g_list_sort (wanted, (GCompareFunc)udisks_iface_compare_func); provider->ifaces = g_list_sort (provider->ifaces, (GCompareFunc)udisks_iface_compare_func); diff_sorted_lists (provider->ifaces, wanted, (GCompareFunc)udisks_iface_compare_func, &added, &removed, NULL); for (l = removed; l != NULL; l = l->next) { GDBusInterface *iface = G_DBUS_INTERFACE (l->data); StorageObject *object; object = g_hash_table_lookup (provider->hash_interface_to_storage_object, iface); g_warn_if_fail (object != NULL); if (object) { g_warn_if_fail (g_dbus_object_manager_server_unexport (object_manager, g_dbus_object_get_object_path (G_DBUS_OBJECT (object)))); } g_hash_table_remove (provider->hash_interface_to_storage_object, iface); provider->ifaces = g_list_remove (provider->ifaces, iface); g_object_unref (iface); } for (l = added; l != NULL; l = l->next) { GDBusInterface *iface = G_DBUS_INTERFACE (l->data); StorageObject *object = make_storage_object (provider, iface); g_warn_if_fail (g_hash_table_lookup (provider->hash_interface_to_storage_object, iface) == NULL); g_hash_table_insert (provider->hash_interface_to_storage_object, g_object_ref (iface), object); gs_free gchar *object_path = storage_object_make_object_path (object); g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path); g_dbus_object_manager_server_export_uniquely (object_manager, G_DBUS_OBJECT_SKELETON (object)); provider->ifaces = g_list_prepend (provider->ifaces, g_object_ref (iface)); } g_list_free (added); g_list_free (removed); g_list_free_full (udisks_objects, g_object_unref); g_list_free_full (lvm_objects, g_object_unref); g_list_free_full (wanted, g_object_unref); }