Blame SOURCES/0009-Revert-Allow-saved-session-to-be-a-symlink.patch

cf6cdf
From 489166afdd82af3ec4897c8369a89bbaeffea2d9 Mon Sep 17 00:00:00 2001
cf6cdf
From: Ray Strode <rstrode@redhat.com>
cf6cdf
Date: Fri, 20 Dec 2013 11:22:07 -0500
cf6cdf
Subject: [PATCH 09/19] Revert "Allow saved-session to be a symlink"
cf6cdf
cf6cdf
This reverts commit b733c2ee519b65c3c4eab0d0e93056412f995f3f.
cf6cdf
---
cf6cdf
 gnome-session/gsm-session-save.c | 33 +++++++++++++++++++++++++++-----
cf6cdf
 gnome-session/gsm-util.c         |  6 ++++++
cf6cdf
 2 files changed, 34 insertions(+), 5 deletions(-)
cf6cdf
cf6cdf
diff --git a/gnome-session/gsm-session-save.c b/gnome-session/gsm-session-save.c
cf6cdf
index a71a6181..04b5277c 100644
cf6cdf
--- a/gnome-session/gsm-session-save.c
cf6cdf
+++ b/gnome-session/gsm-session-save.c
cf6cdf
@@ -10,61 +10,61 @@
cf6cdf
  * This program is distributed in the hope that it will be useful, but
cf6cdf
  * WITHOUT ANY WARRANTY; without even the implied warranty of
cf6cdf
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
cf6cdf
  * Lesser General Public License for more details.
cf6cdf
  *
cf6cdf
  * You should have received a copy of the GNU General Public License
cf6cdf
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
cf6cdf
  */
cf6cdf
 
cf6cdf
 #include <config.h>
cf6cdf
 
cf6cdf
 #include <glib.h>
cf6cdf
 #include <glib/gstdio.h>
cf6cdf
 #include <gio/gio.h>
cf6cdf
 
cf6cdf
 #include "gsm-app.h"
cf6cdf
 #include "gsm-util.h"
cf6cdf
 #include "gsm-autostart-app.h"
cf6cdf
 #include "gsm-client.h"
cf6cdf
 
cf6cdf
 #include "gsm-session-save.h"
cf6cdf
 
cf6cdf
 #define GSM_MANAGER_SCHEMA        "org.gnome.SessionManager"
cf6cdf
 #define KEY_AUTOSAVE_ONE_SHOT     "auto-save-session-one-shot"
cf6cdf
 
cf6cdf
 
cf6cdf
 static gboolean gsm_session_clear_saved_session (const char *directory,
cf6cdf
                                                  GHashTable *discard_hash);
cf6cdf
 
cf6cdf
 typedef struct {
cf6cdf
-        const char  *dir;
cf6cdf
+        char        *dir;
cf6cdf
         GHashTable  *discard_hash;
cf6cdf
         GsmStore    *app_store;
cf6cdf
         GError     **error;
cf6cdf
 } SessionSaveData;
cf6cdf
 
cf6cdf
 static gboolean
cf6cdf
 _app_has_app_id (const char   *id,
cf6cdf
                  GsmApp       *app,
cf6cdf
                  const char   *app_id_a)
cf6cdf
 {
cf6cdf
         const char *app_id_b;
cf6cdf
 
cf6cdf
         app_id_b = gsm_app_peek_app_id (app);
cf6cdf
         return g_strcmp0 (app_id_a, app_id_b) == 0;
cf6cdf
 }
cf6cdf
 
cf6cdf
 static gboolean
cf6cdf
 save_one_client (char            *id,
cf6cdf
                  GObject         *object,
cf6cdf
                  SessionSaveData *data)
cf6cdf
 {
cf6cdf
         GsmClient  *client;
cf6cdf
         GKeyFile   *keyfile;
cf6cdf
         GsmApp     *app = NULL;
cf6cdf
         const char *app_id;
cf6cdf
         char       *path = NULL;
cf6cdf
         char       *filename = NULL;
cf6cdf
         char       *contents = NULL;
cf6cdf
         gsize       length = 0;
cf6cdf
         char       *discard_exec;
cf6cdf
@@ -130,91 +130,114 @@ save_one_client (char            *id,
cf6cdf
 
cf6cdf
         g_debug ("GsmSessionSave: saved client %s to %s", id, filename);
cf6cdf
 
cf6cdf
 out:
cf6cdf
         if (keyfile != NULL) {
cf6cdf
                 g_key_file_free (keyfile);
cf6cdf
         }
cf6cdf
 
cf6cdf
         g_free (contents);
cf6cdf
         g_free (filename);
cf6cdf
         g_free (path);
cf6cdf
 
cf6cdf
         /* in case of any error, stop saving session */
cf6cdf
         if (local_error) {
cf6cdf
                 g_propagate_error (data->error, local_error);
cf6cdf
                 g_error_free (local_error);
cf6cdf
 
cf6cdf
                 return TRUE;
cf6cdf
         }
cf6cdf
 
cf6cdf
         return FALSE;
cf6cdf
 }
cf6cdf
 
cf6cdf
 void
cf6cdf
 gsm_session_save (GsmStore  *client_store,
cf6cdf
                   GsmStore  *app_store,
cf6cdf
                   GError   **error)
cf6cdf
 {
cf6cdf
         GSettings       *settings;
cf6cdf
         const char      *save_dir;
cf6cdf
+        char            *tmp_dir;
cf6cdf
         SessionSaveData  data;
cf6cdf
 
cf6cdf
         g_debug ("GsmSessionSave: Saving session");
cf6cdf
 
cf6cdf
         /* Clear one shot key autosave in the event its set (so that it's actually
cf6cdf
          * one shot only)
cf6cdf
          */
cf6cdf
         settings = g_settings_new (GSM_MANAGER_SCHEMA);
cf6cdf
         g_settings_set_boolean (settings, KEY_AUTOSAVE_ONE_SHOT, FALSE);
cf6cdf
         g_object_unref (settings);
cf6cdf
 
cf6cdf
         save_dir = gsm_util_get_saved_session_dir ();
cf6cdf
         if (save_dir == NULL) {
cf6cdf
                 g_warning ("GsmSessionSave: cannot create saved session directory");
cf6cdf
                 return;
cf6cdf
         }
cf6cdf
 
cf6cdf
-        data.dir = save_dir;
cf6cdf
+        tmp_dir = gsm_util_get_empty_tmp_session_dir ();
cf6cdf
+        if (tmp_dir == NULL) {
cf6cdf
+                g_warning ("GsmSessionSave: cannot create new saved session directory");
cf6cdf
+                return;
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        /* save the session in a temp directory, and remember the discard
cf6cdf
+         * commands */
cf6cdf
+        data.dir = tmp_dir;
cf6cdf
         data.discard_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
cf6cdf
                                                    g_free, NULL);
cf6cdf
         data.app_store = app_store;
cf6cdf
-
cf6cdf
-        /* remove old saved session */
cf6cdf
-        gsm_session_clear_saved_session (save_dir, data.discard_hash);
cf6cdf
         data.error = error;
cf6cdf
 
cf6cdf
         gsm_store_foreach (client_store,
cf6cdf
                            (GsmStoreFunc) save_one_client,
cf6cdf
                            &data);
cf6cdf
 
cf6cdf
+        if (!*error) {
cf6cdf
+                /* remove the old saved session */
cf6cdf
+                gsm_session_clear_saved_session (save_dir, data.discard_hash);
cf6cdf
+
cf6cdf
+                /* rename the temp session dir */
cf6cdf
+                if (g_file_test (save_dir, G_FILE_TEST_IS_DIR))
cf6cdf
+                        g_rmdir (save_dir);
cf6cdf
+                g_rename (tmp_dir, save_dir);
cf6cdf
+        } else {
cf6cdf
+                g_warning ("GsmSessionSave: error saving session: %s", (*error)->message);
cf6cdf
+                /* FIXME: we should create a hash table filled with the discard
cf6cdf
+                 * commands that are in desktop files from save_dir. */
cf6cdf
+                gsm_session_clear_saved_session (tmp_dir, NULL);
cf6cdf
+                g_rmdir (tmp_dir);
cf6cdf
+        }
cf6cdf
+
cf6cdf
         g_hash_table_destroy (data.discard_hash);
cf6cdf
+        g_free (tmp_dir);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static gboolean
cf6cdf
 gsm_session_clear_one_client (const char *filename,
cf6cdf
                               GHashTable *discard_hash)
cf6cdf
 {
cf6cdf
         gboolean  result = TRUE;
cf6cdf
         GKeyFile *key_file;
cf6cdf
         char     *discard_exec = NULL;
cf6cdf
         char    **envp;
cf6cdf
 
cf6cdf
         g_debug ("GsmSessionSave: removing '%s' from saved session", filename);
cf6cdf
 
cf6cdf
         envp = (char **) gsm_util_listenv ();
cf6cdf
         key_file = g_key_file_new ();
cf6cdf
         if (g_key_file_load_from_file (key_file, filename,
cf6cdf
                                        G_KEY_FILE_NONE, NULL)) {
cf6cdf
                 char **argv;
cf6cdf
                 int    argc;
cf6cdf
 
cf6cdf
                 discard_exec = g_key_file_get_string (key_file,
cf6cdf
                                                       G_KEY_FILE_DESKTOP_GROUP,
cf6cdf
                                                       GSM_AUTOSTART_APP_DISCARD_KEY,
cf6cdf
                                                       NULL);
cf6cdf
                 if (!discard_exec)
cf6cdf
                         goto out;
cf6cdf
 
cf6cdf
                 if (discard_hash && g_hash_table_lookup (discard_hash, discard_exec))
cf6cdf
                         goto out;
cf6cdf
 
cf6cdf
diff --git a/gnome-session/gsm-util.c b/gnome-session/gsm-util.c
cf6cdf
index acb446a3..b086568c 100644
cf6cdf
--- a/gnome-session/gsm-util.c
cf6cdf
+++ b/gnome-session/gsm-util.c
cf6cdf
@@ -71,63 +71,69 @@ gsm_util_find_desktop_file_for_app_name (const char *name,
cf6cdf
                 g_debug ("GsmUtil: found in XDG dirs: '%s'", app_path);
cf6cdf
         }
cf6cdf
 
cf6cdf
         /* look for gnome vendor prefix */
cf6cdf
         if (app_path == NULL) {
cf6cdf
                 g_free (desktop_file);
cf6cdf
                 desktop_file = g_strdup_printf ("gnome-%s.desktop", name);
cf6cdf
 
cf6cdf
                 g_key_file_load_from_dirs (key_file,
cf6cdf
                                            desktop_file,
cf6cdf
                                            (const char **) app_dirs,
cf6cdf
                                            &app_path,
cf6cdf
                                            G_KEY_FILE_NONE,
cf6cdf
                                            NULL);
cf6cdf
                 if (app_path != NULL) {
cf6cdf
                         g_debug ("GsmUtil: found in XDG dirs: '%s'", app_path);
cf6cdf
                 }
cf6cdf
         }
cf6cdf
 
cf6cdf
         g_free (desktop_file);
cf6cdf
         g_key_file_free (key_file);
cf6cdf
 
cf6cdf
         g_strfreev (app_dirs);
cf6cdf
 
cf6cdf
         return app_path;
cf6cdf
 }
cf6cdf
 
cf6cdf
 static gboolean
cf6cdf
 ensure_dir_exists (const char *dir)
cf6cdf
 {
cf6cdf
+        if (g_file_test (dir, G_FILE_TEST_IS_DIR))
cf6cdf
+                return TRUE;
cf6cdf
+
cf6cdf
         if (g_mkdir_with_parents (dir, 0700) == 0)
cf6cdf
                 return TRUE;
cf6cdf
 
cf6cdf
+        if (errno == EEXIST)
cf6cdf
+                return g_file_test (dir, G_FILE_TEST_IS_DIR);
cf6cdf
+
cf6cdf
         g_warning ("GsmSessionSave: Failed to create directory %s: %s", dir, strerror (errno));
cf6cdf
 
cf6cdf
         return FALSE;
cf6cdf
 }
cf6cdf
 
cf6cdf
 gchar *
cf6cdf
 gsm_util_get_empty_tmp_session_dir (void)
cf6cdf
 {
cf6cdf
         char *tmp;
cf6cdf
         gboolean exists;
cf6cdf
 
cf6cdf
         tmp = g_build_filename (g_get_user_config_dir (),
cf6cdf
                                 "gnome-session",
cf6cdf
                                 "saved-session.new",
cf6cdf
                                 NULL);
cf6cdf
 
cf6cdf
         exists = ensure_dir_exists (tmp);
cf6cdf
 
cf6cdf
         if (G_UNLIKELY (!exists)) {
cf6cdf
                 g_warning ("GsmSessionSave: could not create directory for saved session: %s", tmp);
cf6cdf
                 g_free (tmp);
cf6cdf
                 return NULL;
cf6cdf
         } else {
cf6cdf
                 /* make sure it's empty */
cf6cdf
                 GDir       *dir;
cf6cdf
                 const char *filename;
cf6cdf
 
cf6cdf
                 dir = g_dir_open (tmp, 0, NULL);
cf6cdf
                 if (dir) {
cf6cdf
                         while ((filename = g_dir_read_name (dir))) {
cf6cdf
-- 
cf6cdf
2.17.0
cf6cdf