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