summaryrefslogtreecommitdiff
path: root/src/libostree/ostree-core.c
diff options
context:
space:
mode:
authorJonathan Lebon <jlebon@redhat.com>2017-10-11 14:52:02 +0000
committerAtomic Bot <atomic-devel@projectatomic.io>2017-10-12 12:53:01 +0000
commit077d2718ad5ef58935ecb03f7757302250753c09 (patch)
tree2ee331a61631584f2b000491385446cd6619aca7 /src/libostree/ostree-core.c
parent60b5925c549288171a38d97ad06cb4693a7f8107 (diff)
downloadostree-077d2718ad5ef58935ecb03f7757302250753c09.tar.gz
lib/core: add ostree_checksum_file_at API
This is like `ostree_checksum_file` but fd-relative. This will be used by https://github.com/ostreedev/ostree/pull/1258. AFAICT, we actually didn't have any tests that check the `checksum` CLI. Add a basic one here to test the old code as well as the new code. Closes: #1263 Approved by: cgwalters
Diffstat (limited to 'src/libostree/ostree-core.c')
-rw-r--r--src/libostree/ostree-core.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 733901f7..615f5dec 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -832,6 +832,81 @@ ostree_checksum_file (GFile *f,
return TRUE;
}
+/**
+ * ostree_checksum_file_at:
+ * @dfd: Directory file descriptor
+ * @path: Subpath
+ * @stbuf (allow-none): Optional stat buffer
+ * @objtype: Object type
+ * @flags: Flags
+ * @out_checksum (out) (transfer full): Return location for hex checksum
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Compute the OSTree checksum for a given file. This is an fd-relative version
+ * of ostree_checksum_file() which also takes flags and fills in a caller
+ * allocated buffer.
+ *
+ * Since: 2017.13
+ */
+gboolean
+ostree_checksum_file_at (int dfd,
+ const char *path,
+ struct stat *stbuf,
+ OstreeObjectType objtype,
+ OstreeChecksumFlags flags,
+ char **out_checksum,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (out_checksum != NULL, FALSE);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
+
+ struct stat local_stbuf;
+ if (stbuf == NULL)
+ {
+ stbuf = &local_stbuf;
+ if (!glnx_fstatat (dfd, path, stbuf, AT_SYMLINK_NOFOLLOW, error))
+ return FALSE;
+ }
+
+ g_autoptr(GFileInfo) file_info = _ostree_stbuf_to_gfileinfo (stbuf);
+
+ g_autoptr(GInputStream) in = NULL;
+ if (S_ISREG (stbuf->st_mode))
+ {
+ glnx_autofd int fd = -1;
+ if (!glnx_openat_rdonly (dfd, path, FALSE, &fd, error))
+ return FALSE;
+ in = g_unix_input_stream_new (glnx_steal_fd (&fd), TRUE);
+ }
+ else if (S_ISLNK (stbuf->st_mode))
+ {
+ if (!ot_readlinkat_gfile_info (dfd, path, file_info, cancellable, error))
+ return FALSE;
+ }
+
+ const gboolean ignore_xattrs =
+ ((flags & OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS) > 0);
+
+ g_autoptr(GVariant) xattrs = NULL;
+ if (!ignore_xattrs && objtype == OSTREE_OBJECT_TYPE_FILE)
+ {
+ if (!glnx_dfd_name_get_all_xattrs (dfd, path, &xattrs, cancellable, error))
+ return FALSE;
+ }
+
+ g_autofree guchar *csum_bytes = NULL;
+ if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype,
+ &csum_bytes, cancellable, error))
+ return FALSE;
+
+ *out_checksum = ostree_checksum_from_bytes (csum_bytes);
+ return TRUE;
+}
+
typedef struct {
GFile *f;
OstreeObjectType objtype;