summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2018-01-24 13:21:47 +0100
committerRemi Collet <remi@remirepo.net>2018-01-24 13:21:47 +0100
commit88e8bef6b42bbd1a831e5c8a37e0567251df83bb (patch)
tree04918715f782ef0312e92d21a99dd2096dec5969
initial work, only PoC for now
-rw-r--r--.gitignore54
-rw-r--r--CREDITS2
-rw-r--r--EXPERIMENTAL0
-rw-r--r--LICENSE68
-rw-r--r--README.md36
-rw-r--r--config.m430
-rw-r--r--examples/repomanage.php74
-rw-r--r--php_rpminfo.h60
-rw-r--r--rpminfo.c178
-rw-r--r--tests/001.phpt10
-rw-r--r--tests/002.phpt29
11 files changed, 541 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7c022dd
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,54 @@
+# Object files
+*.o
+*.lo
+
+# Libraries
+*.lib
+*.a
+*.la
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+
+
+# autotools
+.deps
+.libs
+config.cache
+config.guess
+config.h
+config.h.in
+config.log
+config.nice
+config.status
+config.sub
+configure
+configure.in
+conftest
+conftest.c
+Makefile
+Makefile.fragments
+Makefile.global
+Makefile.objects
+acinclude.m4
+aclocal.m4
+autom4te.cache
+build
+install-sh
+libtool
+ltmain.sh
+ltmain.sh.backup
+missing
+mkinstalldirs
+modules
+run-tests.php
+run-tests.log
+tmp-php.ini
diff --git a/CREDITS b/CREDITS
new file mode 100644
index 0000000..b90dc70
--- /dev/null
+++ b/CREDITS
@@ -0,0 +1,2 @@
+rpminfo
+Remi Collet
diff --git a/EXPERIMENTAL b/EXPERIMENTAL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/EXPERIMENTAL
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..9964e07
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,68 @@
+--------------------------------------------------------------------
+ The PHP License, version 3.01
+Copyright (c) 1999 - 2017 The PHP Group. All rights reserved.
+--------------------------------------------------------------------
+
+Redistribution and use in source and binary forms, with or without
+modification, is permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. The name "PHP" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact group@php.net.
+
+ 4. Products derived from this software may not be called "PHP", nor
+ may "PHP" appear in their name, without prior written permission
+ from group@php.net. You may indicate that your software works in
+ conjunction with PHP by saying "Foo for PHP" instead of calling
+ it "PHP Foo" or "phpfoo"
+
+ 5. The PHP Group may publish revised and/or new versions of the
+ license from time to time. Each version will be given a
+ distinguishing version number.
+ Once covered code has been published under a particular version
+ of the license, you may always continue to use it under the terms
+ of that version. You may also choose to use such covered code
+ under the terms of any subsequent version of the license
+ published by the PHP Group. No one other than the PHP Group has
+ the right to modify the terms applicable to covered code created
+ under this License.
+
+ 6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes PHP software, freely available from
+ <http://www.php.net/software/>".
+
+THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
+ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
+DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--------------------------------------------------------------------
+
+This software consists of voluntary contributions made by many
+individuals on behalf of the PHP Group.
+
+The PHP Group can be contacted via Email at group@php.net.
+
+For more information on the PHP Group and the PHP project,
+please see <http://www.php.net>.
+
+PHP includes the Zend Engine, freely available at
+<http://www.zend.com>.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e3c75aa
--- /dev/null
+++ b/README.md
@@ -0,0 +1,36 @@
+rpminfo
+=======
+
+Experimental wrapper for librpm
+
+For now, only expose
+
+ int rpmvercmp(string evr1, string evr2);
+
+
+Mostly a PoC build for fun because of
+
+https://bugzilla.redhat.com/1537981
+performance issue: dnf repomanage is really slow
+
+
+Some benchmark results (find 15 old RPMs among 5000)
+
+# DNF on Fedora
+
+ $ time dnf repomanage --old --keep 5 .
+ ...
+ real 0m15,971s
+
+# YUM on RHEL / CentOS
+
+ $ time repomanage --old --keep 5 .
+ ...
+ real 0m5.519s
+
+# PHP script
+
+ $ time php repomanage.php --old --keep 5 .
+ ...
+ real 0m0,634s
+
diff --git a/config.m4 b/config.m4
new file mode 100644
index 0000000..8d117a9
--- /dev/null
+++ b/config.m4
@@ -0,0 +1,30 @@
+dnl config.m4 for extension rpminfo
+
+PHP_ARG_ENABLE(rpminfo, whether to enable rpminfo support,
+ [ --enable-rpminfo Enable rpminfo support])
+
+if test "$PHP_RPMINFO" != "no"; then
+ dnl Write more examples of tests here...
+
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+
+ AC_MSG_CHECKING(for librpm)
+ if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists rpm; then
+ if $PKG_CONFIG rpm --atleast-version 4; then
+ LIBRPM_CFLAGS=`$PKG_CONFIG rpm --cflags`
+ LIBRPM_LIBDIR=`$PKG_CONFIG rpm --libs`
+ LIBRPM_VERSON=`$PKG_CONFIG rpm --modversion`
+ AC_MSG_RESULT(from pkgconfig: version $LIBRPM_VERSON)
+ else
+ AC_MSG_ERROR(system librpm is too old)
+ fi
+ else
+ AC_MSG_ERROR(pkg-config not found)
+ fi
+ PHP_EVAL_LIBLINE($LIBRPM_LIBDIR, RPMINFO_SHARED_LIBADD)
+ PHP_EVAL_INCLINE($LIBRPM_CFLAGS)
+
+ PHP_SUBST(RPMINFO_SHARED_LIBADD)
+
+ PHP_NEW_EXTENSION(rpminfo, rpminfo.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
+fi
diff --git a/examples/repomanage.php b/examples/repomanage.php
new file mode 100644
index 0000000..8428118
--- /dev/null
+++ b/examples/repomanage.php
@@ -0,0 +1,74 @@
+#!/usr/bin/php
+<?php
+
+extension_loaded("rpminfo") or die("rpminfo extension missing");
+
+for ($i=1 ; $i<$_SERVER['argc'] ; $i++) {
+ switch($_SERVER['argv'][$i]) {
+ case '-o':
+ case '--old':
+ if (isset($old)) {
+ die("--old option incompatible with --new\n");
+ }
+ $old = true;
+ break;
+ case '-n':
+ case '--new':
+ if (isset($new)) {
+ die("--new option incompatible with --old\n");
+ }
+ case '-k':
+ case '--keep':
+ if (!isset($_SERVER['argv'][$i+1])) {
+ die("Missing argument for --keep option\n");
+ }
+ $keep = (int)$_SERVER['argv'][$i+1];
+ $i++;
+ break;
+ default:
+ $rpms = $_SERVER['argv'][$i];
+ }
+}
+if (!isset($old)) {
+ die("Missing --old or --new option\n");
+}
+if (!isset($keep)) {
+ $keep = 1;
+}
+if (!isset($rpms)) {
+ die("Missing rpm directory argument\n");
+}
+if (is_dir($rpms)) {
+} else {
+ die("$rpms is not a directory\n");
+}
+
+$tree = [];
+$handle = popen('rpm -qp --qf "%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH} %{NEVR}\n" ' . $rpms . "/*.rpm", "r");
+while ($line = fgets($handle)) {
+ $tab = explode(' ', trim($line));
+ if (count($tab) == 6) {
+ $tree[$tab[4]][$tab[0]][] = [
+ 'name' => $tab[0],
+ 'path' => $tab[5],
+ 'evr' => "${tab[1]}:${tab[2]}-${tab[3]}",
+ ];
+ } else {
+ echo "Ignore $line\n";
+ }
+}
+foreach($tree as $arch => $subtree) {
+ foreach ($subtree as $name => $versions) {
+ if (count($versions) > $keep) {
+ if ($old) {
+ usort($versions, function($a, $b) { return -rpmvercmp($a['evr'], $b['evr']);} );
+ } else {
+ usort($versions, function($a, $b) { return rpmvercmp($a['evr'], $b['evr']);} );
+ }
+ for ($i = $keep ; $i < count($versions) ; $i++) {
+ echo $versions[$i]['path'] . "\n";
+ }
+ }
+ }
+}
+
diff --git a/php_rpminfo.h b/php_rpminfo.h
new file mode 100644
index 0000000..9c8319c
--- /dev/null
+++ b/php_rpminfo.h
@@ -0,0 +1,60 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2018 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Remi Collet <remi@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHP_RPMINFO_H
+#define PHP_RPMINFO_H
+
+extern zend_module_entry rpminfo_module_entry;
+#define phpext_rpminfo_ptr &rpminfo_module_entry
+
+#define PHP_RPMINFO_VERSION "0.1.0" /* Replace with version number for your extension */
+
+#ifdef PHP_WIN32
+# define PHP_RPMINFO_API __declspec(dllexport)
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define PHP_RPMINFO_API __attribute__ ((visibility("default")))
+#else
+# define PHP_RPMINFO_API
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+/*
+ Declare any global variables you may need between the BEGIN
+ and END macros here:
+
+ZEND_BEGIN_MODULE_GLOBALS(rpminfo)
+ zend_long global_value;
+ char *global_string;
+ZEND_END_MODULE_GLOBALS(rpminfo)
+*/
+
+/* Always refer to the globals in your function as RPMINFO_G(variable).
+ You are encouraged to rename these macros something shorter, see
+ examples in any other php module directory.
+*/
+#define RPMINFO_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(rpminfo, v)
+
+#if defined(ZTS) && defined(COMPILE_DL_RPMINFO)
+ZEND_TSRMLS_CACHE_EXTERN()
+#endif
+
+#endif /* PHP_RPMINFO_H */
+
diff --git a/rpminfo.c b/rpminfo.c
new file mode 100644
index 0000000..b08e05b
--- /dev/null
+++ b/rpminfo.c
@@ -0,0 +1,178 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2018 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Remi Collet <remi@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_rpminfo.h"
+
+#include <rpm/rpmlib.h>
+
+/* If you declare any globals in php_rpminfo.h uncomment this:
+ZEND_DECLARE_MODULE_GLOBALS(rpminfo)
+*/
+
+/* True global resources - no need for thread safety here */
+static int le_rpminfo;
+
+/* {{{ PHP_INI
+ */
+/* Remove comments and fill if you need to have entries in php.ini
+PHP_INI_BEGIN()
+ STD_PHP_INI_ENTRY("rpminfo.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_rpminfo_globals, rpminfo_globals)
+ STD_PHP_INI_ENTRY("rpminfo.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_rpminfo_globals, rpminfo_globals)
+PHP_INI_END()
+*/
+/* }}} */
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_rpmvercmp, 0, 0, 2)
+ ZEND_ARG_INFO(0, evr1)
+ ZEND_ARG_INFO(0, evr2)
+ZEND_END_ARG_INFO()
+
+/* Every user-visible function in PHP should document itself in the source */
+/* {{{ proto string rpmcmpver(string evr1, string evr2)
+ Return a string to confirm that the module is compiled in */
+PHP_FUNCTION(rpmvercmp)
+{
+ char *evr1, *evr2;
+ size_t len1, len2;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &evr1, &len1, &evr2, &len2) == FAILURE) {
+ return;
+ }
+
+ RETURN_LONG(rpmvercmp(evr1, evr2));
+}
+
+/* {{{ php_rpminfo_init_globals
+ */
+/* Uncomment this function if you have INI entries
+static void php_rpminfo_init_globals(zend_rpminfo_globals *rpminfo_globals)
+{
+ rpminfo_globals->global_value = 0;
+ rpminfo_globals->global_string = NULL;
+}
+*/
+/* }}} */
+
+/* {{{ PHP_MINIT_FUNCTION
+ */
+PHP_MINIT_FUNCTION(rpminfo)
+{
+ /* If you have INI entries, uncomment these lines
+ REGISTER_INI_ENTRIES();
+ */
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MSHUTDOWN_FUNCTION
+ */
+PHP_MSHUTDOWN_FUNCTION(rpminfo)
+{
+ /* uncomment this line if you have INI entries
+ UNREGISTER_INI_ENTRIES();
+ */
+ return SUCCESS;
+}
+/* }}} */
+
+/* Remove if there's nothing to do at request start */
+/* {{{ PHP_RINIT_FUNCTION
+ */
+PHP_RINIT_FUNCTION(rpminfo)
+{
+#if defined(COMPILE_DL_RPMINFO) && defined(ZTS)
+ ZEND_TSRMLS_CACHE_UPDATE();
+#endif
+ return SUCCESS;
+}
+/* }}} */
+
+/* Remove if there's nothing to do at request end */
+/* {{{ PHP_RSHUTDOWN_FUNCTION
+ */
+PHP_RSHUTDOWN_FUNCTION(rpminfo)
+{
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION
+ */
+PHP_MINFO_FUNCTION(rpminfo)
+{
+ php_info_print_table_start();
+ php_info_print_table_header(2, "rpminfo support", "enabled");
+ php_info_print_table_row(2, "Extension version", PHP_RPMINFO_VERSION);
+ php_info_print_table_row(2, "RPM library version", RPMVERSION);
+ php_info_print_table_end();
+
+ /* Remove comments if you have entries in php.ini
+ DISPLAY_INI_ENTRIES();
+ */
+}
+/* }}} */
+
+/* {{{ rpminfo_functions[]
+ *
+ * Every user visible function must have an entry in rpminfo_functions[].
+ */
+const zend_function_entry rpminfo_functions[] = {
+ PHP_FE(rpmvercmp, arginfo_rpmvercmp)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ rpminfo_module_entry
+ */
+zend_module_entry rpminfo_module_entry = {
+ STANDARD_MODULE_HEADER,
+ "rpminfo",
+ rpminfo_functions,
+ PHP_MINIT(rpminfo),
+ PHP_MSHUTDOWN(rpminfo),
+ PHP_RINIT(rpminfo), /* Replace with NULL if there's nothing to do at request start */
+ PHP_RSHUTDOWN(rpminfo), /* Replace with NULL if there's nothing to do at request end */
+ PHP_MINFO(rpminfo),
+ PHP_RPMINFO_VERSION,
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+#ifdef COMPILE_DL_RPMINFO
+#ifdef ZTS
+ZEND_TSRMLS_CACHE_DEFINE()
+#endif
+ZEND_GET_MODULE(rpminfo)
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/tests/001.phpt b/tests/001.phpt
new file mode 100644
index 0000000..69f6aff
--- /dev/null
+++ b/tests/001.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Check for rpminfo presence
+--SKIPIF--
+<?php if (!extension_loaded("rpminfo")) print "skip"; ?>
+--FILE--
+<?php
+echo "rpminfo extension is available";
+?>
+--EXPECT--
+rpminfo extension is available
diff --git a/tests/002.phpt b/tests/002.phpt
new file mode 100644
index 0000000..513339c
--- /dev/null
+++ b/tests/002.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Check for rpmvercmp function
+--SKIPIF--
+<?php if (!extension_loaded("rpminfo")) print "skip"; ?>
+--FILE--
+<?php
+var_dump(rpmvercmp("1.0", "1.1"));
+var_dump(rpmvercmp("1.1", "1.0"));
+var_dump(rpmvercmp("1.0", "1.0"));
+// Errors
+var_dump(rpmvercmp());
+var_dump(rpmvercmp("a"));
+var_dump(rpmvercmp("a", "b", "c"));
+?>
+Done
+--EXPECT--
+int(-1)
+int(1)
+int(0)
+
+Warning: rpmvercmp() expects exactly 2 parameters, 0 given in /work/GIT/php-rpminfo/tests/002.php on line 6
+NULL
+
+Warning: rpmvercmp() expects exactly 2 parameters, 1 given in /work/GIT/php-rpminfo/tests/002.php on line 7
+NULL
+
+Warning: rpmvercmp() expects exactly 2 parameters, 3 given in /work/GIT/php-rpminfo/tests/002.php on line 8
+NULL
+Done