From 7568419159bbad8edf41385bbec3d091f4369dc3 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Thu, 4 Oct 2012 16:15:02 +0200 Subject: [PATCH 1/2] accountsservice: Add User.LoginTimes property https://bugzilla.gnome.org/show_bug.cgi?id=681772 --- data/org.freedesktop.Accounts.User.xml | 10 +++++++++ src/daemon.c | 31 +++++++++++++++++---------- src/libaccountsservice/act-user.c | 39 ++++++++++++++++++++++++++++++++++ src/libaccountsservice/act-user.h | 1 + src/user.c | 16 ++++++++++++++ 5 files changed, 86 insertions(+), 11 deletions(-) diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml index deab745..9065ce1 100644 --- a/data/org.freedesktop.Accounts.User.xml +++ b/data/org.freedesktop.Accounts.User.xml @@ -653,6 +653,16 @@ + + + + + The login times. + + + + + diff --git a/src/daemon.c b/src/daemon.c index c65eca3..f7fdad0 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -214,6 +214,13 @@ entry_generator_wtmp (GHashTable *users, GHashTableIter iter; gpointer key, value; struct passwd *pwent; + User *user; + struct hash_data *data; + + struct hash_data { + int frequency; + GVariantBuilder *times; + }; if (*state == NULL) { /* First iteration */ @@ -247,17 +254,17 @@ entry_generator_wtmp (GHashTable *users, if (!g_hash_table_lookup_extended (login_frequency_hash, wtmp_entry->ut_user, &key, &value)) { + data = g_new (struct hash_data, 1); + data->frequency = 1; + data->times = g_variant_builder_new (G_VARIANT_TYPE ("ax")); + g_variant_builder_add (data->times, "x", (gint64)wtmp_entry->ut_tv.tv_sec); g_hash_table_insert (login_frequency_hash, g_strdup (wtmp_entry->ut_user), - GUINT_TO_POINTER (1)); + data); } else { - guint frequency; - - frequency = GPOINTER_TO_UINT (value) + 1; - - g_hash_table_insert (login_frequency_hash, - key, - GUINT_TO_POINTER (frequency)); + data = value; + data->frequency++; + g_variant_builder_add (data->times, "x", (gint64)wtmp_entry->ut_tv.tv_sec); } return pwent; @@ -268,15 +275,17 @@ entry_generator_wtmp (GHashTable *users, g_hash_table_iter_init (&iter, login_frequency_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { - User *user; - guint64 frequency = (guint64) GPOINTER_TO_UINT (value); + data = value; user = g_hash_table_lookup (users, key); if (user == NULL) { continue; } - g_object_set (user, "login-frequency", frequency, NULL); + g_object_set (user, "login-frequency", data->frequency, NULL); + g_object_set (user, "login-times", g_variant_new ("ax", data->times), NULL); + + g_variant_builder_unref (data->times); } g_hash_table_foreach (login_frequency_hash, (GHFunc) g_free, NULL); diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c index 13d82e7..3611b51 100644 --- a/src/libaccountsservice/act-user.c +++ b/src/libaccountsservice/act-user.c @@ -57,6 +57,7 @@ enum { PROP_SYSTEM_ACCOUNT, PROP_LOCAL_ACCOUNT, PROP_LOGIN_FREQUENCY, + PROP_LOGIN_TIMES, PROP_ICON_FILE, PROP_LANGUAGE, PROP_X_SESSION, @@ -91,6 +92,7 @@ struct _ActUser { char *x_session; GList *sessions; int login_frequency; + GVariant *login_times; ActUserAccountType account_type; ActUserPasswordMode password_mode; @@ -206,6 +208,9 @@ act_user_get_property (GObject *object, case PROP_LOGIN_FREQUENCY: g_value_set_int (value, user->login_frequency); break; + case PROP_LOGIN_TIMES: + g_value_set_variant (value, user->login_times); + break; case PROP_SHELL: g_value_set_string (value, user->shell); break; @@ -343,6 +348,14 @@ act_user_class_init (ActUserClass *class) 0, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, + PROP_LOGIN_TIMES, + g_param_spec_variant ("login-times", + "Login times", + "The login times for this user.", + G_VARIANT_TYPE ("ax"), + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, PROP_ICON_FILE, g_param_spec_string ("icon-file", "Icon File", @@ -429,6 +442,7 @@ act_user_init (ActUser *user) user->user_name = NULL; user->real_name = NULL; user->sessions = NULL; + user->login_times = NULL; user->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (user->connection == NULL) { @@ -454,6 +468,7 @@ act_user_finalize (GObject *object) g_free (user->shell); g_free (user->email); g_free (user->location); + g_variant_unref (user->login_times); if (user->accounts_proxy != NULL) { g_object_unref (user->accounts_proxy); @@ -676,6 +691,22 @@ act_user_get_login_frequency (ActUser *user) return user->login_frequency; } +/** + * act_user_get_login_times: + * @user: a #ActUser + * + * Returns the login times for @user. + * + * Returns: (transfer none): a pointer to GVariant of type "ax" which must not be modified or + * freed, or %NULL. + */ +const GVariant * +act_user_get_login_times (ActUser *user) { + g_return_val_if_fail (ACT_IS_USER (user), NULL); + + return user->login_times; +} + int act_user_collate (ActUser *user1, ActUser *user2) @@ -1036,6 +1067,14 @@ collect_props (const gchar *key, user->login_frequency = new_login_frequency; g_object_notify (G_OBJECT (user), "login-frequency"); } + } else if (strcmp (key, "LoginTimes") == 0) { + GVariant *new_login_times = value; + + if (!g_variant_compare (user->login_times, new_login_times)) { + g_variant_unref (user->login_times); + user->login_times = g_variant_ref (new_login_times); + g_object_notify (G_OBJECT (user), "login-times"); + } } else if (strcmp (key, "IconFile") == 0) { const char *new_icon_file; diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h index c01c1e9..bd30b20 100644 --- a/src/libaccountsservice/act-user.h +++ b/src/libaccountsservice/act-user.h @@ -66,6 +66,7 @@ const char *act_user_get_location (ActUser *user); guint act_user_get_num_sessions (ActUser *user); gboolean act_user_is_logged_in (ActUser *user); int act_user_get_login_frequency (ActUser *user); +const GVariant*act_user_get_login_times (ActUser *user); gboolean act_user_get_locked (ActUser *user); gboolean act_user_get_automatic_login (ActUser *user); gboolean act_user_is_system_account (ActUser *user); diff --git a/src/user.c b/src/user.c index ff84c6d..35c1de3 100644 --- a/src/user.c +++ b/src/user.c @@ -59,6 +59,7 @@ enum { PROP_X_SESSION, PROP_LOCATION, PROP_LOGIN_FREQUENCY, + PROP_LOGIN_TIMES, PROP_ICON_FILE, PROP_LOCKED, PROP_PASSWORD_MODE, @@ -90,6 +91,7 @@ struct User { gchar *x_session; gchar *location; guint64 login_frequency; + GVariant *login_times; gchar *icon_file; gchar *default_icon_file; gboolean locked; @@ -1683,6 +1685,12 @@ user_real_get_login_frequency (AccountsUser *user) return USER (user)->login_frequency; } +static const GVariant * +user_real_get_login_times (AccountsUser *user) +{ + return USER (user)->login_times; +} + static const gchar * user_real_get_icon_file (AccountsUser *user) { @@ -1770,6 +1778,9 @@ user_set_property (GObject *object, case PROP_LOGIN_FREQUENCY: user->login_frequency = g_value_get_uint64 (value); break; + case PROP_LOGIN_TIMES: + user->login_times = g_variant_ref (g_value_get_variant (value)); + break; case PROP_AUTOMATIC_LOGIN: user->automatic_login = g_value_get_boolean (value); break; @@ -1840,6 +1851,9 @@ user_get_property (GObject *object, case PROP_LOGIN_FREQUENCY: g_value_set_uint64 (value, user->login_frequency); break; + case PROP_LOGIN_TIMES: + g_value_set_variant (value, user->login_times); + break; case PROP_LOCKED: g_value_set_boolean (value, user->locked); break; @@ -1900,6 +1914,7 @@ user_accounts_user_iface_init (AccountsUserIface *iface) iface->get_xsession = user_real_get_xsession; iface->get_location = user_real_get_location; iface->get_login_frequency = user_real_get_login_frequency; + iface->get_login_times = user_real_get_login_times; iface->get_icon_file = user_real_get_icon_file; iface->get_locked = user_real_get_locked; iface->get_password_mode = user_real_get_password_mode; @@ -1929,4 +1944,5 @@ user_init (User *user) user->locked = FALSE; user->automatic_login = FALSE; user->system_account = FALSE; + user->login_times = NULL; } -- 1.7.11.4