From d93c4a3be8a56d55ecfc814eeef5c1bf1efe33de Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 27 Sep 2017 11:01:28 -0400 Subject: [PATCH 04/13] daemon: don't send spurious change signals when wtmp changes Right now, we unintentionally send out a changed signal for every tracked user anytime wtmp changes. This commit fixes that. --- src/wtmp-helper.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/wtmp-helper.c b/src/wtmp-helper.c index 787480b..a1edffe 100644 --- a/src/wtmp-helper.c +++ b/src/wtmp-helper.c @@ -138,75 +138,91 @@ wtmp_helper_update_login_frequencies (GHashTable *users) &key, &value)) { accounting = g_new (UserAccounting, 1); accounting->frequency = 0; accounting->previous_logins = NULL; g_hash_table_insert (login_hash, g_strdup (wtmp_entry->ut_user), accounting); } else { accounting = value; } accounting->frequency++; accounting->time = wtmp_entry->ut_tv.tv_sec; /* Add zero logout time to change it later on logout record */ previous_login = g_new (UserPreviousLogin, 1); previous_login->id = g_strdup (wtmp_entry->ut_line); previous_login->login_time = wtmp_entry->ut_tv.tv_sec; previous_login->logout_time = 0; accounting->previous_logins = g_list_prepend (accounting->previous_logins, previous_login); g_hash_table_insert (logout_hash, g_strdup (wtmp_entry->ut_line), previous_login); } /* Last iteration */ endutxent (); g_hash_table_iter_init (&iter, login_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { UserAccounting *accounting = (UserAccounting *) value; UserPreviousLogin *previous_login; + gboolean changed = FALSE; + guint64 old_login_frequency; + guint64 old_login_time; user = g_hash_table_lookup (users, key); if (user == NULL) { g_list_free_full (accounting->previous_logins, (GDestroyNotify) user_previous_login_free); continue; } - g_object_set (user, "login-frequency", accounting->frequency, NULL); - g_object_set (user, "login-time", accounting->time, NULL); + g_object_get (user, + "login-frequency", &old_login_frequency, + "login-time", &old_login_time, + NULL); + + if (old_login_frequency != accounting->frequency) { + g_object_set (user, "login-frequency", accounting->frequency, NULL); + changed = TRUE; + } + + if (old_login_time != accounting->time) { + g_object_set (user, "login-time", accounting->time, NULL); + changed = TRUE; + } builder = g_variant_builder_new (G_VARIANT_TYPE ("a(xxa{sv})")); for (l = g_list_last (accounting->previous_logins); l != NULL; l = l->prev) { previous_login = l->data; builder2 = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (builder2, "{sv}", "type", g_variant_new_string (previous_login->id)); g_variant_builder_add (builder, "(xxa{sv})", previous_login->login_time, previous_login->logout_time, builder2); g_variant_builder_unref (builder2); } g_object_set (user, "login-history", g_variant_new ("a(xxa{sv})", builder), NULL); g_variant_builder_unref (builder); g_list_free_full (accounting->previous_logins, (GDestroyNotify) user_previous_login_free); - user_changed (user); + if (changed) + user_changed (user); } g_hash_table_unref (login_hash); g_hash_table_unref (logout_hash); } const gchar * wtmp_helper_get_path_for_monitor (void) { return PATH_WTMP; } #else /* HAVE_UTMPX_H */ const gchar * wtmp_helper_get_path_for_monitor (void) { return NULL; } #endif /* HAVE_UTMPX_H */ -- 2.14.1