From: Visarion Alexandru <viorel.visarion@xxxxxxxxx> Allow to specify a list of directories at runtime via properties, which are symlinked in a per-session temporary, shared directory. https://bugs.freedesktop.org/show_bug.cgi?id=95255 --- src/spice-session-priv.h | 2 ++ src/spice-session.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/src/spice-session-priv.h b/src/spice-session-priv.h index 049973a..013265b 100644 --- a/src/spice-session-priv.h +++ b/src/spice-session-priv.h @@ -88,6 +88,8 @@ guint32 spice_session_get_playback_latency(SpiceSession *session); void spice_session_sync_playback_latency(SpiceSession *session); const gchar* spice_session_get_shared_dir(SpiceSession *session); void spice_session_set_shared_dir(SpiceSession *session, const gchar *dir); +GStrv spice_session_get_multiple_shared_dirs(SpiceSession *session); +void spice_session_set_multiple_shared_dirs(SpiceSession *session, GStrv shared_directories); gboolean spice_session_get_audio_enabled(SpiceSession *session); gboolean spice_session_get_smartcard_enabled(SpiceSession *session); gboolean spice_session_get_usbredir_enabled(SpiceSession *session); diff --git a/src/spice-session.c b/src/spice-session.c index db283d4..82e1fda 100644 --- a/src/spice-session.c +++ b/src/spice-session.c @@ -19,6 +19,7 @@ #include <gio/gio.h> #include <glib.h> +#include <glib/gstdio.h> #ifdef G_OS_UNIX #include <gio/gunixsocketaddress.h> #endif @@ -60,6 +61,7 @@ struct _SpiceSessionPrivate { gboolean read_only; SpiceURI *proxy; gchar *shared_dir; + GStrv multiple_shared_dirs; gboolean share_dir_ro; /* whether to enable audio */ @@ -200,6 +202,7 @@ enum { PROP_PROXY, PROP_SECURE_CHANNELS, PROP_SHARED_DIR, + PROP_MULTIPLE_SHARED_DIRS, PROP_SHARE_DIR_RO, PROP_USERNAME, PROP_UNIX_PATH, @@ -369,6 +372,7 @@ spice_session_finalize(GObject *gobject) g_strfreev(s->disable_effects); g_strfreev(s->secure_channels); g_free(s->shared_dir); + g_strfreev(s->multiple_shared_dirs); g_clear_pointer(&s->images, cache_free); glz_decoder_window_destroy(s->glz_window); @@ -683,6 +687,9 @@ static void spice_session_get_property(GObject *gobject, case PROP_SHARED_DIR: g_value_set_string(value, spice_session_get_shared_dir(session)); break; + case PROP_MULTIPLE_SHARED_DIRS: + g_value_set_boxed(value, spice_session_get_multiple_shared_dirs(session)); + break; case PROP_SHARE_DIR_RO: g_value_set_boolean(value, s->share_dir_ro); break; @@ -822,6 +829,9 @@ static void spice_session_set_property(GObject *gobject, case PROP_SHARED_DIR: spice_session_set_shared_dir(session, g_value_get_string(value)); break; + case PROP_MULTIPLE_SHARED_DIRS: + spice_session_set_multiple_shared_dirs(session, g_value_dup_boxed(value)); + break; case PROP_SHARE_DIR_RO: s->share_dir_ro = g_value_get_boolean(value); break; @@ -1421,6 +1431,22 @@ static void spice_session_class_init(SpiceSessionClass *klass) G_PARAM_STATIC_STRINGS)); /** + * SpiceSession:multiple-shared-dirs: + * + * Location of the shared directory + * + * Since: 0.24 + **/ + g_object_class_install_property + (gobject_class, PROP_MULTIPLE_SHARED_DIRS, + g_param_spec_boxed("multiple-shared-dirs", + "Multiple shared directories", + "Multiple shared directories", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** * SpiceSession:share-dir-ro: * * Whether to share the directory read-only. @@ -2595,6 +2621,71 @@ void spice_session_set_shared_dir(SpiceSession *session, const gchar *dir) s->shared_dir = g_strdup(dir); } +G_GNUC_INTERNAL +GStrv spice_session_get_multiple_shared_dirs(SpiceSession *session) +{ + g_return_val_if_fail(SPICE_IS_SESSION(session), NULL); + + SpiceSessionPrivate *s = session->priv; + return s->multiple_shared_dirs; +} + +G_GNUC_INTERNAL +void spice_session_set_multiple_shared_dirs(SpiceSession *session, GStrv directories) +{ + g_return_if_fail(SPICE_IS_SESSION(session)); + + SpiceSessionPrivate *s = session->priv; + g_strfreev(s->multiple_shared_dirs); + + gint i, mode = S_IRWXU; + + gchar *conf_dir_name = g_strconcat("shared_folders_", g_strdup_printf("%d", s->connection_id), NULL); + gchar *conf_dir = g_build_filename(g_get_tmp_dir(), "spice", conf_dir_name, NULL); + + g_free(conf_dir_name); + + GDir *dir = g_dir_open(conf_dir, 0, NULL); + + if (dir != NULL) { + // remove any old symlinks belonging to this session + const gchar *link = g_dir_read_name(dir); + + while (link != NULL) { + g_remove(g_build_filename(conf_dir, link, NULL)); + link = g_dir_read_name(dir); + } + + g_dir_close(dir); + } + else + g_return_if_fail(g_mkdir_with_parents(conf_dir, mode) == 0); + + for (i = 0; directories[i] != NULL; i++) { + + gchar *link_name = g_strrstr(directories[i], "/"); + + if (link_name == NULL) { + SPICE_DEBUG("Couldn't extract directory from %s", directories[i]); + + continue; + } + link_name++; + + gchar *link_path = g_build_filename(conf_dir, link_name, NULL); + + if (symlink(directories[i], link_path) == -1) + SPICE_DEBUG("Couldn't create symlink for %s", link_path); + + g_free(link_path); + } + + s->multiple_shared_dirs = directories; + s->shared_dir = g_strdup(g_build_filename(conf_dir, NULL)); + + g_free(conf_dir); +} + /** * spice_session_get_proxy_uri: * @session: a #SpiceSession -- 2.7.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel