~darkxst/ubuntu/saucy/gdm/lp1212408

« back to all changes in this revision

Viewing changes to .pc/00git_logind_check.patch/utils/gdmflexiserver.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha, Tim Lunn, Jeremy Bicha, Robert Ancell
  • Date: 2013-05-31 22:36:08 UTC
  • mfrom: (1.4.55)
  • Revision ID: package-import@ubuntu.com-20130531223608-33uo85niksee5460
Tags: 3.8.1.1-0ubuntu1
[ Tim Lunn ]
* New upstream release
* debian/patches/ubuntu_dont_catch_sigsegv.patch:
  - Dropped, obsolete
* debian/rules:
  - Don't rename gdm binary since that's already been
    done in the new version

[ Jeremy Bicha ]
* debian/control.in: Bump minimum glib
* debian/watch: Watch for unstable releases
* debian/patches/00git_logind_check.patch:
  - Dropped, applied in new release
* debian/patches/08_frequent-users_greeter.patch: Refreshed

[ Robert Ancell ]
* New upstream release
* debian/patches/ubuntu_daemon_autologin_tracking.patch:
* debian/patches/ubuntu_ensure_dirs.patch:
* debian/patches/ubuntu_slave-only-set-up-autologin.patch:
  - Applied upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2
 
 *
3
 
 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 
 *
19
 
 */
20
 
 
21
 
#include "config.h"
22
 
 
23
 
#include <stdlib.h>
24
 
#include <stdio.h>
25
 
#include <unistd.h>
26
 
#include <string.h>
27
 
#include <locale.h>
28
 
 
29
 
#include <glib/gi18n.h>
30
 
#include <gtk/gtk.h>
31
 
 
32
 
#ifdef WITH_SYSTEMD
33
 
#include <systemd/sd-daemon.h>
34
 
#include <systemd/sd-login.h>
35
 
#endif
36
 
 
37
 
#define GDM_DBUS_NAME                            "org.gnome.DisplayManager"
38
 
#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH      "/org/gnome/DisplayManager/LocalDisplayFactory"
39
 
#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory"
40
 
 
41
 
#ifdef WITH_CONSOLE_KIT
42
 
#define CK_NAME      "org.freedesktop.ConsoleKit"
43
 
#define CK_PATH      "/org/freedesktop/ConsoleKit"
44
 
#define CK_INTERFACE "org.freedesktop.ConsoleKit"
45
 
 
46
 
#define CK_MANAGER_PATH      "/org/freedesktop/ConsoleKit/Manager"
47
 
#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
48
 
#define CK_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
49
 
#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
50
 
#endif
51
 
 
52
 
static const char *send_command     = NULL;
53
 
static gboolean    use_xnest        = FALSE;
54
 
static gboolean    no_lock          = FALSE;
55
 
static gboolean    debug_in         = FALSE;
56
 
static gboolean    authenticate     = FALSE;
57
 
static gboolean    startnew         = FALSE;
58
 
static gboolean    monte_carlo_pi   = FALSE;
59
 
static gboolean    show_version     = FALSE;
60
 
static char      **args_remaining   = NULL;
61
 
 
62
 
/* Keep all config options for compatibility even if they are noops */
63
 
GOptionEntry options [] = {
64
 
        { "command", 'c', 0, G_OPTION_ARG_STRING, &send_command, "Only the VERSION command is supported", "COMMAND" },
65
 
        { "xnest", 'n', 0, G_OPTION_ARG_NONE, &use_xnest, "Ignored — retained for compatibility", NULL },
66
 
        { "no-lock", 'l', 0, G_OPTION_ARG_NONE, &no_lock, "Ignored — retained for compatibility", NULL },
67
 
        { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug_in, "Debugging output", NULL },
68
 
        { "authenticate", 'a', 0, G_OPTION_ARG_NONE, &authenticate, "Ignored — retained for compatibility", NULL },
69
 
        { "startnew", 's', 0, G_OPTION_ARG_NONE, &startnew, "Ignored — retained for compatibility", NULL },
70
 
        { "monte-carlo-pi", 0, 0, G_OPTION_ARG_NONE, &monte_carlo_pi, NULL, NULL },
71
 
        { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Version of this application", NULL },
72
 
        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args_remaining, NULL, NULL },
73
 
        { NULL }
74
 
};
75
 
 
76
 
#define GDM_FLEXISERVER_ERROR gdm_flexiserver_error_quark ()
77
 
static GQuark
78
 
gdm_flexiserver_error_quark (void)
79
 
{
80
 
        static GQuark ret = 0;
81
 
        if (ret == 0) {
82
 
                ret = g_quark_from_static_string ("gdm_flexiserver_error");
83
 
        }
84
 
 
85
 
        return ret;
86
 
}
87
 
 
88
 
static gboolean
89
 
is_program_in_path (const char *program)
90
 
{
91
 
        char *tmp = g_find_program_in_path (program);
92
 
        if (tmp != NULL) {
93
 
                g_free (tmp);
94
 
                return TRUE;
95
 
        } else {
96
 
                return FALSE;
97
 
        }
98
 
}
99
 
 
100
 
static void
101
 
maybe_lock_screen (void)
102
 
{
103
 
        gboolean   use_gscreensaver = FALSE;
104
 
        GError    *error            = NULL;
105
 
        char      *command;
106
 
 
107
 
        if (is_program_in_path ("gnome-screensaver-command")) {
108
 
                use_gscreensaver = TRUE;
109
 
        } else if (! is_program_in_path ("xscreensaver-command")) {
110
 
                return;
111
 
        }
112
 
 
113
 
        if (use_gscreensaver) {
114
 
                command = g_strdup ("gnome-screensaver-command --lock");
115
 
        } else {
116
 
                command = g_strdup ("xscreensaver-command -lock");
117
 
        }
118
 
 
119
 
        if (! g_spawn_command_line_async (command, &error)) {
120
 
                g_warning ("Cannot lock screen: %s", error->message);
121
 
                g_error_free (error);
122
 
        }
123
 
 
124
 
        g_free (command);
125
 
 
126
 
        if (! use_gscreensaver) {
127
 
                command = g_strdup ("xscreensaver-command -throttle");
128
 
                if (! g_spawn_command_line_async (command, &error)) {
129
 
                        g_warning ("Cannot disable screensaver engines: %s", error->message);
130
 
                        g_error_free (error);
131
 
                }
132
 
 
133
 
                g_free (command);
134
 
        }
135
 
}
136
 
 
137
 
static void
138
 
calc_pi (void)
139
 
{
140
 
        unsigned long n = 0, h = 0;
141
 
        double x, y;
142
 
        printf ("\n");
143
 
        for (;;) {
144
 
                x = g_random_double ();
145
 
                y = g_random_double ();
146
 
                if (x*x + y*y <= 1)
147
 
                        h++;
148
 
                n++;
149
 
                if ( ! (n & 0xfff))
150
 
                        printf ("pi ~~ %1.10f\t(%lu/%lu * 4) iteration: %lu \r",
151
 
                                ((double)h)/(double)n * 4.0, h, n, n);
152
 
        }
153
 
}
154
 
 
155
 
static gboolean
156
 
create_transient_display (GDBusConnection *connection,
157
 
                          GError         **error)
158
 
{
159
 
        GError *local_error = NULL;
160
 
        GVariant *reply;
161
 
        const char     *value;
162
 
 
163
 
        reply = g_dbus_connection_call_sync (connection,
164
 
                                             GDM_DBUS_NAME,
165
 
                                             GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH,
166
 
                                             GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE,
167
 
                                             "CreateTransientDisplay",
168
 
                                             NULL, /* parameters */
169
 
                                             G_VARIANT_TYPE ("(o)"),
170
 
                                             G_DBUS_CALL_FLAGS_NONE,
171
 
                                             -1,
172
 
                                             NULL, &local_error);
173
 
        if (reply == NULL) {
174
 
                g_warning ("Unable to create transient display: %s", local_error->message);
175
 
                g_propagate_error (error, local_error);
176
 
                return FALSE;
177
 
        }
178
 
 
179
 
        g_variant_get (reply, "(&o)", &value);
180
 
        g_debug ("Started %s", value);
181
 
 
182
 
        g_variant_unref (reply);
183
 
        return TRUE;
184
 
}
185
 
 
186
 
#ifdef WITH_CONSOLE_KIT
187
 
 
188
 
static gboolean
189
 
get_current_session_id (GDBusConnection  *connection,
190
 
                        char            **session_id)
191
 
{
192
 
        GError *local_error = NULL;
193
 
        GVariant *reply;
194
 
 
195
 
        reply = g_dbus_connection_call_sync (connection,
196
 
                                             CK_NAME,
197
 
                                             CK_MANAGER_PATH,
198
 
                                             CK_MANAGER_INTERFACE,
199
 
                                             "GetCurrentSession",
200
 
                                             NULL, /* parameters */
201
 
                                             G_VARIANT_TYPE ("(o)"),
202
 
                                             G_DBUS_CALL_FLAGS_NONE,
203
 
                                             -1,
204
 
                                             NULL, &local_error);
205
 
        if (reply == NULL) {
206
 
                g_warning ("Unable to determine session: %s", local_error->message);
207
 
                g_error_free (local_error);
208
 
                return FALSE;
209
 
        }
210
 
 
211
 
        g_variant_get (reply, "(o)", session_id);
212
 
        g_variant_unref (reply);
213
 
 
214
 
        return TRUE;
215
 
}
216
 
 
217
 
static gboolean
218
 
get_seat_id_for_session (GDBusConnection  *connection,
219
 
                         const char       *session_id,
220
 
                         char            **seat_id)
221
 
{
222
 
        GError *local_error = NULL;
223
 
        GVariant *reply;
224
 
 
225
 
        reply = g_dbus_connection_call_sync (connection,
226
 
                                             CK_NAME,
227
 
                                             session_id,
228
 
                                             CK_SESSION_INTERFACE,
229
 
                                             "GetSeatId",
230
 
                                             NULL, /* parameters */
231
 
                                             G_VARIANT_TYPE ("(o)"),
232
 
                                             G_DBUS_CALL_FLAGS_NONE,
233
 
                                             -1,
234
 
                                             NULL, &local_error);
235
 
        if (reply == NULL) {
236
 
                g_warning ("Unable to determine seat: %s", local_error->message);
237
 
                g_error_free (local_error);
238
 
                return FALSE;
239
 
        }
240
 
 
241
 
        g_variant_get (reply, "(o)", seat_id);
242
 
        g_variant_unref (reply);
243
 
 
244
 
        return TRUE;
245
 
}
246
 
 
247
 
static char *
248
 
get_current_seat_id (GDBusConnection *connection)
249
 
{
250
 
        gboolean res;
251
 
        char    *session_id;
252
 
        char    *seat_id;
253
 
 
254
 
        session_id = NULL;
255
 
        seat_id = NULL;
256
 
 
257
 
        res = get_current_session_id (connection, &session_id);
258
 
        if (res) {
259
 
                res = get_seat_id_for_session (connection, session_id, &seat_id);
260
 
        }
261
 
        g_free (session_id);
262
 
 
263
 
        return seat_id;
264
 
}
265
 
 
266
 
static gboolean
267
 
activate_session_id_for_ck (GDBusConnection *connection,
268
 
                            const char      *seat_id,
269
 
                            const char      *session_id)
270
 
{
271
 
        GError *local_error = NULL;
272
 
        GVariant *reply;
273
 
 
274
 
        reply = g_dbus_connection_call_sync (connection,
275
 
                                             CK_NAME,
276
 
                                             seat_id,
277
 
                                             CK_SEAT_INTERFACE,
278
 
                                             "ActivateSession",
279
 
                                             g_variant_new ("(o)", session_id),
280
 
                                             NULL,
281
 
                                             G_DBUS_CALL_FLAGS_NONE,
282
 
                                             -1,
283
 
                                             NULL, &local_error);
284
 
        if (reply == NULL) {
285
 
                g_warning ("Unable to activate session: %s", local_error->message);
286
 
                g_error_free (local_error);
287
 
                return FALSE;
288
 
        }
289
 
 
290
 
        g_variant_unref (reply);
291
 
 
292
 
        return TRUE;
293
 
}
294
 
 
295
 
static gboolean
296
 
session_is_login_window (GDBusConnection *connection,
297
 
                         const char      *session_id)
298
 
{
299
 
        GError *local_error = NULL;
300
 
        GVariant *reply;
301
 
        const char *value;
302
 
        gboolean ret;
303
 
 
304
 
        reply = g_dbus_connection_call_sync (connection,
305
 
                                             CK_NAME,
306
 
                                             session_id,
307
 
                                             CK_SESSION_INTERFACE,
308
 
                                             "GetSessionType",
309
 
                                             NULL,
310
 
                                             G_VARIANT_TYPE ("(s)"),
311
 
                                             G_DBUS_CALL_FLAGS_NONE,
312
 
                                             -1,
313
 
                                             NULL, &local_error);
314
 
        if (reply == NULL) {
315
 
                g_warning ("Unable to determine session type: %s", local_error->message);
316
 
                g_error_free (local_error);
317
 
                return FALSE;
318
 
        }
319
 
 
320
 
        g_variant_get (reply, "(&s)", &value);
321
 
 
322
 
        if (value == NULL || value[0] == '\0' || strcmp (value, "LoginWindow") != 0) {
323
 
                ret = FALSE;
324
 
        } else {
325
 
                ret = TRUE;
326
 
        }
327
 
 
328
 
        g_variant_unref (reply);
329
 
 
330
 
        return ret;
331
 
}
332
 
 
333
 
static gboolean
334
 
seat_can_activate_sessions (GDBusConnection *connection,
335
 
                            const char      *seat_id)
336
 
{
337
 
        GError *local_error = NULL;
338
 
        GVariant *reply;
339
 
        gboolean ret;
340
 
 
341
 
        reply = g_dbus_connection_call_sync (connection,
342
 
                                             CK_NAME,
343
 
                                             seat_id,
344
 
                                             CK_SEAT_INTERFACE,
345
 
                                             "CanActivateSessions",
346
 
                                             NULL,
347
 
                                             G_VARIANT_TYPE ("(b)"),
348
 
                                             G_DBUS_CALL_FLAGS_NONE,
349
 
                                             -1,
350
 
                                             NULL, &local_error);
351
 
        if (reply == NULL) {
352
 
                g_warning ("Unable to determine if can activate sessions: %s", local_error->message);
353
 
                g_error_free (local_error);
354
 
                return FALSE;
355
 
        }
356
 
 
357
 
        g_variant_get (reply, "(b)", &ret);
358
 
        g_variant_unref (reply);
359
 
 
360
 
        return ret;
361
 
}
362
 
 
363
 
static const char **
364
 
seat_get_sessions (GDBusConnection *connection,
365
 
                   const char      *seat_id)
366
 
{
367
 
        GError *local_error = NULL;
368
 
        GVariant *reply;
369
 
        const char **value;
370
 
 
371
 
        reply = g_dbus_connection_call_sync (connection,
372
 
                                             CK_NAME,
373
 
                                             seat_id,
374
 
                                             CK_SEAT_INTERFACE,
375
 
                                             "GetSessions",
376
 
                                             NULL,
377
 
                                             G_VARIANT_TYPE ("(ao)"),
378
 
                                             G_DBUS_CALL_FLAGS_NONE,
379
 
                                             -1,
380
 
                                             NULL, &local_error);
381
 
        if (reply == NULL) {
382
 
                g_warning ("Unable to list sessions: %s", local_error->message);
383
 
                g_error_free (local_error);
384
 
                return FALSE;
385
 
        }
386
 
 
387
 
        g_variant_get (reply, "(^ao)", &value);
388
 
        g_variant_unref (reply);
389
 
 
390
 
        return value;
391
 
}
392
 
 
393
 
static gboolean
394
 
get_login_window_session_id_for_ck (GDBusConnection  *connection,
395
 
                                    const char       *seat_id,
396
 
                                    char            **session_id)
397
 
{
398
 
        gboolean     can_activate_sessions;
399
 
        const char **sessions;
400
 
        int          i;
401
 
 
402
 
        *session_id = NULL;
403
 
        sessions = NULL;
404
 
 
405
 
        g_debug ("checking if seat can activate sessions");
406
 
 
407
 
        can_activate_sessions = seat_can_activate_sessions (connection, seat_id);
408
 
        if (! can_activate_sessions) {
409
 
                g_debug ("seat is unable to activate sessions");
410
 
                return FALSE;
411
 
        }
412
 
 
413
 
        sessions = seat_get_sessions (connection, seat_id);
414
 
        for (i = 0; sessions [i] != NULL; i++) {
415
 
                const char *ssid;
416
 
 
417
 
                ssid = sessions [i];
418
 
 
419
 
                if (session_is_login_window (connection, ssid)) {
420
 
                        *session_id = g_strdup (ssid);
421
 
                        break;
422
 
                }
423
 
        }
424
 
        g_free (sessions);
425
 
 
426
 
        return TRUE;
427
 
}
428
 
 
429
 
static gboolean
430
 
goto_login_session_for_ck (GDBusConnection  *connection,
431
 
                           GError          **error)
432
 
{
433
 
        gboolean        ret;
434
 
        gboolean        res;
435
 
        char           *session_id;
436
 
        char           *seat_id;
437
 
 
438
 
        ret = FALSE;
439
 
 
440
 
        /* First look for any existing LoginWindow sessions on the seat.
441
 
           If none are found, create a new one. */
442
 
 
443
 
        seat_id = get_current_seat_id (connection);
444
 
        if (seat_id == NULL || seat_id[0] == '\0') {
445
 
                g_debug ("seat id is not set; can't switch sessions");
446
 
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "Could not identify the current session.");
447
 
 
448
 
                return FALSE;
449
 
        }
450
 
 
451
 
        res = get_login_window_session_id_for_ck (connection, seat_id, &session_id);
452
 
        if (! res) {
453
 
                g_set_error (error, GDM_FLEXISERVER_ERROR, 1, "User unable to switch sessions.");
454
 
                return FALSE;
455
 
        }
456
 
 
457
 
        if (session_id != NULL) {
458
 
                res = activate_session_id_for_ck (connection, seat_id, session_id);
459
 
                if (res) {
460
 
                        ret = TRUE;
461
 
                }
462
 
        }
463
 
 
464
 
        if (! ret && g_strcmp0 (seat_id, "/org/freedesktop/ConsoleKit/Seat1") == 0) {
465
 
                res = create_transient_display (connection, error);
466
 
                if (res) {
467
 
                        ret = TRUE;
468
 
                }
469
 
        }
470
 
 
471
 
        return ret;
472
 
}
473
 
#endif
474
 
 
475
 
#ifdef WITH_SYSTEMD
476
 
 
477
 
static gboolean
478
 
activate_session_id_for_systemd (GDBusConnection *connection,
479
 
                                 const char      *seat_id,
480
 
                                 const char      *session_id)
481
 
{
482
 
        GError *local_error = NULL;
483
 
        GVariant *reply;
484
 
 
485
 
        reply = g_dbus_connection_call_sync (connection,
486
 
                                             "org.freedesktop.login1",
487
 
                                             "/org/freedesktop/login1",
488
 
                                             "org.freedesktop.login1.Manager",
489
 
                                             "ActivateSessionOnSeat",
490
 
                                             g_variant_new ("(ss)", session_id, seat_id),
491
 
                                             NULL,
492
 
                                             G_DBUS_CALL_FLAGS_NONE,
493
 
                                             -1,
494
 
                                             NULL, &local_error);
495
 
        if (reply == NULL) {
496
 
                g_warning ("Unable to activate session: %s", local_error->message);
497
 
                g_error_free (local_error);
498
 
                return FALSE;
499
 
        }
500
 
 
501
 
        g_variant_unref (reply);
502
 
 
503
 
        return TRUE;
504
 
}
505
 
 
506
 
static gboolean
507
 
get_login_window_session_id_for_systemd (const char  *seat_id,
508
 
                                         char       **session_id)
509
 
{
510
 
        gboolean   ret;
511
 
        int        res, i;
512
 
        char     **sessions;
513
 
        char      *service_id;
514
 
        char      *service_class;
515
 
        char      *state;
516
 
 
517
 
        res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL);
518
 
        if (res < 0) {
519
 
                g_debug ("Failed to determine sessions: %s", strerror (-res));
520
 
                return FALSE;
521
 
        }
522
 
 
523
 
        if (sessions == NULL || sessions[0] == NULL) {
524
 
                *session_id = NULL;
525
 
                ret = TRUE;
526
 
                goto out;
527
 
        }
528
 
 
529
 
        for (i = 0; sessions[i]; i ++) {
530
 
 
531
 
                res = sd_session_get_class (sessions[i], &service_class);
532
 
                if (res < 0) {
533
 
                        g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res));
534
 
                        ret = FALSE;
535
 
                        goto out;
536
 
                }
537
 
 
538
 
                if (strcmp (service_class, "greeter") != 0) {
539
 
                        free (service_class);
540
 
                        continue;
541
 
                }
542
 
 
543
 
                free (service_class);
544
 
 
545
 
                ret = sd_session_get_state (sessions[i], &state);
546
 
                if (ret < 0) {
547
 
                        g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res));
548
 
                        ret = FALSE;
549
 
                        goto out;
550
 
                }
551
 
 
552
 
                if (g_strcmp0 (state, "closing") == 0) {
553
 
                        free (state);
554
 
                        continue;
555
 
                }
556
 
                free (state);
557
 
 
558
 
                res = sd_session_get_service (sessions[i], &service_id);
559
 
                if (res < 0) {
560
 
                        g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res));
561
 
                        ret = FALSE;
562
 
                        goto out;
563
 
                }
564
 
 
565
 
                if (strcmp (service_id, "gdm-welcome") == 0) {
566
 
                        *session_id = g_strdup (sessions[i]);
567
 
                        ret = TRUE;
568
 
 
569
 
                        free (service_id);
570
 
                        goto out;
571
 
                }
572
 
 
573
 
                free (service_id);
574
 
        }
575
 
 
576
 
        *session_id = NULL;
577
 
        ret = TRUE;
578
 
 
579
 
out:
580
 
        for (i = 0; sessions[i]; i ++) {
581
 
                free (sessions[i]);
582
 
        }
583
 
 
584
 
        free (sessions);
585
 
 
586
 
        return ret;
587
 
}
588
 
 
589
 
static gboolean
590
 
goto_login_session_for_systemd (GDBusConnection  *connection,
591
 
                                GError          **error)
592
 
{
593
 
        gboolean        ret;
594
 
        int             res;
595
 
        char           *our_session;
596
 
        char           *session_id;
597
 
        char           *seat_id;
598
 
 
599
 
        ret = FALSE;
600
 
        session_id = NULL;
601
 
        seat_id = NULL;
602
 
 
603
 
        /* First look for any existing LoginWindow sessions on the seat.
604
 
           If none are found, create a new one. */
605
 
 
606
 
        /* Note that we mostly use free () here, instead of g_free ()
607
 
         * since the data allocated is from libsystemd-logind, which
608
 
         * does not use GLib's g_malloc (). */
609
 
 
610
 
        res = sd_pid_get_session (0, &our_session);
611
 
        if (res < 0) {
612
 
                g_debug ("failed to determine own session: %s", strerror (-res));
613
 
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "Could not identify the current session.");
614
 
 
615
 
                return FALSE;
616
 
        }
617
 
 
618
 
        res = sd_session_get_seat (our_session, &seat_id);
619
 
        free (our_session);
620
 
        if (res < 0) {
621
 
                g_debug ("failed to determine own seat: %s", strerror (-res));
622
 
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "Could not identify the current seat.");
623
 
 
624
 
                return FALSE;
625
 
        }
626
 
 
627
 
        res = sd_seat_can_multi_session (seat_id);
628
 
        if (res < 0) {
629
 
                free (seat_id);
630
 
 
631
 
                g_debug ("failed to determine whether seat can do multi session: %s", strerror (-res));
632
 
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "The system is unable to determine whether to switch to an existing login screen or start up a new login screen.");
633
 
 
634
 
                return FALSE;
635
 
        }
636
 
 
637
 
        if (res == 0) {
638
 
                free (seat_id);
639
 
 
640
 
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "The system is unable to start up a new login screen.");
641
 
 
642
 
                return FALSE;
643
 
        }
644
 
 
645
 
        res = get_login_window_session_id_for_systemd (seat_id, &session_id);
646
 
        if (res && session_id != NULL) {
647
 
                res = activate_session_id_for_systemd (connection, seat_id, session_id);
648
 
 
649
 
                if (res) {
650
 
                        ret = TRUE;
651
 
                }
652
 
        }
653
 
 
654
 
        if (! ret && g_strcmp0 (seat_id, "seat0") == 0) {
655
 
                res = create_transient_display (connection, error);
656
 
                if (res) {
657
 
                        ret = TRUE;
658
 
                }
659
 
        }
660
 
 
661
 
        free (seat_id);
662
 
        g_free (session_id);
663
 
 
664
 
        return ret;
665
 
}
666
 
#endif
667
 
 
668
 
static gboolean
669
 
goto_login_session (GError **error)
670
 
{
671
 
        GError *local_error;
672
 
        GDBusConnection *connection;
673
 
 
674
 
        local_error = NULL;
675
 
        connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error);
676
 
        if (connection == NULL) {
677
 
                g_debug ("Failed to connect to the D-Bus daemon: %s", local_error->message);
678
 
                g_propagate_error (error, local_error);
679
 
                return FALSE;
680
 
        }
681
 
 
682
 
#ifdef WITH_SYSTEMD
683
 
        if (sd_booted () > 0) {
684
 
                return goto_login_session_for_systemd (connection, error);
685
 
        }
686
 
#endif
687
 
 
688
 
#ifdef WITH_CONSOLE_KIT
689
 
        return goto_login_session_for_ck (connection, error);
690
 
#endif
691
 
}
692
 
 
693
 
int
694
 
main (int argc, char *argv[])
695
 
{
696
 
        GOptionContext *ctx;
697
 
        gboolean        res;
698
 
        GError         *error;
699
 
 
700
 
        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
701
 
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
702
 
        textdomain (GETTEXT_PACKAGE);
703
 
        setlocale (LC_ALL, "");
704
 
 
705
 
        /* Option parsing */
706
 
        ctx = g_option_context_new ("- New GDM login");
707
 
        g_option_context_set_translation_domain (ctx, GETTEXT_PACKAGE);
708
 
        g_option_context_add_main_entries (ctx, options, NULL);
709
 
        g_option_context_parse (ctx, &argc, &argv, NULL);
710
 
        g_option_context_free (ctx);
711
 
 
712
 
 
713
 
        if (show_version) {
714
 
                g_print ("%s %s\n", argv [0], VERSION);
715
 
                exit (1);
716
 
        }
717
 
 
718
 
        /* don't support commands other than VERSION */
719
 
        if (send_command != NULL) {
720
 
                if (strcmp (send_command, "VERSION") == 0) {
721
 
                        g_print ("GDM  %s \n", VERSION);
722
 
                        return 0;
723
 
                } else {
724
 
                        g_warning ("No longer supported");
725
 
                }
726
 
                return 1;
727
 
        }
728
 
 
729
 
        gtk_init (&argc, &argv);
730
 
 
731
 
        if (monte_carlo_pi) {
732
 
                calc_pi ();
733
 
                return 0;
734
 
        }
735
 
 
736
 
        if (args_remaining != NULL && args_remaining[0] != NULL) {
737
 
 
738
 
        }
739
 
 
740
 
        if (use_xnest) {
741
 
                g_warning ("Not yet implemented");
742
 
                return 1;
743
 
        }
744
 
 
745
 
        error = NULL;
746
 
        res = goto_login_session (&error);
747
 
        if (! res) {
748
 
                GtkWidget *dialog;
749
 
                char      *message;
750
 
 
751
 
                if (error != NULL) {
752
 
                        message = g_strdup_printf ("%s", error->message);
753
 
                        g_error_free (error);
754
 
                } else {
755
 
                        message = g_strdup ("");
756
 
                }
757
 
 
758
 
                dialog = gtk_message_dialog_new (NULL,
759
 
                                                 GTK_DIALOG_DESTROY_WITH_PARENT,
760
 
                                                 GTK_MESSAGE_ERROR,
761
 
                                                 GTK_BUTTONS_CLOSE,
762
 
                                                 "%s", "Unable to start new display");
763
 
 
764
 
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
765
 
                                                          "%s", message);
766
 
                g_free (message);
767
 
 
768
 
                gtk_window_set_title (GTK_WINDOW (dialog), "");
769
 
                gtk_window_set_icon_name (GTK_WINDOW (dialog), "session-properties");
770
 
                gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
771
 
                gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14);
772
 
 
773
 
                gtk_dialog_run (GTK_DIALOG (dialog));
774
 
                gtk_widget_destroy (dialog);
775
 
        } else {
776
 
                maybe_lock_screen ();
777
 
        }
778
 
 
779
 
        return 1;
780
 
}