common: Break out the parts of flatpak-utils that deal with FlatpakDir

This breaks the circular dependency between flatpak-utils and flatpak-dir.
There is still a circular dependency between flatpak-dir and
flatpak-dir-utils, but I don't want to make flatpak-dir even larger.

Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie
2023-05-17 14:10:35 +01:00
committed by Georges Basile Stavracas Neto
parent 3c82620bab
commit 14db9d48cf
12 changed files with 699 additions and 639 deletions

View File

@@ -28,6 +28,7 @@
#include "flatpak-tty-utils-private.h"
#include "flatpak-utils-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-dir-utils-private.h"
#include "flatpak-xml-utils-private.h"
G_BEGIN_DECLS

View File

@@ -346,22 +346,6 @@ GQuark flatpak_dir_error_quark (void);
#define FLATPAK_DEPLOY_DATA_GVARIANT_STRING "(ssasta{sv})"
#define FLATPAK_DEPLOY_DATA_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_DEPLOY_DATA_GVARIANT_STRING)
/**
* FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT:
*
* dict
* s: subset name
* ->
* ay - checksum of subsummary
* aay - previous subsummary checksums
* a{sv} - per subset metadata
* a{sv} - metadata
*/
#define FLATPAK_SUMMARY_INDEX_GVARIANT_STRING "(a{s(ayaaya{sv})}a{sv})"
#define FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_SUMMARY_INDEX_GVARIANT_STRING)
GPtrArray *flatpak_get_system_base_dir_locations (GCancellable *cancellable,
GError **error);
GFile * flatpak_get_system_default_base_dir_location (void);

View File

@@ -0,0 +1,85 @@
/*
* Copyright © 2014 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "libglnx.h"
#include "flatpak-ref-utils-private.h"
G_BEGIN_DECLS
typedef struct
{
char *id;
char *installed_id;
char *commit;
FlatpakDecomposed *ref;
char *directory;
char *files_path;
char *subdir_suffix;
char *add_ld_path;
char **merge_dirs;
int priority;
gboolean needs_tmpfs;
gboolean is_unmaintained;
} FlatpakExtension;
void flatpak_extension_free (FlatpakExtension *extension);
FlatpakDecomposed *flatpak_find_current_ref (const char *app_id,
GCancellable *cancellable,
GError **error);
GFile *flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
FlatpakDir **dir_out,
GCancellable *cancellable,
GError **error);
GFile * flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
GCancellable *cancellable,
GError **error);
GFile * flatpak_find_unmaintained_extension_dir_if_exists (const char *name,
const char *arch,
const char *branch,
GCancellable *cancellable);
FlatpakDeploy * flatpak_find_deploy_for_ref_in (GPtrArray *dirs,
const char *ref,
const char *commit,
GCancellable *cancellable,
GError **error);
FlatpakDeploy * flatpak_find_deploy_for_ref (const char *ref,
const char *commit,
FlatpakDir *opt_user_dir,
GCancellable *cancellable,
GError **error);
char ** flatpak_list_deployed_refs (const char *type,
const char *name_prefix,
const char *arch,
const char *branch,
GCancellable *cancellable,
GError **error);
char ** flatpak_list_unmaintained_refs (const char *name_prefix,
const char *branch,
const char *arch,
GCancellable *cancellable,
GError **error);
GList *flatpak_list_extensions (GKeyFile *metakey,
const char *arch,
const char *branch);
void flatpak_log_dir_access (FlatpakDir *dir);
G_END_DECLS

586
common/flatpak-dir-utils.c Normal file
View File

@@ -0,0 +1,586 @@
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
* Copyright © 1995-1998 Free Software Foundation, Inc.
* Copyright © 2014-2019 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "flatpak-dir-utils-private.h"
#include <glib/gi18n-lib.h>
#include "flatpak-dir-private.h"
#include "flatpak-metadata-private.h"
#include "flatpak-utils-private.h"
char **
flatpak_list_deployed_refs (const char *type,
const char *name_prefix,
const char *arch,
const char *branch,
GCancellable *cancellable,
GError **error)
{
gchar **ret = NULL;
g_autoptr(GPtrArray) names = NULL;
g_autoptr(GHashTable) hash = NULL;
g_autoptr(FlatpakDir) user_dir = NULL;
g_autoptr(GPtrArray) system_dirs = NULL;
int i;
hash = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
user_dir = flatpak_dir_get_user ();
system_dirs = flatpak_dir_get_system_list (cancellable, error);
if (system_dirs == NULL)
goto out;
if (!flatpak_dir_collect_deployed_refs (user_dir, type, name_prefix,
arch, branch, hash, cancellable,
error))
goto out;
for (i = 0; i < system_dirs->len; i++)
{
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
if (!flatpak_dir_collect_deployed_refs (system_dir, type, name_prefix,
arch, branch, hash, cancellable,
error))
goto out;
}
names = g_ptr_array_new ();
GLNX_HASH_TABLE_FOREACH (hash, FlatpakDecomposed *, ref)
{
g_ptr_array_add (names, flatpak_decomposed_dup_id (ref));
}
g_ptr_array_sort (names, flatpak_strcmp0_ptr);
g_ptr_array_add (names, NULL);
ret = (char **) g_ptr_array_free (names, FALSE);
names = NULL;
out:
return ret;
}
char **
flatpak_list_unmaintained_refs (const char *name_prefix,
const char *arch,
const char *branch,
GCancellable *cancellable,
GError **error)
{
gchar **ret = NULL;
g_autoptr(GPtrArray) names = NULL;
g_autoptr(GHashTable) hash = NULL;
g_autoptr(FlatpakDir) user_dir = NULL;
const char *key;
GHashTableIter iter;
g_autoptr(GPtrArray) system_dirs = NULL;
int i;
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
user_dir = flatpak_dir_get_user ();
if (!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix,
arch, branch, hash, cancellable,
error))
return NULL;
system_dirs = flatpak_dir_get_system_list (cancellable, error);
if (system_dirs == NULL)
return NULL;
for (i = 0; i < system_dirs->len; i++)
{
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
if (!flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix,
arch, branch, hash, cancellable,
error))
return NULL;
}
names = g_ptr_array_new ();
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
g_ptr_array_add (names, g_strdup (key));
g_ptr_array_sort (names, flatpak_strcmp0_ptr);
g_ptr_array_add (names, NULL);
ret = (char **) g_ptr_array_free (names, FALSE);
names = NULL;
return ret;
}
GFile *
flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
FlatpakDir **dir_out,
GCancellable *cancellable,
GError **error)
{
g_autoptr(FlatpakDir) user_dir = NULL;
g_autoptr(GPtrArray) system_dirs = NULL;
FlatpakDir *dir = NULL;
g_autoptr(GFile) deploy = NULL;
user_dir = flatpak_dir_get_user ();
system_dirs = flatpak_dir_get_system_list (cancellable, error);
if (system_dirs == NULL)
return NULL;
dir = user_dir;
deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
if (deploy == NULL)
{
int i;
for (i = 0; deploy == NULL && i < system_dirs->len; i++)
{
dir = g_ptr_array_index (system_dirs, i);
deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
if (deploy != NULL)
break;
}
}
if (deploy == NULL)
{
flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), flatpak_decomposed_get_ref (ref));
return NULL;
}
if (dir_out)
*dir_out = g_object_ref (dir);
return g_steal_pointer (&deploy);
}
GFile *
flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GFile) deploy = NULL;
deploy = flatpak_find_deploy_dir_for_ref (ref, NULL, cancellable, error);
if (deploy == NULL)
return NULL;
return g_file_get_child (deploy, "files");
}
GFile *
flatpak_find_unmaintained_extension_dir_if_exists (const char *name,
const char *arch,
const char *branch,
GCancellable *cancellable)
{
g_autoptr(FlatpakDir) user_dir = NULL;
g_autoptr(GFile) extension_dir = NULL;
g_autoptr(GError) local_error = NULL;
user_dir = flatpak_dir_get_user ();
extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (user_dir, name, arch, branch, cancellable);
if (extension_dir == NULL)
{
g_autoptr(GPtrArray) system_dirs = NULL;
int i;
system_dirs = flatpak_dir_get_system_list (cancellable, &local_error);
if (system_dirs == NULL)
{
g_warning ("Could not get the system installations: %s", local_error->message);
return NULL;
}
for (i = 0; i < system_dirs->len; i++)
{
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (system_dir, name, arch, branch, cancellable);
if (extension_dir != NULL)
break;
}
}
if (extension_dir == NULL)
return NULL;
return g_steal_pointer (&extension_dir);
}
FlatpakDecomposed *
flatpak_find_current_ref (const char *app_id,
GCancellable *cancellable,
GError **error)
{
g_autoptr(FlatpakDecomposed) current_ref = NULL;
g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();
int i;
current_ref = flatpak_dir_current_ref (user_dir, app_id, NULL);
if (current_ref == NULL)
{
g_autoptr(GPtrArray) system_dirs = NULL;
system_dirs = flatpak_dir_get_system_list (cancellable, error);
if (system_dirs == NULL)
return FALSE;
for (i = 0; i < system_dirs->len; i++)
{
FlatpakDir *dir = g_ptr_array_index (system_dirs, i);
current_ref = flatpak_dir_current_ref (dir, app_id, cancellable);
if (current_ref != NULL)
break;
}
}
if (current_ref)
return g_steal_pointer (&current_ref);
flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), app_id);
return NULL;
}
FlatpakDeploy *
flatpak_find_deploy_for_ref_in (GPtrArray *dirs,
const char *ref_str,
const char *commit,
GCancellable *cancellable,
GError **error)
{
FlatpakDeploy *deploy = NULL;
int i;
g_autoptr(GError) my_error = NULL;
g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, error);
if (ref == NULL)
return NULL;
for (i = 0; deploy == NULL && i < dirs->len; i++)
{
FlatpakDir *dir = g_ptr_array_index (dirs, i);
flatpak_log_dir_access (dir);
g_clear_error (&my_error);
deploy = flatpak_dir_load_deployed (dir, ref, commit, cancellable, &my_error);
}
if (deploy == NULL)
g_propagate_error (error, g_steal_pointer (&my_error));
return deploy;
}
FlatpakDeploy *
flatpak_find_deploy_for_ref (const char *ref,
const char *commit,
FlatpakDir *opt_user_dir,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GPtrArray) dirs = NULL;
dirs = flatpak_dir_get_system_list (cancellable, error);
if (dirs == NULL)
return NULL;
/* If an custom dir was passed, use that instead of the user dir.
* This is used when running apply-extra-data where if the target
* is a custom installation location the regular user one may not
* have the (possibly just installed in this transaction) runtime.
*/
if (opt_user_dir)
g_ptr_array_insert (dirs, 0, g_object_ref (opt_user_dir));
else
g_ptr_array_insert (dirs, 0, flatpak_dir_get_user ());
return flatpak_find_deploy_for_ref_in (dirs, ref, commit, cancellable, error);
}
void
flatpak_extension_free (FlatpakExtension *extension)
{
g_free (extension->id);
g_free (extension->installed_id);
g_free (extension->commit);
flatpak_decomposed_unref (extension->ref);
g_free (extension->directory);
g_free (extension->files_path);
g_free (extension->add_ld_path);
g_free (extension->subdir_suffix);
g_strfreev (extension->merge_dirs);
g_free (extension);
}
static int
flatpak_extension_compare (gconstpointer _a,
gconstpointer _b)
{
const FlatpakExtension *a = _a;
const FlatpakExtension *b = _b;
return b->priority - a->priority;
}
static FlatpakExtension *
flatpak_extension_new (const char *id,
const char *extension,
FlatpakDecomposed *ref,
const char *directory,
const char *add_ld_path,
const char *subdir_suffix,
char **merge_dirs,
GFile *files,
GFile *deploy_dir,
gboolean is_unmaintained,
OstreeRepo *repo)
{
FlatpakExtension *ext = g_new0 (FlatpakExtension, 1);
g_autoptr(GBytes) deploy_data = NULL;
ext->id = g_strdup (id);
ext->installed_id = g_strdup (extension);
ext->ref = flatpak_decomposed_ref (ref);
ext->directory = g_strdup (directory);
ext->files_path = g_file_get_path (files);
ext->add_ld_path = g_strdup (add_ld_path);
ext->subdir_suffix = g_strdup (subdir_suffix);
ext->merge_dirs = g_strdupv (merge_dirs);
ext->is_unmaintained = is_unmaintained;
/* Unmaintained extensions won't have a deploy or commit; see
* https://github.com/flatpak/flatpak/issues/167 */
if (deploy_dir && !is_unmaintained)
{
deploy_data = flatpak_load_deploy_data (deploy_dir, ref, repo, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
if (deploy_data)
ext->commit = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
}
if (is_unmaintained)
ext->priority = 1000;
else
{
g_autoptr(GKeyFile) keyfile = g_key_file_new ();
g_autofree char *metadata_path = g_build_filename (ext->files_path, "../metadata", NULL);
if (g_key_file_load_from_file (keyfile, metadata_path, G_KEY_FILE_NONE, NULL))
ext->priority = g_key_file_get_integer (keyfile,
FLATPAK_METADATA_GROUP_EXTENSION_OF,
FLATPAK_METADATA_KEY_PRIORITY,
NULL);
}
return ext;
}
static GList *
add_extension (GKeyFile *metakey,
const char *group,
const char *extension,
const char *arch,
const char *branch,
GList *res)
{
FlatpakExtension *ext;
g_autofree char *directory = g_key_file_get_string (metakey, group,
FLATPAK_METADATA_KEY_DIRECTORY,
NULL);
g_autofree char *add_ld_path = g_key_file_get_string (metakey, group,
FLATPAK_METADATA_KEY_ADD_LD_PATH,
NULL);
g_auto(GStrv) merge_dirs = g_key_file_get_string_list (metakey, group,
FLATPAK_METADATA_KEY_MERGE_DIRS,
NULL, NULL);
g_autofree char *enable_if = g_key_file_get_string (metakey, group,
FLATPAK_METADATA_KEY_ENABLE_IF,
NULL);
g_autofree char *subdir_suffix = g_key_file_get_string (metakey, group,
FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX,
NULL);
g_autoptr(FlatpakDecomposed) ref = NULL;
gboolean is_unmaintained = FALSE;
g_autoptr(GFile) files = NULL;
g_autoptr(GFile) deploy_dir = NULL;
g_autoptr(FlatpakDir) dir = NULL;
if (directory == NULL)
return res;
ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, extension, arch, branch, NULL);
if (ref == NULL)
return res;
files = flatpak_find_unmaintained_extension_dir_if_exists (extension, arch, branch, NULL);
if (files == NULL)
{
deploy_dir = flatpak_find_deploy_dir_for_ref (ref, &dir, NULL, NULL);
if (deploy_dir)
files = g_file_get_child (deploy_dir, "files");
}
else
is_unmaintained = TRUE;
/* Prefer a full extension (org.freedesktop.Locale) over subdirectory ones (org.freedesktop.Locale.sv) */
if (files != NULL)
{
if (flatpak_extension_matches_reason (extension, enable_if, TRUE))
{
ext = flatpak_extension_new (extension, extension, ref, directory,
add_ld_path, subdir_suffix, merge_dirs,
files, deploy_dir, is_unmaintained,
is_unmaintained ? NULL : flatpak_dir_get_repo (dir));
res = g_list_prepend (res, ext);
}
}
else if (g_key_file_get_boolean (metakey, group,
FLATPAK_METADATA_KEY_SUBDIRECTORIES, NULL))
{
g_autofree char *prefix = g_strconcat (extension, ".", NULL);
g_auto(GStrv) ids = NULL;
g_auto(GStrv) unmaintained_refs = NULL;
int j;
ids = flatpak_list_deployed_refs ("runtime", prefix, arch, branch,
NULL, NULL);
for (j = 0; ids != NULL && ids[j] != NULL; j++)
{
const char *id = ids[j];
g_autofree char *extended_dir = g_build_filename (directory, id + strlen (prefix), NULL);
g_autoptr(FlatpakDecomposed) dir_ref = NULL;
g_autoptr(GFile) subdir_deploy_dir = NULL;
g_autoptr(GFile) subdir_files = NULL;
g_autoptr(FlatpakDir) subdir_dir = NULL;
dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, id, arch, branch, NULL);
if (dir_ref == NULL)
continue;
subdir_deploy_dir = flatpak_find_deploy_dir_for_ref (dir_ref, &subdir_dir, NULL, NULL);
if (subdir_deploy_dir)
subdir_files = g_file_get_child (subdir_deploy_dir, "files");
if (subdir_files && flatpak_extension_matches_reason (id, enable_if, TRUE))
{
ext = flatpak_extension_new (extension, id, dir_ref, extended_dir,
add_ld_path, subdir_suffix, merge_dirs,
subdir_files, subdir_deploy_dir, FALSE,
flatpak_dir_get_repo (subdir_dir));
ext->needs_tmpfs = TRUE;
res = g_list_prepend (res, ext);
}
}
unmaintained_refs = flatpak_list_unmaintained_refs (prefix, arch, branch,
NULL, NULL);
for (j = 0; unmaintained_refs != NULL && unmaintained_refs[j] != NULL; j++)
{
g_autofree char *extended_dir = g_build_filename (directory, unmaintained_refs[j] + strlen (prefix), NULL);
g_autoptr(FlatpakDecomposed) dir_ref = NULL;
g_autoptr(GFile) subdir_files = flatpak_find_unmaintained_extension_dir_if_exists (unmaintained_refs[j], arch, branch, NULL);
dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, unmaintained_refs[j], arch, branch, NULL);
if (dir_ref == NULL)
continue;
if (subdir_files && flatpak_extension_matches_reason (unmaintained_refs[j], enable_if, TRUE))
{
ext = flatpak_extension_new (extension, unmaintained_refs[j], dir_ref,
extended_dir, add_ld_path, subdir_suffix,
merge_dirs, subdir_files, NULL, TRUE, NULL);
ext->needs_tmpfs = TRUE;
res = g_list_prepend (res, ext);
}
}
}
return res;
}
GList *
flatpak_list_extensions (GKeyFile *metakey,
const char *arch,
const char *default_branch)
{
g_auto(GStrv) groups = NULL;
int i, j;
GList *res;
res = NULL;
if (arch == NULL)
arch = flatpak_get_arch ();
groups = g_key_file_get_groups (metakey, NULL);
for (i = 0; groups[i] != NULL; i++)
{
char *extension;
if (g_str_has_prefix (groups[i], FLATPAK_METADATA_GROUP_PREFIX_EXTENSION) &&
*(extension = (groups[i] + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION))) != 0)
{
g_autofree char *version = g_key_file_get_string (metakey, groups[i],
FLATPAK_METADATA_KEY_VERSION,
NULL);
g_auto(GStrv) versions = g_key_file_get_string_list (metakey, groups[i],
FLATPAK_METADATA_KEY_VERSIONS,
NULL, NULL);
g_autofree char *name = NULL;
const char *default_branches[] = { default_branch, NULL};
const char **branches;
flatpak_parse_extension_with_tag (extension, &name, NULL);
if (versions)
branches = (const char **) versions;
else
{
if (version)
default_branches[0] = version;
branches = default_branches;
}
for (j = 0; branches[j] != NULL; j++)
res = add_extension (metakey, groups[i], name, arch, branches[j], res);
}
}
return g_list_sort (g_list_reverse (res), flatpak_extension_compare);
}
void
flatpak_log_dir_access (FlatpakDir *dir)
{
if (dir != NULL)
{
GFile *dir_path = NULL;
g_autofree char *dir_path_str = NULL;
g_autofree char *dir_name = NULL;
dir_path = flatpak_dir_get_path (dir);
if (dir_path != NULL)
dir_path_str = g_file_get_path (dir_path);
dir_name = flatpak_dir_get_name (dir);
g_info ("Opening %s flatpak installation at path %s", dir_name, dir_path_str);
}
}

View File

@@ -49,6 +49,7 @@
#include "flatpak-appdata-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-dir-utils-private.h"
#include "flatpak-error.h"
#include "flatpak-locale-utils-private.h"
#include "flatpak-oci-registry-private.h"
@@ -8330,6 +8331,9 @@ apply_extra_data (FlatpakDir *self,
{
/* We pass in self here so that we ensure that we find the runtime in case it only
exists in this installation (which might be custom) */
/* TODO: This is a circular dependency between flatpak-dir (which
* deals with a single installation) and flatpak-dir-utils (which
* deals with all the installations on the system). */
runtime_deploy = flatpak_find_deploy_for_ref (flatpak_decomposed_get_ref (runtime_ref), NULL, self, cancellable, error);
if (runtime_deploy == NULL)
return FALSE;
@@ -15470,6 +15474,9 @@ add_related (FlatpakDir *self,
auto_prune = TRUE;
/* Don't download if there is an unmaintained extension already installed */
/* TODO: This is a circular dependency between flatpak-dir (which
* deals with a single installation) and flatpak-dir-utils (which
* deals with all the installations on the system). */
unmaintained_path =
flatpak_find_unmaintained_extension_dir_if_exists (id, arch, branch, NULL);
if (unmaintained_path != NULL && deploy_data == NULL)

View File

@@ -25,6 +25,7 @@
#include <glib.h>
#include <gio/gio.h>
#include "flatpak-dir-private.h"
#include "flatpak-json-oci-private.h"
#include "flatpak-utils-http-private.h"
#include "flatpak-utils-private.h"

View File

@@ -22,6 +22,21 @@
#include "libglnx.h"
/**
* FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT:
*
* dict
* s: subset name
* ->
* ay - checksum of subsummary
* aay - previous subsummary checksums
* a{sv} - per subset metadata
* a{sv} - metadata
*/
#define FLATPAK_SUMMARY_INDEX_GVARIANT_STRING "(a{s(ayaaya{sv})}a{sv})"
#define FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_SUMMARY_INDEX_GVARIANT_STRING)
#define FLATPAK_REF_GROUP "Flatpak Ref"
#define FLATPAK_REF_VERSION_KEY "Version"
#define FLATPAK_REF_URL_KEY "Url"

View File

@@ -59,6 +59,7 @@
#include "flatpak-run-sockets-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-dir-utils-private.h"
#include "flatpak-instance-private.h"
#include "flatpak-systemd-dbus-generated.h"
#include "flatpak-document-dbus-generated.h"

View File

@@ -28,8 +28,8 @@
#include <gio/gunixfdlist.h>
#include "flatpak-error.h"
#include "flatpak-glib-backports-private.h"
#include "flatpak-ref-utils-private.h"
#include "flatpak-variant-private.h"
#include "flatpak-dir-private.h"
#include <ostree.h>
#define AUTOFS_SUPER_MAGIC 0x0187
@@ -138,42 +138,6 @@ gboolean flatpak_var_ref_map_lookup_ref (VarRefMapRef ref_map,
const char *ref,
VarRefInfoRef *out_info);
FlatpakDecomposed *flatpak_find_current_ref (const char *app_id,
GCancellable *cancellable,
GError **error);
GFile *flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
FlatpakDir **dir_out,
GCancellable *cancellable,
GError **error);
GFile * flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
GCancellable *cancellable,
GError **error);
GFile * flatpak_find_unmaintained_extension_dir_if_exists (const char *name,
const char *arch,
const char *branch,
GCancellable *cancellable);
FlatpakDeploy * flatpak_find_deploy_for_ref_in (GPtrArray *dirs,
const char *ref,
const char *commit,
GCancellable *cancellable,
GError **error);
FlatpakDeploy * flatpak_find_deploy_for_ref (const char *ref,
const char *commit,
FlatpakDir *opt_user_dir,
GCancellable *cancellable,
GError **error);
char ** flatpak_list_deployed_refs (const char *type,
const char *name_prefix,
const char *arch,
const char *branch,
GCancellable *cancellable,
GError **error);
char ** flatpak_list_unmaintained_refs (const char *name_prefix,
const char *branch,
const char *arch,
GCancellable *cancellable,
GError **error);
gboolean flatpak_remove_dangling_symlinks (GFile *dir,
GCancellable *cancellable,
GError **error);
@@ -358,32 +322,10 @@ gboolean flatpak_pull_from_bundle (OstreeRepo *repo,
GCancellable *cancellable,
GError **error);
typedef struct
{
char *id;
char *installed_id;
char *commit;
FlatpakDecomposed *ref;
char *directory;
char *files_path;
char *subdir_suffix;
char *add_ld_path;
char **merge_dirs;
int priority;
gboolean needs_tmpfs;
gboolean is_unmaintained;
} FlatpakExtension;
void flatpak_extension_free (FlatpakExtension *extension);
void flatpak_parse_extension_with_tag (const char *extension,
char **name,
char **tag);
GList *flatpak_list_extensions (GKeyFile *metakey,
const char *arch,
const char *branch);
gboolean flatpak_argument_needs_quoting (const char *arg);
char * flatpak_quote_argv (const char *argv[],
gssize len);
@@ -560,8 +502,6 @@ typedef OstreeAsyncProgress OstreeAsyncProgressFinish;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeAsyncProgressFinish, flatpak_ostree_progress_finish);
void flatpak_log_dir_access (FlatpakDir *dir);
gboolean flatpak_check_required_version (const char *ref,
GKeyFile *metakey,
GError **error);

View File

@@ -43,9 +43,7 @@
#include <gio/gunixoutputstream.h>
#include <gio/gunixinputstream.h>
#include "flatpak-dir-private.h"
#include "flatpak-error.h"
#include "flatpak-metadata-private.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h"
@@ -864,297 +862,6 @@ flatpak_filters_allow_ref (GRegex *allow_refs,
return FALSE;
}
char **
flatpak_list_deployed_refs (const char *type,
const char *name_prefix,
const char *arch,
const char *branch,
GCancellable *cancellable,
GError **error)
{
gchar **ret = NULL;
g_autoptr(GPtrArray) names = NULL;
g_autoptr(GHashTable) hash = NULL;
g_autoptr(FlatpakDir) user_dir = NULL;
g_autoptr(GPtrArray) system_dirs = NULL;
int i;
hash = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
user_dir = flatpak_dir_get_user ();
system_dirs = flatpak_dir_get_system_list (cancellable, error);
if (system_dirs == NULL)
goto out;
if (!flatpak_dir_collect_deployed_refs (user_dir, type, name_prefix,
arch, branch, hash, cancellable,
error))
goto out;
for (i = 0; i < system_dirs->len; i++)
{
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
if (!flatpak_dir_collect_deployed_refs (system_dir, type, name_prefix,
arch, branch, hash, cancellable,
error))
goto out;
}
names = g_ptr_array_new ();
GLNX_HASH_TABLE_FOREACH (hash, FlatpakDecomposed *, ref)
{
g_ptr_array_add (names, flatpak_decomposed_dup_id (ref));
}
g_ptr_array_sort (names, flatpak_strcmp0_ptr);
g_ptr_array_add (names, NULL);
ret = (char **) g_ptr_array_free (names, FALSE);
names = NULL;
out:
return ret;
}
char **
flatpak_list_unmaintained_refs (const char *name_prefix,
const char *arch,
const char *branch,
GCancellable *cancellable,
GError **error)
{
gchar **ret = NULL;
g_autoptr(GPtrArray) names = NULL;
g_autoptr(GHashTable) hash = NULL;
g_autoptr(FlatpakDir) user_dir = NULL;
const char *key;
GHashTableIter iter;
g_autoptr(GPtrArray) system_dirs = NULL;
int i;
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
user_dir = flatpak_dir_get_user ();
if (!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix,
arch, branch, hash, cancellable,
error))
return NULL;
system_dirs = flatpak_dir_get_system_list (cancellable, error);
if (system_dirs == NULL)
return NULL;
for (i = 0; i < system_dirs->len; i++)
{
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
if (!flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix,
arch, branch, hash, cancellable,
error))
return NULL;
}
names = g_ptr_array_new ();
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
g_ptr_array_add (names, g_strdup (key));
g_ptr_array_sort (names, flatpak_strcmp0_ptr);
g_ptr_array_add (names, NULL);
ret = (char **) g_ptr_array_free (names, FALSE);
names = NULL;
return ret;
}
GFile *
flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
FlatpakDir **dir_out,
GCancellable *cancellable,
GError **error)
{
g_autoptr(FlatpakDir) user_dir = NULL;
g_autoptr(GPtrArray) system_dirs = NULL;
FlatpakDir *dir = NULL;
g_autoptr(GFile) deploy = NULL;
user_dir = flatpak_dir_get_user ();
system_dirs = flatpak_dir_get_system_list (cancellable, error);
if (system_dirs == NULL)
return NULL;
dir = user_dir;
deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
if (deploy == NULL)
{
int i;
for (i = 0; deploy == NULL && i < system_dirs->len; i++)
{
dir = g_ptr_array_index (system_dirs, i);
deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
if (deploy != NULL)
break;
}
}
if (deploy == NULL)
{
flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), flatpak_decomposed_get_ref (ref));
return NULL;
}
if (dir_out)
*dir_out = g_object_ref (dir);
return g_steal_pointer (&deploy);
}
GFile *
flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GFile) deploy = NULL;
deploy = flatpak_find_deploy_dir_for_ref (ref, NULL, cancellable, error);
if (deploy == NULL)
return NULL;
return g_file_get_child (deploy, "files");
}
GFile *
flatpak_find_unmaintained_extension_dir_if_exists (const char *name,
const char *arch,
const char *branch,
GCancellable *cancellable)
{
g_autoptr(FlatpakDir) user_dir = NULL;
g_autoptr(GFile) extension_dir = NULL;
g_autoptr(GError) local_error = NULL;
user_dir = flatpak_dir_get_user ();
extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (user_dir, name, arch, branch, cancellable);
if (extension_dir == NULL)
{
g_autoptr(GPtrArray) system_dirs = NULL;
int i;
system_dirs = flatpak_dir_get_system_list (cancellable, &local_error);
if (system_dirs == NULL)
{
g_warning ("Could not get the system installations: %s", local_error->message);
return NULL;
}
for (i = 0; i < system_dirs->len; i++)
{
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (system_dir, name, arch, branch, cancellable);
if (extension_dir != NULL)
break;
}
}
if (extension_dir == NULL)
return NULL;
return g_steal_pointer (&extension_dir);
}
FlatpakDecomposed *
flatpak_find_current_ref (const char *app_id,
GCancellable *cancellable,
GError **error)
{
g_autoptr(FlatpakDecomposed) current_ref = NULL;
g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();
int i;
current_ref = flatpak_dir_current_ref (user_dir, app_id, NULL);
if (current_ref == NULL)
{
g_autoptr(GPtrArray) system_dirs = NULL;
system_dirs = flatpak_dir_get_system_list (cancellable, error);
if (system_dirs == NULL)
return FALSE;
for (i = 0; i < system_dirs->len; i++)
{
FlatpakDir *dir = g_ptr_array_index (system_dirs, i);
current_ref = flatpak_dir_current_ref (dir, app_id, cancellable);
if (current_ref != NULL)
break;
}
}
if (current_ref)
return g_steal_pointer (&current_ref);
flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), app_id);
return NULL;
}
FlatpakDeploy *
flatpak_find_deploy_for_ref_in (GPtrArray *dirs,
const char *ref_str,
const char *commit,
GCancellable *cancellable,
GError **error)
{
FlatpakDeploy *deploy = NULL;
int i;
g_autoptr(GError) my_error = NULL;
g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, error);
if (ref == NULL)
return NULL;
for (i = 0; deploy == NULL && i < dirs->len; i++)
{
FlatpakDir *dir = g_ptr_array_index (dirs, i);
flatpak_log_dir_access (dir);
g_clear_error (&my_error);
deploy = flatpak_dir_load_deployed (dir, ref, commit, cancellable, &my_error);
}
if (deploy == NULL)
g_propagate_error (error, g_steal_pointer (&my_error));
return deploy;
}
FlatpakDeploy *
flatpak_find_deploy_for_ref (const char *ref,
const char *commit,
FlatpakDir *opt_user_dir,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GPtrArray) dirs = NULL;
dirs = flatpak_dir_get_system_list (cancellable, error);
if (dirs == NULL)
return NULL;
/* If an custom dir was passed, use that instead of the user dir.
* This is used when running apply-extra-data where if the target
* is a custom installation location the regular user one may not
* have the (possibly just installed in this transaction) runtime.
*/
if (opt_user_dir)
g_ptr_array_insert (dirs, 0, g_object_ref (opt_user_dir));
else
g_ptr_array_insert (dirs, 0, flatpak_dir_get_user ());
return flatpak_find_deploy_for_ref_in (dirs, ref, commit, cancellable, error);
}
static gboolean
remove_dangling_symlinks (int parent_fd,
const char *name,
@@ -5494,83 +5201,6 @@ flatpak_repo_generate_appstream (OstreeRepo *repo,
return TRUE;
}
void
flatpak_extension_free (FlatpakExtension *extension)
{
g_free (extension->id);
g_free (extension->installed_id);
g_free (extension->commit);
flatpak_decomposed_unref (extension->ref);
g_free (extension->directory);
g_free (extension->files_path);
g_free (extension->add_ld_path);
g_free (extension->subdir_suffix);
g_strfreev (extension->merge_dirs);
g_free (extension);
}
static int
flatpak_extension_compare (gconstpointer _a,
gconstpointer _b)
{
const FlatpakExtension *a = _a;
const FlatpakExtension *b = _b;
return b->priority - a->priority;
}
static FlatpakExtension *
flatpak_extension_new (const char *id,
const char *extension,
FlatpakDecomposed *ref,
const char *directory,
const char *add_ld_path,
const char *subdir_suffix,
char **merge_dirs,
GFile *files,
GFile *deploy_dir,
gboolean is_unmaintained,
OstreeRepo *repo)
{
FlatpakExtension *ext = g_new0 (FlatpakExtension, 1);
g_autoptr(GBytes) deploy_data = NULL;
ext->id = g_strdup (id);
ext->installed_id = g_strdup (extension);
ext->ref = flatpak_decomposed_ref (ref);
ext->directory = g_strdup (directory);
ext->files_path = g_file_get_path (files);
ext->add_ld_path = g_strdup (add_ld_path);
ext->subdir_suffix = g_strdup (subdir_suffix);
ext->merge_dirs = g_strdupv (merge_dirs);
ext->is_unmaintained = is_unmaintained;
/* Unmaintained extensions won't have a deploy or commit; see
* https://github.com/flatpak/flatpak/issues/167 */
if (deploy_dir && !is_unmaintained)
{
deploy_data = flatpak_load_deploy_data (deploy_dir, ref, repo, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
if (deploy_data)
ext->commit = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
}
if (is_unmaintained)
ext->priority = 1000;
else
{
g_autoptr(GKeyFile) keyfile = g_key_file_new ();
g_autofree char *metadata_path = g_build_filename (ext->files_path, "../metadata", NULL);
if (g_key_file_load_from_file (keyfile, metadata_path, G_KEY_FILE_NONE, NULL))
ext->priority = g_key_file_get_integer (keyfile,
FLATPAK_METADATA_GROUP_EXTENSION_OF,
FLATPAK_METADATA_KEY_PRIORITY,
NULL);
}
return ext;
}
gboolean
flatpak_extension_matches_reason (const char *extension_id,
const char *reasons,
@@ -5648,130 +5278,6 @@ flatpak_extension_matches_reason (const char *extension_id,
return FALSE;
}
static GList *
add_extension (GKeyFile *metakey,
const char *group,
const char *extension,
const char *arch,
const char *branch,
GList *res)
{
FlatpakExtension *ext;
g_autofree char *directory = g_key_file_get_string (metakey, group,
FLATPAK_METADATA_KEY_DIRECTORY,
NULL);
g_autofree char *add_ld_path = g_key_file_get_string (metakey, group,
FLATPAK_METADATA_KEY_ADD_LD_PATH,
NULL);
g_auto(GStrv) merge_dirs = g_key_file_get_string_list (metakey, group,
FLATPAK_METADATA_KEY_MERGE_DIRS,
NULL, NULL);
g_autofree char *enable_if = g_key_file_get_string (metakey, group,
FLATPAK_METADATA_KEY_ENABLE_IF,
NULL);
g_autofree char *subdir_suffix = g_key_file_get_string (metakey, group,
FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX,
NULL);
g_autoptr(FlatpakDecomposed) ref = NULL;
gboolean is_unmaintained = FALSE;
g_autoptr(GFile) files = NULL;
g_autoptr(GFile) deploy_dir = NULL;
g_autoptr(FlatpakDir) dir = NULL;
if (directory == NULL)
return res;
ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, extension, arch, branch, NULL);
if (ref == NULL)
return res;
files = flatpak_find_unmaintained_extension_dir_if_exists (extension, arch, branch, NULL);
if (files == NULL)
{
deploy_dir = flatpak_find_deploy_dir_for_ref (ref, &dir, NULL, NULL);
if (deploy_dir)
files = g_file_get_child (deploy_dir, "files");
}
else
is_unmaintained = TRUE;
/* Prefer a full extension (org.freedesktop.Locale) over subdirectory ones (org.freedesktop.Locale.sv) */
if (files != NULL)
{
if (flatpak_extension_matches_reason (extension, enable_if, TRUE))
{
ext = flatpak_extension_new (extension, extension, ref, directory,
add_ld_path, subdir_suffix, merge_dirs,
files, deploy_dir, is_unmaintained,
is_unmaintained ? NULL : flatpak_dir_get_repo (dir));
res = g_list_prepend (res, ext);
}
}
else if (g_key_file_get_boolean (metakey, group,
FLATPAK_METADATA_KEY_SUBDIRECTORIES, NULL))
{
g_autofree char *prefix = g_strconcat (extension, ".", NULL);
g_auto(GStrv) ids = NULL;
g_auto(GStrv) unmaintained_refs = NULL;
int j;
ids = flatpak_list_deployed_refs ("runtime", prefix, arch, branch,
NULL, NULL);
for (j = 0; ids != NULL && ids[j] != NULL; j++)
{
const char *id = ids[j];
g_autofree char *extended_dir = g_build_filename (directory, id + strlen (prefix), NULL);
g_autoptr(FlatpakDecomposed) dir_ref = NULL;
g_autoptr(GFile) subdir_deploy_dir = NULL;
g_autoptr(GFile) subdir_files = NULL;
g_autoptr(FlatpakDir) subdir_dir = NULL;
dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, id, arch, branch, NULL);
if (dir_ref == NULL)
continue;
subdir_deploy_dir = flatpak_find_deploy_dir_for_ref (dir_ref, &subdir_dir, NULL, NULL);
if (subdir_deploy_dir)
subdir_files = g_file_get_child (subdir_deploy_dir, "files");
if (subdir_files && flatpak_extension_matches_reason (id, enable_if, TRUE))
{
ext = flatpak_extension_new (extension, id, dir_ref, extended_dir,
add_ld_path, subdir_suffix, merge_dirs,
subdir_files, subdir_deploy_dir, FALSE,
flatpak_dir_get_repo (subdir_dir));
ext->needs_tmpfs = TRUE;
res = g_list_prepend (res, ext);
}
}
unmaintained_refs = flatpak_list_unmaintained_refs (prefix, arch, branch,
NULL, NULL);
for (j = 0; unmaintained_refs != NULL && unmaintained_refs[j] != NULL; j++)
{
g_autofree char *extended_dir = g_build_filename (directory, unmaintained_refs[j] + strlen (prefix), NULL);
g_autoptr(FlatpakDecomposed) dir_ref = NULL;
g_autoptr(GFile) subdir_files = flatpak_find_unmaintained_extension_dir_if_exists (unmaintained_refs[j], arch, branch, NULL);
dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, unmaintained_refs[j], arch, branch, NULL);
if (dir_ref == NULL)
continue;
if (subdir_files && flatpak_extension_matches_reason (unmaintained_refs[j], enable_if, TRUE))
{
ext = flatpak_extension_new (extension, unmaintained_refs[j], dir_ref,
extended_dir, add_ld_path, subdir_suffix,
merge_dirs, subdir_files, NULL, TRUE, NULL);
ext->needs_tmpfs = TRUE;
res = g_list_prepend (res, ext);
}
}
}
return res;
}
void
flatpak_parse_extension_with_tag (const char *extension,
char **name,
@@ -5798,57 +5304,6 @@ flatpak_parse_extension_with_tag (const char *extension,
*tag = NULL;
}
GList *
flatpak_list_extensions (GKeyFile *metakey,
const char *arch,
const char *default_branch)
{
g_auto(GStrv) groups = NULL;
int i, j;
GList *res;
res = NULL;
if (arch == NULL)
arch = flatpak_get_arch ();
groups = g_key_file_get_groups (metakey, NULL);
for (i = 0; groups[i] != NULL; i++)
{
char *extension;
if (g_str_has_prefix (groups[i], FLATPAK_METADATA_GROUP_PREFIX_EXTENSION) &&
*(extension = (groups[i] + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION))) != 0)
{
g_autofree char *version = g_key_file_get_string (metakey, groups[i],
FLATPAK_METADATA_KEY_VERSION,
NULL);
g_auto(GStrv) versions = g_key_file_get_string_list (metakey, groups[i],
FLATPAK_METADATA_KEY_VERSIONS,
NULL, NULL);
g_autofree char *name = NULL;
const char *default_branches[] = { default_branch, NULL};
const char **branches;
flatpak_parse_extension_with_tag (extension, &name, NULL);
if (versions)
branches = (const char **) versions;
else
{
if (version)
default_branches[0] = version;
branches = default_branches;
}
for (j = 0; branches[j] != NULL; j++)
res = add_extension (metakey, groups[i], name, arch, branches[j], res);
}
}
return g_list_sort (g_list_reverse (res), flatpak_extension_compare);
}
#define OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "(uayttay)"
#define OSTREE_STATIC_DELTA_FALLBACK_FORMAT "(yaytt)"
#define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")"
@@ -6370,23 +5825,6 @@ flatpak_g_ptr_array_contains_string (GPtrArray *array, const char *str)
return FALSE;
}
void
flatpak_log_dir_access (FlatpakDir *dir)
{
if (dir != NULL)
{
GFile *dir_path = NULL;
g_autofree char *dir_path_str = NULL;
g_autofree char *dir_name = NULL;
dir_path = flatpak_dir_get_path (dir);
if (dir_path != NULL)
dir_path_str = g_file_get_path (dir_path);
dir_name = flatpak_dir_get_name (dir);
g_info ("Opening %s flatpak installation at path %s", dir_name, dir_path_str);
}
}
gboolean
flatpak_check_required_version (const char *ref,
GKeyFile *metakey,

View File

@@ -168,6 +168,7 @@ sources = [
'flatpak-chain-input-stream.c',
'flatpak-context.c',
'flatpak-dir.c',
'flatpak-dir-utils.c',
'flatpak-error.c',
'flatpak-exports.c',
'flatpak-glib-backports.c',

View File

@@ -49,6 +49,7 @@ app/flatpak-main.c
app/flatpak-quiet-transaction.c
common/flatpak-auth.c
common/flatpak-context.c
common/flatpak-dir-utils.c
common/flatpak-dir.c
common/flatpak-exports.c
common/flatpak-glib-backports.c