diff --git a/src/file-chooser.c b/src/file-chooser.c index 7beebf460..201b972d9 100644 --- a/src/file-chooser.c +++ b/src/file-chooser.c @@ -155,41 +155,6 @@ send_response_in_thread_func (GTask *task, g_task_return_boolean (task, TRUE); } -/* Calling Lookup on a nonexisting path does not work, so we - * pull the doc id out of the path manually. - */ -static gboolean -looks_like_document_portal_path (const char *path, - char **guessed_docid) -{ - const char *prefix = "/run/user/"; - char *docid; - char *p, *q; - - if (!g_str_has_prefix (path, prefix)) - return FALSE; - - p = strstr (path, "/doc/"); - if (!p) - return FALSE; - - p += strlen ("/doc/"); - q = strchr (p, '/'); - if (q) - docid = g_strndup (p, q - p); - else - docid = g_strdup (p); - - if (docid[0] == '\0') - { - g_free (docid); - return FALSE; - } - - *guessed_docid = docid; - return TRUE; -} - static char * get_host_folder_for_doc_id (const char *doc_id) { @@ -555,7 +520,7 @@ handle_open_file (XdpDbusFileChooser *object, const char *path_from_app = g_variant_get_bytestring (value); g_autofree char *host_path = g_strdup (path_from_app); g_autofree char *doc_id_from_app = NULL; - if (looks_like_document_portal_path (host_path, &doc_id_from_app)) + if (xdp_looks_like_document_portal_path (host_path, &doc_id_from_app)) { char *real_path = get_host_folder_for_doc_id (doc_id_from_app); if (real_path) @@ -696,7 +661,7 @@ handle_save_file (XdpDbusFileChooser *object, g_autofree char *doc_id = NULL; if (strcmp (path, host_path) == 0 && - looks_like_document_portal_path (path, &doc_id)) + xdp_looks_like_document_portal_path (path, &doc_id)) { char *real_path = xdp_get_real_path_for_doc_id (doc_id); @@ -721,7 +686,7 @@ handle_save_file (XdpDbusFileChooser *object, const char *path_from_app = g_variant_get_bytestring (value); g_autofree char *host_path = g_strdup (path_from_app); g_autofree char *doc_id_from_app = NULL; - if (looks_like_document_portal_path (host_path, &doc_id_from_app)) + if (xdp_looks_like_document_portal_path (host_path, &doc_id_from_app)) { char *real_path = get_host_folder_for_doc_id (doc_id_from_app); if (real_path) diff --git a/src/open-uri.c b/src/open-uri.c index b5447c2ef..148dbbb59 100644 --- a/src/open-uri.c +++ b/src/open-uri.c @@ -585,6 +585,23 @@ app_exists (const char *app_id) return (info != NULL); } +static char* +build_host_path_from_doc_id(const char* doc_id, const char* doc_path) +{ + gchar *result; + g_autofree char *host_path = xdp_get_real_path_for_doc_id (doc_id); + g_autofree char *doc_path_regex = g_strconcat("/run/user/[0-9]+/doc/", doc_id, "/[^/]+(.*)", NULL); + gchar **path_postfix = g_regex_split_simple(doc_path_regex, doc_path, 0, 0); + + if (path_postfix[0] && path_postfix[1]) { + result = g_strconcat(host_path, path_postfix[1], NULL); + } else { + result = g_strdup(host_path); + } + g_strfreev (path_postfix); + return result; +} + static void handle_open_in_thread_func (GTask *task, gpointer source_object, @@ -688,7 +705,11 @@ handle_open_in_thread_func (GTask *task, if (path != NULL) { - host_path = xdp_get_real_path_for_doc_path (path, request->app_info); + g_autofree char *guessed_docid = NULL; + if (xdp_looks_like_document_portal_path(path, &guessed_docid)) + { + host_path = build_host_path_from_doc_id(guessed_docid, path); + } if (host_path) { g_debug ("OpenFile: translating path value '%s' to host path '%s'", path, host_path); @@ -724,7 +745,13 @@ handle_open_in_thread_func (GTask *task, if (open_dir) { - g_autofree char *real_path = xdp_get_real_path_for_doc_path (path, request->app_info); + g_autofree char *guessed_docid = NULL; + g_autofree char *real_path = NULL; + if (xdp_looks_like_document_portal_path(path, &guessed_docid)) { + real_path = build_host_path_from_doc_id(guessed_docid, path); + } else { + real_path = g_strdup(path); + } /* Try opening the directory via the file manager interface, then fall back to a plain URI open */ g_autoptr(GError) local_error = NULL; diff --git a/src/xdp-utils.c b/src/xdp-utils.c index 902bb3199..63b615359 100644 --- a/src/xdp-utils.c +++ b/src/xdp-utils.c @@ -284,6 +284,43 @@ is_valid_name_character (gint c, gboolean allow_dash) (c == '_') || (allow_dash && c == '-'); } + +/* Get the document id from the path, if there's any. + * Returns TRUE when path seems to point to the documents + * storage. + */ +gboolean +xdp_looks_like_document_portal_path (const char *path, + char **guessed_docid) +{ + const char *prefix = "/run/user/"; + char *docid; + char *p, *q; + + if (!g_str_has_prefix (path, prefix)) + return FALSE; + + p = strstr (path, "/doc/"); + if (!p) + return FALSE; + + p += strlen ("/doc/"); + q = strchr (p, '/'); + if (q) + docid = g_strndup (p, q - p); + else + docid = g_strdup (p); + + if (docid[0] == '\0') + { + g_free (docid); + return FALSE; + } + + *guessed_docid = docid; + return TRUE; +} + /* This is the same as flatpak apps, except we also allow names to start with digits, and two-element names so that ids of the form snap.$snapname is allowed for all snap names. */ diff --git a/src/xdp-utils.h b/src/xdp-utils.h index 59a18d67c..c3f89921c 100644 --- a/src/xdp-utils.h +++ b/src/xdp-utils.h @@ -66,6 +66,7 @@ G_DEFINE_AUTO_CLEANUP_FREE_FUNC(XdpFd, close, -1) void xdp_set_documents_mountpoint (const char *path); const char * xdp_get_documents_mountpoint (void); char * xdp_get_alternate_document_path (const char *path, const char *app_id); +gboolean xdp_looks_like_document_portal_path (const char *path, char **guessed_docid); void xdp_connection_track_name_owners (GDBusConnection *connection, XdpPeerDiedCallback peer_died_cb);