core: Move merge dirs code into gio utils

This commit is contained in:
Colin Walters 2011-11-21 15:03:09 -05:00
parent c117aadc95
commit aa69aae94e
4 changed files with 99 additions and 100 deletions

View File

@ -29,8 +29,6 @@ G_BEGIN_DECLS
#define OSTREE_MAX_METADATA_SIZE (1 << 26)
#define OSTREE_GIO_FAST_QUERYINFO "standard::name,standard::type,standard::is-symlink,standard::symlink-target,standard::is-hidden,unix::*"
#define OSTREE_EMPTY_STRING_SHA256 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
typedef enum {

View File

@ -132,3 +132,93 @@ ot_gfile_get_basename_cached (GFile *file)
}
return name;
}
gboolean
ot_gfile_merge_dirs (GFile *destination,
GFile *src,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
const char *dest_path = NULL;
const char *src_path = NULL;
GError *temp_error = NULL;
GFileInfo *src_fileinfo = NULL;
GFileInfo *dest_fileinfo = NULL;
GFileEnumerator *src_enum = NULL;
GFile *dest_subfile = NULL;
GFile *src_subfile = NULL;
const char *name;
guint32 type;
const int move_flags = G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA;
dest_path = ot_gfile_get_path_cached (destination);
src_path = ot_gfile_get_path_cached (src);
dest_fileinfo = g_file_query_info (destination, OSTREE_GIO_FAST_QUERYINFO,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
cancellable, &temp_error);
if (dest_fileinfo)
{
type = g_file_info_get_attribute_uint32 (dest_fileinfo, "standard::type");
if (type != G_FILE_TYPE_DIRECTORY)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Attempting to replace non-directory %s with directory %s",
dest_path, src_path);
goto out;
}
src_enum = g_file_enumerate_children (src, OSTREE_GIO_FAST_QUERYINFO,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
cancellable, error);
if (!src_enum)
goto out;
while ((src_fileinfo = g_file_enumerator_next_file (src_enum, cancellable, &temp_error)) != NULL)
{
type = g_file_info_get_attribute_uint32 (src_fileinfo, "standard::type");
name = g_file_info_get_attribute_byte_string (src_fileinfo, "standard::name");
dest_subfile = g_file_get_child (destination, name);
src_subfile = g_file_get_child (src, name);
if (type == G_FILE_TYPE_DIRECTORY)
{
if (!ot_gfile_merge_dirs (dest_subfile, src_subfile, cancellable, error))
goto out;
}
else
{
if (!g_file_move (src_subfile, dest_subfile,
move_flags, NULL, NULL, cancellable, error))
goto out;
}
g_clear_object (&dest_subfile);
g_clear_object (&src_subfile);
}
if (temp_error)
{
g_propagate_error (error, temp_error);
goto out;
}
}
else if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
g_clear_error (&temp_error);
if (!g_file_move (src, destination, move_flags, NULL, NULL, cancellable, error))
goto out;
}
else
goto out;
ret = TRUE;
out:
g_clear_object (&src_fileinfo);
g_clear_object (&dest_fileinfo);
g_clear_object (&src_enum);
g_clear_object (&dest_subfile);
g_clear_object (&src_subfile);
return ret;
}

View File

@ -27,6 +27,8 @@
G_BEGIN_DECLS
#define OSTREE_GIO_FAST_QUERYINFO "standard::name,standard::type,standard::is-symlink,standard::symlink-target,standard::is-hidden,unix::*"
GFile *ot_gfile_new_for_path (const char *path);
const char *ot_gfile_get_path_cached (GFile *file);
@ -41,6 +43,12 @@ gboolean ot_gfile_load_contents_utf8 (GFile *file,
GCancellable *cancellable,
GError **error);
gboolean ot_gfile_merge_dirs (GFile *destination,
GFile *src,
GCancellable *cancellable,
GError **error);
G_END_DECLS
#endif

View File

@ -74,103 +74,6 @@ rm_rf (GFile *path)
g_clear_object (&path_enum);
}
static gboolean
merge_dir (GFile *destination,
GFile *src,
GError **error)
{
gboolean ret = FALSE;
const char *dest_path = NULL;
const char *src_path = NULL;
GError *temp_error = NULL;
GFileInfo *src_fileinfo = NULL;
GFileInfo *dest_fileinfo = NULL;
GFileEnumerator *src_enum = NULL;
GFile *dest_subfile = NULL;
GFile *src_subfile = NULL;
const char *name;
guint32 type;
dest_path = ot_gfile_get_path_cached (destination);
src_path = ot_gfile_get_path_cached (src);
dest_fileinfo = g_file_query_info (destination, OSTREE_GIO_FAST_QUERYINFO,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL, &temp_error);
if (dest_fileinfo)
{
type = g_file_info_get_attribute_uint32 (dest_fileinfo, "standard::type");
if (type != G_FILE_TYPE_DIRECTORY)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Attempting to replace non-directory %s with directory %s",
dest_path, src_path);
goto out;
}
src_enum = g_file_enumerate_children (src, OSTREE_GIO_FAST_QUERYINFO,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL, error);
if (!src_enum)
goto out;
while ((src_fileinfo = g_file_enumerator_next_file (src_enum, NULL, &temp_error)) != NULL)
{
type = g_file_info_get_attribute_uint32 (src_fileinfo, "standard::type");
name = g_file_info_get_attribute_byte_string (src_fileinfo, "standard::name");
dest_subfile = g_file_get_child (destination, name);
src_subfile = g_file_get_child (src, name);
if (type == G_FILE_TYPE_DIRECTORY)
{
if (!merge_dir (dest_subfile, src_subfile, error))
goto out;
}
else
{
if (!g_file_delete (dest_subfile, NULL, &temp_error))
{
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
g_clear_error (&temp_error);
else
{
g_propagate_error (error, temp_error);
goto out;
}
}
if (!g_file_move (src_subfile, dest_subfile, 0, NULL, NULL, NULL, error))
goto out;
}
g_clear_object (&dest_subfile);
g_clear_object (&src_subfile);
}
if (temp_error)
{
g_propagate_error (error, temp_error);
goto out;
}
}
else if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
g_clear_error (&temp_error);
if (!g_file_move (src, destination, 0, NULL, NULL, NULL, error))
goto out;
}
else
goto out;
ret = TRUE;
out:
g_clear_object (&src_fileinfo);
g_clear_object (&dest_fileinfo);
g_clear_object (&src_enum);
g_clear_object (&dest_subfile);
g_clear_object (&src_subfile);
return ret;
}
static gboolean
compose_branch_on_dir (OstreeRepo *repo,
GFile *destination,
@ -199,7 +102,7 @@ compose_branch_on_dir (OstreeRepo *repo,
goto out;
g_print ("...done\n");
g_print ("Merging over destination...\n");
if (!merge_dir (destination, branchf, error))
if (!ot_gfile_merge_dirs (destination, branchf, NULL, error))
goto out;
if (metadata_builder)