summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile.am3
-rw-r--r--README2
-rw-r--r--TODO4
-rw-r--r--configure.ac14
-rw-r--r--daemon/configure.ac2
-rw-r--r--libguestfs.spec.in30
-rw-r--r--ruby/Makefile.am43
-rw-r--r--ruby/Rakefile.in103
-rw-r--r--ruby/ext/guestfs/_guestfs.c2064
-rw-r--r--ruby/ext/guestfs/extconf.rb30
-rw-r--r--ruby/lib/guestfs.rb18
-rwxr-xr-xruby/run-ruby-tests22
-rw-r--r--ruby/tests/tc_010_load.rb28
-rw-r--r--ruby/tests/tc_050_lvcreate.rb49
-rwxr-xr-xsrc/generator.ml240
16 files changed, 2648 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index 1b11a246..174489e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -63,6 +63,9 @@ perl/Makefile.PL
perl/blib
perl/pm_to_blib
python/guestfs.pyc
+ruby/Rakefile
+ruby/ext/guestfs/extconf.h
+ruby/ext/guestfs/mkmf.log
pod2htm?.tmp
stamp-h1
test*.img
diff --git a/Makefile.am b/Makefile.am
index f6289e47..710e39d9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -28,6 +28,9 @@ endif
if HAVE_PYTHON
SUBDIRS += python
endif
+if HAVE_RUBY
+SUBDIRS += ruby
+endif
EXTRA_DIST = \
make-initramfs.sh update-initramfs.sh \
diff --git a/README b/README
index 2db1725f..ec05bddd 100644
--- a/README
+++ b/README
@@ -50,6 +50,8 @@ also to build the OCaml bindings
- (Optional) Python if you want to build the python bindings
+- (Optional) Ruby, rake if you want to build the ruby bindings
+
Running ./configure will check you have all the requirements installed
on your machine.
diff --git a/TODO b/TODO
index 3655b70c..17829c26 100644
--- a/TODO
+++ b/TODO
@@ -3,10 +3,6 @@ https://www.redhat.com/archives/fedora-virt/2009-April/msg00114.html
----------------------------------------------------------------------
-Several people have asked for Ruby bindings.
-
-----------------------------------------------------------------------
-
We badly need to actually implement the FTP server mentioned in the
documentation.
diff --git a/configure.ac b/configure.ac
index ad9361cd..a771cdf5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-AC_INIT([libguestfs],[0.9.9])
+AC_INIT([libguestfs],[1.0.0])
AM_INIT_AUTOMAKE
AC_CONFIG_MACRO_DIR([m4])
@@ -188,7 +188,16 @@ AC_SUBST(PYTHON_INCLUDEDIR)
AC_SUBST(PYTHON_SITE_PACKAGES)
AM_CONDITIONAL([HAVE_PYTHON],
- [test "x$PYTHON_INCLUDEDIR" != "x" && test "x$PYTHON_SITE_PACKAGES" != "x"])
+ [test "x$PYTHON_INCLUDEDIR" != "x" -a "x$PYTHON_SITE_PACKAGES" != "x"])
+
+dnl Check for Ruby and rake (optional, for Ruby bindings).
+old_libs="$LIBS"
+AC_CHECK_LIB([ruby],[ruby_init])
+LIBS="$old_libs"
+AC_CHECK_PROG([RAKE],[rake],[rake],[no])
+
+AM_CONDITIONAL([HAVE_RUBY],
+ [test "x$RAKE" != "xno" -a -n "x$HAVE_LIBRUBY"])
dnl Run in subdirs.
AC_CONFIG_SUBDIRS([daemon])
@@ -200,6 +209,7 @@ AC_CONFIG_FILES([Makefile src/Makefile fish/Makefile examples/Makefile
ocaml/Makefile ocaml/examples/Makefile
perl/Makefile
python/Makefile
+ ruby/Makefile ruby/Rakefile
make-initramfs.sh update-initramfs.sh
libguestfs.spec
ocaml/META perl/Makefile.PL])
diff --git a/daemon/configure.ac b/daemon/configure.ac
index 8edcb2de..0bd37b0b 100644
--- a/daemon/configure.ac
+++ b/daemon/configure.ac
@@ -15,7 +15,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-AC_INIT([libguestfs-daemon],[0.8.2])
+AC_INIT([libguestfs-daemon],[1.0.0])
AM_INIT_AUTOMAKE
AC_CONFIG_MACRO_DIR([m4])
diff --git a/libguestfs.spec.in b/libguestfs.spec.in
index fc70b017..c1e3e49e 100644
--- a/libguestfs.spec.in
+++ b/libguestfs.spec.in
@@ -35,6 +35,8 @@ BuildRequires: perl-Test-Pod
BuildRequires: perl-Test-Pod-Coverage
BuildRequires: perl-ExtUtils-MakeMaker
BuildRequires: python-devel
+BuildRequires: ruby-devel
+BuildRequires: rubygem-rake
# Runtime requires:
Requires: qemu >= 0.10-7
@@ -70,6 +72,8 @@ For OCaml bindings, see 'libguestfs-ocaml-devel'.
For Python bindings, see 'libguestfs-python'.
+For Ruby bindings, see 'libguestfs-ruby'.
+
%package devel
Summary: Development tools and libraries for %{name}
@@ -143,6 +147,20 @@ Requires: %{name} = %{version}-%{release}
%{name}-python contains Python bindings for %{name}.
+%package ruby
+Summary: Ruby bindings for %{name}
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+Requires: ruby(abi) = 1.8
+Provides: ruby(guestfs) = %{version}
+
+%{!?ruby_sitelib: %define ruby_sitelib %(ruby -rrbconfig -e "puts Config::CONFIG['sitelibdir']")}
+%{!?ruby_sitearch: %define ruby_sitearch %(ruby -rrbconfig -e "puts Config::CONFIG['sitearchdir']")}
+
+%description ruby
+%{name}-ruby contains Ruby bindings for %{name}.
+
+
%prep
%setup -q
@@ -196,6 +214,12 @@ if [ "$RPM_BUILD_ROOT%{python_sitearch}" != "$RPM_BUILD_ROOT%{python_sitelib}" ]
$RPM_BUILD_ROOT%{python_sitelib}/
fi
+# Install ruby bindings by hand.
+mkdir -p $RPM_BUILD_ROOT%{ruby_sitelib}
+mkdir -p $RPM_BUILD_ROOT%{ruby_sitearch}
+install -p -m0644 ruby/lib/libvirt.rb $RPM_BUILD_ROOT%{ruby_sitelib}
+install -p -m0755 ruby/ext/libvirt/_libvirt.so $RPM_BUILD_ROOT%{ruby_sitearch}
+
%clean
rm -rf $RPM_BUILD_ROOT
@@ -266,6 +290,12 @@ rm -rf $RPM_BUILD_ROOT
%{python_sitelib}/*.pyo
+%files ruby
+%defattr(-,root,root,-)
+%{ruby_sitelib}/guestfs.rb
+%{ruby_sitearch}/_guestfs.so
+
+
%changelog
* Thu Apr 16 2009 Richard Jones <rjones@redhat.com> - @VERSION@-1
- New upstream version @VERSION@.
diff --git a/ruby/Makefile.am b/ruby/Makefile.am
new file mode 100644
index 00000000..2b4b2010
--- /dev/null
+++ b/ruby/Makefile.am
@@ -0,0 +1,43 @@
+# libguestfs Ruby bindings
+# Copyright (C) 2009 Red Hat Inc.
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+EXTRA_DIST = \
+ Rakefile.in \
+ ext/guestfs/_guestfs.c \
+ ext/guestfs/extconf.rb \
+ lib/guestfs.rb \
+ run-ruby-tests \
+ tests/tc_*.rb
+
+CLEANFILES = *~ \
+ lib/*~ \
+ tests/*~ \
+ ext/guestfs/*~ \
+ ext/guestfs/extconf.h \
+ ext/guestfs/_guestfs.o \
+ ext/guestfs/_guestfs.so \
+ ext/guestfs/mkmf.log \
+ ext/guestfs/Makefile
+
+if HAVE_RUBY
+
+TESTS = run-ruby-tests
+
+all:
+ rake build
+
+endif \ No newline at end of file
diff --git a/ruby/Rakefile.in b/ruby/Rakefile.in
new file mode 100644
index 00000000..fc95f3ff
--- /dev/null
+++ b/ruby/Rakefile.in
@@ -0,0 +1,103 @@
+# libguestfs Ruby bindings -*- ruby -*-
+# @configure_input@
+# Copyright (C) 2009 Red Hat Inc.
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'rake/clean'
+require 'rake/rdoctask'
+require 'rake/testtask'
+require 'rake/gempackagetask'
+
+PKG_NAME='@PACKAGE_NAME@'
+PKG_VERSION='@PACKAGE_VERSION@'
+
+EXT_CONF='ext/guestfs/extconf.rb'
+MAKEFILE='ext/guestfs/Makefile'
+GUESTFS_MODULE='ext/guestfs/_guestfs.so'
+GUESTFS_SRC='ext/guestfs/_guestfs.c'
+
+CLEAN.include [ "ext/**/*.o", GUESTFS_MODULE,
+ "ext/**/depend" ]
+
+CLOBBER.include [ "config.save", "ext/**/mkmf.log",
+ MAKEFILE ]
+
+# Build locally
+
+file MAKEFILE => EXT_CONF do |t|
+ Dir::chdir(File::dirname(EXT_CONF)) do
+ unless sh "ruby #{File::basename(EXT_CONF)}"
+ $stderr.puts "Failed to run extconf"
+ break
+ end
+ end
+end
+file GUESTFS_MODULE => [ MAKEFILE, GUESTFS_SRC ] do |t|
+ Dir::chdir(File::dirname(EXT_CONF)) do
+ unless sh "make"
+ $stderr.puts "make failed"
+ break
+ end
+ end
+end
+desc "Build the native library"
+task :build => GUESTFS_MODULE
+
+Rake::TestTask.new(:test) do |t|
+ t.test_files = FileList['tests/tc_*.rb']
+ t.libs = [ 'lib', 'ext/guestfs' ]
+end
+task :test => :build
+
+Rake::RDocTask.new do |rd|
+ rd.main = "README.rdoc"
+ rd.rdoc_dir = "doc/site/api"
+ rd.rdoc_files.include("README.rdoc", "lib/**/*.rb", "ext/**/*.[ch]")
+end
+
+# Package tasks
+
+PKG_FILES = FileList[
+ "Rakefile", "COPYING", "README", "NEWS", "README.rdoc",
+ "lib/**/*.rb",
+ "ext/**/*.[ch]", "ext/**/MANIFEST", "ext/**/extconf.rb",
+ "tests/**/*",
+ "spec/**/*"
+]
+
+DIST_FILES = FileList[
+ "pkg/*.src.rpm", "pkg/*.gem", "pkg/*.zip", "pkg/*.tgz"
+]
+
+SPEC = Gem::Specification.new do |s|
+ s.name = PKG_NAME
+ s.version = PKG_VERSION
+ s.email = "rjones@redhat.com"
+ s.homepage = "http://et.redhat.com/~rjones/libguestfs/"
+ s.summary = "Ruby bindings for libguestfs"
+ s.files = PKG_FILES
+ s.autorequire = "guestfs"
+ s.required_ruby_version = '>= 1.8.1'
+ s.extensions = "ext/guestfs/extconf.rb"
+ s.description = <<EOF
+Ruby bindings for libguestfs.
+EOF
+end
+
+Rake::GemPackageTask.new(SPEC) do |pkg|
+ pkg.need_tar = true
+ pkg.need_zip = true
+end
diff --git a/ruby/ext/guestfs/_guestfs.c b/ruby/ext/guestfs/_guestfs.c
new file mode 100644
index 00000000..d6850465
--- /dev/null
+++ b/ruby/ext/guestfs/_guestfs.c
@@ -0,0 +1,2064 @@
+/* libguestfs generated file
+ * WARNING: THIS FILE IS GENERATED BY 'src/generator.ml'.
+ * ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <ruby.h>
+
+#include "guestfs.h"
+
+#include "extconf.h"
+
+static VALUE m_guestfs; /* guestfs module */
+static VALUE c_guestfs; /* guestfs_h handle */
+static VALUE e_Error; /* used for all errors */
+
+static void ruby_guestfs_free (void *p)
+{
+ if (!p) return;
+ guestfs_close ((guestfs_h *) p);
+}
+
+static VALUE ruby_guestfs_create (VALUE m)
+{
+ guestfs_h *g;
+
+ g = guestfs_create ();
+ if (!g)
+ rb_raise (e_Error, "failed to create guestfs handle");
+
+ /* Don't print error messages to stderr by default. */
+ guestfs_set_error_handler (g, NULL, NULL);
+
+ /* Wrap it, and make sure the close function is called when the
+ * handle goes away.
+ */
+ return Data_Wrap_Struct (c_guestfs, NULL, ruby_guestfs_free, g);
+}
+
+static VALUE ruby_guestfs_close (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+
+ ruby_guestfs_free (g);
+ DATA_PTR (gv) = NULL;
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_launch (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "launch");
+
+
+ int r;
+
+ r = guestfs_launch (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_wait_ready (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "wait_ready");
+
+
+ int r;
+
+ r = guestfs_wait_ready (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_kill_subprocess (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "kill_subprocess");
+
+
+ int r;
+
+ r = guestfs_kill_subprocess (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_add_drive (VALUE gv, VALUE filenamev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "add_drive");
+
+ const char *filename = StringValueCStr (filenamev);
+ if (!filename)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "filename", "add_drive");
+
+ int r;
+
+ r = guestfs_add_drive (g, filename);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_add_cdrom (VALUE gv, VALUE filenamev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "add_cdrom");
+
+ const char *filename = StringValueCStr (filenamev);
+ if (!filename)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "filename", "add_cdrom");
+
+ int r;
+
+ r = guestfs_add_cdrom (g, filename);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_config (VALUE gv, VALUE qemuparamv, VALUE qemuvaluev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "config");
+
+ const char *qemuparam = StringValueCStr (qemuparamv);
+ if (!qemuparam)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "qemuparam", "config");
+ const char *qemuvalue = StringValueCStr (qemuvaluev);
+
+ int r;
+
+ r = guestfs_config (g, qemuparam, qemuvalue);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_set_path (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "set_path");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "set_path");
+
+ int r;
+
+ r = guestfs_set_path (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_get_path (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "get_path");
+
+
+ const char *r;
+
+ r = guestfs_get_path (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return rb_str_new2 (r);
+}
+
+static VALUE ruby_guestfs_set_autosync (VALUE gv, VALUE autosyncv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "set_autosync");
+
+ int autosync = NUM2INT (autosyncv);
+
+ int r;
+
+ r = guestfs_set_autosync (g, autosync);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_get_autosync (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "get_autosync");
+
+
+ int r;
+
+ r = guestfs_get_autosync (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_set_verbose (VALUE gv, VALUE verbosev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "set_verbose");
+
+ int verbose = NUM2INT (verbosev);
+
+ int r;
+
+ r = guestfs_set_verbose (g, verbose);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_get_verbose (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "get_verbose");
+
+
+ int r;
+
+ r = guestfs_get_verbose (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_mount (VALUE gv, VALUE devicev, VALUE mountpointv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "mount");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "mount");
+ const char *mountpoint = StringValueCStr (mountpointv);
+ if (!mountpoint)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "mountpoint", "mount");
+
+ int r;
+
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_sync (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "sync");
+
+
+ int r;
+
+ r = guestfs_sync (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_touch (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "touch");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "touch");
+
+ int r;
+
+ r = guestfs_touch (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_cat (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "cat");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "cat");
+
+ char *r;
+
+ r = guestfs_cat (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_str_new2 (r);
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_ll (VALUE gv, VALUE directoryv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "ll");
+
+ const char *directory = StringValueCStr (directoryv);
+ if (!directory)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "directory", "ll");
+
+ char *r;
+
+ r = guestfs_ll (g, directory);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_str_new2 (r);
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_ls (VALUE gv, VALUE directoryv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "ls");
+
+ const char *directory = StringValueCStr (directoryv);
+ if (!directory)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "directory", "ls");
+
+ char **r;
+
+ r = guestfs_ls (g, directory);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_list_devices (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "list_devices");
+
+
+ char **r;
+
+ r = guestfs_list_devices (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_list_partitions (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "list_partitions");
+
+
+ char **r;
+
+ r = guestfs_list_partitions (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_pvs (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "pvs");
+
+
+ char **r;
+
+ r = guestfs_pvs (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_vgs (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "vgs");
+
+
+ char **r;
+
+ r = guestfs_vgs (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_lvs (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "lvs");
+
+
+ char **r;
+
+ r = guestfs_lvs (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_pvs_full (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "pvs_full");
+
+
+ struct guestfs_lvm_pv_list *r;
+
+ r = guestfs_pvs_full (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_ary_new2 (r->len);
+ int i;
+ for (i = 0; i < r->len; ++i) {
+ VALUE hv = rb_hash_new ();
+ rb_hash_aset (rv, rb_str_new2 ("pv_name"), rb_str_new2 (r->val[i].pv_name));
+ rb_hash_aset (rv, rb_str_new2 ("pv_uuid"), rb_str_new (r->val[i].pv_uuid, 32));
+ rb_hash_aset (rv, rb_str_new2 ("pv_fmt"), rb_str_new2 (r->val[i].pv_fmt));
+ rb_hash_aset (rv, rb_str_new2 ("pv_size"), ULL2NUM (r->val[i].pv_size));
+ rb_hash_aset (rv, rb_str_new2 ("dev_size"), ULL2NUM (r->val[i].dev_size));
+ rb_hash_aset (rv, rb_str_new2 ("pv_free"), ULL2NUM (r->val[i].pv_free));
+ rb_hash_aset (rv, rb_str_new2 ("pv_used"), ULL2NUM (r->val[i].pv_used));
+ rb_hash_aset (rv, rb_str_new2 ("pv_attr"), rb_str_new2 (r->val[i].pv_attr));
+ rb_hash_aset (rv, rb_str_new2 ("pv_pe_count"), ULL2NUM (r->val[i].pv_pe_count));
+ rb_hash_aset (rv, rb_str_new2 ("pv_pe_alloc_count"), ULL2NUM (r->val[i].pv_pe_alloc_count));
+ rb_hash_aset (rv, rb_str_new2 ("pv_tags"), rb_str_new2 (r->val[i].pv_tags));
+ rb_hash_aset (rv, rb_str_new2 ("pe_start"), ULL2NUM (r->val[i].pe_start));
+ rb_hash_aset (rv, rb_str_new2 ("pv_mda_count"), ULL2NUM (r->val[i].pv_mda_count));
+ rb_hash_aset (rv, rb_str_new2 ("pv_mda_free"), ULL2NUM (r->val[i].pv_mda_free));
+ rb_ary_push (rv, hv);
+ }
+ guestfs_free_lvm_pv_list (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_vgs_full (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "vgs_full");
+
+
+ struct guestfs_lvm_vg_list *r;
+
+ r = guestfs_vgs_full (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_ary_new2 (r->len);
+ int i;
+ for (i = 0; i < r->len; ++i) {
+ VALUE hv = rb_hash_new ();
+ rb_hash_aset (rv, rb_str_new2 ("vg_name"), rb_str_new2 (r->val[i].vg_name));
+ rb_hash_aset (rv, rb_str_new2 ("vg_uuid"), rb_str_new (r->val[i].vg_uuid, 32));
+ rb_hash_aset (rv, rb_str_new2 ("vg_fmt"), rb_str_new2 (r->val[i].vg_fmt));
+ rb_hash_aset (rv, rb_str_new2 ("vg_attr"), rb_str_new2 (r->val[i].vg_attr));
+ rb_hash_aset (rv, rb_str_new2 ("vg_size"), ULL2NUM (r->val[i].vg_size));
+ rb_hash_aset (rv, rb_str_new2 ("vg_free"), ULL2NUM (r->val[i].vg_free));
+ rb_hash_aset (rv, rb_str_new2 ("vg_sysid"), rb_str_new2 (r->val[i].vg_sysid));
+ rb_hash_aset (rv, rb_str_new2 ("vg_extent_size"), ULL2NUM (r->val[i].vg_extent_size));
+ rb_hash_aset (rv, rb_str_new2 ("vg_extent_count"), ULL2NUM (r->val[i].vg_extent_count));
+ rb_hash_aset (rv, rb_str_new2 ("vg_free_count"), ULL2NUM (r->val[i].vg_free_count));
+ rb_hash_aset (rv, rb_str_new2 ("max_lv"), ULL2NUM (r->val[i].max_lv));
+ rb_hash_aset (rv, rb_str_new2 ("max_pv"), ULL2NUM (r->val[i].max_pv));
+ rb_hash_aset (rv, rb_str_new2 ("pv_count"), ULL2NUM (r->val[i].pv_count));
+ rb_hash_aset (rv, rb_str_new2 ("lv_count"), ULL2NUM (r->val[i].lv_count));
+ rb_hash_aset (rv, rb_str_new2 ("snap_count"), ULL2NUM (r->val[i].snap_count));
+ rb_hash_aset (rv, rb_str_new2 ("vg_seqno"), ULL2NUM (r->val[i].vg_seqno));
+ rb_hash_aset (rv, rb_str_new2 ("vg_tags"), rb_str_new2 (r->val[i].vg_tags));
+ rb_hash_aset (rv, rb_str_new2 ("vg_mda_count"), ULL2NUM (r->val[i].vg_mda_count));
+ rb_hash_aset (rv, rb_str_new2 ("vg_mda_free"), ULL2NUM (r->val[i].vg_mda_free));
+ rb_ary_push (rv, hv);
+ }
+ guestfs_free_lvm_vg_list (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_lvs_full (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "lvs_full");
+
+
+ struct guestfs_lvm_lv_list *r;
+
+ r = guestfs_lvs_full (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_ary_new2 (r->len);
+ int i;
+ for (i = 0; i < r->len; ++i) {
+ VALUE hv = rb_hash_new ();
+ rb_hash_aset (rv, rb_str_new2 ("lv_name"), rb_str_new2 (r->val[i].lv_name));
+ rb_hash_aset (rv, rb_str_new2 ("lv_uuid"), rb_str_new (r->val[i].lv_uuid, 32));
+ rb_hash_aset (rv, rb_str_new2 ("lv_attr"), rb_str_new2 (r->val[i].lv_attr));
+ rb_hash_aset (rv, rb_str_new2 ("lv_major"), ULL2NUM (r->val[i].lv_major));
+ rb_hash_aset (rv, rb_str_new2 ("lv_minor"), ULL2NUM (r->val[i].lv_minor));
+ rb_hash_aset (rv, rb_str_new2 ("lv_kernel_major"), ULL2NUM (r->val[i].lv_kernel_major));
+ rb_hash_aset (rv, rb_str_new2 ("lv_kernel_minor"), ULL2NUM (r->val[i].lv_kernel_minor));
+ rb_hash_aset (rv, rb_str_new2 ("lv_size"), ULL2NUM (r->val[i].lv_size));
+ rb_hash_aset (rv, rb_str_new2 ("seg_count"), ULL2NUM (r->val[i].seg_count));
+ rb_hash_aset (rv, rb_str_new2 ("origin"), rb_str_new2 (r->val[i].origin));
+ rb_hash_aset (rv, rb_str_new2 ("snap_percent"), rb_dbl2big (r->val[i].snap_percent));
+ rb_hash_aset (rv, rb_str_new2 ("copy_percent"), rb_dbl2big (r->val[i].copy_percent));
+ rb_hash_aset (rv, rb_str_new2 ("move_pv"), rb_str_new2 (r->val[i].move_pv));
+ rb_hash_aset (rv, rb_str_new2 ("lv_tags"), rb_str_new2 (r->val[i].lv_tags));
+ rb_hash_aset (rv, rb_str_new2 ("mirror_log"), rb_str_new2 (r->val[i].mirror_log));
+ rb_hash_aset (rv, rb_str_new2 ("modules"), rb_str_new2 (r->val[i].modules));
+ rb_ary_push (rv, hv);
+ }
+ guestfs_free_lvm_lv_list (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_read_lines (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "read_lines");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "read_lines");
+
+ char **r;
+
+ r = guestfs_read_lines (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_aug_init (VALUE gv, VALUE rootv, VALUE flagsv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_init");
+
+ const char *root = StringValueCStr (rootv);
+ if (!root)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "root", "aug_init");
+ int flags = NUM2INT (flagsv);
+
+ int r;
+
+ r = guestfs_aug_init (g, root, flags);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_aug_close (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_close");
+
+
+ int r;
+
+ r = guestfs_aug_close (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_aug_defvar (VALUE gv, VALUE namev, VALUE exprv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_defvar");
+
+ const char *name = StringValueCStr (namev);
+ if (!name)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "name", "aug_defvar");
+ const char *expr = StringValueCStr (exprv);
+
+ int r;
+
+ r = guestfs_aug_defvar (g, name, expr);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_aug_defnode (VALUE gv, VALUE namev, VALUE exprv, VALUE valv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_defnode");
+
+ const char *name = StringValueCStr (namev);
+ if (!name)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "name", "aug_defnode");
+ const char *expr = StringValueCStr (exprv);
+ if (!expr)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "expr", "aug_defnode");
+ const char *val = StringValueCStr (valv);
+ if (!val)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "val", "aug_defnode");
+
+ struct guestfs_int_bool *r;
+
+ r = guestfs_aug_defnode (g, name, expr, val);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_ary_new2 (2);
+ rb_ary_push (rv, INT2NUM (r->i));
+ rb_ary_push (rv, INT2NUM (r->b));
+ guestfs_free_int_bool (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_aug_get (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_get");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "aug_get");
+
+ char *r;
+
+ r = guestfs_aug_get (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_str_new2 (r);
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_aug_set (VALUE gv, VALUE pathv, VALUE valv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_set");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "aug_set");
+ const char *val = StringValueCStr (valv);
+ if (!val)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "val", "aug_set");
+
+ int r;
+
+ r = guestfs_aug_set (g, path, val);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_aug_insert (VALUE gv, VALUE pathv, VALUE labelv, VALUE beforev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_insert");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "aug_insert");
+ const char *label = StringValueCStr (labelv);
+ if (!label)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "label", "aug_insert");
+ int before = NUM2INT (beforev);
+
+ int r;
+
+ r = guestfs_aug_insert (g, path, label, before);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_aug_rm (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_rm");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "aug_rm");
+
+ int r;
+
+ r = guestfs_aug_rm (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_aug_mv (VALUE gv, VALUE srcv, VALUE destv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_mv");
+
+ const char *src = StringValueCStr (srcv);
+ if (!src)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "src", "aug_mv");
+ const char *dest = StringValueCStr (destv);
+ if (!dest)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "dest", "aug_mv");
+
+ int r;
+
+ r = guestfs_aug_mv (g, src, dest);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_aug_match (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_match");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "aug_match");
+
+ char **r;
+
+ r = guestfs_aug_match (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_aug_save (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_save");
+
+
+ int r;
+
+ r = guestfs_aug_save (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_aug_load (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_load");
+
+
+ int r;
+
+ r = guestfs_aug_load (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_aug_ls (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "aug_ls");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "aug_ls");
+
+ char **r;
+
+ r = guestfs_aug_ls (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_rm (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "rm");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "rm");
+
+ int r;
+
+ r = guestfs_rm (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_rmdir (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "rmdir");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "rmdir");
+
+ int r;
+
+ r = guestfs_rmdir (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_rm_rf (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "rm_rf");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "rm_rf");
+
+ int r;
+
+ r = guestfs_rm_rf (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_mkdir (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "mkdir");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "mkdir");
+
+ int r;
+
+ r = guestfs_mkdir (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_mkdir_p (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "mkdir_p");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "mkdir_p");
+
+ int r;
+
+ r = guestfs_mkdir_p (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_chmod (VALUE gv, VALUE modev, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "chmod");
+
+ int mode = NUM2INT (modev);
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "chmod");
+
+ int r;
+
+ r = guestfs_chmod (g, mode, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_chown (VALUE gv, VALUE ownerv, VALUE groupv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "chown");
+
+ int owner = NUM2INT (ownerv);
+ int group = NUM2INT (groupv);
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "chown");
+
+ int r;
+
+ r = guestfs_chown (g, owner, group, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_exists (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "exists");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "exists");
+
+ int r;
+
+ r = guestfs_exists (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_is_file (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "is_file");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "is_file");
+
+ int r;
+
+ r = guestfs_is_file (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_is_dir (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "is_dir");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "is_dir");
+
+ int r;
+
+ r = guestfs_is_dir (g, path);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_pvcreate (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "pvcreate");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "pvcreate");
+
+ int r;
+
+ r = guestfs_pvcreate (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_vgcreate (VALUE gv, VALUE volgroupv, VALUE physvolsv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "vgcreate");
+
+ const char *volgroup = StringValueCStr (volgroupv);
+ if (!volgroup)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "volgroup", "vgcreate");
+ char **physvols; {
+ int i, len;
+ len = RARRAY_LEN (physvolsv);
+ physvols = malloc (sizeof (char *) * (len+1));
+ for (i = 0; i < len; ++i) {
+ VALUE v = rb_ary_entry (physvolsv, i);
+ physvols[i] = StringValueCStr (v);
+ }
+ }
+
+ int r;
+
+ r = guestfs_vgcreate (g, volgroup, physvols);
+ free (physvols);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_lvcreate (VALUE gv, VALUE logvolv, VALUE volgroupv, VALUE mbytesv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "lvcreate");
+
+ const char *logvol = StringValueCStr (logvolv);
+ if (!logvol)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "logvol", "lvcreate");
+ const char *volgroup = StringValueCStr (volgroupv);
+ if (!volgroup)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "volgroup", "lvcreate");
+ int mbytes = NUM2INT (mbytesv);
+
+ int r;
+
+ r = guestfs_lvcreate (g, logvol, volgroup, mbytes);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_mkfs (VALUE gv, VALUE fstypev, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "mkfs");
+
+ const char *fstype = StringValueCStr (fstypev);
+ if (!fstype)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "fstype", "mkfs");
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "mkfs");
+
+ int r;
+
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_sfdisk (VALUE gv, VALUE devicev, VALUE cylsv, VALUE headsv, VALUE sectorsv, VALUE linesv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "sfdisk");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "sfdisk");
+ int cyls = NUM2INT (cylsv);
+ int heads = NUM2INT (headsv);
+ int sectors = NUM2INT (sectorsv);
+ char **lines; {
+ int i, len;
+ len = RARRAY_LEN (linesv);
+ lines = malloc (sizeof (char *) * (len+1));
+ for (i = 0; i < len; ++i) {
+ VALUE v = rb_ary_entry (linesv, i);
+ lines[i] = StringValueCStr (v);
+ }
+ }
+
+ int r;
+
+ r = guestfs_sfdisk (g, device, cyls, heads, sectors, lines);
+ free (lines);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_write_file (VALUE gv, VALUE pathv, VALUE contentv, VALUE sizev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "write_file");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "write_file");
+ const char *content = StringValueCStr (contentv);
+ if (!content)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "content", "write_file");
+ int size = NUM2INT (sizev);
+
+ int r;
+
+ r = guestfs_write_file (g, path, content, size);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_umount (VALUE gv, VALUE pathordevicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "umount");
+
+ const char *pathordevice = StringValueCStr (pathordevicev);
+ if (!pathordevice)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "pathordevice", "umount");
+
+ int r;
+
+ r = guestfs_umount (g, pathordevice);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_mounts (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "mounts");
+
+
+ char **r;
+
+ r = guestfs_mounts (g);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_umount_all (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "umount_all");
+
+
+ int r;
+
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_lvm_remove_all (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "lvm_remove_all");
+
+
+ int r;
+
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_file (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "file");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "file");
+
+ char *r;
+
+ r = guestfs_file (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_str_new2 (r);
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_command (VALUE gv, VALUE argumentsv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "command");
+
+ char **arguments; {
+ int i, len;
+ len = RARRAY_LEN (argumentsv);
+ arguments = malloc (sizeof (char *) * (len+1));
+ for (i = 0; i < len; ++i) {
+ VALUE v = rb_ary_entry (argumentsv, i);
+ arguments[i] = StringValueCStr (v);
+ }
+ }
+
+ char *r;
+
+ r = guestfs_command (g, arguments);
+ free (arguments);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_str_new2 (r);
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_command_lines (VALUE gv, VALUE argumentsv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "command_lines");
+
+ char **arguments; {
+ int i, len;
+ len = RARRAY_LEN (argumentsv);
+ arguments = malloc (sizeof (char *) * (len+1));
+ for (i = 0; i < len; ++i) {
+ VALUE v = rb_ary_entry (argumentsv, i);
+ arguments[i] = StringValueCStr (v);
+ }
+ }
+
+ char **r;
+
+ r = guestfs_command_lines (g, arguments);
+ free (arguments);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_stat (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "stat");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "stat");
+
+ struct guestfs_stat *r;
+
+ r = guestfs_stat (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_hash_new ();
+ rb_hash_aset (rv, rb_str_new2 ("dev"), ULL2NUM (r->dev));
+ rb_hash_aset (rv, rb_str_new2 ("ino"), ULL2NUM (r->ino));
+ rb_hash_aset (rv, rb_str_new2 ("mode"), ULL2NUM (r->mode));
+ rb_hash_aset (rv, rb_str_new2 ("nlink"), ULL2NUM (r->nlink));
+ rb_hash_aset (rv, rb_str_new2 ("uid"), ULL2NUM (r->uid));
+ rb_hash_aset (rv, rb_str_new2 ("gid"), ULL2NUM (r->gid));
+ rb_hash_aset (rv, rb_str_new2 ("rdev"), ULL2NUM (r->rdev));
+ rb_hash_aset (rv, rb_str_new2 ("size"), ULL2NUM (r->size));
+ rb_hash_aset (rv, rb_str_new2 ("blksize"), ULL2NUM (r->blksize));
+ rb_hash_aset (rv, rb_str_new2 ("blocks"), ULL2NUM (r->blocks));
+ rb_hash_aset (rv, rb_str_new2 ("atime"), ULL2NUM (r->atime));
+ rb_hash_aset (rv, rb_str_new2 ("mtime"), ULL2NUM (r->mtime));
+ rb_hash_aset (rv, rb_str_new2 ("ctime"), ULL2NUM (r->ctime));
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_lstat (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "lstat");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "lstat");
+
+ struct guestfs_stat *r;
+
+ r = guestfs_lstat (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_hash_new ();
+ rb_hash_aset (rv, rb_str_new2 ("dev"), ULL2NUM (r->dev));
+ rb_hash_aset (rv, rb_str_new2 ("ino"), ULL2NUM (r->ino));
+ rb_hash_aset (rv, rb_str_new2 ("mode"), ULL2NUM (r->mode));
+ rb_hash_aset (rv, rb_str_new2 ("nlink"), ULL2NUM (r->nlink));
+ rb_hash_aset (rv, rb_str_new2 ("uid"), ULL2NUM (r->uid));
+ rb_hash_aset (rv, rb_str_new2 ("gid"), ULL2NUM (r->gid));
+ rb_hash_aset (rv, rb_str_new2 ("rdev"), ULL2NUM (r->rdev));
+ rb_hash_aset (rv, rb_str_new2 ("size"), ULL2NUM (r->size));
+ rb_hash_aset (rv, rb_str_new2 ("blksize"), ULL2NUM (r->blksize));
+ rb_hash_aset (rv, rb_str_new2 ("blocks"), ULL2NUM (r->blocks));
+ rb_hash_aset (rv, rb_str_new2 ("atime"), ULL2NUM (r->atime));
+ rb_hash_aset (rv, rb_str_new2 ("mtime"), ULL2NUM (r->mtime));
+ rb_hash_aset (rv, rb_str_new2 ("ctime"), ULL2NUM (r->ctime));
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_statvfs (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "statvfs");
+
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "statvfs");
+
+ struct guestfs_statvfs *r;
+
+ r = guestfs_statvfs (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_hash_new ();
+ rb_hash_aset (rv, rb_str_new2 ("bsize"), ULL2NUM (r->bsize));
+ rb_hash_aset (rv, rb_str_new2 ("frsize"), ULL2NUM (r->frsize));
+ rb_hash_aset (rv, rb_str_new2 ("blocks"), ULL2NUM (r->blocks));
+ rb_hash_aset (rv, rb_str_new2 ("bfree"), ULL2NUM (r->bfree));
+ rb_hash_aset (rv, rb_str_new2 ("bavail"), ULL2NUM (r->bavail));
+ rb_hash_aset (rv, rb_str_new2 ("files"), ULL2NUM (r->files));
+ rb_hash_aset (rv, rb_str_new2 ("ffree"), ULL2NUM (r->ffree));
+ rb_hash_aset (rv, rb_str_new2 ("favail"), ULL2NUM (r->favail));
+ rb_hash_aset (rv, rb_str_new2 ("fsid"), ULL2NUM (r->fsid));
+ rb_hash_aset (rv, rb_str_new2 ("flag"), ULL2NUM (r->flag));
+ rb_hash_aset (rv, rb_str_new2 ("namemax"), ULL2NUM (r->namemax));
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_tune2fs_l (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "tune2fs_l");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "tune2fs_l");
+
+ char **r;
+
+ r = guestfs_tune2fs_l (g, device);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_hash_new ();
+ int i;
+ for (i = 0; r[i] != NULL; i+=2) {
+ rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));
+ free (r[i]);
+ free (r[i+1]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_blockdev_setro (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_setro");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_setro");
+
+ int r;
+
+ r = guestfs_blockdev_setro (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_blockdev_setrw (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_setrw");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_setrw");
+
+ int r;
+
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_blockdev_getro (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_getro");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_getro");
+
+ int r;
+
+ r = guestfs_blockdev_getro (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_blockdev_getss (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_getss");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_getss");
+
+ int r;
+
+ r = guestfs_blockdev_getss (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_blockdev_getbsz (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_getbsz");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_getbsz");
+
+ int r;
+
+ r = guestfs_blockdev_getbsz (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return INT2NUM (r);
+}
+
+static VALUE ruby_guestfs_blockdev_setbsz (VALUE gv, VALUE devicev, VALUE blocksizev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_setbsz");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_setbsz");
+ int blocksize = NUM2INT (blocksizev);
+
+ int r;
+
+ r = guestfs_blockdev_setbsz (g, device, blocksize);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_blockdev_getsz (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_getsz");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_getsz");
+
+ int64_t r;
+
+ r = guestfs_blockdev_getsz (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return ULL2NUM (r);
+}
+
+static VALUE ruby_guestfs_blockdev_getsize64 (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_getsize64");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_getsize64");
+
+ int64_t r;
+
+ r = guestfs_blockdev_getsize64 (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return ULL2NUM (r);
+}
+
+static VALUE ruby_guestfs_blockdev_flushbufs (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_flushbufs");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_flushbufs");
+
+ int r;
+
+ r = guestfs_blockdev_flushbufs (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_blockdev_rereadpt (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "blockdev_rereadpt");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "blockdev_rereadpt");
+
+ int r;
+
+ r = guestfs_blockdev_rereadpt (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+/* Initialize the module. */
+void Init__guestfs ()
+{
+ m_guestfs = rb_define_module ("Guestfs");
+ c_guestfs = rb_define_class_under (m_guestfs, "Guestfs", rb_cObject);
+ e_Error = rb_define_class_under (m_guestfs, "Error", rb_eStandardError);
+
+ rb_define_module_function (m_guestfs, "create", ruby_guestfs_create, 0);
+ rb_define_method (c_guestfs, "close", ruby_guestfs_close, 0);
+
+ rb_define_method (c_guestfs, "launch",
+ ruby_guestfs_launch, 0);
+ rb_define_method (c_guestfs, "wait_ready",
+ ruby_guestfs_wait_ready, 0);
+ rb_define_method (c_guestfs, "kill_subprocess",
+ ruby_guestfs_kill_subprocess, 0);
+ rb_define_method (c_guestfs, "add_drive",
+ ruby_guestfs_add_drive, 1);
+ rb_define_method (c_guestfs, "add_cdrom",
+ ruby_guestfs_add_cdrom, 1);
+ rb_define_method (c_guestfs, "config",
+ ruby_guestfs_config, 2);
+ rb_define_method (c_guestfs, "set_path",
+ ruby_guestfs_set_path, 1);
+ rb_define_method (c_guestfs, "get_path",
+ ruby_guestfs_get_path, 0);
+ rb_define_method (c_guestfs, "set_autosync",
+ ruby_guestfs_set_autosync, 1);
+ rb_define_method (c_guestfs, "get_autosync",
+ ruby_guestfs_get_autosync, 0);
+ rb_define_method (c_guestfs, "set_verbose",
+ ruby_guestfs_set_verbose, 1);
+ rb_define_method (c_guestfs, "get_verbose",
+ ruby_guestfs_get_verbose, 0);
+ rb_define_method (c_guestfs, "mount",
+ ruby_guestfs_mount, 2);
+ rb_define_method (c_guestfs, "sync",
+ ruby_guestfs_sync, 0);
+ rb_define_method (c_guestfs, "touch",
+ ruby_guestfs_touch, 1);
+ rb_define_method (c_guestfs, "cat",
+ ruby_guestfs_cat, 1);
+ rb_define_method (c_guestfs, "ll",
+ ruby_guestfs_ll, 1);
+ rb_define_method (c_guestfs, "ls",
+ ruby_guestfs_ls, 1);
+ rb_define_method (c_guestfs, "list_devices",
+ ruby_guestfs_list_devices, 0);
+ rb_define_method (c_guestfs, "list_partitions",
+ ruby_guestfs_list_partitions, 0);
+ rb_define_method (c_guestfs, "pvs",
+ ruby_guestfs_pvs, 0);
+ rb_define_method (c_guestfs, "vgs",
+ ruby_guestfs_vgs, 0);
+ rb_define_method (c_guestfs, "lvs",
+ ruby_guestfs_lvs, 0);
+ rb_define_method (c_guestfs, "pvs_full",
+ ruby_guestfs_pvs_full, 0);
+ rb_define_method (c_guestfs, "vgs_full",
+ ruby_guestfs_vgs_full, 0);
+ rb_define_method (c_guestfs, "lvs_full",
+ ruby_guestfs_lvs_full, 0);
+ rb_define_method (c_guestfs, "read_lines",
+ ruby_guestfs_read_lines, 1);
+ rb_define_method (c_guestfs, "aug_init",
+ ruby_guestfs_aug_init, 2);
+ rb_define_method (c_guestfs, "aug_close",
+ ruby_guestfs_aug_close, 0);
+ rb_define_method (c_guestfs, "aug_defvar",
+ ruby_guestfs_aug_defvar, 2);
+ rb_define_method (c_guestfs, "aug_defnode",
+ ruby_guestfs_aug_defnode, 3);
+ rb_define_method (c_guestfs, "aug_get",
+ ruby_guestfs_aug_get, 1);
+ rb_define_method (c_guestfs, "aug_set",
+ ruby_guestfs_aug_set, 2);
+ rb_define_method (c_guestfs, "aug_insert",
+ ruby_guestfs_aug_insert, 3);
+ rb_define_method (c_guestfs, "aug_rm",
+ ruby_guestfs_aug_rm, 1);
+ rb_define_method (c_guestfs, "aug_mv",
+ ruby_guestfs_aug_mv, 2);
+ rb_define_method (c_guestfs, "aug_match",
+ ruby_guestfs_aug_match, 1);
+ rb_define_method (c_guestfs, "aug_save",
+ ruby_guestfs_aug_save, 0);
+ rb_define_method (c_guestfs, "aug_load",
+ ruby_guestfs_aug_load, 0);
+ rb_define_method (c_guestfs, "aug_ls",
+ ruby_guestfs_aug_ls, 1);
+ rb_define_method (c_guestfs, "rm",
+ ruby_guestfs_rm, 1);
+ rb_define_method (c_guestfs, "rmdir",
+ ruby_guestfs_rmdir, 1);
+ rb_define_method (c_guestfs, "rm_rf",
+ ruby_guestfs_rm_rf, 1);
+ rb_define_method (c_guestfs, "mkdir",
+ ruby_guestfs_mkdir, 1);
+ rb_define_method (c_guestfs, "mkdir_p",
+ ruby_guestfs_mkdir_p, 1);
+ rb_define_method (c_guestfs, "chmod",
+ ruby_guestfs_chmod, 2);
+ rb_define_method (c_guestfs, "chown",
+ ruby_guestfs_chown, 3);
+ rb_define_method (c_guestfs, "exists",
+ ruby_guestfs_exists, 1);
+ rb_define_method (c_guestfs, "is_file",
+ ruby_guestfs_is_file, 1);
+ rb_define_method (c_guestfs, "is_dir",
+ ruby_guestfs_is_dir, 1);
+ rb_define_method (c_guestfs, "pvcreate",
+ ruby_guestfs_pvcreate, 1);
+ rb_define_method (c_guestfs, "vgcreate",
+ ruby_guestfs_vgcreate, 2);
+ rb_define_method (c_guestfs, "lvcreate",
+ ruby_guestfs_lvcreate, 3);
+ rb_define_method (c_guestfs, "mkfs",
+ ruby_guestfs_mkfs, 2);
+ rb_define_method (c_guestfs, "sfdisk",
+ ruby_guestfs_sfdisk, 5);
+ rb_define_method (c_guestfs, "write_file",
+ ruby_guestfs_write_file, 3);
+ rb_define_method (c_guestfs, "umount",
+ ruby_guestfs_umount, 1);
+ rb_define_method (c_guestfs, "mounts",
+ ruby_guestfs_mounts, 0);
+ rb_define_method (c_guestfs, "umount_all",
+ ruby_guestfs_umount_all, 0);
+ rb_define_method (c_guestfs, "lvm_remove_all",
+ ruby_guestfs_lvm_remove_all, 0);
+ rb_define_method (c_guestfs, "file",
+ ruby_guestfs_file, 1);
+ rb_define_method (c_guestfs, "command",
+ ruby_guestfs_command, 1);
+ rb_define_method (c_guestfs, "command_lines",
+ ruby_guestfs_command_lines, 1);
+ rb_define_method (c_guestfs, "stat",
+ ruby_guestfs_stat, 1);
+ rb_define_method (c_guestfs, "lstat",
+ ruby_guestfs_lstat, 1);
+ rb_define_method (c_guestfs, "statvfs",
+ ruby_guestfs_statvfs, 1);
+ rb_define_method (c_guestfs, "tune2fs_l",
+ ruby_guestfs_tune2fs_l, 1);
+ rb_define_method (c_guestfs, "blockdev_setro",
+ ruby_guestfs_blockdev_setro, 1);
+ rb_define_method (c_guestfs, "blockdev_setrw",
+ ruby_guestfs_blockdev_setrw, 1);
+ rb_define_method (c_guestfs, "blockdev_getro",
+ ruby_guestfs_blockdev_getro, 1);
+ rb_define_method (c_guestfs, "blockdev_getss",
+ ruby_guestfs_blockdev_getss, 1);
+ rb_define_method (c_guestfs, "blockdev_getbsz",
+ ruby_guestfs_blockdev_getbsz, 1);
+ rb_define_method (c_guestfs, "blockdev_setbsz",
+ ruby_guestfs_blockdev_setbsz, 2);
+ rb_define_method (c_guestfs, "blockdev_getsz",
+ ruby_guestfs_blockdev_getsz, 1);
+ rb_define_method (c_guestfs, "blockdev_getsize64",
+ ruby_guestfs_blockdev_getsize64, 1);
+ rb_define_method (c_guestfs, "blockdev_flushbufs",
+ ruby_guestfs_blockdev_flushbufs, 1);
+ rb_define_method (c_guestfs, "blockdev_rereadpt",
+ ruby_guestfs_blockdev_rereadpt, 1);
+}
diff --git a/ruby/ext/guestfs/extconf.rb b/ruby/ext/guestfs/extconf.rb
new file mode 100644
index 00000000..67389fd5
--- /dev/null
+++ b/ruby/ext/guestfs/extconf.rb
@@ -0,0 +1,30 @@
+# libguestfs Ruby bindings -*- ruby -*-
+# @configure_input@
+# Copyright (C) 2009 Red Hat Inc.
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'mkmf'
+
+extension_name = '_guestfs'
+
+dir_config(extension_name)
+
+unless have_library("guestfs", "guestfs_create")
+ raise "libguestfs not found"
+end
+
+create_header
+create_makefile(extension_name)
diff --git a/ruby/lib/guestfs.rb b/ruby/lib/guestfs.rb
new file mode 100644
index 00000000..28c3785c
--- /dev/null
+++ b/ruby/lib/guestfs.rb
@@ -0,0 +1,18 @@
+# libvirt Ruby bindings
+# Copyright (C) 2009 Red Hat Inc.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+require '_guestfs'
diff --git a/ruby/run-ruby-tests b/ruby/run-ruby-tests
new file mode 100755
index 00000000..9e8908cc
--- /dev/null
+++ b/ruby/run-ruby-tests
@@ -0,0 +1,22 @@
+#!/bin/sh -
+# libguestfs Ruby bindings
+# Copyright (C) 2009 Red Hat Inc.
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+export LD_LIBRARY_PATH=../src/.libs
+export LIBGUESTFS_PATH=$(cd .. && pwd)
+rake test "$@"
+
diff --git a/ruby/tests/tc_010_load.rb b/ruby/tests/tc_010_load.rb
new file mode 100644
index 00000000..6d882db8
--- /dev/null
+++ b/ruby/tests/tc_010_load.rb
@@ -0,0 +1,28 @@
+# libguestfs Ruby bindings -*- ruby -*-
+# Copyright (C) 2009 Red Hat Inc.
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'test/unit'
+$:.unshift(File::join(File::dirname(__FILE__), "..", "lib"))
+$:.unshift(File::join(File::dirname(__FILE__), "..", "ext", "guestfs"))
+require 'guestfs'
+
+class TestLoad < Test::Unit::TestCase
+ def test_load
+ g = Guestfs::create()
+ assert_not_nil (g)
+ end
+end
diff --git a/ruby/tests/tc_050_lvcreate.rb b/ruby/tests/tc_050_lvcreate.rb
new file mode 100644
index 00000000..ea87e398
--- /dev/null
+++ b/ruby/tests/tc_050_lvcreate.rb
@@ -0,0 +1,49 @@
+# libguestfs Ruby bindings -*- ruby -*-
+# Copyright (C) 2009 Red Hat Inc.
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'test/unit'
+$:.unshift(File::join(File::dirname(__FILE__), "..", "lib"))
+$:.unshift(File::join(File::dirname(__FILE__), "..", "ext", "guestfs"))
+require 'guestfs'
+
+class TestLoad < Test::Unit::TestCase
+ def test_lvcreate
+ g = Guestfs::create()
+
+ File.open("test.img", "w") {
+ |f| f.seek(500*1024*1024); f.write("\0")
+ }
+
+ g.add_drive("test.img")
+ g.launch()
+ g.wait_ready()
+
+ g.pvcreate("/dev/sda")
+ g.vgcreate("VG", ["/dev/sda"]);
+ g.lvcreate("LV1", "VG", 200);
+ g.lvcreate("LV2", "VG", 200);
+
+ lvs = g.lvs()
+ if lvs != ["/dev/VG/LV1", "/dev/VG/LV2"]
+ raise "incorrect lvs returned"
+ end
+
+ g.sync()
+
+ File.unlink("test.img")
+ end
+end
diff --git a/src/generator.ml b/src/generator.ml
index 41fc0c81..c0a47404 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -4863,6 +4863,242 @@ and pod2text ~width name longdesc =
| Unix.WSIGNALED i | Unix.WSTOPPED i ->
failwithf "pod2text: process signalled or stopped by signal %d" i
+(* Generate ruby bindings. *)
+and generate_ruby_c () =
+ generate_header CStyle LGPLv2;
+
+ pr "\
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <ruby.h>
+
+#include \"guestfs.h\"
+
+#include \"extconf.h\"
+
+static VALUE m_guestfs; /* guestfs module */
+static VALUE c_guestfs; /* guestfs_h handle */
+static VALUE e_Error; /* used for all errors */
+
+static void ruby_guestfs_free (void *p)
+{
+ if (!p) return;
+ guestfs_close ((guestfs_h *) p);
+}
+
+static VALUE ruby_guestfs_create (VALUE m)
+{
+ guestfs_h *g;
+
+ g = guestfs_create ();
+ if (!g)
+ rb_raise (e_Error, \"failed to create guestfs handle\");
+
+ /* Don't print error messages to stderr by default. */
+ guestfs_set_error_handler (g, NULL, NULL);
+
+ /* Wrap it, and make sure the close function is called when the
+ * handle goes away.
+ */
+ return Data_Wrap_Struct (c_guestfs, NULL, ruby_guestfs_free, g);
+}
+
+static VALUE ruby_guestfs_close (VALUE gv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+
+ ruby_guestfs_free (g);
+ DATA_PTR (gv) = NULL;
+
+ return Qnil;
+}
+
+";
+
+ List.iter (
+ fun (name, style, _, _, _, _, _) ->
+ pr "static VALUE ruby_guestfs_%s (VALUE gv" name;
+ List.iter (fun arg -> pr ", VALUE %sv" (name_of_argt arg)) (snd style);
+ pr ")\n";
+ pr "{\n";
+ pr " guestfs_h *g;\n";
+ pr " Data_Get_Struct (gv, guestfs_h, g);\n";
+ pr " if (!g)\n";
+ pr " rb_raise (rb_eArgError, \"%%s: used handle after closing it\", \"%s\");\n"
+ name;
+ pr "\n";
+
+ List.iter (
+ function
+ | String n ->
+ pr " const char *%s = StringValueCStr (%sv);\n" n n;
+ pr " if (!%s)\n" n;
+ pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
+ pr " \"%s\", \"%s\");\n" n name
+ | OptString n ->
+ pr " const char *%s = StringValueCStr (%sv);\n" n n
+ | StringList n ->
+ pr " char **%s;" n;
+ pr " {\n";
+ pr " int i, len;\n";
+ pr " len = RARRAY_LEN (%sv);\n" n;
+ pr " %s = malloc (sizeof (char *) * (len+1));\n" n;
+ pr " for (i = 0; i < len; ++i) {\n";
+ pr " VALUE v = rb_ary_entry (%sv, i);\n" n;
+ pr " %s[i] = StringValueCStr (v);\n" n;
+ pr " }\n";
+ pr " }\n";
+ | Bool n
+ | Int n ->
+ pr " int %s = NUM2INT (%sv);\n" n n
+ ) (snd style);
+ pr "\n";
+
+ let error_code =
+ match fst style with
+ | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
+ | RInt64 _ -> pr " int64_t r;\n"; "-1"
+ | RConstString _ -> pr " const char *r;\n"; "NULL"
+ | RString _ -> pr " char *r;\n"; "NULL"
+ | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
+ | RIntBool _ -> pr " struct guestfs_int_bool *r;\n"; "NULL"
+ | RPVList n -> pr " struct guestfs_lvm_pv_list *r;\n"; "NULL"
+ | RVGList n -> pr " struct guestfs_lvm_vg_list *r;\n"; "NULL"
+ | RLVList n -> pr " struct guestfs_lvm_lv_list *r;\n"; "NULL"
+ | RStat n -> pr " struct guestfs_stat *r;\n"; "NULL"
+ | RStatVFS n -> pr " struct guestfs_statvfs *r;\n"; "NULL" in
+ pr "\n";
+
+ pr " r = guestfs_%s " name;
+ generate_call_args ~handle:"g" style;
+ pr ";\n";
+
+ List.iter (
+ function
+ | String _ | OptString _ | Bool _ | Int _ -> ()
+ | StringList n ->
+ pr " free (%s);\n" n
+ ) (snd style);
+
+ pr " if (r == %s)\n" error_code;
+ pr " rb_raise (e_Error, \"%%s\", guestfs_last_error (g));\n";
+ pr "\n";
+
+ (match fst style with
+ | RErr ->
+ pr " return Qnil;\n"
+ | RInt _ | RBool _ ->
+ pr " return INT2NUM (r);\n"
+ | RInt64 _ ->
+ pr " return ULL2NUM (r);\n"
+ | RConstString _ ->
+ pr " return rb_str_new2 (r);\n";
+ | RString _ ->
+ pr " VALUE rv = rb_str_new2 (r);\n";
+ pr " free (r);\n";
+ pr " return rv;\n";
+ | RStringList _ ->
+ pr " int i, len = 0;\n";
+ pr " for (i = 0; r[i] != NULL; ++i) len++;\n";
+ pr " VALUE rv = rb_ary_new2 (len);\n";
+ pr " for (i = 0; r[i] != NULL; ++i) {\n";
+ pr " rb_ary_push (rv, rb_str_new2 (r[i]));\n";
+ pr " free (r[i]);\n";
+ pr " }\n";
+ pr " free (r);\n";
+ pr " return rv;\n"
+ | RIntBool _ ->
+ pr " VALUE rv = rb_ary_new2 (2);\n";
+ pr " rb_ary_push (rv, INT2NUM (r->i));\n";
+ pr " rb_ary_push (rv, INT2NUM (r->b));\n";
+ pr " guestfs_free_int_bool (r);\n";
+ pr " return rv;\n"
+ | RPVList n ->
+ generate_ruby_lvm_code "pv" pv_cols
+ | RVGList n ->
+ generate_ruby_lvm_code "vg" vg_cols
+ | RLVList n ->
+ generate_ruby_lvm_code "lv" lv_cols
+ | RStat n ->
+ pr " VALUE rv = rb_hash_new ();\n";
+ List.iter (
+ function
+ | name, `Int ->
+ pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
+ ) stat_cols;
+ pr " free (r);\n";
+ pr " return rv;\n"
+ | RStatVFS n ->
+ pr " VALUE rv = rb_hash_new ();\n";
+ List.iter (
+ function
+ | name, `Int ->
+ pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
+ ) statvfs_cols;
+ pr " free (r);\n";
+ pr " return rv;\n"
+ | RHashtable _ ->
+ pr " VALUE rv = rb_hash_new ();\n";
+ pr " int i;\n";
+ pr " for (i = 0; r[i] != NULL; i+=2) {\n";
+ pr " rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));\n";
+ pr " free (r[i]);\n";
+ pr " free (r[i+1]);\n";
+ pr " }\n";
+ pr " free (r);\n";
+ pr " return rv;\n"
+ );
+
+ pr "}\n";
+ pr "\n"
+ ) all_functions;
+
+ pr "\
+/* Initialize the module. */
+void Init__guestfs ()
+{
+ m_guestfs = rb_define_module (\"Guestfs\");
+ c_guestfs = rb_define_class_under (m_guestfs, \"Guestfs\", rb_cObject);
+ e_Error = rb_define_class_under (m_guestfs, \"Error\", rb_eStandardError);
+
+ rb_define_module_function (m_guestfs, \"create\", ruby_guestfs_create, 0);
+ rb_define_method (c_guestfs, \"close\", ruby_guestfs_close, 0);
+
+";
+ (* Define the rest of the methods. *)
+ List.iter (
+ fun (name, style, _, _, _, _, _) ->
+ pr " rb_define_method (c_guestfs, \"%s\",\n" name;
+ pr " ruby_guestfs_%s, %d);\n" name (List.length (snd style))
+ ) all_functions;
+
+ pr "}\n"
+
+(* Ruby code to return an LVM struct list. *)
+and generate_ruby_lvm_code typ cols =
+ pr " VALUE rv = rb_ary_new2 (r->len);\n";
+ pr " int i;\n";
+ pr " for (i = 0; i < r->len; ++i) {\n";
+ pr " VALUE hv = rb_hash_new ();\n";
+ List.iter (
+ function
+ | name, `String ->
+ pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name
+ | name, `UUID ->
+ pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name
+ | name, `Bytes
+ | name, `Int ->
+ pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
+ | name, `OptPercent ->
+ pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name
+ ) cols;
+ pr " rb_ary_push (rv, hv);\n";
+ pr " }\n";
+ pr " guestfs_free_lvm_%s_list (r);\n" typ;
+ pr " return rv;\n"
+
let output_to filename =
let filename_new = filename ^ ".new" in
chan := open_out filename_new;
@@ -4962,3 +5198,7 @@ Run it from the top source directory using the command
let close = output_to "python/guestfs.py" in
generate_python_py ();
close ();
+
+ let close = output_to "ruby/ext/guestfs/_guestfs.c" in
+ generate_ruby_c ();
+ close ();