]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - liblightdm-gobject/greeter.c
Use G_DECLARE_*_TYPE to simplify code and fix docs
[sojka/lightdm.git] / liblightdm-gobject / greeter.c
index 33562bce6a792653b2489b2778df91fabcb981a5..6e3c93ede37c7762feb7cd75e56e974c2747c897 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <gio/gio.h>
+#include <gio/gunixsocketaddress.h>
 #include <security/pam_appl.h>
 
 #include "lightdm/greeter.h"
@@ -19,8 +21,7 @@
 G_DEFINE_QUARK (lightdm_greeter_error, lightdm_greeter_error)
 
 enum {
-    PROP_0,
-    PROP_DEFAULT_SESSION_HINT,
+    PROP_DEFAULT_SESSION_HINT = 1,
     PROP_HIDE_USERS_HINT,
     PROP_SHOW_MANUAL_LOGIN_HINT,
     PROP_SHOW_REMOTE_LOGIN_HINT,
@@ -52,11 +53,15 @@ typedef struct
     /* TRUE if the daemon can reuse this greeter */
     gboolean resettable;
 
+    /* Socket connection to daemon */
+    GSocket *socket;
+
     /* Channel to write to daemon */
     GIOChannel *to_server_channel;
 
     /* Channel to read from daemon */
     GIOChannel *from_server_channel;
+    guint from_server_watch;
 
     /* Data read from the daemon */
     guint8 *read_buffer;
@@ -90,9 +95,7 @@ typedef struct
     gboolean cancelling_authentication;
 } LightDMGreeterPrivate;
 
-G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
-
-#define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
+G_DEFINE_TYPE_WITH_PRIVATE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
 
 #define HEADER_SIZE 8
 #define MAX_MESSAGE_LENGTH 1024
@@ -230,7 +233,7 @@ lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable)
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_if_fail (!priv->connected);
     priv->resettable = resettable;
@@ -242,7 +245,7 @@ request_new (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCall
     Request *request;
 
     request = g_object_new (request_get_type (), NULL);
-    request->greeter = g_object_ref (greeter);
+    request->greeter = greeter;
     if (cancellable)
         request->cancellable = g_object_ref (cancellable);
     request->callback = callback;
@@ -279,7 +282,7 @@ static gboolean
 timed_login_cb (gpointer data)
 {
     LightDMGreeter *greeter = data;
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
 
     priv->autologin_timeout = 0;
     g_signal_emit (G_OBJECT (greeter), signals[AUTOLOGIN_TIMER_EXPIRED], 0);
@@ -399,24 +402,47 @@ get_message_length (guint8 *message, gsize message_length)
 static gboolean
 connect_to_daemon (LightDMGreeter *greeter, GError **error)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
-    const gchar *to_server_fd, *from_server_fd;
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
+    const gchar *to_server_fd, *from_server_fd, *pipe_path;
 
     if (priv->to_server_channel || priv->from_server_channel)
         return TRUE;
 
+    /* Use private connection if one exists */  
     to_server_fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
     from_server_fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
-    if (!to_server_fd || !from_server_fd)
+    pipe_path = g_getenv ("LIGHTDM_GREETER_PIPE");
+    if (to_server_fd && from_server_fd)
+    {
+        priv->to_server_channel = g_io_channel_unix_new (atoi (to_server_fd));
+        priv->from_server_channel = g_io_channel_unix_new (atoi (from_server_fd));
+    }
+    else if (pipe_path)
+    {
+        GSocketAddress *address;
+        gboolean result;
+
+        priv->socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, error);
+        if (!priv->socket)
+            return FALSE;
+
+        address = g_unix_socket_address_new (pipe_path);
+        result = g_socket_connect (priv->socket, address, NULL, error);
+        g_object_unref (address);
+        if (!result)
+            return FALSE;
+
+        priv->from_server_channel = g_io_channel_unix_new (g_socket_get_fd (priv->socket));
+        priv->to_server_channel = g_io_channel_ref (priv->from_server_channel);
+    }
+    else
     {
         g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_CONNECTION_FAILED,
                              "Unable to determine socket to daemon");
         return FALSE;
     }
 
-    priv->to_server_channel = g_io_channel_unix_new (atoi (to_server_fd));
-    priv->from_server_channel = g_io_channel_unix_new (atoi (from_server_fd));
-    g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
+    priv->from_server_watch = g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
 
     if (!g_io_channel_set_encoding (priv->to_server_channel, NULL, error) ||
         !g_io_channel_set_encoding (priv->from_server_channel, NULL, error))
@@ -428,7 +454,7 @@ connect_to_daemon (LightDMGreeter *greeter, GError **error)
 static gboolean
 send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length, GError **error)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
     gchar *data;
     gsize data_length;
     guint32 stated_length;
@@ -489,7 +515,7 @@ send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length, GE
 static void
 handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
     gchar *version;
     GString *hint_string;
     int timeout;
@@ -534,7 +560,7 @@ handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length
 static void
 handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
     guint32 sequence_number, n_messages, i;
     gchar *username;
 
@@ -602,7 +628,7 @@ handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize me
 static void
 handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
     guint32 sequence_number, return_code;
     gchar *username;
 
@@ -644,7 +670,7 @@ handle_idle (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsi
 static void
 handle_reset (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
     GString *hint_string;
 
     g_hash_table_remove_all (priv->hints);
@@ -669,7 +695,7 @@ handle_reset (LightDMGreeter *greeter, guint8 *message, gsize message_length, gs
 static void
 handle_session_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
     Request *request;
 
     /* Notify asynchronous caller */
@@ -693,7 +719,7 @@ handle_session_result (LightDMGreeter *greeter, guint8 *message, gsize message_l
 static void
 handle_shared_dir_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
     Request *request;
 
     /* Notify asynchronous caller */
@@ -755,7 +781,7 @@ handle_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
 static gboolean
 recv_message (LightDMGreeter *greeter, gboolean block, guint8 **message, gsize *length, GError **error)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
     gsize n_to_read, n_read;
 
     if (!connect_to_daemon (greeter, error))
@@ -919,7 +945,7 @@ lightdm_greeter_connect_to_daemon (LightDMGreeter *greeter, GCancellable *cancel
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     request = request_new (greeter, cancellable, callback, user_data);
     if (send_connect (greeter, priv->resettable, &error))
@@ -948,8 +974,9 @@ lightdm_greeter_connect_to_daemon_finish (LightDMGreeter *greeter, GAsyncResult
     Request *request = REQUEST (result);
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
-  
-    g_propagate_error (error, request->error);
+
+    if (request->error)
+        g_propagate_error (error, request->error);
     return request->result;
 }
 
@@ -970,7 +997,7 @@ lightdm_greeter_connect_to_daemon_sync (LightDMGreeter *greeter, GError **error)
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     /* Read until we are connected */
     if (!send_connect (greeter, priv->resettable, error))
@@ -1020,8 +1047,13 @@ lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error)
 const gchar *
 lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
 {
+    LightDMGreeterPrivate *priv;
+
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
-    return g_hash_table_lookup (GET_PRIVATE (greeter)->hints, name);
+
+    priv = lightdm_greeter_get_instance_private (greeter);
+
+    return g_hash_table_lookup (priv->hints, name);
 }
 
 /**
@@ -1249,7 +1281,7 @@ lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     if (priv->autologin_timeout)
        g_source_remove (priv->autologin_timeout);
@@ -1275,7 +1307,7 @@ lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username, GE
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_val_if_fail (priv->connected, FALSE);
 
@@ -1314,7 +1346,7 @@ lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter, GError **error)
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_val_if_fail (priv->connected, FALSE);
 
@@ -1378,7 +1410,7 @@ lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *sessi
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_val_if_fail (priv->connected, FALSE);
 
@@ -1421,7 +1453,7 @@ lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response, GError
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
     g_return_val_if_fail (response != NULL, FALSE);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_val_if_fail (priv->connected, FALSE);
     g_return_val_if_fail (priv->n_responses_waiting > 0, FALSE);
@@ -1476,7 +1508,7 @@ lightdm_greeter_cancel_authentication (LightDMGreeter *greeter, GError **error)
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_val_if_fail (priv->connected, FALSE);
 
@@ -1496,8 +1528,13 @@ lightdm_greeter_cancel_authentication (LightDMGreeter *greeter, GError **error)
 gboolean
 lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
 {
+    LightDMGreeterPrivate *priv;
+
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
-    return GET_PRIVATE (greeter)->in_authentication;
+
+    priv = lightdm_greeter_get_instance_private (greeter);
+
+    return priv->in_authentication;
 }
 
 /**
@@ -1511,8 +1548,13 @@ lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
 gboolean
 lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
 {
+    LightDMGreeterPrivate *priv;
+
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
-    return GET_PRIVATE (greeter)->is_authenticated;
+
+    priv = lightdm_greeter_get_instance_private (greeter);
+
+    return priv->is_authenticated;
 }
 
 /**
@@ -1526,8 +1568,13 @@ lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
 const gchar *
 lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
 {
+    LightDMGreeterPrivate *priv;
+
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
-    return GET_PRIVATE (greeter)->authentication_user;
+
+    priv = lightdm_greeter_get_instance_private (greeter);
+
+    return priv->authentication_user;
 }
 
 /**
@@ -1549,7 +1596,7 @@ lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language, GE
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_val_if_fail (priv->connected, FALSE);
 
@@ -1581,7 +1628,7 @@ lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session, GC
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     request = request_new (greeter, cancellable, callback, user_data);
     priv->start_session_requests = g_list_append (priv->start_session_requests, request);
@@ -1609,7 +1656,8 @@ lightdm_greeter_start_session_finish (LightDMGreeter *greeter, GAsyncResult *res
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    g_propagate_error (error, request->error);
+    if (request->error)  
+        g_propagate_error (error, request->error);
     return request->result;
 }
 
@@ -1631,7 +1679,7 @@ lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *sessio
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_val_if_fail (priv->connected, FALSE);
     g_return_val_if_fail (priv->is_authenticated, FALSE);
@@ -1683,7 +1731,7 @@ lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *us
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     request = request_new (greeter, cancellable, callback, user_data);
     priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, request);
@@ -1711,7 +1759,8 @@ lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncRe
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
 
-    g_propagate_error (error, request->error);
+    if (request->error)
+        g_propagate_error (error, request->error);
     return g_strdup (request->dir);
 }
 
@@ -1742,7 +1791,7 @@ lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gcha
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
 
-    priv = GET_PRIVATE (greeter);
+    priv = lightdm_greeter_get_instance_private (greeter);
 
     g_return_val_if_fail (priv->connected, NULL);
 
@@ -1768,7 +1817,7 @@ lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gcha
 static void
 lightdm_greeter_init (LightDMGreeter *greeter)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);
 
     priv->read_buffer = g_malloc (HEADER_SIZE);
     priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
@@ -1846,14 +1895,28 @@ static void
 lightdm_greeter_finalize (GObject *object)
 {
     LightDMGreeter *self = LIGHTDM_GREETER (object);
-    LightDMGreeterPrivate *priv = GET_PRIVATE (self);
+    LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (self);
 
+    g_clear_object (&priv->socket);
     if (priv->to_server_channel)
         g_io_channel_unref (priv->to_server_channel);
     if (priv->from_server_channel)
         g_io_channel_unref (priv->from_server_channel);
-    g_free (priv->authentication_user);
+    if (priv->from_server_watch)
+        g_source_remove (priv->from_server_watch);
+    priv->from_server_watch = 0;
+    g_clear_pointer (&priv->read_buffer, g_free);
+    g_list_free_full (priv->responses_received, g_free);
+    priv->responses_received = NULL;
+    g_list_free_full (priv->connect_requests, g_object_unref);
+    priv->connect_requests = NULL;
+    g_list_free_full (priv->start_session_requests, g_object_unref);
+    priv->start_session_requests = NULL;
+    g_list_free_full (priv->ensure_shared_data_dir_requests, g_object_unref);
+    priv->ensure_shared_data_dir_requests = NULL;
+    g_clear_pointer (&priv->authentication_user, g_free);
     g_hash_table_unref (priv->hints);
+    priv->hints = NULL;
 
     G_OBJECT_CLASS (lightdm_greeter_parent_class)->finalize (object);
 }
@@ -1863,8 +1926,6 @@ lightdm_greeter_class_init (LightDMGreeterClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-    g_type_class_add_private (klass, sizeof (LightDMGreeterPrivate));
-
     object_class->set_property = lightdm_greeter_set_property;
     object_class->get_property = lightdm_greeter_get_property;
     object_class->finalize = lightdm_greeter_finalize;
@@ -2103,7 +2164,6 @@ request_finalize (GObject *object)
 {
     Request *request = REQUEST (object);
 
-    g_clear_object (&request->greeter);
     g_clear_object (&request->cancellable);
     g_free (request->dir);