hal: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Sun Feb 25 13:02:19 PST 2007


 hald/ck-tracker.c    |  160 ++++++++++++++++++++++++++++++++++++++++++++-------
 hald/ck-tracker.h    |    7 +-
 hald/hald_dbus.c     |   26 ++++++++
 hald/hald_runner.c   |   21 +++---
 tools/hal-acl-tool.c |   40 ++++++------
 5 files changed, 204 insertions(+), 50 deletions(-)

New commits:
diff-tree 50d21832d0ba27dbd158d050d1ba7cda1582ab91 (from 9282a81f75a10b8fe48d686f673b862c5c5811d7)
Author: David Zeuthen <davidz at redhat.com>
Date:   Sun Feb 25 16:02:10 2007 -0500

    handle multiple / remote seats
    
    One nice way to test this is XDMCP logins - the CK patch for gdm
    supports this right now - for the remote session a new seat with an
    enclosing session will be created. The session will have is_local ->
    FALSE and hostname pointing to the adress.

diff --git a/hald/ck-tracker.c b/hald/ck-tracker.c
index 02d7bf2..83a868f 100644
--- a/hald/ck-tracker.c
+++ b/hald/ck-tracker.c
@@ -44,7 +44,6 @@
 struct CKSeat_s {
 	int refcount;
 	char *seat_objpath;           /* obj path of ConsoleKit seat */
-	gboolean is_local;            /* whether the seat is local */
 	GSList *sessions;             /* list of sessions on this seat */
 };
 
@@ -54,12 +53,16 @@ struct CKSession_s {
 	CKSeat *seat;                 /* seat that session belongs to */
 	gboolean is_active;           /* whether the session is active */
 	uid_t user;                   /* user id of the user the session belongs to */
+	gboolean is_local;            /* whether the session is on a local seat */
+	char *hostname;               /* name/address of the host the session is being displayed on */
 };
 
 struct CKTracker_s {
 	int refcount;
 	DBusConnection *dbus_connection;
 	void *user_data;
+	CKSeatAddedCB seat_added_cb;
+	CKSeatRemovedCB seat_removed_cb;
 	CKSessionAddedCB session_added_cb;
 	CKSessionRemovedCB session_removed_cb;
 	CKSessionActiveChangedCB session_active_changed_cb;
@@ -77,6 +80,8 @@ ck_session_new (const char *session_objp
 	session->refcount = 1;
 	session->session_objpath = g_strdup (session_objpath);
 	session->seat = NULL;
+	session->hostname = NULL;
+	session->is_local = FALSE;
 	return session;
 }
 
@@ -85,6 +90,7 @@ ck_session_unref (CKSession *session)
 {
 	session->refcount--;
 	if (session->refcount == 0) {
+		g_free (session->hostname);
 		g_free (session->session_objpath);
 		g_free (session);
 	}
@@ -154,8 +160,7 @@ ck_seat_ref (CKSeat *seat)
 static gboolean
 ck_seat_get_info (CKTracker *tracker, CKSeat *seat)
 {
-	/* TODO: replace with a D-Bus call to IsLocal() when that appears on ConsoleKit */
-	seat->is_local = TRUE;
+	/* currently no interesting info from CK to get */
 	return TRUE;
 }
 
@@ -166,6 +171,7 @@ ck_session_get_info (CKTracker *tracker,
 	DBusError error;
 	DBusMessage *message;
 	DBusMessage *reply;
+	char *hostname;
 
 	ret = FALSE;
 
@@ -194,6 +200,51 @@ ck_session_get_info (CKTracker *tracker,
 	message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", 
 						session->session_objpath,
 						"org.freedesktop.ConsoleKit.Session",
+						"IsLocal");
+	dbus_error_init (&error);
+	reply = dbus_connection_send_with_reply_and_block (tracker->dbus_connection, message, -1, &error);
+	if (reply == NULL || dbus_error_is_set (&error)) {
+		HAL_ERROR (("Error doing Session.IsLocal on ConsoleKit: %s: %s", error.name, error.message));
+		dbus_message_unref (message);
+		if (reply != NULL)
+			dbus_message_unref (reply);
+		goto error;
+	}
+	if (!dbus_message_get_args (reply, NULL,
+				    DBUS_TYPE_BOOLEAN, &(session->is_local),
+				    DBUS_TYPE_INVALID)) {
+		HAL_ERROR (("Invalid IsLocal reply from CK"));
+		goto error;
+	}
+	dbus_message_unref (message);
+	dbus_message_unref (reply);
+
+	message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", 
+						session->session_objpath,
+						"org.freedesktop.ConsoleKit.Session",
+						"GetHostName");
+	dbus_error_init (&error);
+	reply = dbus_connection_send_with_reply_and_block (tracker->dbus_connection, message, -1, &error);
+	if (reply == NULL || dbus_error_is_set (&error)) {
+		HAL_ERROR (("Error doing Session.GetHostName on ConsoleKit: %s: %s", error.name, error.message));
+		dbus_message_unref (message);
+		if (reply != NULL)
+			dbus_message_unref (reply);
+		goto error;
+	}
+	if (!dbus_message_get_args (reply, NULL,
+				    DBUS_TYPE_STRING, &hostname,
+				    DBUS_TYPE_INVALID)) {
+		HAL_ERROR (("Invalid GetHostName reply from CK"));
+		goto error;
+	}
+	session->hostname = g_strdup (hostname);
+	dbus_message_unref (message);
+	dbus_message_unref (reply);
+
+	message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", 
+						session->session_objpath,
+						"org.freedesktop.ConsoleKit.Session",
 						"GetUser");
 	dbus_error_init (&error);
 	reply = dbus_connection_send_with_reply_and_block (tracker->dbus_connection, message, -1, &error);
@@ -337,7 +388,7 @@ ck_tracker_init_get_seats_and_sessions (
 
 		seat = ck_seat_new (seat_objpath);
 
-		/* get information: is_local etc. */
+		/* get information */
 		if (!ck_seat_get_info (tracker, seat)) {
 			HAL_ERROR (("Could not get information for seat '%s'", seat_objpath));
 			dbus_message_unref (message);
@@ -417,6 +468,18 @@ ck_tracker_set_user_data (CKTracker *tra
 }
 
 void
+ck_tracker_set_seat_added_cb (CKTracker *tracker, CKSeatAddedCB cb)
+{
+	tracker->seat_added_cb = cb;
+}
+
+void
+ck_tracker_set_seat_removed_cb (CKTracker *tracker, CKSeatRemovedCB cb)
+{
+	tracker->seat_removed_cb = cb;
+}
+
+void
 ck_tracker_set_session_added_cb (CKTracker *tracker, CKSessionAddedCB cb)
 {
 	tracker->session_added_cb = cb;
@@ -463,7 +526,64 @@ ck_tracker_process_system_bus_message (C
 
 	/* TODO: also handle SeatRemoved and SeatAdded */
 
-	if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Seat", "SessionAdded")) {
+	if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Manager", "SeatAdded")) {
+
+		seat_objpath = dbus_message_get_path (message);
+
+		if (!dbus_message_get_args (message, NULL,
+					    DBUS_TYPE_STRING, &seat_objpath,
+					    DBUS_TYPE_INVALID)) {
+			HAL_ERROR (("Invalid SeatAdded signal from CK"));
+			goto out;
+		}
+
+		HAL_INFO (("Received SeatAdded '%s' from CK", seat_objpath));
+
+		seat = ck_seat_new (seat_objpath);
+
+		/* get information */
+		if (!ck_seat_get_info (tracker, seat)) {
+			HAL_ERROR (("Could not get information for seat '%s'", seat_objpath));
+			goto out;
+		}
+
+		tracker->seats = g_slist_prepend (tracker->seats, seat);
+
+		if (tracker->seat_added_cb != NULL) {
+			tracker->seat_added_cb (tracker, seat, tracker->user_data);
+		}
+
+	} else if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Manager", "SeatRemoved")) {
+
+		seat_objpath = dbus_message_get_path (message);
+
+		if (!dbus_message_get_args (message, NULL,
+					    DBUS_TYPE_STRING, &seat_objpath,
+					    DBUS_TYPE_INVALID)) {
+			HAL_ERROR (("Invalid SeatRemoved signal from CK"));
+			goto out;
+		}
+
+		HAL_INFO (("Received SeatRemoved '%s' from CK", seat_objpath));
+
+		for (i = tracker->seats; i != NULL; i = g_slist_next (i)) {
+			seat = (CKSeat *) i->data;
+			if (strcmp (seat->seat_objpath, seat_objpath) == 0) {
+
+				tracker->seats = g_slist_remove (tracker->seats, seat);
+
+				if (tracker->seat_removed_cb != NULL) {
+					tracker->seat_removed_cb (tracker, seat, tracker->user_data);
+				}
+
+				ck_seat_unref (seat);
+				break;
+			}
+		}
+		if (i == NULL) {
+			HAL_ERROR (("No such seat '%s'", seat_objpath));
+		}
+	} else if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Seat", "SessionAdded")) {
 
 		seat_objpath = dbus_message_get_path (message);
 
@@ -499,8 +619,6 @@ ck_tracker_process_system_bus_message (C
 		if (i == NULL) {
 			HAL_ERROR (("No seat '%s for session '%s'", seat_objpath, session_objpath));
 		}
-
-
 	} else if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Seat", "SessionRemoved")) {
 
 		seat_objpath = dbus_message_get_path (message);
@@ -518,6 +636,10 @@ ck_tracker_process_system_bus_message (C
 			session = (CKSession *) i->data;
 			if (strcmp (session->session_objpath, session_objpath) == 0) {
 
+				if (tracker->session_removed_cb != NULL) {
+					tracker->session_removed_cb (tracker, session, tracker->user_data);
+				}
+
 				if (session->seat == NULL) {
 					HAL_ERROR (("Session '%s' to be removed is not attached to a seat", 
 						    session_objpath));
@@ -526,18 +648,12 @@ ck_tracker_process_system_bus_message (C
 				}
 				tracker->sessions = g_slist_remove (tracker->sessions, session);
 				ck_session_unref (session);
-
-				if (tracker->session_removed_cb != NULL) {
-					tracker->session_removed_cb (tracker, session, tracker->user_data);
-				}
-
 				break;
 			}
 		}
 		if (i == NULL) {
 			HAL_ERROR (("No such session '%s'", session_objpath));
 		}
-
 	} else if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Session", "ActiveChanged")) {
 
 		session_objpath = dbus_message_get_path (message);
@@ -617,12 +733,6 @@ ck_tracker_get_sessions (CKTracker *trac
 	return tracker->sessions;
 }
 
-gboolean
-ck_seat_is_local (CKSeat *seat)
-{
-	return seat->is_local;
-}
-
 GSList *
 ck_seat_get_sessions (CKSeat *seat)
 {
@@ -660,6 +770,18 @@ ck_session_get_user (CKSession *session)
 }
 
 gboolean
+ck_session_is_local (CKSession *session)
+{
+	return session->is_local;
+}
+
+const char *
+ck_session_get_hostname (CKSession *session)
+{
+	return session->hostname;
+}
+
+gboolean
 ck_tracker_init (CKTracker *tracker)
 {
 	dbus_bool_t ret;
diff --git a/hald/ck-tracker.h b/hald/ck-tracker.h
index 6f8b5dd..bcf92ad 100644
--- a/hald/ck-tracker.h
+++ b/hald/ck-tracker.h
@@ -38,6 +38,8 @@ typedef struct CKSeat_s CKSeat;
 struct CKSession_s;
 typedef struct CKSession_s CKSession;
 
+typedef void (*CKSeatAddedCB) (CKTracker *tracker, CKSeat *seat, void *user_data);
+typedef void (*CKSeatRemovedCB) (CKTracker *tracker, CKSeat *seat, void *user_data);
 typedef void (*CKSessionAddedCB) (CKTracker *tracker, CKSession *session, void *user_data);
 typedef void (*CKSessionRemovedCB) (CKTracker *tracker, CKSession *session, void *user_data);
 typedef void (*CKSessionActiveChangedCB) (CKTracker *tracker, CKSession *session, void *user_data);
@@ -47,6 +49,8 @@ typedef void (*CKServiceAppearedCB) (CKT
 CKTracker  *ck_tracker_new                        (void);
 void        ck_tracker_set_system_bus_connection     (CKTracker *tracker, DBusConnection *system_bus_connection);
 void        ck_tracker_set_user_data                 (CKTracker *tracker, void *user_data);
+void        ck_tracker_set_seat_added_cb             (CKTracker *tracker, CKSeatAddedCB cb);
+void        ck_tracker_set_seat_removed_cb           (CKTracker *tracker, CKSeatRemovedCB cb);
 void        ck_tracker_set_session_added_cb          (CKTracker *tracker, CKSessionAddedCB cb);
 void        ck_tracker_set_session_removed_cb        (CKTracker *tracker, CKSessionRemovedCB cb);
 void        ck_tracker_set_session_active_changed_cb (CKTracker *tracker, CKSessionActiveChangedCB cb);
@@ -77,7 +81,6 @@ void        ck_tracker_unref            
 GSList     *ck_tracker_get_seats                  (CKTracker *tracker);
 GSList     *ck_tracker_get_sessions               (CKTracker *tracker);
 
-gboolean    ck_seat_is_local                      (CKSeat *seat);
 GSList     *ck_seat_get_sessions                  (CKSeat *seat);
 const char *ck_seat_get_id                        (CKSeat *seat);
 
@@ -85,6 +88,8 @@ gboolean    ck_session_is_active        
 CKSeat     *ck_session_get_seat                   (CKSession *session);
 const char *ck_session_get_id                     (CKSession *session);
 uid_t       ck_session_get_user                   (CKSession *session);
+gboolean    ck_session_is_local                   (CKSession *session);
+const char *ck_session_get_hostname               (CKSession *session);
 
 
 #endif /* CK_TRACKER_H */
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 8c05adb..dccadc4 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -4559,6 +4559,18 @@ out:
 }
 
 static void 
+hald_dbus_seat_added (CKTracker *tracker, CKSeat *seat, void *user_data)
+{
+	/* TODO: we could run callouts here... but they wouldn't do anything useful right now */
+}
+
+static void 
+hald_dbus_seat_removed (CKTracker *tracker, CKSeat *seat, void *user_data)
+{
+	/* TODO: we could run callouts here... but they wouldn't do anything useful right now */
+}
+
+static void 
 hald_dbus_session_active_changed (CKTracker *tracker, CKSession *session, void *user_data)
 {
 	HalDevice *d;
@@ -4699,9 +4711,23 @@ hald_dbus_init_preprobe (void)
 			    ",sender='org.freedesktop.ConsoleKit'"
 			    ",member='SessionRemoved'",
 			    NULL);
+	dbus_bus_add_match (dbus_connection,
+			    "type='signal'"
+			    ",interface='org.freedesktop.ConsoleKit.Manager'"
+			    ",sender='org.freedesktop.ConsoleKit'"
+			    ",member='SeatAdded'",
+			    NULL);
+	dbus_bus_add_match (dbus_connection,
+			    "type='signal'"
+			    ",interface='org.freedesktop.ConsoleKit.Manager'"
+			    ",sender='org.freedesktop.ConsoleKit'"
+			    ",member='SeatRemoved'",
+			    NULL);
 
 	ck_tracker = ck_tracker_new ();
 	ck_tracker_set_system_bus_connection (ck_tracker, dbus_connection);
+	ck_tracker_set_seat_added_cb (ck_tracker, hald_dbus_seat_added);
+	ck_tracker_set_seat_removed_cb (ck_tracker, hald_dbus_seat_removed);
 	ck_tracker_set_session_added_cb (ck_tracker, hald_dbus_session_added);
 	ck_tracker_set_session_removed_cb (ck_tracker, hald_dbus_session_removed);
 	ck_tracker_set_session_active_changed_cb (ck_tracker, hald_dbus_session_active_changed);
diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index 008c2cf..2fe0da5 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -403,18 +403,10 @@ add_basic_env (DBusMessageIter * iter, c
 			}
 			g_string_append (seats_string, seat_id);
 
-			/* for each Seat, export IS_LOCAL 
-			 *
-			 * CK_SEAT_IS_LOCAL_SEAT1=true|false
-			 */
-			s = g_strdup_printf ("CK_SEAT_IS_LOCAL_%s", seat_id);
-			add_env (iter, s, ck_seat_is_local (seat) ? "true" : "false");
-			g_free (s);
-			
 			sessions = ck_seat_get_sessions (seat);
 			for (j = sessions; j != NULL; j = g_slist_next (j)) {
 				CKSession *session;
-				char *session_id;
+				const char *session_id;
 
 				session = j->data;
 				/* basename again; e.g. Session1 rather than /org/freedesktop/ConsoleKit/Session1 */
@@ -429,6 +421,8 @@ add_basic_env (DBusMessageIter * iter, c
 				 *
 				 * CK_SESSION_IS_ACTIVE_Session2=true|false
 				 * CK_SESSION_UID_Session2=501
+				 * CK_SESSION_IS_LOCAL_Session2=true|false
+				 * CK_SESSION_HOSTNAME_Session2=192.168.1.112
 				 */
 				s = g_strdup_printf ("CK_SESSION_IS_ACTIVE_%s", session_id);
 				add_env (iter, s, ck_session_is_active (session) ? "true" : "false");
@@ -438,7 +432,14 @@ add_basic_env (DBusMessageIter * iter, c
 				add_env (iter, s, p);
 				g_free (s);
 				g_free (p);
-
+				s = g_strdup_printf ("CK_SESSION_IS_LOCAL_%s", session_id);
+				add_env (iter, s, ck_session_is_local (session) ? "true" : "false");
+				g_free (s);
+				s = g_strdup_printf ("CK_SESSION_HOSTNAME_%s", session_id);
+				p = g_strdup_printf ("%s", ck_session_get_hostname (session));
+				add_env (iter, s, p);
+				g_free (s);
+				g_free (p);
 			}
 
 			/* for each Seat, export sessions on each seat 
diff --git a/tools/hal-acl-tool.c b/tools/hal-acl-tool.c
index 2d8b6ea..530d4dc 100644
--- a/tools/hal-acl-tool.c
+++ b/tools/hal-acl-tool.c
@@ -305,10 +305,10 @@ out:
 }
 
 typedef void (*SeatSessionVisitor) (const char *seat_id, 
-				    gboolean seat_is_local,
 				    int num_sessions_on_seat,
 				    const char *session_id,     /* may be NULL */
 				    uid_t session_uid,
+				    gboolean seat_is_local,
 				    gboolean session_is_active, 
 				    gpointer user_data);
 
@@ -338,16 +338,6 @@ visit_seats_and_sessions (SeatSessionVis
 		char *seat = seats[i];
 		char **sessions;
 		int num_sessions_on_seat;
-		gboolean seat_is_local;
-
-		p = g_strdup_printf ("CK_SEAT_IS_LOCAL_%s", seat);
-		if ((s = getenv (p)) == NULL) {
-			printf ("%d: CK_SEAT_IS_LOCAL_%s is not set!\n", getpid(), seat);
-			g_free (p);
-			goto out;
-		}
-		g_free (p);
-		seat_is_local = (strcmp (s, "true") == 0);
 
 		p = g_strdup_printf ("CK_SEAT_%s", seat);
 		if ((s = getenv (p)) == NULL) {
@@ -359,15 +349,25 @@ visit_seats_and_sessions (SeatSessionVis
 		sessions = g_strsplit (s, "\t", 0);
 		num_sessions_on_seat = g_strv_length (sessions);
 
-		visitor_cb (seat, seat_is_local, num_sessions_on_seat, NULL, 0, FALSE, user_data);
+		visitor_cb (seat, num_sessions_on_seat, NULL, 0, FALSE, FALSE, user_data);
 
 		/* for all sessions on seat */
 		for (j = 0; sessions[j] != NULL; j++) {
 			char *session = sessions[j];
+			gboolean session_is_local;
 			gboolean session_is_active;
 			uid_t session_uid;
 			char *endptr;
 
+			p = g_strdup_printf ("CK_SESSION_IS_LOCAL_%s", session);
+			if ((s = getenv (p)) == NULL) {
+				printf ("%d: CK_SESSION_IS_LOCAL_%s is not set!\n", getpid(), session);
+				g_free (p);
+				goto out;
+			}
+			g_free (p);
+			session_is_local = (strcmp (s, "true") == 0);
+
 			p = g_strdup_printf ("CK_SESSION_IS_ACTIVE_%s", session);
 			if ((s = getenv (p)) == NULL) {
 				printf ("%d: CK_SESSION_IS_ACTIVE_%s is not set!\n", getpid(), session);
@@ -390,8 +390,8 @@ visit_seats_and_sessions (SeatSessionVis
 				goto out;
 			}
 
-			visitor_cb (seat, seat_is_local, num_sessions_on_seat, 
-				    session, session_uid, session_is_active, user_data);
+			visitor_cb (seat, num_sessions_on_seat, 
+				    session, session_uid, session_is_local, session_is_active, user_data);
 
 		}
 		g_strfreev (sessions);
@@ -580,10 +580,10 @@ acl_for_device_free (ACLForDevice* afd)
 
 static void 
 acl_device_added_visitor (const char *seat_id, 
-			  gboolean seat_is_local,
 			  int num_sessions_on_seat,
 			  const char *session_id, 
 			  uid_t session_uid,
+			  gboolean session_is_local,
 			  gboolean session_is_active, 
 			  gpointer user_data)
 {
@@ -593,11 +593,11 @@ acl_device_added_visitor (const char *se
 #if 0
 	if (session_id == NULL) {
 		/* means we're just visiting the seat; each session on the seat will be visited accordingly */
-		printf ("Visiting seat '%s' (is_local=%d) with %d sessions\n", 
-			seat_id, seat_is_local, num_sessions_on_seat);
+		printf ("Visiting seat '%s' with %d sessions\n", 
+			seat_id, num_sessions_on_seat);
 	} else {
-		printf ("  %s: Visiting session '%s' with uid %d (is_active=%d)\n",
-			seat_id, session_id, session_uid, session_is_active);
+		printf ("  %s: Visiting session '%s' with uid %d  (is_local=%d) (is_active=%d)\n",
+			seat_id, session_id, session_uid, session_is_local, session_is_active);
 	}
 #endif
 
@@ -623,7 +623,7 @@ acl_device_added_visitor (const char *se
 		/* apply the policy defined by grant_to_local_seat and grant_to_local_seat_active_only */
 
 		/* we only grant access to local seats... */
-		if (!seat_is_local)
+		if (!session_is_local)
 			continue;
 
 		if (afd->grant_to_local_seat)


More information about the hal-commit mailing list