core: Rework object iteration API to be GFile based and pass more data
It makes more sense to have e.g. the details of .packfile naming inside the repo, and pass the expected checksum and type.
This commit is contained in:
parent
8621eb85b1
commit
f6ec479f17
|
|
@ -1524,9 +1524,9 @@ ostree_repo_commit_from_filelist_fd (OstreeRepo *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
iter_object_dir (OstreeRepo *self,
|
iter_object_dir (OstreeRepo *self,
|
||||||
GFile *dir,
|
GFile *dir,
|
||||||
OstreeRepoObjectIter callback,
|
OstreeRepoObjectIter callback,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
|
@ -1534,9 +1534,9 @@ iter_object_dir (OstreeRepo *self,
|
||||||
GError *temp_error = NULL;
|
GError *temp_error = NULL;
|
||||||
GFileEnumerator *enumerator = NULL;
|
GFileEnumerator *enumerator = NULL;
|
||||||
GFileInfo *file_info = NULL;
|
GFileInfo *file_info = NULL;
|
||||||
const char *dirpath = NULL;
|
const char *dirname = NULL;
|
||||||
|
|
||||||
dirpath = ot_gfile_get_path_cached (dir);
|
dirname = ot_gfile_get_basename_cached (dir);
|
||||||
|
|
||||||
enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
|
enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||||
|
|
@ -1549,31 +1549,44 @@ iter_object_dir (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
guint32 type;
|
guint32 type;
|
||||||
|
char *dot;
|
||||||
|
GFile *child;
|
||||||
|
GString *checksum = NULL;
|
||||||
|
OstreeObjectType objtype;
|
||||||
|
|
||||||
name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
|
name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
|
||||||
type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
|
type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
|
||||||
|
|
||||||
if (type != G_FILE_TYPE_DIRECTORY
|
|
||||||
&& (g_str_has_suffix (name, ".meta")
|
|
||||||
|| g_str_has_suffix (name, ".file")
|
|
||||||
|| g_str_has_suffix (name, ".packfile")))
|
|
||||||
{
|
|
||||||
char *dot;
|
|
||||||
char *path;
|
|
||||||
|
|
||||||
dot = strrchr (name, '.');
|
|
||||||
g_assert (dot);
|
|
||||||
|
|
||||||
if ((dot - name) == 62)
|
|
||||||
{
|
|
||||||
path = g_build_filename (dirpath, name, NULL);
|
|
||||||
callback (self, path, file_info, user_data);
|
|
||||||
g_free (path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (file_info);
|
if (type == G_FILE_TYPE_DIRECTORY)
|
||||||
|
goto loop_out;
|
||||||
|
|
||||||
|
if (g_str_has_suffix (name, ".meta"))
|
||||||
|
objtype = OSTREE_OBJECT_TYPE_META;
|
||||||
|
else if (g_str_has_suffix (name, ".file")
|
||||||
|
|| g_str_has_suffix (name, ".packfile"))
|
||||||
|
objtype = OSTREE_OBJECT_TYPE_FILE;
|
||||||
|
else
|
||||||
|
goto loop_out;
|
||||||
|
|
||||||
|
dot = strrchr (name, '.');
|
||||||
|
g_assert (dot);
|
||||||
|
|
||||||
|
if ((dot - name) != 62)
|
||||||
|
goto loop_out;
|
||||||
|
|
||||||
|
checksum = g_string_new (dirname);
|
||||||
|
g_string_append_len (checksum, name, 62);
|
||||||
|
|
||||||
|
child = g_file_get_child (dir, name);
|
||||||
|
callback (self, checksum->str, objtype, child, file_info, user_data);
|
||||||
|
|
||||||
|
loop_out:
|
||||||
|
if (checksum)
|
||||||
|
g_string_free (checksum, TRUE);
|
||||||
|
g_clear_object (&file_info);
|
||||||
|
g_clear_object (&child);
|
||||||
}
|
}
|
||||||
if (file_info == NULL && temp_error != NULL)
|
if (temp_error != NULL)
|
||||||
{
|
{
|
||||||
g_propagate_error (error, temp_error);
|
g_propagate_error (error, temp_error);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -1583,14 +1596,15 @@ iter_object_dir (OstreeRepo *self,
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
|
g_clear_object (&file_info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
ostree_repo_iter_objects (OstreeRepo *self,
|
ostree_repo_iter_objects (OstreeRepo *self,
|
||||||
OstreeRepoObjectIter callback,
|
OstreeRepoObjectIter callback,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
OstreeRepoPrivate *priv = GET_PRIVATE (self);
|
OstreeRepoPrivate *priv = GET_PRIVATE (self);
|
||||||
GFile *objectdir = NULL;
|
GFile *objectdir = NULL;
|
||||||
|
|
|
||||||
|
|
@ -157,13 +157,17 @@ gboolean ostree_repo_diff (OstreeRepo *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
typedef void (*OstreeRepoObjectIter) (OstreeRepo *self, const char *path,
|
typedef void (*OstreeRepoObjectIter) (OstreeRepo *self,
|
||||||
GFileInfo *fileinfo, gpointer user_data);
|
const char *checksum,
|
||||||
|
OstreeObjectType type,
|
||||||
|
GFile *path,
|
||||||
|
GFileInfo *fileinfo,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
gboolean ostree_repo_iter_objects (OstreeRepo *self,
|
gboolean ostree_repo_iter_objects (OstreeRepo *self,
|
||||||
OstreeRepoObjectIter callback,
|
OstreeRepoObjectIter callback,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,13 +41,12 @@ typedef struct {
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
checksum_packed_file (OtFsckData *data,
|
checksum_packed_file (OtFsckData *data,
|
||||||
const char *path,
|
GFile *file,
|
||||||
GChecksum **out_checksum,
|
GChecksum **out_checksum,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
GChecksum *ret_checksum = NULL;
|
GChecksum *ret_checksum = NULL;
|
||||||
GFile *file = NULL;
|
|
||||||
char *metadata_buf = NULL;
|
char *metadata_buf = NULL;
|
||||||
GVariant *metadata = NULL;
|
GVariant *metadata = NULL;
|
||||||
GVariant *xattrs = NULL;
|
GVariant *xattrs = NULL;
|
||||||
|
|
@ -58,8 +57,6 @@ checksum_packed_file (OtFsckData *data,
|
||||||
gsize bytes_read;
|
gsize bytes_read;
|
||||||
char buf[8192];
|
char buf[8192];
|
||||||
|
|
||||||
file = ot_gfile_new_for_path (path);
|
|
||||||
|
|
||||||
in = g_file_read (file, NULL, error);
|
in = g_file_read (file, NULL, error);
|
||||||
if (!in)
|
if (!in)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -105,7 +102,6 @@ checksum_packed_file (OtFsckData *data,
|
||||||
if (ret_checksum)
|
if (ret_checksum)
|
||||||
g_checksum_free (ret_checksum);
|
g_checksum_free (ret_checksum);
|
||||||
g_free (metadata_buf);
|
g_free (metadata_buf);
|
||||||
g_clear_object (&file);
|
|
||||||
g_clear_object (&in);
|
g_clear_object (&in);
|
||||||
if (metadata)
|
if (metadata)
|
||||||
g_variant_unref (metadata);
|
g_variant_unref (metadata);
|
||||||
|
|
@ -115,78 +111,55 @@ checksum_packed_file (OtFsckData *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
object_iter_callback (OstreeRepo *repo,
|
object_iter_callback (OstreeRepo *repo,
|
||||||
const char *path,
|
const char *exp_checksum,
|
||||||
|
OstreeObjectType objtype,
|
||||||
|
GFile *objf,
|
||||||
GFileInfo *file_info,
|
GFileInfo *file_info,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
OtFsckData *data = user_data;
|
OtFsckData *data = user_data;
|
||||||
GChecksum *checksum = NULL;
|
const char *path = NULL;
|
||||||
|
GChecksum *real_checksum = NULL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char *dirname = NULL;
|
|
||||||
char *checksum_prefix = NULL;
|
|
||||||
char *checksum_string = NULL;
|
|
||||||
char *filename_checksum = NULL;
|
|
||||||
gboolean packed = FALSE;
|
|
||||||
OstreeObjectType objtype;
|
|
||||||
char *dot;
|
|
||||||
GFile *f = NULL;
|
|
||||||
|
|
||||||
f = ot_gfile_new_for_path (path);
|
path = ot_gfile_get_path_cached (objf);
|
||||||
|
|
||||||
/* nlinks = g_file_info_get_attribute_uint32 (file_info, "unix::nlink");
|
/* nlinks = g_file_info_get_attribute_uint32 (file_info, "unix::nlink");
|
||||||
if (nlinks < 2 && !quiet)
|
if (nlinks < 2 && !quiet)
|
||||||
g_printerr ("note: floating object: %s\n", path); */
|
g_printerr ("note: floating object: %s\n", path); */
|
||||||
|
|
||||||
if (g_str_has_suffix (path, ".meta"))
|
if (ostree_repo_is_archive (repo)
|
||||||
objtype = OSTREE_OBJECT_TYPE_META;
|
&& objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||||
else if (g_str_has_suffix (path, ".file"))
|
|
||||||
objtype = OSTREE_OBJECT_TYPE_FILE;
|
|
||||||
else if (g_str_has_suffix (path, ".packfile"))
|
|
||||||
{
|
{
|
||||||
objtype = OSTREE_OBJECT_TYPE_FILE;
|
if (!g_str_has_suffix (path, ".packfile"))
|
||||||
packed = TRUE;
|
{
|
||||||
}
|
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
else
|
"Invalid unpacked filename '%s'",
|
||||||
g_assert_not_reached ();
|
path);
|
||||||
|
goto out;
|
||||||
if (packed && objtype == OSTREE_OBJECT_TYPE_FILE)
|
}
|
||||||
{
|
if (!checksum_packed_file (data, objf, &real_checksum, &error))
|
||||||
if (!checksum_packed_file (data, path, &checksum, &error))
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!ostree_checksum_file (f, objtype, &checksum, NULL, &error))
|
if (!ostree_checksum_file (objf, objtype, &real_checksum, NULL, &error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
filename_checksum = g_strdup (g_file_info_get_name (file_info));
|
if (strcmp (exp_checksum, g_checksum_get_string (real_checksum)) != 0)
|
||||||
dot = strrchr (filename_checksum, '.');
|
|
||||||
g_assert (dot != NULL);
|
|
||||||
*dot = '\0';
|
|
||||||
|
|
||||||
dirname = g_path_get_dirname (path);
|
|
||||||
checksum_prefix = g_path_get_basename (dirname);
|
|
||||||
checksum_string = g_strconcat (checksum_prefix, filename_checksum, NULL);
|
|
||||||
|
|
||||||
if (strcmp (checksum_string, g_checksum_get_string (checksum)) != 0)
|
|
||||||
{
|
{
|
||||||
data->had_error = TRUE;
|
data->had_error = TRUE;
|
||||||
g_printerr ("ERROR: corrupted object '%s' expected checksum: %s\n",
|
g_printerr ("ERROR: corrupted object '%s' expected checksum: %s\n",
|
||||||
path, g_checksum_get_string (checksum));
|
exp_checksum, g_checksum_get_string (real_checksum));
|
||||||
}
|
}
|
||||||
|
|
||||||
data->n_objects++;
|
data->n_objects++;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_clear_object (&f);
|
if (real_checksum != NULL)
|
||||||
if (checksum != NULL)
|
g_checksum_free (real_checksum);
|
||||||
g_checksum_free (checksum);
|
|
||||||
g_free (dirname);
|
|
||||||
g_free (checksum_prefix);
|
|
||||||
g_free (checksum_string);
|
|
||||||
g_free (filename_checksum);
|
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
g_printerr ("%s\n", error->message);
|
g_printerr ("%s\n", error->message);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue