]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Make directory creation synchronous
authorMichael Terry <michael.terry@canonical.com>
Tue, 18 Feb 2014 21:44:30 +0000 (16:44 -0500)
committerMichael Terry <michael.terry@canonical.com>
Tue, 18 Feb 2014 21:44:30 +0000 (16:44 -0500)
12 files changed:
debian/liblightdm-gobject-1-0.symbols
doc/lightdm-gobject-1-sections.txt
doc/tmpl/greeter.sgml
liblightdm-gobject/greeter.c
liblightdm-gobject/lightdm/greeter.h
liblightdm-qt/QLightDM/greeter.h
liblightdm-qt/greeter.cpp
src/greeter.c
src/shared-data-manager.c
src/shared-data-manager.h
tests/scripts/shared-data-dirs.conf
tests/src/test-gobject-greeter.c

index 6793787f8b3546c01a288acbf39b75a5bd3369ad..f5a789d4d33286be10f8b17b50963d4eda6c3049 100644 (file)
@@ -17,7 +17,7 @@ liblightdm-gobject-1.so.0 liblightdm-gobject-1-0 #MINVER#
  lightdm_greeter_cancel_authentication@Base 0.9.2
  lightdm_greeter_cancel_autologin@Base 0.9.2
  lightdm_greeter_connect_sync@Base 0.9.2
- lightdm_greeter_ensure_shared_data_dir@Base 1.9.7
+ lightdm_greeter_ensure_shared_data_dir_sync@Base 1.9.7
  lightdm_greeter_get_authentication_user@Base 0.9.2
  lightdm_greeter_get_autologin_guest_hint@Base 0.9.2
  lightdm_greeter_get_autologin_timeout_hint@Base 0.9.2
index 6496e9dcfa4f0933137e540e27a70a0c95e88f22..e7c3d004a4ce5696dfa0814238cfa423faaf3010 100644 (file)
@@ -131,7 +131,7 @@ LightDMMessageType
 LightDMPromptType
 lightdm_greeter_new
 lightdm_greeter_connect_sync
-lightdm_greeter_ensure_shared_data_dir
+lightdm_greeter_ensure_shared_data_dir_sync
 lightdm_greeter_get_default_session_hint
 lightdm_greeter_get_hint
 lightdm_greeter_get_lock_hint
index 5dee0813b6cbbd2cc59b12da212557e821975e6a..5ea3e02f673e95012e3f95c2bd6e4de5e2759ffd 100644 (file)
@@ -356,7 +356,7 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 @Returns: 
 
 
-<!-- ##### FUNCTION lightdm_greeter_ensure_shared_data_dir ##### -->
+<!-- ##### FUNCTION lightdm_greeter_ensure_shared_data_dir_sync ##### -->
 <para>
 
 </para>
index 1d52218e44954b276584e6b65a7270d0d34ee746..2fedb5c02be93335cc864f2359f32d1824492e49 100644 (file)
@@ -91,7 +91,8 @@ typedef enum
     SERVER_MESSAGE_CONNECTED = 0,
     SERVER_MESSAGE_PROMPT_AUTHENTICATION,
     SERVER_MESSAGE_END_AUTHENTICATION,
-    SERVER_MESSAGE_SESSION_RESULT
+    SERVER_MESSAGE_SESSION_RESULT,
+    SERVER_MESSAGE_SHARED_DIR_RESULT,
 } ServerMessage;
 
 /**
@@ -1108,7 +1109,7 @@ lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *sessio
 }
 
 /**
- * lightdm_greeter_ensure_shared_data_dir:
+ * lightdm_greeter_ensure_shared_data_dir_sync:
  * @greeter: A #LightDMGreeter
  * @username: A username
  *
@@ -1122,13 +1123,17 @@ lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *sessio
  * LightDM will automatically create these if the user actually logs in, so
  * greeters only need to call this method if they want to store something in
  * the directory themselves.
+ *
+ * Return value: TRUE if the directory is ready for use.
  **/
-void
-lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username)
+gboolean
+lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username)
 {
     LightDMGreeterPrivate *priv;
     guint8 message[MAX_MESSAGE_LENGTH];
-    gsize offset = 0;
+    guint8 *response;
+    gsize response_length, offset = 0;
+    guint32 id, return_code = 1;
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
@@ -1139,6 +1144,22 @@ lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *us
     write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset);
     write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
     write_message (greeter, message, offset);
+
+    response = read_message (greeter, &response_length, TRUE);
+    if (!response)
+        return FALSE;
+
+    offset = 0;
+    id = read_int (response, response_length, &offset);
+    read_int (response, response_length, &offset);
+    if (id == SERVER_MESSAGE_SHARED_DIR_RESULT)
+        return_code = read_int (response, response_length, &offset);
+    else
+        g_warning ("Expected SHARED_DIR_RESULT message, got %d", id);
+
+    g_free (response);
+
+    return return_code == 0;
 }
 
 static void
index f0b59f8394d47d702dd21eadcfa83ad798cfc125..d52775142e5fb3bde9cb3f6d0dc95ee6f8f39950 100644 (file)
@@ -121,7 +121,7 @@ void lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *languag
 
 gboolean lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error);
 
-void lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username);
+gboolean lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username);
 
 G_END_DECLS
 
index b69105ee6b423ddf6764b09f75fa9754fcbcd325..775740df376ce2bc4ac19a03db653b51e2a6e8ed 100644 (file)
@@ -80,7 +80,7 @@ public Q_SLOTS:
     void cancelAuthentication();
     void setLanguage (const QString &language);
     bool startSessionSync(const QString &session=QString());
-    void ensureSharedDataDir (const QString &username);
+    bool ensureSharedDataDirSync(const QString &username);
 
 Q_SIGNALS:
     void showMessage(QString text, QLightDM::Greeter::MessageType type);
index 1e2a84fc6deab4af58a434e62a8da2e5f87e1518..8187ac967d6dbd2531dbf7a089419ae5b809d2d3 100644 (file)
@@ -172,10 +172,10 @@ bool Greeter::startSessionSync(const QString &session)
     return lightdm_greeter_start_session_sync(d->ldmGreeter, session.toLocal8Bit().constData(), NULL);
 }
 
-void Greeter::ensureSharedDataDir(const QString &username)
+bool Greeter::ensureSharedDataDirSync(const QString &username)
 {
     Q_D(Greeter);
-    lightdm_greeter_ensure_shared_data_dir(d->ldmGreeter, username.toLocal8Bit().constData());
+    return lightdm_greeter_ensure_shared_data_dir_sync(d->ldmGreeter, username.toLocal8Bit().constData());
 }
 
 
index 554b90f481d2c594aeec70fd623a10b9736d2e58..b000ac3e3be9008c7145051dec4ce30dd13d451d 100644 (file)
@@ -100,7 +100,8 @@ typedef enum
     SERVER_MESSAGE_CONNECTED = 0,
     SERVER_MESSAGE_PROMPT_AUTHENTICATION,
     SERVER_MESSAGE_END_AUTHENTICATION,
-    SERVER_MESSAGE_SESSION_RESULT
+    SERVER_MESSAGE_SESSION_RESULT,
+    SERVER_MESSAGE_SHARED_DIR_RESULT,
 } ServerMessage;
 
 static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data);
@@ -629,6 +630,20 @@ handle_set_language (Greeter *greeter, const gchar *language)
     user_set_language (user, language);
 }
 
+static void
+handle_ensure_shared_dir (Greeter *greeter, const gchar *username)
+{
+    gboolean result;
+    guint8 message[MAX_MESSAGE_LENGTH];
+    gsize offset = 0;
+
+    result = shared_data_manager_ensure_user_dir (shared_data_manager_get_instance (), username);
+
+    write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_SHARED_DIR_RESULT, int_length (), &offset);
+    write_int (message, MAX_MESSAGE_LENGTH, result ? 0 : 1, &offset);
+    write_message (greeter, message, offset);
+}
+
 static guint32
 read_int (Greeter *greeter, gsize *offset)
 {
@@ -815,7 +830,7 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
         break;
     case GREETER_MESSAGE_ENSURE_SHARED_DIR:
         username = read_string (greeter, &offset);
-        shared_data_manager_ensure_user_dir (shared_data_manager_get_instance (), username);
+        handle_ensure_shared_dir (greeter, username);
         g_free (username);
         break;
     default:
index 9f0e44f9e412954b8482e1b6c34f68be23c7a917..eb39a3d946af915e5ff40f14f4fdf0b04c0f9a06 100644 (file)
@@ -62,8 +62,7 @@ delete_unused_user (gpointer key, gpointer value, gpointer user_data)
     const gchar *user = (const gchar *)key;
     GError *error = NULL;
 
-    /* Listen, the rest of this file is nice async glib code and all, but
-       for this operation, we just need a fire and forget rm -rf.  Since
+    /* For this operation, we just need a fire and forget rm -rf.  Since
        recursively deleting in GIO is a huge pain in the butt, we'll just drop
        to shell for this. */
 
@@ -82,47 +81,31 @@ delete_unused_user (gpointer key, gpointer value, gpointer user_data)
     g_free (path);
 }
 
-static void
-chown_user_dir_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+gboolean
+shared_data_manager_ensure_user_dir (SharedDataManager *manager, const gchar *user)
 {
-    GFile *file = G_FILE (object);
-    GFileInfo *info = NULL;
-    GError *error = NULL;
-
-    if (!g_file_set_attributes_finish (file, res, &info, &error))
-    {
-        gchar *path = g_file_get_path (file);
-        g_warning ("Could not chown user data directory %s: %s",
-                   path, error->message);
-        g_free (path);
-        g_error_free (error);
-    }
-
-    if (info)
-        g_object_unref (info);
-}
+    struct passwd *entry = getpwnam (user);
+    if (!entry)
+        return FALSE;
 
-static void
-make_user_dir_cb (GObject *object, GAsyncResult *res, gpointer user_data)
-{
-    GFile *file = G_FILE (object);
-    struct OwnerInfo *owner = (struct OwnerInfo *)user_data;
     GError *error = NULL;
 
-    if (!g_file_make_directory_finish (file, res, &error))
+    gchar *path = g_build_filename (USERS_DIR, user, NULL);
+    GFile *file = g_file_new_for_path (path);
+
+    if (!g_file_make_directory (file, NULL, &error))
     {
         if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
         {
-            gchar *path = g_file_get_path (file);
             g_warning ("Could not create user data directory %s: %s",
                        path, error->message);
-            g_free (path);
             g_error_free (error);
-            g_object_unref (owner->manager);
-            g_free (owner);
-            return;
+            g_object_unref (file);
+            g_free (path);
+            return FALSE;
         }
         g_error_free (error);
+        error = NULL;
     }
 
     /* Even if the directory already exists, we want to re-affirm the owners
@@ -130,37 +113,26 @@ make_user_dir_cb (GObject *object, GAsyncResult *res, gpointer user_data)
        runs. */
     GFileInfo *info = g_file_info_new ();
     g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID,
-                                      owner->uid);
+                                      entry->pw_uid);
     g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID,
-                                      owner->manager->priv->greeter_gid);
+                                      manager->priv->greeter_gid);
     g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, 0770);
-    g_file_set_attributes_async (file, info, G_FILE_QUERY_INFO_NONE,
-                                 G_PRIORITY_DEFAULT, NULL,
-                                 chown_user_dir_cb, NULL);
-
-    g_object_unref (owner->manager);
-    g_free (owner);
-}
-
-void
-shared_data_manager_ensure_user_dir (SharedDataManager *manager, const gchar *user)
-{
-    struct passwd *entry = getpwnam (user);
-    if (!entry)
-        return;
-
-    struct OwnerInfo *owner = g_malloc (sizeof (struct OwnerInfo));
-    owner->manager = g_object_ref (manager);
-    owner->uid = entry->pw_uid;
-
-    gchar *path = g_build_filename (USERS_DIR, user, NULL);
-    GFile *file = g_file_new_for_path (path);
-    g_free (path);
-
-    g_file_make_directory_async (file, G_PRIORITY_DEFAULT, NULL,
-                                 make_user_dir_cb, owner);
+    if (!g_file_set_attributes_from_info (file, info, G_FILE_QUERY_INFO_NONE,
+                                          NULL, &error))
+    {
+        g_warning ("Could not chown user data directory %s: %s",
+                   path, error->message);
+        g_error_free (error);
+        g_object_unref (info);
+        g_object_unref (file);
+        g_free (path);
+        return FALSE;
+    }
 
+    g_object_unref (info);
     g_object_unref (file);
+    g_free (path);
+    return TRUE;
 }
 
 static void
index 737337af6b44d365c3c1dd2a72b96b77dc9f79dc..dfaaa562f8f7a52755f672188465ee644d3c449f 100644 (file)
@@ -44,7 +44,7 @@ void shared_data_manager_start (SharedDataManager *manager);
 
 void shared_data_manager_cleanup (void);
 
-void shared_data_manager_ensure_user_dir (SharedDataManager *manager, const gchar *user);
+gboolean shared_data_manager_ensure_user_dir (SharedDataManager *manager, const gchar *user);
 
 G_END_DECLS
 
index 3432331e13086f75ff89f0a4fad1b14a1eccbfd4..bd58f6f829a32f6b8a89828637a1df3d59175667 100644 (file)
@@ -30,7 +30,7 @@ shared-data-dirs=have-password1:1000:100:0770 have-password2:1000:1000:0777 xxx:
 
 # Make sure we can create/chown a directory from the greeter
 #?*GREETER-X-0 ENSURE-SHARED-DATA-DIR USERNAME=have-password2
-#?*WAIT
+#?GREETER-X-0 ENSURE-SHARED-DATA-DIR RESULT=TRUE
 #?*LIST-SHARED-DATA-DIRS
 #?RUNNER LIST-SHARED-DATA-DIRS DIRS=have-password1:1000:100:0770,have-password2:1001:100:0770,lightdm:100:100:0770
 
@@ -46,7 +46,6 @@ shared-data-dirs=have-password1:1000:100:0770 have-password2:1000:1000:0777 xxx:
 #?SESSION-X-0 CONNECT-XSERVER
 
 # Make sure we created the directory as we started session
-#?*WAIT
 #?*LIST-SHARED-DATA-DIRS
 #?RUNNER LIST-SHARED-DATA-DIRS DIRS=have-password1:1000:100:0770,have-password2:1001:100:0770,lightdm:100:100:0770,no-password1:1005:100:0770
 
index 17126b163612fefdd276ebd91c0e919181accbdd..972f2ba9dabe137021a4b9cad4b0f2baa6ea0153 100644 (file)
@@ -204,7 +204,7 @@ request_cb (const gchar *request)
         status_notify ("%s LOG-USER-LIST-LENGTH N=%d", greeter_id, lightdm_user_list_get_length (lightdm_user_list_get_instance ()));
 
     if (strcmp (name, "ENSURE-SHARED-DATA-DIR") == 0)
-        lightdm_greeter_ensure_shared_data_dir (greeter, g_hash_table_lookup (params, "USERNAME"));
+        status_notify ("%s ENSURE-SHARED-DATA-DIR RESULT=%s", greeter_id, lightdm_greeter_ensure_shared_data_dir_sync (greeter, g_hash_table_lookup (params, "USERNAME")) ? "TRUE" : "FALSE");
 
     if (strcmp (name, "WATCH-USER") == 0)
     {