Source for file Registry.php
Documentation is available at Registry.php
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2004 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 3.0 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_0.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: Stig Bakken <ssb@php.net> |
// | Tomas V.V.Cox <cox@idecnet.com> |
// +----------------------------------------------------------------------+
// $Id: Registry.php,v 1.50.4.3 2004/10/26 19:19:56 cellog Exp $
- Transform into singleton()
- Add application level lock (avoid change the registry from the cmdline
while using the GTK interface, for ex.)
require_once "System.php";
define('PEAR_REGISTRY_ERROR_LOCK', -2 );
define('PEAR_REGISTRY_ERROR_FORMAT', -3 );
define('PEAR_REGISTRY_ERROR_FILE', -4 );
* Administration class used to maintain the installed package database.
class PEAR_Registry extends PEAR
/** Directory where registry files are stored.
/** File where the file map is stored
/** Name of file used for locking the registry
/** File descriptor used during locking
/** Mode used during locking
var $lock_mode = 0; // XXX UNUSED
/** Cache of package information. Structure:
* 'package' => array('id' => ... ),
var $pkginfo_cache = array ();
/** Cache of file map. Structure:
* array( '/path/to/file' => 'package', ... )
var $filemap_cache = array ();
* PEAR_Registry constructor.
* @param string (optional) PEAR install directory (for .php files)
function PEAR_Registry ($pear_install_dir = PEAR_INSTALL_DIR )
$ds = DIRECTORY_SEPARATOR;
$this->install_dir = $pear_install_dir;
$this->statedir = $pear_install_dir. $ds. '.registry';
$this->filemap = $pear_install_dir. $ds. '.filemap';
$this->lockfile = $pear_install_dir. $ds. '.lock';
// XXX Compatibility code should be removed in the future
// rename all registry files if any to lowercase
$dest = $this->statedir . DIRECTORY_SEPARATOR;
while (false !== ($file = readdir($handle))) {
* PEAR_Registry destructor. Makes sure no locks are forgotten.
function _PEAR_Registry ()
* Make sure the directory where we keep registry files exists.
* @return bool TRUE if directory exists, FALSE if it could not be
function _assertStateDir ()
if (!@is_dir($this->statedir)) {
if (!System::mkdir (array ('-p', $this->statedir))) {
return $this->raiseError (" could not create directory '{$this->statedir}' ");
// {{{ _packageFileName()
* Get the name of the file where data for a given package is stored.
* @param string package name
* @return string registry file name
function _packageFileName($package)
return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg';
// {{{ _openPackageFile()
function _openPackageFile($package, $mode)
$this->_assertStateDir();
$file = $this->_packageFileName($package);
$fp = @fopen($file, $mode);
// {{{ _closePackageFile()
function _closePackageFile($fp)
function rebuildFileMap()
$packages = $this->listPackages();
foreach ($packages as $package) {
$version = $this->packageInfo($package, 'version');
$filelist = $this->packageInfo($package, 'filelist');
foreach ($filelist as $name => $attrs) {
if (isset($attrs['role']) && $attrs['role'] != 'php') {
if (isset($attrs['baseinstalldir'])) {
$file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name;
$files[$file] = $package;
$this->_assertStateDir();
$fp = @fopen($this->filemap, 'wb');
$this->filemap_cache = $files;
$fp = @fopen($this->filemap, 'r');
return $this->raiseError('PEAR_Registry: could not open filemap', <a href="../PEAR/_PEAR-1.3.5---PEAR---Registry.php.html#definePEAR_REGISTRY_ERROR_FILE">PEAR_REGISTRY_ERROR_FILE</a>, null, null, $php_errormsg);
$data = fread($fp, $fsize);
if (!$tmp && $fsize > 7) {
return $this->raiseError('PEAR_Registry: invalid filemap data', <a href="../PEAR/_PEAR-1.3.5---PEAR---Registry.php.html#definePEAR_REGISTRY_ERROR_FORMAT">PEAR_REGISTRY_ERROR_FORMAT</a>, null, null, $data);
$this->filemap_cache = $tmp;
* @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN.
* See flock manual for more information.
* @return bool TRUE on success, FALSE if locking failed, or a
* PEAR error if some other error occurs (such as the
* lock file not being writable).
function _lock($mode = LOCK_EX)
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
if (PEAR::isError($err = $this->_assertStateDir())) {
// XXX People reported problems with LOCK_SH and 'w'
if ($mode === LOCK_SH || $mode === LOCK_UN) {
$this->lock_fp = @fopen($this->lockfile, $open_mode);
return $this->raiseError("could not create lock file" .
(isset($php_errormsg) ? ": " . $php_errormsg : ""));
if (!(int)flock($this->lock_fp, $mode)) {
case LOCK_SH: $str = 'shared'; break;
case LOCK_EX: $str = 'exclusive'; break;
case LOCK_UN: $str = 'unlock'; break;
default: $str = 'unknown'; break;
return $this->raiseError("could not acquire $str lock ( $this->lockfile)" ,
PEAR_REGISTRY_ERROR_LOCK);
$ret = $this->_lock(LOCK_UN);
if (is_resource($this->lock_fp)) {
function _packageExists($package)
return file_exists($this->_packageFileName($package));
function _packageInfo($package = null, $key = null)
return array_map(array($this, '_packageInfo'),
$fp = $this->_openPackageFile($package, 'r');
$this->_closePackageFile($fp);
if (isset($data[$key])) {
if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
$pkglist[] = substr($ent, 0, -4);
function packageExists($package)
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
$ret = $this->_packageExists($package);
function packageInfo($package = null, $key = null)
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
$ret = $this->_packageInfo($package, $key);
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
$ret = $this->_listPackages();
function addPackage($package, $info)
if ($this->packageExists($package)) {
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
$fp = $this->_openPackageFile($package, 'wb');
$info['_lastmodified'] = time();
$this->_closePackageFile($fp);
function deletePackage($package)
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
$file = $this->_packageFileName($package);
function updatePackage($package, $info, $merge = true)
$oldinfo = $this->packageInfo($package);
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
$fp = $this->_openPackageFile($package, 'w');
$info['_lastmodified'] = time();
$this->_closePackageFile($fp);
if (isset($info['filelist'])) {
* Test whether a file belongs to a package.
* @param string $path file path, absolute or relative to the pear
* @return string which package the file belongs to, or an empty
* string if the file does not belong to an installed package
function checkFileMap($path)
foreach ($path as $name => $attrs) {
if (is_array($attrs) && isset($attrs['baseinstalldir'])) {
$name = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name;
$pkgs[$name] = $this->checkFileMap($name);
if (empty($this->filemap_cache) && PEAR::isError($this->readFileMap())) {
if (isset($this->filemap_cache[$path])) {
return $this->filemap_cache[$path];
$l = strlen($this->install_dir);
if (substr($path, 0, $l) == $this->install_dir) {
if (isset($this->filemap_cache[$path])) {
return $this->filemap_cache[$path];
Documentation generated on Mon, 11 Mar 2019 14:24:00 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|