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:
Colin Walters 2011-11-18 15:21:32 -05:00
parent 8621eb85b1
commit f6ec479f17
3 changed files with 75 additions and 84 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);