[ostree] Some work on ostree-build



commit 8bca7393153ce120c74128d0345daabe7ad000ec
Author: Colin Walters <walters verbum org>
Date:   Thu Nov 3 16:25:35 2011 -0400

    Some work on ostree-build

 Makefile-osbuild.am               |   38 ++++++++
 Makefile-ostree.am                |    2 +-
 Makefile-otutil.am                |    2 +
 Makefile.am                       |    1 +
 libotutil/ot-glib-compat.c        |  159 +++++++++++++++++++++++++++++++
 libotutil/ot-glib-compat.h        |   52 ++++++++++
 libotutil/ot-opt-utils.h          |    4 +-
 libotutil/ot-unix-utils.c         |   16 +++
 libotutil/ot-unix-utils.h         |    4 +
 libotutil/otutil.h                |    1 +
 osbuild/main.c                    |  107 +++++++++++++++++++++
 osbuild/ob-builtin-buildone.c     |  134 ++++++++++++++++++++++++++
 osbuild/ob-builtins.h             |   43 +++++++++
 osbuild/osbuild-raw-makeinstall.c |  189 +++++++++++++++++++++++++++++++++++++
 14 files changed, 749 insertions(+), 3 deletions(-)
---
diff --git a/Makefile-osbuild.am b/Makefile-osbuild.am
new file mode 100644
index 0000000..9373fdf
--- /dev/null
+++ b/Makefile-osbuild.am
@@ -0,0 +1,38 @@
+# Makefile for C source code
+#
+# Copyright (C) 2011 Colin Walters <walters verbum org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; 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>
+
+bin_PROGRAMS += ostree-build
+
+osbuild_common_cflags = -I$(srcdir)/libotutil -I$(srcdir)/osbuild -DLOCALEDIR=\"$(datadir)/locale\" -DG_LOG_DOMAIN=\"osbuild\" $(GIO_UNIX_CFLAGS)
+osbuild_common_ldadd = libotutil.la $(GIO_UNIX_LIBS)
+
+ostree_build_SOURCES = osbuild/main.c \
+	osbuild/ob-builtins.h \
+	osbuild/ob-builtin-buildone.c \
+	$(NULL)
+ostree_build_CFLAGS = $(osbuild_common_cflags)
+ostree_build_LDADD = $(osbuild_common_ldadd)
+
+bin_PROGRAMS += osbuild-raw-makeinstall
+
+osbuild_raw_makeinstall_SOURCES = osbuild/osbuild-raw-makeinstall.c \
+	$(NULL)
+osbuild_raw_makeinstall_CFLAGS = $(osbuild_common_cflags)
+osbuild_raw_makeinstall_LDADD = $(osbuild_common_ldadd)
diff --git a/Makefile-ostree.am b/Makefile-ostree.am
index 01ffbec..ef26c81 100644
--- a/Makefile-ostree.am
+++ b/Makefile-ostree.am
@@ -34,5 +34,5 @@ ostree_SOURCES = ostree/main.c \
 	ostree/ot-builtin-rev-parse.c \
 	ostree/ot-builtin-show.c \
 	$(NULL)
-ostree_CFLAGS = -I$(srcdir)/src -I$(srcdir)/libostree -I$(srcdir)/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
+ostree_CFLAGS = -I$(srcdir)/libotutil -I$(srcdir)/libostree -I$(srcdir)/ostree  -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
 ostree_LDADD = libotutil.la libostree.la $(OT_COREBIN_DEP_LIBS)
diff --git a/Makefile-otutil.am b/Makefile-otutil.am
index 8df7c5b..2e492b8 100644
--- a/Makefile-otutil.am
+++ b/Makefile-otutil.am
@@ -27,6 +27,8 @@ libotutil_la_SOURCES = \
 	libotutil/ot-unix-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 \
 	$(NULL)
 libotutil_la_CFLAGS = -I$(srcdir)/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(GIO_UNIX_CFLAGS)
diff --git a/Makefile.am b/Makefile.am
index 3dbda72..2404075 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,4 +14,5 @@ noinst_PROGRAMS =
 include Makefile-otutil.am
 include Makefile-libostree.am
 include Makefile-ostree.am
+include Makefile-osbuild.am
 include Makefile-triggers.am
diff --git a/libotutil/ot-glib-compat.c b/libotutil/ot-glib-compat.c
new file mode 100644
index 0000000..16d4cf5
--- /dev/null
+++ b/libotutil/ot-glib-compat.c
@@ -0,0 +1,159 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; 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 <gio/gio.h>
+
+#include <string.h>
+
+#include "otutil.h"
+
+#if GLIB_CHECK_VERSION(2,32,0)
+/* nothing */
+#else
+/* Code copied from glib/glib/genviron.c */
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+static gint
+ot_g_environ_find (gchar       **envp,
+                const gchar  *variable)
+{
+  gint len, i;
+
+  len = strlen (variable);
+
+  for (i = 0; envp[i]; i++)
+    {
+      if (strncmp (envp[i], variable, len) == 0 &&
+          envp[i][len] == '=')
+        return i;
+    }
+
+  return -1;
+}
+
+const gchar *
+ot_g_environ_getenv (gchar       **envp,
+                  const gchar  *variable)
+{
+  gint index;
+
+  g_return_val_if_fail (envp != NULL, NULL);
+  g_return_val_if_fail (variable != NULL, NULL);
+
+  index = ot_g_environ_find (envp, variable);
+  if (index != -1)
+    return envp[index] + strlen (variable) + 1;
+  else
+    return NULL;
+}
+
+gchar **
+ot_g_environ_setenv (gchar       **envp,
+                  const gchar  *variable,
+                  const gchar  *value,
+                  gboolean      overwrite)
+{
+  gint index;
+
+  g_return_val_if_fail (envp != NULL, NULL);
+  g_return_val_if_fail (variable != NULL, NULL);
+  g_return_val_if_fail (strchr (variable, '=') == NULL, NULL);
+
+  index = ot_g_environ_find (envp, variable);
+  if (index != -1)
+    {
+      if (overwrite)
+        {
+          g_free (envp[index]);
+          envp[index] = g_strdup_printf ("%s=%s", variable, value);
+        }
+    }
+  else
+    {
+      gint length;
+
+      length = g_strv_length (envp);
+      envp = g_renew (gchar *, envp, length + 2);
+      envp[length] = g_strdup_printf ("%s=%s", variable, value);
+      envp[length + 1] = NULL;
+    }
+
+  return envp;
+}
+
+gchar **
+ot_g_environ_unsetenv (gchar       **envp,
+                    const gchar  *variable)
+{
+  gint len;
+  gchar **e, **f;
+
+  g_return_val_if_fail (envp != NULL, NULL);
+  g_return_val_if_fail (variable != NULL, NULL);
+  g_return_val_if_fail (strchr (variable, '=') == NULL, NULL);
+
+  len = strlen (variable);
+
+  /* Note that we remove *all* environment entries for
+   * the variable name, not just the first.
+   */
+  e = f = envp;
+  while (*e != NULL)
+    {
+      if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=')
+        {
+          *f = *e;
+          f++;
+        }
+      e++;
+    }
+  *f = NULL;
+
+  return envp;
+}
+
+#endif
diff --git a/libotutil/ot-glib-compat.h b/libotutil/ot-glib-compat.h
new file mode 100644
index 0000000..f33728e
--- /dev/null
+++ b/libotutil/ot-glib-compat.h
@@ -0,0 +1,52 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; 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_GLIB_COMPAT_H__
+#define __OSTREE_GLIB_COMPAT_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#if GLIB_CHECK_VERSION(2,32,0)
+#define ot_g_environ_getenv g_environ_getenv
+#define ot_g_environ_setenv g_environ_setenv
+#define ot_g_environ_unsetenv g_environ_unsetenv
+#else
+const gchar *
+ot_g_environ_getenv (gchar       **envp,
+                     const gchar  *variable);
+
+gchar **
+ot_g_environ_setenv (gchar       **envp,
+                     const gchar  *variable,
+                     const gchar  *value,
+                     gboolean      overwrite);
+
+gchar **
+ot_g_environ_unsetenv (gchar       **envp,
+                       const gchar  *variable);
+#endif
+
+
+G_END_DECLS
+
+#endif
diff --git a/libotutil/ot-opt-utils.h b/libotutil/ot-opt-utils.h
index b65996f..5f4a10d 100644
--- a/libotutil/ot-opt-utils.h
+++ b/libotutil/ot-opt-utils.h
@@ -19,8 +19,8 @@
  * Author: Colin Walters <walters verbum org>
  */
 
-#ifndef __OSTREE_GIO_UTILS_H__
-#define __OSTREE_GIO_UTILS_H__
+#ifndef __OSTREE_OPT_UTILS_H__
+#define __OSTREE_OPT_UTILS_H__
 
 #include <gio/gio.h>
 
diff --git a/libotutil/ot-unix-utils.c b/libotutil/ot-unix-utils.c
index 78243f7..763f8a9 100644
--- a/libotutil/ot-unix-utils.c
+++ b/libotutil/ot-unix-utils.c
@@ -28,6 +28,8 @@
 
 #include <string.h>
 #include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
 #include <dirent.h>
 
 gboolean
@@ -254,3 +256,17 @@ ot_util_open_file_read_at (int dirfd, const char *name, GError **error)
     ot_util_set_error_from_errno (error, errno);
   return fd;
 }
+
+void
+ot_util_fatal_literal (const char *msg)
+{
+  g_printerr ("%s\n", msg);
+  exit (1);
+}
+
+void
+ot_util_fatal_gerror (GError *error)
+{
+  g_assert (error != NULL);
+  ot_util_fatal_literal (error->message);
+}
diff --git a/libotutil/ot-unix-utils.h b/libotutil/ot-unix-utils.h
index 0e1d392..d249d34 100644
--- a/libotutil/ot-unix-utils.h
+++ b/libotutil/ot-unix-utils.h
@@ -38,6 +38,10 @@ G_BEGIN_DECLS
 
 gboolean ot_util_spawn_pager (GOutputStream  **out_stream, GError         **error);
 
+void ot_util_fatal_literal (const char *msg) G_GNUC_NORETURN;
+
+void ot_util_fatal_gerror (GError *error) G_GNUC_NORETURN;
+
 gboolean ot_util_filename_has_dotdot (const char *path);
 
 GPtrArray *ot_util_sort_filenames_by_component_length (GPtrArray *files);
diff --git a/libotutil/otutil.h b/libotutil/otutil.h
index 2c49819..dd11553 100644
--- a/libotutil/otutil.h
+++ b/libotutil/otutil.h
@@ -24,5 +24,6 @@
 #include <ot-unix-utils.h>
 #include <ot-gio-utils.h>
 #include <ot-opt-utils.h>
+#include <ot-glib-compat.h>
 
 #endif
diff --git a/osbuild/main.c b/osbuild/main.c
new file mode 100644
index 0000000..db6d26f
--- /dev/null
+++ b/osbuild/main.c
@@ -0,0 +1,107 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; 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 <gio/gio.h>
+
+#include <string.h>
+
+#include "ob-builtins.h"
+
+static OsbuildBuiltin builtins[] = {
+  { "buildone", osbuild_builtin_buildone, 0 },
+  { NULL }
+};
+
+static int
+usage (char **argv, gboolean is_error)
+{
+  OsbuildBuiltin *builtin = builtins;
+  void (*print_func) (const gchar *format, ...);
+
+  if (is_error)
+    print_func = g_printerr;
+  else
+    print_func = g_print;
+
+  print_func ("usage: %s COMMAND [options]\n",
+              argv[0]);
+  print_func ("Builtin commands:\n");
+
+  while (builtin->name)
+    {
+      print_func ("  %s\n", builtin->name);
+      builtin++;
+    }
+  return (is_error ? 1 : 0);
+}
+
+
+int
+main (int    argc,
+      char **argv)
+{
+  OsbuildBuiltin *builtin;
+  const char *cmd;
+
+  g_type_init ();
+
+  g_set_prgname (argv[0]);
+
+  builtin = builtins;
+
+  if (argc < 2)
+    return usage (argv, 1);
+  
+  cmd = argv[1];
+
+  while (builtin->name)
+    {
+      GError *error = NULL;
+      if (strcmp (cmd, builtin->name) == 0)
+        {
+          int i;
+          int tmp_argc;
+          char **tmp_argv;
+
+          tmp_argc = argc - 1;
+          tmp_argv = g_new0 (char *, tmp_argc + 1);
+
+          tmp_argv[0] = (char*)builtin->name;
+          for (i = 0; i < tmp_argc; i++)
+            tmp_argv[i+1] = argv[i+2];
+          if (!builtin->fn (tmp_argc, tmp_argv, NULL, &error))
+            {
+              g_free (tmp_argv);
+              g_printerr ("%s\n", error->message);
+              g_clear_error (&error);
+              return 1;
+            }
+          g_free (tmp_argv);
+          return 0;
+        }
+      builtin++;
+    }
+  
+  g_printerr ("Unknown command '%s'\n", cmd);
+  return usage (argv, 1);
+}
diff --git a/osbuild/ob-builtin-buildone.c b/osbuild/ob-builtin-buildone.c
new file mode 100644
index 0000000..d2da5e9
--- /dev/null
+++ b/osbuild/ob-builtin-buildone.c
@@ -0,0 +1,134 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; 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 "otutil.h"
+#include "ob-builtins.h"
+
+#include <glib/gi18n.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *repo_path;
+static char *ref;
+static char *name;
+static char *generator;
+static char *resultdir;
+static gboolean raw;
+
+static GOptionEntry options[] = {
+  { "repo", 0, 0, G_OPTION_ARG_FILENAME, &repo_path, "Repository path", "repo" },
+  { "rev", 'r', 0, G_OPTION_ARG_STRING, &ref, "Build using this tree", "rev" },
+  { "name", 0, 0, G_OPTION_ARG_STRING, &name, "Name of the source", "source" },
+  { "generator", 0, 0, G_OPTION_ARG_FILENAME, &generator, "Script to run on installed tree", "script" },
+  { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "Do not instantiate a tree, use current", NULL },
+  { "resultdir", 0, 0, G_OPTION_ARG_FILENAME, &resultdir, "Directory for output artifacts", "dir" },
+  { NULL }
+};
+
+static char *
+get_tmpdir (void)
+{
+  char *tmp_prefix = g_strdup (g_getenv ("XDG_RUNTIME_DIR"));
+  char *ret;
+  
+  if (tmp_prefix)
+    {
+      ret = g_strdup_printf ("%s/osbuild", tmp_prefix);
+    }
+  else
+    {
+      tmp_prefix = g_strdup_printf ("/tmp/osbuild-%d", getuid ());
+      if (!g_file_test (tmp_prefix, G_FILE_TEST_IS_DIR))
+        {
+          if (!mkdir (tmp_prefix, 0755))
+            {
+              g_printerr ("Failed to make logging directory %s\n", tmp_prefix);
+              exit (1);
+            }
+        }
+      ret = tmp_prefix;
+      tmp_prefix = NULL;
+    }
+  g_free (tmp_prefix);
+  return ret;
+}
+
+static gboolean
+open_log (const char *name, 
+          GOutputStream **out_log,
+          GError **error)
+{
+  gboolean ret = FALSE;
+  char *tmpdir = NULL;
+  char *path = NULL;
+  GFile *logf = NULL;
+  GFileOutputStream *ret_log = NULL;
+
+  path = g_strdup_printf ("%s/%s.log", tmpdir, name);
+  logf = ot_util_new_file_for_path (path);
+
+  ret_log = g_file_replace (logf, NULL, FALSE, 0, NULL, error);
+  if (!ret_log)
+    goto out;
+
+  ret = TRUE;
+  *out_log = (GOutputStream*)ret_log;
+  ret_log = NULL;
+ out:
+  g_free (path);
+  g_free (tmpdir);
+  g_clear_object (&logf);
+  g_clear_object (&ret_log);
+  return ret;
+}
+
+gboolean
+osbuild_builtin_buildone (int argc, char **argv, const char *prefix, GError **error)
+{
+  GOptionContext *context;
+  gboolean ret = FALSE;
+  char *tmpdir;
+
+  context = g_option_context_new ("- Build current directory");
+  g_option_context_add_main_entries (context, options, NULL);
+
+  if (!g_option_context_parse (context, &argc, &argv, error))
+    goto out;
+
+  if (!raw && !repo_path)
+    {
+      ot_util_usage_error (context, "A result directory must be specified with --resultdir", error);
+      goto out;
+    }
+
+  if (!generator)
+    generator = g_build_filename (LIBEXECDIR, "ostree", "generators", "default", NULL);
+
+  
+
+ out:
+  if (context)
+    g_option_context_free (context);
+  return ret;
+}
diff --git a/osbuild/ob-builtins.h b/osbuild/ob-builtins.h
new file mode 100644
index 0000000..f21aafd
--- /dev/null
+++ b/osbuild/ob-builtins.h
@@ -0,0 +1,43 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; 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 __OSBUILD_BUILTINS__
+#define __OSBUILD_BUILTINS__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+  OSBUILD_BUILTIN_FLAG_NONE = 0,
+} OsbuildBuiltinFlags;
+
+typedef struct {
+  const char *name;
+  gboolean (*fn) (int argc, char **argv, const char *prefix, GError **error);
+  int flags; /* OsbuildBuiltinFlags */
+} OsbuildBuiltin;
+
+gboolean osbuild_builtin_buildone (int argc, char **argv, const char *prefix, GError **error);
+
+G_END_DECLS
+
+#endif
diff --git a/osbuild/osbuild-raw-makeinstall.c b/osbuild/osbuild-raw-makeinstall.c
new file mode 100644
index 0000000..49013ed
--- /dev/null
+++ b/osbuild/osbuild-raw-makeinstall.c
@@ -0,0 +1,189 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; 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 <gio/gio.h>
+
+#include "otutil.h"
+
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+static const char *
+find_first_file (GFileTest test, const char *name, ...) G_GNUC_NULL_TERMINATED;
+
+static const char *
+find_first_file (GFileTest test, const char *name, ...)
+{
+  va_list args;
+
+  va_start (args, name);
+
+  do
+    {
+      if (g_file_test (name, test))
+        break;
+      name = va_arg (args, const char *);
+    }
+  while (name != NULL);
+
+  va_end (args);
+
+  return name;
+}
+
+static void
+split_configure_make_args (int argc,
+                           char **argv,
+                           GPtrArray **out_configure_args,
+                           GPtrArray **out_make_args,
+                           GPtrArray **out_makeinstall_args)
+{
+  int i;
+
+  *out_configure_args = g_ptr_array_new ();
+  *out_make_args = g_ptr_array_new ();
+  *out_makeinstall_args = g_ptr_array_new ();
+
+  for (i = 1; i < argc; i++)
+    {
+      if (g_str_has_prefix (argv[i], "--"))
+        g_ptr_array_add (*out_configure_args, argv[i]);
+      else if (g_str_has_prefix (argv[i], "DESTDIR="))
+        g_ptr_array_add (*out_makeinstall_args, argv[i]);
+      else
+        g_ptr_array_add (*out_make_args, argv[i]);
+    }
+}
+
+static void
+spawn_sync_or_fatal (char **args, char **env, GSpawnFlags flags)
+{
+  GError *error = NULL;
+  int estatus;
+  char **iter;
+
+  g_print ("osbuild: running: ");
+  for (iter = args; *iter; iter++)
+    g_print ("%s ", *iter);
+  g_print ("\n");
+  if (g_spawn_sync (NULL, args, env, flags, NULL, NULL, NULL, NULL, &estatus, &error))
+    { 
+      if (WIFEXITED (estatus) && WEXITSTATUS (estatus) == 0)
+        {
+          g_message ("Subprocess %s exited successfully\n", args[0]);
+        }
+      else
+        {
+          if (WIFEXITED (estatus))
+            g_error ("Subprocess %s exited with code %d\n", args[0], WEXITSTATUS (estatus));
+          else if (WIFSIGNALED (estatus))
+            g_error ("Subprocess %s killed by signal %d\n", args[0], WTERMSIG (estatus));
+          else
+            g_error ("Subprocess %s terminated with status %d\n", args[0], estatus);
+          exit (1);
+        }
+    }
+  else
+    {
+      g_error ("Failed to execute %s: %s\n", args[0], error->message);
+      exit (1);
+    }
+}
+
+static void
+ptr_array_extend (GPtrArray *dest, GPtrArray *to_append)
+{
+  int i;
+
+  for (i = 0; i < to_append->len; i++)
+    g_ptr_array_add (dest, to_append->pdata[i]);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  GPtrArray *config_args;
+  GPtrArray *make_args;
+  GPtrArray *makeinstall_args;
+  GPtrArray *args;
+  int i;
+  char **subprocess_env;
+  GError *error = NULL;
+
+  g_type_init ();
+
+  g_set_prgname (argv[0]);
+
+  args = g_ptr_array_new ();
+
+  subprocess_env = g_get_environ ();
+  ot_g_environ_setenv (subprocess_env, "LANG", "C", TRUE);
+  ot_g_environ_unsetenv (subprocess_env, "LC_ALL");
+
+  split_configure_make_args (argc, argv, &config_args, &make_args, &makeinstall_args);
+
+  if (!g_file_test ("./configure", G_FILE_TEST_IS_EXECUTABLE))
+    {
+      const char *autogen;
+      char **autogen_env;
+      
+      autogen = find_first_file (G_FILE_TEST_IS_EXECUTABLE, "./autogen", "./autogen.sh");
+      if (!autogen)
+        ot_util_fatal_literal ("No executable configure or autogen script found"); 
+
+      autogen_env = g_strdupv (subprocess_env);
+      ot_g_environ_setenv (autogen_env, "NOCONFIGURE", "1", TRUE);
+      
+      g_ptr_array_set_size (args, 0);
+      g_ptr_array_add (args, (char*) autogen);
+      g_ptr_array_add (args, NULL);
+      spawn_sync_or_fatal ((char**)args->pdata, autogen_env, 0);
+    }
+
+  if (!g_file_test ("./configure", G_FILE_TEST_IS_EXECUTABLE))
+    ot_util_fatal_literal ("autogen script failed to generate a configure script");
+
+  g_ptr_array_set_size (args, 0);
+  g_ptr_array_add (args, "./configure");
+  ptr_array_extend (args, config_args);
+  g_ptr_array_add (args, NULL);
+  spawn_sync_or_fatal ((char**)args->pdata, subprocess_env, 0);
+    
+  g_ptr_array_set_size (args, 0);
+  g_ptr_array_add (args, "make");
+  ptr_array_extend (args, make_args);
+  g_ptr_array_add (args, NULL);
+  spawn_sync_or_fatal ((char**)args->pdata, subprocess_env, G_SPAWN_SEARCH_PATH);
+  
+  g_ptr_array_set_size (args, 0);
+  g_ptr_array_add (args, "make");
+  g_ptr_array_add (args, "install");
+  ptr_array_extend (args, makeinstall_args);
+  g_ptr_array_add (args, NULL);
+  spawn_sync_or_fatal ((char**)args->pdata, subprocess_env, G_SPAWN_SEARCH_PATH);
+
+  return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]