~robert-ancell/lightdm/private-mir-connection-merge

« back to all changes in this revision

Viewing changes to src/lightdm.c

  • Committer: Robert Ancell
  • Date: 2013-07-23 02:24:45 UTC
  • mfrom: (1723 trunk)
  • mto: This revision was merged to the branch mainline in revision 1741.
  • Revision ID: robert.ancell@canonical.com-20130723022445-gpaq8vtkp4hods7r
Merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
349
349
        GList *link;
350
350
 
351
351
        builder = g_variant_builder_new (G_VARIANT_TYPE ("ao"));
352
 
        for (link = seat_get_displays (seat); link; link = link->next)
 
352
        for (link = seat_get_sessions (seat); link; link = link->next)
353
353
        {
354
 
            Display *display = link->data;
 
354
            Session *session = link->data;
355
355
            BusEntry *entry;
356
 
            entry = g_hash_table_lookup (session_bus_entries, display_get_session (display));
 
356
            entry = g_hash_table_lookup (session_bus_entries, session);
357
357
            if (entry)
358
358
                g_variant_builder_add_value (builder, g_variant_new_object_path (entry->path));
359
359
        }
428
428
    for (seat_link = display_manager_get_seats (display_manager); seat_link; seat_link = seat_link->next)
429
429
    {
430
430
        Seat *seat = seat_link->data;
431
 
        GList *display_link;
 
431
        GList *session_link;
432
432
 
433
 
        for (display_link = seat_get_displays (seat); display_link; display_link = display_link->next)
 
433
        for (session_link = seat_get_sessions (seat); session_link; session_link = session_link->next)
434
434
        {
435
 
            Display *display = display_link->data;
 
435
            Session *s = session_link->data;
436
436
 
437
 
            if (display_get_session (display) == session)
 
437
            if (s == session)
438
438
                return seat;
439
439
        }
440
440
    }
520
520
    g_free (entry);
521
521
}
522
522
 
523
 
static gboolean
524
 
start_session_cb (Display *display, Seat *seat)
 
523
static void
 
524
running_user_session_cb (Seat *seat, Session *session)
525
525
{
526
 
    Session *session;
527
 
    BusEntry *seat_entry;
 
526
    static const GDBusInterfaceVTable session_vtable =
 
527
    {
 
528
        handle_session_call,
 
529
        handle_session_get_property
 
530
    };
 
531
    BusEntry *seat_entry, *entry;
528
532
    gchar *path;
529
533
 
530
 
    session = display_get_session (display);
531
 
 
532
534
    /* Set environment variables when session runs */
533
535
    seat_entry = g_hash_table_lookup (seat_bus_entries, seat);
534
536
    session_set_env (session, "XDG_SEAT_PATH", seat_entry->path);
537
539
    session_set_env (session, "XDG_SESSION_PATH", path);
538
540
    g_object_set_data_full (G_OBJECT (session), "XDG_SESSION_PATH", path, g_free);
539
541
 
540
 
    return FALSE;
541
 
}
542
 
 
543
 
static void
544
 
session_stopped_cb (Session *session, Seat *seat)
545
 
{
546
 
    g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
547
 
    g_hash_table_remove (session_bus_entries, session);
548
 
}
549
 
 
550
 
static gboolean
551
 
session_started_cb (Display *display, Seat *seat)
552
 
{
553
 
    static const GDBusInterfaceVTable session_vtable =
554
 
    {
555
 
        handle_session_call,
556
 
        handle_session_get_property
557
 
    };
558
 
    Session *session;
559
 
    BusEntry *seat_entry, *entry;
560
 
 
561
 
    session = display_get_session (display);
562
 
 
563
 
    g_signal_connect (session, "stopped", G_CALLBACK (session_stopped_cb), seat);
564
 
 
565
542
    seat_entry = g_hash_table_lookup (seat_bus_entries, seat);
566
543
    entry = bus_entry_new (g_object_get_data (G_OBJECT (session), "XDG_SESSION_PATH"), seat_entry ? seat_entry->path : NULL, "SessionRemoved");
567
544
    g_hash_table_insert (session_bus_entries, g_object_ref (session), entry);
581
558
                                   "SessionAdded",
582
559
                                   g_variant_new ("(o)", entry->path),
583
560
                                   NULL);
584
 
 
585
 
    return FALSE;
586
561
}
587
562
 
588
563
static void
589
 
display_added_cb (Seat *seat, Display *display)
 
564
session_removed_cb (Session *session, Seat *seat)
590
565
{
591
 
    g_signal_connect (display, "start-session", G_CALLBACK (start_session_cb), seat);
592
 
    g_signal_connect_after (display, "start-session", G_CALLBACK (session_started_cb), seat);
 
566
    g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
 
567
    g_hash_table_remove (session_bus_entries, session);
593
568
}
594
569
 
595
570
static void
600
575
        handle_seat_call,
601
576
        handle_seat_get_property
602
577
    };
603
 
    GList *link;
604
578
    gchar *path;
605
579
    BusEntry *entry;
606
580
 
607
 
    g_signal_connect (seat, "display-added", G_CALLBACK (display_added_cb), NULL);
608
 
    for (link = seat_get_displays (seat); link; link = link->next)
609
 
        display_added_cb (seat, (Display *) link->data);
610
 
 
611
581
    path = g_strdup_printf ("/org/freedesktop/DisplayManager/Seat%d", seat_index);
612
582
    seat_index++;
613
583
 
630
600
                                   "SeatAdded",
631
601
                                   g_variant_new ("(o)", entry->path),
632
602
                                   NULL);
 
603
 
 
604
    g_signal_connect (seat, "running-user-session", G_CALLBACK (running_user_session_cb), NULL);
 
605
    g_signal_connect (seat, "session-removed", G_CALLBACK (session_removed_cb), NULL);
633
606
}
634
607
 
635
608
static void
638
611
    g_hash_table_remove (seat_bus_entries, seat);
639
612
}
640
613
 
 
614
static gboolean
 
615
xdmcp_session_cb (XDMCPServer *server, XDMCPSession *session)
 
616
{
 
617
    SeatXDMCPSession *seat;
 
618
    gboolean result;
 
619
 
 
620
    seat = seat_xdmcp_session_new (session);
 
621
    set_seat_properties (SEAT (seat), NULL);
 
622
    result = display_manager_add_seat (display_manager, SEAT (seat));
 
623
    g_object_unref (seat);
 
624
 
 
625
    return result;
 
626
}
 
627
 
 
628
static void
 
629
vnc_connection_cb (VNCServer *server, GSocket *connection)
 
630
{
 
631
    SeatXVNC *seat;
 
632
 
 
633
    seat = seat_xvnc_new (connection);
 
634
    set_seat_properties (SEAT (seat), NULL);
 
635
    display_manager_add_seat (display_manager, SEAT (seat));
 
636
    g_object_unref (seat);
 
637
}
 
638
 
641
639
static void
642
640
bus_acquired_cb (GDBusConnection *connection,
643
641
                 const gchar     *name,
730
728
    g_signal_connect (display_manager, "seat-removed", G_CALLBACK (seat_removed_cb), NULL);
731
729
    for (link = display_manager_get_seats (display_manager); link; link = link->next)
732
730
        seat_added_cb (display_manager, (Seat *) link->data);
 
731
 
 
732
    display_manager_start (display_manager);
 
733
 
 
734
    /* Start the XDMCP server */
 
735
    if (config_get_boolean (config_get_instance (), "XDMCPServer", "enabled"))
 
736
    {
 
737
        gchar *key_name, *key = NULL;
 
738
 
 
739
        xdmcp_server = xdmcp_server_new ();
 
740
        if (config_has_key (config_get_instance (), "XDMCPServer", "port"))
 
741
        {
 
742
            gint port;
 
743
            port = config_get_integer (config_get_instance (), "XDMCPServer", "port");
 
744
            if (port > 0)
 
745
                xdmcp_server_set_port (xdmcp_server, port);
 
746
        }
 
747
        g_signal_connect (xdmcp_server, "new-session", G_CALLBACK (xdmcp_session_cb), NULL);
 
748
 
 
749
        key_name = config_get_string (config_get_instance (), "XDMCPServer", "key");
 
750
        if (key_name)
 
751
        {
 
752
            gchar *dir, *path;
 
753
            GKeyFile *keys;
 
754
            gboolean result;
 
755
            GError *error = NULL;
 
756
 
 
757
            dir = config_get_string (config_get_instance (), "LightDM", "config-directory");
 
758
            path = g_build_filename (dir, "keys.conf", NULL);
 
759
            g_free (dir);
 
760
 
 
761
            keys = g_key_file_new ();
 
762
            result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
 
763
            if (error)
 
764
                g_debug ("Error getting key %s", error->message);
 
765
            g_clear_error (&error);
 
766
 
 
767
            if (result)
 
768
            {
 
769
                if (g_key_file_has_key (keys, "keyring", key_name, NULL))
 
770
                    key = g_key_file_get_string (keys, "keyring", key_name, NULL);
 
771
                else
 
772
                    g_debug ("Key %s not defined", key_name);
 
773
            }
 
774
            g_free (path);
 
775
            g_key_file_free (keys);
 
776
        }
 
777
        if (key)
 
778
            xdmcp_server_set_key (xdmcp_server, key);
 
779
        g_free (key_name);
 
780
        g_free (key);
 
781
 
 
782
        g_debug ("Starting XDMCP server on UDP/IP port %d", xdmcp_server_get_port (xdmcp_server));
 
783
        xdmcp_server_start (xdmcp_server);
 
784
    }
 
785
 
 
786
    /* Start the VNC server */
 
787
    if (config_get_boolean (config_get_instance (), "VNCServer", "enabled"))
 
788
    {
 
789
        gchar *path;
 
790
 
 
791
        path = g_find_program_in_path ("Xvnc");
 
792
        if (path)
 
793
        {
 
794
            vnc_server = vnc_server_new ();
 
795
            if (config_has_key (config_get_instance (), "VNCServer", "port"))
 
796
            {
 
797
                gint port;
 
798
                port = config_get_integer (config_get_instance (), "VNCServer", "port");
 
799
                if (port > 0)
 
800
                    vnc_server_set_port (vnc_server, port);
 
801
            }
 
802
            g_signal_connect (vnc_server, "new-connection", G_CALLBACK (vnc_connection_cb), NULL);
 
803
 
 
804
            g_debug ("Starting VNC server on TCP/IP port %d", vnc_server_get_port (vnc_server));
 
805
            vnc_server_start (vnc_server);
 
806
 
 
807
            g_free (path);
 
808
        }
 
809
        else
 
810
            g_warning ("Can't start VNC server, Xvn is not in the path");
 
811
    }
733
812
}
734
813
 
735
814
static void
763
842
    return abs_path;
764
843
}
765
844
 
766
 
static gboolean
767
 
xdmcp_session_cb (XDMCPServer *server, XDMCPSession *session)
768
 
{
769
 
    SeatXDMCPSession *seat;
770
 
    gboolean result;
771
 
 
772
 
    seat = seat_xdmcp_session_new (session);
773
 
    set_seat_properties (SEAT (seat), NULL);
774
 
    result = display_manager_add_seat (display_manager, SEAT (seat));
775
 
    g_object_unref (seat);
776
 
 
777
 
    return result;
778
 
}
779
 
 
780
 
static void
781
 
vnc_connection_cb (VNCServer *server, GSocket *connection)
782
 
{
783
 
    SeatXVNC *seat;
784
 
 
785
 
    seat = seat_xvnc_new (connection);
786
 
    set_seat_properties (SEAT (seat), NULL);
787
 
    display_manager_add_seat (display_manager, SEAT (seat));
788
 
    g_object_unref (seat);
789
 
}
790
 
 
791
845
static int
792
846
compare_strings (gconstpointer a, gconstpointer b)
793
847
{
805
859
    gboolean explicit_config = FALSE;
806
860
    gboolean test_mode = FALSE;
807
861
    gchar *pid_path = "/var/run/lightdm.pid";
808
 
    gchar *xsessions_dir = NULL;
809
 
    gchar *remote_sessions_dir = NULL;
810
 
    gchar *xgreeters_dir = NULL;
811
862
    gchar *config_dir, *config_d_dir = NULL;
812
863
    gchar *log_dir = NULL;
813
864
    gchar *run_dir = NULL;
831
882
        { "pid-file", 0, 0, G_OPTION_ARG_STRING, &pid_path,
832
883
          /* Help string for command line --pid-file flag */
833
884
          N_("File to write PID into"), "FILE" },
834
 
        { "xsessions-dir", 0, 0, G_OPTION_ARG_STRING, &xsessions_dir,
835
 
          /* Help string for command line --xsessions-dir flag */
836
 
          N_("Directory to load X sessions from"), "DIRECTORY" },
837
 
        { "remote-sessions-dir", 0, 0, G_OPTION_ARG_STRING, &remote_sessions_dir,
838
 
          /* Help string for command line --remote-sessions-dir flag */
839
 
          N_("Directory to load remote sessions from"), "DIRECTORY" },
840
 
        { "xgreeters-dir", 0, 0, G_OPTION_ARG_STRING, &xgreeters_dir,
841
 
          /* Help string for command line --xgreeters-dir flag */
842
 
          N_("Directory to load X greeters from"), "DIRECTORY" },
843
885
        { "log-dir", 0, 0, G_OPTION_ARG_STRING, &log_dir,
844
886
          /* Help string for command line --log-dir flag */
845
887
          N_("Directory to write logs to"), "DIRECTORY" },
949
991
        fclose (pid_file);
950
992
    }
951
993
 
952
 
    /* Always use absolute directories as child processes may run from different locations */
953
 
    xsessions_dir = path_make_absolute (xsessions_dir);
954
 
    remote_sessions_dir = path_make_absolute (remote_sessions_dir);
955
 
    xgreeters_dir = path_make_absolute (xgreeters_dir);
956
 
 
957
994
    /* If not running as root write output to directories we control */
958
995
    if (getuid () != 0)
959
996
    {
985
1022
    if (config_d_dir)
986
1023
    {
987
1024
        GDir *dir;
988
 
        GList *files, *link;
989
 
        GKeyFile *f;
 
1025
        GList *files = NULL, *link;
990
1026
 
991
1027
        /* Find configuration files */
992
1028
        dir = g_dir_open (config_d_dir, 0, &error);
1067
1103
    if (!config_has_key (config_get_instance (), "LightDM", "cache-directory"))
1068
1104
        config_set_string (config_get_instance (), "LightDM", "cache-directory", default_cache_dir);
1069
1105
    g_free (default_cache_dir);
1070
 
    if (!config_has_key (config_get_instance (), "LightDM", "xsessions-directory"))
1071
 
        config_set_string (config_get_instance (), "LightDM", "xsessions-directory", XSESSIONS_DIR);
 
1106
    if (!config_has_key (config_get_instance (), "LightDM", "sessions-directory"))
 
1107
        config_set_string (config_get_instance (), "LightDM", "sessions-directory", SESSIONS_DIR);
1072
1108
    if (!config_has_key (config_get_instance (), "LightDM", "remote-sessions-directory"))
1073
1109
        config_set_string (config_get_instance (), "LightDM", "remote-sessions-directory", REMOTE_SESSIONS_DIR);
1074
 
    if (!config_has_key (config_get_instance (), "LightDM", "xgreeters-directory"))
1075
 
        config_set_string (config_get_instance (), "LightDM", "xgreeters-directory", XGREETERS_DIR);
 
1110
    if (!config_has_key (config_get_instance (), "LightDM", "greeters-directory"))
 
1111
        config_set_string (config_get_instance (), "LightDM", "greeters-directory", GREETERS_DIR);
1076
1112
 
1077
1113
    /* Override defaults */
1078
1114
    if (log_dir)
1084
1120
    if (cache_dir)
1085
1121
        config_set_string (config_get_instance (), "LightDM", "cache-directory", cache_dir);
1086
1122
    g_free (cache_dir);
1087
 
    if (xsessions_dir)
1088
 
        config_set_string (config_get_instance (), "LightDM", "xsessions-directory", xsessions_dir);
1089
 
    g_free (xsessions_dir);
1090
 
    if (remote_sessions_dir)
1091
 
        config_set_string (config_get_instance (), "LightDM", "remote-sessions-directory", remote_sessions_dir);
1092
 
    g_free (remote_sessions_dir);
1093
 
    if (xgreeters_dir)
1094
 
        config_set_string (config_get_instance (), "LightDM", "xgreeters-directory", xgreeters_dir);
1095
 
    g_free (xgreeters_dir);
1096
1123
 
1097
1124
    /* Create run and cache directories */
1098
1125
    dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
1112
1139
 
1113
1140
    /* Show queued messages once logging is complete */
1114
1141
    for (link = messages; link; link = link->next)
1115
 
        g_debug ("%s", link->data);
 
1142
        g_debug ("%s", (gchar *)link->data);
1116
1143
    g_list_free_full (messages, g_free);
1117
1144
 
1118
1145
    g_debug ("Using D-Bus name %s", LIGHTDM_BUS_NAME);
1178
1205
        {
1179
1206
            set_seat_properties (seat, NULL);
1180
1207
            seat_set_property (seat, "exit-on-failure", "true");
1181
 
            display_manager_add_seat (display_manager, seat);
 
1208
            if (!display_manager_add_seat (display_manager, seat))
 
1209
                return EXIT_FAILURE;
1182
1210
            g_object_unref (seat);
1183
1211
        }
1184
1212
        else
1188
1216
        }
1189
1217
    }
1190
1218
 
1191
 
    display_manager_start (display_manager);
1192
 
 
1193
 
    /* Start the XDMCP server */
1194
 
    if (config_get_boolean (config_get_instance (), "XDMCPServer", "enabled"))
1195
 
    {
1196
 
        gchar *key_name, *key = NULL;
1197
 
 
1198
 
        xdmcp_server = xdmcp_server_new ();
1199
 
        if (config_has_key (config_get_instance (), "XDMCPServer", "port"))
1200
 
        {
1201
 
            gint port;
1202
 
            port = config_get_integer (config_get_instance (), "XDMCPServer", "port");
1203
 
            if (port > 0)
1204
 
                xdmcp_server_set_port (xdmcp_server, port);
1205
 
        }
1206
 
        g_signal_connect (xdmcp_server, "new-session", G_CALLBACK (xdmcp_session_cb), NULL);
1207
 
 
1208
 
        key_name = config_get_string (config_get_instance (), "XDMCPServer", "key");
1209
 
        if (key_name)
1210
 
        {
1211
 
            gchar *dir, *path;
1212
 
            GKeyFile *keys;
1213
 
            gboolean result;
1214
 
            GError *error = NULL;
1215
 
 
1216
 
            dir = config_get_string (config_get_instance (), "LightDM", "config-directory");
1217
 
            path = g_build_filename (dir, "keys.conf", NULL);
1218
 
            g_free (dir);
1219
 
 
1220
 
            keys = g_key_file_new ();
1221
 
            result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
1222
 
            if (error)
1223
 
                g_debug ("Error getting key %s", error->message);
1224
 
            g_clear_error (&error);
1225
 
 
1226
 
            if (result)
1227
 
            {
1228
 
                if (g_key_file_has_key (keys, "keyring", key_name, NULL))
1229
 
                    key = g_key_file_get_string (keys, "keyring", key_name, NULL);
1230
 
                else
1231
 
                    g_debug ("Key %s not defined", key_name);
1232
 
            }
1233
 
            g_free (path);
1234
 
            g_key_file_free (keys);
1235
 
        }
1236
 
        if (key)
1237
 
            xdmcp_server_set_key (xdmcp_server, key);
1238
 
        g_free (key_name);
1239
 
        g_free (key);
1240
 
 
1241
 
        g_debug ("Starting XDMCP server on UDP/IP port %d", xdmcp_server_get_port (xdmcp_server));
1242
 
        xdmcp_server_start (xdmcp_server);
1243
 
    }
1244
 
 
1245
 
    /* Start the VNC server */
1246
 
    if (config_get_boolean (config_get_instance (), "VNCServer", "enabled"))
1247
 
    {
1248
 
        gchar *path;
1249
 
 
1250
 
        path = g_find_program_in_path ("Xvnc");
1251
 
        if (path)
1252
 
        {
1253
 
            vnc_server = vnc_server_new ();
1254
 
            if (config_has_key (config_get_instance (), "VNCServer", "port"))
1255
 
            {
1256
 
                gint port;
1257
 
                port = config_get_integer (config_get_instance (), "VNCServer", "port");
1258
 
                if (port > 0)
1259
 
                    vnc_server_set_port (vnc_server, port);
1260
 
            }
1261
 
            g_signal_connect (vnc_server, "new-connection", G_CALLBACK (vnc_connection_cb), NULL);
1262
 
 
1263
 
            g_debug ("Starting VNC server on TCP/IP port %d", vnc_server_get_port (vnc_server));
1264
 
            vnc_server_start (vnc_server);
1265
 
 
1266
 
            g_free (path);
1267
 
        }
1268
 
        else
1269
 
            g_warning ("Can't start VNC server, Xvn is not in the path");
1270
 
    }
1271
 
 
1272
1219
    g_main_loop_run (loop);
1273
1220
 
1274
1221
    /* Clean up display manager */