~lightdm-team/lightdm/1.4

« back to all changes in this revision

Viewing changes to liblightdm-gobject/greeter.c

  • Committer: Robert Ancell
  • Date: 2011-05-05 06:11:16 UTC
  • Revision ID: robert.ancell@canonical.com-20110505061116-4nhrdw6k0huve3ek
Move user manager into liblightdm

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 */
11
11
 
12
12
#include <stdlib.h>
 
13
#include <errno.h>
13
14
#include <string.h>
14
15
#include <locale.h>
15
16
#include <sys/utsname.h>
16
 
 
 
17
#include <pwd.h>
17
18
#include <gio/gdesktopappinfo.h>
18
19
#include <security/pam_appl.h>
19
20
#include <libxklavier/xklavier.h>
64
65
 
65
66
    GDBusConnection *system_bus;
66
67
 
67
 
    GDBusProxy *session_proxy, *user_proxy;
 
68
    GDBusProxy *lightdm_proxy;
68
69
 
69
70
    GIOChannel *to_server_channel, *from_server_channel;
70
71
    gchar *read_buffer;
74
75
 
75
76
    gchar *hostname;
76
77
 
 
78
    /* Configuration file */
 
79
    GKeyFile *config;
 
80
 
77
81
    gchar *theme;
78
82
    GKeyFile *theme_file;
79
83
 
 
84
    /* File monitor for password file */
 
85
    GFileMonitor *passwd_monitor;
 
86
 
 
87
    /* TRUE if have scanned users */
80
88
    gboolean have_users;
 
89
 
 
90
    /* List of users */
81
91
    GList *users;
82
92
 
83
93
    gboolean have_languages;
254
264
}
255
265
 
256
266
static gboolean
257
 
from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
 
267
read_packet (LdmGreeter *greeter, gboolean block)
258
268
{
259
 
    LdmGreeter *greeter = data;
260
 
    gsize n_to_read, n_read, offset;
261
 
    GIOStatus status;
262
 
    guint32 id, return_code;
 
269
    gsize n_to_read, n_read;
263
270
    GError *error = NULL;
264
271
 
 
272
    /* Read the header, or the whole packet if we already have that */
265
273
    n_to_read = HEADER_SIZE;
266
274
    if (greeter->priv->n_read >= HEADER_SIZE)
267
275
        n_to_read += get_packet_length (greeter);
268
276
 
269
 
    status = g_io_channel_read_chars (greeter->priv->from_server_channel,
270
 
                                      greeter->priv->read_buffer + greeter->priv->n_read,
271
 
                                      n_to_read - greeter->priv->n_read,
272
 
                                      &n_read,
273
 
                                      &error);
274
 
    if (status != G_IO_STATUS_NORMAL)
275
 
        g_warning ("Error reading from server: %s", error->message);
276
 
    g_clear_error (&error);
277
 
    if (status != G_IO_STATUS_NORMAL)
278
 
        return TRUE;
279
 
 
280
 
    greeter->priv->n_read += n_read;
 
277
    do
 
278
    {
 
279
        GIOStatus status;
 
280
        status = g_io_channel_read_chars (greeter->priv->from_server_channel,
 
281
                                          greeter->priv->read_buffer + greeter->priv->n_read,
 
282
                                          n_to_read - greeter->priv->n_read,
 
283
                                          &n_read,
 
284
                                          &error);
 
285
        if (status == G_IO_STATUS_ERROR)
 
286
            g_warning ("Error reading from server: %s", error->message);
 
287
        g_clear_error (&error);
 
288
        if (status != G_IO_STATUS_NORMAL)
 
289
            break;
 
290
 
 
291
        greeter->priv->n_read += n_read;
 
292
    } while (greeter->priv->n_read < n_to_read && block);
 
293
 
 
294
    /* Stop if haven't got all the data we want */
281
295
    if (greeter->priv->n_read != n_to_read)
282
 
        return TRUE;
 
296
        return FALSE;
283
297
 
284
298
    /* If have header, rerun for content */
285
299
    if (greeter->priv->n_read == HEADER_SIZE)
288
302
        if (n_to_read > 0)
289
303
        {
290
304
            greeter->priv->read_buffer = g_realloc (greeter->priv->read_buffer, HEADER_SIZE + n_to_read);
291
 
            return from_server_cb (source, condition, data);
 
305
            return read_packet (greeter, block);
292
306
        }
293
307
    }
294
308
 
 
309
    return TRUE;
 
310
}
 
311
 
 
312
static gboolean
 
313
from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
 
314
{
 
315
    LdmGreeter *greeter = data;
 
316
    gsize offset;
 
317
    guint32 id, return_code;
 
318
  
 
319
    if (!read_packet (greeter, FALSE))
 
320
        return TRUE;
 
321
 
295
322
    offset = 0;
296
323
    id = read_int (greeter, &offset);
297
324
    read_int (greeter, &offset);
400
427
    g_io_channel_set_encoding (greeter->priv->from_server_channel, NULL, NULL);
401
428
    g_io_add_watch (greeter->priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
402
429
 
403
 
    greeter->priv->session_proxy = g_dbus_proxy_new_sync (greeter->priv->lightdm_bus,
 
430
    greeter->priv->lightdm_proxy = g_dbus_proxy_new_sync (greeter->priv->lightdm_bus,
404
431
                                                          G_DBUS_PROXY_FLAGS_NONE,
405
432
                                                          NULL,
406
433
                                                          "org.lightdm.LightDisplayManager",
407
 
                                                          "/org/lightdm/LightDisplayManager/Session",
408
 
                                                          "org.lightdm.LightDisplayManager.Session",
 
434
                                                          "/org/lightdm/LightDisplayManager",
 
435
                                                          "org.lightdm.LightDisplayManager",
409
436
                                                          NULL, NULL);
410
 
    greeter->priv->user_proxy = g_dbus_proxy_new_sync (greeter->priv->lightdm_bus,
411
 
                                                       G_DBUS_PROXY_FLAGS_NONE,
412
 
                                                       NULL,
413
 
                                                       "org.lightdm.LightDisplayManager",
414
 
                                                       "/org/lightdm/LightDisplayManager/Users",
415
 
                                                       "org.lightdm.LightDisplayManager.Users",
416
 
                                                       NULL, NULL);
417
437
 
418
438
    g_debug ("Connecting to display manager...");
419
439
    write_header (greeter, GREETER_MESSAGE_CONNECT, 0);
563
583
    return NULL;
564
584
}
565
585
  
566
 
static void
567
 
user_changed_cb (GDBusConnection *connection,
568
 
                 const gchar *sender_name,
569
 
                 const gchar *object_path,
570
 
                 const gchar *interface_name,
571
 
                 const gchar *signal_name,
572
 
                 GVariant *parameters,
573
 
                 gpointer user_data)
574
 
{
575
 
    LdmGreeter *greeter = user_data;
576
 
    gchar *username, *real_name, *image;
577
 
    gboolean logged_in;
578
 
    LdmUser *user;
579
 
 
580
 
    if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sssb)")))
581
 
    {
582
 
        g_warning ("Unknown type in %s signal", signal_name);
583
 
        return;
584
 
    }
585
 
 
586
 
    g_variant_get (parameters, "(sssb)", &username, &real_name, &image, &logged_in);
587
 
 
588
 
    user = get_user_by_name (greeter, username);
589
 
    if (user)
590
 
    {
591
 
        g_debug ("User %s changed", username);
592
 
        ldm_user_set_real_name (user, real_name);
593
 
        ldm_user_set_image (user, image);
594
 
        ldm_user_set_logged_in (user, logged_in);
595
 
        g_signal_emit (greeter, signals[USER_CHANGED], 0, user);
596
 
    }
597
 
    else
598
 
    {
599
 
        g_debug ("User %s added", username);
600
 
        user = ldm_user_new (greeter, username, real_name, image, logged_in);
601
 
        greeter->priv->users = g_list_append (greeter->priv->users, user);
602
 
        g_signal_emit (greeter, signals[USER_ADDED], 0, user);
603
 
    }
604
 
 
605
 
    g_free (username);
606
 
    g_free (real_name);
607
 
    g_free (image);
608
 
}
609
 
 
610
 
static void
611
 
user_removed_cb (GDBusConnection *connection,
612
 
                 const gchar *sender_name,
613
 
                 const gchar *object_path,
614
 
                 const gchar *interface_name,
615
 
                 const gchar *signal_name,
616
 
                 GVariant *parameters,
617
 
                 gpointer user_data)
618
 
{
619
 
    LdmGreeter *greeter = user_data;
620
 
    gchar *username;
621
 
    LdmUser *user;
622
 
 
623
 
    if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)")))
624
 
    {
625
 
        g_warning ("Unknown type in %s signal", signal_name);
626
 
        return;
627
 
    }
628
 
 
629
 
    g_variant_get (parameters, "(s)", &username);
630
 
 
631
 
    user = get_user_by_name (greeter, username);
632
 
    if (user)
633
 
    {
634
 
        g_debug ("User %s removed", username);
635
 
        greeter->priv->users = g_list_remove (greeter->priv->users, user);
636
 
        g_signal_emit (greeter, signals[USER_REMOVED], 0, user);      
637
 
        g_object_unref (user);
638
 
    }
639
 
 
640
 
    g_free (username);
 
586
static gint
 
587
compare_user (gconstpointer a, gconstpointer b)
 
588
{
 
589
    LdmUser *user_a = (LdmUser *) a, *user_b = (LdmUser *) b;
 
590
    return strcmp (ldm_user_get_display_name (user_a), ldm_user_get_display_name (user_b));
 
591
}
 
592
 
 
593
static void
 
594
load_config (LdmGreeter *greeter)
 
595
{
 
596
    GVariant *result;
 
597
    const gchar *config_path = NULL;
 
598
 
 
599
    if (greeter->priv->config)
 
600
        return;
 
601
 
 
602
    result = g_dbus_proxy_get_cached_property (greeter->priv->lightdm_proxy,
 
603
                                               "ConfigFile");
 
604
    if (!result)
 
605
    {
 
606
        g_warning ("No ConfigFile property");
 
607
        return;
 
608
    }
 
609
 
 
610
    if (g_variant_is_of_type (result, G_VARIANT_TYPE_STRING))
 
611
        config_path = g_variant_get_string (result, NULL);
 
612
    else
 
613
        g_warning ("Invalid type for config file: %s, expected string", g_variant_get_type_string (result));
 
614
 
 
615
    if (config_path)
 
616
    {
 
617
        GError *error = NULL;
 
618
 
 
619
        g_debug ("Loading config from %s", config_path);
 
620
 
 
621
        greeter->priv->config = g_key_file_new ();
 
622
        if (!g_key_file_load_from_file (greeter->priv->config, config_path, G_KEY_FILE_NONE, &error))
 
623
            g_warning ("Failed to load configuration from %s: %s", config_path, error->message); // FIXME: Don't make warning on no file, just info
 
624
        g_clear_error (&error);
 
625
    }
 
626
 
 
627
    g_variant_unref (result);
 
628
}
 
629
  
 
630
static void
 
631
load_users (LdmGreeter *greeter)
 
632
{
 
633
    gchar **hidden_users, **hidden_shells;
 
634
    gchar *value;
 
635
    gint minimum_uid;
 
636
    GList *users = NULL, *old_users, *new_users = NULL, *changed_users = NULL, *link;
 
637
 
 
638
    load_config (greeter);
 
639
 
 
640
    if (g_key_file_has_key (greeter->priv->config, "UserManager", "minimum-uid", NULL))
 
641
        minimum_uid = g_key_file_get_integer (greeter->priv->config, "UserManager", "minimum-uid", NULL);
 
642
    else
 
643
        minimum_uid = 500;
 
644
 
 
645
    value = g_key_file_get_string (greeter->priv->config, "UserManager", "hidden-users", NULL);
 
646
    if (!value)
 
647
        value = g_strdup ("nobody nobody4 noaccess");
 
648
    hidden_users = g_strsplit (value, " ", -1);
 
649
    g_free (value);
 
650
 
 
651
    value = g_key_file_get_string (greeter->priv->config, "UserManager", "hidden-shells", NULL);
 
652
    if (!value)
 
653
        value = g_strdup ("/bin/false /usr/sbin/nologin");
 
654
    hidden_shells = g_strsplit (value, " ", -1);
 
655
    g_free (value);
 
656
 
 
657
    setpwent ();
 
658
 
 
659
    while (TRUE)
 
660
    {
 
661
        struct passwd *entry;
 
662
        LdmUser *user;
 
663
        char **tokens;
 
664
        gchar *real_name, *image_path, *image;
 
665
        int i;
 
666
 
 
667
        errno = 0;
 
668
        entry = getpwent ();
 
669
        if (!entry)
 
670
            break;
 
671
 
 
672
        /* Ignore system users */
 
673
        if (entry->pw_uid < minimum_uid)
 
674
            continue;
 
675
 
 
676
        /* Ignore users disabled by shell */
 
677
        if (entry->pw_shell)
 
678
        {
 
679
            for (i = 0; hidden_shells[i] && strcmp (entry->pw_shell, hidden_shells[i]) != 0; i++);
 
680
            if (hidden_shells[i])
 
681
                continue;
 
682
        }
 
683
 
 
684
        /* Ignore certain users */
 
685
        for (i = 0; hidden_users[i] && strcmp (entry->pw_name, hidden_users[i]) != 0; i++);
 
686
        if (hidden_users[i])
 
687
            continue;
 
688
 
 
689
        tokens = g_strsplit (entry->pw_gecos, ",", -1);
 
690
        if (tokens[0] != NULL && tokens[0][0] != '\0')
 
691
            real_name = g_strdup (tokens[0]);
 
692
        else
 
693
            real_name = NULL;
 
694
        g_strfreev (tokens);
 
695
      
 
696
        image_path = g_build_filename (entry->pw_dir, ".face", NULL);
 
697
        if (!g_file_test (image_path, G_FILE_TEST_EXISTS))
 
698
        {
 
699
            g_free (image_path);
 
700
            image_path = g_build_filename (entry->pw_dir, ".face.icon", NULL);
 
701
            if (!g_file_test (image_path, G_FILE_TEST_EXISTS))
 
702
            {
 
703
                g_free (image_path);
 
704
                image_path = NULL;
 
705
            }
 
706
        }
 
707
        if (image_path)
 
708
            image = g_filename_to_uri (image_path, NULL, NULL);
 
709
        else
 
710
            image = NULL;
 
711
        g_free (image_path);
 
712
 
 
713
        user = ldm_user_new (greeter, entry->pw_name, real_name, entry->pw_dir, image, FALSE);
 
714
        g_free (real_name);
 
715
        g_free (image);
 
716
 
 
717
        /* Update existing users if have them */
 
718
        for (link = greeter->priv->users; link; link = link->next)
 
719
        {
 
720
            LdmUser *info = link->data;
 
721
            if (strcmp (ldm_user_get_name (info), ldm_user_get_name (user)) == 0)
 
722
            {
 
723
                // FIXME: Use changed signal from user object?
 
724
                if (g_strcmp0 (ldm_user_get_real_name (info), ldm_user_get_real_name (user)) != 0 ||
 
725
                    g_strcmp0 (ldm_user_get_image (info), ldm_user_get_image (user)) != 0 ||
 
726
                    g_strcmp0 (ldm_user_get_home_directory (info), ldm_user_get_home_directory (user)) != 0 ||
 
727
                    ldm_user_get_logged_in (info) != ldm_user_get_logged_in (user))
 
728
                {
 
729
                    ldm_user_set_real_name (info, ldm_user_get_real_name (user));
 
730
                    ldm_user_set_image (info, ldm_user_get_image (user));
 
731
                    ldm_user_set_home_directory (info, ldm_user_get_home_directory (user));
 
732
                    ldm_user_set_logged_in (info, ldm_user_get_logged_in (user));
 
733
                    g_object_unref (user);
 
734
                    user = info;
 
735
                    changed_users = g_list_insert_sorted (changed_users, user, compare_user);
 
736
                }
 
737
                else
 
738
                {
 
739
                    g_object_unref (user);
 
740
                    user = info;
 
741
                }
 
742
                break;
 
743
            }
 
744
        }
 
745
        if (!link)
 
746
        {
 
747
            /* Only notify once we have loaded the user list */
 
748
            if (greeter->priv->have_users)
 
749
                new_users = g_list_insert_sorted (new_users, user, compare_user);
 
750
        }
 
751
        users = g_list_insert_sorted (users, user, compare_user);
 
752
    }
 
753
    g_strfreev (hidden_users);
 
754
    g_strfreev (hidden_shells);
 
755
 
 
756
    if (errno != 0)
 
757
        g_warning ("Failed to read password database: %s", strerror (errno));
 
758
 
 
759
    endpwent ();
 
760
 
 
761
    /* Use new user list */
 
762
    old_users = greeter->priv->users;
 
763
    greeter->priv->users = users;
 
764
 
 
765
    /* Notify of changes */
 
766
    for (link = new_users; link; link = link->next)
 
767
    {
 
768
        LdmUser *info = link->data;
 
769
        g_debug ("User %s added", ldm_user_get_name (info));
 
770
        g_signal_emit (greeter, signals[USER_ADDED], 0, info);
 
771
    }
 
772
    g_list_free (new_users);
 
773
    for (link = changed_users; link; link = link->next)
 
774
    {
 
775
        LdmUser *info = link->data;
 
776
        g_debug ("User %s changed", ldm_user_get_name (info));
 
777
        g_signal_emit (greeter, signals[USER_CHANGED], 0, info);
 
778
    }
 
779
    g_list_free (changed_users);
 
780
    for (link = old_users; link; link = link->next)
 
781
    {
 
782
        GList *new_link;
 
783
 
 
784
        /* See if this user is in the current list */
 
785
        for (new_link = greeter->priv->users; new_link; new_link = new_link->next)
 
786
        {
 
787
            if (new_link->data == link->data)
 
788
                break;
 
789
        }
 
790
 
 
791
        if (!new_link)
 
792
        {
 
793
            LdmUser *info = link->data;
 
794
            g_debug ("User %s removed", ldm_user_get_name (info));
 
795
            g_signal_emit (greeter, signals[USER_REMOVED], 0, info);
 
796
            g_object_unref (info);
 
797
        }
 
798
    }
 
799
    g_list_free (old_users);
 
800
}
 
801
 
 
802
static void
 
803
passwd_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, LdmGreeter *greeter)
 
804
{
 
805
    if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
 
806
    {
 
807
        g_debug ("%s changed, reloading user list", g_file_get_path (file));
 
808
        load_users (greeter);
 
809
    }
641
810
}
642
811
 
643
812
static void
644
813
update_users (LdmGreeter *greeter)
645
814
{
646
 
    GVariant *result, *user_array;
647
 
    GVariantIter iter;
648
 
    gchar *name, *real_name, *image;
649
 
    gboolean logged_in;
 
815
    GFile *passwd_file;
650
816
    GError *error = NULL;
651
817
 
652
818
    if (greeter->priv->have_users)
653
819
        return;
654
820
 
655
 
    g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus,
656
 
                                        "org.lightdm.LightDisplayManager",
657
 
                                        "org.lightdm.LightDisplayManager.Users",
658
 
                                        "UserAdded",
659
 
                                        "/org/lightdm/LightDisplayManager/Users",
660
 
                                        NULL,
661
 
                                        G_DBUS_SIGNAL_FLAGS_NONE,
662
 
                                        user_changed_cb,
663
 
                                        greeter,
664
 
                                        NULL);
665
 
    g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus,
666
 
                                        "org.lightdm.LightDisplayManager",
667
 
                                        "org.lightdm.LightDisplayManager.Users",
668
 
                                        "UserChanged",
669
 
                                        "/org/lightdm/LightDisplayManager/Users",
670
 
                                        NULL,
671
 
                                        G_DBUS_SIGNAL_FLAGS_NONE,
672
 
                                        user_changed_cb,
673
 
                                        greeter,
674
 
                                        NULL);
675
 
    g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus,
676
 
                                        "org.lightdm.LightDisplayManager",
677
 
                                        "org.lightdm.LightDisplayManager.Users",
678
 
                                        "UserRemoved",
679
 
                                        "/org/lightdm/LightDisplayManager/Users",
680
 
                                        NULL,
681
 
                                        G_DBUS_SIGNAL_FLAGS_NONE,
682
 
                                        user_removed_cb,
683
 
                                        greeter,
684
 
                                        NULL);
685
 
 
686
 
    g_debug ("Getting user list...");
687
 
    result = g_dbus_proxy_call_sync (greeter->priv->user_proxy,
688
 
                                     "GetUsers",
689
 
                                     NULL,
690
 
                                     G_DBUS_CALL_FLAGS_NONE,
691
 
                                     -1,
692
 
                                     NULL,
693
 
                                     &error);
694
 
    if (!result)
695
 
        g_warning ("Failed to get users: %s", error->message);
 
821
    load_config (greeter);
 
822
 
 
823
    /* User listing is disabled */
 
824
    if (g_key_file_has_key (greeter->priv->config, "UserManager", "load-users", NULL) &&
 
825
        !g_key_file_get_boolean (greeter->priv->config, "UserManager", "load-users", NULL))
 
826
    {
 
827
        greeter->priv->have_users = TRUE;
 
828
        return;
 
829
    }
 
830
 
 
831
    load_users (greeter);
 
832
 
 
833
    /* Watch for changes to user list */
 
834
    passwd_file = g_file_new_for_path ("/etc/passwd");
 
835
    greeter->priv->passwd_monitor = g_file_monitor (passwd_file, G_FILE_MONITOR_NONE, NULL, &error);
 
836
    g_object_unref (passwd_file);
 
837
    if (!greeter->priv->passwd_monitor)
 
838
        g_warning ("Error monitoring /etc/passwd: %s", error->message);
 
839
    else
 
840
        g_signal_connect (greeter->priv->passwd_monitor, "changed", G_CALLBACK (passwd_changed_cb), greeter);
696
841
    g_clear_error (&error);
697
 
    if (!result)
698
 
        return;
699
 
 
700
 
    if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(a(sssb))")))
701
 
    {
702
 
        g_warning ("Unknown type returned");
703
 
        g_variant_unref (result);
704
 
        return;
705
 
    }
706
 
    user_array = g_variant_get_child_value (result, 0);
707
 
    g_debug ("Got %zi users", g_variant_n_children (user_array));
708
 
    g_variant_iter_init (&iter, user_array);
709
 
    while (g_variant_iter_next (&iter, "(&s&s&sb)", &name, &real_name, &image, &logged_in))
710
 
    {
711
 
        LdmUser *user;
712
 
 
713
 
        user = ldm_user_new (greeter, name, real_name, image, logged_in);
714
 
        greeter->priv->users = g_list_append (greeter->priv->users, user);
715
 
    }
716
842
 
717
843
    greeter->priv->have_users = TRUE;
718
 
 
719
 
    g_variant_unref (result);
720
844
}
721
845
 
722
846
/**
1466
1590
gboolean
1467
1591
ldm_greeter_get_user_defaults (LdmGreeter *greeter, const gchar *username, gchar **language, gchar **layout, gchar **session)
1468
1592
{
1469
 
    GError *error = NULL;
1470
 
    GVariant *result;
1471
 
    gboolean got_defaults = FALSE;
 
1593
    gsize offset = 0;
 
1594
    guint32 id;
1472
1595
 
1473
1596
    g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1474
1597
    g_return_val_if_fail (username != NULL, FALSE);
1475
1598
 
1476
 
    result = g_dbus_proxy_call_sync (greeter->priv->user_proxy,
1477
 
                                     "GetUserDefaults",
1478
 
                                     g_variant_new ("(s)", username),
1479
 
                                     G_DBUS_CALL_FLAGS_NONE,
1480
 
                                     -1,
1481
 
                                     NULL,
1482
 
                                     &error);
1483
 
 
1484
 
    if (!result)
1485
 
        g_warning ("Failed to get user defaults: %s", error->message);
1486
 
    g_clear_error (&error);
1487
 
 
1488
 
    if (!result)
 
1599
    write_header (greeter, GREETER_MESSAGE_GET_USER_DEFAULTS, string_length (username));
 
1600
    write_string (greeter, username);
 
1601
    flush (greeter);
 
1602
 
 
1603
    if (!read_packet (greeter, TRUE))
 
1604
    {
 
1605
        g_warning ("Error reading user defaults from server");
1489
1606
        return FALSE;
1490
 
 
1491
 
    if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(sss)")))
1492
 
    {
1493
 
        g_variant_get (result, "(sss)", language, layout, session);
1494
 
        got_defaults = TRUE;
1495
1607
    }
1496
1608
 
1497
 
    g_variant_unref (result);
1498
 
 
1499
 
    return got_defaults;
 
1609
    id = read_int (greeter, &offset);
 
1610
    g_assert (id == GREETER_MESSAGE_USER_DEFAULTS);
 
1611
    read_int (greeter, &offset);
 
1612
    *language = read_string (greeter, &offset);
 
1613
    *layout = read_string (greeter, &offset);
 
1614
    *session = read_string (greeter, &offset);
 
1615
 
 
1616
    g_debug ("User defaults for %s: language=%s, layout=%s, session=%s", username, *language, *layout, *session);
 
1617
 
 
1618
    greeter->priv->n_read = 0;
 
1619
 
 
1620
    return TRUE;
1500
1621
}
1501
1622
 
1502
1623
static void