]> git.pld-linux.org Git - packages/NetworkManager.git/blame - systemd-fallback.patch
- do not bcond patch sources
[packages/NetworkManager.git] / systemd-fallback.patch
CommitLineData
b761b8be
ŁK
1diff -u -Nr NetworkManager-0.9.3.995/configure.ac NetworkManager-0.9.3.995-systemd-fallback/configure.ac
2--- NetworkManager-0.9.3.995/configure.ac 2012-03-02 01:05:21.000000000 +0100
3+++ NetworkManager-0.9.3.995-systemd-fallback/configure.ac 2012-03-06 16:55:58.294793902 +0100
4@@ -344,7 +344,7 @@
5 case $with_session_tracking in
6 ck|none) ;;
7 systemd)
8- PKG_CHECK_MODULES(SYSTEMD, [libsystemd-login])
9+ PKG_CHECK_MODULES(SYSTEMD, [libsystemd-daemon libsystemd-login])
10 ;;
11 *)
12 AC_MSG_ERROR(--with-session-tracking must be one of [none, ck, systemd])
13diff -u -Nr NetworkManager-0.9.3.995/src/nm-session-monitor-systemd.c NetworkManager-0.9.3.995-systemd-fallback/src/nm-session-monitor-systemd.c
14--- NetworkManager-0.9.3.995/src/nm-session-monitor-systemd.c 2012-02-27 16:57:16.000000000 +0100
15+++ NetworkManager-0.9.3.995-systemd-fallback/src/nm-session-monitor-systemd.c 2012-03-06 16:55:01.285264295 +0100
16@@ -28,6 +28,10 @@
17 #include <glib/gstdio.h>
18 #include <systemd/sd-login.h>
19 #include <stdlib.h>
20+#include <systemd/sd-daemon.h>
21+#include <sys/stat.h>
22+#include <gio/gio.h>
23+#include "nm-logging.h"
24
25 #include "nm-session-utils.h"
26 #include "nm-session-monitor.h"
27@@ -107,10 +111,20 @@
28 return source;
29 }
30
31+/********************************************************************/
32+
33+#define CKDB_PATH "/var/run/ConsoleKit/database"
34+
35 struct _NMSessionMonitor {
36 GObject parent_instance;
37
38 GSource *sd_source;
39+
40+ GKeyFile *database;
41+ GFileMonitor *database_monitor;
42+ time_t database_mtime;
43+ GHashTable *sessions_by_uid;
44+ GHashTable *sessions_by_user;
45 };
46
47 struct _NMSessionMonitorClass {
48@@ -130,6 +144,215 @@
49
50 /* ---------------------------------------------------------------------------------------------------- */
51
52+typedef struct {
53+ char *user;
54+ uid_t uid;
55+ gboolean local;
56+ gboolean active;
57+} Session;
58+
59+static void
60+session_free (Session *s)
61+{
62+ g_free (s->user);
63+ memset (s, 0, sizeof (Session));
64+ g_free (s);
65+}
66+
67+static gboolean
68+check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error)
69+{
70+ if (g_key_file_has_key (keyfile, group, key, error))
71+ return TRUE;
72+
73+ if (!error) {
74+ g_set_error (error,
75+ NM_SESSION_MONITOR_ERROR,
76+ NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE,
77+ "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key",
78+ group, key);
79+ }
80+ return FALSE;
81+}
82+
83+static Session *
84+session_new (GKeyFile *keyfile, const char *group, GError **error)
85+{
86+ GError *local = NULL;
87+ Session *s;
88+ const char *uname = NULL;
89+
90+ s = g_new0 (Session, 1);
91+ g_assert (s);
92+
93+ s->uid = G_MAXUINT; /* paranoia */
94+ if (!check_key (keyfile, group, "uid", &local))
95+ goto error;
96+ s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", &local);
97+ if (local)
98+ goto error;
99+
100+ if (!check_key (keyfile, group, "is_active", &local))
101+ goto error;
102+ s->active = g_key_file_get_boolean (keyfile, group, "is_active", &local);
103+ if (local)
104+ goto error;
105+
106+ if (!check_key (keyfile, group, "is_local", &local))
107+ goto error;
108+ s->local = g_key_file_get_boolean (keyfile, group, "is_local", &local);
109+ if (local)
110+ goto error;
111+
112+ if (!nm_session_uid_to_user (s->uid, &uname, error))
113+ return FALSE;
114+ s->user = g_strdup (uname);
115+
116+ return s;
117+
118+error:
119+ session_free (s);
120+ g_propagate_error (error, local);
121+ return NULL;
122+}
123+
124+static void
125+session_merge (Session *src, Session *dest)
126+{
127+ g_return_if_fail (src != NULL);
128+ g_return_if_fail (dest != NULL);
129+
130+ g_warn_if_fail (g_strcmp0 (src->user, dest->user) == 0);
131+ g_warn_if_fail (src->uid == dest->uid);
132+
133+ dest->local = (dest->local || src->local);
134+ dest->active = (dest->active || src->active);
135+}
136+
137+/********************************************************************/
138+
139+static void
140+free_database (NMSessionMonitor *self)
141+{
142+ if (self->database != NULL) {
143+ g_key_file_free (self->database);
144+ self->database = NULL;
145+ }
146+
147+ g_hash_table_remove_all (self->sessions_by_uid);
148+ g_hash_table_remove_all (self->sessions_by_user);
149+}
150+
151+static gboolean
152+reload_database (NMSessionMonitor *self, GError **error)
153+{
154+ struct stat statbuf;
155+ char **groups = NULL;
156+ gsize len = 0, i;
157+ Session *s;
158+
159+ free_database (self);
160+
161+ errno = 0;
162+ if (stat (CKDB_PATH, &statbuf) != 0) {
163+ g_set_error (error,
164+ NM_SESSION_MONITOR_ERROR,
165+ errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR,
166+ "Error statting file " CKDB_PATH ": %s",
167+ strerror (errno));
168+ goto error;
169+ }
170+ self->database_mtime = statbuf.st_mtime;
171+
172+ self->database = g_key_file_new ();
173+ if (!g_key_file_load_from_file (self->database, CKDB_PATH, G_KEY_FILE_NONE, error))
174+ goto error;
175+
176+ groups = g_key_file_get_groups (self->database, &len);
177+ if (!groups) {
178+ g_set_error_literal (error,
179+ NM_SESSION_MONITOR_ERROR,
180+ NM_SESSION_MONITOR_ERROR_IO_ERROR,
181+ "Could not load groups from " CKDB_PATH "");
182+ goto error;
183+ }
184+
185+ for (i = 0; i < len; i++) {
186+ Session *found;
187+
188+ if (!g_str_has_prefix (groups[i], "Session "))
189+ continue;
190+
191+ s = session_new (self->database, groups[i], error);
192+ if (!s)
193+ goto error;
194+
195+ found = g_hash_table_lookup (self->sessions_by_user, (gpointer) s->user);
196+ if (found) {
197+ session_merge (s, found);
198+ session_free (s);
199+ } else {
200+ /* Entirely new user */
201+ g_hash_table_insert (self->sessions_by_user, (gpointer) s->user, s);
202+ g_hash_table_insert (self->sessions_by_uid, GUINT_TO_POINTER (s->uid), s);
203+ }
204+ }
205+
206+ g_strfreev (groups);
207+ return TRUE;
208+
209+error:
210+ if (groups)
211+ g_strfreev (groups);
212+ free_database (self);
213+ return FALSE;
214+}
215+
216+static gboolean
217+ensure_database (NMSessionMonitor *self, GError **error)
218+{
219+ gboolean ret = FALSE;
220+
221+ if (self->database != NULL) {
222+ struct stat statbuf;
223+
224+ errno = 0;
225+ if (stat (CKDB_PATH, &statbuf) != 0) {
226+ g_set_error (error,
227+ NM_SESSION_MONITOR_ERROR,
228+ errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR,
229+ "Error statting file " CKDB_PATH " to check timestamp: %s",
230+ strerror (errno));
231+ goto out;
232+ }
233+
234+ if (statbuf.st_mtime == self->database_mtime) {
235+ ret = TRUE;
236+ goto out;
237+ }
238+ }
239+
240+ ret = reload_database (self, error);
241+
242+out:
243+ return ret;
244+}
245+
246+static void
247+on_file_monitor_changed (GFileMonitor * file_monitor,
248+ GFile * file,
249+ GFile * other_file,
250+ GFileMonitorEvent event_type,
251+ gpointer user_data)
252+{
253+ NMSessionMonitor *self = NM_SESSION_MONITOR (user_data);
254+
255+ /* throw away cache */
256+ free_database (self);
257+
258+ g_signal_emit (self, signals[CHANGED_SIGNAL], 0);
259+}
260+
261 static gboolean
262 sessions_changed (gpointer user_data)
263 {
264@@ -143,9 +366,50 @@
265 static void
266 nm_session_monitor_init (NMSessionMonitor *monitor)
267 {
268- monitor->sd_source = sd_source_new ();
269- g_source_set_callback (monitor->sd_source, sessions_changed, monitor, NULL);
270- g_source_attach (monitor->sd_source, NULL);
271+ if (sd_booted () > 0) {
272+ monitor->sd_source = sd_source_new ();
273+ g_source_set_callback (monitor->sd_source, sessions_changed, monitor, NULL);
274+ g_source_attach (monitor->sd_source, NULL);
275+
276+ monitor->database_monitor = NULL;
277+ monitor->database = NULL;
278+ } else {
279+ monitor->sd_source = NULL;
280+
281+ GError *error = NULL;
282+ GFile *file;
283+
284+ /* Sessions-by-user is responsible for destroying the Session objects */
285+ monitor->sessions_by_user = g_hash_table_new_full (g_str_hash, g_str_equal,
286+ NULL, (GDestroyNotify) session_free);
287+ monitor->sessions_by_uid = g_hash_table_new (g_direct_hash, g_direct_equal);
288+
289+
290+ error = NULL;
291+ if (!ensure_database (monitor, &error)) {
292+ /* Ignore the first error if the CK database isn't found yet */
293+ if (g_error_matches (error,
294+ NM_SESSION_MONITOR_ERROR,
295+ NM_SESSION_MONITOR_ERROR_NO_DATABASE) == FALSE) {
296+ nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message);
297+ }
298+ g_error_free (error);
299+ }
300+
301+ error = NULL;
302+ file = g_file_new_for_path (CKDB_PATH);
303+ monitor->database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
304+ g_object_unref (file);
305+ if (monitor->database_monitor == NULL) {
306+ nm_log_err (LOGD_CORE, "Error monitoring " CKDB_PATH ": %s", error->message);
307+ g_error_free (error);
308+ } else {
309+ g_signal_connect (monitor->database_monitor,
310+ "changed",
311+ G_CALLBACK (on_file_monitor_changed),
312+ monitor);
313+ }
314+ }
315 }
316
317 static void
318@@ -158,6 +422,12 @@
319 g_source_unref (monitor->sd_source);
320 }
321
322+ if (monitor->database_monitor != NULL)
323+ g_object_unref (monitor->database_monitor);
324+
325+ if (monitor->database != NULL)
326+ free_database (monitor);
327+
328 if (G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize != NULL)
329 G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object);
330 }
331@@ -206,15 +476,36 @@
332 uid_t *out_uid,
333 GError **error)
334 {
335- uid_t uid;
336+ if (monitor->sd_source != NULL) {
337+ uid_t uid;
338
339- if (!nm_session_user_to_uid (username, &uid, error))
340- return FALSE;
341+ if (!nm_session_user_to_uid (username, &uid, error))
342+ return FALSE;
343
344- if (out_uid)
345- *out_uid = uid;
346+ if (out_uid)
347+ *out_uid = uid;
348
349- return nm_session_monitor_uid_has_session (monitor, uid, NULL, error);
350+ return nm_session_monitor_uid_has_session (monitor, uid, NULL, error);
351+ } else {
352+ Session *s;
353+
354+ if (!ensure_database (monitor, error))
355+ return FALSE;
356+
357+ s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username);
358+ if (!s) {
359+ g_set_error (error,
360+ NM_SESSION_MONITOR_ERROR,
361+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
362+ "No session found for user '%s'",
363+ username);
364+ return FALSE;
365+ }
366+
367+ if (out_uid)
368+ *out_uid = s->uid;
369+ return TRUE;
370+ }
371 }
372
373 gboolean
374@@ -222,12 +513,31 @@
375 const char *username,
376 GError **error)
377 {
378- uid_t uid;
379+ if (monitor->sd_source != NULL) {
380+ uid_t uid;
381
382- if (!nm_session_user_to_uid (username, &uid, error))
383- return FALSE;
384+ if (!nm_session_user_to_uid (username, &uid, error))
385+ return FALSE;
386+
387+ return nm_session_monitor_uid_active (monitor, uid, error);
388+ } else {
389+ Session *s;
390+
391+ if (!ensure_database (monitor, error))
392+ return FALSE;
393+
394+ s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username);
395+ if (!s) {
396+ g_set_error (error,
397+ NM_SESSION_MONITOR_ERROR,
398+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
399+ "No session found for user '%s'",
400+ username);
401+ return FALSE;
402+ }
403
404- return nm_session_monitor_uid_active (monitor, uid, error);
405+ return s->active;
406+ }
407 }
408
409 gboolean
410@@ -236,10 +546,31 @@
411 const char **out_user,
412 GError **error)
413 {
414- if (!nm_session_uid_to_user (uid, out_user, error))
415- return FALSE;
416+ if (monitor->sd_source != NULL) {
417+ if (!nm_session_uid_to_user (uid, out_user, error))
418+ return FALSE;
419
420- return sd_uid_get_sessions (uid, FALSE, NULL) > 0;
421+ return sd_uid_get_sessions (uid, FALSE, NULL) > 0;
422+ } else {
423+ Session *s;
424+
425+ if (!ensure_database (monitor, error))
426+ return FALSE;
427+
428+ s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid));
429+ if (!s) {
430+ g_set_error (error,
431+ NM_SESSION_MONITOR_ERROR,
432+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
433+ "No session found for uid %d",
434+ uid);
435+ return FALSE;
436+ }
437+
438+ if (out_user)
439+ *out_user = s->user;
440+ return TRUE;
441+ }
442 }
443
444 gboolean
445@@ -247,5 +578,24 @@
446 uid_t uid,
447 GError **error)
448 {
449- return sd_uid_get_sessions (uid, TRUE, NULL) > 0;
450+ if (monitor->sd_source != NULL)
451+ return sd_uid_get_sessions (uid, TRUE, NULL) > 0;
452+ else {
453+ Session *s;
454+
455+ if (!ensure_database (monitor, error))
456+ return FALSE;
457+
458+ s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid));
459+ if (!s) {
460+ g_set_error (error,
461+ NM_SESSION_MONITOR_ERROR,
462+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
463+ "No session found for uid '%d'",
464+ uid);
465+ return FALSE;
466+ }
467+
468+ return s->active;
469+ }
470 }
This page took 0.102378 seconds and 4 git commands to generate.