~ubuntu-branches/ubuntu/raring/gnome-session/raring

« back to all changes in this revision

Viewing changes to gnome-session/gsm-systemd.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2012-07-29 16:22:23 UTC
  • mfrom: (1.1.78)
  • Revision ID: package-import@ubuntu.com-20120729162223-zvvdhbwa7s8r0zdx
Tags: 3.5.4-0ubuntu1
* New upstream release
* debian/control:
  - Bump build-depends on libglib2.0-dev
* debian/patches/21_up_start_on_demand.patch:
  - Dropped, code has changed too much

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include <sys/types.h>
33
33
#include <pwd.h>
34
34
 
35
 
#include <polkit/polkit.h>
36
35
#include <systemd/sd-login.h>
37
36
#include <systemd/sd-daemon.h>
38
37
 
40
39
#include <glib-object.h>
41
40
#include <glib/gi18n.h>
42
41
#include <gio/gio.h>
 
42
#include <gio/gunixfdlist.h>
43
43
 
44
44
#include "gsm-marshal.h"
45
45
#include "gsm-system.h"
55
55
        GDBusProxy      *sd_proxy;
56
56
        gchar           *session_id;
57
57
        gchar           *session_path;
58
 
        PolkitAuthority *authority;
59
 
        PolkitSubject   *subject;
 
58
 
 
59
        GSList          *inhibitors;
 
60
        gint             inhibit_fd;
60
61
};
61
62
 
62
63
static void gsm_systemd_system_init (GsmSystemInterface *iface);
72
73
        GsmSystemd *systemd = GSM_SYSTEMD (object);
73
74
 
74
75
        g_clear_object (&systemd->priv->sd_proxy);
75
 
        g_clear_object (&systemd->priv->authority);
76
 
        g_clear_object (&systemd->priv->subject);
77
76
        g_free (systemd->priv->session_id);
78
77
        g_free (systemd->priv->session_path);
79
78
 
 
79
        if (systemd->priv->inhibitors != NULL) {
 
80
                g_slist_free_full (systemd->priv->inhibitors, g_free);
 
81
                close (systemd->priv->inhibit_fd);
 
82
        }
 
83
 
80
84
        G_OBJECT_CLASS (gsm_systemd_parent_class)->finalize (object);
81
85
}
82
86
 
130
134
                g_object_unref (bus);
131
135
        }
132
136
 
133
 
        manager->priv->authority = polkit_authority_get_sync (NULL, NULL);
134
 
        manager->priv->subject = polkit_unix_session_new_for_process_sync (getpid (), NULL, NULL);
135
 
 
136
137
        sd_pid_get_session (getpid (), &manager->priv->session_id);
137
138
 
138
139
        res = g_dbus_proxy_call_sync (manager->priv->sd_proxy,
303
304
gsm_systemd_can_restart (GsmSystem *system)
304
305
{
305
306
        GsmSystemd *manager = GSM_SYSTEMD (system);
306
 
        PolkitAuthorizationResult *res;
 
307
        gchar *rv;
 
308
        GVariant *res;
307
309
        gboolean can_restart;
308
310
 
309
 
        res = polkit_authority_check_authorization_sync (manager->priv->authority,
310
 
                                                         manager->priv->subject,
311
 
                                                         "org.freedesktop.login1.reboot",
312
 
                                                         NULL,
313
 
                                                         POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
314
 
                                                         NULL,
315
 
                                                         NULL);
316
 
        if (res == NULL) {
317
 
                return FALSE;
318
 
        }
319
 
 
320
 
        can_restart = polkit_authorization_result_get_is_authorized (res) ||
321
 
                      polkit_authorization_result_get_is_challenge (res);
322
 
 
323
 
        g_object_unref (res);
 
311
        res = g_dbus_proxy_call_sync (manager->priv->sd_proxy,
 
312
                                      "CanReboot",
 
313
                                      NULL,
 
314
                                      0,
 
315
                                      G_MAXINT,
 
316
                                      NULL,
 
317
                                      NULL);
 
318
        g_variant_get (res, "(s)", &rv);
 
319
        g_variant_unref (res);
 
320
 
 
321
        can_restart = g_strcmp0 (rv, "yes") == 0 ||
 
322
                      g_strcmp0 (rv, "challenge") == 0;
 
323
 
 
324
        g_free (rv);
324
325
 
325
326
        return can_restart;
326
327
}
329
330
gsm_systemd_can_stop (GsmSystem *system)
330
331
{
331
332
        GsmSystemd *manager = GSM_SYSTEMD (system);
332
 
        PolkitAuthorizationResult *res;
 
333
        gchar *rv;
 
334
        GVariant *res;
333
335
        gboolean can_stop;
334
336
 
335
 
        res = polkit_authority_check_authorization_sync (manager->priv->authority,
336
 
                                                         manager->priv->subject,
337
 
                                                         "org.freedesktop.login1.power-off",
338
 
                                                         NULL,
339
 
                                                         POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
340
 
                                                         NULL,
341
 
                                                         NULL);
342
 
        if (res == NULL) {
343
 
                return FALSE;
344
 
        }
345
 
 
346
 
        can_stop = polkit_authorization_result_get_is_authorized (res) ||
347
 
                   polkit_authorization_result_get_is_challenge (res);
348
 
 
349
 
        g_object_unref (res);
 
337
        res = g_dbus_proxy_call_sync (manager->priv->sd_proxy,
 
338
                                      "CanPowerOff",
 
339
                                      NULL,
 
340
                                      0,
 
341
                                      G_MAXINT,
 
342
                                      NULL,
 
343
                                      NULL);
 
344
        g_variant_get (res, "(s)", &rv);
 
345
        g_variant_unref (res);
 
346
 
 
347
        can_stop = g_strcmp0 (rv, "yes") == 0 ||
 
348
                   g_strcmp0 (rv, "challenge") == 0;
 
349
 
 
350
        g_free (rv);
350
351
 
351
352
        return can_stop;
352
353
}
372
373
        return ret;
373
374
}
374
375
 
 
376
static gboolean
 
377
gsm_systemd_can_suspend (GsmSystem *system)
 
378
{
 
379
        GsmSystemd *manager = GSM_SYSTEMD (system);
 
380
        gchar *rv;
 
381
        GVariant *res;
 
382
        gboolean can_suspend;
 
383
 
 
384
        res = g_dbus_proxy_call_sync (manager->priv->sd_proxy,
 
385
                                      "CanSuspend",
 
386
                                      NULL,
 
387
                                      0,
 
388
                                      G_MAXINT,
 
389
                                      NULL,
 
390
                                      NULL);
 
391
        g_variant_get (res, "(s)", &rv);
 
392
        g_variant_unref (res);
 
393
 
 
394
        can_suspend = g_strcmp0 (rv, "yes") == 0 ||
 
395
                      g_strcmp0 (rv, "challenge") == 0;
 
396
 
 
397
        g_free (rv);
 
398
 
 
399
        return can_suspend;
 
400
}
 
401
 
 
402
static gboolean
 
403
gsm_systemd_can_hibernate (GsmSystem *system)
 
404
{
 
405
        GsmSystemd *manager = GSM_SYSTEMD (system);
 
406
        gchar *rv;
 
407
        GVariant *res;
 
408
        gboolean can_hibernate;
 
409
 
 
410
        res = g_dbus_proxy_call_sync (manager->priv->sd_proxy,
 
411
                                      "CanHibernate",
 
412
                                      NULL,
 
413
                                      0,
 
414
                                      G_MAXINT,
 
415
                                      NULL,
 
416
                                      NULL);
 
417
        g_variant_get (res, "(s)", &rv);
 
418
        g_variant_unref (res);
 
419
 
 
420
        can_hibernate = g_strcmp0 (rv, "yes") == 0 ||
 
421
                        g_strcmp0 (rv, "challenge") == 0;
 
422
 
 
423
        g_free (rv);
 
424
 
 
425
        return can_hibernate;
 
426
}
 
427
 
 
428
static void
 
429
suspend_done (GObject      *source,
 
430
              GAsyncResult *result,
 
431
              gpointer      user_data)
 
432
{
 
433
        GDBusProxy *proxy = G_DBUS_PROXY (source);
 
434
        GError *error = NULL;
 
435
        GVariant *res;
 
436
 
 
437
        res = g_dbus_proxy_call_finish (proxy, result, &error);
 
438
 
 
439
        if (!res) {
 
440
                g_warning ("Unable to suspend system: %s", error->message);
 
441
                g_error_free (error);
 
442
        } else {
 
443
                g_variant_unref (res);
 
444
        }
 
445
}
 
446
 
 
447
static void
 
448
hibernate_done (GObject      *source,
 
449
                GAsyncResult *result,
 
450
              gpointer      user_data)
 
451
{
 
452
        GDBusProxy *proxy = G_DBUS_PROXY (source);
 
453
        GError *error = NULL;
 
454
        GVariant *res;
 
455
 
 
456
        res = g_dbus_proxy_call_finish (proxy, result, &error);
 
457
 
 
458
        if (!res) {
 
459
                g_warning ("Unable to hibernate system: %s", error->message);
 
460
                g_error_free (error);
 
461
        } else {
 
462
                g_variant_unref (res);
 
463
        }
 
464
}
 
465
 
 
466
static void
 
467
gsm_systemd_suspend (GsmSystem *system)
 
468
{
 
469
        GsmSystemd *manager = GSM_SYSTEMD (system);
 
470
 
 
471
        g_dbus_proxy_call (manager->priv->sd_proxy,
 
472
                           "Suspend",
 
473
                           g_variant_new ("(b)", TRUE),
 
474
                           0,
 
475
                           G_MAXINT,
 
476
                           NULL,
 
477
                           hibernate_done,
 
478
                           manager);
 
479
}
 
480
 
 
481
static void
 
482
gsm_systemd_hibernate (GsmSystem *system)
 
483
{
 
484
        GsmSystemd *manager = GSM_SYSTEMD (system);
 
485
 
 
486
        g_dbus_proxy_call (manager->priv->sd_proxy,
 
487
                           "Hibernate",
 
488
                           g_variant_new ("(b)", TRUE),
 
489
                           0,
 
490
                           G_MAXINT,
 
491
                           NULL,
 
492
                           suspend_done,
 
493
                           manager);
 
494
}
 
495
 
 
496
static void
 
497
inhibit_done (GObject      *source,
 
498
              GAsyncResult *result,
 
499
              gpointer      user_data)
 
500
{
 
501
        GDBusProxy *proxy = G_DBUS_PROXY (source);
 
502
        GsmSystemd *manager = GSM_SYSTEMD (user_data);
 
503
        GError *error = NULL;
 
504
        GVariant *res;
 
505
        GUnixFDList *fd_list = NULL;
 
506
        gint idx;
 
507
 
 
508
        res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error);
 
509
 
 
510
        if (!res) {
 
511
                g_warning ("Unable to inhibit system: %s", error->message);
 
512
                g_error_free (error);
 
513
        } else {
 
514
                g_variant_get (res, "(h)", &idx);
 
515
                manager->priv->inhibit_fd = g_unix_fd_list_get (fd_list, idx, &error);
 
516
                if (manager->priv->inhibit_fd == -1) {
 
517
                        g_warning ("Failed to receive system inhibitor fd: %s", error->message);
 
518
                        g_error_free (error);
 
519
                }
 
520
                g_debug ("System inhibitor fd is %d", manager->priv->inhibit_fd);
 
521
                g_object_unref (fd_list);
 
522
                g_variant_unref (res);
 
523
        }
 
524
}
 
525
 
 
526
static void
 
527
gsm_systemd_add_inhibitor (GsmSystem        *system,
 
528
                           const gchar      *id,
 
529
                           GsmInhibitorFlag  flag)
 
530
{
 
531
        GsmSystemd *manager = GSM_SYSTEMD (system);
 
532
 
 
533
        if ((flag & GSM_INHIBITOR_FLAG_SUSPEND) == 0)
 
534
                return;
 
535
 
 
536
        if (manager->priv->inhibitors == NULL) {
 
537
                g_debug ("Adding system inhibitor");
 
538
                g_dbus_proxy_call_with_unix_fd_list (manager->priv->sd_proxy,
 
539
                                                     "Inhibit",
 
540
                                                     g_variant_new ("(ssss)",
 
541
                                                                    "sleep:shutdown",
 
542
                                                                    g_get_user_name (),
 
543
                                                                    "user session inhibited",
 
544
                                                                    "block"),
 
545
                                                     0,
 
546
                                                     G_MAXINT,
 
547
                                                     NULL,
 
548
                                                     NULL,
 
549
                                                     inhibit_done,
 
550
                                                     manager);
 
551
        }
 
552
        manager->priv->inhibitors = g_slist_prepend (manager->priv->inhibitors, g_strdup (id));
 
553
}
 
554
 
 
555
static void
 
556
gsm_systemd_remove_inhibitor (GsmSystem   *system,
 
557
                              const gchar *id)
 
558
{
 
559
        GsmSystemd *manager = GSM_SYSTEMD (system);
 
560
        GSList *l;
 
561
 
 
562
        l = g_slist_find_custom (manager->priv->inhibitors, id, (GCompareFunc)g_strcmp0);
 
563
        if (l == NULL)
 
564
                return;
 
565
 
 
566
        g_free (l->data);
 
567
        manager->priv->inhibitors = g_slist_delete_link (manager->priv->inhibitors, l);
 
568
        if (manager->priv->inhibitors == NULL) {
 
569
                        g_debug ("Dropping system inhibitor");
 
570
                        close (manager->priv->inhibit_fd);
 
571
                        manager->priv->inhibit_fd = -1;
 
572
        }
 
573
}
 
574
 
375
575
static void
376
576
gsm_systemd_system_init (GsmSystemInterface *iface)
377
577
{
378
578
        iface->can_switch_user = gsm_systemd_can_switch_user;
379
579
        iface->can_stop = gsm_systemd_can_stop;
380
580
        iface->can_restart = gsm_systemd_can_restart;
 
581
        iface->can_suspend = gsm_systemd_can_suspend;
 
582
        iface->can_hibernate = gsm_systemd_can_hibernate;
381
583
        iface->attempt_stop = gsm_systemd_attempt_stop;
382
584
        iface->attempt_restart = gsm_systemd_attempt_restart;
 
585
        iface->suspend = gsm_systemd_suspend;
 
586
        iface->hibernate = gsm_systemd_hibernate;
383
587
        iface->set_session_idle = gsm_systemd_set_session_idle;
384
588
        iface->is_login_session = gsm_systemd_is_login_session;
 
589
        iface->add_inhibitor = gsm_systemd_add_inhibitor;
 
590
        iface->remove_inhibitor = gsm_systemd_remove_inhibitor;
385
591
}
386
592
 
387
593
GsmSystemd *