[gdm/f15/master] - Fix user list async bugs by dropping async code and moving to accounts service library Resolve
Ray Strode
rstrode at fedoraproject.org
Fri Feb 18 23:40:00 UTC 2011
commit e9a33290544894ff65dd92b277403eb4829c9785
Author: Ray Strode <rstrode at redhat.com>
Date: Fri Feb 18 18:39:47 2011 -0500
- Fix user list async bugs by dropping async code and
moving to accounts service library
Resolves: #678236
- Add requires for accounts service to spec since it isn't
optional (and hasn't been for a while)
gdm-multistack.patch | 101 +-
gdm.spec | 12 +-
move-to-accounts-library.patch | 3961 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 4022 insertions(+), 52 deletions(-)
---
diff --git a/gdm-multistack.patch b/gdm-multistack.patch
index ef8dc9a..6fd5ce5 100644
--- a/gdm-multistack.patch
+++ b/gdm-multistack.patch
@@ -1,4 +1,4 @@
-From bfe82193e0ffdc8434000e0a409ad8f4858f8941 Mon Sep 17 00:00:00 2001
+From d8945b88ee774a96db43ef743db49d1a91f44d33 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Thu, 22 Jul 2010 13:38:09 -0400
Subject: [PATCH 01/35] Revert "Don't wait a mandatory 2 seconds when resetting greeter"
@@ -28,7 +28,7 @@ index e6b3c98..9ea5bc9 100644
1.7.4.1
-From f9fb5f69d92799e2df7e4756716f1a092464c50f Mon Sep 17 00:00:00 2001
+From 9f8735086e8b32b64460797183595d058203ebf1 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 7 Jul 2010 17:16:38 -0400
Subject: [PATCH 02/35] Don't set list-visible unless the widget is visible
@@ -62,7 +62,7 @@ index ebbfdb9..e81bd77 100644
1.7.4.1
-From 8723117094dc995c755fb9c194c10f011d724f01 Mon Sep 17 00:00:00 2001
+From 95513b3697900f71e769b5a1948be557ecd64757 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Mon, 28 Jun 2010 14:35:35 -0400
Subject: [PATCH 03/35] Add user chooser to ui file
@@ -157,7 +157,7 @@ index 8409166..7ce166b 100644
1.7.4.1
-From 5b384978830352baff78433b4584d88ade679bd8 Mon Sep 17 00:00:00 2001
+From b18cc72457e6abde22a8423a80cde831efd677c5 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 20 Feb 2009 14:05:20 -0500
Subject: [PATCH 04/35] Add new api to ask when chooser widget is done loading items
@@ -213,7 +213,7 @@ index 11a6456..3f6fea3 100644
1.7.4.1
-From 284784301a26480e350678716efaa7a6f956ed2c Mon Sep 17 00:00:00 2001
+From f54cca866610069e51ef4bcdb7c0fe1f9ba76964 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 6 Mar 2009 11:19:40 -0500
Subject: [PATCH 05/35] Create session settings object up front
@@ -249,7 +249,7 @@ index 3dd714f..9adb0de 100644
1.7.4.1
-From d22a6da1635c6cfcfd9c7b7017a283da62a597c9 Mon Sep 17 00:00:00 2001
+From 0ab65e8c6ca52f4785f2466cce7f7507d88fc9c3 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Tue, 13 Jul 2010 22:42:43 -0400
Subject: [PATCH 06/35] disconnect signal handlers in destroy session
@@ -388,7 +388,7 @@ index 9ea5bc9..d37cc79 100644
1.7.4.1
-From b16c63af9e95e2b654f35200532be9aa81a0c733 Mon Sep 17 00:00:00 2001
+From acdd83e5a3fd6e135eed33706824123d53ba3357 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 16 Jan 2009 11:00:08 -0500
Subject: [PATCH 07/35] Introduce new Conversation object
@@ -1458,7 +1458,7 @@ index 8bed085..9bfda86 100644
1.7.4.1
-From 16e0827700e1b871564a6f576885c7649579f4ba Mon Sep 17 00:00:00 2001
+From be4f83a6b936d7f73614accd78cf10c78e4b257b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 4 Feb 2009 10:55:03 -0500
Subject: [PATCH 08/35] Rename session worker to the service it's managing
@@ -1647,7 +1647,7 @@ index d24f025..4833f23 100644
1.7.4.1
-From cf7b821e28dc5bf19e3894aec55a0b131e1948f0 Mon Sep 17 00:00:00 2001
+From 791bd408970f023cca1211d21400e7f73d3a557c Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 16 Jan 2009 13:01:48 -0500
Subject: [PATCH 09/35] Make greeter/autologin session explicitly request PAM conversation
@@ -2008,7 +2008,7 @@ index 7be5acd..ed20884 100644
1.7.4.1
-From 3175d2a8e4b985a8a67f5e8a345617e9d1ac17f0 Mon Sep 17 00:00:00 2001
+From 90eb845b64bb5668aeb2d54eb78a7c2d4892778d Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 16 Jan 2009 15:18:31 -0500
Subject: [PATCH 10/35] Store multiple conversations in the session
@@ -6615,7 +6615,7 @@ index ed20884..16f8db5 100644
1.7.4.1
-From 4234b610a8874324fdb86062de631da640ee38ad Mon Sep 17 00:00:00 2001
+From 9f4212f9ea630e7b30b00ccf86a882b91e3b5c17 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 28 Oct 2009 16:05:14 -0400
Subject: [PATCH 11/35] Return a different error code for "service won't work" than "auth failed"
@@ -6675,7 +6675,7 @@ index ee5465a..b1c8285 100644
1.7.4.1
-From 2647bdf50d3ab9d992d7db3249dedbebb95b3925 Mon Sep 17 00:00:00 2001
+From 9e9a68065a829025da372b034868cfc0ca4971a1 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 28 Oct 2009 21:32:00 -0400
Subject: [PATCH 12/35] Emit "service-unavailable" from session when pam service refuses to work
@@ -6914,7 +6914,7 @@ index 9e72f89..ab16031 100644
1.7.4.1
-From 00dcd646370958bd2500c6d4890dd62a8e42dd63 Mon Sep 17 00:00:00 2001
+From 12dbb74e8cd44eb579587469d6e376f419056ff4 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 28 Oct 2009 21:38:52 -0400
Subject: [PATCH 13/35] Bubble service-unavailable up to greeter
@@ -7048,7 +7048,7 @@ index 396007f..7d967b3 100644
1.7.4.1
-From 9494ef0f580ee708be0d3c1efbf2c96aed28a5ec Mon Sep 17 00:00:00 2001
+From 8c7b68952240df1c40a7f14c5868665a365ff64f Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 28 Oct 2009 21:46:39 -0400
Subject: [PATCH 14/35] Catch service-unavailable from server in client and propagate it
@@ -7127,7 +7127,7 @@ index 868b496..63bd4b5 100644
1.7.4.1
-From cabbd657ff61c2ee3c5b3dc849628f1ae2ac9b03 Mon Sep 17 00:00:00 2001
+From 6489e96641ee835a7c0fb22010e66fbf82ce3db8 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Thu, 5 Feb 2009 15:20:25 -0500
Subject: [PATCH 15/35] Queue a greeter reset when the user clicks cancel
@@ -7252,7 +7252,7 @@ index 7d967b3..2ecf0a4 100644
1.7.4.1
-From 2aa8d609e1617b8e42bdac773f98582cd4473ab0 Mon Sep 17 00:00:00 2001
+From e3efa1719fdb78952cf57e28647cc52fe7844957 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 6 Nov 2009 13:35:26 -0500
Subject: [PATCH 16/35] Don't delay login for passwd -d users
@@ -7281,7 +7281,7 @@ index a64bbc2..d689d91 100644
1.7.4.1
-From 4f2908ab972ed543a50455f2b1b52953cbc95741 Mon Sep 17 00:00:00 2001
+From b0a3cad225154377fa0e5429ebe4525d5f7e291e Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 30 Jan 2009 23:57:31 -0500
Subject: [PATCH 17/35] Add a plugin based extension system to greeter
@@ -7356,7 +7356,7 @@ index d5455e1..d8a9e72 100644
VOID:DOUBLE
+BOOLEAN:STRING
diff --git a/configure.ac b/configure.ac
-index fe612e7..8a423bb 100644
+index 48be019..2a2e37b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,6 +18,22 @@ AC_PROG_CXX
@@ -7382,7 +7382,7 @@ index fe612e7..8a423bb 100644
AC_HEADER_STDC
AC_SUBST(VERSION)
-@@ -192,6 +208,15 @@ AC_ARG_WITH(dmconfdir,
+@@ -193,6 +209,15 @@ AC_ARG_WITH(dmconfdir,
AC_SUBST(dmconfdir)
dnl ---------------------------------------------------------------------------
@@ -7398,7 +7398,7 @@ index fe612e7..8a423bb 100644
dnl - Configure arguments
dnl ---------------------------------------------------------------------------
-@@ -1268,6 +1293,21 @@ fi
+@@ -1269,6 +1294,21 @@ fi
AC_SUBST(GDM_SCREENSHOT_DIR)
@@ -7420,7 +7420,7 @@ index fe612e7..8a423bb 100644
dnl ---------------------------------------------------------------------------
dnl - Finish
-@@ -1395,6 +1435,10 @@ daemon/Makefile
+@@ -1396,6 +1436,10 @@ daemon/Makefile
docs/Makefile
gui/Makefile
gui/simple-greeter/Makefile
@@ -7432,7 +7432,7 @@ index fe612e7..8a423bb 100644
utils/Makefile
data/gdm.conf
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
-index aa78504..f0ff206 100644
+index a842c7b..d5e68a2 100644
--- a/gui/simple-greeter/Makefile.am
+++ b/gui/simple-greeter/Makefile.am
@@ -1,8 +1,13 @@
@@ -7457,7 +7457,7 @@ index aa78504..f0ff206 100644
$(DISABLE_DEPRECATED_CFLAGS) \
$(GTK_CFLAGS) \
$(SIMPLE_GREETER_CFLAGS) \
-@@ -83,10 +89,17 @@ test_greeter_login_window_SOURCES = \
+@@ -60,10 +66,17 @@ test_greeter_login_window_SOURCES = \
gdm-user-chooser-widget.c \
gdm-user-chooser-dialog.h \
gdm-user-chooser-dialog.c \
@@ -7472,10 +7472,10 @@ index aa78504..f0ff206 100644
test_greeter_login_window_LDADD = \
$(top_builddir)/common/libgdmcommon.la \
+ $(top_builddir)/gui/simple-greeter/libgdmsimplegreeter/libgdmsimplegreeter.la \
- libgdmuser.la \
$(COMMON_LIBS) \
$(SIMPLE_GREETER_LIBS) \
-@@ -128,6 +141,7 @@ test_greeter_panel_SOURCES = \
+ $(RBAC_LIBS) \
+@@ -104,6 +117,7 @@ test_greeter_panel_SOURCES = \
test_greeter_panel_LDADD = \
$(top_builddir)/common/libgdmcommon.la \
@@ -7483,7 +7483,7 @@ index aa78504..f0ff206 100644
$(SIMPLE_GREETER_LIBS) \
$(GTK_LIBS) \
$(GCONF_LIBS) \
-@@ -271,17 +285,24 @@ gdm_simple_greeter_SOURCES = \
+@@ -245,16 +259,23 @@ gdm_simple_greeter_SOURCES = \
gdm-language-chooser-dialog.c \
gdm-language-option-widget.h \
gdm-language-option-widget.c \
@@ -7503,7 +7503,6 @@ index aa78504..f0ff206 100644
gdm_simple_greeter_LDADD = \
$(top_builddir)/common/libgdmcommon.la \
- libgdmuser.la \
+ $(top_builddir)/gui/simple-greeter/libgdmsimplegreeter/libgdmsimplegreeter.la \
$(COMMON_LIBS) \
$(EXTRA_GREETER_LIBS) \
@@ -10938,10 +10937,10 @@ index 0000000..cc377bd
+
+#endif /* __GDM_TASK_LIST_H */
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
-index 9447e59..136194a 100644
+index a385218..8414313 100644
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
-@@ -371,9 +371,30 @@ gdm_user_chooser_widget_set_show_user_auto (GdmUserChooserWidget *widget,
+@@ -635,9 +635,30 @@ gdm_user_chooser_widget_set_show_user_auto (GdmUserChooserWidget *widget,
char *
gdm_user_chooser_widget_get_chosen_user_name (GdmUserChooserWidget *widget)
{
@@ -12313,7 +12312,7 @@ index 8a4997a..2f9af97 100644
1.7.4.1
-From 8b0c7fb9df4c51983bdc745e4ab0450cc4b7610e Mon Sep 17 00:00:00 2001
+From a659374376aa864925143b7b58847aca9e830345 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 4 Aug 2010 18:25:50 -0400
Subject: [PATCH 18/35] squash with password
@@ -12378,7 +12377,7 @@ index 255283e..11a171c 100644
1.7.4.1
-From 8aaa69fab5eecab0049b7bfe09c493cee2daccc1 Mon Sep 17 00:00:00 2001
+From 047ceabcb1fa549e9a6bb7197c5e12cdd4e49296 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 6 Aug 2010 11:13:10 -0400
Subject: [PATCH 19/35] task list fix
@@ -12428,7 +12427,7 @@ index 5fdc2b8..3e49fb7 100644
1.7.4.1
-From ab1ee02f38bcde2f7f999570c3b13725f096d20a Mon Sep 17 00:00:00 2001
+From 1055ba4d586d4f61a22faca0d968ddb8816b5569 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Tue, 29 Jun 2010 14:13:35 -0400
Subject: [PATCH 20/35] Show cancel button after first message
@@ -12472,7 +12471,7 @@ index 9844af9..938e523 100644
1.7.4.1
-From 20da8b82b8a4fd0d0233d8e3ecc05dd97af6a852 Mon Sep 17 00:00:00 2001
+From 72355ea96c482d015422b327c5ecca3b3766478d Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 28 Oct 2009 11:13:10 -0400
Subject: [PATCH 21/35] Prevent start session signal handler from getting called multiple times
@@ -12508,7 +12507,7 @@ index 938e523..0fb6c64 100644
1.7.4.1
-From 2645ecce2175231378170af39e08cf244f76d925 Mon Sep 17 00:00:00 2001
+From 889691316c708a787a5f60e91e380c658893542d Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 6 Feb 2009 16:25:47 -0500
Subject: [PATCH 22/35] Add fingerprint plugin
@@ -12544,10 +12543,10 @@ fingerprint scans.
create mode 100644 gui/simple-greeter/plugins/fingerprint/plugin.c
diff --git a/configure.ac b/configure.ac
-index 8a423bb..be1ff01 100644
+index 2a2e37b..98a8bf6 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -1439,6 +1439,10 @@ gui/simple-greeter/libgdmsimplegreeter/Makefile
+@@ -1440,6 +1440,10 @@ gui/simple-greeter/libgdmsimplegreeter/Makefile
gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc
gui/simple-greeter/plugins/Makefile
gui/simple-greeter/plugins/password/Makefile
@@ -13278,7 +13277,7 @@ index 2f9af97..4f5b317 100644
1.7.4.1
-From d197aa8a487a2ec249cc6dfd0c993bde13f22389 Mon Sep 17 00:00:00 2001
+From 65dd58cf8a77e2df4e517d23aefc7e7f2a186231 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 6 Feb 2009 16:25:47 -0500
Subject: [PATCH 23/35] Add smartcard plugin
@@ -13324,7 +13323,7 @@ smartcards are inserted.
create mode 100644 gui/simple-greeter/plugins/smartcard/plugin.c
diff --git a/configure.ac b/configure.ac
-index be1ff01..1048e3c 100644
+index 98a8bf6..5f370ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,7 @@ LIBCANBERRA_GTK_REQUIRED_VERSION=0.4
@@ -13348,7 +13347,7 @@ index be1ff01..1048e3c 100644
PKG_CHECK_MODULES(XLIB, x11 xau, ,
[AC_PATH_XTRA
if test "x$no_x" = xyes; then
-@@ -1443,6 +1450,10 @@ gui/simple-greeter/plugins/fingerprint/Makefile
+@@ -1444,6 +1451,10 @@ gui/simple-greeter/plugins/fingerprint/Makefile
gui/simple-greeter/plugins/fingerprint/icons/Makefile
gui/simple-greeter/plugins/fingerprint/icons/16x16/Makefile
gui/simple-greeter/plugins/fingerprint/icons/48x48/Makefile
@@ -16794,7 +16793,7 @@ index 4f5b317..48634f1 100644
1.7.4.1
-From 82fbee221f78718703481ae9b28933d81c7a2011 Mon Sep 17 00:00:00 2001
+From d52b686f0869887997864ea0553f3f5785f65b94 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 4 Aug 2010 18:26:01 -0400
Subject: [PATCH 24/35] squash with smartcard
@@ -16835,7 +16834,7 @@ index b925f5e..b40a21c 100644
1.7.4.1
-From 7e8cb867f0f73a1208e773bb7b09b57ba0d3a759 Mon Sep 17 00:00:00 2001
+From 6977055677ac889d204d17391327261e7dd1757f Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Tue, 21 Apr 2009 10:25:18 -0400
Subject: [PATCH 25/35] When one PAM conversation wins, stop the others
@@ -16967,7 +16966,7 @@ index 2ecf0a4..ff1f3af 100644
1.7.4.1
-From 01c711f4bc117d8c67eb1f78b56c3b3220d7371e Mon Sep 17 00:00:00 2001
+From 78949a4384dc2aae51bb8835520075bcc9793ef6 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 24 Jul 2009 14:41:48 -0400
Subject: [PATCH 26/35] KILL stuck processes if they don't die on TERM
@@ -17091,7 +17090,7 @@ index be85f30..8b93663 100644
1.7.4.1
-From ea0473ddf20f19d9506cac45a3d1dae85af62e42 Mon Sep 17 00:00:00 2001
+From 2316076b232cd4efd6e6e6f22c6af206ff7bb581 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Tue, 13 Jul 2010 22:36:19 -0400
Subject: [PATCH 27/35] add better debug spew (needs squash)
@@ -17144,7 +17143,7 @@ index 0f0c053..23812d2 100644
1.7.4.1
-From e8dffd5eb064b91a361333ffbfec661f1cc8f10a Mon Sep 17 00:00:00 2001
+From b98e46ec2d16d390c5fecf0b18471583ca54670f Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Tue, 13 Jul 2010 22:37:35 -0400
Subject: [PATCH 28/35] switch to proper mode when going to timed login
@@ -17170,7 +17169,7 @@ index 0fb6c64..adcd71f 100644
1.7.4.1
-From 31362325aaffea2632c21d42de137e64f560db44 Mon Sep 17 00:00:00 2001
+From 16c4f635f7442808d4f3f7f9232097b8bb093345 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Tue, 3 Aug 2010 15:21:26 -0400
Subject: [PATCH 29/35] Drop "Cancelling" message for plugin initiated cancels
@@ -17199,7 +17198,7 @@ index adcd71f..cd1941e 100644
1.7.4.1
-From 878951bf14c64b9103722ddebad9c8b4ea1023ad Mon Sep 17 00:00:00 2001
+From 40114bb382490be345b04004082c85d55cf53691 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 4 Aug 2010 18:11:27 -0400
Subject: [PATCH 30/35] drop code for label that doesn't exist anymore
@@ -17235,7 +17234,7 @@ index cd1941e..f3f89b2 100644
1.7.4.1
-From 8fca2ce5f0c8e7d3b9c491cb0bbac131582ae9dc Mon Sep 17 00:00:00 2001
+From 5cb876a52cd54a895dc925fc8625a4b4c490f4e9 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 4 Aug 2010 18:03:52 -0400
Subject: [PATCH 31/35] Add delay when showing messages (needs split)
@@ -17700,7 +17699,7 @@ index b40a21c..5e234b9 100644
1.7.4.1
-From 5a300c3cf9f73682c7209032193fc1b84442ad18 Mon Sep 17 00:00:00 2001
+From 438a429d75d0af77649901c2421e2898a504f831 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Wed, 4 Aug 2010 19:27:14 -0400
Subject: [PATCH 32/35] Drop cancelling message
@@ -17727,7 +17726,7 @@ index e43449e..cb03d06 100644
1.7.4.1
-From 203cf6865fda36f3b31db67ce1e316659c869134 Mon Sep 17 00:00:00 2001
+From 6720d05d54ec542dc9031f13462438fa5b8ebdf4 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Fri, 6 Aug 2010 11:14:23 -0400
Subject: [PATCH 33/35] manage tasks outside of task list
@@ -18528,7 +18527,7 @@ index cb03d06..627a6f9 100644
1.7.4.1
-From 73a39fd1baf58a88e9c01eb8815f662d2c1380e0 Mon Sep 17 00:00:00 2001
+From 62d27058a556a1e27099684470f9b24c97f011eb Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Mon, 9 Aug 2010 18:09:19 -0400
Subject: [PATCH 34/35] hide task actions more aggressively
@@ -18563,7 +18562,7 @@ index 627a6f9..8772fdd 100644
1.7.4.1
-From 58e5e724f54f1dffc20671b8131d8a4c7b354dcc Mon Sep 17 00:00:00 2001
+From 9255529aa654bd240db39888d1fd452d44ec9df3 Mon Sep 17 00:00:00 2001
From: Gal Hammer <ghammer at redhat.com>
Date: Thu, 21 Oct 2010 10:14:32 -0400
Subject: [PATCH 35/35] smartcard: don't show extension if disabled in authconfig
diff --git a/gdm.spec b/gdm.spec
index 2a14cd8..ccdb268 100644
--- a/gdm.spec
+++ b/gdm.spec
@@ -15,7 +15,7 @@
Summary: The GNOME Display Manager
Name: gdm
Version: 2.91.6
-Release: 9%{?dist}
+Release: 10%{?dist}
Epoch: 1
License: GPLv2+
Group: User Interface/X
@@ -42,6 +42,7 @@ Requires: xorg-x11-server-utils
Requires: setxkbmap
Requires: xorg-x11-xinit
Requires: ConsoleKit >= %{consolekit_version}
+Requires: accountsservice
Requires: gnome-settings-daemon >= 2.21.92
Requires: iso-codes
Requires: gnome-session
@@ -93,6 +94,7 @@ Patch2: plymouth.patch
Patch3: fix-theme-related-crash.patch
Patch4: fix-crasher.patch
Patch5: add-session-chooser.patch
+Patch6: move-to-accounts-library.patch
Patch96: gdm-multistack.patch
# Fedora-specific
@@ -127,6 +129,7 @@ The GDM fingerprint plugin provides functionality necessary to use a fingerprint
%patch3 -p1 -b .fix-theme-related-crash
%patch4 -p1 -b .fix-crasher
%patch5 -p1 -b .add-session-chooser
+%patch6 -p1 -b .move-to-accounts-library
%patch96 -p1 -b .multistack
%patch99 -p1 -b .fedora-logo
@@ -366,6 +369,13 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/ull || :
%{_libdir}/gdm/simple-greeter/plugins/fingerprint.so
%changelog
+* Fri Feb 18 2011 Ray Strode <rstrode at redhat.com> 2.91.6-10
+- Fix user list async bugs by dropping async code and
+ moving to accounts service library
+ Resolves: #678236
+- Add requires for accounts service to spec since it isn't
+ optional (and hasn't been for a while)
+
* Thu Feb 17 2011 Ray Strode <rstrode at redhat.com> 2.91.6-9
- Add back session chooser
Resolves: #539638
diff --git a/move-to-accounts-library.patch b/move-to-accounts-library.patch
new file mode 100644
index 0000000..7596555
--- /dev/null
+++ b/move-to-accounts-library.patch
@@ -0,0 +1,3961 @@
+From 4dad44a175493f1c495a90ba67270ba11c9c1802 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Fri, 18 Feb 2011 17:56:09 -0500
+Subject: [PATCH 1/2] greeter: fix swapped LHS/RHS in icon loading error path
+
+This nasty bug means in some obscure cases we're going to
+end up using freed memory.
+---
+ gui/simple-greeter/gdm-user-chooser-widget.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
+index 9447e59..4b5a80f 100644
+--- a/gui/simple-greeter/gdm-user-chooser-widget.c
++++ b/gui/simple-greeter/gdm-user-chooser-widget.c
+@@ -900,7 +900,7 @@ get_pixbuf_from_icon_names (GdmUserChooserWidget *widget,
+ TRUE, 8, 1, 1, 1, NULL, NULL);
+ scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, size, size, GDK_INTERP_NEAREST);
+ g_object_unref (pixbuf);
+- scaled_pixbuf = pixbuf;
++ pixbuf = scaled_pixbuf;
+ }
+
+ return pixbuf;
+--
+1.7.4.1
+
+
+From ec034f78dcb27baf240658323892ac2a665c6580 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Fri, 18 Feb 2011 17:54:08 -0500
+Subject: [PATCH 2/2] greeter: port to account service library
+
+The current user manager code is a mess of dbus code for
+talking to the accounts daemon and code for falling back if
+it isn't there. The accounts daemon is no longer optional,
+so drop all that and just use the accounts service library
+directly.
+---
+ configure.ac | 1 +
+ gui/simple-greeter/Makefile.am | 27 -
+ gui/simple-greeter/gdm-user-chooser-widget.c | 370 +++-
+ gui/simple-greeter/gdm-user-manager.c | 3082 --------------------------
+ gui/simple-greeter/gdm-user-manager.h | 91 -
+ gui/simple-greeter/test-user-manager.c | 27 +-
+ 6 files changed, 316 insertions(+), 3282 deletions(-)
+ delete mode 100644 gui/simple-greeter/gdm-user-manager.c
+ delete mode 100644 gui/simple-greeter/gdm-user-manager.h
+
+diff --git a/configure.ac b/configure.ac
+index fe612e7..48be019 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -125,6 +125,7 @@ PKG_CHECK_MODULES(SIMPLE_GREETER,
+ gtk+-3.0 >= $GTK_REQUIRED_VERSION
+ gconf-2.0 >= $GCONF_REQUIRED_VERSION
+ fontconfig >= $FONTCONFIG_REQUIRED_VERSION
++ accountsservice >= $ACCOUNTS_SERVICE_REQUIRED_VERSION
+ x11
+ )
+ SIMPLE_GREETER_LIBS="$SIMPLE_GREETER_LIBS -lm"
+diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
+index aa78504..a842c7b 100644
+--- a/gui/simple-greeter/Makefile.am
++++ b/gui/simple-greeter/Makefile.am
+@@ -26,29 +26,6 @@ schemasdir = @GCONF_SCHEMA_FILE_DIR@
+ schemas_in_files = gdm-simple-greeter.schemas.in
+ schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
+
+-noinst_LTLIBRARIES = \
+- libgdmuser.la \
+- $(null)
+-
+-libgdmuser_la_SOURCES = \
+- gdm-user.c \
+- gdm-user.h \
+- gdm-user-private.h \
+- gdm-user-manager.c \
+- gdm-user-manager.h \
+- $(NULL)
+-
+-libgdmuser_la_CFLAGS = \
+- $(SIMPLE_GREETER_CFLAGS) \
+- $(NULL)
+-
+-libgdmuser_la_LIBADD = \
+- $(NULL)
+-
+-libgdmuser_la_LDFLAGS = \
+- -export-dynamic \
+- $(NULL)
+-
+ noinst_PROGRAMS = \
+ test-filesystem-type \
+ test-greeter-login-window \
+@@ -87,7 +64,6 @@ test_greeter_login_window_SOURCES = \
+
+ test_greeter_login_window_LDADD = \
+ $(top_builddir)/common/libgdmcommon.la \
+- libgdmuser.la \
+ $(COMMON_LIBS) \
+ $(SIMPLE_GREETER_LIBS) \
+ $(RBAC_LIBS) \
+@@ -216,7 +192,6 @@ test_user_chooser_SOURCES = \
+ $(NULL)
+
+ test_user_chooser_LDADD = \
+- libgdmuser.la \
+ $(top_builddir)/common/libgdmcommon.la \
+ $(COMMON_LIBS) \
+ $(SIMPLE_GREETER_LIBS) \
+@@ -227,7 +202,6 @@ test_user_manager_SOURCES = \
+ $(NULL)
+
+ test_user_manager_LDADD = \
+- libgdmuser.la \
+ $(top_builddir)/common/libgdmcommon.la \
+ $(COMMON_LIBS) \
+ $(SIMPLE_GREETER_LIBS) \
+@@ -281,7 +255,6 @@ gdm_simple_greeter_SOURCES = \
+
+ gdm_simple_greeter_LDADD = \
+ $(top_builddir)/common/libgdmcommon.la \
+- libgdmuser.la \
+ $(COMMON_LIBS) \
+ $(EXTRA_GREETER_LIBS) \
+ $(SIMPLE_GREETER_LIBS) \
+diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
+index 4b5a80f..a385218 100644
+--- a/gui/simple-greeter/gdm-user-chooser-widget.c
++++ b/gui/simple-greeter/gdm-user-chooser-widget.c
+@@ -37,7 +37,9 @@
+
+ #include <gconf/gconf-client.h>
+
+-#include "gdm-user-manager.h"
++#include <act/act-user-manager.h>
++#include <act/act-user.h>
++
+ #include "gdm-user-chooser-widget.h"
+ #include "gdm-settings-keys.h"
+ #include "gdm-settings-client.h"
+@@ -59,7 +61,7 @@ enum {
+
+ struct GdmUserChooserWidgetPrivate
+ {
+- GdmUserManager *manager;
++ ActUserManager *manager;
+ GtkIconTheme *icon_theme;
+
+ GSList *users_to_add;
+@@ -170,45 +172,307 @@ queue_update_other_user_visibility (GdmUserChooserWidget *widget)
+ }
+
+ static void
++rounded_rectangle (cairo_t *cr,
++ gdouble aspect,
++ gdouble x,
++ gdouble y,
++ gdouble corner_radius,
++ gdouble width,
++ gdouble height)
++{
++ gdouble radius;
++ gdouble degrees;
++
++ radius = corner_radius / aspect;
++ degrees = G_PI / 180.0;
++
++ cairo_new_sub_path (cr);
++ cairo_arc (cr,
++ x + width - radius,
++ y + radius,
++ radius,
++ -90 * degrees,
++ 0 * degrees);
++ cairo_arc (cr,
++ x + width - radius,
++ y + height - radius,
++ radius,
++ 0 * degrees,
++ 90 * degrees);
++ cairo_arc (cr,
++ x + radius,
++ y + height - radius,
++ radius,
++ 90 * degrees,
++ 180 * degrees);
++ cairo_arc (cr,
++ x + radius,
++ y + radius,
++ radius,
++ 180 * degrees,
++ 270 * degrees);
++ cairo_close_path (cr);
++}
++
++static cairo_surface_t *
++surface_from_pixbuf (GdkPixbuf *pixbuf)
++{
++ cairo_surface_t *surface;
++ cairo_t *cr;
++
++ surface = cairo_image_surface_create (gdk_pixbuf_get_has_alpha (pixbuf) ?
++ CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
++ gdk_pixbuf_get_width (pixbuf),
++ gdk_pixbuf_get_height (pixbuf));
++ cr = cairo_create (surface);
++ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
++ cairo_paint (cr);
++ cairo_destroy (cr);
++
++ return surface;
++}
++
++/**
++ * go_cairo_convert_data_to_pixbuf:
++ * @src: a pointer to pixel data in cairo format
++ * @dst: a pointer to pixel data in pixbuf format
++ * @width: image width
++ * @height: image height
++ * @rowstride: data rowstride
++ *
++ * Converts the pixel data stored in @src in CAIRO_FORMAT_ARGB32 cairo format
++ * to GDK_COLORSPACE_RGB pixbuf format and move them
++ * to @dst. If @src == @dst, pixel are converted in place.
++ **/
++
++static void
++go_cairo_convert_data_to_pixbuf (unsigned char *dst,
++ unsigned char const *src,
++ int width,
++ int height,
++ int rowstride)
++{
++ int i,j;
++ unsigned int t;
++ unsigned char a, b, c;
++
++ g_return_if_fail (dst != NULL);
++
++#define MULT(d,c,a,t) G_STMT_START { t = (a)? c * 255 / a: 0; d = t;} G_STMT_END
++
++ if (src == dst || src == NULL) {
++ for (i = 0; i < height; i++) {
++ for (j = 0; j < width; j++) {
++#if G_BYTE_ORDER == G_LITTLE_ENDIAN
++ MULT(a, dst[2], dst[3], t);
++ MULT(b, dst[1], dst[3], t);
++ MULT(c, dst[0], dst[3], t);
++ dst[0] = a;
++ dst[1] = b;
++ dst[2] = c;
++#else
++ MULT(a, dst[1], dst[0], t);
++ MULT(b, dst[2], dst[0], t);
++ MULT(c, dst[3], dst[0], t);
++ dst[3] = dst[0];
++ dst[0] = a;
++ dst[1] = b;
++ dst[2] = c;
++#endif
++ dst += 4;
++ }
++ dst += rowstride - width * 4;
++ }
++ } else {
++ for (i = 0; i < height; i++) {
++ for (j = 0; j < width; j++) {
++#if G_BYTE_ORDER == G_LITTLE_ENDIAN
++ MULT(dst[0], src[2], src[3], t);
++ MULT(dst[1], src[1], src[3], t);
++ MULT(dst[2], src[0], src[3], t);
++ dst[3] = src[3];
++#else
++ MULT(dst[0], src[1], src[0], t);
++ MULT(dst[1], src[2], src[0], t);
++ MULT(dst[2], src[3], src[0], t);
++ dst[3] = src[0];
++#endif
++ src += 4;
++ dst += 4;
++ }
++ src += rowstride - width * 4;
++ dst += rowstride - width * 4;
++ }
++ }
++#undef MULT
++}
++
++static void
++cairo_to_pixbuf (guint8 *src_data,
++ GdkPixbuf *dst_pixbuf)
++{
++ unsigned char *src;
++ unsigned char *dst;
++ guint w;
++ guint h;
++ guint rowstride;
++
++ w = gdk_pixbuf_get_width (dst_pixbuf);
++ h = gdk_pixbuf_get_height (dst_pixbuf);
++ rowstride = gdk_pixbuf_get_rowstride (dst_pixbuf);
++
++ dst = gdk_pixbuf_get_pixels (dst_pixbuf);
++ src = src_data;
++
++ go_cairo_convert_data_to_pixbuf (dst, src, w, h, rowstride);
++}
++
++static GdkPixbuf *
++frame_pixbuf (GdkPixbuf *source)
++{
++ GdkPixbuf *dest;
++ cairo_t *cr;
++ cairo_surface_t *surface;
++ guint w;
++ guint h;
++ guint rowstride;
++ int frame_width;
++ double radius;
++ guint8 *data;
++
++ frame_width = 2;
++
++ w = gdk_pixbuf_get_width (source) + frame_width * 2;
++ h = gdk_pixbuf_get_height (source) + frame_width * 2;
++ radius = w / 10;
++
++ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
++ TRUE,
++ 8,
++ w,
++ h);
++ rowstride = gdk_pixbuf_get_rowstride (dest);
++
++
++ data = g_new0 (guint8, h * rowstride);
++
++ surface = cairo_image_surface_create_for_data (data,
++ CAIRO_FORMAT_ARGB32,
++ w,
++ h,
++ rowstride);
++ cr = cairo_create (surface);
++ cairo_surface_destroy (surface);
++
++ /* set up image */
++ cairo_rectangle (cr, 0, 0, w, h);
++ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
++ cairo_fill (cr);
++
++ rounded_rectangle (cr,
++ 1.0,
++ frame_width + 0.5,
++ frame_width + 0.5,
++ radius,
++ w - frame_width * 2 - 1,
++ h - frame_width * 2 - 1);
++ cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3);
++ cairo_fill_preserve (cr);
++
++ surface = surface_from_pixbuf (source);
++ cairo_set_source_surface (cr, surface, frame_width, frame_width);
++ cairo_fill (cr);
++ cairo_surface_destroy (surface);
++
++ cairo_to_pixbuf (data, dest);
++
++ cairo_destroy (cr);
++ g_free (data);
++
++ return dest;
++}
++
++static GdkPixbuf *
++render_user_icon (GdmUserChooserWidget *widget,
++ ActUser *user)
++{
++ int size;
++ const char *file;
++ GdkPixbuf *pixbuf;
++ GdkPixbuf *framed;
++
++ pixbuf = NULL;
++
++ size = get_icon_height_for_widget (GTK_WIDGET (widget));
++ file = act_user_get_icon_file (user);
++
++ if (file) {
++ pixbuf = gdk_pixbuf_new_from_file_at_size (file, size, size, NULL);
++ }
++
++ if (pixbuf == NULL) {
++ GError *error;
++
++ error = NULL;
++ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
++ "avatar-default",
++ size,
++ GTK_ICON_LOOKUP_FORCE_SIZE,
++ &error);
++ if (error != NULL) {
++ g_warning ("%s", error->message);
++ g_error_free (error);
++ }
++ }
++
++ if (pixbuf != NULL) {
++ framed = frame_pixbuf (pixbuf);
++ g_object_unref (pixbuf);
++
++ pixbuf = framed;
++ }
++
++ return pixbuf;
++}
++
++static void
+ update_item_for_user (GdmUserChooserWidget *widget,
+- GdmUser *user)
++ ActUser *user)
+ {
+ GdkPixbuf *pixbuf;
+ char *tooltip;
+ gboolean is_logged_in;
+- int size;
+ char *escaped_username;
+ char *escaped_real_name;
+
+- if (!gdm_user_is_loaded (user)) {
++ if (!act_user_is_loaded (user)) {
+ return;
+ }
+
+- size = get_icon_height_for_widget (GTK_WIDGET (widget));
+- pixbuf = gdm_user_render_icon (user, size);
++ pixbuf = render_user_icon (widget, user);
+
+ if (pixbuf == NULL && widget->priv->stock_person_pixbuf != NULL) {
+ pixbuf = g_object_ref (widget->priv->stock_person_pixbuf);
+ }
+
+ tooltip = g_strdup_printf (_("Log in as %s"),
+- gdm_user_get_user_name (user));
++ act_user_get_user_name (user));
+
+- is_logged_in = gdm_user_is_logged_in (user);
++ is_logged_in = act_user_is_logged_in (user);
+
+ g_debug ("GdmUserChooserWidget: User added name:%s logged-in:%d pixbuf:%p",
+- gdm_user_get_user_name (user),
++ act_user_get_user_name (user),
+ is_logged_in,
+ pixbuf);
+
+- escaped_username = g_markup_escape_text (gdm_user_get_user_name (user), -1);
+- escaped_real_name = g_markup_escape_text (gdm_user_get_real_name (user), -1);
++ escaped_username = g_markup_escape_text (act_user_get_user_name (user), -1);
++ escaped_real_name = g_markup_escape_text (act_user_get_real_name (user), -1);
+ gdm_chooser_widget_update_item (GDM_CHOOSER_WIDGET (widget),
+ escaped_username,
+ pixbuf,
+ escaped_real_name,
+ tooltip,
+- gdm_user_get_login_frequency (user),
++ act_user_get_login_frequency (user),
+ is_logged_in,
+ FALSE);
+ g_free (escaped_real_name);
+@@ -225,7 +489,7 @@ on_item_load (GdmChooserWidget *widget,
+ const char *id,
+ GdmUserChooserWidget *user_chooser)
+ {
+- GdmUser *user;
++ ActUser *user;
+
+ g_debug ("GdmUserChooserWidget: Loading item for id=%s", id);
+
+@@ -241,7 +505,7 @@ on_item_load (GdmChooserWidget *widget,
+ return;
+ }
+
+- user = gdm_user_manager_get_user (user_chooser->priv->manager, id);
++ user = act_user_manager_get_user (user_chooser->priv->manager, id);
+ if (user != NULL) {
+ update_item_for_user (user_chooser, user);
+ }
+@@ -467,7 +731,7 @@ is_user_list_disabled (GdmUserChooserWidget *widget)
+
+ static void
+ add_user (GdmUserChooserWidget *widget,
+- GdmUser *user)
++ ActUser *user)
+ {
+ GdkPixbuf *pixbuf;
+ char *tooltip;
+@@ -486,18 +750,18 @@ add_user (GdmUserChooserWidget *widget,
+ }
+
+ tooltip = g_strdup_printf (_("Log in as %s"),
+- gdm_user_get_user_name (user));
++ act_user_get_user_name (user));
+
+- is_logged_in = gdm_user_is_logged_in (user);
++ is_logged_in = act_user_is_logged_in (user);
+
+- escaped_username = g_markup_escape_text (gdm_user_get_user_name (user), -1);
+- escaped_real_name = g_markup_escape_text (gdm_user_get_real_name (user), -1);
++ escaped_username = g_markup_escape_text (act_user_get_user_name (user), -1);
++ escaped_real_name = g_markup_escape_text (act_user_get_real_name (user), -1);
+ gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget),
+ escaped_username,
+ pixbuf,
+ escaped_real_name,
+ tooltip,
+- gdm_user_get_login_frequency (user),
++ act_user_get_login_frequency (user),
+ is_logged_in,
+ FALSE,
+ (GdmChooserWidgetItemLoadFunc) on_item_load,
+@@ -514,8 +778,8 @@ add_user (GdmUserChooserWidget *widget,
+ }
+
+ static void
+-on_user_added (GdmUserManager *manager,
+- GdmUser *user,
++on_user_added (ActUserManager *manager,
++ ActUser *user,
+ GdmUserChooserWidget *widget)
+ {
+ /* wait for all users to be loaded */
+@@ -526,19 +790,19 @@ on_user_added (GdmUserManager *manager,
+ }
+
+ static void
+-on_user_removed (GdmUserManager *manager,
+- GdmUser *user,
++on_user_removed (ActUserManager *manager,
++ ActUser *user,
+ GdmUserChooserWidget *widget)
+ {
+ const char *user_name;
+
+- g_debug ("GdmUserChooserWidget: User removed: %s", gdm_user_get_user_name (user));
++ g_debug ("GdmUserChooserWidget: User removed: %s", act_user_get_user_name (user));
+ /* wait for all users to be loaded */
+ if (! widget->priv->loaded) {
+ return;
+ }
+
+- user_name = gdm_user_get_user_name (user);
++ user_name = act_user_get_user_name (user);
+
+ gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
+ user_name);
+@@ -547,17 +811,17 @@ on_user_removed (GdmUserManager *manager,
+ }
+
+ static void
+-on_user_is_logged_in_changed (GdmUserManager *manager,
+- GdmUser *user,
++on_user_is_logged_in_changed (ActUserManager *manager,
++ ActUser *user,
+ GdmUserChooserWidget *widget)
+ {
+ const char *user_name;
+ gboolean is_logged_in;
+
+- g_debug ("GdmUserChooserWidget: User logged in changed: %s", gdm_user_get_user_name (user));
++ g_debug ("GdmUserChooserWidget: User logged in changed: %s", act_user_get_user_name (user));
+
+- user_name = gdm_user_get_user_name (user);
+- is_logged_in = gdm_user_is_logged_in (user);
++ user_name = act_user_get_user_name (user);
++ is_logged_in = act_user_is_logged_in (user);
+
+ gdm_chooser_widget_set_item_in_use (GDM_CHOOSER_WIDGET (widget),
+ user_name,
+@@ -565,8 +829,8 @@ on_user_is_logged_in_changed (GdmUserManager *manager,
+ }
+
+ static void
+-on_user_changed (GdmUserManager *manager,
+- GdmUser *user,
++on_user_changed (ActUserManager *manager,
++ ActUser *user,
+ GdmUserChooserWidget *widget)
+ {
+ /* wait for all users to be loaded */
+@@ -612,7 +876,7 @@ queue_add_users (GdmUserChooserWidget *widget)
+ }
+
+ static void
+-on_is_loaded_changed (GdmUserManager *manager,
++on_is_loaded_changed (ActUserManager *manager,
+ GParamSpec *pspec,
+ GdmUserChooserWidget *widget)
+ {
+@@ -622,7 +886,7 @@ on_is_loaded_changed (GdmUserManager *manager,
+
+ g_debug ("GdmUserChooserWidget: Users loaded");
+
+- users = gdm_user_manager_list_users (manager);
++ users = act_user_manager_list_users (manager);
+ g_slist_foreach (users, (GFunc) g_object_ref, NULL);
+ widget->priv->users_to_add = g_slist_concat (widget->priv->users_to_add, g_slist_copy (users));
+
+@@ -658,38 +922,7 @@ load_users (GdmUserChooserWidget *widget)
+ {
+
+ if (widget->priv->show_normal_users) {
+- char *temp;
+- gboolean res;
+- gboolean include_all;
+- GSList *includes;
+- GSList *excludes;
+-
+- widget->priv->manager = gdm_user_manager_ref_default ();
+-
+- /* exclude/include */
+- g_debug ("Setting users to include:");
+- res = gdm_settings_client_get_string (GDM_KEY_INCLUDE,
+- &temp);
+- parse_string_list (temp, &includes);
+-
+- g_debug ("Setting users to exclude:");
+- res = gdm_settings_client_get_string (GDM_KEY_EXCLUDE,
+- &temp);
+- parse_string_list (temp, &excludes);
+-
+- include_all = FALSE;
+- res = gdm_settings_client_get_boolean (GDM_KEY_INCLUDE_ALL,
+- &include_all);
+- g_object_set (widget->priv->manager,
+- "include-all", include_all,
+- "include-usernames-list", includes,
+- "exclude-usernames-list", excludes,
+- NULL);
+-
+- g_slist_foreach (includes, (GFunc) g_free, NULL);
+- g_slist_free (includes);
+- g_slist_foreach (excludes, (GFunc) g_free, NULL);
+- g_slist_free (excludes);
++ widget->priv->manager = act_user_manager_get_default ();
+
+ g_signal_connect (widget->priv->manager,
+ "user-added",
+@@ -711,7 +944,6 @@ load_users (GdmUserChooserWidget *widget)
+ "user-changed",
+ G_CALLBACK (on_user_changed),
+ widget);
+- gdm_user_manager_queue_load (widget->priv->manager);
+ } else {
+ gdm_chooser_widget_loaded (GDM_CHOOSER_WIDGET (widget));
+ }
+diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
+deleted file mode 100644
+index c631989..0000000
+--- a/gui/simple-greeter/gdm-user-manager.c
++++ /dev/null
+@@ -1,3082 +0,0 @@
+-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+- *
+- * Copyright (C) 2007-2008 William Jon McCann <mccann at jhu.edu>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+- *
+- */
+-
+-#include "config.h"
+-
+-#include <stdlib.h>
+-#include <stdio.h>
+-#include <fcntl.h>
+-#include <unistd.h>
+-#include <string.h>
+-#include <signal.h>
+-#include <errno.h>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-
+-#ifdef HAVE_PATHS_H
+-#include <paths.h>
+-#endif /* HAVE_PATHS_H */
+-
+-#include <glib.h>
+-#include <glib/gi18n.h>
+-#include <glib/gstdio.h>
+-#include <glib-object.h>
+-#include <gio/gio.h>
+-
+-#include <dbus/dbus.h>
+-#include <dbus/dbus-glib.h>
+-#include <dbus/dbus-glib-lowlevel.h>
+-
+-#include "gdm-user-manager.h"
+-#include "gdm-user-private.h"
+-
+-#define GDM_USER_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerPrivate))
+-
+-#define CK_NAME "org.freedesktop.ConsoleKit"
+-
+-#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
+-#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+-#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
+-#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
+-
+-#define GDM_DBUS_TYPE_G_OBJECT_PATH_ARRAY (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))
+-
+-/* Prefs Defaults */
+-
+-#ifdef __sun
+-#define FALLBACK_MINIMAL_UID 100
+-#else
+-#define FALLBACK_MINIMAL_UID 500
+-#endif
+-
+-#ifndef _PATH_SHELLS
+-#define _PATH_SHELLS "/etc/shells"
+-#endif
+-#define PATH_PASSWD "/etc/passwd"
+-
+-#ifndef GDM_USERNAME
+-#define GDM_USERNAME "gdm"
+-#endif
+-
+-#define RELOAD_PASSWD_THROTTLE_SECS 5
+-
+-/* approximately two months */
+-#define LOGIN_FREQUENCY_TIME_WINDOW_SECS (60 * 24 * 60 * 60)
+-
+-#define ACCOUNTS_NAME "org.freedesktop.Accounts"
+-#define ACCOUNTS_PATH "/org/freedesktop/Accounts"
+-#define ACCOUNTS_INTERFACE "org.freedesktop.Accounts"
+-
+-typedef enum {
+- GDM_USER_MANAGER_SEAT_STATE_UNLOADED = 0,
+- GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID,
+- GDM_USER_MANAGER_SEAT_STATE_GET_ID,
+- GDM_USER_MANAGER_SEAT_STATE_GET_PROXY,
+- GDM_USER_MANAGER_SEAT_STATE_LOADED,
+-} GdmUserManagerSeatState;
+-
+-typedef struct
+-{
+- GdmUserManagerSeatState state;
+- char *id;
+- char *session_id;
+- union {
+- DBusGProxyCall *get_current_session_call;
+- DBusGProxyCall *get_seat_id_call;
+- };
+-
+- DBusGProxy *proxy;
+-} GdmUserManagerSeat;
+-
+-typedef enum {
+- GDM_USER_MANAGER_NEW_SESSION_STATE_UNLOADED = 0,
+- GDM_USER_MANAGER_NEW_SESSION_STATE_GET_PROXY,
+- GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID,
+- GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY,
+- GDM_USER_MANAGER_NEW_SESSION_STATE_MAYBE_ADD,
+- GDM_USER_MANAGER_NEW_SESSION_STATE_LOADED,
+-} GdmUserManagerNewSessionState;
+-
+-typedef struct
+-{
+- GdmUserManager *manager;
+- GdmUserManagerNewSessionState state;
+- char *id;
+-
+- union {
+- DBusGProxyCall *get_unix_user_call;
+- DBusGProxyCall *get_x11_display_call;
+- };
+-
+- DBusGProxy *proxy;
+-
+- uid_t uid;
+- char *x11_display;
+-} GdmUserManagerNewSession;
+-
+-typedef enum {
+- GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED = 0,
+- GDM_USER_MANAGER_GET_USER_STATE_WAIT_FOR_LOADED,
+- GDM_USER_MANAGER_GET_USER_STATE_ASK_ACCOUNTS_SERVICE,
+- GDM_USER_MANAGER_GET_USER_STATE_FETCHED
+-} GdmUserManagerGetUserState;
+-
+-typedef struct
+-{
+- GdmUserManager *manager;
+- GdmUserManagerGetUserState state;
+- GdmUser *user;
+- char *username;
+- char *object_path;
+-
+- DBusGProxyCall *call;
+-} GdmUserManagerFetchUserRequest;
+-
+-struct GdmUserManagerPrivate
+-{
+- GHashTable *users_by_name;
+- GHashTable *users_by_object_path;
+- GHashTable *sessions;
+- GHashTable *shells;
+- DBusGConnection *connection;
+- DBusGProxyCall *get_sessions_call;
+- DBusGProxy *accounts_proxy;
+-
+- GdmUserManagerSeat seat;
+-
+- GSList *new_sessions;
+- GSList *new_users;
+- GSList *fetch_user_requests;
+-
+- GFileMonitor *passwd_monitor;
+- GFileMonitor *shells_monitor;
+-
+- GSList *exclude_usernames;
+- GSList *include_usernames;
+- gboolean include_all;
+-
+- gboolean load_passwd_pending;
+-
+- guint load_id;
+- guint reload_passwd_id;
+- guint ck_history_id;
+- guint ck_history_watchdog_id;
+- GPid ck_history_pid;
+-
+- gboolean is_loaded;
+- gboolean has_multiple_users;
+- gboolean listing_cached_users;
+-};
+-
+-enum {
+- PROP_0,
+- PROP_INCLUDE_ALL,
+- PROP_INCLUDE_USERNAMES_LIST,
+- PROP_EXCLUDE_USERNAMES_LIST,
+- PROP_IS_LOADED,
+- PROP_HAS_MULTIPLE_USERS
+-};
+-
+-enum {
+- USER_ADDED,
+- USER_REMOVED,
+- USER_IS_LOGGED_IN_CHANGED,
+- USER_CHANGED,
+- LAST_SIGNAL
+-};
+-
+-static guint signals [LAST_SIGNAL] = { 0, };
+-
+-static void gdm_user_manager_class_init (GdmUserManagerClass *klass);
+-static void gdm_user_manager_init (GdmUserManager *user_manager);
+-static void gdm_user_manager_finalize (GObject *object);
+-
+-static void load_users_manually (GdmUserManager *manager);
+-static void monitor_local_users (GdmUserManager *manager);
+-static void load_seat_incrementally (GdmUserManager *manager);
+-static void unload_seat (GdmUserManager *manager);
+-static void load_users (GdmUserManager *manager);
+-static void queue_load_seat_and_users (GdmUserManager *manager);
+-static void monitor_local_users (GdmUserManager *manager);
+-
+-static void load_new_session_incrementally (GdmUserManagerNewSession *new_session);
+-static void set_is_loaded (GdmUserManager *manager, gboolean is_loaded);
+-
+-static void on_new_user_loaded (GdmUser *user,
+- GParamSpec *pspec,
+- GdmUserManager *manager);
+-static void give_up_and_fetch_user_locally (GdmUserManager *manager,
+- GdmUserManagerFetchUserRequest *request);
+-static void fetch_user_locally (GdmUserManager *manager,
+- GdmUser *user,
+- const char *username);
+-static void fetch_user_incrementally (GdmUserManagerFetchUserRequest *request);
+-
+-static void maybe_set_is_loaded (GdmUserManager *manager);
+-static gpointer user_manager_object = NULL;
+-
+-G_DEFINE_TYPE (GdmUserManager, gdm_user_manager, G_TYPE_OBJECT)
+-
+-GQuark
+-gdm_user_manager_error_quark (void)
+-{
+- static GQuark ret = 0;
+- if (ret == 0) {
+- ret = g_quark_from_static_string ("gdm_user_manager_error");
+- }
+-
+- return ret;
+-}
+-
+-static gboolean
+-start_new_login_session (GdmUserManager *manager)
+-{
+- GError *error;
+- gboolean res;
+-
+- res = g_spawn_command_line_async ("gdmflexiserver -s", &error);
+- if (! res) {
+- if (error != NULL) {
+- g_warning ("Unable to start new login: %s", error->message);
+- g_error_free (error);
+- } else {
+- g_warning ("Unable to start new login");
+- }
+- }
+-
+- return res;
+-}
+-
+-static gboolean
+-activate_session_id (GdmUserManager *manager,
+- const char *seat_id,
+- const char *session_id)
+-{
+- DBusError local_error;
+- DBusMessage *message;
+- DBusMessage *reply;
+- gboolean ret;
+-
+- ret = FALSE;
+- reply = NULL;
+-
+- dbus_error_init (&local_error);
+- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+- seat_id,
+- "org.freedesktop.ConsoleKit.Seat",
+- "ActivateSession");
+- if (message == NULL) {
+- goto out;
+- }
+-
+- if (! dbus_message_append_args (message,
+- DBUS_TYPE_OBJECT_PATH, &session_id,
+- DBUS_TYPE_INVALID)) {
+- goto out;
+- }
+-
+-
+- dbus_error_init (&local_error);
+- reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (manager->priv->connection),
+- message,
+- -1,
+- &local_error);
+- if (reply == NULL) {
+- if (dbus_error_is_set (&local_error)) {
+- g_warning ("Unable to activate session: %s", local_error.message);
+- dbus_error_free (&local_error);
+- goto out;
+- }
+- }
+-
+- ret = TRUE;
+- out:
+- if (message != NULL) {
+- dbus_message_unref (message);
+- }
+- if (reply != NULL) {
+- dbus_message_unref (reply);
+- }
+-
+- return ret;
+-}
+-
+-static gboolean
+-session_is_login_window (GdmUserManager *manager,
+- const char *session_id)
+-{
+- DBusGProxy *proxy;
+- GError *error;
+- gboolean res;
+- gboolean ret;
+- char *session_type;
+-
+- ret = FALSE;
+-
+- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
+- CK_NAME,
+- session_id,
+- CK_SESSION_INTERFACE);
+- if (proxy == NULL) {
+- g_warning ("Failed to connect to the ConsoleKit seat object");
+- goto out;
+- }
+-
+- session_type = NULL;
+- error = NULL;
+- res = dbus_g_proxy_call (proxy,
+- "GetSessionType",
+- &error,
+- G_TYPE_INVALID,
+- G_TYPE_STRING, &session_type,
+- G_TYPE_INVALID);
+- if (! res) {
+- if (error != NULL) {
+- g_debug ("GdmUserManager: Failed to identify the session type: %s", error->message);
+- g_error_free (error);
+- } else {
+- g_debug ("GdmUserManager: Failed to identify the session type");
+- }
+- goto out;
+- }
+-
+- if (session_type == NULL || session_type[0] == '\0' || strcmp (session_type, "LoginWindow") != 0) {
+- goto out;
+- }
+-
+- ret = TRUE;
+-
+- out:
+- if (proxy != NULL) {
+- g_object_unref (proxy);
+- }
+-
+- return ret;
+-}
+-
+-static char *
+-_get_login_window_session_id (GdmUserManager *manager)
+-{
+- gboolean res;
+- gboolean can_activate_sessions;
+- GError *error;
+- GPtrArray *sessions;
+- char *primary_ssid;
+- int i;
+-
+- if (manager->priv->seat.id == NULL || manager->priv->seat.id[0] == '\0') {
+- g_debug ("GdmUserManager: display seat ID is not set; can't switch sessions");
+- return NULL;
+- }
+-
+- primary_ssid = NULL;
+- sessions = NULL;
+-
+- can_activate_sessions = gdm_user_manager_can_switch (manager);
+-
+- if (! can_activate_sessions) {
+- g_debug ("GdmUserManager: seat is unable to activate sessions");
+- goto out;
+- }
+-
+- error = NULL;
+- res = dbus_g_proxy_call (manager->priv->seat.proxy,
+- "GetSessions",
+- &error,
+- G_TYPE_INVALID,
+- dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions,
+- G_TYPE_INVALID);
+- if (! res) {
+- if (error != NULL) {
+- g_warning ("unable to determine sessions for user: %s",
+- error->message);
+- g_error_free (error);
+- } else {
+- g_warning ("unable to determine sessions for user");
+- }
+- goto out;
+- }
+-
+- for (i = 0; i < sessions->len; i++) {
+- char *ssid;
+-
+- ssid = g_ptr_array_index (sessions, i);
+-
+- if (session_is_login_window (manager, ssid)) {
+- primary_ssid = g_strdup (ssid);
+- break;
+- }
+- }
+- g_ptr_array_foreach (sessions, (GFunc)g_free, NULL);
+- g_ptr_array_free (sessions, TRUE);
+-
+- out:
+-
+- return primary_ssid;
+-}
+-
+-gboolean
+-gdm_user_manager_goto_login_session (GdmUserManager *manager)
+-{
+- gboolean ret;
+- gboolean res;
+- char *ssid;
+-
+- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), FALSE);
+- g_return_val_if_fail (manager->priv->is_loaded, FALSE);
+-
+- ret = FALSE;
+-
+- /* First look for any existing LoginWindow sessions on the seat.
+- If none are found, create a new one. */
+-
+- ssid = _get_login_window_session_id (manager);
+- if (ssid != NULL) {
+- res = activate_session_id (manager, manager->priv->seat.id, ssid);
+- if (res) {
+- ret = TRUE;
+- }
+- }
+-
+- if (! ret) {
+- res = start_new_login_session (manager);
+- if (res) {
+- ret = TRUE;
+- }
+- }
+-
+- return ret;
+-}
+-
+-gboolean
+-gdm_user_manager_can_switch (GdmUserManager *manager)
+-{
+- gboolean res;
+- gboolean can_activate_sessions;
+- GError *error;
+-
+- if (!manager->priv->is_loaded) {
+- g_debug ("GdmUserManager: Unable to switch sessions until fully loaded");
+- return FALSE;
+- }
+-
+- if (manager->priv->seat.id == NULL || manager->priv->seat.id[0] == '\0') {
+- g_debug ("GdmUserManager: display seat ID is not set; can't switch sessions");
+- return FALSE;
+- }
+-
+- g_debug ("GdmUserManager: checking if seat can activate sessions");
+-
+- error = NULL;
+- res = dbus_g_proxy_call (manager->priv->seat.proxy,
+- "CanActivateSessions",
+- &error,
+- G_TYPE_INVALID,
+- G_TYPE_BOOLEAN, &can_activate_sessions,
+- G_TYPE_INVALID);
+- if (! res) {
+- if (error != NULL) {
+- g_warning ("unable to determine if seat can activate sessions: %s",
+- error->message);
+- g_error_free (error);
+- } else {
+- g_warning ("unable to determine if seat can activate sessions");
+- }
+- return FALSE;
+- }
+-
+- return can_activate_sessions;
+-}
+-
+-gboolean
+-gdm_user_manager_activate_user_session (GdmUserManager *manager,
+- GdmUser *user)
+-{
+- gboolean ret;
+- const char *ssid;
+- gboolean res;
+-
+- gboolean can_activate_sessions;
+- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), FALSE);
+- g_return_val_if_fail (GDM_IS_USER (user), FALSE);
+- g_return_val_if_fail (manager->priv->is_loaded, FALSE);
+-
+- ret = FALSE;
+-
+- can_activate_sessions = gdm_user_manager_can_switch (manager);
+-
+- if (! can_activate_sessions) {
+- g_debug ("GdmUserManager: seat is unable to activate sessions");
+- goto out;
+- }
+-
+- ssid = gdm_user_get_primary_session_id (user);
+- if (ssid == NULL) {
+- goto out;
+- }
+-
+- res = activate_session_id (manager, manager->priv->seat.id, ssid);
+- if (! res) {
+- g_debug ("GdmUserManager: unable to activate session: %s", ssid);
+- goto out;
+- }
+-
+- ret = TRUE;
+- out:
+- return ret;
+-}
+-
+-static void
+-on_user_sessions_changed (GdmUser *user,
+- GdmUserManager *manager)
+-{
+- guint nsessions;
+-
+- if (! manager->priv->is_loaded) {
+- return;
+- }
+-
+- nsessions = gdm_user_get_num_sessions (user);
+-
+- g_debug ("GdmUserManager: sessions changed user=%s num=%d",
+- gdm_user_get_user_name (user),
+- nsessions);
+-
+- /* only signal on zero and one */
+- if (nsessions > 1) {
+- return;
+- }
+-
+- g_signal_emit (manager, signals [USER_IS_LOGGED_IN_CHANGED], 0, user);
+-}
+-
+-static void
+-on_user_changed (GdmUser *user,
+- GdmUserManager *manager)
+-{
+- if (manager->priv->is_loaded) {
+- g_debug ("GdmUserManager: user changed");
+- g_signal_emit (manager, signals[USER_CHANGED], 0, user);
+- }
+-}
+-
+-static void
+-on_get_seat_id_finished (DBusGProxy *proxy,
+- DBusGProxyCall *call,
+- GdmUserManager *manager)
+-{
+- GError *error;
+- char *seat_id;
+- gboolean res;
+-
+- g_assert (manager->priv->seat.get_seat_id_call == call);
+-
+- error = NULL;
+- seat_id = NULL;
+- res = dbus_g_proxy_end_call (proxy,
+- call,
+- &error,
+- DBUS_TYPE_G_OBJECT_PATH,
+- &seat_id,
+- G_TYPE_INVALID);
+- manager->priv->seat.get_seat_id_call = NULL;
+- g_object_unref (proxy);
+-
+- if (! res) {
+- if (error != NULL) {
+- g_debug ("Failed to identify the seat of the "
+- "current session: %s",
+- error->message);
+- g_error_free (error);
+- } else {
+- g_debug ("Failed to identify the seat of the "
+- "current session");
+- }
+- unload_seat (manager);
+- maybe_set_is_loaded (manager);
+- return;
+- }
+-
+- g_debug ("GdmUserManager: Found current seat: %s", seat_id);
+-
+- manager->priv->seat.id = seat_id;
+- manager->priv->seat.state++;
+-
+- load_seat_incrementally (manager);
+-}
+-
+-static void
+-get_seat_id_for_current_session (GdmUserManager *manager)
+-{
+- DBusGProxy *proxy;
+- DBusGProxyCall *call;
+-
+- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
+- CK_NAME,
+- manager->priv->seat.session_id,
+- CK_SESSION_INTERFACE);
+- if (proxy == NULL) {
+- g_warning ("Failed to connect to the ConsoleKit session object");
+- goto failed;
+- }
+-
+- call = dbus_g_proxy_begin_call (proxy,
+- "GetSeatId",
+- (DBusGProxyCallNotify)
+- on_get_seat_id_finished,
+- manager,
+- NULL,
+- G_TYPE_INVALID);
+- if (call == NULL) {
+- g_warning ("GdmUserManager: failed to make GetSeatId call");
+- goto failed;
+- }
+-
+- manager->priv->seat.get_seat_id_call = call;
+-
+- return;
+-
+-failed:
+- if (proxy != NULL) {
+- g_object_unref (proxy);
+- }
+-
+- unload_seat (manager);
+-}
+-
+-static gint
+-match_name_cmpfunc (gconstpointer a,
+- gconstpointer b)
+-{
+- return g_strcmp0 ((char *) a,
+- (char *) b);
+-}
+-
+-static gboolean
+-username_in_exclude_list (GdmUserManager *manager,
+- const char *username)
+-{
+- GSList *found;
+- gboolean ret = FALSE;
+-
+- /* always exclude the "gdm" user. */
+- if (username == NULL || (strcmp (username, GDM_USERNAME) == 0)) {
+- return TRUE;
+- }
+-
+- if (manager->priv->exclude_usernames != NULL) {
+- found = g_slist_find_custom (manager->priv->exclude_usernames,
+- username,
+- match_name_cmpfunc);
+- if (found != NULL) {
+- ret = TRUE;
+- }
+- }
+-
+- return ret;
+-}
+-
+-static void
+-add_session_for_user (GdmUserManager *manager,
+- GdmUser *user,
+- const char *ssid)
+-{
+- g_hash_table_insert (manager->priv->sessions,
+- g_strdup (ssid),
+- g_strdup (gdm_user_get_user_name (user)));
+-
+- _gdm_user_add_session (user, ssid);
+- g_debug ("GdmUserManager: added session for user: %s", gdm_user_get_user_name (user));
+-}
+-
+-static void
+-set_has_multiple_users (GdmUserManager *manager,
+- gboolean has_multiple_users)
+-{
+- if (manager->priv->has_multiple_users != has_multiple_users) {
+- manager->priv->has_multiple_users = has_multiple_users;
+- g_object_notify (G_OBJECT (manager), "has-multiple-users");
+- }
+-}
+-
+-static GdmUser *
+-create_new_user (GdmUserManager *manager)
+-{
+- GdmUser *user;
+-
+- user = g_object_new (GDM_TYPE_USER, NULL);
+-
+- manager->priv->new_users = g_slist_prepend (manager->priv->new_users, user);
+-
+- g_signal_connect (user, "notify::is-loaded", G_CALLBACK (on_new_user_loaded), manager);
+-
+- return g_object_ref (user);
+-}
+-
+-static void
+-add_user (GdmUserManager *manager,
+- GdmUser *user)
+-{
+- const char *object_path;
+-
+- g_hash_table_insert (manager->priv->users_by_name,
+- g_strdup (gdm_user_get_user_name (user)),
+- g_object_ref (user));
+-
+- object_path = gdm_user_get_object_path (user);
+- if (object_path != NULL) {
+- g_hash_table_insert (manager->priv->users_by_object_path,
+- (gpointer) object_path,
+- g_object_ref (user));
+- }
+-
+- g_signal_connect (user,
+- "sessions-changed",
+- G_CALLBACK (on_user_sessions_changed),
+- manager);
+- g_signal_connect (user,
+- "changed",
+- G_CALLBACK (on_user_changed),
+- manager);
+-
+- if (manager->priv->is_loaded) {
+- g_signal_emit (manager, signals[USER_ADDED], 0, user);
+- }
+-
+- if (g_hash_table_size (manager->priv->users_by_name) > 1) {
+- set_has_multiple_users (manager, TRUE);
+- }
+-}
+-
+-static void
+-remove_user (GdmUserManager *manager,
+- GdmUser *user)
+-{
+- g_object_ref (user);
+-
+- g_signal_handlers_disconnect_by_func (user, on_user_changed, manager);
+- g_signal_handlers_disconnect_by_func (user, on_user_sessions_changed, manager);
+- if (gdm_user_get_object_path (user) != NULL) {
+- g_hash_table_remove (manager->priv->users_by_object_path, gdm_user_get_object_path (user));
+- }
+- g_hash_table_remove (manager->priv->users_by_name, gdm_user_get_user_name (user));
+-
+- if (manager->priv->is_loaded) {
+- g_signal_emit (manager, signals[USER_REMOVED], 0, user);
+- }
+-
+- g_object_unref (user);
+-
+- if (g_hash_table_size (manager->priv->users_by_name) > 1) {
+- set_has_multiple_users (manager, FALSE);
+- }
+-}
+-
+-static void
+-on_new_user_loaded (GdmUser *user,
+- GParamSpec *pspec,
+- GdmUserManager *manager)
+-{
+- const char *username;
+- GdmUser *old_user;
+-
+- if (!gdm_user_is_loaded (user)) {
+- return;
+- }
+-
+- g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
+- manager->priv->new_users = g_slist_remove (manager->priv->new_users,
+- user);
+-
+- username = gdm_user_get_user_name (user);
+-
+- if (username == NULL) {
+- const char *object_path;
+-
+- object_path = gdm_user_get_object_path (user);
+-
+- if (object_path != NULL) {
+- g_warning ("GdmUserManager: user has no username "
+- "(object path: %s, uid: %lu)",
+- object_path, gdm_user_get_uid (user));
+- } else {
+- g_warning ("GdmUserManager: user has no username (uid: %lu)",
+- gdm_user_get_uid (user));
+- }
+- g_object_unref (user);
+- return;
+- }
+-
+- if (username_in_exclude_list (manager, username)) {
+- g_debug ("GdmUserManager: excluding user '%s'", username);
+- g_object_unref (user);
+- return;
+- }
+-
+- old_user = g_hash_table_lookup (manager->priv->users_by_name, username);
+-
+- /* If username got added earlier by a different means, trump it now.
+- */
+- if (old_user != NULL) {
+- remove_user (manager, old_user);
+- }
+-
+- add_user (manager, user);
+- g_object_unref (user);
+-
+- if (manager->priv->new_users == NULL) {
+- set_is_loaded (manager, TRUE);
+- }
+-}
+-
+-static GdmUser *
+-add_new_user_for_object_path (const char *object_path,
+- GdmUserManager *manager)
+-{
+- GdmUser *user;
+-
+- user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path);
+-
+- if (user != NULL) {
+- return user;
+- }
+- user = create_new_user (manager);
+- _gdm_user_update_from_object_path (user, object_path);
+-
+- return user;
+-}
+-
+-static void
+-on_new_user_in_accounts_service (DBusGProxy *proxy,
+- const char *object_path,
+- gpointer user_data)
+-{
+- GdmUserManager *manager = GDM_USER_MANAGER (user_data);
+-
+- add_new_user_for_object_path (object_path, manager);
+-}
+-
+-static void
+-on_user_removed_in_accounts_service (DBusGProxy *proxy,
+- const char *object_path,
+- gpointer user_data)
+-{
+- GdmUserManager *manager = GDM_USER_MANAGER (user_data);
+- GdmUser *user;
+-
+- user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path);
+-
+- manager->priv->new_users = g_slist_remove (manager->priv->new_users, user);
+-
+- remove_user (manager, user);
+-}
+-
+-static void
+-on_get_current_session_finished (DBusGProxy *proxy,
+- DBusGProxyCall *call,
+- GdmUserManager *manager)
+-{
+- GError *error;
+- char *session_id;
+- gboolean res;
+-
+- g_assert (manager->priv->seat.get_current_session_call == call);
+- g_assert (manager->priv->seat.state == GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID);
+-
+- error = NULL;
+- session_id = NULL;
+- res = dbus_g_proxy_end_call (proxy,
+- call,
+- &error,
+- DBUS_TYPE_G_OBJECT_PATH,
+- &session_id,
+- G_TYPE_INVALID);
+- manager->priv->seat.get_current_session_call = NULL;
+- g_object_unref (proxy);
+-
+- if (! res) {
+- if (error != NULL) {
+- g_debug ("Failed to identify the current session: %s",
+- error->message);
+- g_error_free (error);
+- } else {
+- g_debug ("Failed to identify the current session");
+- }
+- unload_seat (manager);
+- maybe_set_is_loaded (manager);
+- return;
+- }
+-
+- manager->priv->seat.session_id = session_id;
+- manager->priv->seat.state++;
+-
+- load_seat_incrementally (manager);
+-}
+-
+-static void
+-get_current_session_id (GdmUserManager *manager)
+-{
+- DBusGProxy *proxy;
+- DBusGProxyCall *call;
+-
+- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
+- CK_NAME,
+- CK_MANAGER_PATH,
+- CK_MANAGER_INTERFACE);
+- if (proxy == NULL) {
+- g_warning ("Failed to connect to the ConsoleKit manager object");
+- goto failed;
+- }
+-
+- call = dbus_g_proxy_begin_call (proxy,
+- "GetCurrentSession",
+- (DBusGProxyCallNotify)
+- on_get_current_session_finished,
+- manager,
+- NULL,
+- G_TYPE_INVALID);
+- if (call == NULL) {
+- g_warning ("GdmUserManager: failed to make GetCurrentSession call");
+- goto failed;
+- }
+-
+- manager->priv->seat.get_current_session_call = call;
+-
+- return;
+-
+-failed:
+- if (proxy != NULL) {
+- g_object_unref (proxy);
+- }
+-
+- unload_seat (manager);
+-}
+-
+-static void
+-unload_new_session (GdmUserManagerNewSession *new_session)
+-{
+- GdmUserManager *manager;
+-
+- manager = new_session->manager;
+-
+- manager->priv->new_sessions = g_slist_remove (manager->priv->new_sessions,
+- new_session);
+-
+- if (new_session->proxy != NULL) {
+- g_object_unref (new_session->proxy);
+- }
+-
+- g_free (new_session->x11_display);
+- g_free (new_session->id);
+-
+- g_slice_free (GdmUserManagerNewSession, new_session);
+-}
+-
+-static void
+-get_proxy_for_new_session (GdmUserManagerNewSession *new_session)
+-{
+- GdmUserManager *manager;
+- DBusGProxy *proxy;
+-
+- manager = new_session->manager;
+-
+- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
+- CK_NAME,
+- new_session->id,
+- CK_SESSION_INTERFACE);
+- if (proxy == NULL) {
+- g_warning ("Failed to connect to the ConsoleKit '%s' object",
+- new_session->id);
+- unload_new_session (new_session);
+- return;
+- }
+-
+- new_session->proxy = proxy;
+- new_session->state++;
+-
+- load_new_session_incrementally (new_session);
+-}
+-
+-static void
+-on_get_unix_user_finished (DBusGProxy *proxy,
+- DBusGProxyCall *call,
+- GdmUserManagerNewSession *new_session)
+-{
+- GdmUserManager *manager;
+- GError *error;
+- guint uid;
+- gboolean res;
+-
+- manager = new_session->manager;
+-
+- g_assert (new_session->get_unix_user_call == call);
+-
+- error = NULL;
+-
+- uid = (guint) -1;
+- res = dbus_g_proxy_end_call (proxy,
+- call,
+- &error,
+- G_TYPE_UINT, &uid,
+- G_TYPE_INVALID);
+- new_session->get_unix_user_call = NULL;
+-
+- if (! res) {
+- if (error != NULL) {
+- g_debug ("Failed to get uid of session '%s': %s",
+- new_session->id, error->message);
+- g_error_free (error);
+- } else {
+- g_debug ("Failed to get uid of session '%s'",
+- new_session->id);
+- }
+- unload_new_session (new_session);
+- return;
+- }
+-
+- g_debug ("GdmUserManager: Found uid of session '%s': %u",
+- new_session->id, uid);
+-
+- new_session->uid = (uid_t) uid;
+- new_session->state++;
+-
+- load_new_session_incrementally (new_session);
+-}
+-
+-static void
+-get_uid_for_new_session (GdmUserManagerNewSession *new_session)
+-{
+- DBusGProxyCall *call;
+-
+- g_assert (new_session->proxy != NULL);
+-
+- call = dbus_g_proxy_begin_call (new_session->proxy,
+- "GetUnixUser",
+- (DBusGProxyCallNotify)
+- on_get_unix_user_finished,
+- new_session,
+- NULL,
+- G_TYPE_INVALID);
+- if (call == NULL) {
+- g_warning ("GdmUserManager: failed to make GetUnixUser call");
+- goto failed;
+- }
+-
+- new_session->get_unix_user_call = call;
+- return;
+-
+-failed:
+- unload_new_session (new_session);
+-}
+-
+-static void
+-on_find_user_by_name_finished (DBusGProxy *proxy,
+- DBusGProxyCall *call,
+- GdmUserManagerFetchUserRequest *request)
+-{
+- GdmUserManager *manager;
+- GError *error;
+- char *object_path;
+- gboolean res;
+-
+- g_assert (request->call == call);
+-
+- error = NULL;
+- object_path = NULL;
+- manager = request->manager;
+- res = dbus_g_proxy_end_call (manager->priv->accounts_proxy,
+- call,
+- &error,
+- DBUS_TYPE_G_OBJECT_PATH,
+- &object_path,
+- G_TYPE_INVALID);
+- if (! res) {
+- if (error != NULL) {
+- g_debug ("GdmUserManager: Failed to find user %s: %s",
+- request->username, error->message);
+- g_error_free (error);
+- } else {
+- g_debug ("GdmUserManager: Failed to find user %s",
+- request->username);
+- }
+- give_up_and_fetch_user_locally (manager, request);
+- return;
+- }
+-
+- g_debug ("GdmUserManager: Found object path of user '%s': %s",
+- request->username, object_path);
+- request->object_path = object_path;
+- request->state++;
+-
+- fetch_user_incrementally (request);
+-}
+-
+-static void
+-find_user_in_accounts_service (GdmUserManager *manager,
+- GdmUserManagerFetchUserRequest *request)
+-{
+- DBusGProxyCall *call;
+-
+- g_debug ("GdmUserManager: Looking for user %s in accounts service",
+- request->username);
+-
+- g_assert (manager->priv->accounts_proxy != NULL);
+-
+- call = dbus_g_proxy_begin_call (manager->priv->accounts_proxy,
+- "FindUserByName",
+- (DBusGProxyCallNotify)
+- on_find_user_by_name_finished,
+- request,
+- NULL,
+- G_TYPE_STRING,
+- request->username,
+- G_TYPE_INVALID);
+-
+- if (call == NULL) {
+- g_warning ("GdmUserManager: failed to make FindUserByName('%s') call",
+- request->username);
+- goto failed;
+- }
+-
+- request->call = call;
+- return;
+-
+-failed:
+- give_up_and_fetch_user_locally (manager, request);
+-}
+-
+-static void
+-set_is_loaded (GdmUserManager *manager,
+- gboolean is_loaded)
+-{
+- if (manager->priv->is_loaded != is_loaded) {
+- manager->priv->is_loaded = is_loaded;
+- g_object_notify (G_OBJECT (manager), "is-loaded");
+- }
+-}
+-
+-static void
+-on_list_cached_users_finished (DBusGProxy *proxy,
+- DBusGProxyCall *call_id,
+- gpointer data)
+-{
+- GdmUserManager *manager = data;
+- GError *error = NULL;
+- GPtrArray *paths;
+-
+- manager->priv->listing_cached_users = FALSE;
+- if (!dbus_g_proxy_end_call (proxy,
+- call_id,
+- &error,
+- dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &paths,
+- G_TYPE_INVALID)) {
+- g_debug ("GdmUserManager: ListCachedUsers failed: %s", error->message);
+- g_error_free (error);
+-
+- g_object_unref (manager->priv->accounts_proxy);
+- manager->priv->accounts_proxy = NULL;
+-
+- load_users_manually (manager);
+-
+- return;
+- }
+-
+- maybe_set_is_loaded (manager);
+-
+- g_ptr_array_foreach (paths, (GFunc)add_new_user_for_object_path, manager);
+-
+- g_ptr_array_foreach (paths, (GFunc)g_free, NULL);
+- g_ptr_array_free (paths, TRUE);
+-
+- /* Add users who are specifically included */
+- if (manager->priv->include_usernames != NULL) {
+- GSList *l;
+-
+- for (l = manager->priv->include_usernames; l != NULL; l = l->next) {
+- GdmUser *user;
+-
+- g_debug ("GdmUserManager: Adding included user %s", (char *)l->data);
+- /*
+- * The call to gdm_user_manager_get_user will add the user if it is
+- * valid and not already in the hash.
+- */
+- user = gdm_user_manager_get_user (manager, l->data);
+- if (user == NULL) {
+- g_debug ("GdmUserManager: unable to lookup user '%s'", (char *)l->data);
+- }
+- }
+- }
+-}
+-
+-static void
+-on_get_x11_display_finished (DBusGProxy *proxy,
+- DBusGProxyCall *call,
+- GdmUserManagerNewSession *new_session)
+-{
+- GError *error;
+- char *x11_display;
+- gboolean res;
+-
+- g_assert (new_session->get_x11_display_call == call);
+-
+- error = NULL;
+- x11_display = NULL;
+- res = dbus_g_proxy_end_call (proxy,
+- call,
+- &error,
+- G_TYPE_STRING,
+- &x11_display,
+- G_TYPE_INVALID);
+- new_session->get_x11_display_call = NULL;
+-
+- if (! res) {
+- if (error != NULL) {
+- g_debug ("Failed to get the x11 display of session '%s': %s",
+- new_session->id, error->message);
+- g_error_free (error);
+- } else {
+- g_debug ("Failed to get the x11 display of session '%s'",
+- new_session->id);
+- }
+- unload_new_session (new_session);
+- return;
+- }
+-
+- g_debug ("GdmUserManager: Found x11 display of session '%s': %s",
+- new_session->id, x11_display);
+-
+- new_session->x11_display = x11_display;
+- new_session->state++;
+-
+- load_new_session_incrementally (new_session);
+-}
+-
+-static void
+-get_x11_display_for_new_session (GdmUserManagerNewSession *new_session)
+-{
+- DBusGProxyCall *call;
+-
+- g_assert (new_session->proxy != NULL);
+-
+- call = dbus_g_proxy_begin_call (new_session->proxy,
+- "GetX11Display",
+- (DBusGProxyCallNotify)
+- on_get_x11_display_finished,
+- new_session,
+- NULL,
+- G_TYPE_INVALID);
+- if (call == NULL) {
+- g_warning ("GdmUserManager: failed to make GetX11Display call");
+- goto failed;
+- }
+-
+- new_session->get_x11_display_call = call;
+- return;
+-
+-failed:
+- unload_new_session (new_session);
+-}
+-
+-static gboolean
+-get_pwent_for_name (const char *name,
+- struct passwd **pwentp)
+-{
+- struct passwd *pwent;
+-
+- do {
+- errno = 0;
+- pwent = getpwnam (name);
+- } while (pwent == NULL && errno == EINTR);
+-
+- if (pwentp != NULL) {
+- *pwentp = pwent;
+- }
+-
+- return (pwent != NULL);
+-}
+-
+-static gboolean
+-get_pwent_for_uid (uid_t uid,
+- struct passwd **pwentp)
+-{
+- struct passwd *pwent;
+-
+- do {
+- errno = 0;
+- pwent = getpwuid (uid);
+- } while (pwent == NULL && errno == EINTR);
+-
+- if (pwentp != NULL) {
+- *pwentp = pwent;
+- }
+-
+- return (pwent != NULL);
+-}
+-
+-static void
+-maybe_add_new_session (GdmUserManagerNewSession *new_session)
+-{
+- GdmUserManager *manager;
+- struct passwd *pwent;
+- GdmUser *user;
+-
+- manager = GDM_USER_MANAGER (new_session->manager);
+-
+- errno = 0;
+- get_pwent_for_uid (new_session->uid, &pwent);
+- if (pwent == NULL) {
+- g_warning ("Unable to lookup user ID %d: %s",
+- (int) new_session->uid, g_strerror (errno));
+- goto failed;
+- }
+-
+- /* check exclusions up front */
+- if (username_in_exclude_list (manager, pwent->pw_name)) {
+- g_debug ("GdmUserManager: excluding user '%s'", pwent->pw_name);
+- goto failed;
+- }
+-
+- user = gdm_user_manager_get_user (manager, pwent->pw_name);
+- if (user == NULL) {
+- return;
+- }
+-
+- add_session_for_user (manager, user, new_session->id);
+-
+- /* if we haven't yet gotten the login frequency
+- then at least add one because the session exists */
+- if (gdm_user_get_login_frequency (user) == 0) {
+- _gdm_user_update_login_frequency (user, 1);
+- }
+-
+- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_LOADED;
+- unload_new_session (new_session);
+- return;
+-
+-failed:
+- unload_new_session (new_session);
+-}
+-
+-static void
+-load_new_session (GdmUserManager *manager,
+- const char *session_id)
+-{
+- GdmUserManagerNewSession *new_session;
+-
+- new_session = g_slice_new0 (GdmUserManagerNewSession);
+-
+- new_session->manager = manager;
+- new_session->id = g_strdup (session_id);
+- new_session->state = GDM_USER_MANAGER_NEW_SESSION_STATE_UNLOADED + 1;
+-
+- manager->priv->new_sessions = g_slist_prepend (manager->priv->new_sessions,
+- new_session);
+- load_new_session_incrementally (new_session);
+-}
+-
+-static void
+-seat_session_added (DBusGProxy *seat_proxy,
+- const char *session_id,
+- GdmUserManager *manager)
+-{
+- g_debug ("GdmUserManager: Session added: %s", session_id);
+-
+- load_new_session (manager, session_id);
+-}
+-
+-static gint
+-match_new_session_cmpfunc (gconstpointer a,
+- gconstpointer b)
+-{
+- GdmUserManagerNewSession *new_session;
+- const char *session_id;
+-
+- new_session = (GdmUserManagerNewSession *) a;
+- session_id = (const char *) b;
+-
+- return strcmp (new_session->id, session_id);
+-}
+-
+-static void
+-seat_session_removed (DBusGProxy *seat_proxy,
+- const char *session_id,
+- GdmUserManager *manager)
+-{
+- GdmUser *user;
+- GSList *found;
+- char *username;
+-
+- g_debug ("GdmUserManager: Session removed: %s", session_id);
+-
+- found = g_slist_find_custom (manager->priv->new_sessions,
+- session_id,
+- match_new_session_cmpfunc);
+-
+- if (found != NULL) {
+- GdmUserManagerNewSession *new_session;
+-
+- new_session = (GdmUserManagerNewSession *) found->data;
+-
+- if (new_session->state > GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY) {
+- g_debug ("GdmUserManager: New session for uid %d on "
+- "x11 display %s removed before fully loading",
+- (int) new_session->uid, new_session->x11_display);
+- } else if (new_session->state > GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID) {
+- g_debug ("GdmUserManager: New session for uid %d "
+- "removed before fully loading",
+- (int) new_session->uid);
+- } else {
+- g_debug ("GdmUserManager: New session removed "
+- "before fully loading");
+- }
+- unload_new_session (new_session);
+- return;
+- }
+-
+- /* since the session object may already be gone
+- * we can't query CK directly */
+-
+- username = g_hash_table_lookup (manager->priv->sessions, session_id);
+- if (username == NULL) {
+- return;
+- }
+-
+- user = g_hash_table_lookup (manager->priv->users_by_name, username);
+- if (user == NULL) {
+- /* nothing to do */
+- return;
+- }
+-
+- g_debug ("GdmUserManager: Session removed for %s", username);
+- _gdm_user_remove_session (user, session_id);
+-}
+-
+-static void
+-on_seat_proxy_destroy (DBusGProxy *proxy,
+- GdmUserManager *manager)
+-{
+- g_debug ("GdmUserManager: seat proxy destroyed");
+-
+- manager->priv->seat.proxy = NULL;
+-}
+-
+-static void
+-get_seat_proxy (GdmUserManager *manager)
+-{
+- DBusGProxy *proxy;
+- GError *error;
+-
+- g_assert (manager->priv->seat.proxy == NULL);
+-
+- error = NULL;
+- proxy = dbus_g_proxy_new_for_name_owner (manager->priv->connection,
+- CK_NAME,
+- manager->priv->seat.id,
+- CK_SEAT_INTERFACE,
+- &error);
+-
+- if (proxy == NULL) {
+- if (error != NULL) {
+- g_warning ("Failed to connect to the ConsoleKit seat object: %s",
+- error->message);
+- g_error_free (error);
+- } else {
+- g_warning ("Failed to connect to the ConsoleKit seat object");
+- }
+- unload_seat (manager);
+- return;
+- }
+-
+- g_signal_connect (proxy, "destroy", G_CALLBACK (on_seat_proxy_destroy), manager);
+-
+- dbus_g_proxy_add_signal (proxy,
+- "SessionAdded",
+- DBUS_TYPE_G_OBJECT_PATH,
+- G_TYPE_INVALID);
+- dbus_g_proxy_add_signal (proxy,
+- "SessionRemoved",
+- DBUS_TYPE_G_OBJECT_PATH,
+- G_TYPE_INVALID);
+- dbus_g_proxy_connect_signal (proxy,
+- "SessionAdded",
+- G_CALLBACK (seat_session_added),
+- manager,
+- NULL);
+- dbus_g_proxy_connect_signal (proxy,
+- "SessionRemoved",
+- G_CALLBACK (seat_session_removed),
+- manager,
+- NULL);
+- manager->priv->seat.proxy = proxy;
+- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_LOADED;
+-}
+-
+-static void
+-unload_seat (GdmUserManager *manager)
+-{
+- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED;
+-
+- if (manager->priv->seat.proxy != NULL) {
+- g_object_unref (manager->priv->seat.proxy);
+- manager->priv->seat.proxy = NULL;
+- }
+-
+- g_free (manager->priv->seat.id);
+- manager->priv->seat.id = NULL;
+-
+- g_free (manager->priv->seat.session_id);
+- manager->priv->seat.session_id = NULL;
+-}
+-
+-static void
+-get_accounts_proxy (GdmUserManager *manager)
+-{
+- DBusGProxy *proxy;
+- GError *error;
+-
+- g_assert (manager->priv->accounts_proxy == NULL);
+-
+- error = NULL;
+- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
+- ACCOUNTS_NAME,
+- ACCOUNTS_PATH,
+- ACCOUNTS_INTERFACE);
+- manager->priv->accounts_proxy = proxy;
+-
+- dbus_g_proxy_add_signal (proxy,
+- "UserAdded",
+- DBUS_TYPE_G_OBJECT_PATH,
+- G_TYPE_INVALID);
+- dbus_g_proxy_add_signal (proxy,
+- "UserDeleted",
+- DBUS_TYPE_G_OBJECT_PATH,
+- G_TYPE_INVALID);
+-
+- dbus_g_proxy_connect_signal (proxy,
+- "UserAdded",
+- G_CALLBACK (on_new_user_in_accounts_service),
+- manager,
+- NULL);
+- dbus_g_proxy_connect_signal (proxy,
+- "UserDeleted",
+- G_CALLBACK (on_user_removed_in_accounts_service),
+- manager,
+- NULL);
+-}
+-
+-static void
+-load_new_session_incrementally (GdmUserManagerNewSession *new_session)
+-{
+- switch (new_session->state) {
+- case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_PROXY:
+- get_proxy_for_new_session (new_session);
+- break;
+- case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID:
+- get_uid_for_new_session (new_session);
+- break;
+- case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY:
+- get_x11_display_for_new_session (new_session);
+- break;
+- case GDM_USER_MANAGER_NEW_SESSION_STATE_MAYBE_ADD:
+- maybe_add_new_session (new_session);
+- break;
+- case GDM_USER_MANAGER_NEW_SESSION_STATE_LOADED:
+- break;
+- default:
+- g_assert_not_reached ();
+- }
+-}
+-
+-static void
+-free_fetch_user_request (GdmUserManagerFetchUserRequest *request)
+-{
+- GdmUserManager *manager;
+-
+- manager = request->manager;
+-
+- manager->priv->fetch_user_requests = g_slist_remove (manager->priv->fetch_user_requests, request);
+- g_free (request->username);
+- g_free (request->object_path);
+- g_slice_free (GdmUserManagerFetchUserRequest, request);
+-}
+-
+-static void
+-give_up_and_fetch_user_locally (GdmUserManager *manager,
+- GdmUserManagerFetchUserRequest *request)
+-{
+-
+- g_debug ("GdmUserManager: account service unavailable, "
+- "fetching user %s locally",
+- request->username);
+- fetch_user_locally (manager, request->user, request->username);
+- request->state = GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED;
+-}
+-
+-static void
+-on_user_manager_maybe_ready_for_request (GdmUserManager *manager,
+- GParamSpec *pspec,
+- GdmUserManagerFetchUserRequest *request)
+-{
+- if (!manager->priv->is_loaded) {
+- return;
+- }
+-
+- g_signal_handlers_disconnect_by_func (manager, on_user_manager_maybe_ready_for_request, request);
+-
+- request->state++;
+- fetch_user_incrementally (request);
+-}
+-
+-static void
+-fetch_user_incrementally (GdmUserManagerFetchUserRequest *request)
+-{
+- GdmUserManager *manager;
+-
+- g_debug ("GdmUserManager: finding user %s state %d",
+- request->username, request->state);
+- manager = request->manager;
+- switch (request->state) {
+- case GDM_USER_MANAGER_GET_USER_STATE_WAIT_FOR_LOADED:
+- if (manager->priv->is_loaded) {
+- request->state++;
+- fetch_user_incrementally (request);
+- } else {
+- g_debug ("GdmUserManager: waiting for user manager to load before finding user %s",
+- request->username);
+- g_signal_connect (manager, "notify::is-loaded",
+- G_CALLBACK (on_user_manager_maybe_ready_for_request), request);
+-
+- }
+- break;
+-
+- case GDM_USER_MANAGER_GET_USER_STATE_ASK_ACCOUNTS_SERVICE:
+- if (manager->priv->accounts_proxy == NULL) {
+- give_up_and_fetch_user_locally (manager, request);
+- } else {
+- find_user_in_accounts_service (manager, request);
+- }
+- break;
+- case GDM_USER_MANAGER_GET_USER_STATE_FETCHED:
+- g_debug ("GdmUserManager: user %s fetched", request->username);
+- _gdm_user_update_from_object_path (request->user, request->object_path);
+- break;
+- case GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED:
+- g_debug ("GdmUserManager: user %s was not fetched", request->username);
+- break;
+- default:
+- g_assert_not_reached ();
+- }
+-
+- if (request->state == GDM_USER_MANAGER_GET_USER_STATE_FETCHED ||
+- request->state == GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED) {
+- g_debug ("GdmUserManager: finished handling request for user %s",
+- request->username);
+- free_fetch_user_request (request);
+- }
+-}
+-
+-static void
+-fetch_user_from_accounts_service (GdmUserManager *manager,
+- GdmUser *user,
+- const char *username)
+-{
+- GdmUserManagerFetchUserRequest *request;
+-
+- request = g_slice_new0 (GdmUserManagerFetchUserRequest);
+-
+- request->manager = manager;
+- request->username = g_strdup (username);
+- request->user = user;
+- request->state = GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED + 1;
+-
+- manager->priv->fetch_user_requests = g_slist_prepend (manager->priv->fetch_user_requests,
+- request);
+- fetch_user_incrementally (request);
+-}
+-
+-static void
+-fetch_user_locally (GdmUserManager *manager,
+- GdmUser *user,
+- const char *username)
+-{
+- struct passwd *pwent;
+-
+- get_pwent_for_name (username, &pwent);
+-
+- if (pwent != NULL) {
+- _gdm_user_update_from_pwent (user, pwent);
+- }
+-}
+-
+-/**
+- * gdm_user_manager_get_user:
+- * @manager: the manager to query.
+- * @username: the login name of the user to get.
+- *
+- * Retrieves a pointer to the #GdmUser object for the login @username
+- * from @manager. Trying to use this object before its
+- * #GdmUser:is-loaded property is %TRUE will result in undefined
+- * behavior.
+- *
+- * Returns: (transfer none): #GdmUser object
+- **/
+-GdmUser *
+-gdm_user_manager_get_user (GdmUserManager *manager,
+- const char *username)
+-{
+- GdmUser *user;
+-
+- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL);
+- g_return_val_if_fail (username != NULL && username[0] != '\0', NULL);
+-
+- user = g_hash_table_lookup (manager->priv->users_by_name, username);
+-
+- /* if we don't have it loaded try to load it now */
+- if (user == NULL) {
+- user = create_new_user (manager);
+-
+- if (manager->priv->accounts_proxy != NULL) {
+- fetch_user_from_accounts_service (manager, user, username);
+- } else {
+- fetch_user_locally (manager, user, username);
+- }
+- }
+-
+- return user;
+-}
+-
+-/**
+- * gdm_user_manager_get_user_by_uid:
+- * @manager: the manager to query.
+- * @uid: the uid of the user to get.
+- *
+- * Retrieves a pointer to the #GdmUser object for the uid @uid
+- * from @manager. Trying to use this object before its
+- * #GdmUser:is-loaded property is %TRUE will result in undefined
+- * behavior.
+- *
+- * Returns: (transfer none): #GdmUser object
+- */
+-GdmUser *
+-gdm_user_manager_get_user_by_uid (GdmUserManager *manager,
+- gulong uid)
+-{
+- struct passwd *pwent;
+-
+- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL);
+-
+- get_pwent_for_uid (uid, &pwent);
+- if (pwent == NULL) {
+- g_warning ("GdmUserManager: unable to lookup uid %d", (int)uid);
+- return NULL;
+- }
+-
+- return gdm_user_manager_get_user (manager, pwent->pw_name);
+-}
+-
+-static void
+-listify_hash_values_hfunc (gpointer key,
+- gpointer value,
+- gpointer user_data)
+-{
+- GSList **list = user_data;
+-
+- *list = g_slist_prepend (*list, value);
+-}
+-
+-/**
+- * gdm_user_manager_list_users:
+- * @manager: a #GdmUserManager
+- *
+- * Get a list of system user accounts
+- *
+- * Returns: (element-type GdmUser) (transfer full): List of #GdmUser objects
+- */
+-GSList *
+-gdm_user_manager_list_users (GdmUserManager *manager)
+-{
+- GSList *retval;
+-
+- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL);
+-
+- retval = NULL;
+- g_hash_table_foreach (manager->priv->users_by_name, listify_hash_values_hfunc, &retval);
+-
+- return g_slist_sort (retval, (GCompareFunc) gdm_user_collate);
+-}
+-
+-static gboolean
+-parse_value_as_ulong (const char *value,
+- gulong *ulongval)
+-{
+- char *end_of_valid_long;
+- glong long_value;
+- gulong ulong_value;
+-
+- errno = 0;
+- long_value = strtol (value, &end_of_valid_long, 10);
+-
+- if (*value == '\0' || *end_of_valid_long != '\0') {
+- return FALSE;
+- }
+-
+- ulong_value = long_value;
+- if (ulong_value != long_value || errno == ERANGE) {
+- return FALSE;
+- }
+-
+- *ulongval = ulong_value;
+-
+- return TRUE;
+-}
+-
+-static gboolean
+-parse_ck_history_line (const char *line,
+- char **user_namep,
+- gulong *frequencyp)
+-{
+- GRegex *re;
+- GMatchInfo *match_info;
+- gboolean res;
+- gboolean ret;
+- GError *error;
+-
+- ret = FALSE;
+- re = NULL;
+- match_info = NULL;
+-
+- error = NULL;
+- re = g_regex_new ("(?P<username>[0-9a-zA-Z]+)[ ]+(?P<frequency>[0-9]+)", 0, 0, &error);
+- if (re == NULL) {
+- if (error != NULL) {
+- g_critical ("%s", error->message);
+- } else {
+- g_critical ("Error in regex call");
+- }
+- goto out;
+- }
+-
+- g_regex_match (re, line, 0, &match_info);
+-
+- res = g_match_info_matches (match_info);
+- if (! res) {
+- g_warning ("Unable to parse history: %s", line);
+- goto out;
+- }
+-
+- if (user_namep != NULL) {
+- *user_namep = g_match_info_fetch_named (match_info, "username");
+- }
+-
+- if (frequencyp != NULL) {
+- char *freq;
+- freq = g_match_info_fetch_named (match_info, "frequency");
+- res = parse_value_as_ulong (freq, frequencyp);
+- g_free (freq);
+- if (! res) {
+- goto out;
+- }
+- }
+-
+- ret = TRUE;
+-
+- out:
+- if (match_info != NULL) {
+- g_match_info_free (match_info);
+- }
+- if (re != NULL) {
+- g_regex_unref (re);
+- }
+- return ret;
+-}
+-
+-static void
+-process_ck_history_line (GdmUserManager *manager,
+- const char *line)
+-{
+- gboolean res;
+- char *username;
+- gulong frequency;
+- GdmUser *user;
+-
+- frequency = 0;
+- username = NULL;
+- res = parse_ck_history_line (line, &username, &frequency);
+- if (! res) {
+- return;
+- }
+-
+- if (username_in_exclude_list (manager, username)) {
+- g_debug ("GdmUserManager: excluding user '%s'", username);
+- g_free (username);
+- return;
+- }
+-
+- user = gdm_user_manager_get_user (manager, username);
+- if (user == NULL) {
+- g_debug ("GdmUserManager: unable to lookup user '%s'", username);
+- g_free (username);
+- return;
+- }
+-
+- _gdm_user_update_login_frequency (user, frequency);
+- g_free (username);
+-}
+-
+-static void
+-maybe_set_is_loaded (GdmUserManager *manager)
+-{
+- if (manager->priv->is_loaded) {
+- return;
+- }
+-
+- if (manager->priv->ck_history_pid != 0) {
+- return;
+- }
+-
+- if (manager->priv->load_passwd_pending) {
+- return;
+- }
+-
+- if (manager->priv->get_sessions_call != NULL) {
+- return;
+- }
+-
+- if (manager->priv->listing_cached_users) {
+- return;
+- }
+-
+- /* Don't set is_loaded yet unless the seat is already loaded
+- * or failed to load.
+- */
+- if (manager->priv->seat.state != GDM_USER_MANAGER_SEAT_STATE_LOADED
+- && manager->priv->seat.state != GDM_USER_MANAGER_SEAT_STATE_UNLOADED) {
+- return;
+- }
+-
+- set_is_loaded (manager, TRUE);
+-}
+-
+-static gboolean
+-ck_history_watch (GIOChannel *source,
+- GIOCondition condition,
+- GdmUserManager *manager)
+-{
+- GIOStatus status;
+- gboolean done = FALSE;
+-
+- g_return_val_if_fail (manager != NULL, FALSE);
+-
+- if (condition & G_IO_IN) {
+- char *str;
+- GError *error;
+-
+- error = NULL;
+- status = g_io_channel_read_line (source, &str, NULL, NULL, &error);
+- if (error != NULL) {
+- g_warning ("GdmUserManager: unable to read line: %s", error->message);
+- g_error_free (error);
+- }
+-
+- if (status == G_IO_STATUS_NORMAL) {
+- g_debug ("GdmUserManager: history output: %s", str);
+- process_ck_history_line (manager, str);
+- } else if (status == G_IO_STATUS_EOF) {
+- done = TRUE;
+- }
+-
+- g_free (str);
+- } else if (condition & G_IO_HUP) {
+- done = TRUE;
+- }
+-
+- if (done) {
+- manager->priv->ck_history_id = 0;
+- if (manager->priv->ck_history_watchdog_id != 0) {
+- g_source_remove (manager->priv->ck_history_watchdog_id);
+- manager->priv->ck_history_watchdog_id = 0;
+- }
+- manager->priv->ck_history_pid = 0;
+-
+- maybe_set_is_loaded (manager);
+-
+- return FALSE;
+- }
+-
+- return TRUE;
+-}
+-
+-static int
+-signal_pid (int pid,
+- int signal)
+-{
+- int status = -1;
+-
+- status = kill (pid, signal);
+-
+- if (status < 0) {
+- if (errno == ESRCH) {
+- g_debug ("Child process %lu was already dead.",
+- (unsigned long) pid);
+- } else {
+- char buf [1024];
+- snprintf (buf,
+- sizeof (buf),
+- "Couldn't kill child process %lu",
+- (unsigned long) pid);
+- perror (buf);
+- }
+- }
+-
+- return status;
+-}
+-
+-static gboolean
+-ck_history_watchdog (GdmUserManager *manager)
+-{
+- if (manager->priv->ck_history_pid > 0) {
+- g_debug ("Killing ck-history process");
+- signal_pid (manager->priv->ck_history_pid, SIGTERM);
+- manager->priv->ck_history_pid = 0;
+- }
+-
+- manager->priv->ck_history_watchdog_id = 0;
+- return FALSE;
+-}
+-
+-static gboolean
+-load_ck_history (GdmUserManager *manager)
+-{
+- char *command;
+- char *since;
+- const char *seat_id;
+- GError *error;
+- gboolean res;
+- char **argv;
+- int standard_out;
+- GIOChannel *channel;
+- GTimeVal tv;
+-
+- g_assert (manager->priv->ck_history_id == 0);
+-
+- command = NULL;
+-
+- seat_id = NULL;
+- if (manager->priv->seat.id != NULL
+- && g_str_has_prefix (manager->priv->seat.id, "/org/freedesktop/ConsoleKit/")) {
+-
+- seat_id = manager->priv->seat.id + strlen ("/org/freedesktop/ConsoleKit/");
+- }
+-
+- if (seat_id == NULL) {
+- g_warning ("Unable to load CK history: no seat-id found");
+- goto out;
+- }
+-
+- g_get_current_time (&tv);
+- tv.tv_sec -= LOGIN_FREQUENCY_TIME_WINDOW_SECS;
+- since = g_time_val_to_iso8601 (&tv);
+-
+- command = g_strdup_printf ("ck-history --frequent --since='%s' --seat='%s' --session-type=''",
+- since,
+- seat_id);
+- g_free (since);
+- g_debug ("GdmUserManager: running '%s'", command);
+- error = NULL;
+- if (! g_shell_parse_argv (command, NULL, &argv, &error)) {
+- if (error != NULL) {
+- g_warning ("Could not parse command: %s", error->message);
+- g_error_free (error);
+- } else {
+- g_warning ("Could not parse command");
+- }
+- goto out;
+- }
+-
+- error = NULL;
+- res = g_spawn_async_with_pipes (NULL,
+- argv,
+- NULL,
+- G_SPAWN_SEARCH_PATH,
+- NULL,
+- NULL,
+- &manager->priv->ck_history_pid, /* pid */
+- NULL,
+- &standard_out,
+- NULL,
+- &error);
+- g_strfreev (argv);
+- if (! res) {
+- if (error != NULL) {
+- g_warning ("Unable to run ck-history: %s", error->message);
+- g_error_free (error);
+- } else {
+- g_warning ("Unable to run ck-history");
+- }
+- goto out;
+- }
+-
+- channel = g_io_channel_unix_new (standard_out);
+- g_io_channel_set_close_on_unref (channel, TRUE);
+- g_io_channel_set_flags (channel,
+- g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
+- NULL);
+- manager->priv->ck_history_watchdog_id = g_timeout_add_seconds (1, (GSourceFunc) ck_history_watchdog, manager);
+- manager->priv->ck_history_id = g_io_add_watch (channel,
+- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+- (GIOFunc)ck_history_watch,
+- manager);
+- g_io_channel_unref (channel);
+-
+- out:
+-
+- g_free (command);
+-
+- return manager->priv->ck_history_id != 0;
+-}
+-
+-static void
+-reload_passwd_file (GHashTable *valid_shells,
+- GSList *exclude_users,
+- GSList *include_users,
+- gboolean include_all,
+- GHashTable *current_users_by_name,
+- GSList **added_users,
+- GSList **removed_users)
+-{
+- FILE *fp;
+- GHashTableIter iter;
+- GHashTable *new_users_by_name;
+- GdmUser *user;
+- char *name;
+-
+- new_users_by_name = g_hash_table_new_full (g_str_hash,
+- g_str_equal,
+- NULL,
+- g_object_unref);
+-
+- errno = 0;
+- fp = fopen (PATH_PASSWD, "r");
+- if (fp == NULL) {
+- g_warning ("Unable to open %s: %s", PATH_PASSWD, g_strerror (errno));
+- goto out;
+- }
+-
+- /* Make sure we keep users who are logged in no matter what. */
+- g_hash_table_iter_init (&iter, current_users_by_name);
+- while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
+- struct passwd *pwent;
+-
+- get_pwent_for_name (name, &pwent);
+- if (pwent == NULL) {
+- continue;
+- }
+-
+- g_object_freeze_notify (G_OBJECT (user));
+- _gdm_user_update_from_pwent (user, pwent);
+- g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), g_object_ref (user));
+- }
+-
+- if (include_users != NULL) {
+- GSList *l;
+- for (l = include_users; l != NULL; l = l->next) {
+- struct passwd *pwent;
+-
+- get_pwent_for_name (l->data, &pwent);
+- if (pwent == NULL) {
+- continue;
+- }
+-
+- user = g_hash_table_lookup (new_users_by_name, pwent->pw_name);
+- if (user != NULL) {
+- /* already there */
+- continue;
+- }
+-
+- user = g_hash_table_lookup (current_users_by_name, pwent->pw_name);
+- if (user == NULL) {
+- user = g_object_new (GDM_TYPE_USER, NULL);
+- } else {
+- g_object_ref (user);
+- }
+- g_object_freeze_notify (G_OBJECT (user));
+- _gdm_user_update_from_pwent (user, pwent);
+- g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), user);
+- }
+- }
+-
+- if (include_all != TRUE) {
+- g_debug ("GdmUserManager: include_all is FALSE");
+- } else {
+- struct passwd *pwent;
+-
+- g_debug ("GdmUserManager: include_all is TRUE");
+-
+- for (pwent = fgetpwent (fp);
+- pwent != NULL;
+- pwent = fgetpwent (fp)) {
+-
+- /* Skip users below MinimalUID... */
+- if (pwent->pw_uid < FALLBACK_MINIMAL_UID) {
+- continue;
+- }
+-
+- /* ...And users w/ invalid shells... */
+- if (pwent->pw_shell == NULL
+- || !g_hash_table_lookup (valid_shells, pwent->pw_shell)) {
+- g_debug ("GdmUserManager: skipping user with bad shell: %s", pwent->pw_name);
+- continue;
+- }
+-
+- /* always exclude the "gdm" user. */
+- if (strcmp (pwent->pw_name, GDM_USERNAME) == 0) {
+- continue;
+- }
+-
+- /* ...And explicitly excluded users */
+- if (exclude_users != NULL) {
+- GSList *found;
+-
+- found = g_slist_find_custom (exclude_users,
+- pwent->pw_name,
+- match_name_cmpfunc);
+- if (found != NULL) {
+- g_debug ("GdmUserManager: explicitly skipping user: %s", pwent->pw_name);
+- continue;
+- }
+- }
+-
+- user = g_hash_table_lookup (new_users_by_name, pwent->pw_name);
+- if (user != NULL) {
+- /* already there */
+- continue;
+- }
+-
+- user = g_hash_table_lookup (current_users_by_name, pwent->pw_name);
+- if (user == NULL) {
+- user = g_object_new (GDM_TYPE_USER, NULL);
+- } else {
+- g_object_ref (user);
+- }
+-
+- /* Freeze & update users not already in the new list */
+- g_object_freeze_notify (G_OBJECT (user));
+- _gdm_user_update_from_pwent (user, pwent);
+- g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), user);
+- }
+- }
+-
+- /* Go through and handle added users */
+- g_hash_table_iter_init (&iter, new_users_by_name);
+- while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
+- GdmUser *user2;
+- user2 = g_hash_table_lookup (current_users_by_name, name);
+- if (user2 == NULL) {
+- *added_users = g_slist_prepend (*added_users, g_object_ref (user));
+- }
+- }
+-
+- /* Go through and handle removed users */
+- g_hash_table_iter_init (&iter, current_users_by_name);
+- while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
+- GdmUser *user2;
+- user2 = g_hash_table_lookup (new_users_by_name, name);
+- if (user2 == NULL) {
+- *removed_users = g_slist_prepend (*removed_users, g_object_ref (user));
+- }
+- }
+-
+- out:
+- /* Cleanup */
+-
+- fclose (fp);
+-
+- g_hash_table_iter_init (&iter, new_users_by_name);
+- while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
+- g_object_thaw_notify (G_OBJECT (user));
+- }
+-
+- g_hash_table_destroy (new_users_by_name);
+-}
+-
+-typedef struct {
+- GdmUserManager *manager;
+- GSList *exclude_users;
+- GSList *include_users;
+- gboolean include_all;
+- GHashTable *shells;
+- GHashTable *current_users_by_name;
+- GSList *added_users;
+- GSList *removed_users;
+-} PasswdData;
+-
+-static void
+-passwd_data_free (PasswdData *data)
+-{
+- if (data->manager != NULL) {
+- g_object_unref (data->manager);
+- }
+-
+- g_slist_foreach (data->added_users, (GFunc) g_object_unref, NULL);
+- g_slist_free (data->added_users);
+-
+- g_slist_foreach (data->removed_users, (GFunc) g_object_unref, NULL);
+- g_slist_free (data->removed_users);
+-
+- g_slist_foreach (data->exclude_users, (GFunc) g_free, NULL);
+- g_slist_free (data->exclude_users);
+-
+- g_slist_foreach (data->include_users, (GFunc) g_free, NULL);
+- g_slist_free (data->include_users);
+-
+- g_slice_free (PasswdData, data);
+-}
+-
+-static gboolean
+-reload_passwd_job_done (PasswdData *data)
+-{
+- GSList *l;
+-
+- g_debug ("GdmUserManager: done reloading passwd file");
+-
+- /* Go through and handle added users */
+- for (l = data->added_users; l != NULL; l = l->next) {
+- add_user (data->manager, l->data);
+- }
+-
+- /* Go through and handle removed users */
+- for (l = data->removed_users; l != NULL; l = l->next) {
+- remove_user (data->manager, l->data);
+- }
+-
+- data->manager->priv->load_passwd_pending = FALSE;
+-
+- if (! data->manager->priv->is_loaded) {
+- maybe_set_is_loaded (data->manager);
+-
+- if (data->manager->priv->include_all == TRUE) {
+- monitor_local_users (data->manager);
+- }
+- }
+-
+- passwd_data_free (data);
+-
+- return FALSE;
+-}
+-
+-static gboolean
+-do_reload_passwd_job (GIOSchedulerJob *job,
+- GCancellable *cancellable,
+- PasswdData *data)
+-{
+- g_debug ("GdmUserManager: reloading passwd file worker");
+-
+- reload_passwd_file (data->shells,
+- data->exclude_users,
+- data->include_users,
+- data->include_all,
+- data->current_users_by_name,
+- &data->added_users,
+- &data->removed_users);
+-
+- g_io_scheduler_job_send_to_mainloop_async (job,
+- (GSourceFunc) reload_passwd_job_done,
+- data,
+- NULL);
+-
+- return FALSE;
+-}
+-
+-static GSList *
+-slist_deep_copy (const GSList *list)
+-{
+- GSList *retval;
+- GSList *l;
+-
+- if (list == NULL)
+- return NULL;
+-
+- retval = g_slist_copy ((GSList *) list);
+- for (l = retval; l != NULL; l = l->next) {
+- l->data = g_strdup (l->data);
+- }
+-
+- return retval;
+-}
+-
+-static void
+-schedule_reload_passwd (GdmUserManager *manager)
+-{
+- PasswdData *passwd_data;
+-
+- manager->priv->load_passwd_pending = TRUE;
+-
+- passwd_data = g_slice_new0 (PasswdData);
+- passwd_data->manager = g_object_ref (manager);
+- passwd_data->shells = manager->priv->shells;
+- passwd_data->exclude_users = slist_deep_copy (manager->priv->exclude_usernames);
+- passwd_data->include_users = slist_deep_copy (manager->priv->include_usernames);
+- passwd_data->include_all = manager->priv->include_all;
+- passwd_data->current_users_by_name = manager->priv->users_by_name;
+- passwd_data->added_users = NULL;
+- passwd_data->removed_users = NULL;
+-
+- g_debug ("GdmUserManager: scheduling a passwd file update");
+-
+- g_io_scheduler_push_job ((GIOSchedulerJobFunc) do_reload_passwd_job,
+- passwd_data,
+- NULL,
+- G_PRIORITY_DEFAULT,
+- NULL);
+-}
+-
+-static void
+-load_sessions_from_array (GdmUserManager *manager,
+- const char * const *session_ids,
+- int number_of_sessions)
+-{
+- int i;
+-
+- for (i = 0; i < number_of_sessions; i++) {
+- load_new_session (manager, session_ids[i]);
+- }
+-}
+-
+-static void
+-on_get_sessions_finished (DBusGProxy *proxy,
+- DBusGProxyCall *call,
+- GdmUserManager *manager)
+-{
+- GError *error;
+- gboolean res;
+- GPtrArray *sessions;
+-
+- g_assert (manager->priv->get_sessions_call == call);
+-
+- error = NULL;
+- sessions = NULL;
+- res = dbus_g_proxy_end_call (proxy,
+- call,
+- &error,
+- GDM_DBUS_TYPE_G_OBJECT_PATH_ARRAY,
+- &sessions,
+- G_TYPE_INVALID);
+-
+- if (! res) {
+- if (error != NULL) {
+- g_warning ("unable to determine sessions for seat: %s",
+- error->message);
+- g_error_free (error);
+- } else {
+- g_warning ("unable to determine sessions for seat");
+- }
+- return;
+- }
+-
+- manager->priv->get_sessions_call = NULL;
+- g_assert (sessions->len <= G_MAXINT);
+- load_sessions_from_array (manager,
+- (const char * const *) sessions->pdata,
+- (int) sessions->len);
+- g_ptr_array_foreach (sessions, (GFunc) g_free, NULL);
+- g_ptr_array_free (sessions, TRUE);
+- maybe_set_is_loaded (manager);
+-}
+-
+-static void
+-load_sessions (GdmUserManager *manager)
+-{
+- DBusGProxyCall *call;
+-
+- if (manager->priv->seat.proxy == NULL) {
+- g_debug ("GdmUserManager: no seat proxy; can't load sessions");
+- return;
+- }
+-
+- call = dbus_g_proxy_begin_call (manager->priv->seat.proxy,
+- "GetSessions",
+- (DBusGProxyCallNotify)
+- on_get_sessions_finished,
+- manager,
+- NULL,
+- G_TYPE_INVALID);
+-
+- if (call == NULL) {
+- g_warning ("GdmUserManager: failed to make GetSessions call");
+- return;
+- }
+-
+- manager->priv->get_sessions_call = call;
+-}
+-
+-static void
+-reload_shells (GdmUserManager *manager)
+-{
+- char *shell;
+-
+- setusershell ();
+-
+- g_hash_table_remove_all (manager->priv->shells);
+- for (shell = getusershell (); shell != NULL; shell = getusershell ()) {
+- /* skip well known not-real shells */
+- if (shell == NULL
+- || strcmp (shell, "/sbin/nologin") == 0
+- || strcmp (shell, "/bin/false") == 0) {
+- g_debug ("GdmUserManager: skipping shell %s", shell);
+- continue;
+- }
+- g_hash_table_insert (manager->priv->shells,
+- g_strdup (shell),
+- GUINT_TO_POINTER (TRUE));
+- }
+-
+- endusershell ();
+-}
+-
+-static void
+-load_users_manually (GdmUserManager *manager)
+-{
+- gboolean res;
+-
+- manager->priv->shells = g_hash_table_new_full (g_str_hash,
+- g_str_equal,
+- g_free,
+- NULL);
+- reload_shells (manager);
+-
+- load_sessions (manager);
+-
+- res = load_ck_history (manager);
+- schedule_reload_passwd (manager);
+-}
+-
+-static void
+-load_users (GdmUserManager *manager)
+-{
+- g_assert (manager->priv->accounts_proxy != NULL);
+- g_debug ("GdmUserManager: calling 'ListCachedUsers'");
+-
+- dbus_g_proxy_begin_call (manager->priv->accounts_proxy,
+- "ListCachedUsers",
+- on_list_cached_users_finished,
+- manager,
+- NULL,
+- G_TYPE_INVALID);
+- manager->priv->listing_cached_users = TRUE;
+-}
+-
+-static void
+-load_seat_incrementally (GdmUserManager *manager)
+-{
+- g_assert (manager->priv->seat.proxy == NULL);
+-
+- switch (manager->priv->seat.state) {
+- case GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID:
+- get_current_session_id (manager);
+- break;
+- case GDM_USER_MANAGER_SEAT_STATE_GET_ID:
+- get_seat_id_for_current_session (manager);
+- break;
+- case GDM_USER_MANAGER_SEAT_STATE_GET_PROXY:
+- get_seat_proxy (manager);
+- break;
+- case GDM_USER_MANAGER_SEAT_STATE_LOADED:
+- break;
+- default:
+- g_assert_not_reached ();
+- }
+-
+- if (manager->priv->seat.state == GDM_USER_MANAGER_SEAT_STATE_LOADED) {
+- gboolean res;
+-
+- load_sessions (manager);
+- res = load_ck_history (manager);
+- }
+-
+- maybe_set_is_loaded (manager);
+-}
+-
+-static gboolean
+-load_idle (GdmUserManager *manager)
+-{
+- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED + 1;
+- load_seat_incrementally (manager);
+- load_users (manager);
+- manager->priv->load_id = 0;
+-
+- return FALSE;
+-}
+-
+-static void
+-queue_load_seat_and_users (GdmUserManager *manager)
+-{
+- if (manager->priv->load_id > 0) {
+- return;
+- }
+-
+- manager->priv->load_id = g_idle_add ((GSourceFunc)load_idle, manager);
+-}
+-
+-static gboolean
+-reload_passwd_idle (GdmUserManager *manager)
+-{
+- schedule_reload_passwd (manager);
+- manager->priv->reload_passwd_id = 0;
+-
+- return FALSE;
+-}
+-
+-static void
+-queue_reload_passwd (GdmUserManager *manager)
+-{
+- if (manager->priv->reload_passwd_id > 0) {
+- g_source_remove (manager->priv->reload_passwd_id);
+- }
+-
+- manager->priv->reload_passwd_id = g_timeout_add_seconds (RELOAD_PASSWD_THROTTLE_SECS, (GSourceFunc)reload_passwd_idle, manager);
+-}
+-
+-static void
+-on_shells_monitor_changed (GFileMonitor *monitor,
+- GFile *file,
+- GFile *other_file,
+- GFileMonitorEvent event_type,
+- GdmUserManager *manager)
+-{
+- if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
+- event_type != G_FILE_MONITOR_EVENT_CREATED) {
+- return;
+- }
+-
+- reload_shells (manager);
+- queue_reload_passwd (manager);
+-}
+-
+-static void
+-on_passwd_monitor_changed (GFileMonitor *monitor,
+- GFile *file,
+- GFile *other_file,
+- GFileMonitorEvent event_type,
+- GdmUserManager *manager)
+-{
+- if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
+- event_type != G_FILE_MONITOR_EVENT_CREATED) {
+- return;
+- }
+-
+- queue_reload_passwd (manager);
+-}
+-
+-static void
+-gdm_user_manager_get_property (GObject *object,
+- guint prop_id,
+- GValue *value,
+- GParamSpec *pspec)
+-{
+- GdmUserManager *manager;
+-
+- manager = GDM_USER_MANAGER (object);
+-
+- switch (prop_id) {
+- case PROP_IS_LOADED:
+- g_value_set_boolean (value, manager->priv->is_loaded);
+- break;
+- case PROP_HAS_MULTIPLE_USERS:
+- g_value_set_boolean (value, manager->priv->has_multiple_users);
+- break;
+- case PROP_INCLUDE_ALL:
+- g_value_set_boolean (value, manager->priv->include_all);
+- break;
+- case PROP_INCLUDE_USERNAMES_LIST:
+- g_value_set_pointer (value, manager->priv->include_usernames);
+- break;
+- case PROP_EXCLUDE_USERNAMES_LIST:
+- g_value_set_pointer (value, manager->priv->exclude_usernames);
+- break;
+- default:
+- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+- break;
+- }
+-}
+-
+-static void
+-set_include_usernames (GdmUserManager *manager,
+- GSList *list)
+-{
+- if (manager->priv->include_usernames != NULL) {
+- g_slist_foreach (manager->priv->include_usernames, (GFunc) g_free, NULL);
+- g_slist_free (manager->priv->include_usernames);
+- }
+- manager->priv->include_usernames = slist_deep_copy (list);
+-}
+-
+-static void
+-set_exclude_usernames (GdmUserManager *manager,
+- GSList *list)
+-{
+- if (manager->priv->exclude_usernames != NULL) {
+- g_slist_foreach (manager->priv->exclude_usernames, (GFunc) g_free, NULL);
+- g_slist_free (manager->priv->exclude_usernames);
+- }
+- manager->priv->exclude_usernames = slist_deep_copy (list);
+-}
+-
+-static void
+-set_include_all (GdmUserManager *manager,
+- gboolean all)
+-{
+- if (manager->priv->include_all != all) {
+- manager->priv->include_all = all;
+- }
+-}
+-
+-static void
+-gdm_user_manager_set_property (GObject *object,
+- guint prop_id,
+- const GValue *value,
+- GParamSpec *pspec)
+-{
+- GdmUserManager *self;
+-
+- self = GDM_USER_MANAGER (object);
+-
+- switch (prop_id) {
+- case PROP_INCLUDE_ALL:
+- set_include_all (self, g_value_get_boolean (value));
+- break;
+- case PROP_INCLUDE_USERNAMES_LIST:
+- set_include_usernames (self, g_value_get_pointer (value));
+- break;
+- case PROP_EXCLUDE_USERNAMES_LIST:
+- set_exclude_usernames (self, g_value_get_pointer (value));
+- break;
+- default:
+- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+- break;
+- }
+-}
+-
+-static void
+-monitor_local_users (GdmUserManager *manager)
+-{
+- GFile *file;
+- GError *error;
+-
+- g_debug ("GdmUserManager: Monitoring local users");
+-
+- /* /etc/shells */
+- file = g_file_new_for_path (_PATH_SHELLS);
+- error = NULL;
+- manager->priv->shells_monitor = g_file_monitor_file (file,
+- G_FILE_MONITOR_NONE,
+- NULL,
+- &error);
+- if (manager->priv->shells_monitor != NULL) {
+- g_signal_connect (manager->priv->shells_monitor,
+- "changed",
+- G_CALLBACK (on_shells_monitor_changed),
+- manager);
+- } else {
+- g_warning ("Unable to monitor %s: %s", _PATH_SHELLS, error->message);
+- g_error_free (error);
+- }
+- g_object_unref (file);
+-
+- /* /etc/passwd */
+- file = g_file_new_for_path (PATH_PASSWD);
+- manager->priv->passwd_monitor = g_file_monitor_file (file,
+- G_FILE_MONITOR_NONE,
+- NULL,
+- &error);
+- if (manager->priv->passwd_monitor != NULL) {
+- g_signal_connect (manager->priv->passwd_monitor,
+- "changed",
+- G_CALLBACK (on_passwd_monitor_changed),
+- manager);
+- } else {
+- g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message);
+- g_error_free (error);
+- }
+- g_object_unref (file);
+-}
+-
+-static void
+-gdm_user_manager_class_init (GdmUserManagerClass *klass)
+-{
+- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+-
+- object_class->finalize = gdm_user_manager_finalize;
+- object_class->get_property = gdm_user_manager_get_property;
+- object_class->set_property = gdm_user_manager_set_property;
+-
+- g_object_class_install_property (object_class,
+- PROP_IS_LOADED,
+- g_param_spec_boolean ("is-loaded",
+- NULL,
+- NULL,
+- FALSE,
+- G_PARAM_READABLE));
+- g_object_class_install_property (object_class,
+- PROP_HAS_MULTIPLE_USERS,
+- g_param_spec_boolean ("has-multiple-users",
+- NULL,
+- NULL,
+- FALSE,
+- G_PARAM_READABLE));
+- g_object_class_install_property (object_class,
+- PROP_INCLUDE_ALL,
+- g_param_spec_boolean ("include-all",
+- NULL,
+- NULL,
+- FALSE,
+- G_PARAM_READWRITE));
+- g_object_class_install_property (object_class,
+- PROP_INCLUDE_USERNAMES_LIST,
+- g_param_spec_pointer ("include-usernames-list",
+- NULL,
+- NULL,
+- G_PARAM_READWRITE));
+-
+- g_object_class_install_property (object_class,
+- PROP_EXCLUDE_USERNAMES_LIST,
+- g_param_spec_pointer ("exclude-usernames-list",
+- NULL,
+- NULL,
+- G_PARAM_READWRITE));
+-
+- signals [USER_ADDED] =
+- g_signal_new ("user-added",
+- G_TYPE_FROM_CLASS (klass),
+- G_SIGNAL_RUN_LAST,
+- G_STRUCT_OFFSET (GdmUserManagerClass, user_added),
+- NULL, NULL,
+- g_cclosure_marshal_VOID__OBJECT,
+- G_TYPE_NONE, 1, GDM_TYPE_USER);
+- signals [USER_REMOVED] =
+- g_signal_new ("user-removed",
+- G_TYPE_FROM_CLASS (klass),
+- G_SIGNAL_RUN_LAST,
+- G_STRUCT_OFFSET (GdmUserManagerClass, user_removed),
+- NULL, NULL,
+- g_cclosure_marshal_VOID__OBJECT,
+- G_TYPE_NONE, 1, GDM_TYPE_USER);
+- signals [USER_IS_LOGGED_IN_CHANGED] =
+- g_signal_new ("user-is-logged-in-changed",
+- G_TYPE_FROM_CLASS (klass),
+- G_SIGNAL_RUN_LAST,
+- G_STRUCT_OFFSET (GdmUserManagerClass, user_is_logged_in_changed),
+- NULL, NULL,
+- g_cclosure_marshal_VOID__OBJECT,
+- G_TYPE_NONE, 1, GDM_TYPE_USER);
+- signals [USER_CHANGED] =
+- g_signal_new ("user-changed",
+- G_TYPE_FROM_CLASS (klass),
+- G_SIGNAL_RUN_LAST,
+- G_STRUCT_OFFSET (GdmUserManagerClass, user_changed),
+- NULL, NULL,
+- g_cclosure_marshal_VOID__OBJECT,
+- G_TYPE_NONE, 1, GDM_TYPE_USER);
+-
+- g_type_class_add_private (klass, sizeof (GdmUserManagerPrivate));
+-}
+-
+-/**
+- * gdm_user_manager_queue_load:
+- * @manager: a #GdmUserManager
+- *
+- * Queue loading users into user manager. This must be called, and the
+- * #GdmUserManager:is-loaded property must be %TRUE before calling
+- * gdm_user_manager_list_users()
+- */
+-void
+-gdm_user_manager_queue_load (GdmUserManager *manager)
+-{
+- g_return_if_fail (GDM_IS_USER_MANAGER (manager));
+-
+- if (! manager->priv->is_loaded) {
+- queue_load_seat_and_users (manager);
+- }
+-}
+-
+-static void
+-gdm_user_manager_init (GdmUserManager *manager)
+-{
+- GError *error;
+-
+- manager->priv = GDM_USER_MANAGER_GET_PRIVATE (manager);
+-
+- /* sessions */
+- manager->priv->sessions = g_hash_table_new_full (g_str_hash,
+- g_str_equal,
+- g_free,
+- g_free);
+-
+- /* users */
+- manager->priv->users_by_name = g_hash_table_new_full (g_str_hash,
+- g_str_equal,
+- g_free,
+- g_object_unref);
+-
+- manager->priv->users_by_object_path = g_hash_table_new_full (g_str_hash,
+- g_str_equal,
+- NULL,
+- g_object_unref);
+-
+- g_assert (manager->priv->seat.proxy == NULL);
+-
+- error = NULL;
+- manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+- if (manager->priv->connection == NULL) {
+- if (error != NULL) {
+- g_warning ("Failed to connect to the D-Bus daemon: %s", error->message);
+- g_error_free (error);
+- } else {
+- g_warning ("Failed to connect to the D-Bus daemon");
+- }
+- return;
+- }
+-
+- get_accounts_proxy (manager);
+-
+- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED;
+-}
+-
+-static void
+-gdm_user_manager_finalize (GObject *object)
+-{
+- GdmUserManager *manager;
+- GSList *node;
+-
+- g_return_if_fail (object != NULL);
+- g_return_if_fail (GDM_IS_USER_MANAGER (object));
+-
+- manager = GDM_USER_MANAGER (object);
+-
+- g_return_if_fail (manager->priv != NULL);
+-
+- if (manager->priv->ck_history_pid > 0) {
+- g_debug ("Killing ck-history process");
+- signal_pid (manager->priv->ck_history_pid, SIGTERM);
+- }
+-
+- g_slist_foreach (manager->priv->new_sessions,
+- (GFunc) unload_new_session, NULL);
+- g_slist_free (manager->priv->new_sessions);
+-
+- g_slist_foreach (manager->priv->fetch_user_requests,
+- (GFunc) free_fetch_user_request, NULL);
+- g_slist_free (manager->priv->fetch_user_requests);
+-
+- node = manager->priv->new_users;
+- while (node != NULL) {
+- GdmUser *user;
+- GSList *next_node;
+-
+- user = GDM_USER (node->data);
+- next_node = node->next;
+-
+- g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
+- g_object_unref (user);
+- manager->priv->new_users = g_slist_delete_link (manager->priv->new_users, node);
+- node = next_node;
+- }
+-
+- unload_seat (manager);
+-
+- if (manager->priv->exclude_usernames != NULL) {
+- g_slist_foreach (manager->priv->exclude_usernames, (GFunc) g_free, NULL);
+- g_slist_free (manager->priv->exclude_usernames);
+- }
+-
+- if (manager->priv->include_usernames != NULL) {
+- g_slist_foreach (manager->priv->include_usernames, (GFunc) g_free, NULL);
+- g_slist_free (manager->priv->include_usernames);
+- }
+-
+- if (manager->priv->seat.proxy != NULL) {
+- g_object_unref (manager->priv->seat.proxy);
+- }
+-
+- if (manager->priv->accounts_proxy != NULL) {
+- g_object_unref (manager->priv->accounts_proxy);
+- }
+-
+- if (manager->priv->ck_history_id != 0) {
+- g_source_remove (manager->priv->ck_history_id);
+- manager->priv->ck_history_id = 0;
+- }
+-
+- if (manager->priv->ck_history_watchdog_id != 0) {
+- g_source_remove (manager->priv->ck_history_watchdog_id);
+- manager->priv->ck_history_watchdog_id = 0;
+- }
+-
+- if (manager->priv->load_id > 0) {
+- g_source_remove (manager->priv->load_id);
+- manager->priv->load_id = 0;
+- }
+-
+- if (manager->priv->reload_passwd_id > 0) {
+- g_source_remove (manager->priv->reload_passwd_id);
+- manager->priv->reload_passwd_id = 0;
+- }
+-
+- g_hash_table_destroy (manager->priv->sessions);
+-
+- if (manager->priv->passwd_monitor != NULL) {
+- g_file_monitor_cancel (manager->priv->passwd_monitor);
+- }
+-
+- g_hash_table_destroy (manager->priv->users_by_name);
+- g_hash_table_destroy (manager->priv->users_by_object_path);
+-
+- if (manager->priv->shells_monitor != NULL) {
+- g_file_monitor_cancel (manager->priv->shells_monitor);
+- }
+-
+- if (manager->priv->shells != NULL) {
+- g_hash_table_destroy (manager->priv->shells);
+- }
+-
+- G_OBJECT_CLASS (gdm_user_manager_parent_class)->finalize (object);
+-}
+-
+-/**
+- * gdm_user_manager_ref_default:
+- *
+- * Queue loading users into user manager. This must be called, and the
+- * #GdmUserManager:is-loaded property must be %TRUE before calling
+- * gdm_user_manager_list_users()
+- *
+- * Returns: (transfer full): user manager object
+- */
+-GdmUserManager *
+-gdm_user_manager_ref_default (void)
+-{
+- if (user_manager_object != NULL) {
+- g_object_ref (user_manager_object);
+- } else {
+- user_manager_object = g_object_new (GDM_TYPE_USER_MANAGER, NULL);
+- g_object_add_weak_pointer (user_manager_object,
+- (gpointer *) &user_manager_object);
+- }
+-
+- return GDM_USER_MANAGER (user_manager_object);
+-}
+diff --git a/gui/simple-greeter/gdm-user-manager.h b/gui/simple-greeter/gdm-user-manager.h
+deleted file mode 100644
+index 8dd9ede..0000000
+--- a/gui/simple-greeter/gdm-user-manager.h
++++ /dev/null
+@@ -1,91 +0,0 @@
+-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+- *
+- * Copyright (C) 2007 William Jon McCann <mccann at jhu.edu>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+- *
+- */
+-
+-#ifndef __GDM_USER_MANAGER_H__
+-#define __GDM_USER_MANAGER_H__
+-
+-#include <glib-object.h>
+-
+-#include "gdm-user.h"
+-
+-G_BEGIN_DECLS
+-
+-#define GDM_TYPE_USER_MANAGER (gdm_user_manager_get_type ())
+-#define GDM_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_USER_MANAGER, GdmUserManager))
+-#define GDM_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_USER_MANAGER, GdmUserManagerClass))
+-#define GDM_IS_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_USER_MANAGER))
+-#define GDM_IS_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_USER_MANAGER))
+-#define GDM_USER_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerClass))
+-
+-typedef struct GdmUserManagerPrivate GdmUserManagerPrivate;
+-typedef struct GdmUserManager GdmUserManager;
+-typedef struct GdmUserManagerClass GdmUserManagerClass;
+-typedef enum GdmUserManagerError GdmUserManagerError;
+-
+-struct GdmUserManager
+-{
+- GObject parent;
+- GdmUserManagerPrivate *priv;
+-};
+-
+-struct GdmUserManagerClass
+-{
+- GObjectClass parent_class;
+-
+- void (* user_added) (GdmUserManager *user_manager,
+- GdmUser *user);
+- void (* user_removed) (GdmUserManager *user_manager,
+- GdmUser *user);
+- void (* user_is_logged_in_changed) (GdmUserManager *user_manager,
+- GdmUser *user);
+- void (* user_changed) (GdmUserManager *user_manager,
+- GdmUser *user);
+-};
+-
+-enum GdmUserManagerError
+-{
+- GDM_USER_MANAGER_ERROR_GENERAL,
+- GDM_USER_MANAGER_ERROR_KEY_NOT_FOUND
+-};
+-
+-#define GDM_USER_MANAGER_ERROR gdm_user_manager_error_quark ()
+-
+-GQuark gdm_user_manager_error_quark (void);
+-GType gdm_user_manager_get_type (void);
+-
+-GdmUserManager * gdm_user_manager_ref_default (void);
+-
+-void gdm_user_manager_queue_load (GdmUserManager *manager);
+-GSList * gdm_user_manager_list_users (GdmUserManager *manager);
+-GdmUser * gdm_user_manager_get_user (GdmUserManager *manager,
+- const char *username);
+-GdmUser * gdm_user_manager_get_user_by_uid (GdmUserManager *manager,
+- gulong uid);
+-
+-gboolean gdm_user_manager_activate_user_session (GdmUserManager *manager,
+- GdmUser *user);
+-
+-gboolean gdm_user_manager_can_switch (GdmUserManager *manager);
+-
+-gboolean gdm_user_manager_goto_login_session (GdmUserManager *manager);
+-
+-G_END_DECLS
+-
+-#endif /* __GDM_USER_MANAGER_H */
+diff --git a/gui/simple-greeter/test-user-manager.c b/gui/simple-greeter/test-user-manager.c
+index d0f6427..03b7a21 100644
+--- a/gui/simple-greeter/test-user-manager.c
++++ b/gui/simple-greeter/test-user-manager.c
+@@ -30,10 +30,12 @@
+ #include <glib/gi18n.h>
+ #include <gtk/gtk.h>
+
+-#include "gdm-user-manager.h"
++#include <act/act-user-manager.h>
++#include <act/act-user.h>
++
+ #include "gdm-settings-client.h"
+
+-static GdmUserManager *manager = NULL;
++static ActUserManager *manager = NULL;
+ static GMainLoop *main_loop = NULL;
+
+ static gboolean do_monitor = FALSE;
+@@ -45,7 +47,7 @@ static GOptionEntry entries [] = {
+ };
+
+ static void
+-on_is_loaded_changed (GdmUserManager *manager,
++on_is_loaded_changed (ActUserManager *manager,
+ GParamSpec *pspec,
+ gpointer data)
+ {
+@@ -53,9 +55,9 @@ on_is_loaded_changed (GdmUserManager *manager,
+
+ g_debug ("Users loaded");
+
+- users = gdm_user_manager_list_users (manager);
++ users = act_user_manager_list_users (manager);
+ while (users != NULL) {
+- g_print ("User: %s\n", gdm_user_get_user_name (users->data));
++ g_print ("User: %s\n", act_user_get_user_name (users->data));
+ users = g_slist_delete_link (users, users);
+ }
+
+@@ -65,19 +67,19 @@ on_is_loaded_changed (GdmUserManager *manager,
+ }
+
+ static void
+-on_user_added (GdmUserManager *manager,
+- GdmUser *user,
++on_user_added (ActUserManager *manager,
++ ActUser *user,
+ gpointer data)
+ {
+- g_debug ("User added: %s", gdm_user_get_user_name (user));
++ g_debug ("User added: %s", act_user_get_user_name (user));
+ }
+
+ static void
+-on_user_removed (GdmUserManager *manager,
+- GdmUser *user,
++on_user_removed (ActUserManager *manager,
++ ActUser *user,
+ gpointer data)
+ {
+- g_debug ("User removed: %s", gdm_user_get_user_name (user));
++ g_debug ("User removed: %s", act_user_get_user_name (user));
+ }
+
+ int
+@@ -123,7 +125,7 @@ main (int argc, char *argv[])
+ exit (1);
+ }
+
+- manager = gdm_user_manager_ref_default ();
++ manager = act_user_manager_get_default ();
+ g_object_set (manager, "include-all", TRUE, NULL);
+ g_signal_connect (manager,
+ "notify::is-loaded",
+@@ -137,7 +139,6 @@ main (int argc, char *argv[])
+ "user-removed",
+ G_CALLBACK (on_user_removed),
+ NULL);
+- gdm_user_manager_queue_load (manager);
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+
+--
+1.7.4.1
+
+From f100b21d67382dbdfdc5305f8cbb7f6bc9233f98 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Fri, 18 Feb 2011 18:34:31 -0500
+Subject: [PATCH] greeter: filter out root and gdm users from list
+
+While the accounts service filters out most of the names
+we care about, it doesn't filter out the above two, so make
+sure they get filtered.
+---
+ gui/simple-greeter/gdm-user-chooser-widget.c | 8 ++++++++
+ 1 files changed, 8 insertions(+), 0 deletions(-)
+
+diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
+index a385218..dd06bc4 100644
+--- a/gui/simple-greeter/gdm-user-chooser-widget.c
++++ b/gui/simple-greeter/gdm-user-chooser-widget.c
+@@ -743,6 +743,14 @@ add_user (GdmUserChooserWidget *widget,
+ return;
+ }
+
++ if (strcmp (act_user_get_user_name (user), GDM_USERNAME) == 0) {
++ return;
++ }
++
++ if (act_user_get_uid (user) == 0) {
++ return;
++ }
++
+ if (widget->priv->stock_person_pixbuf != NULL) {
+ pixbuf = g_object_ref (widget->priv->stock_person_pixbuf);
+ } else {
+--
+1.7.4.1
+
More information about the scm-commits
mailing list