From 37c141d05d2456ccdc19fe1f2f4a36e29e8afe1c Mon Sep 17 00:00:00 2001 From: Richard W.M. Jones Date: Oct 25 2014 22:14:50 +0000 Subject: New upstream version 5.1.11. --- diff --git a/0001-ext2-fix-small-memory-leak-on-error.patch b/0001-ext2-fix-small-memory-leak-on-error.patch deleted file mode 100644 index f4b5643..0000000 --- a/0001-ext2-fix-small-memory-leak-on-error.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b84a7d38902199382a7264cc17be509384940020 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 9 Sep 2014 14:43:02 +0200 -Subject: [PATCH] ext2: fix small memory leak on error - -When failing to read the output of `readlink -f`, free the memory buffer -used for it. ---- - src/ext2fs-c.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/ext2fs-c.c b/src/ext2fs-c.c -index 9e0770a..f3ca7dc 100644 ---- a/src/ext2fs-c.c -+++ b/src/ext2fs-c.c -@@ -631,6 +631,7 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest) - } - if (fgets (new_dirname, PATH_MAX, fp) == NULL) { - pclose (fp); -+ free (new_dirname); - goto cont; - } - pclose (fp); --- -1.9.3 - diff --git a/0002-build-Add-some-more-debug-messages.patch b/0002-build-Add-some-more-debug-messages.patch deleted file mode 100644 index 1f0eeb8..0000000 --- a/0002-build-Add-some-more-debug-messages.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c11daf4e7b254bcb56af4871e0a1b8d27b828486 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 13 Sep 2014 14:41:29 +0100 -Subject: [PATCH] build: Add some more debug messages. - -Allows us to use 'annotate-output supermin -v ...' in order to find -out how long the RPM dependency checking takes. ---- - src/build.ml | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/src/build.ml b/src/build.ml -index 8ff574b..7011731 100644 ---- a/src/build.ml -+++ b/src/build.ml -@@ -86,11 +86,17 @@ let rec build debug - (* Read the supermin appliance, ie. the input files and/or - * directories that make up the appliance. - *) -+ if debug >= 1 then -+ printf "supermin: reading the supermin appliance\n%!"; - let appliance = read_appliance debug basedir empty_appliance inputs in - - (* Resolve dependencies in the list of packages. *) - let ph = get_package_handler () in -+ if debug >= 1 then -+ printf "supermin: mapping package names to installed packages\n%!"; - let packages = filter_map ph.ph_package_of_string appliance.packages in -+ if debug >= 1 then -+ printf "supermin: resolving full list of package dependencies\n%!"; - let packages = - let packages = package_set_of_list packages in - get_all_requires packages in --- -1.9.3 - diff --git a/0003-rpm-Don-t-both-verifying-signatures-and-digests-when.patch b/0003-rpm-Don-t-both-verifying-signatures-and-digests-when.patch deleted file mode 100644 index 7cf193d..0000000 --- a/0003-rpm-Don-t-both-verifying-signatures-and-digests-when.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 7c3984e45b91f8a78530efe6ddfc7a83556892ec Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 15 Sep 2014 13:51:06 +0100 -Subject: [PATCH] rpm: Don't both verifying signatures and digests when reading - RPM metadata. - -supermin doesn't care, and there's a performance penalty for -doing it. - -Thanks: Panu Matilainen ---- - src/rpm.ml | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/src/rpm.ml b/src/rpm.ml -index 434f15b..1195948 100644 ---- a/src/rpm.ml -+++ b/src/rpm.ml -@@ -136,7 +136,7 @@ let rpm_package_of_string str = - * ourselves. *) - let parse_rpm str = - let cmd = -- sprintf "%s -q --qf '%%{name} %%{epoch} %%{version} %%{release} %%{arch}\\n' %s" -+ sprintf "%s --nosignature --nodigest -q --qf '%%{name} %%{epoch} %%{version} %%{release} %%{arch}\\n' %s" - Config.rpm - (quote str) in - let lines = run_command_get_lines cmd in -@@ -177,7 +177,8 @@ let rpm_package_of_string str = - - (* Check if an RPM is installed. *) - and check_rpm_installed name = -- let cmd = sprintf "%s -q %s >/dev/null" Config.rpm (quote name) in -+ let cmd = sprintf "%s --nosignature --nodigest -q %s >/dev/null" -+ Config.rpm (quote name) in - 0 = Sys.command cmd - in - -@@ -227,9 +228,9 @@ let rpm_get_package_database_mtime () = - let rpm_get_all_requires pkgs = - let get pkgs = - let cmd = sprintf "\ -- %s -qR %s | -+ %s --nosignature --nodigest -qR %s | - awk '{print $1}' | -- xargs rpm -q --qf '%%{name}\\n' --whatprovides | -+ xargs rpm --nosignature --nodigest -q --qf '%%{name}\\n' --whatprovides | - grep -v 'no package provides' | - sort -u" - Config.rpm -@@ -251,7 +252,7 @@ let rpm_get_all_requires pkgs = - - let rpm_get_all_files pkgs = - let cmd = sprintf "\ -- %s -q --qf '[%%{FILENAMES}\\t%%{FILEFLAGS:fflags}\\n]' %s | -+ %s --nosignature --nodigest -q --qf '[%%{FILENAMES}\\t%%{FILEFLAGS:fflags}\\n]' %s | - grep '^/' | - sort -u" - Config.rpm --- -1.9.3 - diff --git a/0004-Use-open_process_full-in-compressed-file-reading.patch b/0004-Use-open_process_full-in-compressed-file-reading.patch deleted file mode 100644 index f61d72a..0000000 --- a/0004-Use-open_process_full-in-compressed-file-reading.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 68bc5e82e4892f981b1d5409ec217518749c4b61 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 17 Sep 2014 12:59:54 +0200 -Subject: [PATCH] Use open_process_full in compressed file reading - -Since only few bytes of the compressed file are read, closing the stdout -of the process will cause it to complain about that. -Switch to open_process_full instead of open_process_in, so we can close -also stderr and avoid that harmless error message. ---- - src/build.ml | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/build.ml b/src/build.ml -index 7011731..500ce33 100644 ---- a/src/build.ml -+++ b/src/build.ml -@@ -322,13 +322,13 @@ and get_file_content file buf len = - - and get_compressed_file_content zcat file = - let cmd = sprintf "%s %s" zcat (quote file) in -- let chan = open_process_in cmd in -+ let chan_out, chan_in, chan_err = open_process_full cmd [||] in - let buf = String.create 512 in -- let len = input chan buf 0 (String.length buf) in -+ let len = input chan_out buf 0 (String.length buf) in - (* We're expecting the subprocess to fail because we close the pipe - * early, so: - *) -- ignore (close_process_in chan); -+ ignore (Unix.close_process_full (chan_out, chan_in, chan_err)); - - get_file_content file buf len - --- -1.9.3 - diff --git a/0005-package-handlers-add-possibility-for-final-teardown.patch b/0005-package-handlers-add-possibility-for-final-teardown.patch deleted file mode 100644 index 4de1814..0000000 --- a/0005-package-handlers-add-possibility-for-final-teardown.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 57cb5a62439cc0e4b59d4d19ee1d7e0ffdb4ba26 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 17 Sep 2014 13:07:24 +0200 -Subject: [PATCH] package handlers: add possibility for final teardown - -Add a ph_fini callback to package handlers, so they can do teardown -operations, if needed, at the very end of the supermin run. - -Currently all of the current package handlers do nothing. ---- - src/dpkg.ml | 1 + - src/package_handler.ml | 5 +++++ - src/package_handler.mli | 7 +++++++ - src/pacman.ml | 1 + - src/rpm.ml | 1 + - src/supermin.ml | 4 +++- - 6 files changed, 18 insertions(+), 1 deletion(-) - -diff --git a/src/dpkg.ml b/src/dpkg.ml -index 1bb3f7f..ddfb03a 100644 ---- a/src/dpkg.ml -+++ b/src/dpkg.ml -@@ -191,6 +191,7 @@ let () = - let ph = { - ph_detect = dpkg_detect; - ph_init = dpkg_init; -+ ph_fini = (fun () -> ()); - ph_package_of_string = dpkg_package_of_string; - ph_package_to_string = dpkg_package_to_string; - ph_package_name = dpkg_package_name; -diff --git a/src/package_handler.ml b/src/package_handler.ml -index b1dffc0..64b8f66 100644 ---- a/src/package_handler.ml -+++ b/src/package_handler.ml -@@ -59,6 +59,7 @@ let file_source file = - type package_handler = { - ph_detect : unit -> bool; - ph_init : settings -> unit; -+ ph_fini : unit -> unit; - ph_package_of_string : string -> package option; - ph_package_to_string : package -> string; - ph_package_name : package -> string; -@@ -140,6 +141,10 @@ let rec get_package_handler_name () = - | Some (system, packager, _) -> sprintf "%s/%s" system packager - | None -> assert false - -+let package_handler_shutdown () = -+ let ph = get_package_handler () in -+ ph.ph_fini () -+ - let get_all_requires pkgs = - let ph = get_package_handler () in - match ph.ph_get_requires with -diff --git a/src/package_handler.mli b/src/package_handler.mli -index 7e17981..43b0c08 100644 ---- a/src/package_handler.mli -+++ b/src/package_handler.mli -@@ -99,6 +99,11 @@ type package_handler = { - initializes. The [settings] parameter is a struct of general - settings and configuration. *) - -+ ph_fini : unit -> unit; -+ (** This is called at the end of the supermin processing. It can -+ be used to do teardown operations for the package handler, -+ when no more package-related operations are going to be done. *) -+ - ph_package_of_string : string -> package option; - (** Convert a string (from user input) into a package object. If - the package is not installed or the string is otherwise -@@ -172,6 +177,8 @@ val list_package_handlers : unit -> unit - - val check_system : settings -> unit - -+val package_handler_shutdown : unit -> unit -+ - val get_package_handler : unit -> package_handler - - val get_package_handler_name : unit -> string -diff --git a/src/pacman.ml b/src/pacman.ml -index 8b11ba8..45fb393 100644 ---- a/src/pacman.ml -+++ b/src/pacman.ml -@@ -227,6 +227,7 @@ let () = - let ph = { - ph_detect = pacman_detect; - ph_init = pacman_init; -+ ph_fini = (fun () -> ()); - ph_package_of_string = pacman_package_of_string; - ph_package_to_string = pacman_package_to_string; - ph_package_name = pacman_package_name; -diff --git a/src/rpm.ml b/src/rpm.ml -index 1195948..1bd81f4 100644 ---- a/src/rpm.ml -+++ b/src/rpm.ml -@@ -394,6 +394,7 @@ let () = - let fedora = { - ph_detect = fedora_detect; - ph_init = rpm_init; -+ ph_fini = (fun () -> ()); - ph_package_of_string = rpm_package_of_string; - ph_package_to_string = rpm_package_to_string; - ph_package_name = rpm_package_name; -diff --git a/src/supermin.ml b/src/supermin.ml -index 0153977..2ee61a9 100644 ---- a/src/supermin.ml -+++ b/src/supermin.ml -@@ -261,7 +261,9 @@ let main () = - *) - sprintf "( chmod -R +w %s ; rm -rf %s ) 2>/dev/null &" - (quote old_outputdir) (quote old_outputdir) in -- ignore (Sys.command cmd) -+ ignore (Sys.command cmd); -+ -+ package_handler_shutdown () - - let () = - try main () --- -1.9.3 - diff --git a/0006-rpm-use-the-rpm-library-instead-of-invoking-rpm.patch b/0006-rpm-use-the-rpm-library-instead-of-invoking-rpm.patch deleted file mode 100644 index 4255692..0000000 --- a/0006-rpm-use-the-rpm-library-instead-of-invoking-rpm.patch +++ /dev/null @@ -1,1011 +0,0 @@ -From 5e85a311a866e691715fe4450b53f5655e4d5ae4 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 17 Sep 2014 17:00:11 +0200 -Subject: [PATCH] rpm: use the rpm library instead of invoking rpm - -Look for the rpm library, and use it to query for the information -needed, such as: - - the list of installed packages - - the list of requires for a specified package - - the providers of a specified capability - - the list of files of a package - -Also, rework the dependency resolution, using a queue to iterate on the -packages not resolved yet (thus resolving each package just once), and -caching the provider of each capability. ---- - configure.ac | 4 + - src/Makefile.am | 7 +- - src/librpm-c.c | 483 ++++++++++++++++++++++++++++++++++++++++++++++++ - src/librpm.ml | 51 +++++ - src/librpm.mli | 48 +++++ - src/rpm.ml | 215 +++++++++++---------- - src/supermin-link.sh.in | 2 +- - 7 files changed, 698 insertions(+), 112 deletions(-) - create mode 100644 src/librpm-c.c - create mode 100644 src/librpm.ml - create mode 100644 src/librpm.mli - -diff --git a/configure.ac b/configure.ac -index 65dab78..e604ea2 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -95,6 +95,10 @@ dnl For yum-rpm handler. - AC_PATH_PROG(RPM,[rpm],[no]) - AC_PATH_PROG(RPM2CPIO,[rpm2cpio],[no]) - AC_PATH_PROG(YUMDOWNLOADER,[yumdownloader],[no]) -+PKG_CHECK_MODULES([LIBRPM], [rpm], [librpm=yes], [:]) -+if test "x$librpm" = "xyes"; then -+ AC_DEFINE([HAVE_LIBRPM], [1], [Define if you have librpm]) -+fi - - dnl For Zypper handler. - AC_PATH_PROG(ZYPPER,[zypper],[no]) -diff --git a/src/Makefile.am b/src/Makefile.am -index 90aa773..6261c86 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -42,6 +42,9 @@ SOURCES = \ - realpath-c.c \ - realpath.ml \ - realpath.mli \ -+ librpm-c.c \ -+ librpm.ml \ -+ librpm.mli \ - config.ml \ - utils.ml \ - utils.mli \ -@@ -66,6 +69,7 @@ SOURCES_ML = \ - fnmatch.ml \ - glob.ml \ - realpath.ml \ -+ librpm.ml \ - config.ml \ - utils.ml \ - types.ml \ -@@ -86,6 +90,7 @@ SOURCES_C = \ - ext2init-c.c \ - fnmatch-c.c \ - glob-c.c \ -+ librpm-c.c \ - realpath-c.c - - CLEANFILES = *~ *.cmi *.cmo *.cmx *.o supermin -@@ -98,7 +103,7 @@ bin_PROGRAMS = supermin - supermin_SOURCES = $(SOURCES_C) - supermin_CFLAGS = \ - -I$(shell $(OCAMLC) -where) \ -- $(EXT2FS_CFLAGS) $(COM_ERR_CFLAGS) \ -+ $(EXT2FS_CFLAGS) $(COM_ERR_CFLAGS) $(LIBRPM_CFLAGS) \ - -Wall $(WERROR_CFLAGS) \ - -I$(top_srcdir)/lib -I../lib - -diff --git a/src/librpm-c.c b/src/librpm-c.c -new file mode 100644 -index 0000000..7131de9 ---- /dev/null -+++ b/src/librpm-c.c -@@ -0,0 +1,483 @@ -+/* supermin 5 -+ * Copyright (C) 2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef HAVE_LIBRPM -+ -+#include -+#include -+#include -+#include -+#include -+ -+static rpmlogCallback old_log_callback; -+ -+static int -+supermin_rpm_log_callback (rpmlogRec rec, rpmlogCallbackData data) -+{ -+ fprintf (stderr, "supermin: rpm: lib: %s%s", -+ rpmlogLevelPrefix (rpmlogRecPriority (rec)), -+ rpmlogRecMessage (rec)); -+ return 0; -+} -+ -+struct librpm_data -+{ -+ rpmts ts; -+ int debug; -+}; -+ -+static void librpm_handle_closed (void) __attribute__((noreturn)); -+ -+static void -+librpm_handle_closed (void) -+{ -+ caml_failwith ("librpm: function called on a closed handle"); -+} -+ -+static void -+librpm_raise_multiple_matches (int occurrences) -+{ -+ caml_raise_with_arg (*caml_named_value ("librpm_multiple_matches"), -+ Val_int (occurrences)); -+} -+ -+#define Librpm_val(v) (*((struct librpm_data *)Data_custom_val(v))) -+#define Val_none Val_int(0) -+#define Some_val(v) Field(v,0) -+ -+static void -+librpm_finalize (value rpmv) -+{ -+ struct librpm_data data = Librpm_val (rpmv); -+ -+ if (data.ts) { -+ rpmtsFree (data.ts); -+ -+ rpmlogSetCallback (old_log_callback, NULL); -+ } -+} -+ -+static struct custom_operations librpm_custom_operations = { -+ (char *) "librpm_custom_operations", -+ librpm_finalize, -+ custom_compare_default, -+ custom_hash_default, -+ custom_serialize_default, -+ custom_deserialize_default -+}; -+ -+static value -+Val_librpm (struct librpm_data *data) -+{ -+ CAMLparam0 (); -+ CAMLlocal1 (rpmv); -+ -+ rpmv = caml_alloc_custom (&librpm_custom_operations, -+ sizeof (struct librpm_data), 0, 1); -+ Librpm_val (rpmv) = *data; -+ CAMLreturn (rpmv); -+} -+ -+value -+supermin_rpm_is_available (value unit) -+{ -+ return Val_true; -+} -+ -+value -+supermin_rpm_version (value unit) -+{ -+ return caml_copy_string (RPMVERSION); -+} -+ -+value -+supermin_rpm_open (value debugv) -+{ -+ CAMLparam1 (debugv); -+ CAMLlocal1 (rpmv); -+ struct librpm_data data; -+ int res; -+ rpmlogLvl lvl; -+ -+ data.debug = debugv == Val_none ? 0 : Int_val (Some_val (debugv)); -+ -+ switch (data.debug) { -+ case 3: -+ lvl = RPMLOG_INFO; -+ break; -+ case 2: -+ lvl = RPMLOG_NOTICE; -+ break; -+ case 1: -+ lvl = RPMLOG_WARNING; -+ break; -+ case 0: -+ default: -+ lvl = RPMLOG_ERR; -+ break; -+ } -+ -+ rpmSetVerbosity (lvl); -+ old_log_callback = rpmlogSetCallback (supermin_rpm_log_callback, NULL); -+ -+ res = rpmReadConfigFiles (NULL, NULL); -+ if (res == -1) -+ caml_failwith ("rpm_open: rpmReadConfigFiles failed"); -+ -+ data.ts = rpmtsCreate (); -+ if (data.ts == NULL) -+ caml_failwith ("rpm_open: rpmtsCreate failed"); -+ -+ rpmv = Val_librpm (&data); -+ CAMLreturn (rpmv); -+} -+ -+value -+supermin_rpm_close (value rpmv) -+{ -+ CAMLparam1 (rpmv); -+ -+ librpm_finalize (rpmv); -+ -+ /* So we don't double-free in the finalizer. */ -+ Librpm_val (rpmv).ts = NULL; -+ -+ CAMLreturn (Val_unit); -+} -+ -+value -+supermin_rpm_installed (value rpmv, value pkgv) -+{ -+ CAMLparam2 (rpmv, pkgv); -+ CAMLlocal2 (rv, v); -+ struct librpm_data data; -+ rpmdbMatchIterator iter; -+ int count, i; -+ Header h; -+ -+ data = Librpm_val (rpmv); -+ if (data.ts == NULL) -+ librpm_handle_closed (); -+ -+ iter = rpmtsInitIterator (data.ts, RPMTAG_NAME, String_val (pkgv), 0); -+ if (iter == NULL) -+ caml_raise_not_found (); -+ -+ count = rpmdbGetIteratorCount (iter); -+ if (data.debug >= 2) -+ printf ("supermin: rpm: installed: %d occurrences for '%s'\n", count, String_val (pkgv)); -+ -+ rv = caml_alloc (count, 0); -+ i = 0; -+ -+ while ((h = rpmdbNextIterator (iter)) != NULL) { -+ HeaderIterator hi; -+ rpmtd td; -+ uint32_t *val; -+ bool stored_vals[5] = { false }; -+ -+ v = caml_alloc (5, 0); -+ hi = headerInitIterator (h); -+ td = rpmtdNew (); -+ while (headerNext (hi, td) == 1) { -+ switch (rpmtdTag (td)) { -+ case RPMTAG_NAME: -+ Store_field (v, 0, caml_copy_string (rpmtdGetString (td))); -+ stored_vals[0] = true; -+ break; -+ case RPMTAG_EPOCH: -+ val = rpmtdGetUint32 (td); -+ Store_field (v, 1, Val_int ((int) *val)); -+ stored_vals[1] = true; -+ break; -+ case RPMTAG_VERSION: -+ Store_field (v, 2, caml_copy_string (rpmtdGetString (td))); -+ stored_vals[2] = true; -+ break; -+ case RPMTAG_RELEASE: -+ Store_field (v, 3, caml_copy_string (rpmtdGetString (td))); -+ stored_vals[3] = true; -+ break; -+ case RPMTAG_ARCH: -+ Store_field (v, 4, caml_copy_string (rpmtdGetString (td))); -+ stored_vals[4] = true; -+ break; -+ } -+ rpmtdFreeData (td); -+ } -+ /* Make sure to properly initialize all the fields of the returned -+ * rmp_t, even if some tags are missing in the RPM header. -+ */ -+ if (!stored_vals[0]) -+ Store_field (v, 0, caml_copy_string (String_val (pkgv))); -+ if (!stored_vals[1]) -+ Store_field (v, 1, Val_int (0)); -+ if (!stored_vals[2]) -+ Store_field (v, 2, caml_copy_string ("0")); -+ if (!stored_vals[3]) -+ Store_field (v, 3, caml_copy_string ("unknown")); -+ if (!stored_vals[4]) -+ Store_field (v, 4, caml_copy_string ("unknown")); -+ Store_field (rv, i, v); -+ -+ rpmtdFree (td); -+ headerFreeIterator (hi); -+ ++i; -+ } -+ -+ rpmdbFreeIterator (iter); -+ -+ CAMLreturn (rv); -+} -+ -+value -+supermin_rpm_pkg_requires (value rpmv, value pkgv) -+{ -+ CAMLparam2 (rpmv, pkgv); -+ CAMLlocal1 (rv); -+ struct librpm_data data; -+ rpmdbMatchIterator iter; -+ int count, i; -+ Header h; -+ rpmtd td; -+ -+ data = Librpm_val (rpmv); -+ if (data.ts == NULL) -+ librpm_handle_closed (); -+ -+ iter = rpmtsInitIterator (data.ts, RPMDBI_LABEL, String_val (pkgv), 0); -+ if (iter == NULL) -+ caml_raise_not_found (); -+ -+ count = rpmdbGetIteratorCount (iter); -+ if (data.debug >= 2) -+ printf ("supermin: rpm: pkg_requires: %d occurrences for '%s'\n", count, String_val (pkgv)); -+ if (count != 1) -+ librpm_raise_multiple_matches (count); -+ -+ h = rpmdbNextIterator (iter); -+ assert (h != NULL); -+ -+ td = rpmtdNew (); -+ i = headerGet (h, RPMTAG_REQUIRENAME, td, HEADERGET_MINMEM); -+ if (i != 1) -+ caml_failwith ("rpm_pkg_requires: headerGet failed"); -+ -+ rv = caml_alloc (rpmtdCount (td), 0); -+ for (i = 0; i < rpmtdCount (td); ++i) -+ Store_field (rv, i, caml_copy_string (rpmtdNextString (td))); -+ -+ rpmtdFreeData (td); -+ rpmtdFree (td); -+ -+ rpmdbFreeIterator (iter); -+ -+ CAMLreturn (rv); -+} -+ -+static rpmdbMatchIterator -+createProvidesIterator (rpmts ts, const char *what) -+{ -+ rpmdbMatchIterator mi = NULL; -+ -+ if (what[0] != '/') { -+ mi = rpmtsInitIterator(ts, RPMDBI_PROVIDENAME, what, 0); -+ if (mi != NULL) -+ return mi; -+ } -+ mi = rpmtsInitIterator(ts, RPMDBI_INSTFILENAMES, what, 0); -+ if (mi != NULL) -+ return mi; -+ -+ mi = rpmtsInitIterator(ts, RPMDBI_PROVIDENAME, what, 0); -+ -+ return mi; -+} -+ -+value -+supermin_rpm_pkg_whatprovides (value rpmv, value pkgv) -+{ -+ CAMLparam2 (rpmv, pkgv); -+ CAMLlocal1 (rv); -+ struct librpm_data data; -+ rpmdbMatchIterator iter; -+ int count, i; -+ Header h; -+ -+ data = Librpm_val (rpmv); -+ if (data.ts == NULL) -+ librpm_handle_closed (); -+ -+ iter = createProvidesIterator (data.ts, String_val (pkgv)); -+ if (iter == NULL) -+ caml_raise_not_found (); -+ -+ count = rpmdbGetIteratorCount (iter); -+ if (data.debug >= 2) -+ printf ("supermin: rpm: pkg_whatprovides: %d occurrences for '%s'\n", count, String_val (pkgv)); -+ -+ rv = caml_alloc (count, 0); -+ i = 0; -+ -+ while ((h = rpmdbNextIterator (iter)) != NULL) { -+ rpmtd td; -+ int ret; -+ -+ td = rpmtdNew (); -+ ret = headerGet (h, RPMTAG_NAME, td, HEADERGET_MINMEM); -+ if (ret != 1) -+ caml_failwith ("rpm_pkg_whatprovides: headerGet failed"); -+ -+ Store_field (rv, i, caml_copy_string (rpmtdGetString (td))); -+ -+ rpmtdFreeData (td); -+ rpmtdFree (td); -+ ++i; -+ } -+ -+ rpmdbFreeIterator (iter); -+ -+ CAMLreturn (rv); -+} -+ -+value -+supermin_rpm_pkg_filelist (value rpmv, value pkgv) -+{ -+ CAMLparam2 (rpmv, pkgv); -+ CAMLlocal2 (rv, v); -+ struct librpm_data data; -+ rpmdbMatchIterator iter; -+ int count, i; -+ Header h; -+ rpmfi fi; -+ const rpmfiFlags fiflags = RPMFI_NOHEADER | RPMFI_FLAGS_QUERY | RPMFI_NOFILEDIGESTS; -+ -+ data = Librpm_val (rpmv); -+ if (data.ts == NULL) -+ librpm_handle_closed (); -+ -+ iter = rpmtsInitIterator (data.ts, RPMDBI_LABEL, String_val (pkgv), 0); -+ if (iter == NULL) -+ caml_raise_not_found (); -+ -+ count = rpmdbGetIteratorCount (iter); -+ if (data.debug >= 2) -+ printf ("supermin: rpm: pkg_filelist: %d occurrences for '%s'\n", count, String_val (pkgv)); -+ if (count != 1) -+ librpm_raise_multiple_matches (count); -+ -+ h = rpmdbNextIterator (iter); -+ assert (h != NULL); -+ -+ fi = rpmfiNew (data.ts, h, RPMTAG_BASENAMES, fiflags); -+ -+ count = rpmfiFC (fi); -+ if (count < 0) -+ count = 0; -+ -+ rv = caml_alloc (count, 0); -+ i = 0; -+ -+ fi = rpmfiInit (fi, 0); -+ while (rpmfiNext (fi) >= 0) { -+ const char *fn; -+ -+ v = caml_alloc (2, 0); -+ fn = rpmfiFN(fi); -+ Store_field (v, 0, caml_copy_string (fn)); -+ if (rpmfiFFlags (fi) & RPMFILE_CONFIG) -+ Store_field (v, 1, Val_long (1)); /* FileConfig */ -+ else -+ Store_field (v, 1, Val_long (0)); /* FileNormal */ -+ Store_field (rv, i, v); -+ ++i; -+ } -+ rpmfiFree(fi); -+ -+ rpmdbFreeIterator (iter); -+ -+ CAMLreturn (rv); -+} -+ -+#else -+ -+value -+supermin_rpm_is_available (value unit) -+{ -+ return Val_false; -+} -+ -+value -+supermin_rpm_version (value unit) -+{ -+ abort (); -+} -+ -+value -+supermin_rpm_open (value debugv) -+{ -+ abort (); -+} -+ -+value -+supermin_rpm_close (value rpmv) -+{ -+ abort (); -+} -+ -+value -+supermin_rpm_installed (value rpmv, value pkgv) -+{ -+ abort (); -+} -+ -+value -+supermin_rpm_pkg_required (value rpmv, value pkgv) -+{ -+ abort (); -+} -+ -+value -+supermin_rpm_pkg_whatprovides (value rpmv, value pkgv) -+{ -+ abort (); -+} -+ -+value -+supermin_rpm_pkg_filelist (value rpmv, value pkgv) -+{ -+ abort (); -+} -+ -+#endif -diff --git a/src/librpm.ml b/src/librpm.ml -new file mode 100644 -index 0000000..aa8d367 ---- /dev/null -+++ b/src/librpm.ml -@@ -0,0 +1,51 @@ -+(* supermin 5 -+ * Copyright (C) 2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ *) -+ -+external rpm_is_available : unit -> bool = "supermin_rpm_is_available" -+ -+external rpm_version : unit -> string = "supermin_rpm_version" -+ -+type t -+ -+exception Multiple_matches of int -+ -+external rpm_open : ?debug:int -> t = "supermin_rpm_open" -+external rpm_close : t -> unit = "supermin_rpm_close" -+ -+type rpm_t = { -+ name : string; -+ epoch : int; -+ version : string; -+ release : string; -+ arch : string; -+} -+ -+type rpmfile_t = { -+ filepath : string; -+ filetype : rpmfiletype_t; -+} and rpmfiletype_t = -+ | FileNormal -+ | FileConfig -+ -+external rpm_installed : t -> string -> rpm_t array = "supermin_rpm_installed" -+external rpm_pkg_requires : t -> string -> string array = "supermin_rpm_pkg_requires" -+external rpm_pkg_whatprovides : t -> string -> string array = "supermin_rpm_pkg_whatprovides" -+external rpm_pkg_filelist : t -> string -> rpmfile_t array = "supermin_rpm_pkg_filelist" -+ -+let () = -+ Callback.register_exception "librpm_multiple_matches" (Multiple_matches 0) -diff --git a/src/librpm.mli b/src/librpm.mli -new file mode 100644 -index 0000000..880a038 ---- /dev/null -+++ b/src/librpm.mli -@@ -0,0 +1,48 @@ -+(* supermin 5 -+ * Copyright (C) 2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ *) -+ -+val rpm_is_available : unit -> bool -+ -+val rpm_version : unit -> string -+ -+type t -+ -+exception Multiple_matches of int -+ -+val rpm_open : ?debug:int -> t -+val rpm_close : t -> unit -+ -+type rpm_t = { -+ name : string; -+ epoch : int; -+ version : string; -+ release : string; -+ arch : string; -+} -+ -+type rpmfile_t = { -+ filepath : string; -+ filetype : rpmfiletype_t; -+} and rpmfiletype_t = -+ | FileNormal -+ | FileConfig -+ -+val rpm_installed : t -> string -> rpm_t array -+val rpm_pkg_requires : t -> string -> string array -+val rpm_pkg_whatprovides : t -> string -> string array -+val rpm_pkg_filelist : t -> string -> rpmfile_t array -diff --git a/src/rpm.ml b/src/rpm.ml -index 1bd81f4..3a75ea0 100644 ---- a/src/rpm.ml -+++ b/src/rpm.ml -@@ -21,9 +21,15 @@ open Printf - - open Utils - open Package_handler -+open Librpm -+ -+module StringSet = Set.Make (String) -+ -+let stringset_of_list pkgs = -+ List.fold_left (fun set elem -> StringSet.add elem set) StringSet.empty pkgs - - let fedora_detect () = -- Config.rpm <> "no" && Config.rpm2cpio <> "no" && -+ Config.rpm <> "no" && Config.rpm2cpio <> "no" && rpm_is_available () && - Config.yumdownloader <> "no" && - try - (stat "/etc/redhat-release").st_kind = S_REG || -@@ -31,12 +37,12 @@ let fedora_detect () = - with Unix_error _ -> false - - let opensuse_detect () = -- Config.rpm <> "no" && Config.rpm2cpio <> "no" && -+ Config.rpm <> "no" && Config.rpm2cpio <> "no" && rpm_is_available () && - Config.zypper <> "no" && - try (stat "/etc/SuSE-release").st_kind = S_REG with Unix_error _ -> false - - let mageia_detect () = -- Config.rpm <> "no" && Config.rpm2cpio <> "no" && -+ Config.rpm <> "no" && Config.rpm2cpio <> "no" && rpm_is_available () && - Config.urpmi <> "no" && - Config.fakeroot <> "no" && - try (stat "/etc/mageia-release").st_kind = S_REG with Unix_error _ -> false -@@ -44,6 +50,14 @@ let mageia_detect () = - let settings = ref no_settings - let rpm_major, rpm_minor = ref 0, ref 0 - let zypper_major, zypper_minor, zypper_patch = ref 0, ref 0, ref 0 -+let t = ref None -+ -+let get_rpm () = -+ match !t with -+ | None -> -+ eprintf "supermin: rpm: get_rpm called too early"; -+ exit 1 -+ | Some t -> t - - let rec rpm_init s = - settings := s; -@@ -51,31 +65,26 @@ let rec rpm_init s = - (* Get RPM version. We have to adjust some RPM commands based on - * the version. - *) -- let cmd = sprintf "%s --version | awk '{print $3}'" Config.rpm in -- let lines = run_command_get_lines cmd in -+ let version = rpm_version () in - let major, minor = -- match lines with -+ match string_split "." version with - | [] -> -- eprintf "supermin: rpm --version command had no output\n"; -+ eprintf "supermin: unable to parse empty rpm version string\n"; - exit 1 -- | line :: _ -> -- let line = string_split "." line in -- match line with -- | [] -> -- eprintf "supermin: unable to parse empty output of rpm --version\n"; -- exit 1 -- | [x] -> -- eprintf "supermin: unable to parse output of rpm --version: %s\n" x; -- exit 1 -- | major :: minor :: _ -> -- try int_of_string major, int_of_string minor -- with Failure "int_of_string" -> -- eprintf "supermin: unable to parse output of rpm --version: non-numeric\n"; -- exit 1 in -+ | [x] -> -+ eprintf "supermin: unable to parse rpm version string: %s\n" x; -+ exit 1 -+ | major :: minor :: _ -> -+ try int_of_string major, int_of_string minor -+ with Failure "int_of_string" -> -+ eprintf "supermin: unable to parse rpm version string: non-numeric, %s\n" version; -+ exit 1 in - rpm_major := major; - rpm_minor := minor; - if !settings.debug >= 1 then -- printf "supermin: rpm: detected RPM version %d.%d\n" major minor -+ printf "supermin: rpm: detected RPM version %d.%d\n" major minor; -+ -+ t := Some (rpm_open ~debug:!settings.debug) - - and opensuse_init s = - rpm_init s; -@@ -115,13 +124,10 @@ and opensuse_init s = - if !settings.debug >= 1 then - printf "supermin: rpm: detected zypper version %d.%d.%d\n" major minor patch - --type rpm_t = { -- name : string; -- epoch : int32; -- version : string; -- release : string; -- arch : string; --} -+let rpm_fini () = -+ match !t with -+ | None -> () -+ | Some t -> rpm_close t - - (* Memo from package type to internal rpm_t. *) - let rpm_of_pkg, pkg_of_rpm = get_memo_functions () -@@ -130,38 +136,8 @@ let rpm_of_pkg, pkg_of_rpm = get_memo_functions () - let rpmh = Hashtbl.create 13 - - let rpm_package_of_string str = -- (* Parse an RPM name into the fields like name and version. Since -- * the package is installed (see check below), it's easier to use RPM -- * itself to do this parsing rather than haphazardly parsing it -- * ourselves. *) -- let parse_rpm str = -- let cmd = -- sprintf "%s --nosignature --nodigest -q --qf '%%{name} %%{epoch} %%{version} %%{release} %%{arch}\\n' %s" -- Config.rpm -- (quote str) in -- let lines = run_command_get_lines cmd in -- let lines = List.map (string_split " ") lines in -- let rpms = filter_map ( -- function -- | [ name; ("0"|"(none)"); version; release; arch ] -> -- Some { name = name; -- epoch = 0_l; -- version = version; release = release; arch = arch } -- | [ name; epoch; version; release; arch ] -> -- Some { name = name; -- epoch = Int32.of_string epoch; -- version = version; release = release; arch = arch } -- | xs -> -- (* grrr, RPM doesn't send errors to stderr *) -- None -- ) lines in -- -- if rpms = [] then ( -- eprintf "supermin: no output from rpm command could be parsed when searching for '%s'\nThe command was:\n %s\n" -- str cmd; -- exit 1 -- ); -- -+ let query rpm = -+ let rpms = Array.to_list (rpm_installed (get_rpm ()) str) in - (* RPM will return multiple hits when either multiple versions or - * multiple arches are installed at the same time. We are only - * interested in the highest version with the best -@@ -174,12 +150,6 @@ let rpm_package_of_string str = - in - let rpms = List.sort cmp rpms in - List.hd rpms -- -- (* Check if an RPM is installed. *) -- and check_rpm_installed name = -- let cmd = sprintf "%s --nosignature --nodigest -q %s >/dev/null" -- Config.rpm (quote name) in -- 0 = Sys.command cmd - in - - try -@@ -187,11 +157,8 @@ let rpm_package_of_string str = - with - Not_found -> - let r = -- if check_rpm_installed str then ( -- let rpm = parse_rpm str in -- Some (pkg_of_rpm rpm) -- ) -- else None in -+ try Some (pkg_of_rpm (query str)) -+ with Not_found -> None in - Hashtbl.add rpmh str r; - r - -@@ -212,10 +179,10 @@ let rpm_package_to_string pkg = - !rpm_major < 4 || (!rpm_major = 4 && !rpm_minor < 11) in - - let rpm = rpm_of_pkg pkg in -- if is_rpm_lt_4_11 || rpm.epoch = 0_l then -+ if is_rpm_lt_4_11 || rpm.epoch = 0 then - sprintf "%s-%s-%s.%s" rpm.name rpm.version rpm.release rpm.arch - else -- sprintf "%s-%ld:%s-%s.%s" -+ sprintf "%s-%d:%s-%s.%s" - rpm.name rpm.epoch rpm.version rpm.release rpm.arch - - let rpm_package_name pkg = -@@ -225,47 +192,75 @@ let rpm_package_name pkg = - let rpm_get_package_database_mtime () = - (lstat "/var/lib/rpm/Packages").st_mtime - -+(* Memo of resolved provides. *) -+let rpm_providers = Hashtbl.create 13 -+ - let rpm_get_all_requires pkgs = -- let get pkgs = -- let cmd = sprintf "\ -- %s --nosignature --nodigest -qR %s | -- awk '{print $1}' | -- xargs rpm --nosignature --nodigest -q --qf '%%{name}\\n' --whatprovides | -- grep -v 'no package provides' | -- sort -u" -- Config.rpm -- (quoted_list (List.map rpm_package_to_string -- (PackageSet.elements pkgs))) in -- let lines = run_command_get_lines cmd in -- let lines = filter_map rpm_package_of_string lines in -- PackageSet.union pkgs (package_set_of_list lines) -- in -- (* The command above only gets one level of dependencies. We need -- * to keep iterating until we reach a fixpoint. -- *) -- let rec loop pkgs = -- let pkgs' = get pkgs in -- if PackageSet.equal pkgs pkgs' then pkgs -- else loop pkgs' -+ let get pkg = -+ let reqs = -+ try -+ rpm_pkg_requires (get_rpm ()) pkg -+ with -+ Multiple_matches _ as ex -> -+ match rpm_package_of_string pkg with -+ | None -> raise ex -+ | Some pkg -> -+ rpm_pkg_requires (get_rpm ()) (rpm_package_to_string pkg) in -+ let pkgs' = Array.fold_left ( -+ fun set x -> -+ try -+ let provides = -+ try Hashtbl.find rpm_providers x -+ with Not_found -> rpm_pkg_whatprovides (get_rpm ()) x in -+ let newset = Array.fold_left ( -+ fun newset p -> -+ match rpm_package_of_string p with -+ | None -> newset -+ | Some x -> StringSet.add p newset -+ ) StringSet.empty provides in -+ StringSet.union set newset -+ with Not_found -> set -+ ) StringSet.empty reqs in -+ pkgs' - in -- loop pkgs -+ let queue = Queue.create () in -+ let final = ref (stringset_of_list -+ (List.map rpm_package_name -+ (PackageSet.elements pkgs))) in -+ StringSet.iter (fun x -> Queue.push x queue) !final; -+ let resolved = ref StringSet.empty in -+ while not (Queue.is_empty queue) do -+ let current = Queue.pop queue in -+ if not (StringSet.mem current !resolved) then ( -+ try -+ let expanded = get current in -+ let diff = StringSet.diff expanded !final in -+ if not (StringSet.is_empty diff) then ( -+ final := StringSet.union !final diff; -+ StringSet.iter (fun x -> Queue.push x queue) diff; -+ ) -+ with Not_found -> (); -+ resolved := StringSet.add current !resolved -+ ) -+ done; -+ let pkgs' = filter_map rpm_package_of_string (StringSet.elements !final) in -+ package_set_of_list pkgs' - - let rpm_get_all_files pkgs = -- let cmd = sprintf "\ -- %s --nosignature --nodigest -q --qf '[%%{FILENAMES}\\t%%{FILEFLAGS:fflags}\\n]' %s | -- grep '^/' | -- sort -u" -- Config.rpm -- (quoted_list (List.map rpm_package_to_string (PackageSet.elements pkgs))) in -- let lines = run_command_get_lines cmd in -- let lines = List.map (string_split "\t") lines in -+ let files_compare { filepath = a } { filepath = b } = -+ compare a b in -+ let files = List.map rpm_package_to_string (PackageSet.elements pkgs) in -+ let files = List.fold_right ( -+ fun pkg xs -> -+ let files = Array.to_list (rpm_pkg_filelist (get_rpm ()) pkg) in -+ files @ xs -+ ) files [] in -+ let files = sort_uniq ~cmp:files_compare files in - List.map ( -- function -- | [ path; flags ] -> -- let config = String.contains flags 'c' in -+ fun { filepath = path; filetype = flags } -> -+ let config = flags = FileConfig in - { ft_path = path; ft_source_path = path; ft_config = config } -- | _ -> assert false -- ) lines -+ ) files - - let rec fedora_download_all_packages pkgs dir = - let tdir = !settings.tmpdir // string_random8 () in -@@ -394,7 +389,7 @@ let () = - let fedora = { - ph_detect = fedora_detect; - ph_init = rpm_init; -- ph_fini = (fun () -> ()); -+ ph_fini = rpm_fini; - ph_package_of_string = rpm_package_of_string; - ph_package_to_string = rpm_package_to_string; - ph_package_name = rpm_package_name; -diff --git a/src/supermin-link.sh.in b/src/supermin-link.sh.in -index b2d71d9..29b84a1 100644 ---- a/src/supermin-link.sh.in -+++ b/src/supermin-link.sh.in -@@ -21,4 +21,4 @@ - # Hack automake to link 'supermin' binary properly. There is no other - # way to add the -cclib parameter to the end of the command line. - --exec "$@" -linkpkg -cclib '@EXT2FS_LIBS@ @COM_ERR_LIBS@' -+exec "$@" -linkpkg -cclib '@EXT2FS_LIBS@ @COM_ERR_LIBS@ @LIBRPM_LIBS@' --- -1.9.3 - diff --git a/0007-rpm-fix-typo-in-non-librpm-code.patch b/0007-rpm-fix-typo-in-non-librpm-code.patch deleted file mode 100644 index a88b22a..0000000 --- a/0007-rpm-fix-typo-in-non-librpm-code.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 906fedeed83fe8f1a4e4fd7ec2656e548b83b9c5 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 17 Sep 2014 17:34:59 +0200 -Subject: [PATCH] rpm: fix typo in non-librpm code - -Properly spell the name of a stub function, so it builds fine also with -no rpm library. ---- - src/librpm-c.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/librpm-c.c b/src/librpm-c.c -index 7131de9..e5079b1 100644 ---- a/src/librpm-c.c -+++ b/src/librpm-c.c -@@ -463,7 +463,7 @@ supermin_rpm_installed (value rpmv, value pkgv) - } - - value --supermin_rpm_pkg_required (value rpmv, value pkgv) -+supermin_rpm_pkg_requires (value rpmv, value pkgv) - { - abort (); - } --- -1.9.3 - diff --git a/0008-rpm-reuse-the-rpmtd-when-possible.patch b/0008-rpm-reuse-the-rpmtd-when-possible.patch deleted file mode 100644 index 5fceae1..0000000 --- a/0008-rpm-reuse-the-rpmtd-when-possible.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 3a967a746008001fb9b7ade5451d19a1f1956601 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 18 Sep 2014 16:37:48 +0200 -Subject: [PATCH] rpm: reuse the rpmtd when possible - -Use a single rpmtd object per operation, making sure it is properly -cleaned when needed. This slightly reduces the number of malloc/free's. ---- - src/librpm-c.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/src/librpm-c.c b/src/librpm-c.c -index e5079b1..1ae3bad 100644 ---- a/src/librpm-c.c -+++ b/src/librpm-c.c -@@ -185,6 +185,7 @@ supermin_rpm_installed (value rpmv, value pkgv) - rpmdbMatchIterator iter; - int count, i; - Header h; -+ rpmtd td; - - data = Librpm_val (rpmv); - if (data.ts == NULL) -@@ -200,16 +201,15 @@ supermin_rpm_installed (value rpmv, value pkgv) - - rv = caml_alloc (count, 0); - i = 0; -+ td = rpmtdNew (); - - while ((h = rpmdbNextIterator (iter)) != NULL) { - HeaderIterator hi; -- rpmtd td; - uint32_t *val; - bool stored_vals[5] = { false }; - - v = caml_alloc (5, 0); - hi = headerInitIterator (h); -- td = rpmtdNew (); - while (headerNext (hi, td) == 1) { - switch (rpmtdTag (td)) { - case RPMTAG_NAME: -@@ -251,11 +251,11 @@ supermin_rpm_installed (value rpmv, value pkgv) - Store_field (v, 4, caml_copy_string ("unknown")); - Store_field (rv, i, v); - -- rpmtdFree (td); - headerFreeIterator (hi); - ++i; - } - -+ rpmtdFree (td); - rpmdbFreeIterator (iter); - - CAMLreturn (rv); -@@ -334,6 +334,7 @@ supermin_rpm_pkg_whatprovides (value rpmv, value pkgv) - rpmdbMatchIterator iter; - int count, i; - Header h; -+ rpmtd td; - - data = Librpm_val (rpmv); - if (data.ts == NULL) -@@ -349,12 +350,11 @@ supermin_rpm_pkg_whatprovides (value rpmv, value pkgv) - - rv = caml_alloc (count, 0); - i = 0; -+ td = rpmtdNew (); - - while ((h = rpmdbNextIterator (iter)) != NULL) { -- rpmtd td; - int ret; - -- td = rpmtdNew (); - ret = headerGet (h, RPMTAG_NAME, td, HEADERGET_MINMEM); - if (ret != 1) - caml_failwith ("rpm_pkg_whatprovides: headerGet failed"); -@@ -362,10 +362,10 @@ supermin_rpm_pkg_whatprovides (value rpmv, value pkgv) - Store_field (rv, i, caml_copy_string (rpmtdGetString (td))); - - rpmtdFreeData (td); -- rpmtdFree (td); - ++i; - } - -+ rpmtdFree (td); - rpmdbFreeIterator (iter); - - CAMLreturn (rv); --- -1.9.3 - diff --git a/0009-rpm-reuse-the-same-iteration-set.patch b/0009-rpm-reuse-the-same-iteration-set.patch deleted file mode 100644 index ab0a773..0000000 --- a/0009-rpm-reuse-the-same-iteration-set.patch +++ /dev/null @@ -1,35 +0,0 @@ -From c3638240da5f1b56a807cdf802495704bd395cc2 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 18 Sep 2014 16:58:54 +0200 -Subject: [PATCH] rpm: reuse the same iteration set - -When resolving the requirements of a package, use the same set with the -results, instead of creating a new set and merging it with the results -set. ---- - src/rpm.ml | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/src/rpm.ml b/src/rpm.ml -index 3a75ea0..4c2156a 100644 ---- a/src/rpm.ml -+++ b/src/rpm.ml -@@ -212,13 +212,12 @@ let rpm_get_all_requires pkgs = - let provides = - try Hashtbl.find rpm_providers x - with Not_found -> rpm_pkg_whatprovides (get_rpm ()) x in -- let newset = Array.fold_left ( -+ Array.fold_left ( - fun newset p -> - match rpm_package_of_string p with - | None -> newset - | Some x -> StringSet.add p newset -- ) StringSet.empty provides in -- StringSet.union set newset -+ ) set provides - with Not_found -> set - ) StringSet.empty reqs in - pkgs' --- -1.9.3 - diff --git a/0010-chroot-fix-quoting-in-cp-invocation.patch b/0010-chroot-fix-quoting-in-cp-invocation.patch deleted file mode 100644 index 08f2b9c..0000000 --- a/0010-chroot-fix-quoting-in-cp-invocation.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 73e10157dc90309e9d2cea63e1be3c74ed4aa635 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 29 Sep 2014 16:53:55 +0200 -Subject: [PATCH] chroot: fix quoting in cp invocation - -Make sure to quote source and destination, to avoid failures when -dealing with paths with e.g. spaces, brackets, etc. ---- - src/chroot.ml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/chroot.ml b/src/chroot.ml -index 63a5a79..d0ee4c3 100644 ---- a/src/chroot.ml -+++ b/src/chroot.ml -@@ -60,7 +60,7 @@ let build_chroot debug files outputdir = - - | S_REG | S_CHR | S_BLK | S_FIFO | S_SOCK -> - if debug >= 2 then printf "supermin: chroot: copy %s\n%!" opath; -- let cmd = sprintf "cp -p %s %s" path opath in -+ let cmd = sprintf "cp -p %s %s" (quote path) (quote opath) in - ignore (Sys.command cmd) - with Unix_error _ -> () - ) files; --- -1.9.3 - diff --git a/0011-rpm-use-the-proper-parameter.patch b/0011-rpm-use-the-proper-parameter.patch deleted file mode 100644 index 8835e7f..0000000 --- a/0011-rpm-use-the-proper-parameter.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 17317277c8c7a7051502c975d3aa03d9863ca552 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 7 Oct 2014 10:51:01 +0200 -Subject: [PATCH] rpm: use the proper parameter - ---- - src/rpm.ml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/rpm.ml b/src/rpm.ml -index 4c2156a..b88ac73 100644 ---- a/src/rpm.ml -+++ b/src/rpm.ml -@@ -137,7 +137,7 @@ let rpmh = Hashtbl.create 13 - - let rpm_package_of_string str = - let query rpm = -- let rpms = Array.to_list (rpm_installed (get_rpm ()) str) in -+ let rpms = Array.to_list (rpm_installed (get_rpm ()) rpm) in - (* RPM will return multiple hits when either multiple versions or - * multiple arches are installed at the same time. We are only - * interested in the highest version with the best --- -1.9.3 - diff --git a/0012-rpm-fix-caching-of-provides.patch b/0012-rpm-fix-caching-of-provides.patch deleted file mode 100644 index 48c06ea..0000000 --- a/0012-rpm-fix-caching-of-provides.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 46f987c48296ebd35c153c04488fcf7ee97a41bd Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 7 Oct 2014 11:09:10 +0200 -Subject: [PATCH] rpm: fix caching of provides - -Now each provide is resolved really once. ---- - src/rpm.ml | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/rpm.ml b/src/rpm.ml -index b88ac73..71cdab2 100644 ---- a/src/rpm.ml -+++ b/src/rpm.ml -@@ -211,7 +211,10 @@ let rpm_get_all_requires pkgs = - try - let provides = - try Hashtbl.find rpm_providers x -- with Not_found -> rpm_pkg_whatprovides (get_rpm ()) x in -+ with Not_found -> -+ let p = rpm_pkg_whatprovides (get_rpm ()) x in -+ Hashtbl.add rpm_providers x p; -+ p in - Array.fold_left ( - fun newset p -> - match rpm_package_of_string p with --- -1.9.3 - diff --git a/0013-rpm-check-for-providers-for-not-found-package.patch b/0013-rpm-check-for-providers-for-not-found-package.patch deleted file mode 100644 index 5a0ccc7..0000000 --- a/0013-rpm-check-for-providers-for-not-found-package.patch +++ /dev/null @@ -1,38 +0,0 @@ -From d78c898c7e2bc5f12cbebef98b95a7908d9120f1 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 7 Oct 2014 11:51:15 +0200 -Subject: [PATCH] rpm: check for providers for not found package - -If a package is not found among the ones installed, check whether there -is any other package providing it (only a single one). ---- - src/rpm.ml | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/src/rpm.ml b/src/rpm.ml -index 71cdab2..b5c5ff5 100644 ---- a/src/rpm.ml -+++ b/src/rpm.ml -@@ -158,7 +158,18 @@ let rpm_package_of_string str = - Not_found -> - let r = - try Some (pkg_of_rpm (query str)) -- with Not_found -> None in -+ with Not_found -> -+ try -+ let p = rpm_pkg_whatprovides (get_rpm ()) str in -+ (* Pick only a provided package when there is just one of them, -+ * otherwise there is no reliable way to know which one to pick -+ * if there are multiple providers. -+ *) -+ if Array.length p = 1 then -+ Some (pkg_of_rpm (query p.(0))) -+ else -+ None -+ with Not_found -> None in - Hashtbl.add rpmh str r; - r - --- -1.9.3 - diff --git a/sources b/sources index f9eeefa..415ea9c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -55af45d471987cde51cac4b4181073c5 supermin-5.1.10.tar.gz +5843cd7016022d4944227c3019c8b225 supermin-5.1.11.tar.gz diff --git a/supermin.spec b/supermin.spec index b9a99e2..72b344f 100644 --- a/supermin.spec +++ b/supermin.spec @@ -1,7 +1,7 @@ Summary: Tool for creating supermin appliances Name: supermin -Version: 5.1.10 -Release: 2%{?dist} +Version: 5.1.11 +Release: 1%{?dist} License: GPLv2+ %if 0%{?rhel} >= 7 @@ -11,20 +11,6 @@ ExclusiveArch: x86_64 URL: http://people.redhat.com/~rjones/supermin/ Source0: http://libguestfs.org/download/supermin/%{name}-%{version}.tar.gz -Patch1: 0001-ext2-fix-small-memory-leak-on-error.patch -Patch2: 0002-build-Add-some-more-debug-messages.patch -Patch3: 0003-rpm-Don-t-both-verifying-signatures-and-digests-when.patch -Patch4: 0004-Use-open_process_full-in-compressed-file-reading.patch -Patch5: 0005-package-handlers-add-possibility-for-final-teardown.patch -Patch6: 0006-rpm-use-the-rpm-library-instead-of-invoking-rpm.patch -Patch7: 0007-rpm-fix-typo-in-non-librpm-code.patch -Patch8: 0008-rpm-reuse-the-rpmtd-when-possible.patch -Patch9: 0009-rpm-reuse-the-same-iteration-set.patch -Patch10: 0010-chroot-fix-quoting-in-cp-invocation.patch -Patch11: 0011-rpm-use-the-proper-parameter.patch -Patch12: 0012-rpm-fix-caching-of-provides.patch -Patch13: 0013-rpm-check-for-providers-for-not-found-package.patch - BuildRequires: /usr/bin/pod2man BuildRequires: rpm BuildRequires: rpm-devel @@ -36,9 +22,6 @@ BuildRequires: glibc-static, zlib-static BuildRequires: xz-static, xz-devel BuildRequires: ocaml, ocaml-findlib-devel -# autoreconf during build, since the patches change configure.ac -BuildRequires: automake, autoconf - # These are required only to run the tests. We could patch out the # tests to not require these packages. BuildRequires: augeas hivex kernel tar @@ -70,10 +53,6 @@ second when you need to boot one of them. %prep %setup -q -%autopatch -p1 - -autoreconf -i - %build %configure --disable-network-tests @@ -106,6 +85,9 @@ make check || { %changelog +* Sat Oct 25 2014 Richard W.M. Jones - 5.1.11-1 +- New upstream version 5.1.11. + * Tue Oct 7 2014 Pino Toscano - 5.1.10-2 - Update to upstream commit d78c898c7e2bc5f12cbebef98b95a7908d9120f1. - BR rpm-devel, since it is now used instead of invoking rpm.