From 7adc0cf86d301028e268f1803ee117bdd74586d5 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 25 Jan 2018 13:30:20 +0100 Subject: New function: array rpminfo(string path [, bool full ]); --- rpminfo.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 154 insertions(+), 10 deletions(-) (limited to 'rpminfo.c') 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 #include +#include + +#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 }; /* }}} */ -- cgit