Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 347630 Details for
Bug 468930
net-misc/networkmanager: detect consolekit/logind at runtime
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
consolekit/logind runtime detection for 0.9.6.x
0001-core-runtime-detect-logind-and-ConsoleKit.patch (text/plain), 40.60 KB, created by
Fabio Erculiani (RETIRED)
on 2013-05-07 19:51:18 UTC
(
hide
)
Description:
consolekit/logind runtime detection for 0.9.6.x
Filename:
MIME Type:
Creator:
Fabio Erculiani (RETIRED)
Created:
2013-05-07 19:51:18 UTC
Size:
40.60 KB
patch
obsolete
>From 6230e8a92341804ad3f033c2016f6d350468b772 Mon Sep 17 00:00:00 2001 >From: Fabio Erculiani <lxnay@sabayon.org> >Date: Mon, 15 Apr 2013 22:51:20 +0100 >Subject: [PATCH] core: runtime detect logind and ConsoleKit > >If --with-session-tracking=systemd, but logind is not currently running, the code >now falls back to ConsoleKit. >--- > configure.ac | 4 +- > src/Makefile.am | 10 +- > src/nm-session-monitor-ck.c | 509 ------------------------------- > src/nm-session-monitor-systemd.c | 268 ---------------- > src/nm-session-monitor.c | 641 +++++++++++++++++++++++++++++++++++++++ > src/nm-session-monitor.h | 6 + > 6 files changed, 653 insertions(+), 785 deletions(-) > delete mode 100644 src/nm-session-monitor-ck.c > delete mode 100644 src/nm-session-monitor-systemd.c > create mode 100644 src/nm-session-monitor.c > >diff --git a/configure.ac b/configure.ac >index 91afabe..5b6ef8a 100644 >--- a/configure.ac >+++ b/configure.ac >@@ -368,7 +368,7 @@ if test "x$with_systemdsystemunitdir" != xno; then > fi > AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ]) > >-AC_ARG_WITH(session-tracking, AS_HELP_STRING([--with-session-tracking=systemd|ck|none], [Build NetworkManager with specific session tracking support])) >+AC_ARG_WITH(session-tracking, AS_HELP_STRING([--with-session-tracking=systemd|ck|none], [Build NetworkManager with specific session tracking support, systemd falls back to ConsoleKit if logind is not available])) > if test "z$with_session_tracking" = "z"; then > # Default to ConsoleKit session tracking like we used before > with_session_tracking=ck >@@ -378,6 +378,7 @@ case $with_session_tracking in > ck|none|no) ;; > systemd) > PKG_CHECK_MODULES(SYSTEMD, [libsystemd-login]) >+ AC_DEFINE([SESSION_TRACKING_SYSTEMD], 1, [Define to 1 if libsystemd-login is available]) > ;; > *) > AC_MSG_ERROR(--with-session-tracking must be one of [none, ck, systemd]) >@@ -387,6 +388,7 @@ AC_SUBST(SYSTEMD_CFLAGS) > AC_SUBST(SYSTEMD_LIBS) > AM_CONDITIONAL(SESSION_TRACKING_CK, test "x$with_session_tracking" = "xck") > AM_CONDITIONAL(SESSION_TRACKING_SYSTEMD, test "x$with_session_tracking" = "xsystemd") >+AM_CONDITIONAL(SESSION_TRACKING_NULL, test "x$with_session_tracking" = "xnone" || test "x$with_session_tracking" = "xno") > > > have_libnl="no" >diff --git a/src/Makefile.am b/src/Makefile.am >index 7310434..1da8a72 100644 >--- a/src/Makefile.am >+++ b/src/Makefile.am >@@ -199,14 +199,10 @@ if WITH_CONCHECK > NetworkManager_SOURCES += nm-connectivity.c nm-connectivity.h > endif > >-if SESSION_TRACKING_SYSTEMD >-NetworkManager_SOURCES += nm-session-monitor-systemd.c >-else >-if SESSION_TRACKING_CK >-NetworkManager_SOURCES += nm-session-monitor-ck.c >-else >+if SESSION_TRACKING_NULL > NetworkManager_SOURCES += nm-session-monitor-null.c >-endif >+else >+NetworkManager_SOURCES += nm-session-monitor.c > endif > > nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml >diff --git a/src/nm-session-monitor-ck.c b/src/nm-session-monitor-ck.c >deleted file mode 100644 >index 72ffc9f..0000000 >--- a/src/nm-session-monitor-ck.c >+++ /dev/null >@@ -1,509 +0,0 @@ >-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ >-/* 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., >- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >- * >- * (C) Copyright 2008 - 2010 Red Hat, Inc. >- * Author: David Zeuthen <davidz@redhat.com> >- * Author: Dan Williams <dcbw@redhat.com> >- */ >- >-#include "config.h" >-#include <errno.h> >-#include <string.h> >-#include <sys/stat.h> >-#include <gio/gio.h> >-#include "nm-logging.h" >- >-#include "nm-session-utils.h" >-#include "nm-session-monitor.h" >- >-#define CKDB_PATH "/var/run/ConsoleKit/database" >- >-/* <internal> >- * SECTION:nm-session-monitor >- * @title: NMSessionMonitor >- * @short_description: Monitor sessions >- * >- * The #NMSessionMonitor class is a utility class to track and monitor sessions. >- */ >- >-struct _NMSessionMonitor { >- GObject parent_instance; >- >- GKeyFile *database; >- GFileMonitor *database_monitor; >- time_t database_mtime; >- GHashTable *sessions_by_uid; >- GHashTable *sessions_by_user; >-}; >- >-struct _NMSessionMonitorClass { >- GObjectClass parent_class; >- >- void (*changed) (NMSessionMonitor *monitor); >-}; >- >- >-enum { >- CHANGED, >- LAST_SIGNAL, >-}; >-static guint signals[LAST_SIGNAL] = {0}; >- >-G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); >- >-/********************************************************************/ >- >-typedef struct { >- char *user; >- uid_t uid; >- gboolean local; >- gboolean active; >-} Session; >- >-static void >-session_free (Session *s) >-{ >- g_free (s->user); >- memset (s, 0, sizeof (Session)); >- g_free (s); >-} >- >-static gboolean >-check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error) >-{ >- if (g_key_file_has_key (keyfile, group, key, error)) >- return TRUE; >- >- if (!error) { >- g_set_error (error, >- NM_SESSION_MONITOR_ERROR, >- NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, >- "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key", >- group, key); >- } >- return FALSE; >-} >- >-static Session * >-session_new (GKeyFile *keyfile, const char *group, GError **error) >-{ >- GError *local = NULL; >- Session *s; >- const char *uname = NULL; >- >- s = g_new0 (Session, 1); >- g_assert (s); >- >- s->uid = G_MAXUINT; /* paranoia */ >- if (!check_key (keyfile, group, "uid", &local)) >- goto error; >- s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", &local); >- if (local) >- goto error; >- >- if (!check_key (keyfile, group, "is_active", &local)) >- goto error; >- s->active = g_key_file_get_boolean (keyfile, group, "is_active", &local); >- if (local) >- goto error; >- >- if (!check_key (keyfile, group, "is_local", &local)) >- goto error; >- s->local = g_key_file_get_boolean (keyfile, group, "is_local", &local); >- if (local) >- goto error; >- >- if (!nm_session_uid_to_user (s->uid, &uname, error)) >- return FALSE; >- s->user = g_strdup (uname); >- >- return s; >- >-error: >- session_free (s); >- g_propagate_error (error, local); >- return NULL; >-} >- >-static void >-session_merge (Session *src, Session *dest) >-{ >- g_return_if_fail (src != NULL); >- g_return_if_fail (dest != NULL); >- >- g_warn_if_fail (g_strcmp0 (src->user, dest->user) == 0); >- g_warn_if_fail (src->uid == dest->uid); >- >- dest->local = (dest->local || src->local); >- dest->active = (dest->active || src->active); >-} >- >-/********************************************************************/ >- >-static void >-free_database (NMSessionMonitor *self) >-{ >- if (self->database != NULL) { >- g_key_file_free (self->database); >- self->database = NULL; >- } >- >- g_hash_table_remove_all (self->sessions_by_uid); >- g_hash_table_remove_all (self->sessions_by_user); >-} >- >-static gboolean >-reload_database (NMSessionMonitor *self, GError **error) >-{ >- struct stat statbuf; >- char **groups = NULL; >- gsize len = 0, i; >- Session *s; >- >- free_database (self); >- >- errno = 0; >- if (stat (CKDB_PATH, &statbuf) != 0) { >- g_set_error (error, >- NM_SESSION_MONITOR_ERROR, >- errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR, >- "Error statting file " CKDB_PATH ": %s", >- strerror (errno)); >- goto error; >- } >- self->database_mtime = statbuf.st_mtime; >- >- self->database = g_key_file_new (); >- if (!g_key_file_load_from_file (self->database, CKDB_PATH, G_KEY_FILE_NONE, error)) >- goto error; >- >- groups = g_key_file_get_groups (self->database, &len); >- if (!groups) { >- g_set_error_literal (error, >- NM_SESSION_MONITOR_ERROR, >- NM_SESSION_MONITOR_ERROR_IO_ERROR, >- "Could not load groups from " CKDB_PATH ""); >- goto error; >- } >- >- for (i = 0; i < len; i++) { >- Session *found; >- >- if (!g_str_has_prefix (groups[i], "Session ")) >- continue; >- >- s = session_new (self->database, groups[i], error); >- if (!s) >- goto error; >- >- found = g_hash_table_lookup (self->sessions_by_user, (gpointer) s->user); >- if (found) { >- session_merge (s, found); >- session_free (s); >- } else { >- /* Entirely new user */ >- g_hash_table_insert (self->sessions_by_user, (gpointer) s->user, s); >- g_hash_table_insert (self->sessions_by_uid, GUINT_TO_POINTER (s->uid), s); >- } >- } >- >- g_strfreev (groups); >- return TRUE; >- >-error: >- if (groups) >- g_strfreev (groups); >- free_database (self); >- return FALSE; >-} >- >-static gboolean >-ensure_database (NMSessionMonitor *self, GError **error) >-{ >- gboolean ret = FALSE; >- >- if (self->database != NULL) { >- struct stat statbuf; >- >- errno = 0; >- if (stat (CKDB_PATH, &statbuf) != 0) { >- g_set_error (error, >- NM_SESSION_MONITOR_ERROR, >- errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR, >- "Error statting file " CKDB_PATH " to check timestamp: %s", >- strerror (errno)); >- goto out; >- } >- >- if (statbuf.st_mtime == self->database_mtime) { >- ret = TRUE; >- goto out; >- } >- } >- >- ret = reload_database (self, error); >- >-out: >- return ret; >-} >- >-static void >-on_file_monitor_changed (GFileMonitor * file_monitor, >- GFile * file, >- GFile * other_file, >- GFileMonitorEvent event_type, >- gpointer user_data) >-{ >- NMSessionMonitor *self = NM_SESSION_MONITOR (user_data); >- >- /* throw away cache */ >- free_database (self); >- >- g_signal_emit (self, signals[CHANGED], 0); >-} >- >-static void >-nm_session_monitor_init (NMSessionMonitor *self) >-{ >- GError *error = NULL; >- GFile *file; >- >- /* Sessions-by-user is responsible for destroying the Session objects */ >- self->sessions_by_user = g_hash_table_new_full (g_str_hash, g_str_equal, >- NULL, (GDestroyNotify) session_free); >- self->sessions_by_uid = g_hash_table_new (g_direct_hash, g_direct_equal); >- >- >- error = NULL; >- if (!ensure_database (self, &error)) { >- /* Ignore the first error if the CK database isn't found yet */ >- if (g_error_matches (error, >- NM_SESSION_MONITOR_ERROR, >- NM_SESSION_MONITOR_ERROR_NO_DATABASE) == FALSE) { >- nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message); >- } >- g_error_free (error); >- } >- >- error = NULL; >- file = g_file_new_for_path (CKDB_PATH); >- self->database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error); >- g_object_unref (file); >- if (self->database_monitor == NULL) { >- nm_log_err (LOGD_CORE, "Error monitoring " CKDB_PATH ": %s", error->message); >- g_error_free (error); >- } else { >- g_signal_connect (self->database_monitor, >- "changed", >- G_CALLBACK (on_file_monitor_changed), >- self); >- } >-} >- >-static void >-finalize (GObject *object) >-{ >- NMSessionMonitor *self = NM_SESSION_MONITOR (object); >- >- if (self->database_monitor != NULL) >- g_object_unref (self->database_monitor); >- >- free_database (self); >- >- if (G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize != NULL) >- G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object); >-} >- >-static void >-nm_session_monitor_class_init (NMSessionMonitorClass *klass) >-{ >- GObjectClass *gobject_class; >- >- gobject_class = G_OBJECT_CLASS (klass); >- >- gobject_class->finalize = finalize; >- >- /** >- * NMSessionMonitor::changed: >- * @monitor: A #NMSessionMonitor >- * >- * Emitted when something changes. >- */ >- signals[CHANGED] = g_signal_new (NM_SESSION_MONITOR_CHANGED, >- NM_TYPE_SESSION_MONITOR, >- G_SIGNAL_RUN_LAST, >- G_STRUCT_OFFSET (NMSessionMonitorClass, changed), >- NULL, /* accumulator */ >- NULL, /* accumulator data */ >- g_cclosure_marshal_VOID__VOID, >- G_TYPE_NONE, 0); >-} >- >-NMSessionMonitor * >-nm_session_monitor_get (void) >-{ >- static NMSessionMonitor *singleton = NULL; >- >- if (singleton) >- return g_object_ref (singleton); >- >- singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL)); >- return singleton; >-} >- >-/* ---------------------------------------------------------------------------------------------------- */ >- >-/** >- * nm_session_monitor_user_has_session: >- * @monitor: A #NMSessionMonitor. >- * @username: A username. >- * @error: Return location for error. >- * >- * Checks whether the given @username is logged into a session or not. >- * >- * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is >- * currently logged into a session. >- */ >-gboolean >-nm_session_monitor_user_has_session (NMSessionMonitor *monitor, >- const char *username, >- uid_t *out_uid, >- GError **error) >-{ >- Session *s; >- >- if (!ensure_database (monitor, error)) >- return FALSE; >- >- s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); >- if (!s) { >- g_set_error (error, >- NM_SESSION_MONITOR_ERROR, >- NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, >- "No session found for user '%s'", >- username); >- return FALSE; >- } >- >- if (out_uid) >- *out_uid = s->uid; >- return TRUE; >-} >- >-/** >- * nm_session_monitor_uid_has_session: >- * @monitor: A #NMSessionMonitor. >- * @uid: A user ID. >- * @error: Return location for error. >- * >- * Checks whether the given @uid is logged into a session or not. >- * >- * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is >- * currently logged into a session. >- */ >-gboolean >-nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, >- uid_t uid, >- const char **out_user, >- GError **error) >-{ >- Session *s; >- >- if (!ensure_database (monitor, error)) >- return FALSE; >- >- s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); >- if (!s) { >- g_set_error (error, >- NM_SESSION_MONITOR_ERROR, >- NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, >- "No session found for uid %d", >- uid); >- return FALSE; >- } >- >- if (out_user) >- *out_user = s->user; >- return TRUE; >-} >- >-/** >- * nm_session_monitor_user_active: >- * @monitor: A #NMSessionMonitor. >- * @username: A username. >- * @error: Return location for error. >- * >- * Checks whether the given @username is logged into a active session or not. >- * >- * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is >- * logged into an active session. >- */ >-gboolean >-nm_session_monitor_user_active (NMSessionMonitor *monitor, >- const char *username, >- GError **error) >-{ >- Session *s; >- >- if (!ensure_database (monitor, error)) >- return FALSE; >- >- s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); >- if (!s) { >- g_set_error (error, >- NM_SESSION_MONITOR_ERROR, >- NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, >- "No session found for user '%s'", >- username); >- return FALSE; >- } >- >- return s->active; >-} >- >-/** >- * nm_session_monitor_uid_active: >- * @monitor: A #NMSessionMonitor. >- * @uid: A user ID. >- * @error: Return location for error. >- * >- * Checks whether the given @uid is logged into a active session or not. >- * >- * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is >- * logged into an active session. >- */ >-gboolean >-nm_session_monitor_uid_active (NMSessionMonitor *monitor, >- uid_t uid, >- GError **error) >-{ >- Session *s; >- >- if (!ensure_database (monitor, error)) >- return FALSE; >- >- s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); >- if (!s) { >- g_set_error (error, >- NM_SESSION_MONITOR_ERROR, >- NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, >- "No session found for uid '%d'", >- uid); >- return FALSE; >- } >- >- return s->active; >-} >- >diff --git a/src/nm-session-monitor-systemd.c b/src/nm-session-monitor-systemd.c >deleted file mode 100644 >index f9fb075..0000000 >--- a/src/nm-session-monitor-systemd.c >+++ /dev/null >@@ -1,268 +0,0 @@ >-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ >-/* >- * Copyright (C) 2011 Red Hat, Inc. >- * >- * This library is free software; you can redistribute it and/or >- * modify it under the terms of the GNU Lesser General Public >- * License as published by the Free Software Foundation; either >- * version 2 of the License, or (at your option) any later version. >- * >- * This library 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 >- * Lesser General Public License for more details. >- * >- * You should have received a copy of the GNU Lesser General >- * Public License along with this library; if not, write to the >- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >- * Boston, MA 02110-1301, USA. >- * >- * Author: Matthias Clasen >- */ >- >-#include "config.h" >-#include <errno.h> >-#include <pwd.h> >-#include <grp.h> >-#include <string.h> >-#include <glib/gstdio.h> >-#include <systemd/sd-login.h> >-#include <stdlib.h> >- >-#include "nm-session-utils.h" >-#include "nm-session-monitor.h" >-#include "nm-logging.h" >- >-/********************************************************************/ >- >-typedef struct { >- GSource source; >- GPollFD pollfd; >- sd_login_monitor *monitor; >-} SdSource; >- >-static gboolean >-sd_source_prepare (GSource *source, gint *timeout) >-{ >- *timeout = -1; >- return FALSE; >-} >- >-static gboolean >-sd_source_check (GSource *source) >-{ >- SdSource *sd_source = (SdSource *) source; >- >- return sd_source->pollfd.revents != 0; >-} >- >-static gboolean >-sd_source_dispatch (GSource *source, >- GSourceFunc callback, >- gpointer user_data) >- >-{ >- SdSource *sd_source = (SdSource *)source; >- gboolean ret; >- >- g_warn_if_fail (callback != NULL); >- ret = (*callback) (user_data); >- sd_login_monitor_flush (sd_source->monitor); >- return ret; >-} >- >-static void >-sd_source_finalize (GSource *source) >-{ >- SdSource *sd_source = (SdSource*) source; >- >- sd_login_monitor_unref (sd_source->monitor); >-} >- >-static GSourceFuncs sd_source_funcs = { >- sd_source_prepare, >- sd_source_check, >- sd_source_dispatch, >- sd_source_finalize >-}; >- >-static GSource * >-sd_source_new (void) >-{ >- GSource *source; >- SdSource *sd_source; >- int ret; >- >- source = g_source_new (&sd_source_funcs, sizeof (SdSource)); >- sd_source = (SdSource *)source; >- >- ret = sd_login_monitor_new (NULL, &sd_source->monitor); >- if (ret < 0) >- g_printerr ("Error getting login monitor: %d", ret); >- else { >- sd_source->pollfd.fd = sd_login_monitor_get_fd (sd_source->monitor); >- sd_source->pollfd.events = G_IO_IN; >- g_source_add_poll (source, &sd_source->pollfd); >- } >- >- return source; >-} >- >-struct _NMSessionMonitor { >- GObject parent_instance; >- >- GSource *sd_source; >-}; >- >-struct _NMSessionMonitorClass { >- GObjectClass parent_class; >- >- void (*changed) (NMSessionMonitor *monitor); >-}; >- >- >-enum { >- CHANGED_SIGNAL, >- LAST_SIGNAL, >-}; >-static guint signals[LAST_SIGNAL] = {0}; >- >-G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); >- >-/* ---------------------------------------------------------------------------------------------------- */ >- >-static gboolean >-sessions_changed (gpointer user_data) >-{ >- NMSessionMonitor *monitor = NM_SESSION_MONITOR (user_data); >- >- g_signal_emit (monitor, signals[CHANGED_SIGNAL], 0); >- return TRUE; >-} >- >- >-static void >-nm_session_monitor_init (NMSessionMonitor *monitor) >-{ >- monitor->sd_source = sd_source_new (); >- g_source_set_callback (monitor->sd_source, sessions_changed, monitor, NULL); >- g_source_attach (monitor->sd_source, NULL); >-} >- >-static void >-nm_session_monitor_finalize (GObject *object) >-{ >- NMSessionMonitor *monitor = NM_SESSION_MONITOR (object); >- >- if (monitor->sd_source != NULL) { >- g_source_destroy (monitor->sd_source); >- g_source_unref (monitor->sd_source); >- } >- >- if (G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize != NULL) >- G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object); >-} >- >-static void >-nm_session_monitor_class_init (NMSessionMonitorClass *klass) >-{ >- GObjectClass *gobject_class; >- >- gobject_class = G_OBJECT_CLASS (klass); >- gobject_class->finalize = nm_session_monitor_finalize; >- >- /** >- * NMSessionMonitor::changed: >- * @monitor: A #NMSessionMonitor >- * >- * Emitted when something changes. >- */ >- signals[CHANGED_SIGNAL] = g_signal_new ("changed", >- NM_TYPE_SESSION_MONITOR, >- G_SIGNAL_RUN_LAST, >- G_STRUCT_OFFSET (NMSessionMonitorClass, changed), >- NULL, /* accumulator */ >- NULL, /* accumulator data */ >- g_cclosure_marshal_VOID__VOID, >- G_TYPE_NONE, >- 0); >-} >- >-NMSessionMonitor * >-nm_session_monitor_get (void) >-{ >- static NMSessionMonitor *singleton = NULL; >- >- if (singleton) >- return g_object_ref (singleton); >- >- singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL)); >- g_assert (singleton); >- return singleton; >-} >- >-gboolean >-nm_session_monitor_user_has_session (NMSessionMonitor *monitor, >- const char *username, >- uid_t *out_uid, >- GError **error) >-{ >- uid_t uid; >- >- if (!nm_session_user_to_uid (username, &uid, error)) >- return FALSE; >- >- if (out_uid) >- *out_uid = uid; >- >- return nm_session_monitor_uid_has_session (monitor, uid, NULL, error); >-} >- >-gboolean >-nm_session_monitor_user_active (NMSessionMonitor *monitor, >- const char *username, >- GError **error) >-{ >- uid_t uid; >- >- if (!nm_session_user_to_uid (username, &uid, error)) >- return FALSE; >- >- return nm_session_monitor_uid_active (monitor, uid, error); >-} >- >-gboolean >-nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, >- uid_t uid, >- const char **out_user, >- GError **error) >-{ >- int ret; >- >- if (!nm_session_uid_to_user (uid, out_user, error)) >- return FALSE; >- >- ret = sd_uid_get_sessions (uid, FALSE, NULL) > 0; >- if (ret < 0) { >- nm_log_warn (LOGD_CORE, "Failed to get systemd sessions for uid %d: %d", >- uid, ret); >- return FALSE; >- } >- return ret > 0 ? TRUE : FALSE; >-} >- >-gboolean >-nm_session_monitor_uid_active (NMSessionMonitor *monitor, >- uid_t uid, >- GError **error) >-{ >- int ret; >- >- ret = sd_uid_get_sessions (uid, TRUE, NULL) > 0; >- if (ret < 0) { >- nm_log_warn (LOGD_CORE, "Failed to get active systemd sessions for uid %d: %d", >- uid, ret); >- return FALSE; >- } >- return ret > 0 ? TRUE : FALSE; >-} >diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c >new file mode 100644 >index 0000000..26e66ce >--- /dev/null >+++ b/src/nm-session-monitor.c >@@ -0,0 +1,641 @@ >+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ >+/* >+ * Copyright (C) 2011 Red Hat, Inc. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Lesser General Public >+ * License as published by the Free Software Foundation; either >+ * version 2 of the License, or (at your option) any later version. >+ * >+ * This library 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 >+ * Lesser General Public License for more details. >+ * >+ * You should have received a copy of the GNU Lesser General >+ * Public License along with this library; if not, write to the >+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ * >+ * Author: Matthias Clasen >+ */ >+ >+#include "config.h" >+#include <errno.h> >+#include <pwd.h> >+#include <grp.h> >+#include <string.h> >+#include <sys/stat.h> >+#include <glib/gstdio.h> >+#include <gio/gio.h> >+#ifdef SESSION_TRACKING_SYSTEMD >+#include <systemd/sd-login.h> >+#endif >+#include <stdlib.h> >+ >+#include "nm-session-utils.h" >+#include "nm-session-monitor.h" >+#include "nm-logging.h" >+ >+#define CKDB_PATH "/var/run/ConsoleKit/database" >+ >+/********************************************************************/ >+ >+#ifdef SESSION_TRACKING_SYSTEMD >+typedef struct { >+ GSource source; >+ GPollFD pollfd; >+ sd_login_monitor *monitor; >+} SdSource; >+ >+static gboolean >+sd_source_prepare (GSource *source, gint *timeout) >+{ >+ *timeout = -1; >+ return FALSE; >+} >+ >+static gboolean >+sd_source_check (GSource *source) >+{ >+ SdSource *sd_source = (SdSource *) source; >+ >+ return sd_source->pollfd.revents != 0; >+} >+ >+static gboolean >+sd_source_dispatch (GSource *source, >+ GSourceFunc callback, >+ gpointer user_data) >+ >+{ >+ SdSource *sd_source = (SdSource *)source; >+ gboolean ret; >+ >+ g_warn_if_fail (callback != NULL); >+ ret = (*callback) (user_data); >+ sd_login_monitor_flush (sd_source->monitor); >+ return ret; >+} >+ >+static void >+sd_source_finalize (GSource *source) >+{ >+ SdSource *sd_source = (SdSource*) source; >+ >+ sd_login_monitor_unref (sd_source->monitor); >+} >+ >+static GSourceFuncs sd_source_funcs = { >+ sd_source_prepare, >+ sd_source_check, >+ sd_source_dispatch, >+ sd_source_finalize >+}; >+ >+static GSource * >+sd_source_new (void) >+{ >+ GSource *source; >+ SdSource *sd_source; >+ int ret; >+ >+ source = g_source_new (&sd_source_funcs, sizeof (SdSource)); >+ sd_source = (SdSource *)source; >+ >+ ret = sd_login_monitor_new (NULL, &sd_source->monitor); >+ if (ret < 0) >+ g_printerr ("Error getting login monitor: %d", ret); >+ else { >+ sd_source->pollfd.fd = sd_login_monitor_get_fd (sd_source->monitor); >+ sd_source->pollfd.events = G_IO_IN; >+ g_source_add_poll (source, &sd_source->pollfd); >+ } >+ >+ return source; >+} >+#endif /* SESSION_TRACKING_SYSTEMD */ >+ >+struct _NMSessionMonitor { >+ GObject parent_instance; >+ >+ GKeyFile *database; >+ GFileMonitor *database_monitor; >+ time_t database_mtime; >+ GHashTable *sessions_by_uid; >+ GHashTable *sessions_by_user; >+ >+ GSource *sd_source; >+}; >+ >+struct _NMSessionMonitorClass { >+ GObjectClass parent_class; >+ >+ void (*changed) (NMSessionMonitor *monitor); >+}; >+ >+ >+enum { >+ CHANGED_SIGNAL, >+ LAST_SIGNAL, >+}; >+static guint signals[LAST_SIGNAL] = {0}; >+ >+G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); >+ >+/* ---------------------------------------------------------------------------------------------------- */ >+ >+typedef struct { >+ char *user; >+ uid_t uid; >+ gboolean local; >+ gboolean active; >+} Session; >+ >+static void >+session_free (Session *s) >+{ >+ g_free (s->user); >+ memset (s, 0, sizeof (Session)); >+ g_free (s); >+} >+ >+static gboolean >+check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error) >+{ >+ if (g_key_file_has_key (keyfile, group, key, error)) >+ return TRUE; >+ >+ if (!error) { >+ g_set_error (error, >+ NM_SESSION_MONITOR_ERROR, >+ NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, >+ "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key", >+ group, key); >+ } >+ return FALSE; >+} >+ >+static Session * >+session_new (GKeyFile *keyfile, const char *group, GError **error) >+{ >+ GError *local = NULL; >+ Session *s; >+ const char *uname = NULL; >+ >+ s = g_new0 (Session, 1); >+ g_assert (s); >+ >+ s->uid = G_MAXUINT; /* paranoia */ >+ if (!check_key (keyfile, group, "uid", &local)) >+ goto error; >+ s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", &local); >+ if (local) >+ goto error; >+ >+ if (!check_key (keyfile, group, "is_active", &local)) >+ goto error; >+ s->active = g_key_file_get_boolean (keyfile, group, "is_active", &local); >+ if (local) >+ goto error; >+ >+ if (!check_key (keyfile, group, "is_local", &local)) >+ goto error; >+ s->local = g_key_file_get_boolean (keyfile, group, "is_local", &local); >+ if (local) >+ goto error; >+ >+ if (!nm_session_uid_to_user (s->uid, &uname, error)) >+ return FALSE; >+ s->user = g_strdup (uname); >+ >+ return s; >+ >+error: >+ session_free (s); >+ g_propagate_error (error, local); >+ return NULL; >+} >+ >+static void >+session_merge (Session *src, Session *dest) >+{ >+ g_return_if_fail (src != NULL); >+ g_return_if_fail (dest != NULL); >+ >+ g_warn_if_fail (g_strcmp0 (src->user, dest->user) == 0); >+ g_warn_if_fail (src->uid == dest->uid); >+ >+ dest->local = (dest->local || src->local); >+ dest->active = (dest->active || src->active); >+} >+ >+static void >+free_database (NMSessionMonitor *self) >+{ >+ if (self->database != NULL) { >+ g_key_file_free (self->database); >+ self->database = NULL; >+ } >+ >+ g_hash_table_remove_all (self->sessions_by_uid); >+ g_hash_table_remove_all (self->sessions_by_user); >+} >+ >+static gboolean >+reload_database (NMSessionMonitor *self, GError **error) >+{ >+ struct stat statbuf; >+ char **groups = NULL; >+ gsize len = 0, i; >+ Session *s; >+ >+ free_database (self); >+ >+ errno = 0; >+ if (stat (CKDB_PATH, &statbuf) != 0) { >+ g_set_error (error, >+ NM_SESSION_MONITOR_ERROR, >+ errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR, >+ "Error statting file " CKDB_PATH ": %s", >+ strerror (errno)); >+ goto error; >+ } >+ self->database_mtime = statbuf.st_mtime; >+ >+ self->database = g_key_file_new (); >+ if (!g_key_file_load_from_file (self->database, CKDB_PATH, G_KEY_FILE_NONE, error)) >+ goto error; >+ >+ groups = g_key_file_get_groups (self->database, &len); >+ if (!groups) { >+ g_set_error_literal (error, >+ NM_SESSION_MONITOR_ERROR, >+ NM_SESSION_MONITOR_ERROR_IO_ERROR, >+ "Could not load groups from " CKDB_PATH ""); >+ goto error; >+ } >+ >+ for (i = 0; i < len; i++) { >+ Session *found; >+ >+ if (!g_str_has_prefix (groups[i], "Session ")) >+ continue; >+ >+ s = session_new (self->database, groups[i], error); >+ if (!s) >+ goto error; >+ >+ found = g_hash_table_lookup (self->sessions_by_user, (gpointer) s->user); >+ if (found) { >+ session_merge (s, found); >+ session_free (s); >+ } else { >+ /* Entirely new user */ >+ g_hash_table_insert (self->sessions_by_user, (gpointer) s->user, s); >+ g_hash_table_insert (self->sessions_by_uid, GUINT_TO_POINTER (s->uid), s); >+ } >+ } >+ >+ g_strfreev (groups); >+ return TRUE; >+ >+error: >+ if (groups) >+ g_strfreev (groups); >+ free_database (self); >+ return FALSE; >+} >+ >+static gboolean >+ensure_database (NMSessionMonitor *self, GError **error) >+{ >+ gboolean ret = FALSE; >+ >+ if (self->database != NULL) { >+ struct stat statbuf; >+ >+ errno = 0; >+ if (stat (CKDB_PATH, &statbuf) != 0) { >+ g_set_error (error, >+ NM_SESSION_MONITOR_ERROR, >+ errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR, >+ "Error statting file " CKDB_PATH " to check timestamp: %s", >+ strerror (errno)); >+ goto out; >+ } >+ >+ if (statbuf.st_mtime == self->database_mtime) { >+ ret = TRUE; >+ goto out; >+ } >+ } >+ >+ ret = reload_database (self, error); >+ >+out: >+ return ret; >+} >+ >+static void >+on_file_monitor_changed (GFileMonitor * file_monitor, >+ GFile * file, >+ GFile * other_file, >+ GFileMonitorEvent event_type, >+ gpointer user_data) >+{ >+ NMSessionMonitor *self = NM_SESSION_MONITOR (user_data); >+ >+ /* throw away cache */ >+ free_database (self); >+ >+ g_signal_emit (self, signals[CHANGED_SIGNAL], 0); >+} >+ >+#ifdef SESSION_TRACKING_SYSTEMD >+static gboolean >+sessions_changed (gpointer user_data) >+{ >+ NMSessionMonitor *monitor = NM_SESSION_MONITOR (user_data); >+ >+ g_signal_emit (monitor, signals[CHANGED_SIGNAL], 0); >+ return TRUE; >+} >+#endif /* SESSION_TRACKING_SYSTEMD */ >+ >+ >+static void >+nm_session_monitor_init (NMSessionMonitor *monitor) >+{ >+ GError *error; >+ GFile *file; >+ >+ monitor->sd_source = NULL; >+ monitor->database = NULL; >+ monitor->database_monitor = NULL; >+ monitor->sessions_by_uid = NULL; >+ monitor->sessions_by_user = NULL; >+ >+#ifdef SESSION_TRACKING_SYSTEMD >+ if (LOGIND_RUNNING()) >+ { >+ monitor->sd_source = sd_source_new (); >+ g_source_set_callback (monitor->sd_source, sessions_changed, monitor, NULL); >+ g_source_attach (monitor->sd_source, NULL); >+ return; >+ } >+ /* fall through */ >+#endif /* SESSION_TRACKING_SYSTEMD */ >+ >+ error = NULL; >+ >+ /* Sessions-by-user is responsible for destroying the Session objects */ >+ monitor->sessions_by_user = g_hash_table_new_full (g_str_hash, g_str_equal, >+ NULL, (GDestroyNotify) session_free); >+ monitor->sessions_by_uid = g_hash_table_new (g_direct_hash, g_direct_equal); >+ >+ >+ error = NULL; >+ if (!ensure_database (monitor, &error)) { >+ /* Ignore the first error if the CK database isn't found yet */ >+ if (g_error_matches (error, >+ NM_SESSION_MONITOR_ERROR, >+ NM_SESSION_MONITOR_ERROR_NO_DATABASE) == FALSE) { >+ nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message); >+ } >+ g_error_free (error); >+ } >+ >+ error = NULL; >+ file = g_file_new_for_path (CKDB_PATH); >+ monitor->database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error); >+ g_object_unref (file); >+ if (monitor->database_monitor == NULL) { >+ nm_log_err (LOGD_CORE, "Error monitoring " CKDB_PATH ": %s", error->message); >+ g_error_free (error); >+ } else { >+ g_signal_connect (monitor->database_monitor, >+ "changed", >+ G_CALLBACK (on_file_monitor_changed), >+ monitor); >+ } >+} >+ >+static void >+nm_session_monitor_finalize (GObject *object) >+{ >+ NMSessionMonitor *monitor = NM_SESSION_MONITOR (object); >+ >+ if (monitor->sd_source != NULL) { >+ g_source_destroy (monitor->sd_source); >+ g_source_unref (monitor->sd_source); >+ } >+ >+ if (monitor->database_monitor != NULL) >+ g_object_unref (monitor->database_monitor); >+ >+ free_database (monitor); >+ >+ if (G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize != NULL) >+ G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object); >+} >+ >+static void >+nm_session_monitor_class_init (NMSessionMonitorClass *klass) >+{ >+ GObjectClass *gobject_class; >+ >+ gobject_class = G_OBJECT_CLASS (klass); >+ gobject_class->finalize = nm_session_monitor_finalize; >+ >+ /** >+ * NMSessionMonitor::changed: >+ * @monitor: A #NMSessionMonitor >+ * >+ * Emitted when something changes. >+ */ >+ signals[CHANGED_SIGNAL] = g_signal_new (NM_SESSION_MONITOR_CHANGED, >+ NM_TYPE_SESSION_MONITOR, >+ G_SIGNAL_RUN_LAST, >+ G_STRUCT_OFFSET (NMSessionMonitorClass, changed), >+ NULL, /* accumulator */ >+ NULL, /* accumulator data */ >+ g_cclosure_marshal_VOID__VOID, >+ G_TYPE_NONE, >+ 0); >+} >+ >+NMSessionMonitor * >+nm_session_monitor_get (void) >+{ >+ static NMSessionMonitor *singleton = NULL; >+ >+ if (singleton) >+ return g_object_ref (singleton); >+ >+ singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL)); >+ g_assert (singleton); >+ return singleton; >+} >+ >+gboolean >+nm_session_monitor_user_has_session (NMSessionMonitor *monitor, >+ const char *username, >+ uid_t *out_uid, >+ GError **error) >+{ >+#ifdef SESSION_TRACKING_SYSTEMD >+ if (LOGIND_RUNNING()) >+ { >+ uid_t uid; >+ >+ if (!nm_session_user_to_uid (username, &uid, error)) >+ return FALSE; >+ >+ if (out_uid) >+ *out_uid = uid; >+ >+ return nm_session_monitor_uid_has_session (monitor, uid, NULL, error); >+ } >+ /* fall through */ >+#endif /* SESSION_TRACKING_SYSTEMD */ >+ >+ Session *s; >+ >+ if (!ensure_database (monitor, error)) >+ return FALSE; >+ >+ s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); >+ if (!s) { >+ g_set_error (error, >+ NM_SESSION_MONITOR_ERROR, >+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, >+ "No session found for user '%s'", >+ username); >+ return FALSE; >+ } >+ >+ if (out_uid) >+ *out_uid = s->uid; >+ return TRUE; >+} >+ >+gboolean >+nm_session_monitor_user_active (NMSessionMonitor *monitor, >+ const char *username, >+ GError **error) >+{ >+#ifdef SESSION_TRACKING_SYSTEMD >+ if (LOGIND_RUNNING()) >+ { >+ uid_t uid; >+ >+ if (!nm_session_user_to_uid (username, &uid, error)) >+ return FALSE; >+ >+ return nm_session_monitor_uid_active (monitor, uid, error); >+ } >+ /* fall through */ >+#endif >+ >+ Session *s; >+ >+ if (!ensure_database (monitor, error)) >+ return FALSE; >+ >+ s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); >+ if (!s) { >+ g_set_error (error, >+ NM_SESSION_MONITOR_ERROR, >+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, >+ "No session found for user '%s'", >+ username); >+ return FALSE; >+ } >+ >+ return s->active; >+} >+ >+gboolean >+nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, >+ uid_t uid, >+ const char **out_user, >+ GError **error) >+{ >+#ifdef SESSION_TRACKING_SYSTEMD >+ if (LOGIND_RUNNING()) >+ { >+ int ret; >+ >+ if (!nm_session_uid_to_user (uid, out_user, error)) >+ return FALSE; >+ >+ ret = sd_uid_get_sessions (uid, FALSE, NULL) > 0; >+ if (ret < 0) { >+ nm_log_warn (LOGD_CORE, "Failed to get systemd sessions for uid %d: %d", >+ uid, ret); >+ return FALSE; >+ } >+ return ret > 0 ? TRUE : FALSE; >+ } >+ /* fall through */ >+#endif >+ >+ Session *s; >+ >+ if (!ensure_database (monitor, error)) >+ return FALSE; >+ >+ s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); >+ if (!s) { >+ g_set_error (error, >+ NM_SESSION_MONITOR_ERROR, >+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, >+ "No session found for uid %d", >+ uid); >+ return FALSE; >+ } >+ >+ if (out_user) >+ *out_user = s->user; >+ return TRUE; >+} >+ >+gboolean >+nm_session_monitor_uid_active (NMSessionMonitor *monitor, >+ uid_t uid, >+ GError **error) >+{ >+#ifdef SESSION_TRACKING_SYSTEMD >+ if (LOGIND_RUNNING()) >+ { >+ int ret; >+ >+ ret = sd_uid_get_sessions (uid, TRUE, NULL) > 0; >+ if (ret < 0) { >+ nm_log_warn (LOGD_CORE, "Failed to get active systemd sessions for uid %d: %d", >+ uid, ret); >+ return FALSE; >+ } >+ return ret > 0 ? TRUE : FALSE; >+ } >+ /* fall through */ >+#endif >+ >+ Session *s; >+ >+ if (!ensure_database (monitor, error)) >+ return FALSE; >+ >+ s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); >+ if (!s) { >+ g_set_error (error, >+ NM_SESSION_MONITOR_ERROR, >+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, >+ "No session found for uid '%d'", >+ uid); >+ return FALSE; >+ } >+ >+ return s->active; >+} >diff --git a/src/nm-session-monitor.h b/src/nm-session-monitor.h >index 77ea9a0..ac3dec5 100644 >--- a/src/nm-session-monitor.h >+++ b/src/nm-session-monitor.h >@@ -21,6 +21,7 @@ > #ifndef NM_SESSION_MONITOR_H > #define NM_SESSION_MONITOR_H > >+#include <unistd.h> > #include <glib-object.h> > > G_BEGIN_DECLS >@@ -34,6 +35,11 @@ G_BEGIN_DECLS > > #define NM_SESSION_MONITOR_CHANGED "changed" > >+/* check if logind is running >+ * thanks to: https://bugzilla.gnome.org/show_bug.cgi?id=696266 >+ */ >+#define LOGIND_RUNNING() (access("/run/systemd/seats/", F_OK) >= 0) >+ > typedef struct _NMSessionMonitor NMSessionMonitor; > typedef struct _NMSessionMonitorClass NMSessionMonitorClass; > >-- >1.8.2.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 468930
: 347630 |
347632