mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-22 17:35:55 +03:00
build: Move sources into src/ again
This is necessary if we want to build when srcdir == builddir, otherwise we blow up because "ostree" is a source directory and a binary.
This commit is contained in:
parent
9dc6ddce08
commit
18f0b537a4
@ -19,17 +19,17 @@
|
||||
|
||||
noinst_LTLIBRARIES += libostree.la
|
||||
|
||||
libostree_la_SOURCES = libostree/ostree.h \
|
||||
libostree/ostree-core.c \
|
||||
libostree/ostree-core.h \
|
||||
libostree/ostree-repo.c \
|
||||
libostree/ostree-repo.h \
|
||||
libostree/ostree-repo-file.c \
|
||||
libostree/ostree-repo-file.h \
|
||||
libostree/ostree-repo-file-enumerator.c \
|
||||
libostree/ostree-repo-file-enumerator.h \
|
||||
libostree/ostree-checkout.c \
|
||||
libostree/ostree-checkout.h \
|
||||
libostree_la_SOURCES = src/libostree/ostree.h \
|
||||
src/libostree/ostree-core.c \
|
||||
src/libostree/ostree-core.h \
|
||||
src/libostree/ostree-repo.c \
|
||||
src/libostree/ostree-repo.h \
|
||||
src/libostree/ostree-repo-file.c \
|
||||
src/libostree/ostree-repo-file.h \
|
||||
src/libostree/ostree-repo-file-enumerator.c \
|
||||
src/libostree/ostree-repo-file-enumerator.h \
|
||||
src/libostree/ostree-checkout.c \
|
||||
src/libostree/ostree-checkout.h \
|
||||
$(NULL)
|
||||
libostree_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libotutil -I$(srcdir)/libostree -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
|
||||
libostree_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
|
||||
libostree_la_LIBADD = libotutil.la $(OT_COREBIN_DEP_LIBS)
|
||||
|
@ -15,7 +15,7 @@
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
bin_SCRIPTS += osbuild/ostree-buildone \
|
||||
osbuild/ostree-buildone-make \
|
||||
osbuild/ostree-buildone-makeinstall-split-artifacts \
|
||||
bin_SCRIPTS += src/osbuild/ostree-buildone \
|
||||
src/osbuild/ostree-buildone-make \
|
||||
src/osbuild/ostree-buildone-makeinstall-split-artifacts \
|
||||
$(NULL)
|
||||
|
@ -19,23 +19,23 @@
|
||||
|
||||
bin_PROGRAMS += ostree
|
||||
|
||||
ostree_SOURCES = ostree/main.c \
|
||||
ostree/ot-builtins.h \
|
||||
ostree/ot-builtin-checkout.c \
|
||||
ostree/ot-builtin-commit.c \
|
||||
ostree/ot-builtin-compose.c \
|
||||
ostree/ot-builtin-diff.c \
|
||||
ostree/ot-builtin-fsck.c \
|
||||
ostree/ot-builtin-init.c \
|
||||
ostree/ot-builtin-log.c \
|
||||
ostree/ot-builtin-run-triggers.c \
|
||||
ostree/ot-builtin-remote.c \
|
||||
ostree/ot-builtin-rev-parse.c \
|
||||
ostree/ot-builtin-show.c \
|
||||
ostree_SOURCES = src/ostree/main.c \
|
||||
src/ostree/ot-builtins.h \
|
||||
src/ostree/ot-builtin-checkout.c \
|
||||
src/ostree/ot-builtin-commit.c \
|
||||
src/ostree/ot-builtin-compose.c \
|
||||
src/ostree/ot-builtin-diff.c \
|
||||
src/ostree/ot-builtin-fsck.c \
|
||||
src/ostree/ot-builtin-init.c \
|
||||
src/ostree/ot-builtin-log.c \
|
||||
src/ostree/ot-builtin-run-triggers.c \
|
||||
src/ostree/ot-builtin-remote.c \
|
||||
src/ostree/ot-builtin-rev-parse.c \
|
||||
src/ostree/ot-builtin-show.c \
|
||||
$(NULL)
|
||||
|
||||
if USE_LIBSOUP_GNOME
|
||||
ostree_SOURCES += ostree/ot-builtin-pull.c
|
||||
ostree_SOURCES += src/ostree/ot-builtin-pull.c
|
||||
endif
|
||||
ostree_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libotutil -I$(srcdir)/libostree -I$(srcdir)/ostree -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
|
||||
ostree_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(srcdir)/src/ostree -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
|
||||
ostree_LDADD = libotutil.la libostree.la $(OT_COREBIN_DEP_LIBS)
|
||||
|
@ -20,17 +20,17 @@
|
||||
noinst_LTLIBRARIES += libotutil.la
|
||||
|
||||
libotutil_la_SOURCES = \
|
||||
libotutil/ot-opt-utils.c \
|
||||
libotutil/ot-opt-utils.h \
|
||||
libotutil/ot-unix-utils.c \
|
||||
libotutil/ot-unix-utils.h \
|
||||
libotutil/ot-variant-utils.c \
|
||||
libotutil/ot-variant-utils.h \
|
||||
libotutil/ot-gio-utils.c \
|
||||
libotutil/ot-gio-utils.h \
|
||||
libotutil/ot-glib-compat.c \
|
||||
libotutil/ot-glib-compat.h \
|
||||
libotutil/otutil.h \
|
||||
src/libotutil/ot-opt-utils.c \
|
||||
src/libotutil/ot-opt-utils.h \
|
||||
src/libotutil/ot-unix-utils.c \
|
||||
src/libotutil/ot-unix-utils.h \
|
||||
src/libotutil/ot-variant-utils.c \
|
||||
src/libotutil/ot-variant-utils.h \
|
||||
src/libotutil/ot-gio-utils.c \
|
||||
src/libotutil/ot-gio-utils.h \
|
||||
src/libotutil/ot-glib-compat.c \
|
||||
src/libotutil/ot-glib-compat.h \
|
||||
src/libotutil/otutil.h \
|
||||
$(NULL)
|
||||
libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(GIO_UNIX_CFLAGS)
|
||||
libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(GIO_UNIX_CFLAGS)
|
||||
libotutil_la_LIBADD = $(GIO_UNIX_LIBS)
|
||||
|
362
src/libostree/ostree-checkout.c
Normal file
362
src/libostree/ostree-checkout.c
Normal file
@ -0,0 +1,362 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ostree.h"
|
||||
#include "otutil.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_REPO,
|
||||
PROP_PATH
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (OstreeCheckout, ostree_checkout, G_TYPE_OBJECT)
|
||||
|
||||
#define GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), OSTREE_TYPE_CHECKOUT, OstreeCheckoutPrivate))
|
||||
|
||||
typedef struct _OstreeCheckoutPrivate OstreeCheckoutPrivate;
|
||||
|
||||
struct _OstreeCheckoutPrivate {
|
||||
OstreeRepo *repo;
|
||||
char *path;
|
||||
};
|
||||
|
||||
static void
|
||||
ostree_checkout_finalize (GObject *object)
|
||||
{
|
||||
OstreeCheckout *self = OSTREE_CHECKOUT (object);
|
||||
OstreeCheckoutPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
g_free (priv->path);
|
||||
g_clear_object (&priv->repo);
|
||||
|
||||
G_OBJECT_CLASS (ostree_checkout_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_checkout_set_property(GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
OstreeCheckout *self = OSTREE_CHECKOUT (object);
|
||||
OstreeCheckoutPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
priv->path = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_REPO:
|
||||
priv->repo = g_value_dup_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_checkout_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
OstreeCheckout *self = OSTREE_CHECKOUT (object);
|
||||
OstreeCheckoutPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
g_value_set_string (value, priv->path);
|
||||
break;
|
||||
case PROP_REPO:
|
||||
g_value_set_object (value, priv->repo);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GObject *
|
||||
ostree_checkout_constructor (GType gtype,
|
||||
guint n_properties,
|
||||
GObjectConstructParam *properties)
|
||||
{
|
||||
GObject *object;
|
||||
GObjectClass *parent_class;
|
||||
OstreeCheckoutPrivate *priv;
|
||||
|
||||
parent_class = G_OBJECT_CLASS (ostree_checkout_parent_class);
|
||||
object = parent_class->constructor (gtype, n_properties, properties);
|
||||
|
||||
priv = GET_PRIVATE (object);
|
||||
|
||||
g_assert (priv->path != NULL);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_checkout_class_init (OstreeCheckoutClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (OstreeCheckoutPrivate));
|
||||
|
||||
object_class->constructor = ostree_checkout_constructor;
|
||||
object_class->get_property = ostree_checkout_get_property;
|
||||
object_class->set_property = ostree_checkout_set_property;
|
||||
object_class->finalize = ostree_checkout_finalize;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PATH,
|
||||
g_param_spec_string ("path", "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_REPO,
|
||||
g_param_spec_object ("repo", "", "",
|
||||
OSTREE_TYPE_REPO,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_checkout_init (OstreeCheckout *self)
|
||||
{
|
||||
}
|
||||
|
||||
OstreeCheckout*
|
||||
ostree_checkout_new (OstreeRepo *repo,
|
||||
const char *path)
|
||||
{
|
||||
return g_object_new (OSTREE_TYPE_CHECKOUT, "repo", repo, "path", path, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
executable_exists_in_checkout (const char *path,
|
||||
const char *executable)
|
||||
{
|
||||
int i;
|
||||
const char *subdirs[] = {"bin", "sbin", "usr/bin", "usr/sbin"};
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (subdirs); i++)
|
||||
{
|
||||
char *possible_path = g_build_filename (path, subdirs[i], executable, NULL);
|
||||
gboolean exists;
|
||||
|
||||
exists = g_file_test (possible_path, G_FILE_TEST_EXISTS);
|
||||
g_free (possible_path);
|
||||
|
||||
if (exists)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
run_trigger (OstreeCheckout *self,
|
||||
GFile *trigger,
|
||||
gboolean requires_chroot,
|
||||
GError **error)
|
||||
{
|
||||
OstreeCheckoutPrivate *priv = GET_PRIVATE (self);
|
||||
gboolean ret = FALSE;
|
||||
char *path = NULL;
|
||||
char *temp_path = NULL;
|
||||
char *rel_temp_path = NULL;
|
||||
GFile *temp_copy = NULL;
|
||||
char *basename = NULL;
|
||||
GPtrArray *args = NULL;
|
||||
int estatus;
|
||||
|
||||
path = g_file_get_path (trigger);
|
||||
basename = g_path_get_basename (path);
|
||||
|
||||
args = g_ptr_array_new ();
|
||||
|
||||
if (requires_chroot)
|
||||
{
|
||||
temp_path = g_build_filename (priv->path, basename, NULL);
|
||||
rel_temp_path = g_strconcat ("./", basename, NULL);
|
||||
temp_copy = ot_util_new_file_for_path (temp_path);
|
||||
|
||||
if (!g_file_copy (trigger, temp_copy, 0, NULL, NULL, NULL, error))
|
||||
goto out;
|
||||
|
||||
g_ptr_array_add (args, "chroot");
|
||||
g_ptr_array_add (args, ".");
|
||||
g_ptr_array_add (args, rel_temp_path);
|
||||
g_ptr_array_add (args, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ptr_array_add (args, path);
|
||||
g_ptr_array_add (args, NULL);
|
||||
}
|
||||
|
||||
g_print ("Running trigger: %s\n", path);
|
||||
if (!g_spawn_sync (priv->path,
|
||||
(char**)args->pdata,
|
||||
NULL,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL, NULL, NULL,
|
||||
&estatus,
|
||||
error))
|
||||
{
|
||||
g_prefix_error (error, "Failed to run trigger %s: ", basename);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (requires_chroot && temp_path)
|
||||
(void)unlink (temp_path);
|
||||
|
||||
g_free (path);
|
||||
g_free (basename);
|
||||
g_free (temp_path);
|
||||
g_free (rel_temp_path);
|
||||
g_clear_object (&temp_copy);
|
||||
if (args)
|
||||
g_ptr_array_free (args, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_trigger (OstreeCheckout *self,
|
||||
GFile *trigger,
|
||||
GError **error)
|
||||
{
|
||||
OstreeCheckoutPrivate *priv = GET_PRIVATE (self);
|
||||
gboolean ret = FALSE;
|
||||
GInputStream *instream = NULL;
|
||||
GDataInputStream *datain = NULL;
|
||||
GError *temp_error = NULL;
|
||||
char *line;
|
||||
gsize len;
|
||||
gboolean requires_chroot = TRUE;
|
||||
gboolean matches = FALSE;
|
||||
|
||||
instream = (GInputStream*)g_file_read (trigger, NULL, error);
|
||||
if (!instream)
|
||||
goto out;
|
||||
datain = g_data_input_stream_new (instream);
|
||||
|
||||
while ((line = g_data_input_stream_read_line (datain, &len, NULL, &temp_error)) != NULL)
|
||||
{
|
||||
if (g_str_has_prefix (line, "# IfExecutable: "))
|
||||
{
|
||||
char *executable = g_strdup (line + strlen ("# IfExecutable: "));
|
||||
g_strchomp (executable);
|
||||
matches = executable_exists_in_checkout (priv->path, executable);
|
||||
g_free (executable);
|
||||
}
|
||||
|
||||
g_free (line);
|
||||
}
|
||||
if (line == NULL && temp_error != NULL)
|
||||
{
|
||||
g_propagate_error (error, temp_error);
|
||||
goto out;
|
||||
}
|
||||
if (matches)
|
||||
{
|
||||
if (!run_trigger (self, trigger, requires_chroot, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
g_clear_object (&instream);
|
||||
g_clear_object (&datain);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_checkout_run_triggers (OstreeCheckout *self,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GError *temp_error = NULL;
|
||||
char *triggerdir_path = NULL;
|
||||
GFile *triggerdir = NULL;
|
||||
GFileInfo *file_info = NULL;
|
||||
GFileEnumerator *enumerator = NULL;
|
||||
|
||||
triggerdir_path = g_build_filename (LIBEXECDIR, "ostree", "triggers.d", NULL);
|
||||
triggerdir = ot_util_new_file_for_path (triggerdir_path);
|
||||
|
||||
enumerator = g_file_enumerate_children (triggerdir, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
NULL,
|
||||
error);
|
||||
if (!enumerator)
|
||||
goto out;
|
||||
|
||||
while ((file_info = g_file_enumerator_next_file (enumerator, NULL, &temp_error)) != NULL)
|
||||
{
|
||||
const char *name;
|
||||
guint32 type;
|
||||
char *child_path = NULL;
|
||||
GFile *child = NULL;
|
||||
gboolean success;
|
||||
|
||||
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_REGULAR && g_str_has_suffix (name, ".trigger"))
|
||||
{
|
||||
child_path = g_build_filename (triggerdir_path, name, NULL);
|
||||
child = ot_util_new_file_for_path (child_path);
|
||||
|
||||
success = check_trigger (self, child, error);
|
||||
}
|
||||
else
|
||||
success = TRUE;
|
||||
|
||||
g_object_unref (file_info);
|
||||
g_free (child_path);
|
||||
g_clear_object (&child);
|
||||
if (!success)
|
||||
goto out;
|
||||
}
|
||||
if (file_info == NULL && temp_error != NULL)
|
||||
{
|
||||
g_propagate_error (error, temp_error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
g_free (triggerdir_path);
|
||||
g_clear_object (&triggerdir);
|
||||
g_clear_object (&enumerator);
|
||||
return ret;
|
||||
}
|
60
src/libostree/ostree-checkout.h
Normal file
60
src/libostree/ostree-checkout.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#ifndef _OSTREE_CHECKOUT
|
||||
#define _OSTREE_CHECKOUT
|
||||
|
||||
#include <ostree-repo.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_TYPE_CHECKOUT ostree_checkout_get_type()
|
||||
#define OSTREE_CHECKOUT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_CHECKOUT, OstreeCheckout))
|
||||
#define OSTREE_CHECKOUT_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), OSTREE_TYPE_CHECKOUT, OstreeCheckoutClass))
|
||||
#define OSTREE_IS_CHECKOUT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_CHECKOUT))
|
||||
#define OSTREE_IS_CHECKOUT_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), OSTREE_TYPE_CHECKOUT))
|
||||
#define OSTREE_CHECKOUT_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), OSTREE_TYPE_CHECKOUT, OstreeCheckoutClass))
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
} OstreeCheckout;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
} OstreeCheckoutClass;
|
||||
|
||||
GType ostree_checkout_get_type (void);
|
||||
|
||||
OstreeCheckout* ostree_checkout_new (OstreeRepo *repo,
|
||||
const char *path);
|
||||
|
||||
gboolean ostree_checkout_run_triggers (OstreeCheckout *checkout,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _OSTREE_CHECKOUT */
|
856
src/libostree/ostree-core.c
Normal file
856
src/libostree/ostree-core.c
Normal file
@ -0,0 +1,856 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ostree.h"
|
||||
#include "otutil.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <attr/xattr.h>
|
||||
|
||||
gboolean
|
||||
ostree_validate_checksum_string (const char *sha256,
|
||||
GError **error)
|
||||
{
|
||||
if (strlen (sha256) != 64)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid rev '%s'", sha256);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ostree_checksum_update_stat (GChecksum *checksum, guint32 uid, guint32 gid, guint32 mode)
|
||||
{
|
||||
guint32 perms = (mode & ~S_IFMT);
|
||||
g_checksum_update (checksum, (guint8*) &uid, 4);
|
||||
g_checksum_update (checksum, (guint8*) &gid, 4);
|
||||
g_checksum_update (checksum, (guint8*) &perms, 4);
|
||||
}
|
||||
|
||||
static char *
|
||||
canonicalize_xattrs (char *xattr_string, size_t len)
|
||||
{
|
||||
char *p;
|
||||
GSList *xattrs = NULL;
|
||||
GSList *iter;
|
||||
GString *result;
|
||||
|
||||
result = g_string_new (0);
|
||||
|
||||
p = xattr_string;
|
||||
while (p < xattr_string+len)
|
||||
{
|
||||
xattrs = g_slist_prepend (xattrs, p);
|
||||
p += strlen (p) + 1;
|
||||
}
|
||||
|
||||
xattrs = g_slist_sort (xattrs, (GCompareFunc) strcmp);
|
||||
for (iter = xattrs; iter; iter = iter->next)
|
||||
g_string_append (result, iter->data);
|
||||
|
||||
g_slist_free (xattrs);
|
||||
return g_string_free (result, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
read_xattr_name_array (const char *path,
|
||||
const char *xattrs,
|
||||
size_t len,
|
||||
GVariantBuilder *builder,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
const char *p;
|
||||
|
||||
p = xattrs;
|
||||
while (p < xattrs+len)
|
||||
{
|
||||
ssize_t bytes_read;
|
||||
char *buf;
|
||||
|
||||
bytes_read = lgetxattr (path, p, NULL, 0);
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
if (bytes_read == 0)
|
||||
continue;
|
||||
|
||||
buf = g_malloc (bytes_read);
|
||||
if (lgetxattr (path, p, buf, bytes_read) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
g_free (buf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_variant_builder_add (builder, "(@ay@ay)",
|
||||
g_variant_new_bytestring (p),
|
||||
g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
|
||||
buf, bytes_read, FALSE, g_free, buf));
|
||||
|
||||
p = p + strlen (p) + 1;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
ostree_get_xattrs_for_path (const char *path,
|
||||
GError **error)
|
||||
{
|
||||
GVariant *ret = NULL;
|
||||
GVariantBuilder builder;
|
||||
char *xattr_names = NULL;
|
||||
char *xattr_names_canonical = NULL;
|
||||
ssize_t bytes_read;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
|
||||
|
||||
bytes_read = llistxattr (path, NULL, 0);
|
||||
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
if (errno != ENOTSUP)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (bytes_read > 0)
|
||||
{
|
||||
xattr_names = g_malloc (bytes_read);
|
||||
if (llistxattr (path, xattr_names, bytes_read) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
xattr_names_canonical = canonicalize_xattrs (xattr_names, bytes_read);
|
||||
|
||||
if (!read_xattr_name_array (path, xattr_names_canonical, bytes_read, &builder, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = g_variant_builder_end (&builder);
|
||||
g_variant_ref_sink (ret);
|
||||
out:
|
||||
if (!ret)
|
||||
g_variant_builder_clear (&builder);
|
||||
g_free (xattr_names);
|
||||
g_free (xattr_names_canonical);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_stat_and_checksum_file (int dir_fd, const char *path,
|
||||
OstreeObjectType objtype,
|
||||
GChecksum **out_checksum,
|
||||
struct stat *out_stbuf,
|
||||
GError **error)
|
||||
{
|
||||
GChecksum *content_sha256 = NULL;
|
||||
GChecksum *content_and_meta_sha256 = NULL;
|
||||
char *stat_string = NULL;
|
||||
ssize_t bytes_read;
|
||||
GVariant *xattrs = NULL;
|
||||
int fd = -1;
|
||||
DIR *temp_dir = NULL;
|
||||
char *basename = NULL;
|
||||
gboolean ret = FALSE;
|
||||
char *symlink_target = NULL;
|
||||
char *device_id = NULL;
|
||||
struct stat stbuf;
|
||||
|
||||
basename = g_path_get_basename (path);
|
||||
|
||||
if (dir_fd == -1)
|
||||
{
|
||||
char *dirname = g_path_get_dirname (path);
|
||||
temp_dir = opendir (dirname);
|
||||
if (temp_dir == NULL)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
g_free (dirname);
|
||||
}
|
||||
g_free (dirname);
|
||||
dir_fd = dirfd (temp_dir);
|
||||
}
|
||||
|
||||
if (fstatat (dir_fd, basename, &stbuf, AT_SYMLINK_NOFOLLOW) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (S_ISREG(stbuf.st_mode))
|
||||
{
|
||||
fd = ot_util_open_file_read_at (dir_fd, basename, error);
|
||||
if (fd < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
xattrs = ostree_get_xattrs_for_path (path, error);
|
||||
if (!xattrs)
|
||||
goto out;
|
||||
}
|
||||
|
||||
content_sha256 = g_checksum_new (G_CHECKSUM_SHA256);
|
||||
|
||||
if (S_ISREG(stbuf.st_mode))
|
||||
{
|
||||
guint8 buf[8192];
|
||||
|
||||
while ((bytes_read = read (fd, buf, sizeof (buf))) > 0)
|
||||
g_checksum_update (content_sha256, buf, bytes_read);
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (S_ISLNK(stbuf.st_mode))
|
||||
{
|
||||
symlink_target = g_malloc (PATH_MAX);
|
||||
|
||||
g_assert (objtype == OSTREE_OBJECT_TYPE_FILE);
|
||||
|
||||
bytes_read = readlinkat (dir_fd, basename, symlink_target, PATH_MAX);
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
g_checksum_update (content_sha256, (guint8*)symlink_target, bytes_read);
|
||||
}
|
||||
else if (S_ISCHR(stbuf.st_mode) || S_ISBLK(stbuf.st_mode))
|
||||
{
|
||||
g_assert (objtype == OSTREE_OBJECT_TYPE_FILE);
|
||||
device_id = g_strdup_printf ("%u", (guint)stbuf.st_rdev);
|
||||
g_checksum_update (content_sha256, (guint8*)device_id, strlen (device_id));
|
||||
}
|
||||
else if (S_ISFIFO(stbuf.st_mode))
|
||||
{
|
||||
g_assert (objtype == OSTREE_OBJECT_TYPE_FILE);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Unsupported file '%s' (must be regular, symbolic link, fifo, or character/block device)",
|
||||
path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
content_and_meta_sha256 = g_checksum_copy (content_sha256);
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
ostree_checksum_update_stat (content_and_meta_sha256, stbuf.st_uid,
|
||||
stbuf.st_gid, stbuf.st_mode);
|
||||
g_checksum_update (content_and_meta_sha256, (guint8*)g_variant_get_data (xattrs), g_variant_get_size (xattrs));
|
||||
}
|
||||
|
||||
*out_stbuf = stbuf;
|
||||
*out_checksum = content_and_meta_sha256;
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (fd >= 0)
|
||||
close (fd);
|
||||
if (temp_dir != NULL)
|
||||
closedir (temp_dir);
|
||||
g_free (symlink_target);
|
||||
g_free (basename);
|
||||
g_free (stat_string);
|
||||
if (xattrs)
|
||||
g_variant_unref (xattrs);
|
||||
if (content_sha256)
|
||||
g_checksum_free (content_sha256);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_set_xattrs (const char *path, GVariant *xattrs, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int i, n;
|
||||
|
||||
n = g_variant_n_children (xattrs);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
const guint8* name;
|
||||
GVariant *value;
|
||||
const guint8* value_data;
|
||||
gsize value_len;
|
||||
gboolean loop_err;
|
||||
|
||||
g_variant_get_child (xattrs, i, "(^&ay@ay)",
|
||||
&name, &value);
|
||||
value_data = g_variant_get_fixed_array (value, &value_len, 1);
|
||||
|
||||
loop_err = lsetxattr (path, (char*)name, (char*)value_data, value_len, XATTR_REPLACE) < 0;
|
||||
|
||||
g_variant_unref (value);
|
||||
if (loop_err)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_parse_metadata_file (const char *path,
|
||||
OstreeSerializedVariantType *out_type,
|
||||
GVariant **out_variant,
|
||||
GError **error)
|
||||
{
|
||||
GFile *pathf = NULL;
|
||||
gboolean ret = FALSE;
|
||||
GVariant *ret_variant = NULL;
|
||||
GVariant *container = NULL;
|
||||
guint32 ret_type;
|
||||
|
||||
pathf = ot_util_new_file_for_path (path);
|
||||
if (!ot_util_variant_map (pathf, G_VARIANT_TYPE (OSTREE_SERIALIZED_VARIANT_FORMAT),
|
||||
&container, error))
|
||||
goto out;
|
||||
|
||||
g_variant_get (container, "(uv)",
|
||||
&ret_type, &ret_variant);
|
||||
ret_type = GUINT32_FROM_BE (ret_type);
|
||||
if (ret_type <= 0 || ret_type > OSTREE_SERIALIZED_VARIANT_LAST)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Corrupted metadata object '%s'; invalid type %d", path, ret_type);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
*out_type = ret_type;
|
||||
*out_variant = ot_util_variant_take_ref (ret_variant);
|
||||
ret_variant = NULL;
|
||||
out:
|
||||
if (ret_variant)
|
||||
g_variant_unref (ret_variant);
|
||||
if (container != NULL)
|
||||
g_variant_unref (container);
|
||||
g_clear_object (&pathf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
ostree_get_relative_object_path (const char *checksum,
|
||||
OstreeObjectType type,
|
||||
gboolean archive)
|
||||
{
|
||||
GString *path;
|
||||
const char *type_string;
|
||||
|
||||
g_assert (strlen (checksum) == 64);
|
||||
|
||||
path = g_string_new ("objects/");
|
||||
|
||||
g_string_append_len (path, checksum, 2);
|
||||
g_string_append_c (path, '/');
|
||||
g_string_append (path, checksum + 2);
|
||||
switch (type)
|
||||
{
|
||||
case OSTREE_OBJECT_TYPE_FILE:
|
||||
if (archive)
|
||||
type_string = ".packfile";
|
||||
else
|
||||
type_string = ".file";
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_META:
|
||||
type_string = ".meta";
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
g_string_append (path, type_string);
|
||||
return g_string_free (path, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_pack_object (GOutputStream *output,
|
||||
GFile *file,
|
||||
OstreeObjectType objtype,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
char *path = NULL;
|
||||
GFileInfo *finfo = NULL;
|
||||
GFileInputStream *instream = NULL;
|
||||
gboolean pack_builder_initialized = FALSE;
|
||||
GVariantBuilder pack_builder;
|
||||
GVariant *pack_variant = NULL;
|
||||
GVariant *xattrs = NULL;
|
||||
gsize bytes_written;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
||||
finfo = g_file_query_info (file, "standard::type,standard::size,standard::is-symlink,standard::symlink-target,unix::*",
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error);
|
||||
if (!finfo)
|
||||
goto out;
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_META)
|
||||
{
|
||||
guint64 object_size_be = GUINT64_TO_BE ((guint64)g_file_info_get_size (finfo));
|
||||
if (!g_output_stream_write_all (output, &object_size_be, 8, &bytes_written, cancellable, error))
|
||||
goto out;
|
||||
|
||||
instream = g_file_read (file, NULL, error);
|
||||
if (!instream)
|
||||
goto out;
|
||||
|
||||
if (g_output_stream_splice (output, (GInputStream*)instream, 0, cancellable, error) < 0)
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
guint32 uid, gid, mode;
|
||||
guint32 device = 0;
|
||||
guint32 metadata_size_be;
|
||||
const char *target = NULL;
|
||||
guint64 object_size;
|
||||
|
||||
uid = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_UID);
|
||||
gid = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_GID);
|
||||
mode = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_MODE);
|
||||
|
||||
g_variant_builder_init (&pack_builder, G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT));
|
||||
pack_builder_initialized = TRUE;
|
||||
g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (0));
|
||||
g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (uid));
|
||||
g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (gid));
|
||||
g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (mode));
|
||||
|
||||
xattrs = ostree_get_xattrs_for_path (path, error);
|
||||
if (!xattrs)
|
||||
goto out;
|
||||
g_variant_builder_add (&pack_builder, "@a(ayay)", xattrs);
|
||||
|
||||
if (S_ISREG (mode))
|
||||
{
|
||||
object_size = (guint64)g_file_info_get_size (finfo);
|
||||
}
|
||||
else if (S_ISLNK (mode))
|
||||
{
|
||||
target = g_file_info_get_attribute_byte_string (finfo, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET);
|
||||
object_size = strlen (target);
|
||||
}
|
||||
else if (S_ISBLK (mode) || S_ISCHR (mode))
|
||||
{
|
||||
device = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_DEVICE);
|
||||
object_size = 4;
|
||||
}
|
||||
else if (S_ISFIFO (mode))
|
||||
{
|
||||
object_size = 0;
|
||||
}
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
g_variant_builder_add (&pack_builder, "t", GUINT64_TO_BE (object_size));
|
||||
pack_variant = g_variant_builder_end (&pack_builder);
|
||||
pack_builder_initialized = FALSE;
|
||||
|
||||
metadata_size_be = GUINT32_TO_BE (g_variant_get_size (pack_variant));
|
||||
|
||||
if (!g_output_stream_write_all (output, &metadata_size_be, 4,
|
||||
&bytes_written, cancellable, error))
|
||||
goto out;
|
||||
g_assert (bytes_written == 4);
|
||||
|
||||
if (!g_output_stream_write_all (output, g_variant_get_data (pack_variant), g_variant_get_size (pack_variant),
|
||||
&bytes_written, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (S_ISREG (mode))
|
||||
{
|
||||
instream = g_file_read (file, NULL, error);
|
||||
if (!instream)
|
||||
goto out;
|
||||
bytes_written = g_output_stream_splice (output, (GInputStream*)instream, 0, cancellable, error);
|
||||
if (bytes_written < 0)
|
||||
goto out;
|
||||
if (bytes_written != object_size)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"File size changed unexpectedly");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (S_ISLNK (mode))
|
||||
{
|
||||
if (!g_output_stream_write_all (output, target, object_size,
|
||||
&bytes_written, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else if (S_ISBLK (mode) || S_ISCHR (mode))
|
||||
{
|
||||
guint32 device_be = GUINT32_TO_BE (device);
|
||||
g_assert (object_size == 4);
|
||||
if (!g_output_stream_write_all (output, &device_be, object_size,
|
||||
&bytes_written, cancellable, error))
|
||||
goto out;
|
||||
g_assert (bytes_written == 4);
|
||||
}
|
||||
else if (S_ISFIFO (mode))
|
||||
{
|
||||
}
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
g_free (path);
|
||||
g_clear_object (&finfo);
|
||||
g_clear_object (&instream);
|
||||
if (xattrs)
|
||||
g_variant_unref (xattrs);
|
||||
if (pack_builder_initialized)
|
||||
g_variant_builder_clear (&pack_builder);
|
||||
if (pack_variant)
|
||||
g_variant_unref (pack_variant);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
splice_and_checksum (GOutputStream *out,
|
||||
GInputStream *in,
|
||||
GChecksum *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (checksum != NULL)
|
||||
{
|
||||
gsize bytes_read, bytes_written;
|
||||
char buf[4096];
|
||||
do
|
||||
{
|
||||
if (!g_input_stream_read_all (in, buf, sizeof(buf), &bytes_read, cancellable, error))
|
||||
goto out;
|
||||
if (checksum)
|
||||
g_checksum_update (checksum, (guint8*)buf, bytes_read);
|
||||
if (!g_output_stream_write_all (out, buf, bytes_read, &bytes_written, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
while (bytes_read > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_output_stream_splice (out, in, 0, cancellable, error) < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
unpack_meta (const char *path,
|
||||
const char *dest_path,
|
||||
GChecksum **out_checksum,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GFile *file = NULL;
|
||||
GFile *dest_file = NULL;
|
||||
GFileInputStream *in = NULL;
|
||||
GChecksum *ret_checksum = NULL;
|
||||
GFileOutputStream *out = NULL;
|
||||
|
||||
file = ot_util_new_file_for_path (path);
|
||||
dest_file = ot_util_new_file_for_path (dest_path);
|
||||
|
||||
if (out_checksum)
|
||||
ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
|
||||
|
||||
in = g_file_read (file, NULL, error);
|
||||
if (!in)
|
||||
goto out;
|
||||
|
||||
out = g_file_replace (dest_file, NULL, FALSE, 0, NULL, error);
|
||||
if (!out)
|
||||
goto out;
|
||||
|
||||
if (!splice_and_checksum ((GOutputStream*)out, (GInputStream*)in, ret_checksum, NULL, error))
|
||||
goto out;
|
||||
|
||||
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
if (out_checksum)
|
||||
*out_checksum = ret_checksum;
|
||||
ret_checksum = NULL;
|
||||
out:
|
||||
if (!ret)
|
||||
(void) unlink (dest_path);
|
||||
if (ret_checksum)
|
||||
g_checksum_free (ret_checksum);
|
||||
g_clear_object (&file);
|
||||
g_clear_object (&dest_file);
|
||||
g_clear_object (&in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_parse_packed_file (GFile *file,
|
||||
GVariant **out_metadata,
|
||||
GInputStream **out_content,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
char *metadata_buf = NULL;
|
||||
GVariant *ret_metadata = NULL;
|
||||
GFileInputStream *in = NULL;
|
||||
guint32 metadata_len;
|
||||
gsize bytes_read;
|
||||
|
||||
in = g_file_read (file, NULL, error);
|
||||
if (!in)
|
||||
goto out;
|
||||
|
||||
if (!g_input_stream_read_all ((GInputStream*)in, &metadata_len, 4, &bytes_read, NULL, error))
|
||||
goto out;
|
||||
if (bytes_read != 4)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Corrupted packfile; too short while reading metadata length");
|
||||
goto out;
|
||||
}
|
||||
|
||||
metadata_len = GUINT32_FROM_BE (metadata_len);
|
||||
if (metadata_len > OSTREE_MAX_METADATA_SIZE)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Corrupted packfile; metadata length %u is larger than maximum %u",
|
||||
metadata_len, OSTREE_MAX_METADATA_SIZE);
|
||||
goto out;
|
||||
}
|
||||
metadata_buf = g_malloc (metadata_len);
|
||||
|
||||
if (!g_input_stream_read_all ((GInputStream*)in, metadata_buf, metadata_len, &bytes_read, NULL, error))
|
||||
goto out;
|
||||
if (bytes_read != metadata_len)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Corrupted packfile; too short while reading metadata");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_metadata = g_variant_new_from_data (G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT),
|
||||
metadata_buf, metadata_len, FALSE,
|
||||
(GDestroyNotify)g_free,
|
||||
metadata_buf);
|
||||
metadata_buf = NULL;
|
||||
|
||||
ret = TRUE;
|
||||
*out_metadata = ret_metadata;
|
||||
ret_metadata = NULL;
|
||||
*out_content = (GInputStream*)in;
|
||||
in = NULL;
|
||||
out:
|
||||
g_clear_object (&in);
|
||||
if (ret_metadata)
|
||||
g_variant_unref (ret_metadata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
unpack_file (const char *path,
|
||||
const char *dest_path,
|
||||
GChecksum **out_checksum,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GFile *file = NULL;
|
||||
GFile *dest_file = NULL;
|
||||
GVariant *metadata = NULL;
|
||||
GVariant *xattrs = NULL;
|
||||
GInputStream *in = NULL;
|
||||
GFileOutputStream *out = NULL;
|
||||
GChecksum *ret_checksum = NULL;
|
||||
guint32 version, uid, gid, mode;
|
||||
guint64 content_len;
|
||||
gsize bytes_read;
|
||||
|
||||
file = ot_util_new_file_for_path (path);
|
||||
|
||||
if (!ostree_parse_packed_file (file, &metadata, &in, NULL, error))
|
||||
goto out;
|
||||
|
||||
g_variant_get (metadata, "(uuuu@a(ayay)t)",
|
||||
&version, &uid, &gid, &mode,
|
||||
&xattrs, &content_len);
|
||||
uid = GUINT32_FROM_BE (uid);
|
||||
gid = GUINT32_FROM_BE (gid);
|
||||
mode = GUINT32_FROM_BE (mode);
|
||||
content_len = GUINT64_FROM_BE (content_len);
|
||||
|
||||
dest_file = ot_util_new_file_for_path (dest_path);
|
||||
|
||||
if (out_checksum)
|
||||
ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
|
||||
|
||||
if (S_ISREG (mode))
|
||||
{
|
||||
out = g_file_replace (dest_file, NULL, FALSE, 0, NULL, error);
|
||||
if (!out)
|
||||
goto out;
|
||||
|
||||
if (!splice_and_checksum ((GOutputStream*)out, in, ret_checksum, NULL, error))
|
||||
goto out;
|
||||
|
||||
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
|
||||
goto out;
|
||||
}
|
||||
else if (S_ISLNK (mode))
|
||||
{
|
||||
char target[PATH_MAX+1];
|
||||
|
||||
if (!g_input_stream_read_all (in, target, sizeof(target)-1, &bytes_read, NULL, error))
|
||||
goto out;
|
||||
target[bytes_read] = '\0';
|
||||
if (ret_checksum)
|
||||
g_checksum_update (ret_checksum, (guint8*)target, bytes_read);
|
||||
if (symlink (target, dest_path) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (S_ISCHR (mode) || S_ISBLK (mode))
|
||||
{
|
||||
guint32 dev;
|
||||
|
||||
if (!g_input_stream_read_all (in, &dev, 4, &bytes_read, NULL, error))
|
||||
goto out;
|
||||
if (bytes_read != 4)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Corrupted packfile; too short while reading device id");
|
||||
goto out;
|
||||
}
|
||||
dev = GUINT32_FROM_BE (dev);
|
||||
if (ret_checksum)
|
||||
g_checksum_update (ret_checksum, (guint8*)&dev, 4);
|
||||
if (mknod (dest_path, mode, dev) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (S_ISFIFO (mode))
|
||||
{
|
||||
if (mkfifo (dest_path, mode) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Corrupted packfile; invalid mode %u", mode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!S_ISLNK (mode))
|
||||
{
|
||||
if (chmod (dest_path, mode) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ostree_set_xattrs (dest_path, xattrs, NULL, error))
|
||||
goto out;
|
||||
|
||||
if (ret_checksum)
|
||||
{
|
||||
ostree_checksum_update_stat (ret_checksum, uid, gid, mode);
|
||||
g_checksum_update (ret_checksum, (guint8*)g_variant_get_data (xattrs), g_variant_get_size (xattrs));
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
if (out_checksum)
|
||||
*out_checksum = ret_checksum;
|
||||
ret_checksum = NULL;
|
||||
out:
|
||||
if (!ret)
|
||||
(void) unlink (dest_path);
|
||||
if (ret_checksum)
|
||||
g_checksum_free (ret_checksum);
|
||||
g_clear_object (&file);
|
||||
g_clear_object (&dest_file);
|
||||
g_clear_object (&in);
|
||||
g_clear_object (&out);
|
||||
if (metadata)
|
||||
g_variant_unref (metadata);
|
||||
if (xattrs)
|
||||
g_variant_unref (xattrs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_unpack_object (const char *path,
|
||||
OstreeObjectType objtype,
|
||||
const char *dest_path,
|
||||
GChecksum **out_checksum,
|
||||
GError **error)
|
||||
{
|
||||
if (objtype == OSTREE_OBJECT_TYPE_META)
|
||||
return unpack_meta (path, dest_path, out_checksum, error);
|
||||
else
|
||||
return unpack_file (path, dest_path, out_checksum, error);
|
||||
}
|
||||
|
||||
|
||||
|
155
src/libostree/ostree-core.h
Normal file
155
src/libostree/ostree-core.h
Normal file
@ -0,0 +1,155 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#ifndef _OSTREE_CORE
|
||||
#define _OSTREE_CORE
|
||||
|
||||
#include <otutil.h>
|
||||
|
||||
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 {
|
||||
OSTREE_OBJECT_TYPE_FILE = 1,
|
||||
OSTREE_OBJECT_TYPE_META = 2,
|
||||
} OstreeObjectType;
|
||||
|
||||
typedef enum {
|
||||
OSTREE_SERIALIZED_TREE_VARIANT = 1,
|
||||
OSTREE_SERIALIZED_COMMIT_VARIANT = 2,
|
||||
OSTREE_SERIALIZED_DIRMETA_VARIANT = 3,
|
||||
OSTREE_SERIALIZED_XATTR_VARIANT = 4
|
||||
} OstreeSerializedVariantType;
|
||||
#define OSTREE_SERIALIZED_VARIANT_LAST 4
|
||||
|
||||
#define OSTREE_SERIALIZED_VARIANT_FORMAT "(uv)"
|
||||
|
||||
/*
|
||||
* xattr objects:
|
||||
* a(ayay) - array of (name, value) pairs, both binary data, though name is a bytestring
|
||||
*/
|
||||
#define OSTREE_XATTR_GVARIANT_FORMAT "a(ayay)"
|
||||
|
||||
#define OSTREE_DIR_META_VERSION 0
|
||||
/*
|
||||
* dirmeta objects:
|
||||
* u - Version
|
||||
* u - uid
|
||||
* u - gid
|
||||
* u - mode
|
||||
* a(ayay) - xattrs
|
||||
*/
|
||||
#define OSTREE_DIRMETA_GVARIANT_FORMAT "(uuuua(ayay))"
|
||||
|
||||
#define OSTREE_TREE_VERSION 0
|
||||
/*
|
||||
* Tree objects:
|
||||
* u - Version
|
||||
* a{sv} - Metadata
|
||||
* a(ss) - array of (filename, checksum) for files
|
||||
* a(sss) - array of (dirname, tree_checksum, meta_checksum) for directories
|
||||
*/
|
||||
#define OSTREE_TREE_GVARIANT_FORMAT "(ua{sv}a(ss)a(sss)"
|
||||
|
||||
#define OSTREE_COMMIT_VERSION 0
|
||||
/*
|
||||
* Commit objects:
|
||||
* u - Version
|
||||
* a{sv} - Metadata
|
||||
* s - parent checksum (empty string for initial)
|
||||
* s - subject
|
||||
* s - body
|
||||
* t - Timestamp in seconds since the epoch (UTC)
|
||||
* s - Root tree contents
|
||||
* s - Root tree metadata
|
||||
*/
|
||||
#define OSTREE_COMMIT_GVARIANT_FORMAT "(ua{sv}ssstss)"
|
||||
|
||||
gboolean ostree_validate_checksum_string (const char *sha256,
|
||||
GError **error);
|
||||
|
||||
char *ostree_get_relative_object_path (const char *checksum,
|
||||
OstreeObjectType type,
|
||||
gboolean archive);
|
||||
|
||||
GVariant *ostree_get_xattrs_for_path (const char *path,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_set_xattrs (const char *path, GVariant *xattrs,
|
||||
GCancellable *cancellable, GError **error);
|
||||
|
||||
gboolean ostree_parse_metadata_file (const char *path,
|
||||
OstreeSerializedVariantType *out_type,
|
||||
GVariant **out_variant,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_stat_and_checksum_file (int dirfd, const char *path,
|
||||
OstreeObjectType type,
|
||||
GChecksum **out_checksum,
|
||||
struct stat *out_stbuf,
|
||||
GError **error);
|
||||
|
||||
/* Packed files:
|
||||
*
|
||||
* guint32 metadata_length [metadata gvariant] [content]
|
||||
*
|
||||
* metadata variant:
|
||||
* u - Version
|
||||
* u - uid
|
||||
* u - gid
|
||||
* u - mode
|
||||
* a(ayay) - xattrs
|
||||
* t - content length
|
||||
*
|
||||
* And then following the end of the variant is the content. If
|
||||
* symlink, then this is the target; if device, then device ID as
|
||||
* network byte order uint32.
|
||||
*/
|
||||
#define OSTREE_PACK_FILE_VARIANT_FORMAT "(uuuua(ayay)t)"
|
||||
|
||||
gboolean ostree_pack_object (GOutputStream *output,
|
||||
GFile *file,
|
||||
OstreeObjectType objtype,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_parse_packed_file (GFile *file,
|
||||
GVariant **out_metadata,
|
||||
GInputStream **out_content,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_unpack_object (const char *path,
|
||||
OstreeObjectType objtype,
|
||||
const char *dest_path,
|
||||
GChecksum **out_checksum,
|
||||
GError **error);
|
||||
|
||||
void ostree_checksum_update_stat (GChecksum *checksum, guint32 uid, guint32 gid, guint32 mode);
|
||||
|
||||
|
||||
#endif /* _OSTREE_REPO */
|
143
src/libostree/ostree-repo-file-enumerator.c
Normal file
143
src/libostree/ostree-repo-file-enumerator.c
Normal file
@ -0,0 +1,143 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ostree-repo-file-enumerator.h"
|
||||
#include <string.h>
|
||||
|
||||
struct _OstreeRepoFileEnumerator
|
||||
{
|
||||
GFileEnumerator parent;
|
||||
|
||||
OstreeRepoFile *dir;
|
||||
char *attributes;
|
||||
GFileQueryInfoFlags flags;
|
||||
|
||||
int index;
|
||||
};
|
||||
|
||||
#define ostree_repo_file_enumerator_get_type _ostree_repo_file_enumerator_get_type
|
||||
G_DEFINE_TYPE (OstreeRepoFileEnumerator, ostree_repo_file_enumerator, G_TYPE_FILE_ENUMERATOR);
|
||||
|
||||
static GFileInfo *ostree_repo_file_enumerator_next_file (GFileEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
static gboolean ostree_repo_file_enumerator_close (GFileEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
|
||||
static void
|
||||
ostree_repo_file_enumerator_dispose (GObject *object)
|
||||
{
|
||||
OstreeRepoFileEnumerator *self;
|
||||
|
||||
self = OSTREE_REPO_FILE_ENUMERATOR (object);
|
||||
|
||||
g_clear_object (&self->dir);
|
||||
g_free (self->attributes);
|
||||
|
||||
if (G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->dispose)
|
||||
G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_repo_file_enumerator_finalize (GObject *object)
|
||||
{
|
||||
OstreeRepoFileEnumerator *self;
|
||||
|
||||
self = OSTREE_REPO_FILE_ENUMERATOR (object);
|
||||
(void)self;
|
||||
|
||||
G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ostree_repo_file_enumerator_class_init (OstreeRepoFileEnumeratorClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GFileEnumeratorClass *enumerator_class = G_FILE_ENUMERATOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = ostree_repo_file_enumerator_finalize;
|
||||
gobject_class->dispose = ostree_repo_file_enumerator_dispose;
|
||||
|
||||
enumerator_class->next_file = ostree_repo_file_enumerator_next_file;
|
||||
enumerator_class->close_fn = ostree_repo_file_enumerator_close;
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_repo_file_enumerator_init (OstreeRepoFileEnumerator *self)
|
||||
{
|
||||
}
|
||||
|
||||
GFileEnumerator *
|
||||
_ostree_repo_file_enumerator_new (OstreeRepoFile *dir,
|
||||
const char *attributes,
|
||||
GFileQueryInfoFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
OstreeRepoFileEnumerator *self;
|
||||
|
||||
self = g_object_new (OSTREE_TYPE_REPO_FILE_ENUMERATOR,
|
||||
"container", dir,
|
||||
NULL);
|
||||
|
||||
self->dir = g_object_ref (dir);
|
||||
self->attributes = g_strdup (attributes);
|
||||
self->flags = flags;
|
||||
|
||||
return G_FILE_ENUMERATOR (self);
|
||||
}
|
||||
|
||||
static GFileInfo *
|
||||
ostree_repo_file_enumerator_next_file (GFileEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
OstreeRepoFileEnumerator *self = OSTREE_REPO_FILE_ENUMERATOR (enumerator);
|
||||
gboolean ret = FALSE;
|
||||
GFileInfo *info = NULL;
|
||||
|
||||
if (!_ostree_repo_file_tree_query_child (self->dir, self->index,
|
||||
self->attributes, self->flags,
|
||||
&info, cancellable, error))
|
||||
goto out;
|
||||
|
||||
self->index++;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (!ret)
|
||||
g_clear_object (&info);
|
||||
return info;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ostree_repo_file_enumerator_close (GFileEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
55
src/libostree/ostree-repo-file-enumerator.h
Normal file
55
src/libostree/ostree-repo-file-enumerator.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#ifndef _OSTREE_REPO_FILE_ENUMERATOR
|
||||
#define _OSTREE_REPO_FILE_ENUMERATOR
|
||||
|
||||
#include "ostree-repo-file.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_TYPE_REPO_FILE_ENUMERATOR (_ostree_repo_file_enumerator_get_type ())
|
||||
#define OSTREE_REPO_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumerator))
|
||||
#define OSTREE_REPO_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumeratorClass))
|
||||
#define OSTREE_IS_REPO_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR))
|
||||
#define OSTREE_IS_REPO_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_REPO_FILE_ENUMERATOR))
|
||||
#define OSTREE_REPO_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumeratorClass))
|
||||
|
||||
typedef struct _OstreeRepoFileEnumerator OstreeRepoFileEnumerator;
|
||||
typedef struct _OstreeRepoFileEnumeratorClass OstreeRepoFileEnumeratorClass;
|
||||
|
||||
struct _OstreeRepoFileEnumeratorClass
|
||||
{
|
||||
GFileEnumeratorClass parent_class;
|
||||
};
|
||||
|
||||
GType _ostree_repo_file_enumerator_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GFileEnumerator * _ostree_repo_file_enumerator_new (OstreeRepoFile *dir,
|
||||
const char *attributes,
|
||||
GFileQueryInfoFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
1428
src/libostree/ostree-repo-file.c
Normal file
1428
src/libostree/ostree-repo-file.c
Normal file
File diff suppressed because it is too large
Load Diff
115
src/libostree/ostree-repo-file.h
Normal file
115
src/libostree/ostree-repo-file.h
Normal file
@ -0,0 +1,115 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#ifndef _OSTREE_REPO_FILE
|
||||
#define _OSTREE_REPO_FILE
|
||||
|
||||
#include "ostree-repo.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_TYPE_REPO_FILE (_ostree_repo_file_get_type ())
|
||||
#define OSTREE_REPO_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_REPO_FILE, OstreeRepoFile))
|
||||
#define OSTREE_REPO_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_REPO_FILE, OstreeRepoFileClass))
|
||||
#define OSTREE_IS_LOCAL_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_REPO_FILE))
|
||||
#define OSTREE_IS_LOCAL_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_REPO_FILE))
|
||||
#define OSTREE_REPO_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_REPO_FILE, OstreeRepoFileClass))
|
||||
|
||||
typedef struct _OstreeRepoFile OstreeRepoFile;
|
||||
typedef struct _OstreeRepoFileClass OstreeRepoFileClass;
|
||||
|
||||
struct _OstreeRepoFileClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType _ostree_repo_file_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GFile * _ostree_repo_file_new_root (OstreeRepo *repo,
|
||||
const char *commit);
|
||||
|
||||
OstreeRepoFile * _ostree_repo_file_new_empty_tree (OstreeRepo *repo);
|
||||
|
||||
GFile * _ostree_repo_file_new_child (OstreeRepoFile *parent,
|
||||
const char *name);
|
||||
|
||||
gboolean _ostree_repo_file_ensure_resolved (OstreeRepoFile *self,
|
||||
GError **error);
|
||||
|
||||
gboolean _ostree_repo_file_get_xattrs (OstreeRepoFile *self,
|
||||
GVariant **out_xattrs,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
OstreeRepo * _ostree_repo_file_get_repo (OstreeRepoFile *self);
|
||||
OstreeRepoFile * _ostree_repo_file_get_root (OstreeRepoFile *self);
|
||||
|
||||
void _ostree_repo_file_make_empty_tree (OstreeRepoFile *self);
|
||||
|
||||
void _ostree_repo_file_tree_set_metadata (OstreeRepoFile *self,
|
||||
const char *checksum,
|
||||
GVariant *metadata);
|
||||
|
||||
void _ostree_repo_file_tree_set_content_checksum (OstreeRepoFile *self,
|
||||
const char *checksum);
|
||||
const char *_ostree_repo_file_tree_get_content_checksum (OstreeRepoFile *self);
|
||||
|
||||
gboolean _ostree_repo_file_is_tree (OstreeRepoFile *self);
|
||||
|
||||
const char * _ostree_repo_file_nontree_get_checksum (OstreeRepoFile *self);
|
||||
|
||||
GFile *_ostree_repo_file_nontree_get_local (OstreeRepoFile *self);
|
||||
|
||||
void _ostree_repo_file_tree_remove_child (OstreeRepoFile *self,
|
||||
const char *name);
|
||||
|
||||
void _ostree_repo_file_tree_add_file (OstreeRepoFile *self,
|
||||
const char *name,
|
||||
const char *checksum);
|
||||
|
||||
void _ostree_repo_file_tree_add_dir (OstreeRepoFile *self,
|
||||
const char *name,
|
||||
const char *content_checksum,
|
||||
const char *metadata_checksum);
|
||||
|
||||
int _ostree_repo_file_tree_find_child (OstreeRepoFile *self,
|
||||
const char *name,
|
||||
gboolean *is_dir,
|
||||
GVariant **out_container);
|
||||
|
||||
const char *_ostree_repo_file_tree_get_child_checksum (OstreeRepoFile *self,
|
||||
int n);
|
||||
|
||||
gboolean _ostree_repo_file_tree_query_child (OstreeRepoFile *self,
|
||||
int n,
|
||||
const char *attributes,
|
||||
GFileQueryInfoFlags flags,
|
||||
GFileInfo **out_info,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
GVariant *_ostree_repo_file_tree_get_contents (OstreeRepoFile *self);
|
||||
GVariant *_ostree_repo_file_tree_get_metadata (OstreeRepoFile *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
1877
src/libostree/ostree-repo.c
Normal file
1877
src/libostree/ostree-repo.c
Normal file
File diff suppressed because it is too large
Load Diff
162
src/libostree/ostree-repo.h
Normal file
162
src/libostree/ostree-repo.h
Normal file
@ -0,0 +1,162 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#ifndef _OSTREE_REPO
|
||||
#define _OSTREE_REPO
|
||||
|
||||
#include "ostree-core.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_TYPE_REPO ostree_repo_get_type()
|
||||
#define OSTREE_REPO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), OSTREE_TYPE_REPO, OstreeRepo))
|
||||
#define OSTREE_REPO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), OSTREE_TYPE_REPO, OstreeRepoClass))
|
||||
#define OSTREE_IS_REPO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_REPO))
|
||||
#define OSTREE_IS_REPO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), OSTREE_TYPE_REPO))
|
||||
#define OSTREE_REPO_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), OSTREE_TYPE_REPO, OstreeRepoClass))
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
} OstreeRepo;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
} OstreeRepoClass;
|
||||
|
||||
GType ostree_repo_get_type (void);
|
||||
|
||||
OstreeRepo* ostree_repo_new (const char *path);
|
||||
|
||||
gboolean ostree_repo_check (OstreeRepo *self, GError **error);
|
||||
|
||||
const char * ostree_repo_get_path (OstreeRepo *self);
|
||||
|
||||
gboolean ostree_repo_is_archive (OstreeRepo *self);
|
||||
|
||||
GKeyFile * ostree_repo_get_config (OstreeRepo *self);
|
||||
|
||||
GKeyFile * ostree_repo_copy_config (OstreeRepo *self);
|
||||
|
||||
gboolean ostree_repo_write_config (OstreeRepo *self,
|
||||
GKeyFile *new_config,
|
||||
GError **error);
|
||||
|
||||
char * ostree_repo_get_object_path (OstreeRepo *self,
|
||||
const char *object,
|
||||
OstreeObjectType type);
|
||||
|
||||
gboolean ostree_repo_store_packfile (OstreeRepo *self,
|
||||
const char *expected_checksum,
|
||||
const char *path,
|
||||
OstreeObjectType objtype,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_store_object_trusted (OstreeRepo *self,
|
||||
const char *path,
|
||||
const char *checksum,
|
||||
OstreeObjectType objtype,
|
||||
gboolean ignore_exists,
|
||||
gboolean force,
|
||||
gboolean *did_exist,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_resolve_rev (OstreeRepo *self,
|
||||
const char *rev,
|
||||
char **out_resolved,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_write_ref (OstreeRepo *self,
|
||||
gboolean is_local,
|
||||
const char *name,
|
||||
const char *rev,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_load_variant (OstreeRepo *self,
|
||||
const char *sha256,
|
||||
OstreeSerializedVariantType *out_type,
|
||||
GVariant **out_variant,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_load_variant_checked (OstreeRepo *self,
|
||||
OstreeSerializedVariantType expected_type,
|
||||
const char *sha256,
|
||||
GVariant **out_variant,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_commit_from_filelist_fd (OstreeRepo *self,
|
||||
const char *branch,
|
||||
const char *parent,
|
||||
const char *subject,
|
||||
const char *body,
|
||||
GVariant *metadata,
|
||||
const char *base,
|
||||
int fd,
|
||||
char separator,
|
||||
GChecksum **out_commit,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_checkout (OstreeRepo *self,
|
||||
const char *ref,
|
||||
const char *destination,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
typedef struct {
|
||||
guint content_differs : 1;
|
||||
guint xattrs_differs : 1;
|
||||
guint unused : 30;
|
||||
|
||||
GFileInfo *src_info;
|
||||
GFileInfo *target_info;
|
||||
|
||||
char *src_file_checksum;
|
||||
char *target_file_checksum;
|
||||
|
||||
GVariant *src_xattrs;
|
||||
GVariant *target_xattrs;
|
||||
} OstreeRepoDiffItem;
|
||||
|
||||
gboolean ostree_repo_diff (OstreeRepo *self,
|
||||
const char *ref,
|
||||
GFile *target,
|
||||
GPtrArray **out_modified, /* OstreeRepoDiffItem */
|
||||
GPtrArray **out_removed, /* OstreeRepoDiffItem */
|
||||
GPtrArray **out_added, /* OstreeRepoDiffItem */
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
typedef void (*OstreeRepoObjectIter) (OstreeRepo *self, const char *path,
|
||||
GFileInfo *fileinfo, gpointer user_data);
|
||||
|
||||
gboolean ostree_repo_iter_objects (OstreeRepo *self,
|
||||
OstreeRepoObjectIter callback,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _OSTREE_REPO */
|
29
src/libostree/ostree.h
Normal file
29
src/libostree/ostree.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#ifndef __OSTREE_H__
|
||||
|
||||
#include <ostree-core.h>
|
||||
#include <ostree-repo.h>
|
||||
#include <ostree-checkout.h>
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user