~ubuntu-branches/ubuntu/oneiric/gdm3/oneiric

« back to all changes in this revision

Viewing changes to daemon/gdm-factory-slave.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2010-03-25 20:02:20 UTC
  • Revision ID: james.westby@ubuntu.com-20100325200220-12cap62s6p304nuh
Tags: upstream-2.29.92
ImportĀ upstreamĀ versionĀ 2.29.92

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) 2007 William Jon McCann <mccann@jhu.edu>
 
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 *
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#include <stdlib.h>
 
24
#include <stdio.h>
 
25
#include <fcntl.h>
 
26
#include <unistd.h>
 
27
#include <string.h>
 
28
#include <sys/types.h>
 
29
#include <sys/wait.h>
 
30
#include <errno.h>
 
31
#include <pwd.h>
 
32
#include <grp.h>
 
33
 
 
34
#include <glib.h>
 
35
#include <glib/gi18n.h>
 
36
#include <glib/gstdio.h>
 
37
#include <glib-object.h>
 
38
 
 
39
#define DBUS_API_SUBJECT_TO_CHANGE
 
40
#include <dbus/dbus-glib.h>
 
41
#include <dbus/dbus-glib-lowlevel.h>
 
42
 
 
43
#include <X11/Xlib.h> /* for Display */
 
44
 
 
45
#include "gdm-common.h"
 
46
 
 
47
#include "gdm-factory-slave.h"
 
48
#include "gdm-factory-slave-glue.h"
 
49
 
 
50
#include "gdm-server.h"
 
51
#include "gdm-greeter-session.h"
 
52
#include "gdm-greeter-server.h"
 
53
 
 
54
#include "gdm-session-relay.h"
 
55
 
 
56
extern char **environ;
 
57
 
 
58
#define GDM_FACTORY_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_FACTORY_SLAVE, GdmFactorySlavePrivate))
 
59
 
 
60
#define GDM_DBUS_NAME                            "org.gnome.DisplayManager"
 
61
#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH      "/org/gnome/DisplayManager/LocalDisplayFactory"
 
62
#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory"
 
63
 
 
64
#define MAX_CONNECT_ATTEMPTS 10
 
65
 
 
66
struct GdmFactorySlavePrivate
 
67
{
 
68
        char              *id;
 
69
        GPid               pid;
 
70
        guint              greeter_reset_id;
 
71
 
 
72
        GPid               server_pid;
 
73
        Display           *server_display;
 
74
        guint              connection_attempts;
 
75
 
 
76
        GdmServer         *server;
 
77
        GdmSessionRelay   *session;
 
78
        GdmGreeterServer  *greeter_server;
 
79
        GdmGreeterSession *greeter;
 
80
        DBusGProxy        *factory_proxy;
 
81
        DBusGConnection   *connection;
 
82
};
 
83
 
 
84
enum {
 
85
        PROP_0,
 
86
};
 
87
 
 
88
static void     gdm_factory_slave_class_init    (GdmFactorySlaveClass *klass);
 
89
static void     gdm_factory_slave_init          (GdmFactorySlave      *factory_slave);
 
90
static void     gdm_factory_slave_finalize      (GObject             *object);
 
91
 
 
92
G_DEFINE_TYPE (GdmFactorySlave, gdm_factory_slave, GDM_TYPE_SLAVE)
 
93
 
 
94
static gboolean
 
95
greeter_reset_timeout (GdmFactorySlave *slave)
 
96
{
 
97
        gdm_greeter_server_reset (slave->priv->greeter_server);
 
98
        slave->priv->greeter_reset_id = 0;
 
99
        return FALSE;
 
100
}
 
101
 
 
102
static void
 
103
queue_greeter_reset (GdmFactorySlave *slave)
 
104
{
 
105
        if (slave->priv->greeter_reset_id > 0) {
 
106
                return;
 
107
        }
 
108
 
 
109
        slave->priv->greeter_reset_id = g_timeout_add_seconds (2, (GSourceFunc)greeter_reset_timeout, slave);
 
110
}
 
111
 
 
112
static void
 
113
on_greeter_session_start (GdmGreeterSession *greeter,
 
114
                          GdmFactorySlave   *slave)
 
115
{
 
116
        g_debug ("GdmFactorySlave: Greeter started");
 
117
}
 
118
 
 
119
static void
 
120
on_greeter_session_stop (GdmGreeterSession *greeter,
 
121
                         GdmFactorySlave   *slave)
 
122
{
 
123
        g_debug ("GdmFactorySlave: Greeter stopped");
 
124
}
 
125
 
 
126
static void
 
127
on_greeter_session_exited (GdmGreeterSession    *greeter,
 
128
                           int                   code,
 
129
                           GdmFactorySlave      *slave)
 
130
{
 
131
        g_debug ("GdmSimpleSlave: Greeter exited: %d", code);
 
132
        gdm_slave_stopped (GDM_SLAVE (slave));
 
133
}
 
134
 
 
135
static void
 
136
on_greeter_session_died (GdmGreeterSession    *greeter,
 
137
                         int                   signal,
 
138
                         GdmFactorySlave      *slave)
 
139
{
 
140
        g_debug ("GdmSimpleSlave: Greeter died: %d", signal);
 
141
        gdm_slave_stopped (GDM_SLAVE (slave));
 
142
}
 
143
 
 
144
 
 
145
static void
 
146
on_session_info (GdmSession      *session,
 
147
                 const char      *text,
 
148
                 GdmFactorySlave *slave)
 
149
{
 
150
        g_debug ("GdmFactorySlave: Info: %s", text);
 
151
        gdm_greeter_server_info (slave->priv->greeter_server, text);
 
152
}
 
153
 
 
154
static void
 
155
on_session_problem (GdmSession      *session,
 
156
                    const char      *text,
 
157
                    GdmFactorySlave *slave)
 
158
{
 
159
        g_debug ("GdmFactorySlave: Problem: %s", text);
 
160
        gdm_greeter_server_problem (slave->priv->greeter_server, text);
 
161
}
 
162
 
 
163
static void
 
164
on_session_info_query (GdmSession      *session,
 
165
                       const char      *text,
 
166
                       GdmFactorySlave *slave)
 
167
{
 
168
 
 
169
        g_debug ("GdmFactorySlave: Info query: %s", text);
 
170
        gdm_greeter_server_info_query (slave->priv->greeter_server, text);
 
171
}
 
172
 
 
173
static void
 
174
on_session_secret_info_query (GdmSession      *session,
 
175
                              const char      *text,
 
176
                              GdmFactorySlave *slave)
 
177
{
 
178
        g_debug ("GdmFactorySlave: Secret info query: %s", text);
 
179
        gdm_greeter_server_secret_info_query (slave->priv->greeter_server, text);
 
180
}
 
181
 
 
182
static void
 
183
on_session_conversation_started (GdmSession      *session,
 
184
                                 GdmFactorySlave *slave)
 
185
{
 
186
        g_debug ("GdmFactorySlave: session conversation started");
 
187
 
 
188
        gdm_greeter_server_ready (slave->priv->greeter_server);
 
189
}
 
190
 
 
191
static void
 
192
on_session_setup_complete (GdmSession      *session,
 
193
                           GdmFactorySlave *slave)
 
194
{
 
195
        gdm_session_authenticate (session);
 
196
}
 
197
 
 
198
static void
 
199
on_session_setup_failed (GdmSession      *session,
 
200
                         const char      *message,
 
201
                         GdmFactorySlave *slave)
 
202
{
 
203
        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to initialize login system"));
 
204
 
 
205
        queue_greeter_reset (slave);
 
206
}
 
207
 
 
208
static void
 
209
on_session_reset_complete (GdmSession      *session,
 
210
                           GdmFactorySlave *slave)
 
211
{
 
212
        g_debug ("GdmFactorySlave: PAM reset");
 
213
}
 
214
 
 
215
static void
 
216
on_session_reset_failed (GdmSession      *session,
 
217
                         const char      *message,
 
218
                         GdmFactorySlave *slave)
 
219
{
 
220
        g_critical ("Unable to reset PAM");
 
221
}
 
222
 
 
223
static void
 
224
on_session_authenticated (GdmSession      *session,
 
225
                          GdmFactorySlave *slave)
 
226
{
 
227
        gdm_session_authorize (session);
 
228
}
 
229
 
 
230
static void
 
231
on_session_authentication_failed (GdmSession      *session,
 
232
                                  const char      *message,
 
233
                                  GdmFactorySlave *slave)
 
234
{
 
235
        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to authenticate user"));
 
236
 
 
237
        queue_greeter_reset (slave);
 
238
}
 
239
 
 
240
static void
 
241
on_session_authorized (GdmSession      *session,
 
242
                       GdmFactorySlave *slave)
 
243
{
 
244
        int flag;
 
245
 
 
246
        /* FIXME: check for migration? */
 
247
        flag = GDM_SESSION_CRED_ESTABLISH;
 
248
 
 
249
        gdm_session_accredit (session, flag);
 
250
}
 
251
 
 
252
static void
 
253
on_session_authorization_failed (GdmSession      *session,
 
254
                                 const char      *message,
 
255
                                 GdmFactorySlave *slave)
 
256
{
 
257
        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to authorize user"));
 
258
 
 
259
        queue_greeter_reset (slave);
 
260
}
 
261
 
 
262
static void
 
263
on_session_accredited (GdmSession      *session,
 
264
                       GdmFactorySlave *slave)
 
265
{
 
266
        g_debug ("GdmFactorySlave:  session user verified");
 
267
 
 
268
        gdm_session_open_session (session);
 
269
}
 
270
 
 
271
static void
 
272
on_session_accreditation_failed (GdmSession      *session,
 
273
                                 const char      *message,
 
274
                                 GdmFactorySlave *slave)
 
275
{
 
276
        g_debug ("GdmFactorySlave: could not successfully authenticate user: %s",
 
277
                 message);
 
278
 
 
279
        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to establish credentials"));
 
280
 
 
281
        queue_greeter_reset (slave);
 
282
}
 
283
 
 
284
static void
 
285
on_session_opened (GdmSession      *session,
 
286
                   GdmFactorySlave *slave)
 
287
{
 
288
        g_debug ("GdmFactorySlave: session opened");
 
289
 
 
290
        gdm_session_start_session (session);
 
291
 
 
292
        gdm_greeter_server_reset (slave->priv->greeter_server);
 
293
}
 
294
 
 
295
static void
 
296
on_session_open_failed (GdmSession      *session,
 
297
                        const char      *message,
 
298
                        GdmFactorySlave *slave)
 
299
{
 
300
        g_debug ("GdmFactorySlave: could not open session: %s", message);
 
301
 
 
302
        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to open session"));
 
303
 
 
304
        queue_greeter_reset (slave);
 
305
}
 
306
 
 
307
static void
 
308
on_session_session_started (GdmSession      *session,
 
309
                            GdmFactorySlave *slave)
 
310
{
 
311
        g_debug ("GdmFactorySlave: Relay session started");
 
312
 
 
313
        gdm_greeter_server_reset (slave->priv->greeter_server);
 
314
}
 
315
 
 
316
static gboolean
 
317
create_product_display (GdmFactorySlave *slave)
 
318
{
 
319
        char    *parent_display_id;
 
320
        char    *server_address;
 
321
        char    *product_id;
 
322
        GError  *error;
 
323
        gboolean res;
 
324
        gboolean ret;
 
325
 
 
326
        ret = FALSE;
 
327
 
 
328
        g_debug ("GdmFactorySlave: Create product display");
 
329
 
 
330
        g_debug ("GdmFactorySlave: Connecting to local display factory");
 
331
        slave->priv->factory_proxy = dbus_g_proxy_new_for_name (slave->priv->connection,
 
332
                                                                GDM_DBUS_NAME,
 
333
                                                                GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH,
 
334
                                                                GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE);
 
335
        if (slave->priv->factory_proxy == NULL) {
 
336
                g_warning ("Failed to create local display factory proxy");
 
337
                goto out;
 
338
        }
 
339
 
 
340
        server_address = gdm_session_relay_get_address (slave->priv->session);
 
341
 
 
342
        g_object_get (slave,
 
343
                      "display-id", &parent_display_id,
 
344
                      NULL);
 
345
 
 
346
        error = NULL;
 
347
        res = dbus_g_proxy_call (slave->priv->factory_proxy,
 
348
                                 "CreateProductDisplay",
 
349
                                 &error,
 
350
                                 DBUS_TYPE_G_OBJECT_PATH, parent_display_id,
 
351
                                 G_TYPE_STRING, server_address,
 
352
                                 G_TYPE_INVALID,
 
353
                                 DBUS_TYPE_G_OBJECT_PATH, &product_id,
 
354
                                 G_TYPE_INVALID);
 
355
        g_free (server_address);
 
356
        g_free (parent_display_id);
 
357
 
 
358
        if (! res) {
 
359
                if (error != NULL) {
 
360
                        g_warning ("Failed to create product display: %s", error->message);
 
361
                        g_error_free (error);
 
362
                } else {
 
363
                        g_warning ("Failed to create product display");
 
364
                }
 
365
                goto out;
 
366
        }
 
367
 
 
368
        ret = TRUE;
 
369
 
 
370
 out:
 
371
        return ret;
 
372
}
 
373
 
 
374
static void
 
375
on_session_relay_disconnected (GdmSessionRelay *session,
 
376
                               GdmFactorySlave *slave)
 
377
{
 
378
        g_debug ("GdmFactorySlave: Relay disconnected");
 
379
 
 
380
        /* FIXME: do some kind of loop detection */
 
381
        gdm_greeter_server_reset (slave->priv->greeter_server);
 
382
        create_product_display (slave);
 
383
}
 
384
 
 
385
static void
 
386
on_session_relay_connected (GdmSessionRelay *session,
 
387
                            GdmFactorySlave *slave)
 
388
{
 
389
        g_debug ("GdmFactorySlave: Relay Connected");
 
390
 
 
391
        gdm_session_start_conversation (GDM_SESSION (slave->priv->session));
 
392
}
 
393
 
 
394
static void
 
395
on_greeter_begin_verification (GdmGreeterServer *greeter_server,
 
396
                               GdmFactorySlave  *slave)
 
397
{
 
398
        g_debug ("GdmFactorySlave: begin verification");
 
399
        gdm_session_setup (GDM_SESSION (slave->priv->session),
 
400
                           "gdm");
 
401
}
 
402
 
 
403
static void
 
404
on_greeter_begin_verification_for_user (GdmGreeterServer *greeter_server,
 
405
                                        const char       *username,
 
406
                                        GdmFactorySlave  *slave)
 
407
{
 
408
        g_debug ("GdmFactorySlave: begin verification for user");
 
409
        gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
 
410
                                    "gdm",
 
411
                                    username);
 
412
}
 
413
 
 
414
static void
 
415
on_greeter_answer (GdmGreeterServer *greeter_server,
 
416
                   const char       *text,
 
417
                   GdmFactorySlave  *slave)
 
418
{
 
419
        g_debug ("GdmFactorySlave: Greeter answer");
 
420
        gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
 
421
}
 
422
 
 
423
static void
 
424
on_greeter_session_selected (GdmGreeterServer *greeter_server,
 
425
                             const char       *text,
 
426
                             GdmFactorySlave  *slave)
 
427
{
 
428
        gdm_session_select_session (GDM_SESSION (slave->priv->session), text);
 
429
}
 
430
 
 
431
static void
 
432
on_greeter_language_selected (GdmGreeterServer *greeter_server,
 
433
                              const char       *text,
 
434
                              GdmFactorySlave  *slave)
 
435
{
 
436
        gdm_session_select_language (GDM_SESSION (slave->priv->session), text);
 
437
}
 
438
 
 
439
static void
 
440
on_greeter_layout_selected (GdmGreeterServer *greeter_server,
 
441
                            const char       *text,
 
442
                            GdmFactorySlave  *slave)
 
443
{
 
444
        gdm_session_select_layout (GDM_SESSION (slave->priv->session), text);
 
445
}
 
446
 
 
447
static void
 
448
on_greeter_user_selected (GdmGreeterServer *greeter_server,
 
449
                          const char       *text,
 
450
                          GdmFactorySlave  *slave)
 
451
{
 
452
        gdm_session_select_user (GDM_SESSION (slave->priv->session), text);
 
453
}
 
454
 
 
455
static void
 
456
on_greeter_cancel (GdmGreeterServer *greeter_server,
 
457
                   GdmFactorySlave  *slave)
 
458
{
 
459
        gdm_session_cancel (GDM_SESSION (slave->priv->session));
 
460
}
 
461
 
 
462
static void
 
463
on_greeter_connected (GdmGreeterServer *greeter_server,
 
464
                      GdmFactorySlave  *slave)
 
465
{
 
466
        g_debug ("GdmFactorySlave: Greeter started");
 
467
 
 
468
        create_product_display (slave);
 
469
}
 
470
 
 
471
static void
 
472
setup_server (GdmFactorySlave *slave)
 
473
{
 
474
        /* Set the busy cursor */
 
475
        gdm_slave_set_busy_cursor (GDM_SLAVE (slave));
 
476
}
 
477
 
 
478
static void
 
479
run_greeter (GdmFactorySlave *slave)
 
480
{
 
481
        gboolean       display_is_local;
 
482
        char          *display_id;
 
483
        char          *display_name;
 
484
        char          *display_device;
 
485
        char          *display_hostname;
 
486
        char          *auth_file;
 
487
        char          *address;
 
488
 
 
489
        g_debug ("GdmFactorySlave: Running greeter");
 
490
 
 
491
        display_is_local = FALSE;
 
492
        display_id = NULL;
 
493
        display_name = NULL;
 
494
        auth_file = NULL;
 
495
        display_device = NULL;
 
496
        display_hostname = NULL;
 
497
 
 
498
        g_object_get (slave,
 
499
                      "display-is-local", &display_is_local,
 
500
                      "display-id", &display_id,
 
501
                      "display-name", &display_name,
 
502
                      "display-hostname", &display_hostname,
 
503
                      "display-x11-authority-file", &auth_file,
 
504
                      NULL);
 
505
 
 
506
        if (slave->priv->server != NULL) {
 
507
                display_device = gdm_server_get_display_device (slave->priv->server);
 
508
        }
 
509
 
 
510
        /* FIXME: send a signal back to the master */
 
511
 
 
512
        /* Run the init script. gdmslave suspends until script has terminated */
 
513
        gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
 
514
 
 
515
        slave->priv->greeter_server = gdm_greeter_server_new (display_id);
 
516
        g_signal_connect (slave->priv->greeter_server,
 
517
                          "begin-verification",
 
518
                          G_CALLBACK (on_greeter_begin_verification),
 
519
                          slave);
 
520
        g_signal_connect (slave->priv->greeter_server,
 
521
                          "begin-verification-for-user",
 
522
                          G_CALLBACK (on_greeter_begin_verification_for_user),
 
523
                          slave);
 
524
        g_signal_connect (slave->priv->greeter_server,
 
525
                          "query-answer",
 
526
                          G_CALLBACK (on_greeter_answer),
 
527
                          slave);
 
528
        g_signal_connect (slave->priv->greeter_server,
 
529
                          "session-selected",
 
530
                          G_CALLBACK (on_greeter_session_selected),
 
531
                          slave);
 
532
        g_signal_connect (slave->priv->greeter_server,
 
533
                          "language-selected",
 
534
                          G_CALLBACK (on_greeter_language_selected),
 
535
                          slave);
 
536
        g_signal_connect (slave->priv->greeter_server,
 
537
                          "layout-selected",
 
538
                          G_CALLBACK (on_greeter_layout_selected),
 
539
                          slave);
 
540
        g_signal_connect (slave->priv->greeter_server,
 
541
                          "user-selected",
 
542
                          G_CALLBACK (on_greeter_user_selected),
 
543
                          slave);
 
544
        g_signal_connect (slave->priv->greeter_server,
 
545
                          "connected",
 
546
                          G_CALLBACK (on_greeter_connected),
 
547
                          slave);
 
548
        g_signal_connect (slave->priv->greeter_server,
 
549
                          "cancelled",
 
550
                          G_CALLBACK (on_greeter_cancel),
 
551
                          slave);
 
552
        gdm_greeter_server_start (slave->priv->greeter_server);
 
553
 
 
554
        address = gdm_greeter_server_get_address (slave->priv->greeter_server);
 
555
 
 
556
        g_debug ("GdmFactorySlave: Creating greeter on %s %s", display_name, display_device);
 
557
        slave->priv->greeter = gdm_greeter_session_new (display_name,
 
558
                                                        display_device,
 
559
                                                        display_hostname,
 
560
                                                        display_is_local);
 
561
        g_signal_connect (slave->priv->greeter,
 
562
                          "started",
 
563
                          G_CALLBACK (on_greeter_session_start),
 
564
                          slave);
 
565
        g_signal_connect (slave->priv->greeter,
 
566
                          "stopped",
 
567
                          G_CALLBACK (on_greeter_session_stop),
 
568
                          slave);
 
569
        g_signal_connect (slave->priv->greeter,
 
570
                          "exited",
 
571
                          G_CALLBACK (on_greeter_session_exited),
 
572
                          slave);
 
573
        g_signal_connect (slave->priv->greeter,
 
574
                          "died",
 
575
                          G_CALLBACK (on_greeter_session_died),
 
576
                          slave);
 
577
        g_object_set (slave->priv->greeter,
 
578
                      "x11-authority-file", auth_file,
 
579
                      NULL);
 
580
        gdm_welcome_session_set_server_address (GDM_WELCOME_SESSION (slave->priv->greeter), address);
 
581
        gdm_welcome_session_start (GDM_WELCOME_SESSION (slave->priv->greeter));
 
582
 
 
583
        g_free (address);
 
584
 
 
585
        g_free (display_id);
 
586
        g_free (display_name);
 
587
        g_free (display_device);
 
588
        g_free (display_hostname);
 
589
        g_free (auth_file);
 
590
}
 
591
 
 
592
static gboolean
 
593
idle_connect_to_display (GdmFactorySlave *slave)
 
594
{
 
595
        gboolean res;
 
596
 
 
597
        slave->priv->connection_attempts++;
 
598
 
 
599
        g_debug ("GdmFactorySlave: Connect to display");
 
600
 
 
601
        res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave));
 
602
        if (res) {
 
603
                /* FIXME: handle wait-for-go */
 
604
 
 
605
                setup_server (slave);
 
606
                run_greeter (slave);
 
607
        } else {
 
608
                if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) {
 
609
                        g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts);
 
610
                        exit (1);
 
611
                }
 
612
                return TRUE;
 
613
        }
 
614
 
 
615
        return FALSE;
 
616
}
 
617
 
 
618
static void
 
619
on_server_ready (GdmServer       *server,
 
620
                 GdmFactorySlave *slave)
 
621
{
 
622
        g_debug ("GdmFactorySlave: Server ready");
 
623
 
 
624
        g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
 
625
}
 
626
 
 
627
static void
 
628
on_server_exited (GdmServer       *server,
 
629
                  int              exit_code,
 
630
                  GdmFactorySlave *slave)
 
631
{
 
632
        g_debug ("GdmFactorySlave: server exited with code %d\n", exit_code);
 
633
 
 
634
        gdm_slave_stopped (GDM_SLAVE (slave));
 
635
}
 
636
 
 
637
static void
 
638
on_server_died (GdmServer       *server,
 
639
                int              signal_number,
 
640
                GdmFactorySlave *slave)
 
641
{
 
642
        g_debug ("GdmFactorySlave: server died with signal %d, (%s)",
 
643
                 signal_number,
 
644
                 g_strsignal (signal_number));
 
645
 
 
646
        gdm_slave_stopped (GDM_SLAVE (slave));
 
647
}
 
648
 
 
649
static gboolean
 
650
gdm_factory_slave_run (GdmFactorySlave *slave)
 
651
{
 
652
        char    *display_name;
 
653
        char    *auth_file;
 
654
        gboolean display_is_local;
 
655
 
 
656
        g_object_get (slave,
 
657
                      "display-is-local", &display_is_local,
 
658
                      "display-name", &display_name,
 
659
                      "display-x11-authority-file", &auth_file,
 
660
                      NULL);
 
661
 
 
662
        /* if this is local display start a server if one doesn't
 
663
         * exist */
 
664
        if (display_is_local) {
 
665
                gboolean res;
 
666
 
 
667
                slave->priv->server = gdm_server_new (display_name, auth_file);
 
668
                g_signal_connect (slave->priv->server,
 
669
                                  "exited",
 
670
                                  G_CALLBACK (on_server_exited),
 
671
                                  slave);
 
672
                g_signal_connect (slave->priv->server,
 
673
                                  "died",
 
674
                                  G_CALLBACK (on_server_died),
 
675
                                  slave);
 
676
                g_signal_connect (slave->priv->server,
 
677
                                  "ready",
 
678
                                  G_CALLBACK (on_server_ready),
 
679
                                  slave);
 
680
 
 
681
                res = gdm_server_start (slave->priv->server);
 
682
                if (! res) {
 
683
                        g_warning (_("Could not start the X "
 
684
                                     "server (your graphical environment) "
 
685
                                     "due to some internal error. "
 
686
                                     "Please contact your system administrator "
 
687
                                     "or check your syslog to diagnose. "
 
688
                                     "In the meantime this display will be "
 
689
                                     "disabled.  Please restart GDM when "
 
690
                                     "the problem is corrected."));
 
691
                        exit (1);
 
692
                }
 
693
 
 
694
                g_debug ("GdmFactorySlave: Started X server");
 
695
        } else {
 
696
                g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
 
697
        }
 
698
 
 
699
        g_free (display_name);
 
700
        g_free (auth_file);
 
701
 
 
702
        return TRUE;
 
703
}
 
704
 
 
705
static gboolean
 
706
gdm_factory_slave_start (GdmSlave *slave)
 
707
{
 
708
        gboolean ret;
 
709
 
 
710
        ret = FALSE;
 
711
 
 
712
        g_debug ("GdmFactorySlave: Starting factory slave");
 
713
 
 
714
        GDM_SLAVE_CLASS (gdm_factory_slave_parent_class)->start (slave);
 
715
 
 
716
        GDM_FACTORY_SLAVE (slave)->priv->session = gdm_session_relay_new ();
 
717
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
718
                          "conversation-started",
 
719
                          G_CALLBACK (on_session_conversation_started),
 
720
                          slave);
 
721
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
722
                          "setup-complete",
 
723
                          G_CALLBACK (on_session_setup_complete),
 
724
                          slave);
 
725
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
726
                          "setup-failed",
 
727
                          G_CALLBACK (on_session_setup_failed),
 
728
                          slave);
 
729
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
730
                          "reset-complete",
 
731
                          G_CALLBACK (on_session_reset_complete),
 
732
                          slave);
 
733
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
734
                          "reset-failed",
 
735
                          G_CALLBACK (on_session_reset_failed),
 
736
                          slave);
 
737
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
738
                          "authenticated",
 
739
                          G_CALLBACK (on_session_authenticated),
 
740
                          slave);
 
741
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
742
                          "authentication-failed",
 
743
                          G_CALLBACK (on_session_authentication_failed),
 
744
                          slave);
 
745
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
746
                          "authorized",
 
747
                          G_CALLBACK (on_session_authorized),
 
748
                          slave);
 
749
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
750
                          "authorization-failed",
 
751
                          G_CALLBACK (on_session_authorization_failed),
 
752
                          slave);
 
753
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
754
                          "accredited",
 
755
                          G_CALLBACK (on_session_accredited),
 
756
                          slave);
 
757
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
758
                          "accreditation-failed",
 
759
                          G_CALLBACK (on_session_accreditation_failed),
 
760
                          slave);
 
761
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
762
                          "session-opened",
 
763
                          G_CALLBACK (on_session_opened),
 
764
                          slave);
 
765
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
766
                          "session-open-failed",
 
767
                          G_CALLBACK (on_session_open_failed),
 
768
                          slave);
 
769
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
770
                          "info",
 
771
                          G_CALLBACK (on_session_info),
 
772
                          slave);
 
773
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
774
                          "problem",
 
775
                          G_CALLBACK (on_session_problem),
 
776
                          slave);
 
777
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
778
                          "info-query",
 
779
                          G_CALLBACK (on_session_info_query),
 
780
                          slave);
 
781
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
782
                          "secret-info-query",
 
783
                          G_CALLBACK (on_session_secret_info_query),
 
784
                          slave);
 
785
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
786
                          "session-started",
 
787
                          G_CALLBACK (on_session_session_started),
 
788
                          slave);
 
789
 
 
790
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
791
                          "connected",
 
792
                          G_CALLBACK (on_session_relay_connected),
 
793
                          slave);
 
794
        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
 
795
                          "disconnected",
 
796
                          G_CALLBACK (on_session_relay_disconnected),
 
797
                          slave);
 
798
 
 
799
        gdm_session_relay_start (GDM_FACTORY_SLAVE (slave)->priv->session);
 
800
 
 
801
        gdm_factory_slave_run (GDM_FACTORY_SLAVE (slave));
 
802
 
 
803
        ret = TRUE;
 
804
 
 
805
        return ret;
 
806
}
 
807
 
 
808
static gboolean
 
809
gdm_factory_slave_stop (GdmSlave *slave)
 
810
{
 
811
        g_debug ("GdmFactorySlave: Stopping factory_slave");
 
812
 
 
813
        GDM_SLAVE_CLASS (gdm_factory_slave_parent_class)->stop (slave);
 
814
 
 
815
        if (GDM_FACTORY_SLAVE (slave)->priv->session != NULL) {
 
816
                gdm_session_relay_stop (GDM_FACTORY_SLAVE (slave)->priv->session);
 
817
                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->session);
 
818
                GDM_FACTORY_SLAVE (slave)->priv->session = NULL;
 
819
        }
 
820
 
 
821
        if (GDM_FACTORY_SLAVE (slave)->priv->greeter_server != NULL) {
 
822
                gdm_greeter_server_stop (GDM_FACTORY_SLAVE (slave)->priv->greeter_server);
 
823
                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->greeter_server);
 
824
                GDM_FACTORY_SLAVE (slave)->priv->greeter_server = NULL;
 
825
        }
 
826
 
 
827
        if (GDM_FACTORY_SLAVE (slave)->priv->greeter != NULL) {
 
828
                gdm_welcome_session_stop (GDM_WELCOME_SESSION (GDM_FACTORY_SLAVE (slave)->priv->greeter));
 
829
                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->greeter);
 
830
                GDM_FACTORY_SLAVE (slave)->priv->greeter = NULL;
 
831
        }
 
832
 
 
833
        if (GDM_FACTORY_SLAVE (slave)->priv->server != NULL) {
 
834
                gdm_server_stop (GDM_FACTORY_SLAVE (slave)->priv->server);
 
835
                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->server);
 
836
                GDM_FACTORY_SLAVE (slave)->priv->server = NULL;
 
837
        }
 
838
 
 
839
        if (GDM_FACTORY_SLAVE (slave)->priv->factory_proxy != NULL) {
 
840
                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->factory_proxy);
 
841
        }
 
842
 
 
843
        return TRUE;
 
844
}
 
845
 
 
846
static void
 
847
gdm_factory_slave_set_property (GObject      *object,
 
848
                               guint          prop_id,
 
849
                               const GValue *value,
 
850
                               GParamSpec   *pspec)
 
851
{
 
852
        switch (prop_id) {
 
853
        default:
 
854
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
855
                break;
 
856
        }
 
857
}
 
858
 
 
859
static void
 
860
gdm_factory_slave_get_property (GObject    *object,
 
861
                                guint       prop_id,
 
862
                                GValue     *value,
 
863
                                GParamSpec *pspec)
 
864
{
 
865
        switch (prop_id) {
 
866
        default:
 
867
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
868
                break;
 
869
        }
 
870
}
 
871
 
 
872
static GObject *
 
873
gdm_factory_slave_constructor (GType                  type,
 
874
                               guint                  n_construct_properties,
 
875
                               GObjectConstructParam *construct_properties)
 
876
{
 
877
        GdmFactorySlave      *factory_slave;
 
878
 
 
879
        factory_slave = GDM_FACTORY_SLAVE (G_OBJECT_CLASS (gdm_factory_slave_parent_class)->constructor (type,
 
880
                                                                                                         n_construct_properties,
 
881
                                                                                                         construct_properties));
 
882
 
 
883
        return G_OBJECT (factory_slave);
 
884
}
 
885
 
 
886
static void
 
887
gdm_factory_slave_class_init (GdmFactorySlaveClass *klass)
 
888
{
 
889
        GObjectClass  *object_class = G_OBJECT_CLASS (klass);
 
890
        GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass);
 
891
 
 
892
        object_class->get_property = gdm_factory_slave_get_property;
 
893
        object_class->set_property = gdm_factory_slave_set_property;
 
894
        object_class->constructor = gdm_factory_slave_constructor;
 
895
        object_class->finalize = gdm_factory_slave_finalize;
 
896
 
 
897
        slave_class->start = gdm_factory_slave_start;
 
898
        slave_class->stop = gdm_factory_slave_stop;
 
899
 
 
900
        g_type_class_add_private (klass, sizeof (GdmFactorySlavePrivate));
 
901
 
 
902
        dbus_g_object_type_install_info (GDM_TYPE_FACTORY_SLAVE, &dbus_glib_gdm_factory_slave_object_info);
 
903
}
 
904
 
 
905
static void
 
906
gdm_factory_slave_init (GdmFactorySlave *slave)
 
907
{
 
908
        GError *error;
 
909
 
 
910
        slave->priv = GDM_FACTORY_SLAVE_GET_PRIVATE (slave);
 
911
 
 
912
        slave->priv->pid = -1;
 
913
 
 
914
        error = NULL;
 
915
        slave->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
 
916
        if (slave->priv->connection == NULL) {
 
917
                if (error != NULL) {
 
918
                        g_critical ("error getting system bus: %s", error->message);
 
919
                        g_error_free (error);
 
920
                }
 
921
                exit (1);
 
922
        }
 
923
}
 
924
 
 
925
static void
 
926
gdm_factory_slave_finalize (GObject *object)
 
927
{
 
928
        GdmFactorySlave *factory_slave;
 
929
 
 
930
        g_return_if_fail (object != NULL);
 
931
        g_return_if_fail (GDM_IS_FACTORY_SLAVE (object));
 
932
 
 
933
        factory_slave = GDM_FACTORY_SLAVE (object);
 
934
 
 
935
        g_debug ("GdmFactorySlave: Finalizing slave");
 
936
 
 
937
        g_return_if_fail (factory_slave->priv != NULL);
 
938
 
 
939
        gdm_factory_slave_stop (GDM_SLAVE (factory_slave));
 
940
 
 
941
        if (factory_slave->priv->greeter_reset_id > 0) {
 
942
                g_source_remove (factory_slave->priv->greeter_reset_id);
 
943
                factory_slave->priv->greeter_reset_id = 0;
 
944
        }
 
945
 
 
946
        G_OBJECT_CLASS (gdm_factory_slave_parent_class)->finalize (object);
 
947
}
 
948
 
 
949
GdmSlave *
 
950
gdm_factory_slave_new (const char *id)
 
951
{
 
952
        GObject *object;
 
953
 
 
954
        object = g_object_new (GDM_TYPE_FACTORY_SLAVE,
 
955
                               "display-id", id,
 
956
                               NULL);
 
957
 
 
958
        return GDM_SLAVE (object);
 
959
}