core: Have single "overwrite" flag instead of ignore_exists+force pair

The default is always ignore_exists.  Also port the internals here
to use more GIO code, and stop using *at syscall variants since they're
only useful if used 100%.
This commit is contained in:
Colin Walters 2011-11-18 09:37:25 -05:00
parent 860c3cf502
commit 7276e2df43
2 changed files with 57 additions and 92 deletions

View File

@ -645,7 +645,7 @@ import_gvariant_object (OstreeRepo *self,
if (!ostree_repo_store_object_trusted (self, ot_gfile_get_path_cached (tmp_path), if (!ostree_repo_store_object_trusted (self, ot_gfile_get_path_cached (tmp_path),
g_checksum_get_string (ret_checksum), g_checksum_get_string (ret_checksum),
OSTREE_OBJECT_TYPE_META, OSTREE_OBJECT_TYPE_META,
TRUE, FALSE, &did_exist, error)) FALSE, &did_exist, error))
goto out; goto out;
ret = TRUE; ret = TRUE;
@ -783,88 +783,48 @@ link_object_trusted (OstreeRepo *self,
const char *path, const char *path,
const char *checksum, const char *checksum,
OstreeObjectType objtype, OstreeObjectType objtype,
gboolean ignore_exists, gboolean overwrite,
gboolean force,
gboolean *did_exist, gboolean *did_exist,
GError **error) GError **error)
{ {
char *src_basename = NULL;
char *src_dirname = NULL;
char *dest_basename = NULL;
char *tmp_dest_basename = NULL;
char *dest_dirname = NULL;
DIR *src_dir = NULL;
DIR *dest_dir = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
char *dest_basename = NULL;
char *tmp_dest_path = NULL;
const char *dest_path = NULL; const char *dest_path = NULL;
GFile *dest_file = NULL; GFile *dest_file = NULL;
src_basename = g_path_get_basename (path);
src_dirname = g_path_get_dirname (path);
src_dir = opendir (src_dirname);
if (src_dir == NULL)
{
ot_util_set_error_from_errno (error, errno);
goto out;
}
if (!prepare_dir_for_checksum_get_object_path (self, checksum, objtype, &dest_file, error)) if (!prepare_dir_for_checksum_get_object_path (self, checksum, objtype, &dest_file, error))
goto out; goto out;
dest_path = ot_gfile_get_path_cached (dest_file);
dest_basename = g_path_get_basename (dest_path); *did_exist = g_file_query_exists (dest_file, NULL);
dest_dirname = g_path_get_dirname (dest_path); if (!overwrite && *did_exist)
dest_dir = opendir (dest_dirname);
if (dest_dir == NULL)
{ {
ot_util_set_error_from_errno (error, errno); ;
goto out;
}
if (force)
{
tmp_dest_basename = g_strconcat (dest_basename, ".tmp", NULL);
(void) unlinkat (dirfd (dest_dir), tmp_dest_basename, 0);
} }
else else
tmp_dest_basename = g_strdup (dest_basename);
if (linkat (dirfd (src_dir), src_basename, dirfd (dest_dir), tmp_dest_basename, 0) < 0)
{ {
if (errno != EEXIST || !ignore_exists) dest_path = ot_gfile_get_path_cached (dest_file);
dest_basename = g_path_get_basename (dest_path);
tmp_dest_path = g_strconcat (dest_path, ".tmp", NULL);
(void) unlink (tmp_dest_path);
if (link (path, tmp_dest_path) < 0
|| rename (tmp_dest_path, dest_path) < 0)
{ {
ot_util_set_error_from_errno (error, errno); ot_util_set_error_from_errno (error, errno);
goto out; goto out;
} }
else g_free (tmp_dest_path);
*did_exist = TRUE; tmp_dest_path = NULL;
}
else
*did_exist = FALSE;
if (force)
{
if (renameat (dirfd (dest_dir), tmp_dest_basename,
dirfd (dest_dir), dest_basename) < 0)
{
ot_util_set_error_from_errno (error, errno);
goto out;
}
(void) unlinkat (dirfd (dest_dir), tmp_dest_basename, 0);
} }
ret = TRUE; ret = TRUE;
out: out:
if (src_dir != NULL)
closedir (src_dir);
if (dest_dir != NULL)
closedir (dest_dir);
g_free (src_basename);
g_free (src_dirname);
g_free (dest_basename); g_free (dest_basename);
g_free (tmp_dest_basename); if (tmp_dest_path)
g_free (dest_dirname); (void) unlink (tmp_dest_path);
g_free (tmp_dest_path);
g_clear_object (&dest_file); g_clear_object (&dest_file);
return ret; return ret;
} }
@ -874,50 +834,57 @@ archive_file_trusted (OstreeRepo *self,
const char *path, const char *path,
const char *checksum, const char *checksum,
OstreeObjectType objtype, OstreeObjectType objtype,
gboolean ignore_exists, gboolean overwrite,
gboolean force,
gboolean *did_exist, gboolean *did_exist,
GError **error) GError **error)
{ {
GFile *infile = NULL; GFile *infile = NULL;
GFile *outfile = NULL;
GFileOutputStream *out = NULL; GFileOutputStream *out = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
const char *dest_path = NULL;
GFile *dest_file = NULL; GFile *dest_file = NULL;
char *dest_tmp_path = NULL; GError *temp_error = NULL;
infile = ot_gfile_new_for_path (path); infile = ot_gfile_new_for_path (path);
if (!prepare_dir_for_checksum_get_object_path (self, checksum, objtype, &dest_file, error)) if (!prepare_dir_for_checksum_get_object_path (self, checksum, objtype, &dest_file, error))
goto out; goto out;
dest_path = ot_gfile_get_path_cached (dest_file);
dest_tmp_path = g_strconcat (dest_path, ".tmp", NULL); if (overwrite)
outfile = ot_gfile_new_for_path (dest_tmp_path);
out = g_file_replace (outfile, NULL, FALSE, 0, NULL, error);
if (!out)
goto out;
if (!ostree_pack_object ((GOutputStream*)out, infile, objtype, NULL, error))
goto out;
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
goto out;
if (rename (dest_tmp_path, dest_path) < 0)
{ {
ot_util_set_error_from_errno (error, errno); out = g_file_replace (dest_file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, error);
goto out; if (!out)
goto out;
}
else
{
out = g_file_create (dest_file, 0, NULL, &temp_error);
if (!out)
{
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
{
g_clear_error (&temp_error);
}
else
{
g_propagate_error (error, temp_error);
goto out;
}
}
}
if (out)
{
if (!ostree_pack_object ((GOutputStream*)out, infile, objtype, NULL, error))
goto out;
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
goto out;
} }
ret = TRUE; ret = TRUE;
out: out:
g_clear_object (&dest_file); g_clear_object (&dest_file);
g_free (dest_tmp_path);
g_clear_object (&infile); g_clear_object (&infile);
g_clear_object (&outfile);
g_clear_object (&out); g_clear_object (&out);
return ret; return ret;
} }
@ -927,16 +894,15 @@ ostree_repo_store_object_trusted (OstreeRepo *self,
const char *path, const char *path,
const char *checksum, const char *checksum,
OstreeObjectType objtype, OstreeObjectType objtype,
gboolean ignore_exists, gboolean overwrite,
gboolean force,
gboolean *did_exist, gboolean *did_exist,
GError **error) GError **error)
{ {
OstreeRepoPrivate *priv = GET_PRIVATE (self); OstreeRepoPrivate *priv = GET_PRIVATE (self);
if (priv->archive && objtype == OSTREE_OBJECT_TYPE_FILE) if (priv->archive && objtype == OSTREE_OBJECT_TYPE_FILE)
return archive_file_trusted (self, path, checksum, objtype, ignore_exists, force, did_exist, error); return archive_file_trusted (self, path, checksum, objtype, overwrite, did_exist, error);
else else
return link_object_trusted (self, path, checksum, objtype, ignore_exists, force, did_exist, error); return link_object_trusted (self, path, checksum, objtype, overwrite, did_exist, error);
} }
gboolean gboolean
@ -969,7 +935,7 @@ ostree_repo_store_packfile (OstreeRepo *self,
if (!ostree_repo_store_object_trusted (self, tempfile_path ? tempfile_path->str : path, if (!ostree_repo_store_object_trusted (self, tempfile_path ? tempfile_path->str : path,
expected_checksum, expected_checksum,
objtype, objtype,
TRUE, FALSE, did_exist, error)) FALSE, did_exist, error))
goto out; goto out;
ret = TRUE; ret = TRUE;
@ -1234,7 +1200,7 @@ add_one_file_to_tree_and_import (OstreeRepo *self,
goto out; goto out;
if (!ostree_repo_store_object_trusted (self, abspath, g_checksum_get_string (checksum), if (!ostree_repo_store_object_trusted (self, abspath, g_checksum_get_string (checksum),
OSTREE_OBJECT_TYPE_FILE, TRUE, FALSE, &did_exist, error)) OSTREE_OBJECT_TYPE_FILE, FALSE, &did_exist, error))
goto out; goto out;
g_hash_table_replace (tree->files, g_strdup (basename), g_hash_table_replace (tree->files, g_strdup (basename),

View File

@ -80,8 +80,7 @@ gboolean ostree_repo_store_object_trusted (OstreeRepo *self,
const char *path, const char *path,
const char *checksum, const char *checksum,
OstreeObjectType objtype, OstreeObjectType objtype,
gboolean ignore_exists, gboolean overwrite,
gboolean force,
gboolean *did_exist, gboolean *did_exist,
GError **error); GError **error);