diff options
-rw-r--r-- | common/gdm-common.c | 123 | ||||
-rw-r--r-- | common/gdm-common.h | 8 | ||||
-rw-r--r-- | daemon/gdm-launch-environment.c | 44 | ||||
-rw-r--r-- | daemon/gdm-session-worker.c | 120 |
4 files changed, 172 insertions, 123 deletions
diff --git a/common/gdm-common.c b/common/gdm-common.c index bf8364a8..92029027 100644 --- a/common/gdm-common.c +++ b/common/gdm-common.c @@ -956,3 +956,126 @@ gdm_find_display_session (GPid pid, return TRUE; } + +static void +load_env_file (GFile *file, + GdmLoadEnvVarFunc load_env_func, + GdmExpandVarFunc expand_func, + gpointer user_data) +{ + gchar *contents; + gchar **lines; + gchar *line, *p; + gchar *var, *var_end; + gchar *expanded; + char *filename; + int i; + + filename = g_file_get_path (file); + g_debug ("Loading env vars from %s\n", filename); + g_free (filename); + + if (g_file_load_contents (file, NULL, &contents, NULL, NULL, NULL)) { + lines = g_strsplit (contents, "\n", -1); + g_free (contents); + for (i = 0; lines[i] != NULL; i++) { + line = lines[i]; + p = line; + while (g_ascii_isspace (*p)) + p++; + if (*p == '#' || *p == '\0') + continue; + var = p; + while (gdm_shell_var_is_valid_char (*p, p == var)) + p++; + var_end = p; + while (g_ascii_isspace (*p)) + p++; + if (var == var_end || *p != '=') { + g_warning ("Invalid env.d line '%s'\n", line); + continue; + } + *var_end = 0; + p++; /* Skip = */ + while (g_ascii_isspace (*p)) + p++; + + expanded = gdm_shell_expand (p, expand_func, user_data); + expanded = g_strchomp (expanded); + load_env_func (var, expanded, user_data); + g_free (expanded); + } + g_strfreev (lines); + } +} + +static gint +compare_str (gconstpointer a, + gconstpointer b) +{ + return strcmp (*(const char **)a, *(const char **)b); +} + +static void +gdm_load_env_dir (GFile *dir, + GdmLoadEnvVarFunc load_env_func, + GdmExpandVarFunc expand_func, + gpointer user_data) +{ + GFileInfo *info = NULL; + GFileEnumerator *enumerator = NULL; + GPtrArray *names = NULL; + GFile *file; + const gchar *name; + int i; + + enumerator = g_file_enumerate_children (dir, + G_FILE_ATTRIBUTE_STANDARD_TYPE"," + G_FILE_ATTRIBUTE_STANDARD_NAME"," + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN"," + G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + if (!enumerator) { + goto out; + } + + names = g_ptr_array_new_with_free_func (g_free); + while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) { + if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR && + !g_file_info_get_is_hidden (info) && + g_str_has_suffix (g_file_info_get_name (info), ".env")) + g_ptr_array_add (names, g_strdup (g_file_info_get_name (info))); + + g_clear_object (&info); + } + + g_ptr_array_sort (names, compare_str); + + for (i = 0; i < names->len; i++) { + name = g_ptr_array_index (names, i); + file = g_file_get_child (dir, name); + load_env_file (file, load_env_func, expand_func, user_data); + g_object_unref (file); + } + + out: + g_clear_pointer (&names, g_ptr_array_unref); + g_clear_object (&enumerator); +} + +void +gdm_load_env_d (GdmLoadEnvVarFunc load_env_func, + GdmExpandVarFunc expand_func, + gpointer user_data) +{ + GFile *dir; + + dir = g_file_new_for_path (DATADIR "/gdm/env.d"); + gdm_load_env_dir (dir, load_env_func, expand_func, user_data); + g_object_unref (dir); + + dir = g_file_new_for_path (GDMCONFDIR "/env.d"); + gdm_load_env_dir (dir, load_env_func, expand_func, user_data); + g_object_unref (dir); +} diff --git a/common/gdm-common.h b/common/gdm-common.h index 001b70c1..c42f556a 100644 --- a/common/gdm-common.h +++ b/common/gdm-common.h @@ -43,6 +43,10 @@ GQuark gdm_common_error_quark (void); typedef char * (*GdmExpandVarFunc) (const char *var, gpointer user_data); +typedef void (*GdmLoadEnvVarFunc) (const char *var, + const char *value, + gpointer user_data); + G_BEGIN_DECLS int gdm_wait_on_pid (int pid); @@ -87,6 +91,10 @@ gboolean gdm_activate_session_by_id (GDBusConnection *connection, const char *seat_id, const char *session_id); +void gdm_load_env_d (GdmLoadEnvVarFunc load_env_func, + GdmExpandVarFunc expand_func, + gpointer user_data); + G_END_DECLS #endif /* _GDM_COMMON_H */ diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c index feccf057..87a1c5ff 100644 --- a/daemon/gdm-launch-environment.c +++ b/daemon/gdm-launch-environment.c @@ -113,6 +113,23 @@ static void gdm_launch_environment_finalize (GObject G_DEFINE_TYPE_WITH_PRIVATE (GdmLaunchEnvironment, gdm_launch_environment, G_TYPE_OBJECT) +static char * +get_var_cb (const char *var, + gpointer user_data) +{ + const char *value = g_hash_table_lookup (user_data, var); + return g_strdup (value); +} + +static void +load_env_func (const char *var, + const char *value, + gpointer user_data) +{ + GHashTable *environment = user_data; + g_hash_table_replace (environment, g_strdup (var), g_strdup (value)); +} + static GHashTable * build_launch_environment (GdmLaunchEnvironment *launch_environment, gboolean start_session) @@ -159,15 +176,6 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment, g_strdup (g_getenv (optional_environment[i]))); } - system_data_dirs = g_strjoinv (":", (char **) g_get_system_data_dirs ()); - - g_hash_table_insert (hash, - g_strdup ("XDG_DATA_DIRS"), - g_strdup_printf ("%s:%s", - DATADIR "/gdm/greeter", - system_data_dirs)); - g_free (system_data_dirs); - if (launch_environment->priv->x11_authority_file != NULL) g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (launch_environment->priv->x11_authority_file)); @@ -218,6 +226,24 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment, g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true")); + /* Now populate XDG_DATA_DIRS from env.d if we're running initial setup; this allows + * e.g. Flatpak apps to be recognized by gnome-shell. + */ + if (g_strcmp0 (launch_environment->priv->session_mode, INITIAL_SETUP_SESSION_MODE) == 0) + gdm_load_env_d (load_env_func, get_var_cb, hash); + + /* Prepend our own XDG_DATA_DIRS value */ + system_data_dirs = g_strdup (g_hash_table_lookup (hash, "XDG_DATA_DIRS")); + if (!system_data_dirs) + system_data_dirs = g_strjoinv (":", (char **) g_get_system_data_dirs ()); + + g_hash_table_insert (hash, + g_strdup ("XDG_DATA_DIRS"), + g_strdup_printf ("%s:%s", + DATADIR "/gdm/greeter", + system_data_dirs)); + g_free (system_data_dirs); + return hash; } diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index 774298b9..facd05f4 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -1569,120 +1569,12 @@ get_var_cb (const char *key, } static void -load_env_file (GdmSessionWorker *worker, - GFile *file) -{ - gchar *contents; - gchar **lines; - gchar *line, *p; - gchar *var, *var_end; - gchar *expanded; - char *filename; - int i; - - filename = g_file_get_path (file); - g_debug ("Loading env vars from %s\n", filename); - g_free (filename); - - if (g_file_load_contents (file, NULL, &contents, NULL, NULL, NULL)) { - lines = g_strsplit (contents, "\n", -1); - g_free (contents); - for (i = 0; lines[i] != NULL; i++) { - line = lines[i]; - p = line; - while (g_ascii_isspace (*p)) - p++; - if (*p == '#' || *p == '\0') - continue; - var = p; - while (gdm_shell_var_is_valid_char (*p, p == var)) - p++; - var_end = p; - while (g_ascii_isspace (*p)) - p++; - if (var == var_end || *p != '=') { - g_warning ("Invalid env.d line '%s'\n", line); - continue; - } - *var_end = 0; - p++; /* Skip = */ - while (g_ascii_isspace (*p)) - p++; - - expanded = gdm_shell_expand (p, get_var_cb, worker); - expanded = g_strchomp (expanded); - gdm_session_worker_set_environment_variable (worker, var, expanded); - g_free (expanded); - } - g_strfreev (lines); - } -} - -static gint -compare_str (gconstpointer a, - gconstpointer b) -{ - return strcmp (*(const char **)a, *(const char **)b); -} - -static void -gdm_session_worker_load_env_dir (GdmSessionWorker *worker, - GFile *dir) -{ - GFileInfo *info = NULL; - GFileEnumerator *enumerator = NULL; - GPtrArray *names = NULL; - GFile *file; - const gchar *name; - int i; - - enumerator = g_file_enumerate_children (dir, - G_FILE_ATTRIBUTE_STANDARD_TYPE"," - G_FILE_ATTRIBUTE_STANDARD_NAME"," - G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN"," - G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP, - G_FILE_QUERY_INFO_NONE, - NULL, NULL); - if (!enumerator) { - goto out; - } - - names = g_ptr_array_new_with_free_func (g_free); - while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) { - if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR && - !g_file_info_get_is_hidden (info) && - g_str_has_suffix (g_file_info_get_name (info), ".env")) - g_ptr_array_add (names, g_strdup (g_file_info_get_name (info))); - - g_clear_object (&info); - } - - g_ptr_array_sort (names, compare_str); - - for (i = 0; i < names->len; i++) { - name = g_ptr_array_index (names, i); - file = g_file_get_child (dir, name); - load_env_file (worker, file); - g_object_unref (file); - } - - out: - g_clear_pointer (&names, g_ptr_array_unref); - g_clear_object (&enumerator); -} - -static void -gdm_session_worker_load_env_d (GdmSessionWorker *worker) +load_env_func (const char *var, + const char *value, + gpointer user_data) { - GFile *dir; - - dir = g_file_new_for_path (DATADIR "/gdm/env.d"); - gdm_session_worker_load_env_dir (worker, dir); - g_object_unref (dir); - - dir = g_file_new_for_path (GDMCONFDIR "/env.d"); - gdm_session_worker_load_env_dir (worker, dir); - g_object_unref (dir); + GdmSessionWorker *worker = user_data; + gdm_session_worker_set_environment_variable (worker, var, value); } static gboolean @@ -2181,7 +2073,7 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, #endif if (!worker->priv->is_program_session) { - gdm_session_worker_load_env_d (worker); + gdm_load_env_d (load_env_func, get_var_cb, worker); } environment = gdm_session_worker_get_environment (worker); |