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
|
|
@ -1534,9 +1534,9 @@ iter_object_dir (OstreeRepo *self,
|
|||
GError *temp_error = NULL;
|
||||
GFileEnumerator *enumerator = 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,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
|
|
@ -1549,31 +1549,44 @@ iter_object_dir (OstreeRepo *self,
|
|||
{
|
||||
const char *name;
|
||||
guint32 type;
|
||||
char *dot;
|
||||
GFile *child;
|
||||
GString *checksum = NULL;
|
||||
OstreeObjectType objtype;
|
||||
|
||||
name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
|
||||
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;
|
||||
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)
|
||||
{
|
||||
path = g_build_filename (dirpath, name, NULL);
|
||||
callback (self, path, file_info, user_data);
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
if ((dot - name) != 62)
|
||||
goto loop_out;
|
||||
|
||||
g_object_unref (file_info);
|
||||
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);
|
||||
goto out;
|
||||
|
|
@ -1583,6 +1596,7 @@ iter_object_dir (OstreeRepo *self,
|
|||
|
||||
ret = TRUE;
|
||||
out:
|
||||
g_clear_object (&file_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,8 +157,12 @@ gboolean ostree_repo_diff (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
typedef void (*OstreeRepoObjectIter) (OstreeRepo *self, const char *path,
|
||||
GFileInfo *fileinfo, gpointer user_data);
|
||||
typedef void (*OstreeRepoObjectIter) (OstreeRepo *self,
|
||||
const char *checksum,
|
||||
OstreeObjectType type,
|
||||
GFile *path,
|
||||
GFileInfo *fileinfo,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean ostree_repo_iter_objects (OstreeRepo *self,
|
||||
OstreeRepoObjectIter callback,
|
||||
|
|
|
|||
|
|
@ -41,13 +41,12 @@ typedef struct {
|
|||
|
||||
static gboolean
|
||||
checksum_packed_file (OtFsckData *data,
|
||||
const char *path,
|
||||
GFile *file,
|
||||
GChecksum **out_checksum,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GChecksum *ret_checksum = NULL;
|
||||
GFile *file = NULL;
|
||||
char *metadata_buf = NULL;
|
||||
GVariant *metadata = NULL;
|
||||
GVariant *xattrs = NULL;
|
||||
|
|
@ -58,8 +57,6 @@ checksum_packed_file (OtFsckData *data,
|
|||
gsize bytes_read;
|
||||
char buf[8192];
|
||||
|
||||
file = ot_gfile_new_for_path (path);
|
||||
|
||||
in = g_file_read (file, NULL, error);
|
||||
if (!in)
|
||||
goto out;
|
||||
|
|
@ -105,7 +102,6 @@ checksum_packed_file (OtFsckData *data,
|
|||
if (ret_checksum)
|
||||
g_checksum_free (ret_checksum);
|
||||
g_free (metadata_buf);
|
||||
g_clear_object (&file);
|
||||
g_clear_object (&in);
|
||||
if (metadata)
|
||||
g_variant_unref (metadata);
|
||||
|
|
@ -116,77 +112,54 @@ checksum_packed_file (OtFsckData *data,
|
|||
|
||||
static void
|
||||
object_iter_callback (OstreeRepo *repo,
|
||||
const char *path,
|
||||
const char *exp_checksum,
|
||||
OstreeObjectType objtype,
|
||||
GFile *objf,
|
||||
GFileInfo *file_info,
|
||||
gpointer user_data)
|
||||
{
|
||||
OtFsckData *data = user_data;
|
||||
GChecksum *checksum = NULL;
|
||||
const char *path = NULL;
|
||||
GChecksum *real_checksum = 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");
|
||||
if (nlinks < 2 && !quiet)
|
||||
g_printerr ("note: floating object: %s\n", path); */
|
||||
|
||||
if (g_str_has_suffix (path, ".meta"))
|
||||
objtype = OSTREE_OBJECT_TYPE_META;
|
||||
else if (g_str_has_suffix (path, ".file"))
|
||||
objtype = OSTREE_OBJECT_TYPE_FILE;
|
||||
else if (g_str_has_suffix (path, ".packfile"))
|
||||
if (ostree_repo_is_archive (repo)
|
||||
&& objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
objtype = OSTREE_OBJECT_TYPE_FILE;
|
||||
packed = TRUE;
|
||||
if (!g_str_has_suffix (path, ".packfile"))
|
||||
{
|
||||
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid unpacked filename '%s'",
|
||||
path);
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
if (packed && objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
if (!checksum_packed_file (data, path, &checksum, &error))
|
||||
if (!checksum_packed_file (data, objf, &real_checksum, &error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ostree_checksum_file (f, objtype, &checksum, NULL, &error))
|
||||
if (!ostree_checksum_file (objf, objtype, &real_checksum, NULL, &error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
filename_checksum = g_strdup (g_file_info_get_name (file_info));
|
||||
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)
|
||||
if (strcmp (exp_checksum, g_checksum_get_string (real_checksum)) != 0)
|
||||
{
|
||||
data->had_error = TRUE;
|
||||
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++;
|
||||
|
||||
out:
|
||||
g_clear_object (&f);
|
||||
if (checksum != NULL)
|
||||
g_checksum_free (checksum);
|
||||
g_free (dirname);
|
||||
g_free (checksum_prefix);
|
||||
g_free (checksum_string);
|
||||
g_free (filename_checksum);
|
||||
if (real_checksum != NULL)
|
||||
g_checksum_free (real_checksum);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
|
|
|
|||
Loading…
Reference in New Issue