diff options
-rw-r--r-- | README.md | 22 | ||||
-rw-r--r-- | REFLECTION | 11 | ||||
-rw-r--r-- | package.xml | 4 | ||||
-rw-r--r-- | rpminfo.c | 148 | ||||
-rw-r--r-- | tests/007-rpmdbinfo.phpt | 26 |
5 files changed, 156 insertions, 55 deletions
@@ -41,9 +41,10 @@ Allow to compare 2 EVR (epoch:version-release) strings. The return value is < 0 ## rpminfo - array rpminfo(string path [, bool full ]); + array rpminfo(string path [, bool full [, string &error]]); Retrieve information from a rpm file, reading its metadata. +If given `error` will be used to store error message instead of raising a warning. The return value is a hash table, or false if it fails. $ php -a @@ -82,6 +83,25 @@ The return value is a hash table, or false if it fails. php > echo $error; Can't open 'missing.rpm': No such file or directory +## rpmdbinfo + + array rpmdbinfo(string path [, bool full ]); + +Retrieve information from rpm database about an installed package. +The return value is an array of hash tables, or false if it fails. + + $ php -a + php > print_r(rpmdbinfo("php")); + Array + ( + [0] => Array + ( + [Name] => php + [Version] => 7.2.2 + [Release] => 1.fc27.remi + [Arch] => x86_64 + ) + ) ---- @@ -1,10 +1,17 @@ -Extension [ <persistent> extension #15 rpminfo version 0.1.2-dev ] { +Extension [ <persistent> extension #15 rpminfo version 0.1.3-dev ] { - Constants [1] { - Constant [ string RPMVERSION ] { 4.14.0 } + Constant [ string RPMVERSION ] { 4.14.1 } } - Functions { + Function [ <internal:rpminfo> function rpmdbinfo ] { + + - Parameters [2] { + Parameter #0 [ <required> $name ] + Parameter #1 [ <optional> $full ] + } + } Function [ <internal:rpminfo> function rpminfo ] { - Parameters [3] { diff --git a/package.xml b/package.xml index 6ee0aca..4f2d3a6 100644 --- a/package.xml +++ b/package.xml @@ -21,7 +21,8 @@ </stability> <license>PHP 3.01</license> <notes> -- +- new function: + array rpmdbinfo(string name [, bool full]); </notes> <contents> <dir name="/"> @@ -45,6 +46,7 @@ <file name="004-constants.phpt" role="test"/> <file name="005-rpminfo-full.phpt" role="test"/> <file name="006-rpminfo-errors.phpt" role="test"/> + <file name="007-rpmdbinfo.phpt" role="test"/> <file name="bidon.rpm" role="test"/> <file name="bidon-src.rpm" role="test"/> </dir> @@ -24,6 +24,8 @@ #include "php_ini.h" #include "ext/standard/info.h" +#include <fcntl.h> +#include <rpm/rpmdb.h> #include <rpm/rpmio.h> #include <rpm/rpmlib.h> #include <rpm/rpmts.h> @@ -34,6 +36,7 @@ ZEND_DECLARE_MODULE_GLOBALS(rpminfo) static rpmts rpminfo_getts(rpmVSFlags flags) { if (!RPMINFO_G(ts)) { + rpmReadConfigFiles(NULL, NULL); RPMINFO_G(ts) = rpmtsCreate(); } if (RPMINFO_G(ts)) { @@ -42,6 +45,61 @@ static rpmts rpminfo_getts(rpmVSFlags flags) { return RPMINFO_G(ts); } +static void rpm_header_to_zval(zval *return_value, Header h, zend_bool full) +{ + HeaderIterator hi; + rpmTagVal tag; + rpmTagType type; + const char *val; + + 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)); + } +} + ZEND_BEGIN_ARG_INFO_EX(arginfo_rpminfo, 0, 0, 1) ZEND_ARG_INFO(0, path) ZEND_ARG_INFO(0, full) @@ -53,15 +111,11 @@ ZEND_END_ARG_INFO() PHP_FUNCTION(rpminfo) { char *path, *e_msg; - const char *val; size_t len, e_len=0; zend_bool full = 0; zval *error = NULL; FD_t f; 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|bz", &path, &len, &full, &error) == FAILURE) { @@ -79,53 +133,7 @@ PHP_FUNCTION(rpminfo) 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)); - } + rpm_header_to_zval(return_value, h, full); if (h) { headerFree(h); } @@ -156,6 +164,43 @@ PHP_FUNCTION(rpminfo) } /* }}} */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_rpmdbinfo, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, full) +ZEND_END_ARG_INFO() + +/* {{{ proto array rpmdbinfo(string name [, bool full [, string &$error]) + Retrieve information from a RPM file */ +PHP_FUNCTION(rpmdbinfo) +{ + char *name; + size_t len; + zend_bool full = 0; + Header h; + rpmdb db; + rpmdbMatchIterator di; + rpmts ts = rpminfo_getts(_RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES | RPMVSF_NOHDRCHK); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|b", &name, &len, &full) == FAILURE) { + return; + } + + rpmtsOpenDB(ts, O_RDONLY); + db = rpmtsGetRdb(ts); + di = rpmdbInitIterator(db, RPMTAG_NAME, name, len); + if (!di) { + RETURN_FALSE; + } + + array_init(return_value); + while ((h = rpmdbNextIterator(di)) != NULL) { + zval tmp; + rpm_header_to_zval(&tmp, h, full); + add_next_index_zval(return_value, &tmp); + } +} +/* }}} */ + ZEND_BEGIN_ARG_INFO_EX(arginfo_rpmvercmp, 0, 0, 2) ZEND_ARG_INFO(0, evr1) ZEND_ARG_INFO(0, evr2) @@ -240,6 +285,7 @@ PHP_GSHUTDOWN_FUNCTION(rpminfo) * Every user visible function must have an entry in rpminfo_functions[]. */ const zend_function_entry rpminfo_functions[] = { + PHP_FE(rpmdbinfo, arginfo_rpmdbinfo) PHP_FE(rpminfo, arginfo_rpminfo) PHP_FE(rpmvercmp, arginfo_rpmvercmp) PHP_FE_END diff --git a/tests/007-rpmdbinfo.phpt b/tests/007-rpmdbinfo.phpt new file mode 100644 index 0000000..6ef5aa1 --- /dev/null +++ b/tests/007-rpmdbinfo.phpt @@ -0,0 +1,26 @@ +--TEST-- +Check for rpmdbinfo function +--SKIPIF-- +<?php if (!extension_loaded("rpminfo")) print "skip"; ?> +--FILE-- +<?php +var_dump(rpmdbinfo('doesntexistsinrpmdb')); +var_dump(rpmdbinfo('bash')); +?> +Done +--EXPECTF-- +bool(false) +array(1) { + [0]=> + array(4) { + ["Name"]=> + string(4) "bash" + ["Version"]=> + string(%d) "%s" + ["Release"]=> + string(%d) "%s" + ["Arch"]=> + string(%d) "%s" + } +} +Done |