|
|
57a8ef |
From 57df7233ae3789f525b8d7e910bf1e3ffe50ac87 Mon Sep 17 00:00:00 2001
|
|
|
57a8ef |
From: Robert Marshall <rmarshall@redhat.com>
|
|
|
57a8ef |
Date: Mon, 16 Mar 2015 14:14:19 -0400
|
|
|
23d2ea |
Subject: [PATCH 156/198] Use Distribution Package Sort for grub2-mkconfig
|
|
|
57a8ef |
(#1124074)
|
|
|
57a8ef |
|
|
|
57a8ef |
Users reported that newly installed kernels on their systems installed
|
|
|
57a8ef |
with grub-mkconfig would not appear on the grub boot list in order
|
|
|
57a8ef |
starting with the most recent. Added an option for rpm-based systems to
|
|
|
57a8ef |
use the rpm-sort library to sort kernels instead.
|
|
|
57a8ef |
|
|
|
57a8ef |
Resolves rhbz#1124074
|
|
|
57a8ef |
---
|
|
|
57a8ef |
.gitignore | 1 +
|
|
|
57a8ef |
Makefile.util.def | 16 +++
|
|
|
57a8ef |
configure.ac | 29 +++++
|
|
|
57a8ef |
util/grub-mkconfig_lib.in | 8 +-
|
|
|
57a8ef |
util/grub-rpm-sort.8 | 12 ++
|
|
|
57a8ef |
util/grub-rpm-sort.c | 281 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
57a8ef |
6 files changed, 346 insertions(+), 1 deletion(-)
|
|
|
57a8ef |
create mode 100644 util/grub-rpm-sort.8
|
|
|
57a8ef |
create mode 100644 util/grub-rpm-sort.c
|
|
|
57a8ef |
|
|
|
57a8ef |
diff --git a/.gitignore b/.gitignore
|
|
|
57a8ef |
index 18ab8e8..b6c4577 100644
|
|
|
57a8ef |
--- a/.gitignore
|
|
|
57a8ef |
+++ b/.gitignore
|
|
|
57a8ef |
@@ -237,6 +237,7 @@ po/POTFILES.in
|
|
|
57a8ef |
po/POTFILES-shell.in
|
|
|
57a8ef |
/grub-glue-efi
|
|
|
57a8ef |
/grub-render-label
|
|
|
57a8ef |
+grub-rpm-sort
|
|
|
57a8ef |
/grub-glue-efi.exe
|
|
|
57a8ef |
/grub-render-label.exe
|
|
|
57a8ef |
grub-core/gnulib/locale.h
|
|
|
57a8ef |
diff --git a/Makefile.util.def b/Makefile.util.def
|
|
|
57a8ef |
index 87029a1..3ac7572 100644
|
|
|
57a8ef |
--- a/Makefile.util.def
|
|
|
57a8ef |
+++ b/Makefile.util.def
|
|
|
57a8ef |
@@ -675,6 +675,22 @@ program = {
|
|
|
57a8ef |
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
|
|
57a8ef |
};
|
|
|
57a8ef |
|
|
|
57a8ef |
+program = {
|
|
|
57a8ef |
+ name = grub-rpm-sort;
|
|
|
57a8ef |
+ mansection = 8;
|
|
|
57a8ef |
+ installdir = sbin;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ common = grub-core/kern/emu/misc.c;
|
|
|
57a8ef |
+ common = grub-core/kern/emu/argp_common.c;
|
|
|
57a8ef |
+ common = grub-core/osdep/init.c;
|
|
|
57a8ef |
+ common = util/misc.c;
|
|
|
57a8ef |
+ common = util/grub-rpm-sort.c;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ ldadd = grub-core/gnulib/libgnu.a;
|
|
|
57a8ef |
+ ldadd = libgrubkern.a;
|
|
|
57a8ef |
+ ldadd = '$(LIBDEVMAPPER) $(LIBRPM)';
|
|
|
57a8ef |
+};
|
|
|
57a8ef |
+
|
|
|
57a8ef |
script = {
|
|
|
57a8ef |
name = grub-mkconfig;
|
|
|
57a8ef |
common = util/grub-mkconfig.in;
|
|
|
57a8ef |
diff --git a/configure.ac b/configure.ac
|
|
|
57a8ef |
index 048ce7c..de17e65 100644
|
|
|
57a8ef |
--- a/configure.ac
|
|
|
57a8ef |
+++ b/configure.ac
|
|
|
57a8ef |
@@ -65,6 +65,7 @@ grub_TRANSFORM([grub-mkrelpath])
|
|
|
57a8ef |
grub_TRANSFORM([grub-mkrescue])
|
|
|
57a8ef |
grub_TRANSFORM([grub-probe])
|
|
|
57a8ef |
grub_TRANSFORM([grub-reboot])
|
|
|
57a8ef |
+grub_TRANSFORM([grub-rpm-sort])
|
|
|
57a8ef |
grub_TRANSFORM([grub-script-check])
|
|
|
57a8ef |
grub_TRANSFORM([grub-set-default])
|
|
|
57a8ef |
grub_TRANSFORM([grub-sparc64-setup])
|
|
|
57a8ef |
@@ -89,6 +90,7 @@ grub_TRANSFORM([grub-mkrescue.1])
|
|
|
57a8ef |
grub_TRANSFORM([grub-mkstandalone.3])
|
|
|
57a8ef |
grub_TRANSFORM([grub-ofpathname.3])
|
|
|
57a8ef |
grub_TRANSFORM([grub-probe.3])
|
|
|
57a8ef |
+grub_TRANSFORM([grub-rpm-sort.8])
|
|
|
57a8ef |
grub_TRANSFORM([grub-reboot.3])
|
|
|
57a8ef |
grub_TRANSFORM([grub-render-label.3])
|
|
|
57a8ef |
grub_TRANSFORM([grub-script-check.3])
|
|
|
57a8ef |
@@ -1543,6 +1545,33 @@ fi
|
|
|
57a8ef |
|
|
|
57a8ef |
AC_SUBST([LIBDEVMAPPER])
|
|
|
57a8ef |
|
|
|
57a8ef |
+AC_ARG_ENABLE([rpm-sort],
|
|
|
57a8ef |
+ [AS_HELP_STRING([--enable-rpm-sort],
|
|
|
57a8ef |
+ [enable native rpm sorting of kernels in grub (default=guessed)])])
|
|
|
57a8ef |
+if test x"$enable_rpm-sort" = xno ; then
|
|
|
57a8ef |
+ rpm_sort_excuse="explicitly disabled"
|
|
|
57a8ef |
+fi
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+if test x"$rpm_sort_excuse" = x ; then
|
|
|
57a8ef |
+ # Check for rpmlib header.
|
|
|
57a8ef |
+ AC_CHECK_HEADER([rpm/rpmlib.h], [],
|
|
|
57a8ef |
+ [rpm_sort_excuse="need rpm/rpmlib header"])
|
|
|
57a8ef |
+fi
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+if test x"$rpm_sort_excuse" = x ; then
|
|
|
57a8ef |
+ # Check for rpm library.
|
|
|
57a8ef |
+ AC_CHECK_LIB([rpm], [rpmvercmp], [],
|
|
|
57a8ef |
+ [rpm_sort_excuse="rpmlib missing rpmvercmp"])
|
|
|
57a8ef |
+fi
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+if test x"$rpm_sort_excuse" = x ; then
|
|
|
57a8ef |
+ LIBRPM="-lrpm";
|
|
|
57a8ef |
+ AC_DEFINE([HAVE_RPM], [1],
|
|
|
57a8ef |
+ [Define to 1 if you have the rpm library.])
|
|
|
57a8ef |
+fi
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+AC_SUBST([LIBRPM])
|
|
|
57a8ef |
+
|
|
|
57a8ef |
LIBGEOM=
|
|
|
57a8ef |
if test x$host_kernel = xkfreebsd; then
|
|
|
57a8ef |
AC_CHECK_LIB([geom], [geom_gettree], [],
|
|
|
57a8ef |
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
|
|
|
57a8ef |
index 5c9ed84..e85b60c 100644
|
|
|
57a8ef |
--- a/util/grub-mkconfig_lib.in
|
|
|
57a8ef |
+++ b/util/grub-mkconfig_lib.in
|
|
|
57a8ef |
@@ -213,6 +213,12 @@ version_sort ()
|
|
|
57a8ef |
esac
|
|
|
57a8ef |
}
|
|
|
57a8ef |
|
|
|
57a8ef |
+if [ "x$RPMLIB" = x ]; then
|
|
|
57a8ef |
+ kernel_sort=version_sort
|
|
|
57a8ef |
+else
|
|
|
57a8ef |
+ kernel_sort="${sbindir}/grub-rpm-sort"
|
|
|
57a8ef |
+fi
|
|
|
57a8ef |
+
|
|
|
57a8ef |
version_test_numeric ()
|
|
|
57a8ef |
{
|
|
|
57a8ef |
version_test_numeric_a="$1"
|
|
|
57a8ef |
@@ -229,7 +235,7 @@ version_test_numeric ()
|
|
|
57a8ef |
version_test_numeric_a="$version_test_numeric_b"
|
|
|
57a8ef |
version_test_numeric_b="$version_test_numeric_c"
|
|
|
57a8ef |
fi
|
|
|
57a8ef |
- if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
|
|
|
57a8ef |
+ if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | "$kernel_sort" | head -n 1 | grep -qx "$version_test_numeric_b" ; then
|
|
|
57a8ef |
return 0
|
|
|
57a8ef |
else
|
|
|
57a8ef |
return 1
|
|
|
57a8ef |
diff --git a/util/grub-rpm-sort.8 b/util/grub-rpm-sort.8
|
|
|
57a8ef |
new file mode 100644
|
|
|
57a8ef |
index 0000000..8ce2148
|
|
|
57a8ef |
--- /dev/null
|
|
|
57a8ef |
+++ b/util/grub-rpm-sort.8
|
|
|
57a8ef |
@@ -0,0 +1,12 @@
|
|
|
57a8ef |
+.TH GRUB-RPM-SORT 8 "Wed Feb 26 2014"
|
|
|
57a8ef |
+.SH NAME
|
|
|
57a8ef |
+\fBgrub-rpm-sort\fR \(em Sort input according to RPM version compare.
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+.SH SYNOPSIS
|
|
|
57a8ef |
+\fBgrub-rpm-sort\fR [OPTIONS].
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+.SH DESCRIPTION
|
|
|
57a8ef |
+You should not normally run this program directly. Use grub-mkconfig instead.
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+.SH SEE ALSO
|
|
|
57a8ef |
+.BR "info grub"
|
|
|
57a8ef |
diff --git a/util/grub-rpm-sort.c b/util/grub-rpm-sort.c
|
|
|
57a8ef |
new file mode 100644
|
|
|
57a8ef |
index 0000000..f33bd1e
|
|
|
57a8ef |
--- /dev/null
|
|
|
57a8ef |
+++ b/util/grub-rpm-sort.c
|
|
|
57a8ef |
@@ -0,0 +1,281 @@
|
|
|
57a8ef |
+#include <config.h>
|
|
|
57a8ef |
+#include <grub/types.h>
|
|
|
57a8ef |
+#include <grub/util/misc.h>
|
|
|
57a8ef |
+#include <stdio.h>
|
|
|
57a8ef |
+#include <stdlib.h>
|
|
|
57a8ef |
+#include <unistd.h>
|
|
|
57a8ef |
+#include <errno.h>
|
|
|
57a8ef |
+#include <assert.h>
|
|
|
57a8ef |
+#include <argp.h>
|
|
|
57a8ef |
+#include <rpm/rpmlib.h>
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+static size_t
|
|
|
57a8ef |
+read_file (const char *input, char **ret)
|
|
|
57a8ef |
+{
|
|
|
57a8ef |
+ FILE *in;
|
|
|
57a8ef |
+ size_t s;
|
|
|
57a8ef |
+ size_t sz = 2048;
|
|
|
57a8ef |
+ size_t offset = 0;
|
|
|
57a8ef |
+ char *text;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (!strcmp(input, "-"))
|
|
|
57a8ef |
+ in = stdin;
|
|
|
57a8ef |
+ else
|
|
|
57a8ef |
+ in = grub_util_fopen(input, "r");
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ text = xmalloc (sz);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (!in)
|
|
|
57a8ef |
+ grub_util_error (_("cannot open `%s': %s"), input, strerror (errno));
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ while ((s = fread (text + offset, 1, sz - offset, in)) != 0)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ offset += s;
|
|
|
57a8ef |
+ if (sz - offset == 0)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ sz += 2048;
|
|
|
57a8ef |
+ text = xrealloc (text, sz);
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ text[offset] = '\0';
|
|
|
57a8ef |
+ *ret = text;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (in != stdin)
|
|
|
57a8ef |
+ fclose(in);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ return offset + 1;
|
|
|
57a8ef |
+}
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+/* returns name/version/release */
|
|
|
57a8ef |
+/* NULL string pointer returned if nothing found */
|
|
|
57a8ef |
+static void
|
|
|
57a8ef |
+split_package_string (char *package_string, char **name,
|
|
|
57a8ef |
+ char **version, char **release)
|
|
|
57a8ef |
+{
|
|
|
57a8ef |
+ char *package_version, *package_release;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* Release */
|
|
|
57a8ef |
+ package_release = strrchr (package_string, '-');
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (package_release != NULL)
|
|
|
57a8ef |
+ *package_release++ = '\0';
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ *release = package_release;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* Version */
|
|
|
57a8ef |
+ package_version = strrchr(package_string, '-');
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (package_version != NULL)
|
|
|
57a8ef |
+ *package_version++ = '\0';
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ *version = package_version;
|
|
|
57a8ef |
+ /* Name */
|
|
|
57a8ef |
+ *name = package_string;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* Bubble up non-null values from release to name */
|
|
|
57a8ef |
+ if (*name == NULL)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ *name = (*version == NULL ? *release : *version);
|
|
|
57a8ef |
+ *version = *release;
|
|
|
57a8ef |
+ *release = NULL;
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+ if (*version == NULL)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ *version = *release;
|
|
|
57a8ef |
+ *release = NULL;
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+}
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+/*
|
|
|
57a8ef |
+ * package name-version-release comparator for qsort
|
|
|
57a8ef |
+ * expects p, q which are pointers to character strings (char *)
|
|
|
57a8ef |
+ * which will not be altered in this function
|
|
|
57a8ef |
+ */
|
|
|
57a8ef |
+static int
|
|
|
57a8ef |
+package_version_compare (const void *p, const void *q)
|
|
|
57a8ef |
+{
|
|
|
57a8ef |
+ char *local_p, *local_q;
|
|
|
57a8ef |
+ char *lhs_name, *lhs_version, *lhs_release;
|
|
|
57a8ef |
+ char *rhs_name, *rhs_version, *rhs_release;
|
|
|
57a8ef |
+ int vercmpflag = 0;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ local_p = alloca (strlen (*(char * const *)p) + 1);
|
|
|
57a8ef |
+ local_q = alloca (strlen (*(char * const *)q) + 1);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* make sure these allocated */
|
|
|
57a8ef |
+ assert (local_p);
|
|
|
57a8ef |
+ assert (local_q);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ strcpy (local_p, *(char * const *)p);
|
|
|
57a8ef |
+ strcpy (local_q, *(char * const *)q);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ split_package_string (local_p, &lhs_name, &lhs_version, &lhs_release);
|
|
|
57a8ef |
+ split_package_string (local_q, &rhs_name, &rhs_version, &rhs_release);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* Check Name and return if unequal */
|
|
|
57a8ef |
+ vercmpflag = rpmvercmp ((lhs_name == NULL ? "" : lhs_name),
|
|
|
57a8ef |
+ (rhs_name == NULL ? "" : rhs_name));
|
|
|
57a8ef |
+ if (vercmpflag != 0)
|
|
|
57a8ef |
+ return vercmpflag;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* Check version and return if unequal */
|
|
|
57a8ef |
+ vercmpflag = rpmvercmp ((lhs_version == NULL ? "" : lhs_version),
|
|
|
57a8ef |
+ (rhs_version == NULL ? "" : rhs_version));
|
|
|
57a8ef |
+ if (vercmpflag != 0)
|
|
|
57a8ef |
+ return vercmpflag;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* Check release and return the version compare value */
|
|
|
57a8ef |
+ vercmpflag = rpmvercmp ((lhs_release == NULL ? "" : lhs_release),
|
|
|
57a8ef |
+ (rhs_release == NULL ? "" : rhs_release));
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ return vercmpflag;
|
|
|
57a8ef |
+}
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+static void
|
|
|
57a8ef |
+add_input (const char *filename, char ***package_names, size_t *n_package_names)
|
|
|
57a8ef |
+{
|
|
|
57a8ef |
+ char *orig_input_buffer = NULL;
|
|
|
57a8ef |
+ char *input_buffer;
|
|
|
57a8ef |
+ char *position_of_newline;
|
|
|
57a8ef |
+ char **names = *package_names;
|
|
|
57a8ef |
+ char **new_names = NULL;
|
|
|
57a8ef |
+ size_t n_names = *n_package_names;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (!*package_names)
|
|
|
57a8ef |
+ new_names = names = xmalloc (sizeof (char *) * 2);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (read_file (filename, &orig_input_buffer) < 2)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ if (new_names)
|
|
|
57a8ef |
+ free (new_names);
|
|
|
57a8ef |
+ if (orig_input_buffer)
|
|
|
57a8ef |
+ free (orig_input_buffer);
|
|
|
57a8ef |
+ return;
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ input_buffer = orig_input_buffer;
|
|
|
57a8ef |
+ while (input_buffer && *input_buffer &&
|
|
|
57a8ef |
+ (position_of_newline = strchrnul (input_buffer, '\n')))
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ size_t sz = position_of_newline - input_buffer;
|
|
|
57a8ef |
+ char *new;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (sz == 0)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ input_buffer = position_of_newline + 1;
|
|
|
57a8ef |
+ continue;
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ new = xmalloc (sz+1);
|
|
|
57a8ef |
+ strncpy (new, input_buffer, sz);
|
|
|
57a8ef |
+ new[sz] = '\0';
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ names = xrealloc (names, sizeof (char *) * (n_names + 1));
|
|
|
57a8ef |
+ names[n_names] = new;
|
|
|
57a8ef |
+ n_names++;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* move buffer ahead to next line */
|
|
|
57a8ef |
+ input_buffer = position_of_newline + 1;
|
|
|
57a8ef |
+ if (*position_of_newline == '\0')
|
|
|
57a8ef |
+ input_buffer = NULL;
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ free (orig_input_buffer);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ *package_names = names;
|
|
|
57a8ef |
+ *n_package_names = n_names;
|
|
|
57a8ef |
+}
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+static char *
|
|
|
57a8ef |
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
|
|
|
57a8ef |
+{
|
|
|
57a8ef |
+ return (char *)text;
|
|
|
57a8ef |
+}
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+static struct argp_option options[] = {
|
|
|
57a8ef |
+ { 0, }
|
|
|
57a8ef |
+};
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+struct arguments
|
|
|
57a8ef |
+{
|
|
|
57a8ef |
+ size_t ninputs;
|
|
|
57a8ef |
+ size_t input_max;
|
|
|
57a8ef |
+ char **inputs;
|
|
|
57a8ef |
+};
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+static error_t
|
|
|
57a8ef |
+argp_parser (int key, char *arg, struct argp_state *state)
|
|
|
57a8ef |
+{
|
|
|
57a8ef |
+ struct arguments *arguments = state->input;
|
|
|
57a8ef |
+ switch (key)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ case ARGP_KEY_ARG:
|
|
|
57a8ef |
+ assert (arguments->ninputs < arguments->input_max);
|
|
|
57a8ef |
+ arguments->inputs[arguments->ninputs++] = xstrdup (arg);
|
|
|
57a8ef |
+ break;
|
|
|
57a8ef |
+ default:
|
|
|
57a8ef |
+ return ARGP_ERR_UNKNOWN;
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+ return 0;
|
|
|
57a8ef |
+}
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+static struct argp argp = {
|
|
|
57a8ef |
+ options, argp_parser, N_("[INPUT_FILES]"),
|
|
|
57a8ef |
+ N_("Sort a list of strings in RPM version sort order."),
|
|
|
57a8ef |
+ NULL, help_filter, NULL
|
|
|
57a8ef |
+};
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+int
|
|
|
57a8ef |
+main (int argc, char *argv[])
|
|
|
57a8ef |
+{
|
|
|
57a8ef |
+ struct arguments arguments;
|
|
|
57a8ef |
+ char **package_names = NULL;
|
|
|
57a8ef |
+ size_t n_package_names = 0;
|
|
|
57a8ef |
+ int i;
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ grub_util_host_init (&argc, &argv);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ memset (&arguments, 0, sizeof (struct arguments));
|
|
|
57a8ef |
+ arguments.input_max = argc+1;
|
|
|
57a8ef |
+ arguments.inputs = xmalloc ((arguments.input_max + 1)
|
|
|
57a8ef |
+ * sizeof (arguments.inputs[0]));
|
|
|
57a8ef |
+ memset (arguments.inputs, 0, (arguments.input_max + 1)
|
|
|
57a8ef |
+ * sizeof (arguments.inputs[0]));
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* Parse our arguments */
|
|
|
57a8ef |
+ if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
|
|
|
57a8ef |
+ grub_util_error ("%s", _("Error in parsing command line arguments\n"));
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* If there's no inputs in argv, add one for stdin */
|
|
|
57a8ef |
+ if (!arguments.ninputs)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ arguments.ninputs = 1;
|
|
|
57a8ef |
+ arguments.inputs[0] = xmalloc (2);
|
|
|
57a8ef |
+ strcpy(arguments.inputs[0], "-");
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ for (i = 0; i < arguments.ninputs; i++)
|
|
|
57a8ef |
+ add_input(arguments.inputs[i], &package_names, &n_package_names);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ if (package_names == NULL || n_package_names < 1)
|
|
|
57a8ef |
+ grub_util_error ("%s", _("Invalid input\n"));
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ qsort (package_names, n_package_names, sizeof (char *),
|
|
|
57a8ef |
+ package_version_compare);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ /* send sorted list to stdout */
|
|
|
57a8ef |
+ for (i = 0; i < n_package_names; i++)
|
|
|
57a8ef |
+ {
|
|
|
57a8ef |
+ fprintf (stdout, "%s\n", package_names[i]);
|
|
|
57a8ef |
+ free (package_names[i]);
|
|
|
57a8ef |
+ }
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ free (package_names);
|
|
|
57a8ef |
+ for (i = 0; i < arguments.ninputs; i++)
|
|
|
57a8ef |
+ free (arguments.inputs[i]);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ free (arguments.inputs);
|
|
|
57a8ef |
+
|
|
|
57a8ef |
+ return 0;
|
|
|
57a8ef |
+}
|
|
|
57a8ef |
--
|
|
|
23d2ea |
2.7.4
|
|
|
57a8ef |
|