summaryrefslogtreecommitdiffstats
path: root/rpminfo.c
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2018-01-25 13:30:20 +0100
committerRemi Collet <remi@remirepo.net>2018-01-25 13:30:20 +0100
commit7adc0cf86d301028e268f1803ee117bdd74586d5 (patch)
tree72a553f8a633e7ce498fe7579e49db972720ee04 /rpminfo.c
parent4daae0625ceaf2aa7aba7bf0a7230044d346e256 (diff)
New function: array rpminfo(string path [, bool full ]);
Diffstat (limited to 'rpminfo.c')
-rw-r--r--rpminfo.c164
1 files changed, 154 insertions, 10 deletions
diff --git a/rpminfo.c b/rpminfo.c
index b08e05b..30c003c 100644
--- a/rpminfo.c
+++ b/rpminfo.c
@@ -23,16 +23,17 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_rpminfo.h"
+#include <rpm/rpmio.h>
#include <rpm/rpmlib.h>
+#include <rpm/rpmts.h>
+
+#include "php_rpminfo.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;
+// static int le_rpminfo;
/* {{{ PHP_INI
*/
@@ -44,15 +45,130 @@ PHP_INI_END()
*/
/* }}} */
+static rpmts rpminfo_getts(rpmVSFlags flags) {
+ if (!RPMINFO_G(ts)) {
+ RPMINFO_G(ts) = rpmtsCreate();
+ }
+ if (RPMINFO_G(ts)) {
+ (void)rpmtsSetVSFlags(RPMINFO_G(ts), flags);
+ }
+ return RPMINFO_G(ts);
+}
+
+static void rpminfo_freets(void) {
+ if (RPMINFO_G(ts)) {
+ rpmtsFree(RPMINFO_G(ts));
+ RPMINFO_G(ts) = NULL;
+ }
+}
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_rpminfo, 0, 0, 1)
+ ZEND_ARG_INFO(0, path)
+ ZEND_ARG_INFO(0, full)
+ZEND_END_ARG_INFO()
+
+/* {{{ proto array rpminfo(string path [, bool full])
+ Retrieve information from a RPM file */
+PHP_FUNCTION(rpminfo)
+{
+ char *path, *msg=NULL, *val;
+ size_t len;
+ zend_bool full = 0;
+ FD_t f;
+ int rc;
+ Header h;
+ HeaderIterator hi;
+ rpmTagVal tag;
+ rpmTagType type;
+ rpmts ts = rpminfo_getts(_RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES | RPMVSF_NOHDRCHK);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|b", &path, &len, &full) == FAILURE) {
+ return;
+ }
+
+ f = Fopen(path, "r");
+ if (f) {
+ rc = rpmReadPackageFile(ts, f, "rpminfo", &h);
+ if (rc == RPMRC_OK || rc == RPMRC_NOKEY || rc == RPMRC_NOTTRUSTED) {
+
+ array_init(return_value);
+ hi = headerInitIterator(h);
+ while ((tag=headerNextTag(hi)) != RPMTAG_NOT_FOUND) {
+ switch (tag) {
+ case RPMTAG_NAME:
+ case RPMTAG_VERSION:
+ case RPMTAG_RELEASE:
+ case RPMTAG_EPOCH:
+ case RPMTAG_ARCH:
+ break;
+ default:
+ if (!full) {
+ continue;
+ }
+ }
+
+ type = rpmTagGetTagType(tag);
+ switch (type) {
+ case RPM_STRING_TYPE:
+ case RPM_I18NSTRING_TYPE:
+ val = headerGetString(h, tag);
+ if (val) {
+ add_assoc_string(return_value, rpmTagGetName(tag), headerGetAsString(h, tag));
+ } else {
+ add_assoc_null(return_value, rpmTagGetName(tag));
+ }
+ break;
+ case RPM_CHAR_TYPE:
+ case RPM_INT8_TYPE:
+ case RPM_INT16_TYPE:
+ case RPM_INT32_TYPE:
+ case RPM_INT64_TYPE:
+ add_assoc_long(return_value, rpmTagGetName(tag), (zend_long)headerGetNumber(h, tag));
+ break;
+ default:
+ val = headerGetAsString(h, tag);
+ if (val) {
+ add_assoc_string(return_value, rpmTagGetName(tag), headerGetAsString(h, tag));
+ } else {
+ add_assoc_null(return_value, rpmTagGetName(tag));
+ }
+ }
+ }
+ if (full) {
+ add_assoc_bool(return_value, "IsSource", headerIsSource(h));
+ }
+ if (h) {
+ headerFree(h);
+ }
+ Fclose(f);
+ return;
+
+ } else if (rc == RPMRC_NOTFOUND) {
+ php_error_docref(NULL, E_WARNING, "Can't read '%s': Argument is not a RPM file", path);
+
+ } else if (rc == RPMRC_NOTFOUND) {
+ php_error_docref(NULL, E_WARNING, "Can't read '%s': Error reading header from package", path);
+
+ } else {
+ php_error_docref(NULL, E_WARNING, "Can't read '%s': Unkown error", path);
+ }
+
+ Fclose(f);
+ } else {
+ php_error_docref(NULL, E_WARNING, "Can't open '%s': %s", path, Fstrerror(f));
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
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 */
+/* {{{ proto int rpmcmpver(string evr1, string evr2)
+ Compare 2 RPM evr (epoch:version-release) strings */
PHP_FUNCTION(rpmvercmp)
{
char *evr1, *evr2;
@@ -64,6 +180,7 @@ PHP_FUNCTION(rpmvercmp)
RETURN_LONG(rpmvercmp(evr1, evr2));
}
+/* }}} */
/* {{{ php_rpminfo_init_globals
*/
@@ -135,12 +252,33 @@ PHP_MINFO_FUNCTION(rpminfo)
}
/* }}} */
+/* {{{ PHP_GINIT_FUNCTION
+ */
+static PHP_GINIT_FUNCTION(rpminfo) /* {{{ */
+{
+#if defined(COMPILE_DL_SESSION) && defined(ZTS)
+ ZEND_TSRMLS_CACHE_UPDATE();
+#endif
+
+ rpminfo_globals->ts = NULL;
+}
+/* }}} */
+
+/* {{{ PHP_GSHUTDOWN_FUNCTION
+*/
+PHP_GSHUTDOWN_FUNCTION(rpminfo)
+{
+ rpminfo_freets();
+}
+/* }}} */
+
/* {{{ 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(rpminfo, arginfo_rpminfo)
+ PHP_FE(rpmvercmp, arginfo_rpmvercmp)
PHP_FE_END
};
/* }}} */
@@ -148,7 +286,9 @@ const zend_function_entry rpminfo_functions[] = {
/* {{{ rpminfo_module_entry
*/
zend_module_entry rpminfo_module_entry = {
- STANDARD_MODULE_HEADER,
+ STANDARD_MODULE_HEADER_EX,
+ NULL,
+ NULL,
"rpminfo",
rpminfo_functions,
PHP_MINIT(rpminfo),
@@ -157,7 +297,11 @@ zend_module_entry rpminfo_module_entry = {
PHP_RSHUTDOWN(rpminfo), /* Replace with NULL if there's nothing to do at request end */
PHP_MINFO(rpminfo),
PHP_RPMINFO_VERSION,
- STANDARD_MODULE_PROPERTIES
+ PHP_MODULE_GLOBALS(rpminfo),
+ PHP_GINIT(rpminfo),
+ PHP_GSHUTDOWN(rpminfo),
+ NULL,
+ STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */