| From dee5f443807fee3b5b279d0488df617eeed52230 Mon Sep 17 00:00:00 2001 |
| From: Robert Ancell <robert.ancell@canonical.com> |
| Date: Thu, 6 Sep 2018 14:37:39 +1200 |
| Subject: [PATCH] daemon: Fix warnings about type-punning |
| |
| |
| src/daemon.c | 26 +++++++++++++++----------- |
| 1 file changed, 15 insertions(+), 11 deletions(-) |
| |
| diff --git a/src/daemon.c b/src/daemon.c |
| index 2587b8a..00dff51 100644 |
| |
| |
| @@ -232,117 +232,118 @@ entry_generator_fgetpwent (Daemon *daemon, |
| pwent = fgetpwent (generator_state->fp); |
| if (pwent != NULL) { |
| shadow_entry_buffers = g_hash_table_lookup (generator_state->users, pwent->pw_name); |
| |
| if (shadow_entry_buffers != NULL) { |
| *spent = &shadow_entry_buffers->spbuf; |
| } |
| return pwent; |
| } |
| } |
| |
| /* Last iteration */ |
| fclose (generator_state->fp); |
| g_hash_table_unref (generator_state->users); |
| g_free (generator_state); |
| *state = NULL; |
| |
| return NULL; |
| } |
| |
| static struct passwd * |
| entry_generator_cachedir (Daemon *daemon, |
| GHashTable *users, |
| gpointer *state, |
| struct spwd **shadow_entry) |
| { |
| struct passwd *pwent; |
| g_autoptr(GError) error = NULL; |
| gboolean regular; |
| GHashTableIter iter; |
| - const gchar *name; |
| - User *user; |
| + gpointer key, value; |
| GDir *dir; |
| |
| /* First iteration */ |
| if (*state == NULL) { |
| *state = g_dir_open (USERDIR, 0, &error); |
| if (error != NULL) { |
| if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) |
| g_warning ("couldn't list user cache directory: %s", USERDIR); |
| return NULL; |
| } |
| } |
| |
| /* Every iteration */ |
| |
| /* |
| * Use names of files of regular type to lookup information |
| * about each user. Loop until we find something valid. |
| */ |
| dir = *state; |
| while (TRUE) { |
| const gchar *name; |
| g_autofree gchar *filename = NULL; |
| |
| name = g_dir_read_name (dir); |
| if (name == NULL) |
| break; |
| |
| /* Only load files in this directory */ |
| filename = g_build_filename (USERDIR, name, NULL); |
| regular = g_file_test (filename, G_FILE_TEST_IS_REGULAR); |
| |
| if (regular) { |
| errno = 0; |
| pwent = getpwnam (name); |
| if (pwent != NULL) { |
| *shadow_entry = getspnam (pwent->pw_name); |
| |
| return pwent; |
| } else if (errno == 0) { |
| g_debug ("user '%s' in cache dir but not present on system, removing", name); |
| remove_cache_files (name); |
| } |
| else { |
| g_warning ("failed to check if user '%s' in cache dir is present on system: %s", |
| name, g_strerror (errno)); |
| } |
| } |
| } |
| |
| /* Last iteration */ |
| g_dir_close (dir); |
| |
| /* Update all the users from the files in the cache dir */ |
| g_hash_table_iter_init (&iter, users); |
| - while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&user)) { |
| + while (g_hash_table_iter_next (&iter, &key, &value)) { |
| + const gchar *name = key; |
| + User *user = value; |
| g_autofree gchar *filename = NULL; |
| g_autoptr(GKeyFile) key_file = NULL; |
| |
| filename = g_build_filename (USERDIR, name, NULL); |
| key_file = g_key_file_new (); |
| if (g_key_file_load_from_file (key_file, filename, 0, NULL)) |
| user_update_from_keyfile (user, key_file); |
| } |
| |
| *state = NULL; |
| return NULL; |
| } |
| |
| static struct passwd * |
| entry_generator_requested_users (Daemon *daemon, |
| GHashTable *users, |
| gpointer *state, |
| struct spwd **shadow_entry) |
| { |
| struct passwd *pwent; |
| GList *node; |
| |
| /* First iteration */ |
| if (*state == NULL) { |
| *state = daemon->priv->explicitly_requested_users; |
| } |
| |
| /* Every iteration */ |
| |
| if (g_hash_table_size (users) < MAX_LOCAL_USERS) { |
| @@ -423,129 +424,131 @@ load_entries (Daemon *daemon, |
| } |
| |
| if (!explicitly_requested) { |
| user_set_cached (user, TRUE); |
| } |
| } |
| |
| /* Generator should have cleaned up */ |
| g_assert (generator_state == NULL); |
| } |
| |
| static GHashTable * |
| create_users_hash_table (void) |
| { |
| return g_hash_table_new_full (g_str_hash, |
| g_str_equal, |
| g_free, |
| g_object_unref); |
| } |
| |
| static void |
| reload_users (Daemon *daemon) |
| { |
| AccountsAccounts *accounts = ACCOUNTS_ACCOUNTS (daemon); |
| gboolean had_no_users, has_no_users, had_multiple_users, has_multiple_users; |
| GHashTable *users; |
| GHashTable *old_users; |
| GHashTable *local; |
| GHashTableIter iter; |
| gsize number_of_normal_users = 0; |
| - gpointer name; |
| - User *user; |
| + gpointer name, value; |
| |
| /* Track the users that we saw during our (re)load */ |
| users = create_users_hash_table (); |
| |
| /* |
| * NOTE: As we load data from all the sources, notifies are |
| * frozen in load_entries() and then thawed as we process |
| * them below. |
| */ |
| |
| /* Load the local users into our hash table */ |
| load_entries (daemon, users, FALSE, entry_generator_fgetpwent); |
| local = g_hash_table_new (g_str_hash, g_str_equal); |
| g_hash_table_iter_init (&iter, users); |
| while (g_hash_table_iter_next (&iter, &name, NULL)) |
| g_hash_table_add (local, name); |
| |
| /* and add users to hash table that were explicitly requested */ |
| load_entries (daemon, users, TRUE, entry_generator_requested_users); |
| |
| /* Now add/update users from other sources, possibly non-local */ |
| load_entries (daemon, users, FALSE, entry_generator_cachedir); |
| |
| wtmp_helper_update_login_frequencies (users); |
| |
| /* Count the non-system users. Mark which users are local, which are not. */ |
| g_hash_table_iter_init (&iter, users); |
| - while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) { |
| + while (g_hash_table_iter_next (&iter, &name, &value)) { |
| + User *user = value; |
| if (!user_get_system_account (user)) |
| number_of_normal_users++; |
| user_update_local_account_property (user, g_hash_table_lookup (local, name) != NULL); |
| } |
| g_hash_table_destroy (local); |
| |
| had_no_users = accounts_accounts_get_has_no_users (accounts); |
| has_no_users = number_of_normal_users == 0; |
| |
| if (had_no_users != has_no_users) |
| accounts_accounts_set_has_no_users (accounts, has_no_users); |
| |
| had_multiple_users = accounts_accounts_get_has_multiple_users (accounts); |
| has_multiple_users = number_of_normal_users > 1; |
| |
| if (had_multiple_users != has_multiple_users) |
| accounts_accounts_set_has_multiple_users (accounts, has_multiple_users); |
| |
| /* Swap out the users */ |
| old_users = daemon->priv->users; |
| daemon->priv->users = users; |
| |
| /* Remove all the old users */ |
| g_hash_table_iter_init (&iter, old_users); |
| - while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) { |
| + while (g_hash_table_iter_next (&iter, &name, &value)) { |
| + User *user = value; |
| User *refreshed_user; |
| |
| refreshed_user = g_hash_table_lookup (users, name); |
| |
| if (!refreshed_user || (user_get_cached (user) && !user_get_cached (refreshed_user))) { |
| accounts_accounts_emit_user_deleted (ACCOUNTS_ACCOUNTS (daemon), |
| user_get_object_path (user)); |
| user_unregister (user); |
| } |
| } |
| |
| /* Register all the new users */ |
| g_hash_table_iter_init (&iter, users); |
| - while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) { |
| + while (g_hash_table_iter_next (&iter, &name, &value)) { |
| + User *user = value; |
| User *stale_user; |
| |
| stale_user = g_hash_table_lookup (old_users, name); |
| |
| if (!stale_user || (!user_get_cached (stale_user) && user_get_cached (user))) { |
| user_register (user); |
| accounts_accounts_emit_user_added (ACCOUNTS_ACCOUNTS (daemon), |
| user_get_object_path (user)); |
| } |
| g_object_thaw_notify (G_OBJECT (user)); |
| } |
| |
| g_hash_table_destroy (old_users); |
| } |
| |
| static gboolean |
| reload_users_timeout (Daemon *daemon) |
| { |
| reload_users (daemon); |
| daemon->priv->reload_id = 0; |
| |
| return FALSE; |
| } |
| |
| static gboolean load_autologin (Daemon *daemon, |
| gchar **name, |
| gboolean *enabled, |
| GError **error); |
| |
| static gboolean |
| @@ -932,69 +935,70 @@ typedef struct { |
| } ListUserData; |
| |
| |
| static ListUserData * |
| list_user_data_new (Daemon *daemon, |
| GDBusMethodInvocation *context) |
| { |
| ListUserData *data; |
| |
| data = g_new0 (ListUserData, 1); |
| |
| data->daemon = g_object_ref (daemon); |
| data->context = context; |
| |
| return data; |
| } |
| |
| static void |
| list_user_data_free (ListUserData *data) |
| { |
| g_object_unref (data->daemon); |
| g_free (data); |
| } |
| |
| static gboolean |
| finish_list_cached_users (gpointer user_data) |
| { |
| ListUserData *data = user_data; |
| g_autoptr(GPtrArray) object_paths = NULL; |
| GHashTableIter iter; |
| - const gchar *name; |
| - User *user; |
| + gpointer key, value; |
| uid_t uid; |
| const gchar *shell; |
| |
| object_paths = g_ptr_array_new (); |
| |
| g_hash_table_iter_init (&iter, data->daemon->priv->users); |
| - while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&user)) { |
| + while (g_hash_table_iter_next (&iter, &key, &value)) { |
| + const gchar *name = key; |
| + User *user = value; |
| uid = user_get_uid (user); |
| shell = user_get_shell (user); |
| |
| if (!user_classify_is_human (uid, name, shell, NULL)) { |
| g_debug ("user %s %ld excluded", name, (long) uid); |
| continue; |
| } |
| |
| if (!user_get_cached (user)) { |
| g_debug ("user %s %ld not cached", name, (long) uid); |
| continue; |
| } |
| |
| g_debug ("user %s %ld not excluded", name, (long) uid); |
| g_ptr_array_add (object_paths, (gpointer) user_get_object_path (user)); |
| } |
| g_ptr_array_add (object_paths, NULL); |
| |
| accounts_accounts_complete_list_cached_users (NULL, data->context, (const gchar * const *) object_paths->pdata); |
| |
| list_user_data_free (data); |
| |
| return FALSE; |
| } |
| |
| static gboolean |
| daemon_list_cached_users (AccountsAccounts *accounts, |
| GDBusMethodInvocation *context) |
| { |
| Daemon *daemon = (Daemon*)accounts; |
| -- |
| 2.17.1 |
| |